Minimize distance between curves

조회 수: 5(최근 30일)
Deepa Maheshvare
Deepa Maheshvare 2022년 7월 1일
댓글: Deepa Maheshvare 2022년 7월 5일
I have a dataset with values of multiple curves. An example plot is shown below.
I want to shift the curves (up/down) so that all curves overlap. This would mean the data points in each curve is scaled up/down by a factor.
I am not sure how to frame this as a mathematical problem (to minimize the vertical distance between each pair of curves) and determine the scaling factor
for each curve. I tried to start by computing the pair-wise distance matrix using norm fucntion
but I am not sure what to do next and which MATLAB function can be used for set up this problem.
Suggestions will be really appreciated.
  댓글 수: 3
Deepa Maheshvare
Deepa Maheshvare 2022년 7월 5일
Sorry about that. Yes, in the use case that I shared the x values are different. So I tried to find the x range in the region where the curves overlap and interpolated using `interp1`.

댓글을 달려면 로그인하십시오.


John D'Errico
John D'Errico 2022년 7월 1일
편집: John D'Errico 2022년 7월 1일
This is a classic calibration problem of sorts. Lacking any data, I cannot really help you as much as I might want to. But I can at least generate some fake data. If you want to provide some data, feel free to do so, attached to a comment.
First, you need to decide if the problem is PURELY that of a scaling problem, or if you wanted to add some constant also to each curve to translate it up and down.
Next, you will need to choose some target curve. Which one will be the aim, the one that all others will be adjusted to look like?
For example, here is some fake data I just made up:
x = 0:10; nx = length(x);
ytar = 2*x - x.^2/10 + randn(size(x))/8;
So a little noise in it. But not too bad.
Now I'll generate some other random curves that we will need to adjust. 5 curves should be about right.
ny = 5;
ydata = (randn(ny,1)+2)*ytar + randn(ny,nx)/2;
Does that seem at least similar to what you have?
Now, each of those curves need to be adjusted by a pure scale factor to look like the ytar curve. We can do that using some simple linear algebra. Backslash is your friend here.
calconstants = ytar'\ydata'
calconstants = 1×5
2.6715 2.2991 3.0807 0.6909 2.8161
These are the scale factors we need to re-scale the data, to make all of the curves look like the ytar curve. Il plot them all on top of each other now, after re-scaling.
ycal = ydata./calconstants'
ycal = 5×11
0.4483 1.6613 3.5437 4.9324 6.3420 7.0360 8.7843 9.0168 9.7390 10.0170 10.1139 -0.1354 2.0072 3.3771 4.8693 6.6542 7.5588 7.7968 9.2379 9.4374 10.2308 10.2684 0.1827 1.7301 3.6505 4.9389 6.4679 7.0444 8.4057 9.3268 9.5478 10.0945 10.1162 -0.4973 2.0692 4.2226 4.0349 5.5088 6.9762 8.8794 7.5352 10.2266 10.9548 10.6845 -0.3152 1.6675 3.6829 5.2050 6.2903 7.5578 8.3525 9.2361 9.2563 9.9448 10.2788
As you can see, all of the red curves now look as much as possible like the blue curve.
In the event that you also needed a constant additive translation up or down, that is also possible, but I don't have your data to know if that would be useful.




Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by