scatter plot: tall arrays eating up all the memory - arrays

I am working on tone mapping operators in HDR. My question is very simple. I want to scatter plot large arrays on Matlab 2015Ra with computer specs core i5 20GB RAM. Only the scatter plot eats up the whole memory (around 92% of 20GB). I need some suggestion to plot tall arrays. I know Matlab 2018 has binscatter function but I have lower version. Thank you. Sample Code:
a=randn(21026304,1);
scatter(a,a);
Only this code eats up the all memory.

You can create a binscatter like function yourself with histcounts2!
Histcounts bins the data into an NxN array which you can then visualize with imshow... this is pretty memory-efficient as every bin only takes up a couple of bytes, regardless of the input size.
% Some (correlated) data
x = randn(1e6,1);
y = randn(1e6,1)+x;
% Count 32x32 bins
[N,ax,ay] = histcounts2(x,y,32);
% Some gradient
cmap = [linspace(1,0,16);
linspace(1,0.3,16);
linspace(1,0.5,16)].';
% Show the histogram
imshow(...
N,[],... % N contains the counts, [] indicated range min-max
'XData', ax, 'YData', ay, ... % Axis ticks
'InitialMagnification', 800,... % Enlarge 8x
'ColorMap', cmap... % The colormap
);
colorbar;
axis on;
title('bin-counts');

Related

How to scale very large numbers such that they could be represented as an array index?

I have a 2D array of size 30*70.
I have 70 columns. My values are very large ranging from 8066220960081 to (some number with same power of 10 as lowerlimit) and I need to plot a scatter plot in an array. How do I index into the array given very large values?
Also, I need to do this in kernel space
Let's take an array long long int A with large values.
A[0] = 393782040
A[1] = 2*393782040
... and so on
A[N] = 8066220960081; where N = 30*70 - 1
We can scale A with a factor or we can shift A by a certain number and scale it again. That's where you can deal with numbers ranging between 0 and 1 or -1 and 1 or x and y. You choose as per your need. Theoretically, this should not make a difference to the scatter plot other than the placement of the axis. However, if your scatter plot is also a representative of the underlying values i.e. the dots are proportional to values; then it is a good idea to be nice to your plotting tool and not flood it with terribly large values that might lead to overflow depending on how the code for plotting is written.
PS: I would assume you know how to flatten a 2d array.
I just ended up doing regular interval calculation between max and min
and then start from min + interval*index to get the number.
index would be the index in array.

Histogram of image not showing expected distribution

I have a cell array called output. Output contains matrices of size 1024 x 1024, type = double, grayscale. I would like to plot each matrix and its corresponding histogram on a single plot. Here is what I have so far:
for i = 1:size(output,2)
figure
subplot(2,1,1)
imagesc(output{1,i});
colormap('gray')
colorbar;
title(num2str(dinfo(i).name))
subplot(2,1,2)
[pixelCount, grayLevels] = imhist(output{1,i});
bar(pixelCount);
title('Histogram of original image');
xlim([0 grayLevels(end)]); % Scale x axis manually.
grid on;
end
The plot I get, however, seems to be faulty... I was expecting a distribution of bars.
I am somewhat lost at how to proceed, any help or suggestions would be appreciated!
Thanks :)
Based on the colorbar on your image plot the values of your image pixels range from [0, 5*10^6].
For many image processing functions, MATLAB assumes one of two color models, double values ranging from [0, 1] or integer values ranging from [0 255]. While the supported ranges are not explicitly mentioned in the imhist documentation, in the "Tips" section of the imhist documentation, there is a table of scale factors for different numeric types that hints at these assumptions.
I think the discrepancy between your image range and these models is the root of the problem.
For example, I load a grayscale image and scale the pixels by 1000 to approximate your data.
% Toy data to approximate your image
I = im2double(imread('cameraman.tif'));
output = {I, I .* 1000};
for i = 1:size(output,2)
figure
subplot(2,1,1)
imagesc(output{1,i});
colormap('gray')
colorbar;
subplot(2,1,2)
[pixelCount, grayLevels] = imhist(output{1,i});
bar(pixelCount);
title('Histogram of original image');
grid on;
end
The first image is using a matrix with the standard [0,1] double value range. The imhist calculates a histogram as expected. The second image is using a matrix with the scaled [0, 1000] double value range. imhist assigns all the pixels to the 255 bin since that is the maximum bin. Therefore, we need a method that allows us to scale the bins.
Solution : Use histogram
histogram is designed for any numeric type and range. You may need to fiddle with the bin edges to show the structures that you are interested in as it doesn't initialize bins the same way imhist does.
figure
subplot(2,1,1)
imagesc(output{1,2});
colormap('gray')
colorbar;
subplot(2,1,2)
histogram(output{1,2});
title('Histogram of original image');
grid on;

Creating a 3D plot in Matlab

