Matlab - 找到缩放曲线的解决方案
Matlab - finding solution for scaling a curve
考虑两条曲线,例如:
x = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = [0 -0.2 -0.3 -0.8 -2 1 2.8 2.4 1.5 1.1 2.3 -0.4 -0.2 1 1.1 1.2 1.3 0.5 -0.1 0];
我想编写一个通用算法,它接受 x
、y1
和 y2
,并按全局比例因子缩放 y1
,f
,使得 y2-y1
的新值尽可能接近 0
。即y2-f*y1
尽可能接近0。
我该怎么做?
试试这个:
% Create a function that you want to minimize
func = @(f, y1, y2)abs(sum(y2 - f*y1));
% Your example data
x = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = [0 -0.2 -0.3 -0.8 -2 1 2.8 2.4 1.5 1.1 2.3 -0.4 -0.2 1 1.1 1.2 1.3 0.5 -0.1 0];
% Plot the before
figure()
plot(x, y2); hold all;
plot(x, y1)
% Find the optimum scale factor
f_start = 0; % May want a different starting point
f = fminsearch(@(f) func(f, y1, y2), f_start);
disp(['Scale factor = ' num2str(f)]) % print to the output
% Plot the after (scaled data)
figure()
plot(x, y2); hold all;
plot(x, f*y1)
有关详细信息,请参阅 anonymous functions and fminsearch
上的文档(参见示例 #2)。
编辑
以上脚本的输出如下:
Scale factor = -2.9398
之前
之后
如您所见,函数之间的差异已最小化(y1 大于 y2 的区域与 y1 小于 y2 的区域大致相同)。如果你想让线条尽可能接近,那么你需要像这样修改最小化函数:
func = @(f, y1, y2)sum(abs(y2 - f*y1));
我不得不修改这个案例的测试数据,因为看起来数据已经排列成最佳状态。
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = -2*y1 +1;
给出以下输出:
Scale factor = -2.9091
之前
之后
考虑两条曲线,例如:
x = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = [0 -0.2 -0.3 -0.8 -2 1 2.8 2.4 1.5 1.1 2.3 -0.4 -0.2 1 1.1 1.2 1.3 0.5 -0.1 0];
我想编写一个通用算法,它接受 x
、y1
和 y2
,并按全局比例因子缩放 y1
,f
,使得 y2-y1
的新值尽可能接近 0
。即y2-f*y1
尽可能接近0。
我该怎么做?
试试这个:
% Create a function that you want to minimize
func = @(f, y1, y2)abs(sum(y2 - f*y1));
% Your example data
x = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = [0 -0.2 -0.3 -0.8 -2 1 2.8 2.4 1.5 1.1 2.3 -0.4 -0.2 1 1.1 1.2 1.3 0.5 -0.1 0];
% Plot the before
figure()
plot(x, y2); hold all;
plot(x, y1)
% Find the optimum scale factor
f_start = 0; % May want a different starting point
f = fminsearch(@(f) func(f, y1, y2), f_start);
disp(['Scale factor = ' num2str(f)]) % print to the output
% Plot the after (scaled data)
figure()
plot(x, y2); hold all;
plot(x, f*y1)
有关详细信息,请参阅 anonymous functions and fminsearch
上的文档(参见示例 #2)。
编辑
以上脚本的输出如下:
Scale factor = -2.9398
之前
如您所见,函数之间的差异已最小化(y1 大于 y2 的区域与 y1 小于 y2 的区域大致相同)。如果你想让线条尽可能接近,那么你需要像这样修改最小化函数:
func = @(f, y1, y2)sum(abs(y2 - f*y1));
我不得不修改这个案例的测试数据,因为看起来数据已经排列成最佳状态。
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = -2*y1 +1;
给出以下输出:
Scale factor = -2.9091
之前