fcn2optimexpr
関数から最適化式への変換
構文
説明
例
目的関数から式への変換
サポートされている関数で構成されていない問題ベースのアプローチで MATLAB® 関数を使用するには、まず、関数を最適化式に変換します。詳細については、最適化変数および式でサポートされる演算と非線形関数から最適化式への変換を参照してください。
目的関数 gamma
(数学関数 、階乗関数の拡張) を使用し、最適化変数 x
を作成して、変換された無名関数で使用するには、次のようにします。
x = optimvar('x'); obj = fcn2optimexpr(@gamma,x); prob = optimproblem('Objective',obj); show(prob)
OptimizationProblem : Solve for: x minimize : gamma(x)
得られた問題を解くには、初期点構造体を与え、solve
を呼び出します。
x0.x = 1/2; sol = solve(prob,x0)
Solving problem using fminunc. Local minimum found. Optimization completed because the size of the gradient is less than the value of the optimality tolerance.
sol = struct with fields:
x: 1.4616
さらに複雑な関数の場合、関数ファイルを変換します。関数ファイル gammabrock.m
は、2 つの最適化変数の目的関数を計算します。
type gammabrock
function f = gammabrock(x,y) f = (10*(y - gamma(x)))^2 + (1 - x)^2;
この目的関数を問題に含めます。
x = optimvar('x','LowerBound',0); y = optimvar('y'); obj = fcn2optimexpr(@gammabrock,x,y); prob = optimproblem('Objective',obj); show(prob)
OptimizationProblem : Solve for: x, y minimize : gammabrock(x, y) variable bounds: 0 <= x
関数 gammabrock
は二乗和です。この関数を最適化式の陽的な二乗和として表現すれば、より効率的に問題を定式化できます。
f = fcn2optimexpr(@(x,y)y - gamma(x),x,y);
obj2 = (10*f)^2 + (1-x)^2;
prob2 = optimproblem('Objective',obj2);
効率性の違いを確認するには、prob
と prob2
を解き、反復回数の違いを検証します。
x0.x = 1/2; x0.y = 1/2; [sol,fval,~,output] = solve(prob,x0);
Solving problem using fmincon. Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
[sol2,fval2,~,output2] = solve(prob2,x0);
Solving problem using lsqnonlin. Local minimum found. Optimization completed because the size of the gradient is less than the value of the optimality tolerance.
fprintf('prob took %d iterations, but prob2 took %d iterations\n',output.iterations,output2.iterations)
prob took 21 iterations, but prob2 took 2 iterations
関数に複数の出力がある場合、これらの出力を目的関数の要素として使用できます。この場合、u
は 2 行 2 列の変数、v
は 2 行 1 列の変数であり、expfn3
は 3 つの出力をもちます。
type expfn3
function [f,g,mineval] = expfn3(u,v) mineval = min(eig(u)); f = v'*u*v; f = -exp(-f); t = u*v; g = t'*t + sum(t) - 3;
適切なサイズの最適化変数を作成し、最初の 2 つの出力から目的関数を作成します。
u = optimvar('u',2,2); v = optimvar('v',2); [f,g,mineval] = fcn2optimexpr(@expfn3,u,v); prob = optimproblem; prob.Objective = f*g/(1 + f^2); show(prob)
OptimizationProblem : Solve for: u, v minimize : ((arg2 .* arg3) ./ (1 + arg1.^2)) where: [arg1,~,~] = expfn3(u, v); [arg2,~,~] = expfn3(u, v); [~,arg3,~] = expfn3(u, v);
後続の制約式では出力 mineval
を使用できます。
関数からの非線形制約の作成
問題ベースの最適化では、制約は、間に比較演算子 (==
、<=
、または >=
) がある 2 つの最適化式です。fcn2optimexpr
を使用していずれかまたは両方の最適化式を作成できます。詳細については、非線形関数から最適化式への変換を参照してください。
gammafn2
が –1/2 以下であるという非線形制約を作成します。この 2 変数の関数は gammafn2.m
ファイルにあります。
type gammafn2
function f = gammafn2(x,y) f = -gamma(x)*(y/(1+y^2));
最適化変数を作成し、関数ファイルを最適化式に変換して、制約を confn
として表します。
x = optimvar('x','LowerBound',0); y = optimvar('y','LowerBound',0); expr1 = fcn2optimexpr(@gammafn2,x,y); confn = expr1 <= -1/2; show(confn)
gammafn2(x, y) <= -0.5
gammafn2
が x + y
以上になるという別の制約を作成します。
confn2 = expr1 >= x + y;
最適化問題を作成し、制約を問題に配置します。
prob = optimproblem; prob.Constraints.confn = confn; prob.Constraints.confn2 = confn2; show(prob)
OptimizationProblem : Solve for: x, y minimize : subject to confn: gammafn2(x, y) <= -0.5 subject to confn2: gammafn2(x, y) >= (x + y) variable bounds: 0 <= x 0 <= y
共通の目的関数と制約の効率的な計算
目的関数および非線形制約を計算するのに、時間がかかる共通の関数が問題に含まれる場合、名前と値の引数 ReuseEvaluation
を使用することにより、時間を短縮できます。関数 rosenbrocknorm
は、Rosenbrock 目的関数と、制約 に使用する引数のノルム値の両方を計算します。
type rosenbrocknorm
function [f,c] = rosenbrocknorm(x) pause(1) % Simulates time-consuming function c = dot(x,x); f = 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2;
2 次元最適化変数 x
を作成します。その後、fcn2optimexpr
を使用して rosenbrocknorm
を最適化式に変換し、名前と値の引数 ReuseEvaluation
を true
に設定します。fcn2optimexpr
が pause
ステートメントを維持するようにするには、名前と値の引数 Analysis
を 'off'
に設定します。
x = optimvar('x',2); [f,c] = fcn2optimexpr(@rosenbrocknorm,x,... 'ReuseEvaluation',true,'Analysis','off');
返された式から目的関数と制約式を作成します。目的関数と制約式を最適化問題に含めます。show
を使用して問題を確認します。
prob = optimproblem('Objective',f);
prob.Constraints.cineq = c <= 4;
show(prob)
OptimizationProblem : Solve for: x minimize : [argout,~] = rosenbrocknorm(x) subject to cineq: arg_LHS <= 4 where: [~,arg_LHS] = rosenbrocknorm(x);
初期点 x0.x = [-1;1]
から始めて、結果が出るまでにかかる時間を測定しながら、問題を解きます。
x0.x = [-1;1]; tic [sol,fval,exitflag,output] = solve(prob,x0)
Solving problem using fmincon. Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. <stopping criteria details>
sol = struct with fields:
x: [2×1 double]
fval = 4.5793e-11
exitflag = OptimalSolution
output = struct with fields:
iterations: 44
funcCount: 164
constrviolation: 0
stepsize: 4.3124e-08
algorithm: 'interior-point'
firstorderopt: 5.1691e-07
cgiterations: 10
message: 'Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 5.169074e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.'
bestfeasible: [1×1 struct]
objectivederivative: "finite-differences"
constraintderivative: "finite-differences"
solver: 'fmincon'
toc
Elapsed time is 165.623157 seconds.
求解にかかる時間 (秒単位) は関数評価の回数とほぼ同じです。この結果は、ソルバーが関数値を再利用しており、同じ点を 2 回再評価することによって時間を無駄にしなかったことを示しています。
より広範囲な例は、共通の関数を持つ目的関数と制約の逐次評価または並列評価、問題ベースを参照してください。fcn2optimexpr
の使用に関する詳細については、非線形関数から最適化式への変換を参照してください。
入力引数
fcn
— 変換する関数
関数ハンドル
変換する関数。関数ハンドルとして指定します。
例: @sin
は正弦関数を指定します。
データ型: function_handle
in
— 入力引数
MATLAB® 変数
入力引数。MATLAB 変数として指定します。入力は任意のデータ型とサイズをとることができます。任意の問題変数またはデータを入力引数 in
に含めることができます。問題ベースのアプローチでの追加パラメーターの受け渡しを参照してください。
データ型: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
| logical
| char
| string
| struct
| table
| cell
| function_handle
| categorical
| datetime
| duration
| calendarDuration
| fi
複素数のサポート: あり
名前と値の引数
引数の任意のペアを Name1=Value1,...,NameN=ValueN
のように指定します。Name
は引数名、Value
は対応する値です。名前と値の引数は、他の引数より後に指定されている必要があります。ただし、各ペアの順序は任意です。
R2021a 以前では、それぞれの名前と値をコンマで区切り、Name
を引用符で囲みます。
例: [out1,out2] = fcn2optimexpr(@fun,x,y,'OutputSize',[1,1],'ReuseEvaluation',true)
は、out1
および out2
が目的関数と制約関数の間で再計算なしでソルバーが再利用するスカラーであることを指定します。
Analysis
— 関数解析の指定
"on"
(既定値) | "off"
関数 fcn
を解析して、サポートされている演算のみで構成されるかどうかの判定の指定です (最適化変数および式でサポートされる演算を参照してください)。"on"
または "off"
で指定します。
fcn2optimexpr
でfcn
を解析し、可能な場合はサポートされている演算を使用してfcn
を実装する場合は、"on"
を指定します。このように指定すると、fcn
で自動微分を使用できるようになり、Solver
で説明されているように適切なソルバーを選択できるようになります。fcn2optimexpr
でfcn
を解析せず、したがってfcn
を自動微分なしのブラック ボックスとして扱う場合は、"off"
を指定します。この場合、solve
はfmincon
、fminunc
、またはlsqnonlin
のみをソルバーとして使用します。
Analysis
の効果の詳細については、制限を参照してください。
例: [out1,out2] = fcn2optimexpr(@fun,x,"Analysis","off")
データ型: char
| string
Display
— 関数解析の詳細レポート
"off"
(既定値) | "on"
関数解析の詳細をレポートします。"off"
(レポートしない) または "on"
(レポートする) として指定します。Analysis
が "off"
の場合、何もレポートされません。
例: [out1,out2] = fcn2optimexpr(@fun,x,"Display","on")
データ型: char
| string
OutputSize
— 出力式のサイズ
整数ベクトル | 整数ベクトルの cell 配列
出力式のサイズ。次のように指定します。
整数ベクトル — 関数が 1 つの出力
out
1 をもつ場合、OutputSize
はout
1 のサイズを指定します。関数が複数の出力out
1 ~out
N をもつ場合、OutputSize
はすべての出力のサイズが同じであることを指定します。整数ベクトルの cell 配列 — 出力
out
j のサイズは、OutputSize
の j 番目の要素です。
メモ
スカラーのサイズは [1,1]
です。
名前/値のペアの引数 'OutputSize'
を指定しない場合、出力のサイズを決定するために、fcn2optimexpr
によって fcn
にデータが渡されます (アルゴリズムを参照)。'OutputSize'
を指定することにより、fcn2optimexpr
にこの手順をスキップさせて、時間を短縮できます。また、'OutputSize'
を指定せず、何らかの理由で fcn
の評価が失敗した場合、fcn2optimexpr
も失敗します。
例: [out1,out2,out3] = fcn2optimexpr(@fun,x,'OutputSize',[1,1])
は、3 つの出力 [out1,out2,out3]
がスカラーであることを指定します。
例: [out1,out2] = fcn2optimexpr(@fun,x,'OutputSize',{[4,4],[3,5]})
は、out1
のサイズが 4 行 4 列であり、out2
のサイズが 3 行 5 列であることを指定します。
データ型: double
| cell
ReuseEvaluation
— 値を再利用するための指標
false
(既定値) | true
値を再利用するための指標。false
(再利用不可) または true
(再利用可能) として指定します。
ReuseEvaluation
を使用すると、目的関数と一部の非線形制約が共通の計算に依存する場合などに、問題の実行を高速化できます。この場合、ソルバーは値を保存して必要な場合に再利用し、値の再計算を回避します。
再利用可能な値には多少のオーバーヘッドが伴うため、再利用可能な値は、値を共有している式に対してのみ有効にすることをお勧めします。
例: [out1,out2,out3] = fcn2optimexpr(@fun,x,"ReuseEvaluation",true,"Analysis","off")
とすると、out1
、out2
、および out3
が複数の計算で使用され、評価点ごとに 1 回のみ出力が計算されるようになります。
データ型: logical
出力引数
out
— 出力引数
OptimizationExpression
出力引数。OptimizationExpression
として返されます。式のサイズは入力関数に依存します。
制限
Analysis
は計算をしない関数を無視可能
Analysis
アルゴリズムには、計算をしない関数が含まれない場合があります。アルゴリズムにはこのような特徴があるため、次のような結果になります。pause
ステートメントは無視されます。結果に影響しないグローバル変数は無視される可能性があります。たとえば、グローバル変数を使用して関数の実行回数をカウントすると、誤った回数を得る場合があります。
rand
またはrng
の呼び出しが関数に含まれている場合、関数は 1 回目のみ呼び出しを実行すると考えられますが、その後の呼び出しでは乱数ストリームが設定されません。plot
を呼び出しても、すべての反復で Figure が更新されない場合があります。mat
ファイルまたはテキスト ファイルへのデータの保存は、すべての反復で実行されない場合があります。
計算をしない関数が想定したとおりに動作するには、名前と値の引数
Analysis
を"off"
に設定します。
詳細については、静的解析の制限を参照してください。
アルゴリズム
解析
引数 Analysis
が既定の設定である "on"
の場合、fcn2optimexpr
は最も効率的な最適化式の作成を試みるためにいくつかのステップを実行します。アルゴリズムの説明については、fcn2optimexpr アルゴリズムの説明を参照してください。
問題オブジェクトに目的関数や非線形制約関数を含める場合、いくつかの選択肢があります。
オーバーロードを使用します。関数内のすべての演算が最適化変数および式でサポートされる演算の場合は、最適化変数で関数を直接呼び出すことができます。たとえば、
prob.Objective = sin(3*x)*exp(-x-y);
修正されていない関数で、
fcn2optimexpr
を使用します。関数内の演算が 1 つでもサポートされていない場合は、fcn2optimexpr
を呼び出す必要があります。たとえば、関数besselh
はサポートされていないため、この関数を目的関数に含めるには、fcn2optimexpr
を使用する必要があります。prob.Objective = fcn2optimexpr(@(z)besselh(3,z),x);
関数の内部
for
ループが別の関数に表示されるように関数を修正します。そうすることで、静的解析によりループを高速化できます。詳細については、静的解析のための for ループの作成と最適化式の静的解析を参照してください。fcn2optimexpr
で引数Analysis
を"off"
に設定します。そうすることで、fcn2optimexpr
によって関数がブラック ボックスとしてラップされ、操作が高速になります。結果として得られる式は自動微分を利用できないため (自動微分の背景を参照)、ソルバーが有限差分勾配推定のために多くの関数評価を使用する原因となります。
出力サイズ
OutputSize
を指定しない場合に返されるそれぞれの式の出力サイズを確認するために、fcn2optimexpr
は問題変数の各要素について次の点で関数を評価します。
変数の特性 | 評価点 |
---|---|
上限 ub および下限 lb がある | (lb + ub)/2 + ((ub - lb)/2)*eps |
下限はあるが上限がない | lb + max(1,abs(lb))*eps |
上限はあるが下限がない | ub - max(1,abs(ub))*eps |
範囲なし | 1 + eps |
変数が整数として指定される | あらかじめ与えられた点の floor |
評価点によって、関数評価で誤差が発生することがあります。このエラーを回避するには、OutputSize
を指定します。
バージョン履歴
R2019a で導入
MATLAB コマンド
次の MATLAB コマンドに対応するリンクがクリックされました。
コマンドを MATLAB コマンド ウィンドウに入力して実行してください。Web ブラウザーは MATLAB コマンドをサポートしていません。
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)