extract data from a matrix, maintaining NaNs as NaNs matlab - matlab

I have a dataset called 'data' of size 106*103*100. I am extracting a portion of the dataset for further analysis based on its geographical position using latitudes and longitudes and naming the extracted data 'testdata'). 'data' contains a mixture of both numbers and NaNs.
The data I want to extract lies within the latitudinal and longitudinal bounds of ylat_south=44,ylat_north=55,xlon_west=16 and xlon_east=30;
The matrix of latitudes is called: final_lat (106*103);
The matrix of longitudes is called: final_lon (106*103);
This is what I have to extract the data:
for i=1:size(data,3);
testdata(:,:,i)=+(final_lat>=ylat_south & final_lat<=ylat_north &
final_lon>=xlon_west & final_lon<=xlon_east).*data(:,:,i);
end
The code I have works (i.e. I end up with testdata of size 106*103*100), except, when testdata is written out, any cells that contained a NaN in 'data' are being written as a zero is the new 'testdata' matrix'. I know I could do this is a loop, with an if statement, but I am trying to keep the code as efficient as possible.
Any suggestions appreciated.

Related

Matlab function reshape doesnt´t calculate the last dimension while trying to create a 3D image from .raw binary image file

I created binarized images by using the Otsu methode in Matlab and cut out parts of the resulting image using a function. Now i want to take a look at these images with the VolumeViewer command. I know the x,y and z dimensions of the resulting imgages. I currently run this code doing it(excluding the volumeViewerwhich happens after the loop):
files= {'C3\C3_000mal_550_539_527.raw';...
};
for i=1:numel(files)
Image = fopen(files{i},'r');
ImageData{i} = fread(Image,Inf,'uint16=>uint16');
ImageData{i} = reshape(ImageData{i},550,539,[]);
fclose(openedCrystalImage);
end
Using this code runs into the following error using reshape:
Error using reshape
Product of known dimensions, 296450, not divisible into total number of elements, 78114575.
I did the maths and 550*539=296450 and 296450 * 527=156229150: If we divide the last number by the number of elements it equals 2 and thus is divisible into the total number of elements. In my opinion the reshape function is not able to find the size of the last dimension or defines it as 1.
Defining the size of z also results in an error suggesting using the brackets [], so the function can find it.
Error using reshape
Number of elements must not change. Use [] as one of the size inputs to automatically calculate the appropriate size
for that dimension.
Now to the weird part. This code works for another set of images, with diffrent sizes of the x,y and z ranges. So don´t know where the issue lies to be frank. So i would really appreciate and Answer to my question
I figured it out. The error lies here:
ImageData{i} = fread(Image,Inf,'uint16=>uint16');
Apparently by saving them as .raw before it converts the image to an 8 bit file rather than 16 bits it had before. Therefore, my dimension is double the size of the number of elements. With this alteration it works:
ImageData{i} = fread(Image,Inf,'uint8=>uint8');
The reason i was able to look at the other pictures was that the z range was divisble by 2.
So the reshape function was not the problem but size of the integer data while creating the array for the variable ImageData.
P.S. I just started out programming so the accuracy in the answer should be taken with a grain of salt

How to use binning method for identifying the incoming point belongs to which bin?

I have small query. I have two data sets. In one data sets for example I did binning and calculated the mean value and std value along with group binning. Now in I have second data sets of same parameters say X. I would like identify this X data sets belong to which bin groups of my previous data sets using matlab.
Could you give some example how to identify the incoming data points belongs to which bin group...??
I used following binning which is available in matlab :
binEdges = linspace(botEdge, topEdge, numBins+1);
[h,whichBin] = histc(x, binEdges);
Well... you already have your bin edges. Anything inside specific edges is in that bin.
If you know that the data is inside the ranges you defined then, for each new data
newdatabin=find(newdata>binedges,1,'last'); %this is the bin number where the new data goes in
h(newdatabin)=h(newdatabin)+1; %add one!
Also consider using histcounts if your MATLAB version is new enough.

Matlab/Simulink LookupTable with Workspace vectors

