用约束在2变量函数中查找零

时间:2014-02-19 09:42:31

标签: matlab

我有以下非常长的功能:

J = (((q*(((2*a*(a*q + q^(1/2)))/q^3 + (a^2*(a*q + q^(1/2)))/(q^(5/2)*(a*q^(1/2) + 1)))/(a*q^2 + 1)^2 - ((a*q + q^(1/2))*(a^2/(q^2*(a*q^2 + 1)^2) - (2*a*(a/(q*(a*q^2 + 1)) + 1))/(q*(a*q^2 + 1))))/(q^(1/2)*(a*q^(1/2) + 1))))/2 - ((q*(((a*q + q^(1/2))^2/q^4 + (2*a*(a*q + q^(1/2))^2)/(q^(7/2)*(a*q^(1/2) + 1)))/(a*q^2 + 1)^2 + ((a*q + q^(1/2))*((2*(((a/(q*(a*q^2 + 1)) + 1)*(a*q + q^(1/2)))/q^2 + (a*(a*q + q^(1/2)))/(q^3*(a*q^2 + 1))))/(a*q^2 + 1) - (2*a*(a*q + q^(1/2)))/(q^3*(a*q^2 + 1)^2)))/(q^(1/2)*(a*q^(1/2) + 1))))/3 - ((q^4 + q^2)*((2*a*(a*q^4 + q^2))/(a*q^(1/2) + 1)^2 + (((a^2*q)/(a*q^(1/2) + 1)^2 - (2*a*q^(1/2)*((a*q^(1/2))/(a*q^(1/2) + 1) - 1))/(a*q^(1/2) + 1))*(a*q^4 + q^2))/(q^2*(a*q^2 + 1)) - (a^2*(a*q^4 + q^2))/(q*(a*q^2 + 1)*(a*q^(1/2) + 1)^2)))/3 + ((q + q^(1/2))*(((2*a*(a*q + q^(1/2)))/q^3 + (a^2*(a*q + q^(1/2)))/(q^(5/2)*(a*q^(1/2) + 1)))/(a*q^2 + 1)^2 - ((a*q + q^(1/2))*(a^2/(q^2*(a*q^2 + 1)^2) - (2*a*(a/(q*(a*q^2 + 1)) + 1))/(q*(a*q^2 + 1))))/(q^(1/2)*(a*q^(1/2) + 1))))/3 - (((q + q^(1/2))*(((a*q + q^(1/2))^2/q^4 + (2*a*(a*q + q^(1/2))^2)/(q^(7/2)*(a*q^(1/2) + 1)))/(a*q^2 + 1)^2 + ((a*q + q^(1/2))*((2*(((a/(q*(a*q^2 + 1)) + 1)*(a*q + q^(1/2)))/q^2 + (a*(a*q + q^(1/2)))/(q^3*(a*q^2 + 1))))/(a*q^2 + 1) - (2*a*(a*q + q^(1/2)))/(q^3*(a*q^2 + 1)^2)))/(q^(1/2)*(a*q^(1/2) + 1))))/4 - ((q^4 + q^2)*((2*((a*q^(1/2))/(a*q^(1/2) + 1) - 1)*(a*q^4 + q^2)^2)/(q^(5/2)*(a*q^2 + 1)*(a*q^(1/2) + 1)) - (a*q^4 + q^2)^2/(q*(a*q^(1/2) + 1)^2) + (2*a*(a*q^4 + q^2)^2)/(q^2*(a*q^2 + 1)*(a*q^(1/2) + 1)^2)))/4 - ((2*(a*q + q^(1/2))^3*(q + q^(1/2)))/(5*q^(9/2)*(a*q^2 + 1)^2*(a*q^(1/2) + 1)) + (2*(q^4 + q^2)*(a*q^4 + q^2)^3)/(5*q^3*(a*q^2 + 1)*(a*q^(1/2) + 1)^2))/(a*q^4 + q^2) + (a*q + q^(1/2))^3/(2*q^(7/2)*(a*q^2 + 1)^2*(a*q^(1/2) + 1)))/(a*q^4 + q^2))/(a*q^4 + q^2) + ((q^4 + q^2)*((a^2*q)/(a*q^(1/2) + 1)^2 - 1))/2 + (a^2*(q + q^(1/2)))/(2*q^2*(a*q^2 + 1)^2))/(a*q^4 + q^2) - a^2/(q*(a*q^2 + 1)^2))/(a*q^4 + q^2) + (48*a*q + 24*a^2*q + 48*a*q^(1/2) - 150*a*q^3 - 45*a*q^4 + 160*a*q^5 - 20*a*q^6 - 90*a*q^(5/2) - 60*a*q^7 + 120*a*q^8 - 35*a*q^(9/2) + 2*a*q^11 - 55*a*q^12 - 60*a*q^(11/2) - 60*a*q^14 + 120*a*q^(13/2) - 60*a*q^(17/2) + 2*a*q^(21/2) + 15*a*q^(25/2) + 180*a*q^(27/2) - 15*q^2 + 24*q^(1/2) - 30*q^4 + 40*q^6 - 45*q^(5/2) - 30*q^(7/2) - 9*q^10 + 20*q^(9/2) - 10*q^12 + q^(21/2) + 30*q^(23/2) - 75*a^2*q^3 + 24*a^2*q^(3/2) - 70*a^2*q^5 - 60*a^2*q^6 - 75*a^3*q^5 + 290*a^2*q^7 + 90*a^2*q^8 + 160*a^3*q^7 - 105*a^2*q^(7/2) - 180*a^2*q^9 - 30*a^3*q^8 + 120*a^2*q^10 + 70*a^3*q^9 - 90*a^2*q^(9/2) + a^2*q^11 + 120*a^3*q^10 + 80*a^4*q^9 - 180*a^3*q^11 + 180*a^2*q^(11/2) + 10*a^2*q^13 + 40*a^3*q^12 - 90*a^4*q^11 - 150*a^2*q^14 - 105*a^3*q^(11/2) + 5*a^3*q^13 + 40*a^4*q^12 + 20*a^2*q^(13/2) - 60*a^4*q^13 - 150*a^2*q^16 + 20*a^3*q^15 - 30*a^5*q^13 - 180*a^2*q^(15/2) - 240*a^3*q^16 + 10*a^4*q^15 + 360*a^3*q^(15/2) + 260*a^2*q^(17/2) - 200*a^3*q^18 + 20*a^4*q^17 + 10*a^3*q^(17/2) - 245*a^4*q^18 + 10*a^5*q^17 + 60*a^2*q^(19/2) - 450*a^3*q^(19/2) - 150*a^4*q^20 + 10*a^5*q^19 - 240*a^2*q^(21/2) + 180*a^4*q^(19/2) - 159*a^5*q^20 + 5*a^6*q^19 + 240*a^3*q^(21/2) - 9*a^2*q^(23/2) - 60*a^5*q^22 + 2*a^6*q^21 + 240*a^3*q^(23/2) - 60*a^6*q^22 + a^7*q^21 + 10*a^2*q^(25/2) - 450*a^4*q^(23/2) - 360*a^3*q^(25/2) - 10*a^6*q^24 + 80*a^4*q^(25/2) - 10*a^7*q^24 - 45*a^3*q^(27/2) + 70*a^2*q^(29/2) + 360*a^4*q^(27/2) + 20*a^3*q^(29/2) - 150*a^5*q^(27/2) + 450*a^2*q^(31/2) - 240*a^4*q^(29/2) - 90*a^4*q^(31/2) + 160*a^3*q^(33/2) + 240*a^5*q^(31/2) + 20*a^4*q^(33/2) + 600*a^3*q^(35/2) - 60*a^5*q^(33/2) - 90*a^5*q^(35/2) + 205*a^4*q^(37/2) + 60*a^6*q^(35/2) + 10*a^5*q^(37/2) + 450*a^4*q^(39/2) - 45*a^6*q^(39/2) + 151*a^5*q^(41/2) + 2*a^6*q^(41/2) + 180*a^5*q^(43/2) - 9*a^7*q^(43/2) + 60*a^6*q^(45/2) + 30*a^6*q^(47/2) + 10*a^7*q^(49/2) + 24)/(60*q^(25/2)*(a*q^2 + 1)^7) + (a*q^(1/2)*(a^2/(q*(a*q^2 + 1)^2) - (a*q^(1/2)*((q*(((2*a*(a*q + q^(1/2)))/q^3 + (a^2*(a*q + q^(1/2)))/(q^(5/2)*(a*q^(1/2) + 1)))/(a*q^2 + 1)^2 - ((a*q + q^(1/2))*(a^2/(q^2*(a*q^2 + 1)^2) - (2*a*(a/(q*(a*q^2 + 1)) + 1))/(q*(a*q^2 + 1))))/(q^(1/2)*(a*q^(1/2) + 1))))/2 + ((q^4 + q^2)*((a^2*q)/(a*q^(1/2) + 1)^2 - 1))/2 - (a*q^(1/2)*((q*(((a*q + q^(1/2))^2/q^4 + (2*a*(a*q + q^(1/2))^2)/(q^(7/2)*(a*q^(1/2) + 1)))/(a*q^2 + 1)^2 + ((a*q + q^(1/2))*((2*(((a/(q*(a*q^2 + 1)) + 1)*(a*q + q^(1/2)))/q^2 + (a*(a*q + q^(1/2)))/(q^3*(a*q^2 + 1))))/(a*q^2 + 1) - (2*a*(a*q + q^(1/2)))/(q^3*(a*q^2 + 1)^2)))/(q^(1/2)*(a*q^(1/2) + 1))))/3 - ((q^4 + q^2)*((2*a*(a*q^4 + q^2))/(a*q^(1/2) + 1)^2 + (((a^2*q)/(a*q^(1/2) + 1)^2 - (2*a*q^(1/2)*((a*q^(1/2))/(a*q^(1/2) + 1) - 1))/(a*q^(1/2) + 1))*(a*q^4 + q^2))/(q^2*(a*q^2 + 1)) - (a^2*(a*q^4 + q^2))/(q*(a*q^2 + 1)*(a*q^(1/2) + 1)^2)))/3 + ((q + q^(1/2))*(((2*a*(a*q + q^(1/2)))/q^3 + (a^2*(a*q + q^(1/2)))/(q^(5/2)*(a*q^(1/2) + 1)))/(a*q^2 + 1)^2 - ((a*q + q^(1/2))*(a^2/(q^2*(a*q^2 + 1)^2) - (2*a*(a/(q*(a*q^2 + 1)) + 1))/(q*(a*q^2 + 1))))/(q^(1/2)*(a*q^(1/2) + 1))))/3 - (a*q^(1/2)*(((q + q^(1/2))*(((a*q + q^(1/2))^2/q^4 + (2*a*(a*q + q^(1/2))^2)/(q^(7/2)*(a*q^(1/2) + 1)))/(a*q^2 + 1)^2 + ((a*q + q^(1/2))*((2*(((a/(q*(a*q^2 + 1)) + 1)*(a*q + q^(1/2)))/q^2 + (a*(a*q + q^(1/2)))/(q^3*(a*q^2 + 1))))/(a*q^2 + 1) - (2*a*(a*q + q^(1/2)))/(q^3*(a*q^2 + 1)^2)))/(q^(1/2)*(a*q^(1/2) + 1))))/4 - ((q^4 + q^2)*((2*((a*q^(1/2))/(a*q^(1/2) + 1) - 1)*(a*q^4 + q^2)^2)/(q^(5/2)*(a*q^2 + 1)*(a*q^(1/2) + 1)) - (a*q^4 + q^2)^2/(q*(a*q^(1/2) + 1)^2) + (2*a*(a*q^4 + q^2)^2)/(q^2*(a*q^2 + 1)*(a*q^(1/2) + 1)^2)))/4 - (a*q^(1/2)*((2*(a*q + q^(1/2))^3*(q + q^(1/2)))/(5*q^(9/2)*(a*q^2 + 1)^2*(a*q^(1/2) + 1)) + (2*(q^4 + q^2)*(a*q^4 + q^2)^3)/(5*q^3*(a*q^2 + 1)*(a*q^(1/2) + 1)^2)))/(a*q^(1/2) + 1) + (a*q + q^(1/2))^3/(2*q^(7/2)*(a*q^2 + 1)^2*(a*q^(1/2) + 1))))/(a*q^(1/2) + 1)))/(a*q^(1/2) + 1) + (a^2*(q + q^(1/2)))/(2*q^2*(a*q^2 + 1)^2)))/(a*q^(1/2) + 1)))/(a*q^(1/2) + 1) + (a^2*q^3*(q^2 + 1)*(15*a^2*q^4 - 150*a*q^(1/2) - 230*a^2*q + 80*a^3*q^3 - 20*a^4*q^2 - 130*a^3*q^(3/2) + 70*a^2*q^(5/2) + 30*a^3*q^6 + 80*a^4*q^5 + 15*a^4*q^8 + 10*a^4*q^(7/2) + 61*a^3*q^(9/2) + 10*a^5*q^(11/2) - 18*a^4*q^(13/2) - 9*a^5*q^(17/2) - 30))/(60*(a*q^(1/2) + 1)^7);

