用MATLAB中的三角函数最小化方程和约束

时间:2019-06-03 12:57:10

标签: matlab optimization

我有一个优化脚本(如下),该脚本给了我错误:

  

“未定义的函数'cos',用于类型的输入参数   'optim.problemdef.OptimizationExpression'。”

只是为了确保cos函数没有问题,我将cos中的confn2更改为sin,然后得到:

  

“未定义函数'sin'用于类型的输入参数   'optim.problemdef.OptimizationExpression'。”

但是,如果我将cos(pi)放在命令窗口中,则会得到-1。

我之前已经成功运行了该脚本,除了sigma(出现在cos()中)不是优化变量之外,因此对trig函数进行了评估,使结果线性。对于具有三角函数的约束,这种类型的优化脚本难道难道难道吗? MATLAB中有替代方案吗?

k1 = optimvar('k1', 'LowerBound', -3, 'UpperBound', 3);
k2 = optimvar('k2', 'LowerBound', -3, 'UpperBound', 3);
f = optimvar('f', 'LowerBound', -3, 'UpperBound', 3);
sigma = optimvar('sigma', 'LowerBound', 0, 'UpperBound', 6.28318530718);

obj = fcn2optimexpr(@eq1, k1, k2, f, sigma);

confn1 = obj == 0;
confn2 = -0.9313129901097519*k1 - 1.4693755421886672*k2 - 0.18532000686683578*f*cos((1/2)*(-0.372795 + 2*sigma)) + 0.9826782255931369*f*sin((1/2)*(-0.372795 + 2*sigma)) <= 0;

prob = optimproblem('Objective', obj);

prob.Constraints.confn1 = confn1;
prob.Constraints.confn2 = confn2;

k0.k1 = 0;
k0.k2 = 0;
k0.f = 0;
k0.sigma = 0;

[sol, fval, exitflag, output] = solve(prob, k0)

function f1 = eq1(k1, k2, f, sigma)
f1 = 0.01308996938995749 - 0.3642198710296203*k1 - 0.6784053942919677*k2 + 0.37064001373367156*f*sin((1/2)*(-0.372795 + 2*sigma));
end

2 个答案:

答案 0 :(得分:1)

您可以改用fmincon,也可以在其中指定目标和约束。这样,cos函数将在每次迭代中进行数值评估,而不会使用optim.problemdef.OptimizationExpression类型进行调用。

您确实需要将变量指定为向量(初始猜测x0,下限lb,上限ub),请参见代码中的注释。

% x0 = [k1 k2 f sigma];
x0 = [0 0 0 0];
lb = [-3 -3 -3 0];
ub = [3 3 3 2*pi];

% options
options = optimoptions('fmincon','Display','iter', 'ConstraintTolerance', 1e-12);

% optimization
x = fmincon(@objfun,x0,[],[],[],[],lb,ub,@constrfun, options)

% check constraints to check fulfilment of constraints
[c, ceq] = constrfun(x)

您的对象函数必须接受单个向量x,可以将其“解包”为各个变量。

function f1 = objfun(x)
    k1 = x(1);
    k2 = x(2); 
    f = x(3);
    sigma = x(4);
    f1 = 0.01308996938995749 - 0.3642198710296203*k1 - 0.6784053942919677*k2 + 0.37064001373367156*f*sin((1/2)*(-0.372795 + 2*sigma));
end

必须在约束函数中定义约束,该约束函数返回cceq,其中c是不等式约束c(x) <= 0,而ceq是不等式约束等式约束ceq(x) = 0

function [c,ceq] = constrfun(x)
    k1 = x(1);
    k2 = x(2); 
    f = x(3);
    sigma = x(4);
    c = -0.9313129901097519*k1 - 1.4693755421886672*k2 - 0.18532000686683578*f*cos((1/2)*(-0.372795 + 2*sigma)) + 0.9826782255931369*f*sin((1/2)*(-0.372795 + 2*sigma));
    ceq = objfun(x);
end

答案 1 :(得分:0)

由于confn2中的cos(sigma),您需要使用fcn2optimexpr。从R2019a版本开始,仅允许多项式的比率表示优化变量。

k1 = optimvar('k1', 'LowerBound', -3, 'UpperBound', 3);
k2 = optimvar('k2', 'LowerBound', -3, 'UpperBound', 3);
f = optimvar('f', 'LowerBound', -3, 'UpperBound', 3);
sigma = optimvar('sigma', 'LowerBound', 0, 'UpperBound', 6.28318530718);

obj = fcn2optimexpr(@eq1, k1, k2, f, sigma);
c2 = fcn2optimexpr(@conexpr2, k1, k2, f, sigma);

confn1 = obj == 0;
confn2 = c2 <= 0;

prob = optimproblem('Objective', obj);

prob.Constraints.confn1 = confn1;
prob.Constraints.confn2 = confn2;

k0.k1 = 0;
k0.k2 = 0;
k0.f = 0;
k0.sigma = 0;

options = optimoptions(prob,'Display','iter', 'ConstraintTolerance', 1e-12);
[sol, fval, exitflag, output] = solve(prob, k0, 'Options',options)

objval = evaluate(obj,sol)
c2val = evaluate(c2,sol)


function f1 = eq1(k1, k2, f, sigma)
f1 = 0.01308996938995749 - 0.3642198710296203*k1 - 0.6784053942919677*k2 + 0.37064001373367156*f*sin((1/2)*(-0.372795 + 2*sigma));
end

function c2 = conexpr2(k1, k2, f, sigma)
c2 = -0.9313129901097519*k1 - 1.4693755421886672*k2 - 0.18532000686683578*f*cos((1/2)*(-0.372795 + 2*sigma)) + 0.9826782255931369*f*sin((1/2)*(-0.372795 + 2*sigma));
end

正如@rinkert指出的那样,您两次使用物镜。不必具有目标功能。您可能会遇到仅具有约束条件的优化问题。

k1 = optimvar('k1', 'LowerBound', -3, 'UpperBound', 3);
k2 = optimvar('k2', 'LowerBound', -3, 'UpperBound', 3);
f = optimvar('f', 'LowerBound', -3, 'UpperBound', 3);
sigma = optimvar('sigma', 'LowerBound', 0, 'UpperBound', 6.28318530718);

c1 = fcn2optimexpr(@eq1, k1, k2, f, sigma);
c2 = fcn2optimexpr(@conexpr2, k1, k2, f, sigma);

confn1 = c1 == 0;
confn2 = c2 <= 0;

prob = optimproblem();

prob.Constraints.confn1 = confn1;
prob.Constraints.confn2 = confn2;

k0.k1 = 0;
k0.k2 = 0;
k0.f = 0;
k0.sigma = 0;

options = optimoptions(prob,'Display','iter', 'ConstraintTolerance', 1e-12);
[sol, fval, exitflag, output] = solve(prob, k0, 'Options',options)

c1val = evaluate(c1,sol)
c2val = evaluate(c2,sol)


function f1 = eq1(k1, k2, f, sigma)
f1 = 0.01308996938995749 - 0.3642198710296203*k1 - 0.6784053942919677*k2 + 0.37064001373367156*f*sin((1/2)*(-0.372795 + 2*sigma));
end

function c2 = conexpr2(k1, k2, f, sigma)
c2 = -0.9313129901097519*k1 - 1.4693755421886672*k2 - 0.18532000686683578*f*cos((1/2)*(-0.372795 + 2*sigma)) + 0.9826782255931369*f*sin((1/2)*(-0.372795 + 2*sigma));
end