I am new with Simulink and I am struggling with the Dynamic Lookup Table (inputs : x, xadta, ydata; output: y).
I have several 2D vectors (xdata and ydata) stored in my Workspace and I would like to use them in Simulink in a Dynamic Lookup Table to return a value (y) depending on another variable in Simulink (x).
If I understand how it works I have first to convert my 2D vectors in structures (time,values,dimensions) to be read in Simulink ?
So I did it this way but I got an error :
vector.time = xdata; % dimension 1x100
vector.signals.values = ydata; % dimension 1x100
vector.signals.dimensions = [1 100];
save('vector.mat','vector')
Error
"The last dimension of each
'signals.values' field must be the same as the number of rows in the 'time' field."
Besides I am not sure that what I am trying to do is appropriate... I use the xdata of my vectors/structures as "time" in the structures to get my vectors readable in Simulink. But I do not think it should have anything to do with time notion. I just want the Dynamic Lookup Table to return the "ydata" value of the vector/structure corresponding to the value of "x"="xdata". Only "x" change with time in the Simulation.
It looks like you should just be using the 1D Lookup Table, with your xdata and ydata variables (defined in your MATLAB Workspace) used as the block parameters.
As to the error you're getting, it seems to be related to using the From File block (which it looks like you're using to get data into your model) not the look-up table itself. To get that to work, define your time vector as a column vector, not a row vector as you've done, and think of each row as a different time point.
At each time point, you'll get a different signal value. This is like a look-up table itself (looking up the signal value for each different time value), but doesn't sound like what you are really wanting to achieve.

MATLAB: If this value of 5x5 cell with vectors [106x1] are different to zeroes,count them e put the count in a matrix

I have matchcounts (5x5)cell, every cell has a vector of double [106x1]. The vectors of double have zeros and non zero values. I want to find non zero values for every cell, count them and put the result in a matrix.
I tried with this code:
a{i,j}(k,1)=[];
for k=1:106
for i=1:5
for j=1:5
if (matchcounts{i,j}(k,1))~=0
a{i,j}=a{i,j}(k,1)+1;
end
end
end
end
and others but it's not correct! Can you help me? Thanks
While it is possible to fix your answer above, I recommend to change the data structure to have a much simpler solution possible. Instead of having a 2D cell array which holds 1D data, choose a single 3D data structure.
For an optimal solution you would change your previous code code to directly write the 3D-matrix, instead of converting it. To get started, this code converts it so you can already see how the data structure should look like:
%convert to matrix
for idx=1:numel(matchcounts)
matchcounts{idx}=permute(matchcounts{idx},[3,2,1]);
end
matchcounts=cell2mat(matchcounts);
And finding the nonzero elements:
a=(matchcounts~=0)
To index the result, instead of a{k,l}(m,1) you use a(k,l,m)
To give you some rule to avoid complicated data structures in the future. Use cell arrays only for string data and data of different size. Whenever you have a cell array which contains only vectors or matrices of the same size, it should be a multidimensional matrix.

Vectorization or For loop in MATLAB

I want to read data from .txt file to plot a 3D graph in matlab. The data looks like this
T_hor T_ver V_hor V_ver
8,833 -15,43 -11,871 23,604
3,121 -22,78 -9,949 41,712
-8,012 -26,28 -4,317 33,790
-12,697 -20,99 6,948 22,314
-11,960 5,68 2,079 0,469
4,279 -22,17 -10,002 39,791
Each column I've imported as a separate column Vector say T_hor,T_ver,V_hor,V_ver. Now I want to read first 4096 rows of this individual column vector 'T_hor' and then the next 4096 rows of the column vector T_hor. This applies for every column. My Goal was to compute FFT for the 4096 set of values incrementally and store them as column vectors.I was previously using this command to read the values into different column vector.
x1 = T_ver(1:4096);
x2 = T_ver(4097:8193);
I want to make the code look more Logical and avoid unnecessary lines of code. So I tried applying for loop for this but I think I'm doing it in a wrong way.
for X
X = (1:LastValue:4096);
end
I think Vectorization can be more easy and consumes less execution time. Can anyone give me a direction or hints on how to implement this.