This question already has answers here:
Common way to generate finite geometric series in MATLAB
(2 answers)
Closed 7 years ago.
How to calculate the first N terms of the geometric sequence Un = 2^n in Matlab?
Are there any Matlab functions that I'm not aware of to facilitate this? or do I have to pick a math book to understand this and implement it in a for loop or something?
Any links to similar Matlab code would be appreciated, or if you could explain it for me that would be appreciated!
First, you set the N terms for your sequence, i.e.:
N = 10 %//set first 10
Now you want to make a vector from 1 to N, i.e.:
n= [1:N]
Un = 2.^n %//Note the dot is very important! I almost forgot
%//ans = [2,4,8,16...1024]
This would make function a vector of 1 by N where each element is the corresponding answer to your function.
for your second question (in comment)
you want to do something like:
Bflip = B' %//This flips the matrix B so that what use to be column is now rows
So Bflip would be the result you want, I tested with your example:
A = [2 2 2;4 4 4; 6 6 6];
B = [0 0 0; 1 1 1; 2 2 2];
Bflit = [ 0 1 2
0 1 2
0 1 2]
This will generate a 3 dimension matrix. To call on each of the 4 sets of results, just do something like result1 = permutation(:,:,1)
This question already has answers here:
adding values to diagonals of matrix using element-wise addition in matlab
(3 answers)
Closed 7 years ago.
I have an (2n-1)-by-1 vector with certain values and I want to obtain an n-n matrix with the diagonals filled using the same value.
Eg. if I have
a = [1; 2; 3; 4; 5];
I want to obtain
A = [[3 4 5];[2 3 4];[1 2 3]]
= 3 4 5
2 3 4
1 2 3
My matrix dimensions are a lot bigger so I'd want this as efficient as possible. I already found following solutions:
n = 3;
A = toeplitz(a);
A = A(1:n,end-n+1:end)
and
A = a(n)*eye(n);
for j=1:n-1
A(1+j:n+1:end-j*n) = a(n-j);
A(j*n+1:n+1:end) = a(n+j);
end
I wonder if there are more efficient ways to obtain this result, keeping in mind that I am working with huge matrices and really need the speed.
ix=bsxfun(#plus,[1:n],[n-1:-1:0]'); %generate indices
A=a(ix);
or
A=hankel(a) %might be faster than toeplitz because half the matrix is zero
A(n:-1:1,1:n)
here is what hankel does internally (at least in ML R2013a), adapted to this problem:
c=[1:n];
r=[n-1:-1:0]';
idx=c(ones(n,1),:)+r(:,ones(n,1));
A=a(ix);
I guess the bsxfun solution and what thewaywewalk supposed is the fastest (it's basically the same)
Go with:
n = (numel(a)+1)/2;
A = a(bsxfun(#minus, n+1:n+n, (1:n).'));
I want to show 2dim. Surface plots for different combinations of 2 parameters of a 3- or higher-dimensional array in matlab. The data for the non-shown dimensions are integrated (i.e. summed in the remaining dimensions). I am using surf(), and for parameter combinations other than (1,2) (eg. (1,3), (2,3) ...) I have to rearrange the data matrices in order to make it work.
I am looking for an alternative command (or shorter code) which does this work.
Here's the code:
a=zeros(3,3,2);
a(:,:,1) = [1 2 3 ;4 5 6; 7 8 9; 10 11 12]; % // data matrix
a(:,:,2) = -[1 2 3 ;4 5 6; 7 8 9; 10 11 12]*2; % // data matrix
ai=[[1 2 3 4]' [5 6 7 0]' [8 9 0 0]']; % // parameter vector
mat12 = sum(a,3);
surf(ai(1:3,2),ai(1:4,1),mat12)
aux13 = sum(a,2);
for i = 1:2; mat13(:,i) = aux13(:,:,i);
surf(ai(1:2,3),ai(1:4,1),mat13)
aux23 = sum(a,1);
for i = 1:2; mat23(i,:) = aux23(:,:,i);
surf(ai(1:3,2),ai(1:2,3),mat23)
In other words, I am looking for a way to use surf for matrices mat13 and mat23 without the aux13, aux23 variables and the for loop.
First your example doesn't run because you declare a=zeros(3,3,2); as a matrix [3x3x2] but you immediately try to populate it as a [4x3x2] matrix, so I had to adjust your first line to: a=zeros(4,3,2);
If I run your code with that adjustment, your auxiliary variable and for loops are to reform/reshape a matrix stripped of it's singleton dimension. Matlab provide a handy function for that : squeeze.
For example, your variable aux13 is of dimension [4x1x2], then mat13=squeeze(aux13); achieve the same thing than your for loop. Your matrix mat13 is now of dimension [4x2].
Since no for loop is needed, you can completely bypass your auxiliary variable by calling squeeze directly on the result of your summation: mat13=squeeze( sum(a,2) );
Full example, the code below does exactly the same than your code sample:
mat12 = sum(a,3);
surf(ai(1:3,2),ai(1:4,1),mat12)
mat13 = squeeze( sum(a,2) ) ;
surf(ai(1:2,3),ai(1:4,1),mat13)
mat23 = squeeze( sum(a,1) ) ;
mat23 = mat23.' ; %'// <= note the "transpose" operation here
surf(ai(1:3,2),ai(1:2,3),mat23)
Note that I had to transpose mat23 to make it match the one in your example.
sum(a,1) is [1x3x2] => squeeze that and you obtain a [3x2] matrix but your code arrange the same values in a [2x3] matrix, so the use of the transpose. The transpose operator has a shorthand notation .'.
I used it in the example in a separate line just to highlight it. Once understood you can simply write the full operation in one line:
mat23 = squeeze(sum(a,1)).' ;
The way you write your loops isn't exactly MATLAB syntax. Below is the correct loop syntax shown.
On line 2 and 3, you are trying to load (4x3)-matrices into (3x3)-matrices. That is why you get a subscript error. You could resolve it by making the zeros-matrix bigger. Here's some Syntax fixed:
a=zeros(4,3,2);
a(:,:,1) = [1 2 3 ;4 5 6; 7 8 9; 10 11 12]; % // data matrix
a(:,:,2) = -[1 2 3 ;4 5 6; 7 8 9; 10 11 12]*2; % // data matrix
ai=[[1 2 3 4]' [5 6 7 0]' [8 9 0 0]']; % // parameter vector
mat12 = sum(a,3);
surf(ai(1:3,2),ai(1:4,1),mat12)
aux13 = sum(a,2);
for i = 1:2 mat13(:,i) = aux13(:,:,i);
surf(ai(1:2,3),ai(1:4,1),mat13)
end
aux23 = sum(a,1);
for i = 1:2 mat23(i,:) = aux23(:,:,i);
surf(ai(1:3,2),ai(1:2,3),mat23)
end
Now, what are you exactly trying to do inside those loops?
This question already has answers here:
Element-wise array replication according to a count [duplicate]
(4 answers)
Closed 8 years ago.
I would like to vectorize the creation of the following vector:
For example-
Let A be a vector [5 3 2 1]
And let B be a vector [1 2 3 4]
I would like C to be the vector [1 1 1 1 1 2 2 2 3 3 4]
Meaning- each element i in B is duplicated A(i) times in C.
I haven't found a way to vectorize the creation of this, any ideas?
Thanks in advance!
Ronen
Approach #1
Here's one approach if B doesn't have any zeros -
C = nonzeros(bsxfun(#times,bsxfun(#le,[1:max(A)]',A),B))
Approach #2
A general case solution -
mask = bsxfun(#le,[1:max(A)]',A) %//'
B_ext = bsxfun(#times,mask,B)
C = B_ext(mask)
Approach #3
cumsum based approach and must be pretty efficient one -
idx = [1 cumsum(A(1:end-1))+1] %// indices where each new B values start
C = zeros(sum(A),1) %// storage for output
C(idx) = diff([0 B]) %// put those values, but offseted
C = cumsum(C) %// finally get the output
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Element-wise array replication in Matlab
I have a m x 1 vector that I would like to repeat n times to create a (m*n)x1 vector. If I use repmat, I get something like
>> V = [a;b;c];
>> repmat(V,2,1) % n = 2, m = 3
a
b
c
a
b
c
What would be a one-line (and hopefully fast) way of getting the vector
[a;a;a;b;b;b;c;c;c]
for arbitrary n and m?
V=[ 1;2;3];
reshape(repmat(V',3,1),[],1)
ans =
1
1
1
2
2
2
3
3
3