Contour plot in matlab - takes forever - matlab

I am trying do a contour plot in matlab. However, the syntax seems to be correct but the matlab is taking forever to plot this as the matrix could be really large.
Please suggest what can I do about this.
Below is my code:
s = 10000000;
eta_gamma = zeros(s/10000);
for g1= 1:10000:s
for g2 = 1:10000:s
eta_gamma(g1,g2) = floor((1000000000 - g1 - g2)/ (200000*(1 + floor(-0.001 + 20000*(0.001 + (0.1 + 0.9/ (1 + (-1000000 + 5000000* lambertw(power(exp(1), 0.2 + g1/5.E6)/5.))/1.E6))/ 100.))) + 75000*(1 + floor(-0.001 + 20000*(0.002 + (0.2 + 0.8/ (1 + (-8000000 + 4000000* lambertw(2* power(exp(1),2 + g2/4.E6)))/8.E6)) /200.)))));
end
end
figure
contour(eta_gamma)

It seems that the bottleneck is because of the two heavy nested loops there. The solution is of course vectorization with the intention to remove those two loops. One of the best tools for vectorization, bsxfun could be used here. The final vectorized implementation listed next ran in 1.323403 seconds at my end, whereas the original nested loopy version was taking forever and using up a lot of memory. Here's the code -
%// Input parameter
s = 10000000;
%// Define 1D arrays corresponding to each nested loop
G1 = 1:10000:s;
G2 = 1:10000:s;
%// Perform the calculations in a vectorized manner in three parts:
%// Part1: Do vectorized "1000000000 - g1 - g2"
p1 = 1000000000 - bsxfun(#plus,G1,G2.'); %//'
%// Part2: Do vectorized operations for everything involving G1 (nested loop-I)
p2 = 200000*(1 + floor(-0.001 + 20000*(0.001 + (0.1 + 0.9./ (1 + (-1000000 + ...
5000000* lambertw(power(exp(1), 0.2 + G1/5.E6)/5.))./1.E6))/ 100.)));
%// Part3: Do vectorized operations for everything involving G2 (nested loop-II)
p3 = 75000*(1 + floor(-0.001 + 20000*(0.002 + (0.2 + 0.8./(1 + (-8000000 + ...
4000000* lambertw(2* power(exp(1),2 + G2/4.E6)))/8.E6)) /200.)));
%// Finally combine all parts into a 2D array output, which would be eta_gamma
eta_gamma_vectorized = floor(p1./bsxfun(#plus,p2,p3.')); %//'
%// Plot results
figure, contour(eta_gamma_vectorized)
Here's the plot result -

Related

Gauss-Legendre Matlab: How to use Newton method to approximate k_1 and k_2?

Recently as a project I have been working on a program in matlab designed to implement the Gauss-Legendre order 4 method of solving an IVP. Numerical analysis- and coding in particular- is somewhat of a weakness of mine, and thus it has been rather tough going. I used the explicit Euler method to initially seed the method, but I've been stuck for a very long time on how to use the Newton method to get closer values of k1 and k2.
Thusfar, my code looks as follows:
`
%Gauss-Butcher Order 4
function[y] = GBOF(f,fprime,y_0,maxit,ertol)
A = [1/4,1/4-sqrt(3)/6;1/4+sqrt(3)/6,1/4];
h = [1,0,0,0,0,0,0,0,0,0,0,0,0];
t = [0,0,0,0,0,0,0,0,0,0,0,0,0];
for n = 1:12
h(n+1) = 1/(2^n);
t(n+1) = t(n)+h(n);
end
y = zeros(size(t));
y(1) = y_0;
niter = 1;
%Declaration of Variables
for i = 1:12
k = f(y(i));
y1approx = y(i) + ((1/2-sqrt(3))*h(i)*k);
y2approx = y(i) + ((1/2+sqrt(3))*h(i)*k);
k1 = f(y1approx);
k2 = f(y2approx);
%Initial guess for newton seeding
errorFunc =#(k1,k2) [k1-f(y(i) +A(1,1)*k1+A(1,2)*k2*h(i)); k2-f(y(i)+A(2,1)*k1+A(2,2)*k2*h(i))];
error = errorFunc(k1,k2);
%Function for error and creation of error variable
while norm(error) > ertol && niter < maxit
niter = niter + 1;
** k1 = k1-f(k1)/fprime(k1);
k2 = k2-f(k2)/fprime(k2);
** error = errorFunc(k1,k2);
%Newton Raphston for estimating K1 and K2
end
y(i+1) = y(i) +(h(i)*(k1+k2)/2);
%Creation of next
end
disp(t);
`
The part of the code I believe is causing this to fail is highlighted. When I enter in a basic ivp (i.e. y' = y, y(0) =1), I get the output
Any input on how I could go about fixing this would be much appreciated.
Thank you.
I have tried replacing the k1s and k2s in the problem with the values used in the formula extrapolated from the butcher tableau, but nothing changed. I can't think of any other ways to tackle this issue.
The implicit system you have to solve is
k1 = f(y + h*(a11*k1 + a12*k2) )
k2 = f(y + h*(a21*k1 + a22*k2) )
This is also correct in your residual function errorFunc.
The naive way is just to iterate this system, like any other fixed-point iteration.
This system has a linearization rel. h at the base point y
k1 = f(y) + h*f'(y)*(a11*k1 + a12*k2) + O(h^2)
k2 = f(y) + h*f'(y)*(a21*k1 + a22*k2) + O(h^2)
Seen as simple iteration, the contraction factor is O(h), so if h is small enough, the factor is smaller than 1 and thus convergence is sure, increasing the order of h in the residual by 1 in each step. So with 6 iterations the error in the implicit system is O(h^6), which is one order smaller than the local truncation error.
One can reduce the number of iterations if k1,k2 start with some higher-order estimates, not just with k1=k2=f(y).
One can reduce the right side residual by removing the terms that are linear in h (on both sides of course).
k1 - h*f'(y)*(a11*k1 + a12*k2) = f(y + h*(a11*k1 + a12*k2) ) - h*f'(y)*(a11*k1 + a12*k2)
k2 - h*f'(y)*(a21*k1 + a22*k2) = f(y + h*(a21*k1 + a22*k2) ) - h*f'(y)*(a21*k1 + a22*k2)
The right side is evaluated at the current values, the left side is a linear system for the new values. So
K = K - solve(M, rhs)
with
K = [ k1; k2]
M = [ 1 - h*f'(y)*a11, -h*f'(y)*a12 ; -h*f'(y)*a21, 1 - h*f'(y)*a22 ]
= I - h*f'(y)*A
rhs = [ k1 - f(y + h*(a11*k1 + a12*k2) ); k2 - f(y + h*(a12*k1 + a12*k2) )
= K - f(Y)
where
Y = y+h*A*K
This should, probably, work for scalar equations, for systems this involves Kronecker products of matrices and vectors.
As the linear part is taken out of the residual, the contraction factor in this new fixed-point iteration is O(h^2), possibly with smaller constants, so it converges faster and, it has been argued, for larger step sizes.
What you have in the code regarding the implicit method step shows the steps of the algorithm in the right order, but with wrong arguments in the function calls.
What you do with h is not recognizable. One could guess that the task is to explore the results of the method for a collection of step sizes. This means that the h for each integration run is constant, halving the step size and increasing the step number for the next integration run.

Generating vector elements with a random-based command, Matlab

I'm trying to construct a vector with n-elements. I want each of my elements, x_5, to be defined as such :
x_5 = (x_1)^2 + (x_2)^2 + (x_3)^2 + (x_4)^2
where each x_i = randn. This is the script I am using right now :
x_1 = randn;
x_2 = randn;
x_3 = randn;
x_4 = randn;
for x_5 = (x_1)^2 + (x_2)^2 + (x_3)^2 + (x_4)^2
n=1000000
end
v=repelem(x_5,1000000);
I want to implement a loop command, so that each x_5 corresponds to a specific operation for x_5. That is, each x_5 in my vector is generated by my algorithm individually. With this script, x_5 is generated only once, and my vector is then filled with 1.000.000 copies of this same result. Instead, I would like to make 1.000.000 calculations for x_5, and then fill my vector with these results.
Other suggestions besides making
for x_5 = (x_1)^2 + (x_2)^2 + (x_3)^2 + (x_4)^2
n=1000000
end
work are also welcome. I'm not sure whether a loop command is the best choice here, but I would like to learn about it with this problem.
Your loop iterates only once and the numbers are generated only once. You have to move the logic into the loop:
v = zeros(1, 1000000);
parfor n = 1:length(v)
v(n) = sum(randn(1, 4).^2);
end
You can reduce the code to
v = arrayfun(#(x) sum(randn(1, 4).^2), zeros(1, 1000000));

Solving optimal control problems, ode45 vs fmincon

Good afternoon!
First things first, I looked for similar questions for a while, but (probably because of my inexperience) I've found nothing similar to what I'm going to ask.
I'm using matlab for the first time to solve this kind of problems, so I'm not sure of what to do. A brief explenation:
I'm doing a project for my Optimal Control course: I have to replicate the results of a paper about employment, and I'm stuck with the plots. I have the following data:
five variable functions (U(t), T(t), R(t), V1(t) and V2(t))
four control functions(u1(t), u2(t), u3(t), u4(t))
constraints on the control variables (each u must be between 0 and 1)
initial values for U, T, R, V1 and V2 (in t=0, in particular V1 and V2 are constant over time)
final values for the λ coefficients in the hamiltonian
(note: for the controls, I've already found the optimal expression, which is in this form: ui = min{1, max{0,"expression"}}. If needed, I can give also the four expressions, neglected to
synthesize a little)
Under professor's suggestions, I've tried to use fmincon, that theoretically should give me directly the information that I need to plot some result using only the cost function of the problem. But in this case I have some issues involving time in the calculations. Below, the code that I used for fmincon:
syms u
%note: u(5) corresponds to U(t), but this is the only way I've found to get
%a result, the other u(i) are in ascending order (u(1) = u1 and so on...)
g = #(u) 30*u(5) + (20/2)*(u(1))^2 + (20/2)*(u(2))^2 + (10/2)*(u(3))^2 + (40/2)*(u(4))^2;
%initial guesses
u0 = [0 0 0 0 100000]; %
A = [];
b = [];
Aeq = [];
beq = [];
lb = 0.0 * ones(1,2,3,4);
ub = 1.0 * ones(1,2,3,4);
[x,fval,output,lambda] = fmincon(g, u0, A, b, Aeq, beq, lb, ub);
Whit this code, i get (obviously) only one value for each variable as result, and since I've not found any method to involve time, as I said before, I start looking for other solving strategies.
I found that ode45 is a differential equation solver that has the "time iteration" already included in the algorithm, so I tried to write the code to get it work with my problem.
I took all the equations from the paper and put them in a vector as shown in the mathworks examples, and this is my matlab file:
syms u1(t) u2(t) u3(t) u4(t)
syms U(t) T(t) R(t) V1(t) V2(t)
syms lambda_u lambda_t lambda_r lambda_v1 lambda_v2
%all the parameters provided by the paper
delta = 500;
alpha1 = 0.004;
alpha2 = 0.005;
alpha3 = 0.006;
gamma1 = 0.001;
gamma2 = 0.002;
phi1 = 0.22;
phi2 = 0.20;
delta1 = 0.09;
delta2 = 0.05;
k1 = 0.000003;
k2 = 0.000002;
k3 = 0.0000045;
%these two variable are set constant
V1 = 200;
V2 = 100;
%weight values for the cost function (only A1 is used in this case, but I left them all since the unused ones are irrelevant)
A1 = 30;
A2 = 20;
A3 = 20;
A4 = 10;
A5 = 40;
%ordering the unknowns in an array
x = [U T R u1 u2 u3 u4];
%initial conditions, ordered as the x vector (for the ui are guesses)
y0 = [100000 2000 1000 0 0 0 0];
%system set up
f = #(t,x) [delta - (1 + x(4))*k1*x(1)*V1 - (1 + x(5))*k2*x(1)*V2 - alpha1*x(1) + gamma1*x(2) + gamma2*x(3);...
(1 + x(4))*k1*x(1)*V1 - k3*x(2)*V2 - alpha2*x(2) - gamma1*x(2);...
(1 + x(5))*k2*x(1)*V2 - alpha3*x(3) - gamma2*x(3) + k3*x(2)*V2;...
alpha2*x(2) + gamma1*x(2) + (1 + x(6))*phi1*x(1) + k3*x(2)*V2 - delta1*V1;...
alpha3*x(3) + gamma2*x(3) + (1 + x(7))*phi2*x(1) - delta2*V2;...
-A1 + (1 + x(4))*k1*V1*(lambda_u - lambda_t) + (1 + x(5))*k2*V2*(lambda_u - lambda_r) + lambda_u*alpha1 - lambda_v1*(1 + x(6))*phi1 - lambda_v2*(1 + x(7))*phi2;...
-lambda_u*gamma1 + (alpha2 + gamma1)*(lambda_t - lambda_v1) + k3*V2*(lambda_t - lambda_r - lambda_v1);...
-lambda_u*gamma2 + (alpha3 + gamma2)*(lambda_r - lambda_v2);...
(1 + x(4))*k1*x(1)*(lambda_u - lambda_t) + lambda_v1*delta1;...
(1 + x(5))*k2*x(1)*(lambda_u -lambda_r) + k3*x(2)*(lambda_t - lambda_r - lambda_v1) + lambda_v2*delta2];
%using ode45 to solve over the chosen time interval
[t,xa] = ode45(f,[0 10],y0);
With this code, I get the following error:
Error using odearguments (line 95)
#(T,X)[DELTA-(1+X(4))*K1*X(1)*V1-(1+X(5))*K2*X(1)*V2-ALPHA1*X(1)+GAMMA1*X(2)+GAMMA2*X(3);(1+X(4))*K1*X(1)*V1-K3*X(2)*V2-ALPHA2*X(2)-GAMMA1*X(2);(1+X(5))*K2*X(1)*V2-ALPHA3*X(3)-GAMMA2*X(3)+K3*X(2)*V2;ALPHA2*X(2)+GAMMA1*X(2)+(1+X(6))*PHI1*X(1)+K3*X(2)*V2-DELTA1*V1;ALPHA3*X(3)+GAMMA2*X(3)+(1+X(7))*PHI2*X(1)-DELTA2*V2;-A1+(1+X(4))*K1*V1*(LAMBDA_U-LAMBDA_T)+(1+X(5))*K2*V2*(LAMBDA_U-LAMBDA_R)+LAMBDA_U*ALPHA1-LAMBDA_V1*(1+X(6))*PHI1-LAMBDA_V2*(1+X(7))*PHI2;-LAMBDA_U*GAMMA1+(ALPHA2+GAMMA1)*(LAMBDA_T-LAMBDA_V1)+K3*V2*(LAMBDA_T-LAMBDA_R-LAMBDA_V1);-LAMBDA_U*GAMMA2+(ALPHA3+GAMMA2)*(LAMBDA_R-LAMBDA_V2);(1+X(4))*K1*X(1)*(LAMBDA_U-LAMBDA_T)+LAMBDA_V1*DELTA1;(1+X(5))*K2*X(1)*(LAMBDA_U-LAMBDA_R)+K3*X(2)*(LAMBDA_T-LAMBDA_R-LAMBDA_V1)+LAMBDA_V2*DELTA2]
returns a vector of length 10, but the length of initial conditions vector is 7. The vector returned by
#(T,X)[DELTA-(1+X(4))*K1*X(1)*V1-(1+X(5))*K2*X(1)*V2-ALPHA1*X(1)+GAMMA1*X(2)+GAMMA2*X(3);(1+X(4))*K1*X(1)*V1-K3*X(2)*V2-ALPHA2*X(2)-GAMMA1*X(2);(1+X(5))*K2*X(1)*V2-ALPHA3*X(3)-GAMMA2*X(3)+K3*X(2)*V2;ALPHA2*X(2)+GAMMA1*X(2)+(1+X(6))*PHI1*X(1)+K3*X(2)*V2-DELTA1*V1;ALPHA3*X(3)+GAMMA2*X(3)+(1+X(7))*PHI2*X(1)-DELTA2*V2;-A1+(1+X(4))*K1*V1*(LAMBDA_U-LAMBDA_T)+(1+X(5))*K2*V2*(LAMBDA_U-LAMBDA_R)+LAMBDA_U*ALPHA1-LAMBDA_V1*(1+X(6))*PHI1-LAMBDA_V2*(1+X(7))*PHI2;-LAMBDA_U*GAMMA1+(ALPHA2+GAMMA1)*(LAMBDA_T-LAMBDA_V1)+K3*V2*(LAMBDA_T-LAMBDA_R-LAMBDA_V1);-LAMBDA_U*GAMMA2+(ALPHA3+GAMMA2)*(LAMBDA_R-LAMBDA_V2);(1+X(4))*K1*X(1)*(LAMBDA_U-LAMBDA_T)+LAMBDA_V1*DELTA1;(1+X(5))*K2*X(1)*(LAMBDA_U-LAMBDA_R)+K3*X(2)*(LAMBDA_T-LAMBDA_R-LAMBDA_V1)+LAMBDA_V2*DELTA2]
and the initial conditions vector must have the same number of elements.
Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
Error in test (line 62)
[t,xa] = ode45(f,[0 10],y0);
For which I can't find a solution, since I have used all the initial values given in the paper. The only values that I have left are the final values for the lambda coefficients, since they are final values, and I am not sure if they can be used.
In this case, I can't also understand where I should put the bounds on the control variable.
For completeness, I will provide also the link to the paper in question:
https://www.ripublication.com/ijss17/ijssv12n3_13.pdf
Can you help me figure out what I can do to solve my problems?
P.S: I know this is a pretty bad code, but I'm basing on the basics tutorials on mathworks; for sure this should need to be refactored and ordered in various file (one for the cost function and one for the constraints for example) but firstly I would like to understand where the problem is and then I will put all in a pretty form.
Thank you so much!
Generally you confused something with Vectors. In initial conditions you declared 7 values:
%initial conditions, ordered as the x vector (for the ui are guesses)
y0 = [100000 2000 1000 0 0 0 0];
But you declared 10 ODE's:
%system set up
f = #(t,x) [delta - (1 + x(4))*k1*x(1)*V1 - (1 + x(5))*k2*x(1)*V2 - alpha1*x(1) + gamma1*x(2) + gamma2*x(3);...
(1 + x(4))*k1*x(1)*V1 - k3*x(2)*V2 - alpha2*x(2) - gamma1*x(2);...
(1 + x(5))*k2*x(1)*V2 - alpha3*x(3) - gamma2*x(3) + k3*x(2)*V2;...
alpha2*x(2) + gamma1*x(2) + (1 + x(6))*phi1*x(1) + k3*x(2)*V2 - delta1*V1;...
alpha3*x(3) + gamma2*x(3) + (1 + x(7))*phi2*x(1) - delta2*V2;...
-A1 + (1 + x(4))*k1*V1*(lambda_u - lambda_t) + (1 + x(5))*k2*V2*(lambda_u - lambda_r) + lambda_u*alpha1 - lambda_v1*(1 + x(6))*phi1 - lambda_v2*(1 + x(7))*phi2;...
-lambda_u*gamma1 + (alpha2 + gamma1)*(lambda_t - lambda_v1) + k3*V2*(lambda_t - lambda_r - lambda_v1);...
-lambda_u*gamma2 + (alpha3 + gamma2)*(lambda_r - lambda_v2);...
(1 + x(4))*k1*x(1)*(lambda_u - lambda_t) + lambda_v1*delta1;...
(1 + x(5))*k2*x(1)*(lambda_u -lambda_r) + k3*x(2)*(lambda_t - lambda_r - lambda_v1) + lambda_v2*delta2];
Every line in above code is recognized as one ODE.
But that's not all. The second problem is with your construction. You mixed symbolic math (lambda declared as syms) with numerical solving, which will be tricky. I'm not familiar with the exact scientific problem you are trying to solve, but if you can't avoid symbolic math, maybe you should try dsolve from Symbolic Math Toolbox?

Matlab: Extract values that I plot but which has not been stored

I have a mathematical function E which I want to minimize. I get from solving this 16 possible solutions x1, x2, ..., x16, only two of which that actually minimize the function (located at a minimum). Using a for loop, I can then plug all of these 16 solutions into the original function, and select the solutions I need by applying some criteria via if statements (plotting E vs E(x) if x is real and positive, if first derivative of E is below a threshold, and if the second derivative of E is positive).
That way I only plot the solutions I'm interested in. However, I would now like to extract the relevant x that I plot. Here's a sample MATLAB code that plots the way I just described. I want to extract the thetas that I actually end up plotting. How to do that?
format long
theta_s = 0.77944100;
sigma = 0.50659500;
Delta = 0.52687700;
%% Defining the coefficients of the 4th degree polynomial
alpha = cos(2*theta_s);
beta = sin(2*theta_s);
gamma = 2*Delta^2/sigma^2;
a = -gamma^2 - beta^2*Delta^2 - alpha^2*Delta^2 + 2*alpha*Delta*gamma;
b = 2*alpha*gamma - 2*Delta*gamma - 2*alpha^2*Delta + 2*alpha*Delta^2 -...
2*beta^2*Delta;
c = 2*gamma^2 - 2*alpha*Delta*gamma - 2*gamma - alpha^2 + 4*alpha*Delta +...
beta^2*Delta^2 - beta^2 - Delta^2;
d = -2*alpha*gamma + 2*Delta*gamma + 2*alpha + 2*beta^2*Delta - 2*Delta;
e = beta^2 - gamma^2 + 2*gamma - 1;
%% Solve the polynomial numerically.
P = [a b c d e];
R = roots(P);
%% Solve r = cos(2x) for x: x = n*pi +- 1/2 * acos(r). Using n = 0 and 1.
theta = [1/2.*acos(R) -1/2.*acos(R) pi+1/2.*acos(R) pi-1/2.*acos(R)];
figure;
hold on;
x = 0:1/1000:2*pi;
y_1 = sigma*cos(x - theta_s) + sqrt(1 + Delta*cos(2*x));
y_2 = sigma*cos(x - theta_s) - sqrt(1 + Delta*cos(2*x));
plot(x,y_1,'black');
plot(x,y_2,'black');
grid on;
%% Plot theta if real, if positive, if 1st derivative is ~zero, and if 2nd derivative is positive
for j=1:numel(theta);
A = isreal(theta(j));
x_j = theta(j);
y_j = sigma*cos(x_j - theta_s) + sqrt(1 + Delta*cos(2*x_j));
FirstDer = sigma* sin(theta(j) - theta_s) + Delta*sin(2*theta(j))/...
sqrt(1 + Delta*cos(2*theta(j)));
SecDer = -sigma*cos(theta(j)-theta_s) - 2*Delta*cos(2*theta(j))/...
(1 + Delta*cos(2*theta(j)))^(1/2) - Delta^2 * (sin(2*theta(j)))^2/...
(1 + Delta*cos(2*theta(j)))^(3/2);
if A == 1 && x_j>=0 && FirstDer < 1E-7 && SecDer > 0
plot(x_j,y_j,['o','blue'])
end
end
After you finish all plotting, get the axes handle:
ax = gca;
then write:
X = get(ax.Children,{'XData'});
And X will be cell array of all the x-axis values from all lines in the graph. One cell for each line.
For the code above:
X =
[1.961054062875753]
[4.514533853417446]
[1x6284 double]
[1x6284 double]
(First, the code all worked. Thanks for the effort there.)
There are options here. A are couple below
Record the values as you generate them
Within the "success" if statement, simply record the values. See edits to your code below.
This would always be the preferred option for me, it just seems much more efficient.
xyResults = zeros(0,2); %%% INITIALIZE HERE
for j=1:numel(theta);
A = isreal(theta(j));
x_j = theta(j);
y_j = sigma*cos(x_j - theta_s) + sqrt(1 + Delta*cos(2*x_j));
FirstDer = sigma* sin(theta(j) - theta_s) + Delta*sin(2*theta(j))/...
sqrt(1 + Delta*cos(2*theta(j)));
SecDer = -sigma*cos(theta(j)-theta_s) - 2*Delta*cos(2*theta(j))/...
(1 + Delta*cos(2*theta(j)))^(1/2) - Delta^2 * (sin(2*theta(j)))^2/...
(1 + Delta*cos(2*theta(j)))^(3/2);
if A == 1 && x_j>=0 && FirstDer < 1E-7 && SecDer > 0
xyResults(end+1,:) = [x_j y_j]; %%%% RECORD HERE
plot(x_j,y_j,['o','blue'])
end
end
Get the result from the graphics objects
You can get the data you want from the actual graphics objects. This would be the option if there was just no way to capture the data as it was generated.
%First find the objects witht the data you want
% (Ideally you could record handles to the lines as you generated
% them above. But then you could also simply record the answer, so
% let's assume that direct record is not possible.)
% (BTW, 'findobj' is an underused, powerful function.)
h = findobj(0,'Marker','o','Color','b','type','line')
%Then get the `xdata` filed from each
capturedXdata = get(h,'XData');
capturedXdata =
2×1 cell array
[1.96105406287575]
[4.51453385341745]
%Then get the `ydata` filed from each
capturedYdata = get(h,'YData');
capturedYdata =
2×1 cell array
[1.96105406287575]
[4.51453385341745]

How can I get MATLAB to numerically solve a particularly nasty system of equations?

I have four parameters, t1,t2, theta1, and theta2. I want to find a solution (there can potentially be infinitely many) to the following system of equations:
t1*cos(theta1) + t2*cos(theta2) + 2*t1*t2*sin(theta1 + theta2) = t1*sin(theta1) + t2*sin(theta2) + 2*t1*t2*cos(theta1 + theta2) + 1
t1*cos(theta1) + t2*cos(theta2) + t1*sin(theta1) + t2*sin(theta2) = 2*t1*t2*sin(theta1 + theta2) + 2*t1*t2*cos(theta1 + theta2) + 1
2*t1^2*t2^2 + sin(theta1)*t1*t2^2 + sin(theta1 + theta2)*t1*t2 + 1 = sin(theta2)*t1^2*t2 + t1^2 + sin(theta1)*t1 + t2^2
Since there are more parameters than equations, we have to impose further restrictions to identify a specific solution to this system. Right now I don't really care which solution is picked, as long as it isn't trivial (like all the variables equaling zero).
My current method is to set the third equation to 0.5, solving for t1 and t2 in terms of theta1 and theta2, and substituting these expressions into the first two equations to solve for theta1 and theta2. However, MATLAB is trying to do this symbolically, which is extremely time-consuming. Is there a way I can get some approximate solutions to this system? I can't exactly plot the surfaces represented by these equations and look at their intersection, because each side of the equations involves more than two parameters, which means it can't be visualized in three dimensions.
You can use fsolve to do this.
First, you need to create anonymous functions for the residuals of the three equations. I'm going to create a vector x where x = [t1; t2; theta1; theta2]. That makes the residuals:
r1 = #(x) x(1)*cos(x(3)) + x(2)*cos(x(4)) + 2*x(1)*x(2)*sin(x(3) + x(4)) - (x(1)*sin(x(3)) + x(2)*sin(x(4)) + 2*x(1)*x(2)*cos(x(3) + x(4)) + 1);
r2 = #(x) x(1)*cos(x(3)) + x(2)*cos(x(4)) + x(1)*sin(x(3)) + x(2)*sin(x(4)) - (2*x(1)*x(2)*sin(x(3) + x(4)) + 2*x(1)*x(2)*cos(x(3) + x(4)) + 1);
r3 = #(x) 2*x(1)^2*x(2)^2 + sin(x(3))*x(1)*x(2)^2 + sin(x(3) + x(4))*x(1)*x(2) + 1 - (sin(x(4))*x(1)^2*x(2) + x(1)^2 + sin(x(3))*x(1) + x(2)^2);
Then, we need to make a single function that is a vector of those three residuals, since fsolve tries to get this vector to be zero:
r = #(x) [r1(x); r2(x); r3(x)]
Now, we call fsolve. I picked an arbitrary starting point:
>> [x, fval, exitflag] = fsolve(r, [0.5,0.5,pi/4,pi/4])
Warning: Trust-region-dogleg algorithm of FSOLVE cannot handle non-square systems; using Levenberg-Marquardt algorithm instead.
> In fsolve at 287
Equation solved.
fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.
<stopping criteria details>
x =
0.9654 0.5182 0.7363 0.7344
fval =
1.0e-10 *
-0.0090
0.2743
-0.0181
exitflag =
1
You can ignore the warning. x is the four values you were looking for. fval is the value of the residuals. exitFlag == 1 means we found a root.