zeros of a vector-valued function - matlab

Is there any function in MATLAB that can find the zeros of a vector-valued function? The commonly used function fzero is just for scalar functions and also cannot find the zeros of any scalar function such as f(x)=x^2.

Matlab's optimization toolbox has the fsolve method that states it is capable of:
Solves a problem specified by F(x) = 0 for x, where F(x) is a function that returns a vector value. x is a vector or a matrix.
Otherwise, finding zeroes of a generic vector valued function can be done by attempting to minimize the norm of the vectorial output. Lets assume your function F(x) outputs an Nx1 vector. You could attempt to find the zero by doing the following:
y = fminunc(#(x) sum(F(x).^2));
or
y = fminsearch(#(x) sum(F(x).^2));
You would then have to check if the returned y is "sufficiently close" to zero.
One last comment, the fzero function's algorithm determines the existence of roots by checking for sign changes. The [docs] explicitly say that
x = fzero(fun,x0) tries to find a point x where fun(x) = 0. This solution is where fun(x) changes sign. fzero cannot find a root of a function such as x^2.
In fact, in older versions of matlab (R2012b) the fzero's doc had a section with its limitations that said
The fzero command finds a point where the function changes sign. If the function is continuous, this is also a point where the function has a value near zero. If the function is not continuous, fzero may return values that are discontinuous points instead of zeros. For example, fzero(#tan,1) returns 1.5708, a discontinuous point in tan.
Furthermore, the fzero command defines a zero as a point where the function crosses the x-axis. Points where the function touches, but does not cross, the x-axis are not valid zeros. For example, y = x.^2 is a parabola that touches the x-axis at 0. Because the function never crosses the x-axis, however, no zero is found. For functions with no valid zeros, fzero executes until Inf, NaN, or a complex value is detected.

Maybe I misunderstand something in your question, but you can try this solution:
y = #(x) x^2;
fminbnd(y, -100, 100)
ans = -3.5527e-15
And maybe you can try solve:
syms x y
y = #(x) x^2;
solve( y==0, x);
Can't check it right now, I will edit this solution a little bit later.

Related

Numerical gradient of a Matlab function evaluated at a certain point

I have a Matlab function G(x,y,z). At each given (x,y,z), G(x,y,z) is a scalar. x=(x1,x2,...,xK) is a Kx1 vector.
Let us fix y,z at some given values. I would like your help to understand how to compute the derivative of G with respect to xk evaluated at a certain x.
For example, suppose K=3
function f= G(x1,x2,x3,y,z)
f=3*x1*sin(z)*cos(y)+3*x2*sin(z)*cos(y)+3*x3*sin(z)*cos(y);
end
How do I compute the derivative of G(x1,x2,x3,4,3) wrto x2 and then evaluate it at x=(1,2,6)?
You're looking for the partial derivative of dG/dx2
So the first thing would be getting rid of your fixed variables
G2 = #(x2) G(1,x2,6,4,3);
The numerical derivatives are finite differences, you need to choose an step h for your finite difference, and an appropriate method
The simplest one is
(G2(x2+h)-G2(x2))/h
You can make h as small as your numeric precision allows you to. At the limit h -> 0 the finite difference is the partial derivative

How do I get the values of y and y' for specific values of t from ode45 in Matlab?

I have to solve a second-degree differential equation and I specifically need the value of the first derivative of y at the final time point. My code is the following:
[T Y]=ode45(#(t y)vdp4(t,y,0.3),[0 1],[0.3/4,((3*0.3)^0.5)/2]);
I know the output will contain the values at which ode45 evaluated the function. To get the y values at specific time value at have it has been advised to give more than two time points in the MATLAB documentation. I did that too.
tspan=[0:0.01:1]
[T Y]=ode45(#(t y)vdp4(t,y,0.3),tspan,[0.3/4,((3*0.3)^0.5)/2]);
The T vector still does not have all the values from 0 to 1 (The last value is 0.39). This happens especially after multiple executions of ode45 function. I found something else in the MATLAB documentation: using "sol" structure to deval the values for specific t values. Is that the right way to go?
For reference, my differential equation is in the following function.
function dy = vdp4(t,y,k)
dy = zeros(2,1); % a column vector
dy(1)=y(2);
dy(2)=(y(2)^2-2*t*y(2)+2*y(1))/k+2;
end
Edit: I provided the parameter value. It should now be executable.
Try to plot your solution, you will find the answer

Plotting the sum of series

I use this code and i don't know what it needs to work for my problem:
syms x k t
for t=0:10
num=((-1)^k)/k
t1=sin(8*3.1415*k*t)
S1=symsum((num*t1),k,1,2);
x=0.5-((1/3.1415)*S1);
end
Plot(x)
On the x axis I show time and on the y axis I show the function over four periods.
When I try to run the code I get the following error:
Undefined function 'symsum' for input arguments of type 'double'.
Maybe I can't use symsum with my argument type, but is there another function I can use? Sum also didn't work:
Error using sum Dimension argument must be a positive integer scalar within indexing range.
Since you want to plot x(t), you need to use plot(t,x) where t and x are vectors.
Instead of using for t=0:10, just let t=0:10 and calculate the corresponding x.
Also, the symbolic variable is just k.
syms k
t=0:10;
num=((-1)^k)/k;
t1=sin(8*3.1415*k*t);
S1=symsum((num*t1),k,1,2);
x=0.5-((1/3.1415)*S1);
plot(t,x)
It is noted that if you let t=0:10, then the sin(8*k*pi*t) will always be 0 since t is a vector of the integer from 0 to 10. The result of x(t) will be 5:
Output when t=0:10:
As you can see, the value of x(t) is very close to each other. Theoretically, they should all be 5. But there is some numerical approximation which leads to the small error.
You probably want non-integer t. Here is a output when t=0:0.1:10

Assume that x, y, and z are Matlab arrays, plot the function e^(-x)sin(x) across the interval [0. 4pi]

x=linspace(0, 2*pi, 100);
y=sin(x);
z=exp(-x);
Given that x, y, and z are already initialized, how do I write a function that plots exp(-x)sin(x) across the interval [0, 4pi] without additional calls to sin or exp? Just need some help getting started.
Thanks to #Rayryeng for getting me started. I believe the following command more closely satisfies the question's specifications.
plot(x+x, z.*z.*y)
Well, you've already created arrays for sin and exp stored in y and z respectively. These arrays were created on the same domain as x. You just need to multiply both arrays together element-wise and plot the graph. It's as simple as doing:
plot(x, z.*y);
Here, .* stands for element-wise multiplication. If you were to do z*y, MATLAB interprets this as matrix multiplication where z and y are interpreted to be matrices. This is obviously not what you want.
However, your array of x only contains points from 0 to 2*pi. If you want to plot this from 0 to 4*pi, you have to modify your call to linspace:
x=linspace(0, 4*pi, 100); %// Change
y=sin(x);
z=exp(-x);
plot(x, z.*y);
Now, x will contain 100 points between 0 to 4*pi. For more information on basic MATLAB operations, check out this link: http://www.mathworks.com/help/matlab/matlab_prog/array-vs-matrix-operations.html. What you have asked falls into the basic realms of array and matrix operations.
Edit
In the spirit of your question, we can't modify linspace. You did something clever where we can simply scale our values of x by 2 or adding with x so that we have points going from 0 to 2*pi to 0 to 4*pi. Also, if we scale our points by 2, this means that our input argument into the function must also be scaled by 2. So, the final function we need to plot is:
y = exp(-2x)*sin(2x)
Noting your hint, exp(-2x) = exp(-x-x) = exp(-x)exp(-x). Further, note that sin(2x) performs a compression by a factor of 2 (tip of the hat goes to knedlsepp for noticing my blunder). Due to the periodic nature of sin(x), we know that elements will repeat after 2*pi, and so if you want to go to 4*pi, simply subsample y by a factor of 2 and then append these same elements to a new vector. Therefore, our expression for the function simplifies to:
y = exp(-x)exp(-x)sin(2x)
This leads to the answer alluded to knedlsepp:
plot(x+x, z.*z.*[y(1:2:end) y(1:2:end)]);
As such, you should consider changing your edits to match this answer instead. It isn't quite right with respect to the sin(x) part in your code.

Matlab: Error using ==> mpower

I'm trying to use fsolve in matlab to solve a system of nonlinear equations numerically. Here is a test sample of my program, k1 and R are parameters and x0 is the start point.
function y=f(k1, R, x0)
pair=fsolve(#system,x0);
y=pair(1);
function r=system(v)
int1=#(x) exp(k1*x);
int2=#(x) exp(k1*x^2)/(x^4);
r(1)=exp(v(1))*quadl(int1,0,v(1));
r(2)=exp(k1*v(2))*quadl(int2,v(1),20)*k1*R;
end
end
The strange thing is when I run this program, matlab keeps telling me that I should use .^ instead of ^ in int2=#(x) exp(k1*x^2)/(x^4). I am confused because the x in that function handle is supposed to be a scalar when it is used by quadl. Why should I have to use .^ in this case?
Also I see that a lot of the examples provided in online documentations also use .^ even though they are clearly taking power of a scalar, as in here. Can anybody help explain why?
Thanks in advance.
in the function int2 you have used matrix power (^) where you should use element-wise power (.^). Also, you have used matrix right division (/) where you should use element-wise division (./). This is needed, since quadl (and friends) will evaluate the integrand int2 for a whole array of x's at a time for reasons of efficiency.
So, use this:
function y = f(k1, R, x0)
pair = fsolve(#system,x0);
y = pair(1);
function r = system(v)
int1 = #(x) exp(k1*x);
int2 = #(x) exp(k1*x.^2)./(x.^4);
r(1) = exp( v(1)) * quadl(int1,0,v(1));
r(2) = exp(k1*v(2)) * k1*R*quadl(int2,v(1),20);
end
end
Also, have a look at quadgk or integral (if you're on newer Matlab).
By the way, I assume your real functions int1 and int2 are different functions? Because these functions are of course trivial to solve analytically...
Internally MATLAB will evaluate the function fun for necessary values of x, which is more than one and x is a vector. a and b are only used to describe the limits of integration. From the documentation
fun is a function handle. It accepts a vector x and returns a vector y, the function fun evaluated at each element of x. Limits a and b must be finite.
Hence, you must use .^ to operate on individual elements of vector x.