I want to create a 3D plot of the final fraction of grass covered on the Earth (=in 2 billion years from now) (=A) as a function of a varying death rate of grass (=D) and the growth rate of grass (=G).
The final value of A (at 2 billion years away from now) can be calculated using a loop with the following discritised equation:
A(t+dt) = A(t)*((1-A(t))*G-D)*dt + A(t)
%Define variables and arrays
D=0.1; %constant value
G=0.4; %constant value
A=0.001; %initial value of A at t=0
t=0;
dt=10E6;
startloop=1; %define number of iterations
endloop=200;
timevector=zeros(1,endloop); %create vector with 0
grassvector=zeros(1,endloop);
%Define the loop
for t=startloop:endloop
A=A.*((((1-A).*G)-D)) + A;
grassvector(t)=A;
timevector(t)=t*dt;
end
Now i'm stuck on how to create a 3D plot of this final value of A as a function of a varying G and D. I got this but after a few trials, it keeps giving errors:
%(1) Create array of values for G and D varying between 0 and 1
A=0.001;
G=[0.005:0.005:1]; %Vary from 0.005 to 1 in steps of 0.005
D=[0.005:0.005:1]; %Vary from 0.005 to 1 in steps of 0.005
%(2) Meshgrid both variables = all possible combinations in a matrix
[Ggrid,Dgrid]=meshgrid(G,D);
%(3) Calculate the final grass fraction with varying G and D
D=0.1;
G=0.4;
A=0.001;
t=0;
dt=10E6;
startloop=1; %define number of iterations
endloop=200;
timevector=zeros(1,endloop); %create vector with 0
grassvector=zeros(1,endloop);
%Define the loop
for t=startloop:endloop
A=A.*((((1-A).*Ggrid)-Dgrid)) + A;
grassvector(t)=A;
timevector(t)=t*dt;
end
%(4) mesh together with D and G
...??
Can someone help? Thanks!
Your code is wrong, as grassvector(t)=A; can not be executed, as the sizes are not consistent. However, I think you may want to do:
grassvector=zeros([size(Ggrid),endloop]);
and in the loop:
grassvector(:,:,t)=A;
Also, while completely unnecesary computationally, you may want to initialize A to A=0.001*ones(size(Dgrid)), as it makes more sense logically.
Anyways: this is how you can plot it in the end:
surf(Ggrid,Dgrid,A,'LineStyle','none');
xlabel('growth rate ')
ylabel('death rate ')
zlabel('grass')
colorbar
gives:
But, as I was actually interested in your research, I decided to make a couple of plots to see how fast the grass will grow and stuff. Here is some nice plotting code. You can modify different stuff here to be able to change the appearance of it. I use custom colormaps, so if it doesn't work, delete the colormap(viridis()) line. If you like the colormap, visit this.
fh=figure();
filename='grass.gif';
for t=startloop:endloop
clf
hold on
surf(Ggrid,Dgrid,grassvector(:,:,t),'LineStyle','none');
[c,h]=contour3(Ggrid,Dgrid,grassvector(:,:,t)+0.05,[0:0.1:1],'LineColor',[153,0,18]/255,'LineWidth',2);
clabel(c,h);
xlabel('growth rate ')
ylabel('death rate ')
zlabel('grass')
title(['Years passed: ' num2str(t*dt/1000000) ' million'])
colormap(viridis())
axis([0 1 0 1 0 1])
grid on
view(-120,40);
frame = getframe(fh);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if t == 1;
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append','DelayTime',0.1);
end
end
Results:

Matlab access vectors from a multi-dimensional array

I have a 4D matrix of size 300x200x3x20 where 300x200 is the size of one video frame, 3 is the number of channels (Red-Green-Blue channels) and 20 is the number of frames.
I want to extract all the color vectors from this matrix and store them in a 2D array of size 3x1,200,000 (300 x 200 x 20 = 1,200,000) where each row represents a component of the RGB color space and each column contain the RGB values of one pixel in the original matrix.
Besides, I want to carry out pixel-wise operations on this data such as extracting visual features but I cannot find a way to effectively access vectors along the third dimension.
How could I efficiently do these, possible without using loops?
Try this code -
IN = your_4D_data;
OUT = reshape(permute(IN,[3 1 2 4]),3,numel(IN)/3);
help reshape says:
B = reshape(A,m,n,p,...) or B = reshape(A,[m n p ...]) returns an n-dimensional array with the same elements as A but reshaped to have the size m-by-n-by-p-by-.... The product of the specified dimensions, m*n*p*..., must be the same as numel(A).
is this what you are looking for?
also, you can adress pixels like this: Matrix(i,j,:,k) which gives you the 3 colorchanels of pixel i,j in frame k.

Convolutional neural network - How to get the feature maps?

I read a few books and articles about Convolutional neural network, it seems I understand the concept but I don't know how to put it up like in image below:
(source: what-when-how.com)
from 28x28 normalized pixel INPUT we get 4 feature maps of size 24x24. but how to get them ? resizing the INPUT image ? or performing image transformations? but what kind of transformations? or cutting the input image into 4 pieces of size 24x24 by 4 corner? I don't understand the process, to me it seem they cut up or resize the image to smaller images at each step. please help thanks.
This is matlab help file for CONV2 function, which use in CNN Matlab (to get convolutional layers). Read it carefully and you will see your answer.
%CONV2 Two dimensional convolution.
% C = CONV2(A, B) performs the 2-D convolution of matrices A and B.
% If [ma,na] = size(A), [mb,nb] = size(B), and [mc,nc] = size(C), then
% mc = max([ma+mb-1,ma,mb]) and nc = max([na+nb-1,na,nb]).
%
% C = CONV2(H1, H2, A) convolves A first with the vector H1 along the
% rows and then with the vector H2 along the columns. If n1 = length(H1)
% and n2 = length(H2), then mc = max([ma+n1-1,ma,n1]) and
% nc = max([na+n2-1,na,n2]).
%
% C = CONV2(..., SHAPE) returns a subsection of the 2-D
% convolution with size specified by SHAPE:
% 'full' - (default) returns the full 2-D convolution,
% 'same' - returns the central part of the convolution
% that is the same size as A.
% 'valid' - returns only those parts of the convolution
% that are computed without the zero-padded edges.
% **size(C) = max([ma-max(0,mb-1),na-max(0,nb-1)],0).**

Resources