Fill areas in a matrice - matlab

As u can see in this figure, I have 3 "lines", that are not linear with values of zeros (or NaNs) in between.
What I would like to create a picture that has 3 filled areas with a single value by averaging all the values in the "line" section" and fill them where the area of zeroes below.
averaging is not a problem and also using a fill or patch command is not the problem, my problem here is how to identify a piece of data here that is not linear or homogenous in it's content by it's shape and efficiently create three slices of data because real values in the matrice must stay.
will appreciate any idea!
thanks

It's a little tough to tell from a colormap like that, but it looks like the inhomogeneities are considerably worse along the columns. If that is the case, then you may be best off comparing the values of each column to the two adjacent ones and creating a bias index.
Just taking a stab at it - I'll use inhomoge as slang for your inhomogenous image
predictedInhomoge=(inhomoge(1:end-2)+inhomoge(3:end))/2;
biasImage=(predictedInhomoge-inhomoge(2:end-1))./(inhomoge(2:end-1)+predictedInhomoge);
image(255*biasImage/max(biasImage(:)));
If your blue colored data are actually zeros and not just small values the biasImage above will have a lot of pointless Inf values. If that's the case, just drop the denominator off of the biasImage equation so that it is no longer normalized.
biasImage=(predictedInhomoge-inhomoge(2:end-1));
If the biasImage looks like the highest values reflect your inhomogeneities then you're in business, just pick a threshold and recalculate the values above it. If it doesn't, then I'd consider trying something Bayesian.
Probably doesn't need to be said, but any NaNs are easy to find and remove.

Related

How do I get the index of a matrix that is stored in a 4D matrix?

I am writing some code, whereby I store a greyscale image, which is split into 'blocks' in a 4D array. I will be looping through all the 'blocks' in the 4D array and will perform calculations based on the contents of the blocks compared to one another. I want to only compare the 'blocks' that are near each other, and to do this I can just calculate the distance between the 'blocks' and don't loop through the ones that are too far away. To do this I need the index of each 'block' in the 4D matrix, ultimately creating my question.
My code goes like this:
for i=4dmatrix1
for j=4dmatrix2
% Do calculations here involving the index of i
% and j in their respective matrices.
end
end
I have i and j, but I want to find their index in 4dmatrix1 and 4d matrix2 respectively. 4dmatrix1 and 4dmatrix2 are greyscaled images that have been split into "blocks" of 20x20 pixels. Each matrix in 4dmatrix1 and 4dmatrix2 is a "block" in image 1 and image 2. The reason I have used this method for storing the data as it still represents the shape of the image, just split into 20x20 blocks. In my head this is understandable, but maybe for programming, this is inefficient and should be changed. If so, what would you recommend looking into?
Thank you!
You can loop over the indices of a matrix in any dimension, and then map that to the subscripts using ind2sub. Basically, the syntax would be
[id1,id2,id3,id4] = ind2sub(size(my4Dmatrix, i));
And something similar for j.
Not really your question, but something doesn't seem quite right with how you're looping. Also, you should include a minimum working example, including generating a couple of matrices and using correct syntax (you cannot start a variable name in MATLAB with a number).

Is there any option in matlab to optimize (row,column) in order to show subplots?

I have to plot different graphics with subplot within a figure but I do not know how many will be plotted because it depends on the data introduced by the user (for loop). In order to plot a subplot I need to know the number of columns and rows. Is there any option in matlab that matlab configures the best number of columns and rows to display plots knowing the total subplots to do? I mean subplot(a,b,c) => best a,b combination knowing c.
Now I ask to the user to introduce number of columns and rows but it's a bit uncomfortable. Maybe an algorithm to take a decomposition of the total subplots into the 2 most equals factors should work but I think it's quite difficult to code that. If it's too complex I'll follow with my way but I was curious about it.
I don't think there is a built-in solution; what has been working well for me in practice is the following approach, where I try to get a nearly square arrangement with a few more columns than rows (because of wider-than-tall screen aspect ratio):
nRows = floor(sqrt(nPlots));
nCols = ceil(nPlots/nRows);

Spectrum Derivative in MATLAB, the end point problem

