surface plot in Matlab - matlab

I am trying to graph a surface with a diagonal matrix, the equation I am trying graph is f = x^TDx, x is a 2 by 1 vector and D is a 2 by 2 matrix.
Here is what have so far, but I keep getting error.
x = linspace(-10,10);
y = linspace(-10,10);
[X,Y] = meshgrid(x,y);
D = [1 0; 0 1];
f = #(x,y) [x,y]*D*[x,y].'; % [x,y] is 1 by 2
contour (X,Y,f(X,Y))
Can someone tell me how to get rid of the error? Thanks

Since x and y have the same length, your diagonal matrix D must be a square matrix of size n x n, with n equal to two times the length of your x or y vectors. The reason why you need to multiply the length by two is because the operation [x,y] concatenates the arrays horizontally thus duplicating one of the dimensions.
In this example D is the Identity matrix. See eye for more information.
x = linspace(-10,10); % x is 1x100
y = linspace(-10,10); % y is 1x100
[X,Y] = meshgrid(x,y); % X is 100x100 and Y is 100x100
D = eye(2*numel(x)); % D is 2*100x2*100 = 200x200
f = #(x,y) [x,y]*D*[x,y].'; % [X,Y] is 100x200 and [X,Y].' is 200x100
contour (X,Y,f(X,Y))
If you want D to be a random diagonal matrix, you can accomplish this combining diag with one of the Random Number Generation functions available, like for example randn.
On the previous example, replace D with the following instruction:
D = diag(randn(1,2*numel(x)));
You can also give the coefficients you choose to the diagonal matrix. To do so, you will need to create the vector of coefficients manually, making sure that it has the adequate length, so that it satisfies the conditions explained at the beginning of this post.
Try now replacing D with the following instructions:
v = 1:2*numel(x); % vector of coefficients: v = [1 2 ... 200]
D = diag(v);

Related

How can I multiply a matrix with vector and reshape it using one matrix multiplication using matlab

I have a matrix X with size N x N, and a vector Y with size NM x 1. I want to multiply the matrix X with every N elements in Y and then reshape the resultant matrix Z row-wise. In other words, I first reshape the vector Y into a matrix Y_2 with size N x M . Then, get the matrix Z = X * Y_2, and finally reshape the matrix Z row-wise.
That process, I want to do it in matlab using matrices multiplications, as follows:
clear all; clc; clear;
N = 4; M = 8;
X = randn(N,N);
Y = randn(N*M,1);
Z = kron(eye(M,M),X) * Y;
The problem, is that I don't get $Z$ similar to that process explained above. I mean the result of the way I used in Matlab code is not similar to the results of the process explained before. how can I do it, where is it error in my other method?

Curve fitting of complex variable in Matlab

I want to solve the following system of equations shown in the image below,
The matrix system
where the component of the matrix A is complex numbers with the angle (theta) runs from 0 to 2*pi which has m divisions, and n = 9. The known value z = x + iy. Suppose the x and y of matrix z is
z =
0 1.0148
0.1736 0.9848
0.3420 0.9397
0.5047 0.8742
0.6748 0.8042
0.8419 0.7065
0.9919 0.5727
1.1049 0.4022
1.1757 0.2073
1.1999 0
1.1757 -0.2073
1.1049 -0.4022
0.9919 -0.5727
0.8419 -0.7065
0.6748 -0.8042
0.5047 -0.8742
0.3420 -0.9397
0.1736 -0.9848
0 -1.0148
How do you solve them iteratively? Notice that the value of the first component of the desired constants must equal 1. I am working with Matlab.
You can apply simple multilinear regression for complex valued data.
Step 1. Get the matrix ready for linear regression
Your linear system
written without matrices, becomes
that rearranged yelds
If you rewrite it with matrices you get
Step 2. Apply multiple linear regression
Let the system above be
where
Now you can apply linear regression, that returns the best fit for α when
where
is the conjugate transpose.
In MATLAB
Y = Z - A(:,1); % Calculate Y subtracting the first col of A from Z
R = A(:,:); R(:,1) = []; % Calculate R as an exact copy of A, just without first column
Rs = ctranspose(R); % Calculate R-star (conjugate transpose of R)
alpha = (Rs*R)^(-1)*Rs*Y; % Finally apply multiple linear regression
alpha = cat(1, 1, alpha); % Add alpha1 back, whose value is 1
or, if you prefer built-ins, have a look at regress function:
Y = Z - A(:,1); % Calculate Y subtracting the first col of A from Z
R = A(:,:); R(:,1) = []; % Calculate R as an exact copy of A, just without first column
alpha = regress(Y, R); % Finally apply multiple linear regression
alpha = cat(1, 1, alpha); % Add alpha1 back, whose value is 1

Using meshgrid in MATLAB when the function has matrix operations

