Trouble with exponentiation in Octave's ezmesh function - matlab

I made the following function handler:
fhapprox1 = #(x, y) sum ([1:x] .^ y)
This works fine when called with arguments like fhapprox1(3,5). However, when passing this function to ezmesh (using ezmesh(fhapprox1)), I get the following error:
error: operator .^: nonconformant arguments (op1 is 1x0, op2 is 60x60)
What is happening here? How can I rewrite this to get the 3d graph I'm expecting?

This is because your function is only designed to handle single values of x and y. ezmesh uses a grid of co-ordinates and x and y are actually 2D matrices when you use ezmesh. You get undefined behaviour when trying to call up ezmesh this way. In addition, ezmesh plots between -2*pi <= (x,y) <= 2*pi by default.
Because x can be < 0, doing 1:x when x is negative will give you an empty array, which is why you get that error. You need to rethink how your function can be defined so that it takes in a grid of co-ordinates and outputs the values you want. I can't provide anything further because I don't know how your function would be defined for negative values of x. Once I get this information, I'll update my answer.
Edit
We can modify your fhapprox1 function so that it can take in a grid of values. I can't think of a way to vectorize this code right now other than doing nested for loops, but let's try and get something working first. Basically, make a separate M-file that's called fhapprox1.m. After, put this into the file:
function [Z] = fhapprox1(X, Y)
Z = zeros(size(X));
for x = 1 : size(X,1)
for y = 1 : size(X,2)
Z(x,y) = sum((1:X(x,y)) .^ Y(x,y));
end
end
The above code will do what you were doing for single values of (x,y), but now it can take in a grid of (x,y) co-ordinates. By doing this, then calling ezmesh in the way you specified in your comments, this is what we get:
ezmesh(#fhapprox1, [1,1000,1,3])

Related

How to plot function of 3 variables with Octave?

I am new to Octave (and matlab for that matter). I have a function that looks like this
I would like to plot g(x,0.5,5) say.
Here it is what I tried in Octave
I defined an anonymous function
f=#(n,x,t) 1./n.*log(n.*pi.*t).*sin(n.*pi.*x);
then another anonymous function
g=#(m,x,t)x.^2+sum(f([1:m],x,t));
Finally defined
x=-1:0.1:1;
plot(x,g(5,x,0.5))
but I get an error. Is this the right way of plotting this function? I must be doing a simple beginner error?
When you call f(n,x,t), you are passing a 1-by-5 vector for n and a 1-by-21 vector for x. These have different numbers of elements, and therefore can't be multiplied element-by-element. However, you can rewrite f to accommodate vectors for each and perform the sum from g by using matrix multiplication:
f = #(n, x, t) (1./n.*log(n.*pi.*t))*sin(pi.*n(:)*x);
g = #(m, x, t) x.^2 + f(1:m, x, t);
And now your plot will work:
x = -1:0.1:1;
plot(x, g(5, x, 0.5));

Plot sine function in MATLAB

I'm trying to plot this equation but i'm some difficulties, some help please.
I here is what i have tried.
x=[0:pi/20:4*pi];
y= (25*sin(3)*t);
plot (x,y)
Your code isn't working because t is undefined. You either need to change your definition of x to be t, for example:
t=[0:pi/20:4*pi];
or you need to make your y a function of x, rather than t, for example:
y= (25*sin(3)*x);
I am curious if your original equation/function that you are trying to plot is y(t)=25 sin(3 t). If this is the case, then you need to change your parenthesis so that sin is a function of the independent variable (x or t). This would look like:
y = 25*sin(3*x);
I think you meant to get oscillations:
x = [0:pi/20:4*pi];
y = 25*sin(3*x);
plot(x,y)
You need to assign equal vector length value to t as of x.
However, I believe, you need to replace x with t in your equation.
y= (25*sin(3)*x); # will plot a straight line since you have a constant sin(3)
# which you are just multiplying with x resulting in x verses constant x
I assume you want to write the equation as
x=[0:pi/20:4*pi];
y= (25*sin(3*x));
plot (x,y)
Plot Matlab

Matlab: finding polar coordinates from cartesian coordinates

I am a newcomer to Matlab and programming in general. My Cartesian to polar conversion function that I wrote doesn't work.
syms x y
function [r,theta]=something[x,y]
r=(x^2+y^2)^.5
theta=atan(x/y)
end
What you are trying to do is create a function script file, but you have a non-function declaration statement at the beginning of your file. You can't do this. As such, you need to remove the syms x y statement at the beginning of your code. Also, you aren't declaring your function properly. You need to use round braces, not square braces to define your input parameters.
I would also use atan2 instead of atan because it finds the proper four-quadrant arc-tangent of the Cartesian coordinates. Also, use sqrt not ^.5 to take the square root. It's more stable. Also, to properly handle vector inputs, you need to make sure that x and y use .^2 in the r calculation and not ^2. Therefore, do this instead:
function [r,theta]=something(x,y) %// Change
r=sqrt(x.^2 + y.^2); %// Change
theta=atan2(y, x); %// Change
end
Place that into a file called something.m, then you can go into the command prompt and do this:
[r,theta] = something(x,y);
x and y are the x and y values of your Cartesian coordinates. What's great is that x and y can be a single value, a vector or a matrix of any size.
You can use the cart2pol function:
[theta, rho] = cart2pol(x, y)
Or do this:
theta = atan2(y, x) % use atan2() instead of atan()
rho = sqrt(x.^2 + y.^2) % use sqrt() instead of .^5
This is very easy with complex numbers. Specifically, if the given Cartesian coordinates are interpreted as the real and imaginary parts of a complex number, then the polar coordinates are the magnitude (abs) and argument (angle) of that complex number:
>> z = x+1j*y;
>> r = abs(z);
>> theta = angle(z);

How do I plot relations in matlab?

I want to plot relations like y^2=x^2(x+3) in MATLAB without using ezplot or doing algebra to find each branch of the function.
Does anyone know how I can do this? I usually create a linspace and then create a function over the linspace. For example
x=linspace(-pi,pi,1001);
f=sin(x);
plot(x,f)
Can I do something similar for the relation I have provided?
What you could do is use solve and allow MATLAB's symbolic solver to symbolically solve for an expression of y in terms of x. Once you do this, you can use subs to substitute values of x into the expression found from solve and plot all of these together. Bear in mind that you will need to cast the result of subs with double because you want the numerical result of the substitution. Not doing this will still leave the answer in MATLAB's symbolic format, and it is incompatible for use when you want to plot the final points on your graph.
Also, what you'll need to do is that given equations like what you have posted above, you may have to loop over each solution, substitute your values of x into each, then add them to the plot.
Something like the following. Here, you also have control over the domain as you have desired:
syms x y;
eqn = solve('y^2 == x^2*(x+3)', 'y'); %// Solve for y, as an expression of x
xval = linspace(-1, 1, 1000);
%// Spawn a blank figure and remember stuff as we throw it in
figure;
hold on;
%// For as many solutions as we have...
for idx = 1 : numel(eqn)
%// Substitute our values of x into each solution
yval = double(subs(eqn(idx), xval));
%// Plot the points
plot(xval, yval);
end
%// Add a grid
grid;
Take special care of how I used solve. I specified y because I want to solve for y, which will give me an expression in terms of x. x is our independent variable, and so this is important. I then specify a grid of x points from -1 to 1 - exactly 1000 points actually. I spawn a blank figure, then for as many solutions to the equation that we have, we determine the output y values for each solution we have given the x values that I made earlier. I then plot these on a graph of these points. Note that I used hold on to add more points with each invocation to plot. If I didn't do this, the figure would refresh itself and only remember the most recent call to plot. You want to put all of the points on here generated from all of the solution. For some neatness, I threw a grid in.
This is what I get:
Ok I was about to write my answer and I just saw that #rayryeng proposed a similar idea (Good job Ray!) but here it goes. The idea is also to use solve to get an expression for y, then convert the symbolic function to an anonymous function and then plot it. The code is general for any number of solutions you get from solve:
clear
clc
close all
syms x y
FunXY = y^2 == x^2*(x+3);
%//Use solve to solve for y.
Y = solve(FunXY,y);
%// Create anonymous functions, stored in a cell array.
NumSol = numel(Y); %// Number of solutions.
G = cell(1,NumSol);
for k = 1:NumSol
G{k} = matlabFunction(Y(k))
end
%// Plot the functions...
figure
hold on
for PlotCounter = 1:NumSol
fplot(G{PlotCounter},[-pi,pi])
end
hold off
The result is the following:
n = 1000;
[x y] = meshgrid(linspace(-3,3,n),linspace(-3,3,n));
z = nan(n,n);
z = (y .^ 2 <= x .^2 .* (x + 3) + .1);
z = z & (y .^ 2 >= x .^2 .* (x + 3) - .1);
contour(x,y,z)
It's probably not what you want, but I it's pretty cool!

Numerically integrate a function f(x) over x using MATLAB where f(x) has another argument y which is a vector

I would like to numerically integrate a vector which represents a function f(x) over the range of x specified by bounds x0 and x1 in Matlab. I would like to check that the output of the integration is correct and that it converges.
There are the quad and quadl functions that serve well in identifying the required error tolerance, but they need the input argument to be a function and not the resulting vector of the function. There is also the trapz function where we can enter the two vectors x and f(x), but then it computes the integral of f(x) with respect to x depending on the spacing used by vector x. However, there is no given way using trapz to adjust the tolerance as in quad and quadl and make sure the answer is converging.
The main problem why I can't use quad and quadl functions is that f(x) is the following equation:
f(x) = sum(exp(-1/2 *(x-y))), the summation is over y, where y is a vector of length n and x is an element that is given each time to the function f(x). Therefore, all elements in vector y are subtracted from element x and then the summation over y is calculated to give us the value f(x). This is done for m values of x, where m is not equal to n.
When I use quadl as explained in the Matlab manual, where f(x) is defined in a separate function .m file and then in the main calling file, I use Q = quadl(#f,x0,x1,tolerance,X,Y); here X is a vector of length m and Y is a vector of length L. Matlab gives an error: "??? Error using ==> minus
Matrix dimensions must agree." at the line where I define the function f(x) in the .m function file. f(x) = sum(exp(-1/2 *(x-y)))
I assume the problem is that Matlab treats x and y as vectors that should be of the same length when they are subtracted from each other, whereas what's needed is to subtract the vector Y each time from a single element from the vector X.
Would you please recommend a way to solve this problem and successfully numerically integrate f(x) versus x with a method to control the tolerance?
From the documentationon quad it says:
The function y = fun(x) should accept a vector argument x and return a vector result y, the integrand evaluated at each element of x.
So every time we call the function, we need to evaluate the integrand at each given x.
Also, to parameterize the function call with the constant vector Y, I recommend an anonymous function call. There's a reasonable demo here. Here's how I implemented your problem in Matlab:
function Q = test_num_int(x0,x1,Y)
Q = quad(#(x) myFun(x,Y),x0,x1);
end
function fx = myFun(x,Y)
fy = zeros(size(Y));
fx = zeros(size(x));
for jj=1:length(fx)
for ii=1:length(Y)
fy(ii) = exp(-1/2 *(x(jj)-Y(ii)));
end
fx(jj) = sum(fy);
end
end
Then I called the function and got the following output:
Y = 0:0.1:1;
x0 = 0;
x1 = 1;
Q = test_num_int(x0,x1,Y)
Q =
11.2544
The inputs for the lower and upper bound and the constant array are obviously just dummy values, but the integral converges very quickly, almost immediately. Hope this helps!
I believe the following would also work:
y = randn(10,1);
func = #(x) sum(exp(-1/2 *(x-y)));
integral(func,0,1,'ArrayValued',true)