Vectors operations in matlab - arrays

How subtract each element of row vector of size 1xN from column vector Mx1
without using loop in MatLab?
N = 1:100
M = ones(1000,1)

You can use bsxfun as suggested by Daniel
out = bsxfun(#minus, N,M);
but it might be more obvious to use meshgrid or ndgrid to get the matrix you want:
out = meshgrid(N-1,M);
These two functions internally use repmat which is slower than bsxfun, so rather go for the first approach. And bsxfun is always the fastest solution anyway ;)

Related

Creating diagonal matrix from array of matrices in MATLAB

I am interested how to create a diagonal matrix from an array of matrices.
I created an array of matrices in MATLAB:
X<62x62x1000> it consists of 1000 matrices with dimensions 62x62
I want to create a matrix of dimensions 62000x62000 with 1000 sub matrices from array X along main diagonal.
Do you have any clue how to do this, except M=blkdiag(X(:,:,1), X(:,:,2), X(:,:,3)...) because that would be to much writing.
A possible solution
M = kron(speye(1000),ones(62));
M(logical(M)) = X(:);
With kron a 62000*62000 sparse matrix M is created that contains 1000 blocks of ones on its diagonal, then replace ones with elements of X.
You can flatten out your input matrix into a column vector using (:) indexing and then pass it to diag to place these elements along the diagonal of a new matrix.
result = diag(X(:))
This will order the elements along the diagonal in column-major order (the default for MATLAB). If you want a different ordering, you can use permute to re-order the dimensions prior to flattening.
It's important to note that your resulting matrix is going to be quite large. You could use spdiags instead to create a sparse diagonal matrix
spdiags(X(:), 0, numel(X), numel(X))
A very controversial eval call can solve this very lazily, although I suspect there is a much better way to do this:
evalstring = ['M=blkdiag('];
for i = 1:999
evalstring = [evalstring, 'X(:,:,', num2str(i),'),'];
end
evalstring = [evalstring, 'X(:,:,1000));'];
eval(evalstring);

Multiply vectors stored in two multidimensional arrays without for loop in Matlab?