I am trying to take the derivative of the a spectrum with 125 bands using the following lines:
dW=diff(wavelength);
dR=diff(data);
df=dR./dW;
problem is in the next step i want to compare it with original spectrum numerically and also visually by plotting, but the size of df is 124 however my original wavelength is 125. Question is do i have to remove the first or the last band? however the output of some spectral analysis software is not changing the size. taking the average of bands also does not work, it make the graph to show crazy behavior.
diff is basically:
Y = [X(2)-X(1) X(3)-X(2) ... X(m)-X(m-1)]
which means it has to be one shorter than your input (you can't subtract something from nothing, right?).
What you have to do of course depends on what you want to do, but the least "meaning-altering" approach (kind of keeping causality with respect to sampling times) would be to prepend your dW and dR with a single arbitrary value.
By the way, your ratio df=dR./dW might have a lot of NaNs if dW has zeros (which happens as soon as two consecutive data values are the same).

Controlled random number/dataset generation in MATLAB

Say, I have a cube of dimensions 1x1x1 spanning between coordinates (0,0,0) and (1,1,1). I want to generate a random set of points (assume 10 points) within this cube which are somewhat uniformly distributed (i.e. within certain minimum and maximum distance from each other and also not too close to the boundaries). How do I go about this without using loops? If this is not possible using vector/matrix operations then the solution with loops will also do.
Let me provide some more background details about my problem (This will help in terms of what I exactly need and why). I want to integrate a function, F(x,y,z), inside a polyhedron. I want to do it numerically as follows:
$F(x,y,z) = \sum_{i} F(x_i,y_i,z_i) \times V_i(x_i,y_i,z_i)$
Here, $F(x_i,y_i,z_i)$ is the value of function at point $(x_i,y_i,z_i)$ and $V_i$ is the weight. So to calculate the integral accurately, I need to identify set of random points which are not too close to each other or not too far from each other (Sorry but I myself don't know what this range is. I will be able to figure this out using parametric study only after I have a working code). Also, I need to do this for a 3D mesh which has multiple polyhedrons, hence I want to avoid loops to speed things out.
Check out this nice random vectors generator with fixed sum FEX file.
The code "generates m random n-element column vectors of values, [x1;x2;...;xn], each with a fixed sum, s, and subject to a restriction a<=xi<=b. The vectors are randomly and uniformly distributed in the n-1 dimensional space of solutions. This is accomplished by decomposing that space into a number of different types of simplexes (the many-dimensional generalizations of line segments, triangles, and tetrahedra.) The 'rand' function is used to distribute vectors within each simplex uniformly, and further calls on 'rand' serve to select different types of simplexes with probabilities proportional to their respective n-1 dimensional volumes. This algorithm does not perform any rejection of solutions - all are generated so as to already fit within the prescribed hypercube."
Use i=rand(3,10) where each column corresponds to one point, and each row corresponds to the coordinate in one axis (x,y,z)

Using triplequad to calculate density (in Matlab)

As i've explained in a previous question: I have a dataset consisting of a large semi-random collection of points in three dimensional euclidian space. In this collection of points, i am trying to find the point that is closest to the area with the highest density of points.
As high performance mark answered;
the most straightforward thing to do would be to divide your subset of
Euclidean space into lots of little unit volumes (voxels) and count
how many points there are in each one. The voxel with the most points
is where the density of points is at its highest. Perhaps initially
dividing your space into 2 x 2 x 2 voxels, then choosing the voxel
with most points and sub-dividing that in turn until your criteria are
satisfied.
Mark suggested i use triplequad for this, but this is not a function i am familiar with, or understand very well. Does anyone have any pointers on how i could go about using this function in Matlab for what i am trying to do?
For example, say i have a random normally distributed matrix A = randn([300,300,300]), how could i use triplequad to find the point i am looking for? Because as i understand currently, i also have to provide triplequad with a function fun when using it. Which function should that be for this problem?
Here's an answer which doesn't use triplequad.
For the purposes of exposition I define an array of data like this:
A = rand([30,3])*10;
which gives me 30 points uniformly distributed in the box (0:10,0:10,0:10). Note that in this explanation a point in 3D space is represented by each row in A. Now define a 3D array for the counts of points in each voxel:
counts = zeros(10,10,10)
Here I've chosen to have a 10x10x10 array of voxels, but this is just for convenience, it would be only a little more difficult to have chosen some other number of voxels in each dimension, and there don't have to be the same number of voxels along each axis. Then the code
for ix = 1:size(A,1)
counts(ceil(A(ix,1)),ceil(A(ix,2)),ceil(A(ix,3))) = counts(ceil(A(ix,1)),ceil(A(ix,2)),ceil(A(ix,3)))+1
end
will count up the number of points in each of the voxels in counts.
EDIT
Unfortunately I have to do some work this afternoon and won't be able to get back to wrestling with the triplequad solution until later. Hope this is OK in the meantime.