Computing the Jacobian of an anonymous function - MATLAB - matlab

I'm trying to solve a system of non linear odes in Matlab as follows.
editparams %parameters
Tend = 50;
Nt = 100;
% Define RHS functions
RHS = #(t,x) ModelRHS(t,x,param); %anonymous function defining the set of equations
%Execution-----------------------------------------------------------------
x0 =[0.04;0.75;0.85]; %Initial condition
t = linspace(0,Tend,Nt); %TSPAN
[t x] = ode45(RHS, t, x0);
Now, I need to find the steady state of the system and I'm trying to create a function for this. I thought I'd calculate the steady state using the Jacobian. My equations are in an anonymous function which is defined as f in the code below. However, I realised that jacobian does not work for anonymous functions (or may be there is a way to do with anonymous functions) . so I thought I would convert the anonymous function to a symbolic function and try it. But
i still have a difficulty in getting that done. So any help is really appreciated!
function SS = SteadyState(param, E)
f = #(t,x)ModelRHS(t,x,param,E); %set of odes
SymbolicSystem = sym(f); %trying to make the anonymous function symbolic
SymbolicJacobian = jacobian(SymbolicSystem',x); %jacobian
Jacob = matlabFunction(SymbolicJacobian,x);
end
Also if there is any other way apart from finding the Jacobian, kindly let me know about that too.
I tried using 'fsolve' to calculate the steady-state as follows:
f = #(t,x)ModelRHS(t,x,param);
x0 =[0.04;0.75;0.85]';
options = optimoptions('fsolve','Display','iter'); % Option to display output
SS = fsolve(f,x0,options); % Call solver
but it returned an error
Not enough input arguments.
Error in #(t,x)ModelRHS(t,x,param)
Error in fsolve (line 242)
fuser = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial objective function evaluation. FSOLVE cannot continue.

Related

Time varying input ODE solving

I'm trying to solve a set of ODE equations using ode45. A number of my parameters are already a function of time but I keep getting errors.
function odo
dx(1,1) = (vl+vr)/2*cos(x(3));
dx(2,1) = (vl+vr)/2*sin(x(3));
dx(3,1) = obz
where obz, vr and vl are each vectors e.g:
obz = sin(t), t = 0:dt:tf;
I use the following syntax:
[t, x1] = ode45(#(t,x) odo(t,x,b,obz,vr,vl), 0:dt:tf, [0;0;0]);
with R15 but keep getting the error:
Assignment has more non-singleton rhs dimensions than non-singleton subscripts
How to solve this issue?
You have some syntax errors here. First You can't just type function odo and let the MATLAB guess what it should do here. The second, you call t and x twice in your solver expressions. Be consistent, call function in ode solver this way:
t_span=1:1:12;
b=0.2;
[t, x] = ode45(#odo, t_span, [0;0;0], b);
You don't need to pass t and x manually, solver do it itself. Only the additional parameter b (however it is not in use, in your example). Also in declaration of function do as follow:
function dx = odo(t,x,b)
vr=sin(t); %Non-OD equations here
vl=cos(t);
obz=0.05*sin(t);
n=numel(x); %this generate a holder for results
dx=zeros(n,1);
dx(1) = (vl+vr)/2*cos(x(3)); %All ODEs formatted like this
dx(2) = (vl+vr)/2*sin(x(3));
dx(3) = obz;
As you can see, vr, vl, and obz are time-depended values, so need to be re-calculated in every step of solver. You have to place it in your solver function.

changing ObjectiveLimit option in fminunc in matlab

I have a noisy picture that I want to denoise, with specific energy function, my function have 3 free variable which I can change them until the energy function converge to the minimum value,I found values of these 3 variable by testing different value and run the program, but I want to know how can I find them by a good optimization algorithm. as far as I know I can use fminunc function in matlab but it gives me an error:
fminunc stopped because the objective function value is less than or equal to the default value of the objective function limit.
h,beta,v is the 3 variable which initialize by h=0.8,beta=4,v=0.9
here is the enrgy formula
and also my code:
load Input_images.mat;
X=noisyImg();
Z=X;
[n,m]=size(Z);
c=1;
for c=1:5
c
for i=1:n
for j=1:m
[neighbours] = neighbour(i,j,n,m,Z);
sumneighpos=sum(Z(i,j)*neighbours(1,:)');
inputnoisypos=(Z(i,j)*X(i,j));
noisyzpos=h*Z(i,j);
sumpos=noisyzpos-(beta*sumneighpos)-(v*inputnoisypos);
sumneg=-sumpos;
if sumneg<sumpos
Z(i,j)=-Z(i,j);
end
end
end
end
code for the optimization part.
f = #(q,w) h*Z(i,j)-q*sumneighpos-w*inputnoisypos;
fun = #(x) f(x(1),x(2));
x0 = [0.9; 4];
options = optimoptions('fminunc','Algorithm','quasi-newton');
[x, fval, exitflag, output] = fminunc(fun,x0,options);
here I have 2 question how can I fix the error and second one, is there any better algorithm?

Matlab Fmincon "too many output arguments"

I am solving a very simple constrained optimization problem. At this point, I have only entered a constraint that makes the (L-2) vector norm equal 1 and later I hope to add non-negativity constraints.
Fmincon is giving me a "Too many output arguments" on the my constraint. I don't understand why.
Objective function: A simple Quadratic form. Actually a variance covariance Matrix, I am entering as a pre-calculated global variable.
function [y, grady] = quadobj(x)
global Q
y = x*Q*x';
if nargout > 1
grady = 2*Q*x;
end
Equality Constraint: that vector L2 norm should be 1.
function outeq = confuneq2(x)
% Nonlinear equality constraints
outeq = x*x'-1;
end
Fmincon.
x0 = [0.7,0.1, -0.69];
options = optimoptions(#fmincon,'Algorithm','sqp');
[x,fval] = fmincon(#quadobj,x0,[],[],[],[],[],[],...
#confuneq2,options);
But it's not working. I am getting the following error.
Error using confuneq2
Too many output arguments.
Error in fmincon (line 632)
[ctmp,ceqtmp] = feval(confcn{3},X,varargin{:});
Caused by:
Failure in initial user-supplied nonlinear constraint function evaluation. FMINCON cannot continue
Please help!
Confusingly, the problem is that your function has too few output arguments. If you look at the error, it is telling you that MATLAB is trying to call your function with two output arguments but you've programmed it to take only one. Thus it errors because it has called your function with too many output arguments.
All the examples in the docs have two outputs so try create your function this way:
function [out, outeq] = confuneq2(x)
out = x*x'-1;
outeq = [];
end

MATLAB function fminunc generates errors

I am facing an error when using the function fminunc in the context of a maximum-likelihood estimation. I am afraid that it is very straight forward however my experience with MATLAB is very limited.
The function "normal" contains the log-likelihood function. I seek to estimate the expectation and std. deviation of a normal distribution given the observations stored in the variable x.
function f = normal(X, theta)
mean = theta(1);
sigma = theta(2);
z = (X-mean)./sigma;
f = -(sum(-log(sigma) -(1/2).*z.^2 ));
I basically execute the following code:
theta = [1,1]
f = #(theta)normal(x, theta)
[est, fval, exitflag, output, grad, hessian] = fminunc('normal', x, theta)
The error is the following:
Warning: Struct field assignment overwrites a value with class "double". See MATLAB R14SP2 Release
Notes, Assigning Nonstructure Variables As Structures Displays Warning, for details.
In createOptionFeedback at 34
In prepareOptionsForSolver at 31
In fminunc at 157
Warning: Struct field assignment overwrites a value with class "double". See MATLAB R14SP2 Release
Notes, Assigning Nonstructure Variables As Structures Displays Warning, for details.
In fminunc at 203
Error using feval
Undefined function 'normal' for input arguments of type 'double'.
Error in fminunc (line 254)
f = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation. FMINUNC cannot continue.
Unfortunately the manual did not help me to fix the code. Calling
[est, fval, exitflag, output, grad, hessian] = fminunc(f, x, theta)
did not help either. What am I doing wrong?
Thank you in advance!
You have called fminunc with the wrong sintax, please refer to the documentation.
A way to fix your code is by defining the function normal to accept only one parameter: theta.
function f = normal(theta)
global X
mean = theta(1);
sigma = theta(2);
z = (X-mean)./sigma;
f = -(sum(-log(sigma) -(1/2).*z.^2 ));
and call fminunc with
global X
X = randn(100, 1); % A possible time series.
theta0 = [1,1];
[est, fval, exitflag, output, grad, hessian] = fminunc(#normal, theta0);

solving nonlinear equations

I want to solve two nonlinear equations in MATLAB so i did the following:
part of my script
c=[A\u;A\v];
% parts of code are omitted.
x0=[1;1];
sol= fsolve(#myfunc,x0);
the myfunc function is as follows
function F = myfunc(x)
F=[ x(1)*c(1)+x(2)*c(2)+x(1)*x(2)*c(3)+c(4)-ii;
x(1)*c(5)+x(2)*c(6)+x(1)*x(2)*c(7)+c(8)-jj];
end
i have two unknowns x(1) and x(2)
my question is How to pass a values(c,ii,jj) to myfunc in every time i call it?
or how to overcome this error Undefined function or method 'c' for input arguments of type 'double'.
thanks
Edit: The previous answer was bogus and not contributing at all. Hence has been deleted. Here is the right way.
In your main code create a vector of the coefficients c,ii,jj and a dummy function handle f_d
coeffs = [c,ii,jj];
f_d = #(x0) myfunc(x0,coeffs); % f_d considers x0 as variables
sol = fsolve(f_d,x0);
Make your function myfunc capable of taking in 2 variables, x0 and coeffs
function F = myfunc(x, coeffs)
c = coeffs(1:end-2);
ii = coeffs(end-1);
jj = coeffs(end);
F(1) = x(1)*c(1)+x(2)*c(2)+x(1)*x(2)*c(3)+c(4)-ii;
F(2) = x(1)*c(5)+x(2)*c(6)+x(1)*x(2)*c(7)+c(8)-jj;
I think that should solve for x0(1) and x0(2).
Edit: Thank you Eitan_T. Changes have been made above.
There is an alternative option, that I prefer, if a function handle is not what you are looking for.
Say I have this function:
function y = i_have_a_root( x, a )
y = a*x^2;
end
You can pass in your initial guess for x and a value for a by just calling fsolve like so:
a = 5;
x0 = 0;
root = fsolve('i_have_a_root',x0,[],a);
Note: The [] is reserved for fsolve options, which you probably want to use. See the second call to fsolve in the documentation here for information on the options argument.