I need to plot level surfaces of a 3 variable function. The variables are in a column vector X = [x, y, z]^t. The function is f(X) = X^t * A * X. Where ^t means transpose and A is a 3x3 constant matrix. I know for a fact that A is symmetric and therefore diagonalizable, i.e. A = V * D * V^t. Just in case it turns out to be useful.
I intend to use isosurface to get the points of the function where it equals a certain level and then use patch to plot.
However I can't figure out how to compute the value of the function for every point in the grid. Ideally I'd like to do
x = linspace(-1, 1,10); y=x; z = x;
[XX,YY,ZZ]=meshgrid(x,y,z);
f = [XX YY ZZ]'*A*[XX YY ZZ];
level = 1;
s = isosurface(XX,YY,ZZ,f,level);
patch(s, 'EdgeColor','none','FaceColor','blue');
but this won't work obviously because of the sizes of XX and A. What I've done so far is do the math myself to obtain the function as a polynomial of XX, YY and ZZ but it's incredibly ugly and not practical.
Anybody knows how to do this? Thanks!
If I understand correctly, this does that you want. In the following explanation I will use 10x10x10 points as given in your example (although the code works for any number of points). Also, I define a random 3x3 matrix A.
Once XX, YY and ZZ have been generated as 10x10x10 arrays (step 1), the key is to build a 1000x3 matrix in which the first column is x coordinate, the second is y and the third is z. This is variable XYZ in the code below (step 2).
Since XYZ is a matrix, not a vector, the function f can't be computed using matrix multiplication. But it can be obtained efficiently with bsxfun. First compute an intermediate 1000x3x3 variable (XYZ2) with all 3x3 products of coordinates for each of the 1000 points (step 3). Then reshape it into a 1000x9 matrix and multiply by the 9x1 vector obtained from linearizing A (step 4).
The f thus obtained has size 1000x1. You need to reshape it into a 10x10x10 array to match XX, YY and ZZ (step 5). Then you can use isosurface as per your code (step 6).
A = rand(3);
x = linspace(-1, 1,10); y = x; z = x;
[XX,YY,ZZ] = meshgrid(x,y,z); %// step 1
XYZ = [XX(:) YY(:) ZZ(:)]; %// step 2
XYZ2 = bsxfun(#times, XYZ, permute(XYZ, [1 3 2])); %// step 3
f = reshape(XYZ2,[],numel(A))*A(:); %// step 4
f = reshape(f, size(XX)); %// step 5
level = 1;
s = isosurface(XX,YY,ZZ,f,level);
patch(s, 'EdgeColor','none','FaceColor','blue'); %// step 6
I suspect that you could explicitly define your function as
ffun = #(x,y,z) [x y z]*A*[x; y; z];
then use arrayfun to apply this function to each element of your coordinate vectors:
f = arrayfun(ffun,XX,YY,ZZ);
This will return f(i)=ffun(XX(i),YY(i),ZZ(i)) for each i in 1:numel(XX), which I think is what you are after. The output f will have the same shape as your input arrays, which seems perfectly fine to use with isosurface later.

' vectors must be the same length' error

I've got a 250 x 250 image, I want to have a scatter plot of the intensity of every pixel and its nearest neighborhood. This is my code:
I = imread(image);
i = [1,249];
j = [1,250];
X = I(i,j);
Y = I(i+1,j);
scatter(X,Y);
why do I get the " X and Y vectors must be the same length" error? They are the same length !
Because scatter(X, Y) is only used for vectors, not matrix. In your example, both X and Y are 2x2 matrices, not vectors.
From its documentation:
scatter(X,Y) displays circles at the locations specified by the vectors X and Y. This type of graph is also known as a bubble plot.
Edit: if you want to plot matrix, use plotmatrix() instead:
plotmatrix(X,Y)
Scatter(X,Y) is used only for vectors as herohuyongtao correctly mentioned. You could try to do the following:
m = 250;
X = I(m+1:end);
Y = I(1:end-m);
scatter(X,Y);
You convert your image matrix I into a vector X while ignoring the first column and in a vector Y while ignoring the last column. X(n) is thus the neighbour of Y(n) on the right side.
I hope this helps!

Using matlabs regress like polyfit

I have:
x = [1970:1:2000]
y = [data]
size(x) = [30,1]
size(y) = [30,1]
I want:
% Yl = kx + m, where
[k,m] = polyfit(x,y,1)
For some reason i have to use "regress" for this.
Using k = regress(x,y) gives some totally random value that i have no idea where it comes from. How do it?
The number of outputs you get in "k" is dependant on the size of input X, so you will not get both m and k just by putting in your x and y straight. From the docs:
b = regress(y,X) returns a p-by-1 vector b of coefficient estimates for a multilinear regression of the responses in y on the predictors in X. X is an n-by-p matrix of p predictors at each of n observations. y is an n-by-1 vector of observed responses.
It is not exactly stated, but the example in the help docs using the carsmall inbuilt dataset shows you how to set this up. For your case, you'd want:
X = [ones(size(x)) x]; % make sure this is 30 x 2
b = regress(y,X); % y should be 30 x 1, b should be 2 x 1
b(1) should then be your m, and b(2) your k.
regress can also provide additional outputs, such as confidence intervals, residuals, statistics such as r-squared, etc. The input remains the same, you'd just change the outputs:
[b,bint,r,rint,stats] = regress(y,X);