array of matrices numpy - arrays

I need to make an array of matrices in numpy. This is so I can treat them as scalars and dot this with another array, like so:
a = [1,2,3]
b = [A,B,C] #A, B, and C are matrices
result = a.dot(b) #1A + 2B + 3C
Or similarly with a matrix M such that:
M.dot(b) -> another array of matrices
Is there a way of doing this? Currently, every array-like thing gets subsumed into the numpy array outside that allows .dot() in the first place. So, if A, B, and C were 3x3 matrices, a would be:
a.shape -> (3,3,3) #matrices absorbed into array
Thanks.

Solution:
import numpy as np
a = np.array([1,2,3])
X= np.ones((3,3))
Y= np.ones((3,3))
Z= np.ones((3,3))
b = np.array([X,Y,Z], dtype=object)
print a.dot(b)
results in:
[[6.0 6.0 6.0]
[6.0 6.0 6.0]
[6.0 6.0 6.0]]
Remember that the length of array of scalars must be of the same size of matrices (in this case matrices 3x3, so you need an array of length 3)

Related

Create 3d matrix from 3 vectors

I have 3 vectors, named a, b and c and I want to create 3D matrix, M, so that M(i,j,k) = a(i) + b(j) + c(k), where a(i) means ith element of vector a, and likewise for all vectors and matrix.
For creating 2d matrix, it is easy like a+b'. but I am not sure how I can create 3d matrix.
You only need permute or reshape to do the multi-dimensional equivalent of transposition:
a + b.' + reshape(c, 1, 1, []);
Assuming that a, b, c are column vectors of sizes L×1, M×1 and N×1, this works because
a is L×1, or equivalently L×1×1;
b.' is 1×M×1;
reshape(c, 1, 1, [] is 1×1×N.
So, by implicit expansion the result is an L×M×N 3D array.

MATLAB vs Python numpy array/matrix multiplication

I am translating some MATLAB code and am having some problems understanding the syntaxical difference between MATLAB and numpy for Python.
In MATLAB I have a 6 by 6 matrix, A, as well as 6 float values, a, b, c, d, e, f.
The MATLAB code
B = A*[a;b;c;d;e;f];
produces a 6 by 1 matrix, B.
So I figured that the MATLAB operator '*' must correspond to the numpy operator numpy.dot().
So in my Python code I have the same matrix, A, and the same values for a, b, c, d, e and f.
B = numpy.dot(A, [[a],[b],[c],[d],[e],[f]])
does not produce the same matrix, B, and neither does
B = numpy.dot(A, [a,b,c,d,e,f])
I have also tried building the Python matrix and array with numpy's array function with the same result.
It feels like I am mixing something fundamental up here. Any help is greatly appreciated.
It's difficult to answer fully without knowing the values in A, and a,b,c,d,e,f. However, you're code seems to work:
MATLAB:
A = [1,2,3,4,5,6;
1,2,3,4,5,6;
1,2,3,4,5,6;
1,2,3,4,5,6;
1,2,3,4,5,6;
1,2,3,4,5,6];
b = [7;8;9;10;11;12];
A*b
ans =
217
217
217
217
217
217
A'*b
ans =
57
114
171
228
285
342
Python:
import numpy as np
A = np.array([[1,2,3,4,5,6],
[1,2,3,4,5,6],
[1,2,3,4,5,6],
[1,2,3,4,5,6],
[1,2,3,4,5,6],
[1,2,3,4,5,6]])
b = np.array([7,8,9,10,11,12]).reshape(6, 1)
B = np.dot(A, b)
B
array([[217],
[217],
[217],
[217],
[217],
[217]])
B = np.dot(A.transpose(), b)
B
array([[57],
[114],
[171],
[228],
[285],
[342]])
The numpy dot operator does perform matrix multiplication, so it is likely that something is going wrong with your initialisation of A which you don't show.
Note that the reshape operation is not necessary (the same results are seen regardless). However, this makes a column vector rather than a 1D array and so can be transposed etc. in the same fashion as the MATLAB array [7;8;9;10;11;12].
The vector you are multiplying is a column, so use it as a column to have a final 6x1 vector and not a 1x6 vector, as you are doing a dot product of 6x6 by 6x1 in MATLAB.
This example is for a 3x3 dimension (just to reduce the code and be understandable):
import numpy as np
A = np.array([[8,1,6],[3,5,7],[4,9,2]]) # This is the matrix
b = np.array([1,2,3]) # These are the float numbers
c = np.dot(A,b.reshape(-1,1)) # This is a 3x1 vector
This is equivalent on MATLAB to:
magic(3)*[1;2;3]

Multiplication of two arrays with dimension=5 in a vectorize way

I have a three dimensional domain in MATLAB. For each point in the domain I have defined three arrays of size (NX,NY,NZ) at each point of the domain:
A1; % size(A1) = [NX NY NZ]
A2; % size(A2) = [NX NY NZ]
A3; % size(A3) = [NX NY NZ]
For each element, I am trying to construct an array which holds the value of A1, A2, and A3. Would the following be a good candidate for having a 1×3 vector at each point?
B = [A1(:) A2(:) A3(:)];
B = reshape(B, [size(A1) 1 3]);
If the 1×3 array is named C, I am trying to find C'*C at each point.
C = [A1(i,j,k) A2(i,j,k) A3(i,j,k)]; % size(C) = [1 3]
D = C'*C; % size(D) = [3 3]
My ultimate goal is to find the array D with size 3×3 for all the points in the domain in a vectorize fashion? In fact, the output which consists of array D for each point will have the size [NX NY NZ 3 3]. Could someone help me?
Basically we concatenate A1, A2 and A3 along the 4th and 5th dimensions separately that leaves singleton dimensions in the 5th and 4th dimensions respectively, which are then used by bsxfun [Apply element-by-element binary operation to two arrays with singleton expansion enable] to expand as 3x3 matrices along the 4th-5th dimensions for matrix multiplication result from each triplet of [A1(i,j,k),A2(i,j,k),A3(i,j,k)].
D = bsxfun(#times,cat(4,A1,A2,A3),cat(5,A1,A2,A3));

convert several 2 dimensional data into 3 dimensional

I would like to combine several 2-D data into 3 dimensional data. I have 124 2-D data (151 x 151) now I want to combine all these data into 3 dimensional, so that it will be like this 124 x 151 x 151. The 2-D data contains NaN elements.
To concatenate multiple 2D arrays into a 3D array, use the generalized concatenation function cat, specifying dimension 3.
For example, given 2D arrays A1,A2,... of equal size:
M = cat(3,A1,A2,...)
Say you have k 2D arrays organized in a cell array, C, where each cell is a 2D matrix, all of size M-by-N:
M = cat(3,C{:});
Then M will be of size M-by-N-by-k. Now if you want to go from M-by-N-by-k, to k-by-M-by-N, use permute or shiftdim:
Mn = permute(M,[3 1 2]); % my preference
Mn = shiftdim(M,2);
NOTE: An alternative to cat is cell2mat:
M = cell2mat(reshape(C,1,1,[]))

Array Multiplication in Julia

I'm trying to do something that I believe should be relatively simple in Julia, but I can't seem to find any mention of this problem.
Basically what I've got is an mxn matrix, and an nx1 vector. What I would like to do is multiply the vector against the matrix, elementwise, but along the axis such that every element of the matrix is multiplied.
In numpy for instance this would be:
np.multiply(array, vector)
Is there any way to do this in Julia?
I tried just extending the vector to fill an array:
projection = 1:size(matrix)[1]
weight_change = hcat(map(x -> vector, projection))
but that yields something with a type of Array{Array{Float64, 2}, 2}, when what I really need is just Array{Float64, 2}, which means that an elementwise multiplication won't really work.
Is there any way to either fix my approach or remedy my bugged solution?
You're looking for the .* element-wise, broadcasting multiply operator:
julia> A = [ i + j*im for i=1:3, j=1:4 ]
3x4 Array{Complex{Int64},2}:
1+1im 1+2im 1+3im 1+4im
2+1im 2+2im 2+3im 2+4im
3+1im 3+2im 3+3im 3+4im
julia> v = [1:4]
4-element Array{Int64,1}:
1
2
3
4
julia> w = [1:3]
3-element Array{Int64,1}:
1
2
3
julia> A .* w
3x4 Array{Complex{Int64},2}:
1+1im 1+2im 1+3im 1+4im
4+2im 4+4im 4+6im 4+8im
9+3im 9+6im 9+9im 9+12im
julia> A .* v'
3x4 Array{Complex{Int64},2}:
1+1im 2+4im 3+9im 4+16im
2+1im 4+4im 6+9im 8+16im
3+1im 6+4im 9+9im 12+16im

Resources