%In MATLAB: I have stored vectors A and B in two multidim. arrays:
A = rand(4,1,4); B= rand(1,3,4);
%Now I want to create multidim array C(3,3,4)
%by multiply A and B in each dim i (:,:,i) without a for-loop.
%So instead of these four operations below, just perform one operation e.g. C=A*B.
C(:,:,1)=A(:,:,1)*B(:,:,1);
C(:,:,2)=A(:,:,2)*B(:,:,2);
C(:,:,3)=A(:,:,3)*B(:,:,3);
C(:,:,4)=A(:,:,4)*B(:,:,4);
I tried bsxfun, but could not find any suitable operation.
You can use array multiply with bsxfun
C = bsxfun(#times,A,B)

Broadcast function that changes dimension of the input array

Given some function f that accepts 1D array and gives 2D array, is it possible to apply it efficiently for each row of the NxM array A?
More specifically, I want to apply np.triu for each of the row of the NxM array A and then concatenate all the results. I can achieve this by
B = np.dstack(map(np.triu, A))
which gives MxMxN matrix. However, this is not very efficiently for large N. Unfortunately, the function np.apply_along_axis cannot be employed here because f changes dimension.
Knowing the power of NumPy for efficient broadcasting, I am almost sure that there exists a better solution for my problem.
Here's a vectorized approach using broadcasting -
Bout = A.T*(np.tri(A.shape[1],dtype=bool).T[...,None])
Runtime test and output verification -
In [319]: A = np.random.randint(0,20,(400,100))
In [320]: %timeit np.dstack(map(np.triu, A))
10 loops, best of 3: 69.9 ms per loop
In [321]: %timeit A.T*(np.tri(A.shape[1],dtype=bool).T[...,None])
10 loops, best of 3: 24.8 ms per loop
In [322]: B = np.dstack(map(np.triu, A))
In [323]: Bout = A.T*(np.tri(A.shape[1],dtype=bool).T[...,None])
In [324]: np.allclose(B,Bout)
Out[324]: True

Squeeze Some of Singleton Dimensions in Matlab

How can I squeeze only a subset of singleton dimensions of a matrix in Matlab? The squeeze function removes them all.
I keep the index to those dimensions in a vector called "dims".
Code
%// Input matrix is assumed as A
sz = size(A)
t2 = sz~=1
t2(dims)=1
out = reshape(A,sz(t2)) %// out is the desired output
If you are crazy about dense codes, you can try this -
sz = size(A)
out = reshape(A,sz(sort([dims find(sz~=1)])))
In Matlab, there is no tailing singleton dimension. A n*m*1 matrix is automatically a n*m matrix. Knowing this, your problem could be solved permuting the dimensions you don't want to the end:
X=ones(2,1,2,1,2,1,2,1,2,1)
%dimensions you want to keep in any case
dims=[2:4];
%Notice, S is [2,1,2,1,2,1,2,1,2], last dimension already "gone"
S=size(X)
%keep if size>1
dimensions_to_keep=S>1
%and keep if in "dims" list
dimensions_to_keep(dims)=1
%now permute dimensions you don't want to the end
Y=permute(X,[find(dimensions_to_keep),find(~dimensions_to_keep)])

Fastest way to multiply arrays of matrices in Python (numpy)

I have two arrays of 2-by-2 complex matrices, and I was wondering what would be the fastest method of multiplying them. (I want to do matrix multiplication on the elements of the matrix arrays.) At present, I have
numpy.array(map(lambda i: numpy.dot(m1[i], m2[i]), range(l)))
But can one do better than this?
Thanks,
v923z
numpy.einsum is the optimal solution for this problem, and it is mentioned way down toward the bottom of DaveP's reference. The code is clean, very easy to understand, and an order of magnitude faster than looping through the array and doing the multiplication one by one. Here is some sample code:
import numpy
l = 100
m1 = rand(l,2,2)
m2 = rand(l,2,2)
m3 = numpy.array(map(lambda i: numpy.dot(m1[i], m2[i]), range(l)))
m3e = numpy.einsum('lij,ljk->lik', m1, m2)
%timeit numpy.array(map(lambda i: numpy.dot(m1[i], m2[i]), range(l)))
%timeit numpy.einsum('lij,ljk->lik', m1, m2)
print np.all(m3==m3e)
Here are the return values when run in an ipython notebook:
1000 loops, best of 3: 479 µs per loop
10000 loops, best of 3: 48.9 µs per loop
True
I think the answer you are looking for is here. Unfortunately it is a rather messy solution involving reshaping.
If m1 and m2 are 1-dimensional arrays of 2x2 complex matrices, then they essentially have shape (l,2,2). So matrix multiplication on the last two axes is equivalent to summing the product of the last axis of m1 with the second-to-last axis of m2. That's exactly what np.dot does:
np.dot(m1,m2)
Or, since you have complex matrices, perhaps you want to take the complex conjugate of m1 first. In that case, use np.vdot.
PS. If m1 is a list of 2x2 complex matrices, then perhaps see if you can rearrange your code to make m1 an array of shape (l,2,2) from the outset.
If that is not possible, a list comprehension
[np.dot(m1[i],m2[i]) for i in range(l)]
will be faster than using map with lambda, but performing l np.dots is going to be slower than doing one np.dot on two arrays of shape (l,2,2) as suggested above.
If m1 and m2 are 1-dimensional arrays of 2x2 complex matrices, then they essentially have shape (l,2,2). So matrix multiplication on the last two axes is equivalent to summing the product of the last axis of m1 with the second-to-last axis of m2. That's exactly what np.dot does:
But that is not what np.dot does.
a = numpy.array([numpy.diag([1, 2]), numpy.diag([2, 3]), numpy.diag([3, 4])])
produces a (3,2,2) array of 2-by-2 matrices. However, numpy.dot(a,a) creates 6 matrices, and the result's shape is (3, 2, 3, 2). That is not what I need. What I need is an array holding numpy.dot(a[0],a[0]), numpy.dot(a[1],a[1]), numpy.dot(a[2],a[2]) ...
[np.dot(m1[i],m2[i]) for i in range(l)]
should work, but I haven't yet checked, whether it is faster that the mapping of the lambda expression.
Cheers,
v923z
EDIT: the for loop and the map runs at about the same speed. It is the casting to numpy.array that consumes a lot of time, but that would have to be done for both methods, so there is no gain here.
May be it is too old question but i was still searching for an answer.
I tried this code
a=np.asarray(range(1048576),dtype='complex');b=np.reshape(a//1024,(1024,1024));b=b+1J*b
%timeit c=np.dot(b,b)
%timeit d=np.einsum('ij, ki -> jk', b,b).T
The results are : for 'dot'
10 loops, best of 3: 174 ms per loop
for 'einsum'
1 loops, best of 3: 4.51 s per loop
I have checked that c and d are same
(c==d).all()
True
still 'dot' is the winner, I am still searching for a better method but no success

Resources