我正在尝试找到a的最小值,J(q,a) == 0 q中的[0.7, 1.0]。我正在使用这个for循环:

quals = .7:.01:1;
qual_alpha = zeros(l,2);
counter = 0;
for q1=quals
   counter = counter + 1;
   JJ = subs(J, q, q1);
   alpha = solve(JJ==0, a);
   qual_alpha(counter, 1) = q1;
   qual_alpha(counter, 2) = alpha(1);
end

此循环的结果是:

0.700000000000000   0.183045528954296
0.710000000000000   0.162483326198972
0.720000000000000   0.145352851026052
0.730000000000000   0.131333429004711
0.740000000000000   0.120133229131580
0.750000000000000   0.111484806118576
0.760000000000000   0.105141305801803
0.770000000000000   0.100873334197590
0.780000000000000   0.098466481885027
0.790000000000000   0.097719478374352
0.800000000000000   0.098442928050464
0.810000000000000   0.100458553883238
0.820000000000000   0.103598852082798
0.830000000000000   0.107707044887249
0.840000000000000   0.112637213082333
0.850000000000000   0.118254495901928
0.860000000000000   0.124435262477302
0.870000000000000   0.131067182864133
0.880000000000000   0.138049153736913
0.890000000000000   0.145291060018183
0.900000000000000   0.152713375840150
0.910000000000000   0.160246624505360
0.920000000000000   0.167830727062574
0.930000000000000   0.175414273338365
0.940000000000000   0.182953748981668
0.950000000000000   0.190412748720123
0.960000000000000   0.197761200939535
0.970000000000000   0.204974622969659
0.980000000000000   0.212033420863554
0.990000000000000   0.218922242467939
1.000000000000000   0.225629388430389

