I have a time series of temperature profiles that I want to interpolate, I want to ask how to do this if my data is irregularly spaced.
Here are the specifics of the matrix:
The temperature is 30x365
The time is 1x365
Depth is 30x1
Both time and depth are irregularly spaced. I want to ask how I can interpolate them into a regular grid?
I have looked at interp2 and TriScatteredInterp in Matlab, however the problem are the following:
interp2 works only if data is in a regular grid.
TriscatteredInterp works only if the vectors are column vectors. Although time and depth are both column vectors, temperature is not.
Thanks.
Function Interp2 does not require for a regularly spaced measurement grid at all, it only requires a monotonic one. That is, sampling positions stored in vectors depths and times must increase (or decrease) and that's all.
Assuming this is indeed is the situation* and that you want to interpolate at regular positions** stored in vectors rdepths and rtimes, you can do:
[JT, JD] = meshgrid(times, depths); %% The irregular measurement grid
[RT, RD] = meshgrid(rtimes, rdepths); %% The regular interpolation grid
TemperaturesOnRegularGrid = interp2(JT, JD, TemperaturesOnIrregularGrid, RT, RD);
* : If not, you can sort on rows and columns to come back to a monotonic grid.
**: In fact Interp2 has no restriction for output grid (it can be irregular or even non-monotonic).
I would use your data to fit to a spline or polynomial and then re-sample at regular intervals. I would highly recommend the polyfitn function. Actually, anything by this John D'Errico guy is incredible. Aside from that, I have used this function in the past when I had data on a irregularly spaced 3D problem and it worked reasonably well. If your data set has good support, which I suspect it does, this will be a piece of cake. Enjoy! Hope this helps!
Try the GridFit tool on MATLAB central by John D'Errico. To use it, pass in your 2 independent data vectors (time & temperature), the dependent data matrix (depth) along with the regularly spaced X & Y data points to use. By default the tool also does smoothing for overlapping (or nearly) data points. If this is not desired, you can override this (and other options) through a wide range of configuration options. Example code:
%Establish regularly spaced points
num_points = 20;
time_pts = linspace(min(time),max(time),num_points);
depth_pts = linspace(min(depth),max(depth),num_points);
%Run interpolation (with smoothing)
Pest = gridfit(depth, time, temp, time_pts, depth_pts);
Related
I am designing a battery model with an internal resistance which is dependant on two variables: SoC and temperature.
I have interpolated the data I have (x,y and z basically - a total of 131 points each) with MATLAB's curve fitting toolbox and was able to generate the desired 3D map of that dependence (see the picture below):
My question is how can I use that map now for my Simulink model? As input parameters I will have SoC and temperature and the resistance in ohm should be the output. However, I have not been able to find a convenient way to export the data in a suitable lookup table (or similarly useful, my first guess was that I should use a 2-D lookup table in this case) in Simulink. However, I am quite new to this and I do not know how to generate the the table data for the Simulink LUT.
Simulink LUT:
Table data is your interpolated z-data from curve fitting. I guess it will have a value for every combination of breakpoints (i.e. it covers every grid intersection in your first diagram). So if Breakpoint 1 is 100 elements and Breakpoint 2 is 40 elements, Table data is 100x40.
If you can't get the data out from the GUI-based interactive curve fit, I guess you can extract the data from the command line. The following is an excerpt of Mathworks' curve fitting documentation. It would be good to verify this because I don't have the toolbox to test it though.
•Interpolation: fittedmodel = fit([Time,Temperature], Energy, 'cubicinterp');
•Evaluation: fittedmodel(80, 40)
Based on your LUT inputs u1 and u2, the table will interpolate or extrapolate the grid to get your output value.
Hope that helps.
I did find a solution after all, thanks Tom for your help, the fittedmodel() function was indeed the key of it. I then used two FOR loops to populate my matrix which was 49x51 (as seen by the grid in the image) after the cftool interpolation. After that it was all a matter of two for loops in one another to populate my matrix with the z values of my T and SoC parameters.
for x = 1:49
for y = 1:51
TableData(x,y)=fittedmodel(B_SoC(x),B_Temp(y));
end
end
Where TableData is the 49x51 matrix required for my LUT, B_SoC and B_Temp being [0:2.083:100] and [-10:1.1:45] respectively (determined as the desired start and end of my x and y axis with the spacing taken from the image with the data cursor).
I have a huge set of data of a timelapse of 2D laser scans of waves running up and down stairs (see fig.1fig.2fig.3).
There is a lot of noise in the scans, since the water splashes a lot.
Now I want to smoothen the scans.
I have 2 questions:
How do I apply a moving median filter (as recommended by another study dealing with a similar problem)? I can only find instructions for single e.g. (x,y) or (t,y) plots but not for x and y values that vary over time. Maybe an average filter would do it as well, but I do not have a clue on that either.
The scanner is at a fixed point (222m) so all the data spikes point towards that point at the ceiling. Is it possible or necessary to include this into the smoothing process?
This is the part of the code (I hope it's enough to get it):
% Plot data as real time profile
x1=data.x;y1=data.y;
t=data.t;
% add moving median filter here?
h1=plot(x1(1,:),y1(1,:));
axis([210 235 3 9])
ht=title('Scanner data');
for i=1:1:length(t);
set(h1,'XData',x1(i,:),'YData',y1(i,:));set(ht,'String',sprintf('t = %5.2f
s',data.t(i)));pause(.01);end
The data.x values are stored in a (mxn) matrix in which the change in time is arranged vertically and the x values i.e. "laser points" of the scanner are horizontally arranged. The data.y is stored in the same way. The data.t values are stored in a (mx1) matrix.
I hope I explained everything clearly and that somebody can help me. I am already pretty desperate about it... If there is anything missing or confusing, please let me know.
If you're trying to apply a median filter in the x-y plane, then consider using medfilt2 from the Image Processing Toolbox. Note that this function only accepts 2-D inputs, so you'll have to loop over the third dimension.
Also note that medfilt2 assumes that the x and y data are uniformly spaced, so if your x and y data don't fall onto a uniformly spaced grid you may have to manually loop over indices, extract the corresponding patches, and compute the median.
If you can/want to apply an averaging filter instead of a median filter, and if you have uniformly spaced data, then you can use convn to compute a k x k moving average by doing:
y = convn(x, ones(k,k)/(k*k), 'same');
Note that you'll get some bias on the boundaries because you're technically trying to compute an average of k^2 pixels when you have less than that number of values available.
Alternatively, you can use nested calls to movmean since the averaging operation is separable:
y = movmean(movmean(x, k, 2), k, 1);
If your grid is separable, but not uniform, you can still use movmean, just use the SamplePoints name-value pair:
y = movmean(movmean(x, k, 2, 'SamplePoints', yv), k, 1, 'SamplePoints', xv);
You can also control the endpoint handling in movmean with the Endpoints name-value pair.
I want to evaluate the grid quality where all coordinates differ in the real case.
Signal is of a ECG signal where average life-time is 75 years.
My task is to evaluate its age at the moment of measurement, which is an inverse problem.
I think 2D approximation of the 3D case is hard (done here by Abo-Zahhad) with with 3-leads (2 on chest and one at left leg - MIT-BIT arrhythmia database):
where f is a piecewise continuous function in R^2, \epsilon is the error matrix and A is a 2D matrix.
Now, I evaluate the average grid distance in x-axis (time) and average grid distance in y-axis (energy).
I think this can be done by Matlab's Image Analysis toolbox.
However, I am not sure how complete the toolbox's approaches are.
I think a transform approach must be used in the setting of uneven and noncontinuous grids. One approach is exact linear time euclidean distance transforms of grid line sampled shapes by Joakim Lindblad et all.
The method presents a distance transform (DT) which assigns to each image point its smallest distance to a selected subset of image points.
This kind of approach is often a basis of algorithms for many methods in image analysis.
I tested unsuccessfully the case with bwdist (Distance transform of binary image) with chessboard (returns empty square matrix), cityblock, euclidean and quasi-euclidean where the last three options return full matrix.
Another pseudocode
% https://stackoverflow.com/a/29956008/54964
%// retrieve picture
imgRGB = imread('dummy.png');
%// detect lines
imgHSV = rgb2hsv(imgRGB);
BW = (imgHSV(:,:,3) < 1);
BW = imclose(imclose(BW, strel('line',40,0)), strel('line',10,90));
%// clear those masked pixels by setting them to background white color
imgRGB2 = imgRGB;
imgRGB2(repmat(BW,[1 1 3])) = 255;
%// show extracted signal
imshow(imgRGB2)
where I think the approach will not work here because the grids are not necessarily continuous and not necessary ideal.
pdist based on the Lumbreras' answer
In the real examples, all coordinates differ such that pdist hamming and jaccard are always 1 with real data.
The options euclidean, cytoblock, minkowski, chebychev, mahalanobis, cosine, correlation, and spearman offer some descriptions of the data.
However, these options make me now little sense in such full matrices.
I want to estimate how long the signal can live.
Sources
J. Müller, and S. Siltanen. Linear and nonlinear inverse problems with practical applications.
EIT with the D-bar method: discontinuous heart-and-lungs phantom. http://wiki.helsinki.fi/display/mathstatHenkilokunta/EIT+with+the+D-bar+method%3A+discontinuous+heart-and-lungs+phantom Visited 29-Feb 2016.
There is a function in Matlab defined as pdist which computes the pairwisedistance between all row elements in a matrix and enables you to choose the type of distance you want to use (Euclidean, cityblock, correlation). Are you after something like this? Not sure I understood your question!
cheers!
Simply, do not do it in the post-processing. Those artifacts of the body can be about about raster images, about the viewer and/or ... Do quality assurance in the signal generation/processing step.
It is much easier to evaluate the original signal than its views.
I've got to vectors called ttre and ttim which contain real and imaginary data over a frequency (from 1 to 64). The fields are looking like this:
ttim 64x10100 single
ttre 64x10100 single
I can easily make a 2D scatter plot of a certain row by using the command
scatter(ttim(40,:),ttre(40,:))
Now, I would like to display all data in a 3D scatter plot where X=real values, Y=imaginary values and Z=[1...64]
I created an array for Z with the number 1 to 64 and copied it to make it the same size as the other variables, by:
z=(1:64)'
z=repmat(z,1,10100)
result:
z 64x10100 double
When I try to plo a 3D scatter plot now, I get the error "Vectors x,yu,z must be of the same size"...however, as far as I understand, they are of the same size.
>> scatter3(ttim,ttre,z)
Error using scatter3 (line 64)
X, Y and Z must be vectors of the same length.
I hope that someone could point me into the right direction here.
Kind regards
scatter3 needs points to plot, so x,yand z should be 1xN , where N is the amount of points your are plotting. I dont know what your data is, so unfortunately I can not help more. Maybe scatter3(ttim(:),ttre(:),z(:)) works, but I do not recommend it for the huge amount of data you have, it may crash your computer.
However, maybe z=1:64 is not the best option. It means that you will have 64 layers (like floors from a building) of scattered data, not sure if that's what you want.
I have an unknown scalar fonction defined into a partial space (a pyramid portion), for this function, I have several measurements points into the coordonates mesurePoints, where the mesure mesure is known :
size(mesurePoints) = [n 3]
size(mesure) = n
I also have my space discretized into a clood of equidistant points wich I'll call interpolPoints,
I would like to obtain interpolated values interp_mesure on the points interpolPoints based on my measurements mesure on the points mesurePoints.
I tried to use interp3,
interp_mesure = interp3(...
mesurePoints(:,1),mesurePoints(:,2),mesurePoints(:,2),...
mesure,...
interpolPoints(:,1),interpolPoints(:,2),interpolPoints(:,3));
but I get the error that V (mesure) should be a 3D array, but I am confuse, my data isn't 3D, it is 3D dependant, but it's a scalar data, how can I proceed? Is interpol3 not adapted to my problem?
Edit 1 : Here is a similar problem to illustrate mine : how do you interpolate temperature in a volume if you have some temperature measurements in this volume?
Edit 2 : as no matlab solution have come to mind yet, I use a hand-made interpolation weighted by inverse distance with a power factor, the result is good close to points but as my points are quite scattered, the result is not good in empty areas.
I'm having trouble understanding exactly what is your data, but I get the impression that maybe interp1 or interp2 would be better suited to your needs, as your data isn't organized as a 3-D array