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
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.)
Given are N different measurements of a sequence x1, x2, ..., xT, where x has the dimension D. The data is stored in an D x T x N Tensor, namly X. I would like to build the Tensor S with dimensions D x D x T, which defines the covariance between the dimensions of x for every timestep t (t = 1, ..., T), as fast as possible. My current approach is a for-loop, which seems to be very slow.
clear all; close all; clc; rng(0);
% - test data
D = 2;
T = 10;
N = 100;
X = rand(D,T,N);
% - covariance
tic;
S = zeros(D,D,T);
for i = 1:T
S(:,:,i) = cov(reshape((X(:,i,:)),D,N)');
end
toc;
Suppose we have a 2D meshgrid with N points (that is N = Nx*Ny, where Nx is the number of grid points in the x axis and Ny is the number of grid points in the y axis) on the grid and we have a 1D domain embedded in our meshgrid which we discretise to have M points.
Now, let A = F(ij)m be a system matrix (for some function F, with a two dimensional parameter), where the i indexes from 1 to Nx, j indexes from 1 to Ny and m indexes from 1 to M.
A is an M x N matrix. So it has M column and N rows. Clearly, implementing the M columns shouldn't be very difficult but I am having trouble envisaging how we'd implement the N rows.
In particular, we would have something like
[F^(11)_1 , F^(11)_2 - F^(11)_1 , .... , F^(11) _M - F^(11) _(M-1)]
[F^(12)_1 , F^(12)_2 - F^(12)_1 , .... , F^(12) _M - F^(12) _(M-1)]
....
[F^(1Ny)_1 , F^(1Ny)_2 - F^(1Ny)_1 , .... , F^(1Ny) _M - F^(1Ny) _(M-1)]
[F^(21)_1 , F^(21)_2 - F^(21)_1 , .... , F^(21) _M - F^(21) _(M-1)]
....
[F^(NxNy)_1 , F^(NxNy)_2 - F^(NxNy)_1 , .... , F^(NxNy) _M - F^(NxNy) _(M-1)]
Thus M columns and N=Nx*Ny rows.
I am trying to implement this on Matlab and I guess it should begin something like:
x = 1:.5:10;
y = 1:.5:10;
[X Y] = meshgrid(x,y); % create mesh grid
Nx = length(x);
Ny = length(y);
N = Nx*Ny; % number of points in our mesh grid
M = 20; % arbitrary choice
Y0 = 5; % fixed y vector
F = besselh(0,2,norm([X Y]-[X(:,m),Y0])); % a 2D function we want to sum over the loop
A = zeros(M,N); % preallocate the memory
for i = 1:Nx
for j = 1:Ny
for m =1:M
A = F(i,j,m);
...
But I don't really have too much of an idea. Maybe a loop isn't even the way to go
Note that for those commenting about the readability I provide a snippet of the mathematical problem I am dealing with (although not all details are important, of course):
Note that rho is a vector on the Euclidean plane and the i and j subscripts represent the x and y component respectively. rho_{x_s,y_s} is just a fixed point in the Euclidean plane and lambda > 0 is a constant.
Here's an example. Your F isn't valid matlab code, so I've replaced it here with a 'toy' function, just to show you the method.
% Parameters
x = 1:.5:10; y = 1:.5:10; [X Y] = meshgrid(x,y); % create mesh grid
Nx = length(x); Ny = length(y); N = Nx * Ny;
M = 20; % arbitrary choice
% Example 'F' Function (here in the form of an 'anonymous function' handle);
F = #(i,j,m) (10*i - 5*j) * m;
% Evaluate F at each i,j,m index and collect as a 3D array.
A = zeros(M, Nx, Ny); % preallocation
for i = 1:Nx, for j = 1:Ny, for m =1:M
A(m, i, j) = F(i, j, m);
end, end, end
A = reshape(A, [M, N]);
A = A.' % transpose to place 'M' dimension as columns and rest as rows.
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
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)