How to bound sum of 3 variables in matlab - matlab

I want summation of 3 variables to always equal to a number, in this case 1, but I don't know how to make it happen. For example in the following problem I am trying to find maximum value of "resourceOut/maximumTime" which is a function of x1, x2, x3 but while finding the maximum I want x1, x2, x3 to be equal to 1. (xi is the inital guess value for x1, x2 and R can be any positive number.
function Resource(xi,R)
x = fminsearch(#relations, xi);
x(1)
x(2)
function goldenRatio = relations(xi)
x1 = xi(1);
x3 = xi(2);
x2 = 1 - x1 - x3;
x3 = 1 - x1 - x2;
x1 = 1 - x2 - x3;
R1 = R * x1 * 0.1;
R2 = R * x2 * 0.25;
R3 = R * x3 * 0.50;
T1 = ((((R1)^2)*100)^0.45+1800);
T2 = ((((R2)^2)*100)^0.45+1800);
T3 = ((((R3)^2)*100)^0.45+1800);
elapsedTimes =[T1 T2 T3];
resourceOut = R1 + R2 + R3;
maximumTime = max(elapsedTimes);
goldenRatio = -resourceOut/maximumTime;
end
end

Related

How can I use Symbolic in MATLAB to solve an equation that are a division?

Assume that you have these symbolic variables.
ddy1 = sym('ddy1');
ddy2 = sym('ddy2');
dy1 = sym('dy1');
dy2 = sym('dy2');
y1 = sym('y1');
y2 = sym('y2');
k1 = sym('k1');
k2 = sym('k2');
b1 = sym('b1');
b2 = sym('b2');
m1 = sym('m1');
m2 = sym('m2');
u = sym('u');
And these equations:
eq1 = m1*ddy2 == k1*(y2 - y1) + b1*(dy2 - dy1)
eq2 = m2*ddy2 + k1*(y2 - y1) + b1*(dy2 - dy1) == k2*(u - y2)
Your goal is to find a solution
y2/u
To begin with, let's eliminate y1
eq3 = solve(eq1, y1) == solve(eq2, y1)
And now solve for y2/u
eq4 = solve(eq3, y2/u)
But that won't work! What should I do to get the division solution where y2 is the numerator and the u is the demoninator?

Optimisation using Golden Search Method with Matlab

% Power output
power_output = MF_t.*difference.*e;
% POWER OUTPUT OPTIMIZATION USING - GOLDEN SEARCH METHOD
x_lower = 0.2;
x_upper = 1.4;
h = (x_upper - x_lower);
r = (sqrt(5) - 1)*0.5;
x2 = x_lower + (1+r)*h;
x3 = x_upper - (1+r)*h;
tol = 0.05;
count = 1;
while h>-tol
f2 = -power_output(x2)
f3 = -power_output(x3)
if f3<f2
x_lower = x2;
x_upper = x_upper;
h = (x_upper - x_lower);
x2 = x3;
x3 = x_upper - (1-r)*h;
elseif f2<f3
x_lower = x_lower;
x_upper = x3;
h = (x_upper - x_lower);
x3 = x2;
x2 = x_lower + (1-r)*h;
else
x_lower = x2;
x_upper = x3;
h = (x_upper - x_lower);
x2 = x_lower + (1+r)*h;
x3 = x_upper - (1+r)*h;
end
interval = x_upper - x_lower;
count = count + 1
if count > 100
break
end
end
answer = (x_upper + x_lower)/2
value = fanswer
Im trying to run this code, it's telling me that there is an error as my arrays f2 and f3 as "Array indices must be positive integers or logical values". I'm wondering would anyone know if taking the absolute values of my arrays will make my optimisation incorrect
The error message is quite informative in this case. You are trying to access the x2th element of f2. A quick calculation shows that on the first iteration x2 = 2.14. It is not possible to take the 2.14th element of f2 because this is is not an integer, and taking the absolute value will not help.
x2 is not an index, it is a value. On each iteration, the Golden Ratio search requires you to actually evaluate power_output with whatever variable set to x2. So, it looks like you need to do this calculation power_output = MF_t.*difference.*e with x=x2.

"Solve" command with a vector in matlab

I have a problem with the equation shown below. I want to enter a vector in t2 and find the roots of the equation from different values in t2.
t2=[10:10:100]
syms x
p = x^3 + 3*x - t2;
R = solve(p,x)
R1 = vpa(R)
Easy! Don't use syms and use the general formula:
t2 = [10:10:100];
%p = x^3 + 3*x - t2;
a = 1;
b = 0;
c = 3;
d = -t2;
D0 = b*b - 3*a*c;
D1 = 2*b^3 - 9*a*b*c + 27*a^2*d;
C = ((D1+sqrt(D1.^2 - 4*D0.^3))/2).^(1/3);
C1 = C*1;
C2 = C*(-1-sqrt(3)*1i)/2;
C3 = C*(-1+sqrt(3)*1i)/2;
f = -1/(3*a);
x1 = f*(b + C1 + D0./C1);
x2 = f*(b + C2 + D0./C2);
x3 = f*(b + C3 + D0./C3);
Since b = 0, you can simplify this a bit:
% ... polynomial is the same
D0 = -3*a*c;
D1 = 27*a^2*d;
% ... the different C's are the same
f = -1/(3*a);
x1 = f*(C1 + D0./C1);
x2 = f*(C2 + D0./C2);
x3 = f*(C3 + D0./C3);
Trial>> syms x p
Trial>> EQUS = p == x^3 + 3*x - t2
It is unknown that you want to solve an equation or a system.
Suppose that you want to solve a system.
Trial>> solx = solve(Eqns,x)
But, I do not think you can find roots.
You can solve one equation.
Trial>> solx = solve(Eqns(3),x)
As far as I know, Maple can do this batter.
In general, loops should be avoided, but this is the only solution that hit my brain right now.
t2=[10:10:100];
pp=repmat([1,0,3,0],[10,1]);
pp(:,4)=-t2;
for i=1:10
R(i,:) =roots(pp(i,:))';
end

The Fastest Method of Solving System of Non-linear Equations in MATLAB

Assume we have three equations:
eq1 = x1 + (x1 - x2) * t - X == 0;
eq2 = z1 + (z1 - z2) * t - Z == 0;
eq3 = ((X-x1)/a)^2 + ((Z-z1)/b)^2 - 1 == 0;
while six of known variables are:
a = 42 ;
b = 12 ;
x1 = 316190;
z1 = 234070;
x2 = 316190;
z2 = 234070;
So we are looking for three unknown variables that are:
X , Z and t
I wrote two method to solve it. But, since I need to run these code for 5.7 million data, it become really slow.
Method one (using "solve"):
tic
S = solve( eq1 , eq2 , eq3 , X , Z , t ,...
'ReturnConditions', true, 'Real', true);
toc
X = double(S.X(1))
Z = double(S.Z(1))
t = double(S.t(1))
results of method one:
X = 316190;
Z = 234060;
t = -2.9280;
Elapsed time is 0.770429 seconds.
Method two (using "fsolve"):
coeffs = [a,b,x1,x2,z1,z2]; % Known parameters
x0 = [ x2 ; z2 ; 1 ].'; % Initial values for iterations
f_d = #(x0) myfunc(x0,coeffs); % f_d considers x0 as variables
options = optimoptions('fsolve','Display','none');
tic
M = fsolve(f_d,x0,options);
toc
results of method two:
X = 316190; % X = M(1)
Z = 234060; % Z = M(2)
t = -2.9280; % t = M(3)
Elapsed time is 0.014 seconds.
Although, the second method is faster, but it still needs to be improved. Please let me know if you have a better solution for that. Thanks
* extra information:
if you are interested to know what those 3 equations are, the first two are equations of a line in 2D and the third equation is an ellipse equation. I need to find the intersection of the line with the ellipse. Obviously, we have two points as result. But, let's forget about the second answer for simplicity.
My suggestion it's to use the second approce,which it's the recommended by matlab for nonlinear equation system.
Declare a M-function
function Y=mysistem(X)
%X(1) = X
%X(2) = t
%X(3) = Z
a = 42 ;
b = 12 ;
x1 = 316190;
z1 = 234070;
x2 = 316190;
z2 = 234070;
Y(1,1) = x1 + (x1 - x2) * X(2) - X(1);
Y(2,1) = z1 + (z1 - z2) * X(2) - X(3);
Y(3,1) = ((X-x1)/a)^2 + ((Z-z1)/b)^2 - 1;
end
Then for solving use
x0 = [ x2 , z2 , 1 ];
M = fsolve(#mysistem,x0,options);
If you may want to reduce the default precision by changing StepTolerance (default 1e-6).
Also for more increare you may want to use the jacobian matrix for greater efficencies.
For more reference take a look in official documentation:
fsolve Nonlinear Equations with Analytic Jacobian
Basically giving the solver the Jacobian matrix of the system(and special options) you can increase method efficency.

Setting Stop Conditions for Iteration Loop in Matlab

I am trying to solve some equations using a while loop. I have a known and fixed output. Workflow is as follows:
P = 100; %Desired output
x = 1; %Initial guess
while abs(something) > 1e-6
x1 = (25 * x)/2
x2 = 10x - x1
x3 = 20x - (x - x1 - x2)*2
x4 = (x - x1 - x2 -x3)*12
x5 = (x - x1 - x2 -x3) * 10 + x4
P1 = 2005x3
P2 = 1500x5
Pnew = P1 + P2
end
I was hoping to calculate x1, x2, ..., x5 and stop looping when the condition P = Pnew is reached. Due to my modest knowledge of MATLAB any help would be appreciated.
Many thanks in advance.
APPENDIX: Perhaps i didn't explained well. My goal was to stop looping when the condition P = Pnew is achieved. I have a known value P and initial value of x. Pnew should be generated through a given series of equations. When the condition is met x, x1, x2, ..., x5 will have their values. So x is not only the initial value for calculating other unknowns (x1, x2, ..., x5). I tried to modify it but got NaN Pnew, P1, error and inf for P2, x, ...
P = 100; %Desired output
x = 1; %Initial guess
Pnew = P + 1
while abs(P - Pnew) > 1e-6
x1 = (25 * x)/2;
x2 = 10*x - x1;
x3 = 20*x - (x - x1 - x2)*2;
x4 = (x - x1 - x2 -x3)*12;
x5 = (x - x1 - x2 -x3) * 10 + x4
P1 = 2005 * x3;
P2 = 150 * x5;
Pnew = P1 - P2;
error = abs(P - Pnew);
x_new = x - .001 * error;
x = x_new;
end
Your code will error out if you don't use * to multiply. I have fixed the code below for you. The something you are looking for is P - Pnew. This is because you are trying to find the difference and making sure it is over 1e-6 to continue the loop.
Since you need Pnew, you should also do an initial calculation for it. You should note that your calculation doesn't actually make Pnew converge to P.
P = 100; %Desired output
x = 1; %Initial guess
x1 = ( 25 * x ) / 2
x2 = 10 * x - x1
x3 = 20 * x - ( x - x1 - x2 ) * 2
x4 = ( x - x1 - x2 -x3 ) * 12
x5 = ( x - x1 - x2 -x3 ) * 10 + x4
P1 = 2005 * x3
P2 = 1500 * x5
Pnew = P1 + P2
while abs( P - Pnew ) > 1e-6
x1 = ( 25 * x ) / 2
x2 = 10 * x - x1
x3 = 20 * x - ( x - x1 - x2 ) * 2
x4 = ( x - x1 - x2 -x3 ) * 12
x5 = ( x - x1 - x2 -x3 ) * 10 + x4
P1 = 2005 * x3
P2 = 1500 * x5
Pnew = P1 + P2
end
You should probably also put ; to terminate the line to suppress the output of the calculation.
A do-while loop here would work, but Matlab doesn't have one. You can use encapsulation to hide the code duplication or use a for loop as follows as well.
P = 100; %Desired output
x = 1; %Initial guess
for i = 1:Inf
x1 = ( 25 * x ) / 2
x2 = 10 * x - x1
x3 = 20 * x - ( x - x1 - x2 ) * 2
x4 = ( x - x1 - x2 -x3 ) * 12
x5 = ( x - x1 - x2 -x3 ) * 10 + x4
P1 = 2005 * x3
P2 = 1500 * x5
Pnew = P1 + P2
if abs( P - Pnew ) < 1e-6
break;
end
end
To set a predefined iteration termination in case you have an infinite loop, you can replace i = 1:Inf with i = 1:iterMax where iterMax is the number of max iterations.
Usually in numeric calculations one does not test for equality as the computers cannot distinguish all real numbers. Your condition is actually satisfying for something == P - Pnew
In code it would look like this
P = 100; % Desired output
x = 1; % Initial guess
Pnew = P + 1; % Something far off, just to get through the first check
MAX_ITERATION_COUNT = 10000; % a reasonable upper bound to your loop
loopCount = 0;
while abs(P - Pnew) > 1e-6 && loopCount < MAX_ITERATION_COUNT
loopCount = loopCount + 1;
x1 = (25 * x) / 2;
x2 = 10 * x - x1;
x3 = 20 * x - (x - x1 - x2) * 2;
x4 = (x - x1 - x2 - x3) * 12;
x5 = (x - x1 - x2 - x3) * 10 + x4;
P1 = 2005 * x3;
P2 = 1500 * x5;
Pnew = P1 + P2;
end
This should work for your problem.
EDIT: I added a loop counter in case you're loop does not finish regularly.