matlab: using a vector of unknowns in fsolve - matlab

I need to solve a system of nonlinear equations; in order to use fsolve , I have written an m-file containing my function "myfun". This function is called by the main m-file.
Both the system and the unknowns must be written using a "for" loop.
Example:
function F=myfun(x)
n=20;`
for j=1:n
c1=sqrt(x(j)^2-3*x(j));
c2=x(j)^(1/2);
F(j)=c1+c2;
end
My problem is that I have to preallocate memory for my vectors, both F and x, otherwise the solver considers numel(x)=1.
But if I declare
F=zeros(n,1);
x=zeros(n,1);
I have the following output:
No solution found.
fsolve stopped because the problem appears regular as measured by the gradient,
but the vector of function values is not near zero as measured by the
default value of the function tolerance.
Any suggestions? Thanks

You don't need the loop, just use
F = sqrt(x.^2-3*x) + x.^(1/2);
Then you also don't need to declare n, c1, c2.
Your error message also doens't sound like it's a problem with the allocation, but more with finding a solution to you fsolve problem.

Related

How to use ODE45 to solve for a system of differential equations with a difficult end condition?

My system of equations can be written down as-
y1' = F_1(x,y1,y2)
y2' = F_2(x,y1,y2)
where F1 and F2 are some functions of x, y1, y2. y1 and y2 are functions of x and y1'=dy1_dx and y2'=dy2_dx.
The initial condition is at x=0, y1=y2=0. However I need the solution at y1=1, i.e. as soon as y1=1 is reached, the iteration needs to stop. I want to solve it using a proper solver like ODE45 or ODE15s in MATLAB. However I am not sure how to set the x_span i.e. initial and final values of x. Please guide me.
Note that, setting x at a large value say 1000 will not help, because I don't know where y1=1.
Use an event function (typically equal to y1-1) that you give to the ODE solver:
https://fr.mathworks.com/help/matlab/math/ode-event-location.html
As soon as the solver detect a sign change of your event function, it stops.

Using Matlab to solve a system of ODEs using Euler's method

I have created a function Euler.m to solve a a system of ODEs using Euler's method. I wish to use this function to solve the system of ODEs defined by the anonymous function func=#(t) ([x(t)+4*y(t)-exp(t);x(t)+y(t)+2*exp(t)]) with initial conditions given by y0.
func=#(t) ([x(t)+4*y(t)-exp(t);x(t)+y(t)+2*exp(t)]);
y0=[4;5/4];
y_exact=#(t) [4*exp(3*t)+2*exp(-t)-2*exp(t);2*exp(3*t)-exp(-t)+exp(t)/4]; %exact solution of ODEs
a=0; % such that
b=1; % a<t<b
N=120;
[t,y] = Euler(func,a,b,y0,N)
However, the following error is displayed:
"Error using solution>#(t)([x(t)+4*y(t)-exp(t);x(t)+y(t)+2*exp(t)])
Too many input arguments.
Error in solution (line 7)
[t,y] = Euler(func,a,b,y0,N)".
Why is this error being displayed?
You are pretending that you already know when writing the ODE function func what the solutions x(t),y(t) are. Then you are going to compute solutions approximations for it. This is completely the wrong way around.
The function for the right side is just for a point in phase space, so you need
func=#(t,y) ([y(1)+4*y(2)-exp(t);y(1)+y(2)+2*exp(t)]);
where the input y is a two-component vector.

Minimizing Function with vector valued input in MATLAB

I want to minimize a function like below:
Here, n can be 5,10,50 etc. I want to use Matlab and want to use Gradient Descent and Quasi-Newton Method with BFGS update to solve this problem along with backtracking line search. I am a novice in Matlab. Can anyone help, please? I can find a solution for a similar problem in that link: https://www.mathworks.com/help/optim/ug/unconstrained-nonlinear-optimization-algorithms.html .
But, I really don't know how to create a vector-valued function in Matlab (in my case input x can be an n-dimensional vector).
You will have to make quite a leap to get where you want to be -- may I suggest to go through some basic tutorial first in order to digest basic MATLAB syntax and concepts? Another useful read is the very basic example to unconstrained optimization in the documentation. However, the answer to your question touches only basic syntax, so we can go through it quickly nevertheless.
The absolute minimum to invoke the unconstraint nonlinear optimization algorithms of the Optimization Toolbox is the formulation of an objective function. That function is supposed to return the function value f of your function at any given point x, and in your case it reads
function f = objfun(x)
f = sum(100 * (x(2:end) - x(1:end-1).^2).^2 + (1 - x(1:end-1)).^2);
end
Notice that
we select the indiviual components of the x vector by matrix indexing, and that
the .^ notation effects that the operand is to be squared elementwise.
For simplicity, save this function to a file objfun.m in your current working directory, so that you have it available from the command window.
Now all you have to do is to call the appropriate optimization algorithm, say, the quasi Newton method, from the command window:
n = 10; % Use n variables
options = optimoptions(#fminunc,'Algorithm','quasi-newton'); % Use QM method
x0 = rand(n,1); % Random starting guess
[x,fval,exitflag] = fminunc(#objfun, x0, options); % Solve!
fprintf('Final objval=%.2e, exitflag=%d\n', fval, exitflag);
On my machine I see that the algorithm converges:
Local minimum found.
Optimization completed because the size of the gradient is less than
the default value of the optimality tolerance.
Final objval=5.57e-11, exitflag=1

Nonlinear square optimization task in matlab

let us suppose that we have following task:Find the optimal value of weights
so that minimize following equation
where var-means variance of given x1 variable, also we have constraint that sum of these weights should be equal to 1
i have initialized anonymous function and weights for initial points
w=[0.5; 0.5];
>> f=#(x1,x2) (w(1)*w(1)*var(x1)+w(2)*w(2)*var(x2))
f =
#(x1,x2)(w(1)*w(1)*var(x1)+w(2)*w(2)*var(x2))
i think i should use function fmincon,
i have created A matrix
A=[1;1];
and b column
b=[1];
then i tried following fun
weighs=fmincon(f(x1,x2),w,A,b)
but it gives me error
Error using optimfcnchk (line 287)
FUN must be a function, a valid string expression, or an inline function
object.
could you help me please what is wrong? thanks in advance
You need to specify the function in fmincon as a function handle or anonymous function; f(x1,x2) evaluates to a scalar double, not a function handle. fmincon will want to evaluate this function with current values of w to check for the quality of the solution, so it needs a way to feed w as an input.
Thus, you need to
Change the function definition to f(w,x1,x2), i.e.
f=#(w,x1,x2) (w(1)*w(1)*var(x1)+w(2)*w(2)*var(x2))
Write the fmincon call as fmincon(#(u)f(u,x1,x2),...)
However, I would suggest to substitute 1-w(2) for w(1) (or vice versa) in your problem to reformulate it as an unconstrained optimization of one variable (unless w is a real weight, and has to remain between 0 and 1, in which case you still need a constraint).

Matrix dimension error while calling mldivide in MATLAB

I am getting this error while running my code:
Error using ==> mldivide Matrix dimensions must agree.
Here is my code :
%make the plots of phase and group velocity vs discreteness of the grid
c=1;
a=input('Please enter the ratio cdt/dx : ')
figure(1)
R=2:40;
plot(R,phase_vel(R,a)/c)
xlabel('R=l/dx')
ylabel('u_phase/c')
%figure(2)
%plot(group_vel(R,a),R,0,40)
%xlabel('R=l/dx')
%ylabel('u_group/c')
and here are my functions :
function phase_velocity = phase_vel(R,a)
%numerical phase velocity of the discrete wave
c=1;
phase_velocity=(2*pi*c)/(R*knum(R,a));
end
function group_velocity =group_vel(R,a )
%numerical group velocity of the discrete wave
c=1;
group_velocity=(a*sin(knum(R,a)))/(sin(2*pi*a/R))
end
function knumber = knum(R,a)
%This is the k wave number
knumber=acos((1/a)^2*(cos(2*pi*a/R)-1)+1);
end
How can I resolve this error?
EDIT: I used . operator in every equation and i changed the limits of R=4:40
If your goal is to apply your formulas to each individual value in the vector R then you should be performing all of your computations using the element-wise arithmetic operators .*, ./, and .^ instead of the matrix operators *, /, and ^.
Your error is probably occurring in the first call to your function knum, specifically when you try to compute 2*pi*a/R. Since 2*pi*a is a single scalar value, you get an error when trying to perform matrix right division / using the row vector R. The really weird thing is the error message:
??? Error using ==> mldivide
Matrix dimensions must agree.
which implies you are using the matrix left division operator \, which you clearly aren't. I tested this in MATLAB R2010b and I get the same incorrect function name appearing in my message. I think this may just be a typo in the error message, and I've dropped a note to the MATLAB folks to take a look at it and clear it up.
I don't have the Symbolic Math Toolbox, but your problem seems to be that you are using plot, a function which can deal with arrays of numbers, and feeding it the result of a symbolic calculation. Have a look at the Matlab Help, where the Topic Creating Plots of Symbolic Functions suggests using ezplot(). Alternatively you need to evaluate your symbolic expression for certain input values to create an array of numbers that plot can deal with - but you can't use double() for that since it wouldn't know what numbers to plug into your variables.