由此可以猜出,a占据的最小J == 0必须接近q = 0.79,因为这是右列中的最小数字。

我的问题是:MATLAB中有没有办法将q的这个值计算为8位精度?

1 个答案:

答案 0 :(得分:0)

答案可能不是您所期望的:

J(0.7, -1e8)   %//  positive
J(0.7, -1e10)  %//  negative

J(1.0, -1e8)   %// negative
J(1.0, -1e10)  %// positive

进一步的探索表明,该函数具有渐近线,并且这些符号变化可能是由数值噪声引起的。不过,这是需要注意的事情。

话虽如此:如果你有优化工具箱,你可以使用fmincon

function topLevel

    options = optimset(...
        'AlwaysHonorConstraints', 'bounds',...
        'TolCon', 0);
    sol = fmincon(@obj, [0.8 0.09], ...  %// objective function, initial estimate
        [],[], [],[], ...                %// no linear (in)equality constraints
        [0.7 -inf],[1.0 +inf], ...       %// one variable is bound ('q')
        @nonlcon, options)               %// the nonlinear J(q,a) == 0


    %// You want to find minimum 'a': 
    function cost = obj(x)
        cost = x(2); end

    %// the constraint: J(q,a) == 0
    function [c,ceq] = nonlcon(x)
        c = -1;

        %// NOTE: this is your function, with all 'q' replaced by x(1) 
        %// and all 'a' replaced by x(2)
        ceq = (((x(1).*(((2.*x(2).*(x(2).*x(1) + ...
    end

end

我发现了这个:

sol =  %//    'q'                      'a' 
    7.898719012345190e-001    9.771935760808162e-002

fmincon因为超出了允许的最大功能评估而停止。在这个位置:

>> [c,ceq] = nonlcon(sol) 
c = 
    -1
ceq =
    2.346213501258632e-016

所以仍然存在某些约束违规(虽然太小而无法说明由于数字噪音而)。