MATLAB: fzero with a matrix as input to function? - matlab

I am trying to find the value x for a function f(x,y) that produces the function value 0 for a given y. In Matlab I write a small function handle, e.g.
minme = #(y,x) y-x.^2;
and use the fzero function to find that value of x, call it x*.
So e.g.
fzero(#(x) minme(5,x),1)
works great. However, now I want to find x* for a large vector of values of y, called Y. Putting
minme(Y,x)
for some value of x works.
Now I was trying something like
fzero(#(x) minme((3:1:5),x),1)
and
fzero(#(x) minme(Y,x),1)
but that produces an error:
??? Operands to the || and && operators must be convertible to logical scalar values.
Error in ==> fzero at 333
elseif ~isfinite(fx) || ~isreal(fx)
Does anybody know whether there is a way to do this?

Check this out
arrayfun(#(i) fzero(#(x) minme(y(i),x),1),1:numel(y))

Related

ODE solver producing runtime error - not enough input arguments [duplicate]

I have a use case as follows:
Inside F.m I have a function F that takes as its argument a 2 x 1 matrix x. F needs to matrix multiply the matrix kmat by x. kmat is a variable that is generated by a script.
So, what I did was set kmat to be global in the script:
global kmat;
kmat = rand(2);
In F.m:
function result = F(x)
global kmat;
result = kmat*x;
end
Then finally, in the script I have (x_0 has already been defined as an appropriate 2 x 1 matrix, and tstart and tend are positive integers):
xs = ode45(F, [tstart, tend], x_0);
However, this is causing the error:
Error using F (line 3)
Not enough input arguments.
Error in script (line 12)
xs = ode45(F, [tstart, tend], x_0);
What is going on here, and what can I do to fix it? Alternatively, what is the right way to pass kmat to F?
Firstly, the proper way to handle kmat is to make it an input argument to F.m
function result = F(x,kmat)
result = kmat*x;
end
Secondly, the input function to ode45 must be a function with inputs t and x (possibly vectors, t is the dependent variable and x is the dependent). Since your F function doesn't have t as an input argument, and you have an extra parameter kmat, you have to make a small anonymous function when you call ode45
ode45(#(t,x) F(x,kmat),[tstart tend],x_0)
If your derivative function was function result=derivative(t,x), then you simply do ode45(#derivative,[tstart tend],x_0) as Erik said.
I believe F in ode45(F,...) should be a function handle, i.e. #F. Also, you can have a look at this page of the MATLAB documentation for different methods to pass extra parameters to functions.

How to use matrix entries in a double symsum?

I am trying to implement the following double summation in a function:
f(x,y)=\sum_{k=0}^{S}\sum_{l=0}^{S}{a_{kl}x^ky^l}.
Here is my first attempt:
function [ a ] = MyFun( S )
a=randi([0 9],S+1);
syms x y k l;
f(x,y)=symsum(symsum(a(k,l)*x^k*y^l,l,1,S+1),k,1,S+1);
f(1,2)
end
Actually, my code evaluates f in a loop later on, but that does not seem relevant here. Trying something like MyFun(3) results in an error:
Error using sym/subsindex (line 766) Invalid indexing or function
definition. When defining a function, ensure that the arguments are
symbolic variables and the body of the function is a SYM expression.
When indexing, the input must be numeric, logical, or ':'.
Error in MyFun (line 4)
f(x,y)=symsum(symsum(a(k,l)*x^(k-1)*y^(l-1),l,1,S+1),k,1,S+1);
Everything works fine if a(k,l)* is removed from the inner symsum, so I suspect that there is something wrong with the indices. Is it not possible to use the symbolical variables k and l as indices? If not, how can I solve this?
Indexing a matrix using a symbolic value does not seem to work. As an alternative you can use elementwise multiplication as follows:
function f = MyFun( S )
a=randi([0 9],S+1);
k = repmat((0:S)', 1, S+1);
l = repmat((0:S), S+1, 1);
syms x y;
f(x, y) = sum(sum(a .* x.^k .* y.^l));
end

Error using integral: A and B must be floating-point scalars

I want to evaluate the simple example of integral
a = max(solve(x^3 - 2*x^2 + x ==0 , x));
fun = #(x) exp(-x.^2).*log(x).^2;
q = integral(fun,0,a)
and the error is
Error using integral (line 85)
A and B must be floating-point scalars.
Any tips? The lower limit of my integral must be a function, not a number.
The Matlab command solve returns symbolic result. integral accepts only numeric input. Use double to convert symbolic to numeric. As your code is written now, already max should throw an error due to symbolic input. The following works.
syms x;
a = max(double(solve(x^3 - 2*x^2 + x)));
fun = #(x) exp(-x.^2).*log(x).^2;
q = integral(fun,0,a)
Output: 1.9331.
the lower limit of my integral must be a function, not a number
integral is a numeric integration routine; the limits of integration must be numeric.
Check values of a by mouse over in breakpoint or removing the ; from the end of the line so it prints a. Based on the error, a is not a scalar float. You might need another max() or double() statement to transform the vector to a single value.
Solve Help : http://www.mathworks.com/help/symbolic/solve.html
Integral Help : http://www.mathworks.com/help/ref/integral.html

why isn't the result a scalar?

i'm stuck with this error:
In an assignment A(I) = B, the number of elements in B and I must be the same.
yres(1)=((u - uc).^2) + ((y - yc).^2) -(d.^2);
i don't understand, why this won't get a skalar?since the elements are all scalar. what should be changed to get a scalar?
best regards
edit: thanks sloede, all inputs are scalar, but i still get this error
In an assignment A(I) = B, the number of elements in B and I must be the
same.
Error in myfun (line 7)
yres(1)=sqrt(((u - uc).^2) + ((y - yc).^2) ) -d;
Error in fsolve (line 241)
fuser = feval(funfcn{3},x,varargin{:});
Error in modfsolve (line 26)
x= fsolve(#myfun,x0,options,uc,d,spacing_amplitude,spacing_width);
Caused by:
Failure in initial user-supplied objective function evaluation. FSOLVE
cannot continue.*
The "." before an operator means that the following operation should be applied element-wise and not on the vector as a whole. Thus
a = b.^2
will give you as a result all elements of b squared and saved back to a. Therefore, in your code statement above, if any of u, uc, y, yc, d are not scalar but a vector, your result will be a vector as well.
Otherwise there seems to be nothing wrong with your code.
read the documentation of fsolve: http://www.mathworks.nl/help/toolbox/optim/ug/fsolve.html
it states:
fun
The nonlinear system of equations to solve. fun is a function that accepts a vector x and returns a vector F, the nonlinear equations evaluated at x.
Obviously your function myfun doesn't handle vector input.
You can solve this by adding the following construction inside your function (and of course change it to your needs/your parameters):
function out = myfun(in)
if ~isscalar(in)
% assuming it's a matrix or vector
out = reshape(arrayfun(#myfun,in(:)),size(in));
else
% your actual function execution statements
out = dostuffon(in);
end
end
or properly vectorize your function (if that's possible)

How to do with this for fzero loop?

I want to get x from the following equation.
z=fzero(#(x)gamma/(R-(1+phi(1)*x)*(1+phi(2)))-tauA2(1)-((1+alpha*beta)/beta*(gamma/x-tauA1(1))),800)
There, all the alphabets and phi(1), phi(2), tauA2(1) and tauA1(1) are numbers from each matrix.
However, it keeps resulting
??? Undefined function or method 'isfinite' for input arguments of
type 'sym'.
Error in ==> fzero at 333
elseif ~isfinite(fx) || ~isreal(fx)
Also by using the above equation, eventually I have get matrix z of 9*2
since I will modify tauA1 and tauA2 as tauA1(i) and tauA2(i). So, I coded such as
for i=1:9
z(i)=fzero(#(x)gamma/(R-(1+phi(1)*x)*(1+phi(2)))-tauA2(i)-((1+alpha*beta)/beta*(gamma/x-tauA1(i))),800)
end
But the result is the same as before.
What is wrong with the code? How can I fix it?