I'm having trouble letting the xi and yi ranges include anything but positive integer values because of the way I am storing data in the matrix (x and y values corresponding to the slot they are stored in), but I can't figure out a more clever way of doing it. Could someone please help me out? I'd like to be able to let xi = -30:30 and yi = -30:30.
function test3
f = #(x,y) y*sin(x) + sqrt(y);
function p
xi = 1:30;
yi = 1:30;
pts = zeros(size(xi,2),size(yi,2));
for x = xi
for y = yi
pts(x,y) = pts(x,y) + f(x,y);
end
end
surf(xi,yi,pts)
end
p
end
Actual code that I'm working on:
function Eplot(z, w, R, Psi)
ni = 0:2:4;
mi = 0;
xi = -30:30;
yi = -30:30;
pts = zeros(size(xi,2),size(yi,2));
for n = ni
for m = mi
for x = xi
for y = yi
pts(x,y) = pts(x,y) + utot(z, x/10^4, y/10^4, n, m, w, R, Psi);
end
end
end
end
surf(xi,yi,pts)
end
Eplot(zi, wi, Ri, Psii)
Use meshgrid (as stated in the documentation for surf) and write your function f to use element-by-element operations so that it can take matrix input.
f = #(x,y) y.*sin(x) + sqrt(y);
xi = -30:30;
yi = -30:30;
[x,y]=meshgrid(xi,yi);
surf(xi,yi,f(x,y))
(Also, I hope you don'y really want to plot sqrt(y) for negative values of y)
If you can't write your function in such a way that allows you to give it vector arguments, then your for loop is a reasonable method, but I would write it like this:
f = #(x,y) y.*sin(x) + sqrt(y);
xi = -30:30;
yi = -30:30;
pts=zeros(length(xi),length(yi));
for ii=1:length(xi)
for jj=1:length(yi)
pts(ii,jj)=f(xi(ii),yi(jj));
%// If `f` has more variables to iterate over (n, m, etc.) and sum,
%// do those loops inside the ii and jj loops
%// I think it makes the code easier to follow
end
end
surf(xi,yi,pts)
Related
I've been trying to evaluate a function in matlab. I want my x vector to go from 0 to 1000 and my y vector to go from 0 to 125. They should both have a length of 101.
The equation to be evaluated is z(x,y) = ay + bx, with a=10 and b=20.
a = 10;
b = 20;
n = 101;
dx = 10; % Interval length
dy = 1.25;
x = zeros(1,n);
y = zeros(1,n);
z = zeros(n,n);
for i = 1:n;
x(i) = dx*(i-1);
y(i) = dy*(i-1);
for j = 1:n;
z(i,j) = a*dy*(j-1) + b*dx*(j-1);
end
end
I get an answer, but I don't know if I did it correctly with the indices in the nested for loop?
See MATLAB's linspace function.
a=10;
b=20;
n=101;
x=linspace(0,1000,n);
y=linspace(0,125,n);
z=a*y+b*x;
This is easier and takes care of the interval spacing for you. From the linspace documentation,
y = linspace(x1,x2,n) generates n points. The spacing between the points is (x2-x1)/(n-1).
Edit:
As others have pointed out, my solution above makes a vector, not a matrix which the OP seems to want. As #obchardon pointed out, you can use meshgrid to make that 2D grid of x and y points to generate a matrix of z. Updated approached would be:
a=10;
b=20;
n=101;
x=linspace(0,1000,n);
y=linspace(0,125,n);
[X,Y] = meshgrid(x,y);
z=a*Y+b*X;
(you may swap the order of x and y depending on if you want each variable along the row or column of z.)
I'm having an issue completing this Lagrange function and I'm not sure where I'm going wrong.
I keep getting 'Index exceeds matrix dimensions' error. I assume this is because I'm not moving through the array correctly. I've tried a combination of things but seem to continue coming back to this error.
function y = lagrange(X, Y, x)
n = length(X);
if n ~= length(Y)
error('X and Y must have the same length.');
end
y = zeros(size(x));
for i = 1:n
L = ones(size(x));
for j = [1:i-1 i+1:n]
if (i~=j)
L(1:i-1, i+1:n) = L(1:i-1, i+1:n).*(x-X(j))/(X(i)-X(j));
end
end
y = y+Y(i)*L(1:i-1);
end
I think the function below is what you need.
function y = lagrangian(X, Y, x)
if length(X) ~= length(Y); error('X and Y must have the same length.'); end
y = zeros(size(x));
for i = 1:length(X)
L = ones(size(x));
for j = [1:i-1 i+1:length(X)]
L = L.*(x-X(j))/(X(i)-X(j));
end
y = y+Y(i)*L;
end
Could you please help me with the following question:
I want to solve a second order equation with two unknowns and use the results to plot an ellipse.
Here is my function:
fun = #(x) [x(1) x(2)]*V*[x(1) x(2)]'-c
V is 2x2 symmetric matrix, c is a positive constant and there are two unknowns, x1 and x2.
If I solve the equation using fsolve, I notice that the solution is very sensitive to the initial values
fsolve(fun, [1 1])
Is it possible to get the solution to this equation without providing an exact starting value, but rather a range? For example, I would like to see the possible combinations for x1, x2 \in (-4,4)
Using ezplot I obtain the desired graphical output, but not the solution of the equation.
fh= #(x1,x2) [x1 x2]*V*[x1 x2]'-c;
ezplot(fh)
axis equal
Is there a way to have both?
Thanks a lot!
you can take the XData and YData from ezplot:
c = rand;
V = rand(2);
V = V + V';
fh= #(x1,x2) [x1 x2]*V*[x1 x2]'-c;
h = ezplot(fh,[-4,4,-4,4]); % plot in range
axis equal
fun = #(x) [x(1) x(2)]*V*[x(1) x(2)]'-c;
X = fsolve(fun, [1 1]); % specific solution
hold on;
plot(x(1),x(2),'or');
% possible solutions in range
x1 = h.XData;
x2 = h.YData;
or you can use vector input to fsolve:
c = rand;
V = rand(2);
V = V + V';
x1 = linspace(-4,4,100)';
fun2 = #(x2) sum(([x1 x2]*V).*[x1 x2],2)-c;
x2 = fsolve(fun2, ones(size(x1)));
% remove invalid values
tol = 1e-2;
x2(abs(fun2(x2)) > tol) = nan;
plot(x1,x2,'.b')
However, the easiest and most straight forward approach is to rearrange the ellipse matrix form in a quadratic equation form:
k = rand;
V = rand(2);
V = V + V';
a = V(1,1);
b = V(1,2);
c = V(2,2);
% rearange terms in the form of quadratic equation:
% a*x1^2 + (2*b*x2)*x1 + (c*x2^2) = k;
% a*x1^2 + (2*b*x2)*x1 + (c*x2^2 - k) = 0;
x2 = linspace(-4,4,1000);
A = a;
B = (2*b*x2);
C = (c*x2.^2 - k);
% solve regular quadratic equation
dicriminant = B.^2 - 4*A.*C;
x1_1 = (-B - sqrt(dicriminant))./(2*A);
x1_2 = (-B + sqrt(dicriminant))./(2*A);
x1_1(dicriminant < 0) = nan;
x1_2(dicriminant < 0) = nan;
% plot
plot(x1_1,x2,'.b')
hold on
plot(x1_2,x2,'.g')
hold off
Let's say I have a function
f = #(x,y) g(x,y)
g is not explicit. It should be calculated numerically after inputting x and y values.
How can I calculate and save all values of this function at points
[x,y] = meshgrid(0:0.1:1,0:pi/10:2*pi);
I call f[x,y], but it doesn't work.
You have two ways to do it. Your function g should work with matrices, or you should give the values one by one
function eval_on_mesh()
f1 = #(x,y) g1(x,y);
f2 = #(x,y) g2(x,y);
[x,y] = meshgrid(0:0.1:1,0:pi/10:2*pi);
%# If your function work with matrices, you can do it like here
figure, surf(f1(x,y));
%# If your function doesnt, you should give the values one by one
sol = zeros(size(x));
for i=1:size(x,1)
for j=1:size(x,2)
sol(i,j) = f2(x(i,j),y(i,j));
end
end
figure, surf(sol);
end
function res = g1(x, y)
res = x.^2 + y.^2;
end
function res = g2(x, y)
res = x^2 + y^2;
end
I am trying to plot this function in MATLAB:
f(x) = (1./(2*b))*((erf(1./(2*D)+((x/b)-2*n)/D)+ erf(1./(2*D)-((x/b)-2*n)/D)));
The function is to plotted as a sum of n values from 0 to N, where N is a real number and b is a constant; for a range of D values. I am supposed to have different plots for each value in range D representing the function. How can I go about this please?
The different ranges of D can be done like this:
f = #(x, D)(x + D);
x = -10:10; %// pick a good range
D = 1:5; %// pick a good range
figure()
hold all
for d = D
plot(x, f(x, d))
end
I'm not 100% sure what you mean about the summing 0:N bit but maybe it's something of this form:
figure()
hold all
x= -10:10;
for d = 1:5
y = zeros(size(x)); %// Preallocation of memory for speed
for n = 0:10
y = y + n*x + d
end
plot(x, y)
end