I am not a matlab user,I just want to rewrite a function from matlab to python.
So my question is excatly like in tittle,what is meaning of X(1,:) = [x y];
When X is array and x,y are vectors?
Suppose:
x = [1 2 3]
y = [4 5 6]
Then [x y] results in
[1 2 3 4 5 6]
So the two vectors are concatenated.
X(1,:) = ... assigns the right hand side to the first row of matrix X.
X(1,:) = means "put whatever's on the right into the 1st row of X".
[x y] means horizontal concatenation.
Note that if X exists in the workspace, the combination of x and y needs to be of the correct size, or else you'll get a Subscripted assignment dimension mismatch. error.
You can see an example in the answer of m.s.
Related
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);
I have a vector of length 3. i want to represent it as a matrix of dimension 4*2. ie) if the length of vector is n then matrix should be of dimension (n+1)*2. The matrix should have elements arranged as follows:
Vector= [2 3 4]
Matrix = [0 2;2 3;3 4;4 0]
You can solve your problem easily with simple operations:
vector = [2 3 4];
matrix = [0 vector; vector 0]';
' is used to transpose the matrix.
Additionally there are two useful functions in Matlab to manipulate matrices and vectors:
reshape()
repmat()
The command reshape from Matlab is the basis of my answer to your question:
B = reshape(A,m,n) returns the m-by-n matrix B whose elements are taken column-wise from A. An error results if A does not have m*n elements (from the official Matlab help).
You basically add zeros at the beginning and at the end and then have every number in the vector occur twice (if you "unfold"/reshape the matrix). So lets construct the desired matrix by reversing this description:
%set input vector
v = [2 3 4];
%"double" the numbers, v_ is my temporary storage variable
v_ = [v; v];
%align all numbers along one dimension
v_ = reshape(v_, 2*length(v), 1)
%add zeros at beginning and end
v_ = [0 v_ 0];
%procude final matrix
m = reshape(v_, length(v)+1, 2);
in short
%set input vector
v = [2 3 4];
%"double" the numbers, v_ is my temporary storage variable
%all values are aligned as row vector
%zeros are added at beginning and end
v_ = [0, v, v, 0];
%produce final matrix
m = reshape(v_, length(v)+1, 2);
I haven't checked it, since I don't have a Matlab at hand right now, but you should get the idea.
Edit
The answer by 13aumi manages this task even without the reshape command. However, you need to pay close attention to the shape of v (row- vs- column-vector).
I am thinking of recast a double for loop into something I can use with parallel computing. Specifically, I have
for i = 1 : N
x = x0+i*dx;
for j = 1 : N
y = y0+j*dy;
end
end
and the main program calls functions that require x and y as input arguments. In my problem the variables x and y are independent and so the two for loops should be able to recast into something simpler that can be run more efficiently taking advantage of matlab's matrix computations.
I'm thinking of creating a nested 2D array like (symbolically):
A = [{x0,y0},{x0,y1},{x0,y2},...,{x0,yN};
{x1,y0},{x1,y1},{x1,y2},...,{x1,yN};
...
{xN,y0},{xN,y1},{xN,y2},...,{xN,yN}]
i.e. each element in a 2D array is a 2-tuple {xi,yi} formed from the elements of the vectors x and y. Can I create such an object in matlab? If so, how can I call each individual element within each tuple? I need to have a way to call each element, e.g. x2 in {x2,y1}, in this array.
I am thinking of doing this so as to have the program run in parallel with input arguments given by each set of tuple {xi,yi} simultaneously, using the parallel processing toolbox on a GPU.
Many thanks in advance for your help.
James
I think what you are actually looking for is either meshgrid or ndgrid
>> [x y] = meshgrid( 1:N, 1:N )
For N=3 you'll get
>> [x y] = meshgrid( 1:3, 1:3 )
x =
1 2 3
1 2 3
1 2 3
y =
1 1 1
2 2 2
3 3 3
Now if you want to access a pair you can access its x and y coordinate for each matrix.
For example accessing the coordinates of ii=1, jj=2
>> ii=1; jj=2;
>> [x(ii,jj) y(ii,jj)]
Several comments
If you want both x and y to assume the same range of values (like in this example 1:N), you can skip the second arguemnt of meshgrid
>> [x y] = meshgrid( 1:N );
You can modify the inputs of meshgrid to capture the exact pattern you want for x and y, using dx and dy:
>> [x y] = meshgrid( x0 + (1:N)*dx, y0 + (1:N)*dy );
It is best not to use i and j as variable names in Matlab.
I am trying to write code to get the 'N-dimensional product' of vectors. So for example, if I have 2 vectors of length L, x & y, then the '2-dimensional product' is simply the regular vector product, R=x*y', so that each entry of R, R(i,j) is the product of the i'th element of x and the j'th element of y, aka R(i,j)=x(i)*y(j).
The problem is how to elegantly generalize this in matlab for arbitrary dimensions. This is I had 3 vectors, x,y,z, I want the 3 dimensional array, R, such that R(i,j,k)=x(i)*y(j)*z(k).
Same thing for 4 vectors, x1,x2,x3,x4: R(i1,i2,i3,i4)=x1(i1)*x2(i2)*x3(i3)*x4(i4), etc...
Also, I do NOT know the number of dimensions beforehand. The code must be able to handle an arbitrary number of input vectors, and the number of input vectors corresponds to the dimensionality of the final answer.
Is there any easy matlab trick to do this and avoid going through each element of R specifically?
Thanks!
I think by "regular vector product" you mean outer product.
In any case, you can use the ndgrid function. I like this more than using bsxfun as it's a little more straightforward.
% make some vectors
w = 1:10;
x = w+1;
y = x+1;
z = y+1;
vecs = {w,x,y,z};
nvecs = length(vecs);
[grids{1:nvecs}] = ndgrid(vecs{:});
R = grids{1};
for i=2:nvecs
R = R .* grids{i};
end;
% Check results
for i=1:10
for j=1:10
for k=1:10
for l=1:10
V(i,j,k,l) = R(i,j,k,l) == w(i)*x(j)*y(k)*z(l);
end;
end;
end;
end;
all(V(:))
ans = 1
The built-in function bsxfun is a fast utility that should be able to help. It is designed to perform 2 input functions on a per-element basis for two inputs with mismatching dimensions. Singletons dimensions are expanded, and non-singleton dimensions need to match. (It sounds confusing, but once grok'd it useful in many ways.)
As I understand your problem, you can adjust the dimension shape of each vector to define the dimension that it should be defined across. Then use nested bsxfun calls to perform the multiplication.
Example code follows:
%Some inputs, N-by-1 vectors
x = [1; 3; 9];
y = [1; 2; 4];
z = [1; 5];
%The computation you describe, using nested BSXFUN calls
bsxfun(#times, bsxfun(#times, ... %Nested BSX fun calls, 1 per dimension
x, ... % First argument, in dimension 1
permute(y,2:-1:1) ) , ... % Second argument, permuited to dimension 2
permute(z,3:-1:1) ) % Third argument, permuted to dimension 3
%Result
% ans(:,:,1) =
% 1 2 4
% 3 6 12
% 9 18 36
% ans(:,:,2) =
% 5 10 20
% 15 30 60
% 45 90 180
To handle an arbitrary number of dimensions, this can be expanded using a recursive or loop construct. The loop would look something like this:
allInputs = {[1; 3; 9], [1; 2; 4], [1; 5]};
accumulatedResult = allInputs {1};
for ix = 2:length(allInputs)
accumulatedResult = bsxfun(#times, ...
accumulatedResult, ...
permute(allInputs{ix},ix:-1:1));
end
I have a matrix
X = [1 1;2 2;3 3;4 4];
Y = [2 4];
I want a resulting matrix z to have just rows 2 and 4 (the values in Y) of X. That is,
Z = [2 2;4 4];
Any solutions?
Z = X(Y,:);
This is a pretty easily researched question in my opinion: the first result for "MATLAB matrix indexing" answers your question and has a lot more general information about selecting parts of MATLAB matrices.