Minimize distance between curves

4 views (last 30 days)
Deepa Maheshvare
Deepa Maheshvare on 1 Jul 2022
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 Comments
John D'Errico
John D'Errico on 4 Jul 2022
I note that the PICTURE you originally showed had all curves with the same x values. But then when you provide data, nothing of the sort happens.
SIgh.
Deepa Maheshvare
Deepa Maheshvare on 5 Jul 2022
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`.

Sign in to comment.

Answers (1)

John D'Errico
John D'Errico on 1 Jul 2022
Edited: John D'Errico on 1 Jul 2022
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;
plot(x,ytar,'-o')
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;
plot(x',ydata','r-',x,ytar,'b-o')
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
plot(x',ycal','r-',x,ytar,'b-o')
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.

Categories

Find more on Curve Fitting Toolbox in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!