Multiplying matrices across tenor axis with numpy and with GPU - performance

I have a matrix X with shape (F,T,M). I wish to multiply each (T,M) matrix along the F axis so that the answer will be of shape (M,M,F). This code does the job for me but this operation repeats many times and it is very slow:
for f in range(F):
output[:,:,f] = np.matmul(X[f,:,:].T,X[f,:,:])
All I could find is np.tensordot() function. If I understand correctly, this is not a good option for me since I need a matrix multiplication and not a dot product.
How do I implement this efficiently using numpy? Is it possible and beneficial to utilize keras\tf for this purpose?

We can use np.matmul/# opeartor in Python 3.x after extending dimensions -
np.matmul(X.swapaxes(1,2),X).swapaxes(0,2)
(X.swapaxes(1,2)#X).swapaxes(0,2)
Alternatively, with np.einsum with a direct translation off the shape variables used for the string notation -
np.einsum('ftm,ftn->mnf',X,X)

Related

Resolve matrix differential equation with sparse matrix and ojAlgo

I am developping a java evolution tool with ojAlgo, and I try to resolve the following equation :
where A is a sparse matrix (for now the dimension of the matrix is 2000 x 2000, it will be scaled later on), A is not symmetric and use only real values.
I made some researchs and I tried to find the way to resolve this equation (using SparseStore) on github wiki/javadoc but I didn't find a way to do it. Can you help me find methods/class I should use ?
Thank you
There is no direct/specific method to solve differential equations in ojAlgo. You have to know how to do it (using pen and paper) then ojAlgo can help you perform the calculations.
The main problem here is finding the eigenpairs, right?
Eigenvalue<Double> evd = Eigenvalue.PRIMITIVE.make(matrix);
evd.decompose(matrix);
Array1D<ComplexNumber> values = evd.getEigenvalues();
MatrixStore<ComplexNumber> vectors = evd.getEigenvectors();
Eigenpair pair = evd.getEigenpair(0); // One of the pairs

Failed to convert structure to matrix with regionprops in MATLAB

I am working with particle tracking in images in MATLAB and using regionprops function. On the provided resource there is an example with circles:
stats = regionprops('table',bw,'Centroid',...
'MajorAxisLength','MinorAxisLength')
centers = stats.Centroid;
diameters = mean([stats.MajorAxisLength stats.MinorAxisLength],2);
radii = diameters/2;
In my Matlab R2014b, the line centers = stats.Centroid; produces undesired result: my stats.Centroid structure has 20 elements (each element is two numbers - the coordinates of the center of the region). However, after the following command, my variable center is only 1x2 matrix, instead of desired 20x2.
Screenshot attached.
I tried to go around this with different methods. The only solution I found is to do:
t=zeros(20,2);
for i=1:20
t(i,:)=stats(i).Centroid;
end
However, as we all know loops are slow in MATLAB. Is there another method that takes advantage of MATLAB matrix operations?
Doing stats.Centroid would in fact give you a comma-separated list of centroids, so MATLAB would only give you the first centre of that matrix if you did centers = stats.Centroid. What you must do is encapsulate the centres in an array (i.e. [stats.Centroid]), then reshape when you're done.
Something like this should work for you:
centers = reshape([stats.Centroid], 2, []).';
What this will do is read in the centroids as a 1 x 2*M array where M is the total number of blobs and because MATLAB does reshaping in column-major format, you should make sure that specify the total number of rows to be 2 and let MATLAB figure out how many columns there are after by itself. You would then transpose the result when you're done to complete what you want.
Minor Note
If you look at the regionprops documentation page in their Tips section - http://www.mathworks.com/help/images/ref/regionprops.html#buorh6l-1, you will see that they surround stats.Area, which is the area of each blob with [] brackets to ensure that the comma-separated list of values is encapsulated in an array. This is not an accident and there is a purpose of having those there and I've basically told you what that was.

Matlab - use of principal components in finding longest axis of shape

I'm trying to use the pca function to find the longest axis of shapes in binary images. These are 2D images, so I'm expecting just two principal components. If I apply pca to the image itself I get many components.
My thoughts on this are that the matrix that pca acts on is treated such that rows are observations and columns are variables, so I need to convert my image into a list of the x,y coordinates of non-zero pixels. What function does this? Trying with find, this is what I have so far:
for k=1:cellnum %for each cell...
[nucleus, nucnum] = bwlabel(B5.*(cell==k)); %label nuclei in cell (Thanks #CapeCode)
if nucnum == 1
% other methods
[row, col] = find(nucleus);
[coeff, ~, eigen] = pca([row, col]);
disp (coeff);
end
I get two pairs of coefficients for each nucleus, as follows:
0.8327 0.5537
-0.5537 0.8327
0.9791 0.2036
-0.2036 0.9791
0.8546 0.5193
-0.5193 0.8546
so... am I actually doing what I think I'm doing?
Thanks,
Olly
Edit: Link to my earlier question regarding identification of overlapping objects, and Cape Code's elegant single-line solution - Matlab - Identifying objects in one image that overlap objects in another

Does there exist a way to directly figure out the "smoothness" of a digital image?

There exist several ways to evaluate an image, brightness, saturation, hue, intensity, contrast etc. And we always hear about the operation of smoothing or sharperning an image. From this, there must exist a way to evaluate the overall smoothness of an image and an exact way to figure out this value in one formula probably based on wavelet. Or fortunately anyone could even provide the MATLAB function or combination of them to directly calculate this value.
Thanks in advance!
Smoothness is a vague term. What considered smooth for one application might not be considered smooth for another.
In the common case, smoothness is a function of the color gradients. Take a 2d gradient on the 3 color channels, then take their magnitude, sqrt(dx^2 + dy^2) and average, sum or some function over the 3 channels. That can give you local smoothness which you can then sum/average/least squares over the image.
In the more common case, however, linear changes in color is also smooth (think 2 color gradients, or how light might be reflected from an object). For that, a second differential could be more suitable. A laplacian does exactly that.
I've had much luck using the laplacian operator for calculating smoothness in Python with the scipy/numpy libraries. Similar utilities exist for matlab and other tools.
Note that the resulting value isn't something absolute from the math books, you should only use it relative to itself and using constants you deem fit.
Specific how to:
First get scipy. If you are on Linux it's it available on pypi. For Windows you'll have to use a precompiled version here. You should open the image using scipy.ndimage.imread and then use scipy.ndimage.filters.laplace on the image you read. You don't actually have to mix the channels, you can simply call numpy.average and it should be close enough.
import scipy as np
import scipy.ndimage as ndi
print np.average(np.absolute(ndi.filters.laplace(ndi.imread(path).astype(float) / 255.0)))
This would give the average smoothness (for some meaning of smoothness) of the image. I use np.absolute since values can be positive or negative and we don't want them to even out when averaging. I convert to float and divide by 255 to have values between 0.0 and 1.0 instead of 0 to 256, since it's easier to work with.
If you want to see the what the laplacian found, you can use matplotlib:
import matplotlib.pyplot as plt
v = np.absolute(ndi.filters.laplace(ndi.imread(path).astype(float) / 255.0))
v2 = np.average(v, axis=2) # Mixing the channels down
plt.imshow(v2);
plt.figure();
plt.imshow(v2 > 0.05);
plt.show()

GLSL integration function

Any recommendation on how to implement efficient integral functions, like SumX and SumY, in GLSL shaders?
SumX(u) = Integration with respect to x = I(u0,y) + I(u1,y) +... + I(uN,y); u=normalized x coordinate
SumY(v) = Integration with respect to y = I(x,v0) + I(x,v1) +... + I(x,vN); v=normalized y coordinate
For instance the 5th pixel of the first line would be the sum of all five pixels on the first line. And the last pixel would be the sum of all previous pixels including the last pixel itself.
What you are asking for is called prefix sum or summed area table (SAT) for the 2D case (just so you find online resources more easily).
Summed area tables can be efficiently implemented on the GPU by decomposing into several parrallel prefix sum passes [1], [2].
The prefix sum can be accelerated by using local memory to store intermediate partial sums (see example in OpenCL or example in CUDA, the same can in principle be done in an OpenGL fragment shader as well with image load-store, or in a compute shader: OpenGL Super Bible example, similar example to be found in OpenGL Insights around page 280).
Note that you may quickly run into precision issues as the sum may get quite large for the rightmost (downmost) pixels. Integer or fp16 render targets will most likely result in failure due to overflow or lacking precision, fp32 will work most of the time.

Resources