Im looking for a way to add up elements of two arrays - 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(:)'

Related

Count values in a vector less than each one of the elements in another vector

I have two vectors r and d and I'd like to know the number of times r<d(i) where i=1:length(d).
r=rand(1,1E7);
d=linspace(0,1,10);
So far I've got the following, but it's not very elegant:
for i=1:length(d)
sum(r<d(i))
end
This is an example in R but I'm not really sure this would work for matlab:
Finding number of elements in one vector that are less than an element in another vector
You can use singleton expansion with bsxfun: faster, more elegant than the loop, but also more memory-intensive:
result = sum(bsxfun(#lt, r(:), d(:).'), 1);
In recent Matlab versions bsxfun can be dropped thanks to implicit singleton expansion:
result = sum(r(:)<d(:).', 1);
An alternative approach is to use the histcounts function with the 'cumcount' option:
result = histcounts(r(:), [-inf; d(:); inf], 'Normalization', 'cumcount');
result = result(1:end-1);
You may build a matrix flagging values from vector r inferior to values from vector d in one time with bsxfun, then sum the values:
flag=bsxfun(#lt,r',d);
result=sum(flag,1);
For each element in d, count how many times this element is bigger than the elements in r, which is equivalent to your problem.
r=rand(1,10);
d=linspace(0,1,10);
result = sum(d>r(:))
Output:
result =
0 0 1 2 7 8 8 8 9 10

How to get the mean of first values in arrays in matrix in Matlab

If I have a square matrix of arrays such as:
[1,2], [2,3]
[5,9], [1,4]
And I want to get the mean of the first values in the arrays of each row such:
1.5
3
Is this possible in Matlab?
I've used the mean(matrix, 2) command to do this with a matrix of single values, but I'm not sure how to extend this to deal with the arrays.
Get the first elements in all arrays of matrix, then call mean function
mean(matrix(:,:,1))
maybe you need to reshape before call mean
a = matrix(:,:,1);
mean(a(:))
You can apply mean function inside mean function to get the total mean value of the 2D array at index 1. You can do similary with array at index 2. Consider the following snapshot.
After staring at your problem for a long time, it looks like your input is a 3D matrix where each row of your formatting corresponds to a 2D matrix slice. Therefore, in proper MATLAB syntax, your matrix is actually:
M = cat(3, [1,2; 2,3], [5,9; 1,4]);
We thus get:
>> M = cat(3, [1,2; 2,3], [5,9; 1,4])
M(:,:,1) =
1 2
2 3
M(:,:,2) =
5 9
1 4
The first slice is the matrix [1,2; 2,3] and the second slice is [5,9; 1,4]. From what it looks like, you would like the mean of only the first column of every slice and return this as a single vector of values. Therefore, use the mean function and index into the first column for all rows and slices. This will unfortunately become a singleton 3D array so you'll need to squeeze out the singleton dimensions.
Without further ado:
O = squeeze(mean(M(:,1,:)))
We thus get:
>> O = squeeze(mean(M(:,1,:)))
O =
1.5000
3.0000

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.

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

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.

Substitute a vector value with two values in MATLAB

I have to create a function that takes as input a vector v and three scalars a, b and c. The function replaces every element of v that is equal to a with a two element array [b,c].
For example, given v = [1,2,3,4] and a = 2, b = 5, c = 5, the output would be:
out = [1,5,5,3,4]
My first attempt was to try this:
v = [1,2,3,4];
v(2) = [5,5];
However, I get an error, so I do not understand how to put two values in the place of one in a vector, i.e. shift all the following values one position to the right so that the new two values fit in the vector and, therefore, the size of the vector will increase in one. In addition, if there are several values of a that exist in v, I'm not sure how to replace them all at once.
How can I do this in MATLAB?
Here's a solution using cell arrays:
% remember the indices where a occurs
ind = (v == a);
% split array such that each element of a cell array contains one element
v = mat2cell(v, 1, ones(1, numel(v)));
% replace appropriate cells with two-element array
v(ind) = {[b c]};
% concatenate
v = cell2mat(v);
Like rayryeng's solution, it can replace multiple occurrences of a.
The problem mentioned by siliconwafer, that the array changes size, is here solved by intermediately keeping the partial arrays in cells of a cell array. Converting back to an array concenates these parts.
Something I would do is to first find the values of v that are equal to a which we will call ind. Then, create a new output vector that has the output size equal to numel(v) + numel(ind), as we are replacing each value of a that is in v with an additional value, then use indexing to place our new values in.
Assuming that you have created a row vector v, do the following:
%// Find all locations that are equal to a
ind = find(v == a);
%// Allocate output vector
out = zeros(1, numel(v) + numel(ind));
%// Determine locations in output vector that we need to
%// modify to place the value b in
indx = ind + (0:numel(ind)-1);
%// Determine locations in output vector that we need to
%// modify to place the value c in
indy = indx + 1;
%// Place values of b and c into the output
out(indx) = b;
out(indy) = c;
%// Get the rest of the values in v that are not equal to a
%// and place them in their corresponding spots.
rest = true(1,numel(out));
rest([indx,indy]) = false;
out(rest) = v(v ~= a);
The indx and indy statements are rather tricky, but certainly not hard to understand. For each index in v that is equal to a, what happens is that we need to shift the vector over by 1 for each index / location of v that is equal to a. The first value requires that we shift the vector over to the right by 1, then the next value requires that we shift to the right by 1 with respect to the previous shift, which means that we actually need to take the second index and shift by the right by 2 as this is with respect to the original index.
The next value requires that we shift to the right by 1 with respect to the second shift, or shifting to the right by 3 with respect to the original index and so on. These shifts define where we're going to place b. To place c, we simply take the indices generated for placing b and move them over to the right by 1.
What's left is to populate the output vector with those values that are not equal to a. We simply define a logical mask where the indices used to populate the output array have their locations set to false while the rest are set to true. We use this to index into the output and find those locations that are not equal to a to complete the assignment.
Example:
v = [1,2,3,4,5,4,4,5];
a = 4;
b = 10;
c = 11;
Using the above code, we get:
out =
1 2 3 10 11 5 10 11 10 11 5
This successfully replaces every value that is 4 in v with the tuple of [10,11].
I think that strrep deserves a mention here.
Although it's called string replacement and warns for non-char input, it still works perfectly fine for other numbers as well (including integers, doubles and even complex numbers).
v = [1,2,3,4]
a = 2, b = 5, c = 5
out = strrep(v, a, [b c])
Warning: Inputs must be character arrays or cell arrays of strings.
out =
1 5 5 3 4
You are not attempting to overwrite an existing value in the vector. You're attempting to change the size of the vector (meaning the number of rows or columns in the vector) because you're adding an element. This will always result in the vector being reallocated in memory.
Create a new vector, using the first and last half of v.
Let's say your index is stored in the variable index.
index = 2;
newValues = [5, 5];
x = [ v(1:index), newValues, v(index+1:end) ]
x =
1 2 5 5 3 4

Resources