Address each Matlab array element, one by one, independent from dimension (row vs. column) [duplicate] - arrays

This question already has an answer here:
Why, if MATLAB is column-major, do some functions output row vectors?
(1 answer)
Closed 7 years ago.
I would like to do something with each element in an array. For a row array, I can do this:
array = [1 2 3];
i = 0;
for a = array
i = i + 1;
end
fprintf('Number of iterations: %g\n', i)
Number of iterations: 3
It will output 3, so it actually accessed each array element one after another.
However if the array is a column, the same code will output just 1:
array = [1; 2; 3];
...
Number of iterations: 1
I wonder why exactly this happens and if there is a way to iterate through an array, independent from its "directional dimension" and without using for i = 1:numel(array), a = array(i).

When a for loop is initialized with an array, it iterates column by column. This may not be what you want, but that the built in behavior (see http://www.mathworks.com/help/matlab/ref/for.html).
You can force your matrix into a linear row vector, so MATLAB will iterate the elements 1 by 1 with the following:
for i = A(:)'
i % use each value of A
end
Normally, a combination of vector operations will be faster than a for loop, so only use a for loop when you can't think of the appropriate vector operation equivalent.

Related

how to access an element of an n-D matrix where index comes from a mathematical operation [duplicate]

This question already has answers here:
MATLAB: Accessing an element of a multidimensional array with a list
(2 answers)
Use a vector as an index to a matrix
(3 answers)
Closed 5 years ago.
How can I access an element of an n-D matrix where index comes from a mathematical operation in Matlab?
For example I have a 4D Matrix called A.
I want to access element 1,1,1,1 which results from (3,4,5,6) - (2,3,4,5)
Is there any way I can do this assuming that the array can be any dimension d and that the array from subtraction will always be d elements long?
One possible way would be to utilise the fact that MATLAB can use linear indexing for any n-dimensional array as well as row-column type indexing. Then you just have to calculate the linear index of your operation result.
There may be a more elegant way to do this but if x is the array holding the result of your operation, then the following works
element = A(sum((x-1).*(size(A).^[0:length(size(A))-1]))+1);
The sub2ind function feels like it should help here, but doesn't seem to.
Another approach is to converting to a cell array, then to a comma-separated list:
A = rand(3,4,5,6); % example A
t = [2 1 3 4]; % example index
u = num2cell(t);
result = A(u{:});

Matlab matrix indexing from 2 Arrays (X,Y) [duplicate]

This question already has answers here:
Two arrays defining 2D coordinates, as array indices
(2 answers)
Closed 2 years ago.
I have X and Y positions for a large array and I would like to use them to define what the contents of that position. I could run a for loop to define the positions but I think there would be a faster method. I tried to use the array position define function.
x = [6,2,3]
y = [1,2,3]
c = [1,1,1,2,2,3;...
1,1,1,2,2,5;...
2,2,1,4,2,3;...
1,1,4,3,2,3;...
1,2,3,4,5,3;...
1,2,3,5,4,2];
When I type the equation above it results in the answer below
c(y,x)
ans =
1 2 3
1 1 1
2 2 1
What I'm looking for are the 1:1 positions from the arrays.
c(y(1),x(1))
c(y(2),x(2))
c(y(3),x(3))
Is there any way to limit the arrays to a linear sequence? my only guess right now is to reshape the arrays into a cell matrix containing the individual a and b and then perform a cellfun. but I think I'm making it to complicated.
You have to convert the locations into linear indices first, then you can grab the correct elements in the desired linear sequence. You can use sub2ind to help you do that:
ind = sub2ind(size(c), y, x); % Get linear indices
v = c(ind); % Get the elements
Doing this thus gives:
>> v = c(ind)
v =
3 1 1
You can verify for yourself that each pair of (y,x) gives you the right element you're looking for. For example, when y = 1 and x = 6, the element retrieved is 3 and so on.

Repeat values in array n-times with different values for n [duplicate]

This question already has answers here:
Repeat copies of array elements: Run-length decoding in MATLAB
(5 answers)
Closed 7 years ago.
I'm having problems with the following task. I have a dummy array of zeros and 2 vectors of equal size. For example:
array1 = zeros(750,1);
vector1 = [1;3;5];
vector2 = [100;250;400];
I am looking to fill array1 as follows:
repeat element 1 in vector1 100 times
repeat element 2 in vector2 250 times
repeat element 3 in vector1 400 times
The resulting vector should have 7 rows and 1 column. I tried playing around with repmat but can't get it to output only 1 dimension. I also heard about bsxfun but I never end up with the data I need. I'm grateful for any useful suggestions.
I have Matlab 2013, so I'm not able to use the fancy function repelem that I found might be useful.
array1(1:100) = vector1(1);
array1(101:350) = vector2(2);
array1(351:750)=vector1(3);
though why the total length is 2850 is beyond me.
Maybe something like:
vector1 = [1;3;5];
vector2 = [100;250;400];
temp = linspace(1,sum(vector2),sum(vector2))';
array1 = zeros(size(temp));
for ii = 1:length(vector2)
array1 = array1 + (temp <= sum(vector2(1:ii)) & not(array1))*vector1(ii);
end
clear temp ii

Storing multiple powers of matrices in matlab [duplicate]

This question already has answers here:
How to generate the first twenty powers of x?
(4 answers)
Closed 7 years ago.
I have 1000 matrices with dimensions 2x2.
What I now need to do is to get 30 consecutive powers of those matrices (A^2, A^3... ...A^30) and store them all.
I found a topic that suggested using bsxfun:
Vectorizing the creation of a matrix of successive powers
However, bsxfun does not work with cell arrays ("Error using bsxfun
Operands must be numeric arrays").
What can I do?
PS. A secondary question: once I have them, I want to plot 4 graphs (each corresponding to 1 of the elements of the 2x2 matrices) with 30 positions (x-axis) which will show confidence bands (16th and 84th percentile).
EDIT: Someone linked to a question that was similar to the one that I linked. From what I can understand, the question there is about a vector, not array of matrices.
Assuming your array A is 2-by-2-by-1000, here are two loops to make things work:
A = rand(2,2,1000);
K = 30;
%%
N = size(A,3);
APower = zeros(2,2,N,K);
APower(:,:,:,1) = A;
for i = 1:N
for k = 2:K
APower(:,:,i,k) = A(:,:,i)*APower(:,:,i,k-1);
%// Alternatively you could use:
%APower(:,:,i,k) = A(:,:,i)^k;
end
end
You need to replicate the matrix 30 times to do this using cellfun. For example,
a = repmat(A{1},1,30);% Select one of your A matrices
b = num2cell(1:30);
x = cellfun(#(a,b) a^b,a,b,'UniformOutput',false)
Since you need to run cellfun for each element of A another way is to use arrayfun as below.
a = A{1};
b = 1:30;
x = arrayfun(#(b) a^b,b,'UniformOutput',false)

Im looking for a way to add up elements of two arrays

i am looking for a way that i can add up elements in an array such that the first element of the first array is added to every element in the second array, then the second element in the first array is added to all every element in the second array and so on. The final vector will be length(a)*length(b) long
for example...
a=[1,2,3,4] b=[5,6,7]
answer =
[(1+5),(1+6),(1+7),(2+5),(2+6),(2+7),(3+5),(3+6),(3+7),(4+5),(4+6),(4+7)]
=[6,7,8,7,8,9,8,9,10,9,10,11]
Read up on bsxfun. It's very useful for this kind of things (and usually faster than arrayfun or for loops):
result = bsxfun(#plus, a(:).', b(:)); %'// matrix of size numel(b) x numel(a)
result = result(:).'; %'// linearize to a vector
Or, a little more freak: kron does what you want with products instead of sums. So:
result = log(kron(exp(a),exp(b)));
My first thought is to do this with arrayfun using an anonymous function that adds each scalar element of a to the full array in b. Then since you get a cell array result you can expand that cell array into the array you are looking for:
>> a=[1,2,3,4], b=[5,6,7]
>> result = arrayfun(#(x) x+b, a,'UniformOutput',false);
>> result = [result{:}]
result =
6 7 8 7 8 9 8 9 10 9 10 11
Use meshgrid to create matrices of a and b and use matrix addition to compute a+b
a=[1,2,3,4], b=[5,6,7]
[A_matrix,B_matrix] = meshgrid(a,b)
result = A_matrix + B_matrix
result = result(:)'

Resources