在 MATLAB 中求解数据点之间的自变量
Solve for independent variable between data points in MATLAB
我在同一时间段内有很多组数据,时间步长为 300 秒。在观察期结束前终止的集合(这里我将其截断为 0 到 3000 秒)在剩余空间中有 NaN:
x = [0;300;600;900;1200;1500;1800;2100;2400;2700;3000];
y(:,1) = [4.65;3.67;2.92;2.39;2.02;1.67;1.36;1.07;NaN;NaN;NaN];
y(:,2) = [4.65;2.65;2.33;2.18;2.03;1.89;1.75;1.61;1.48;1.36;1.24];
y(:,3) = [4.65;2.73;1.99;1.49;1.05;NaN;NaN;NaN;NaN;NaN;NaN];
我想知道每个数据集什么时候会达到 y 等于特定值的点,在这种情况下 y = 2.5
我首先尝试找到最接近 2.5 的 y 值,然后使用关联的时间,但这不是很准确(点应该都落在同一条水平线上):
ybreak = 2.5;
for ii = 1:3
[~, index] = min(abs(y(:,ii)-ybreak));
yclosest(ii) = y(index,ii);
xbreak(ii) = x(index);
end
然后我尝试在数据点之间进行线性插值,然后在 y=2.5 处求解 x,但无法完成这项工作:
首先我删除了 NaN(似乎必须有更简单的方法?):
for ii = 1:3
NaNs(:,ii) = isnan(y(:,ii));
for jj = 1:length(x);
if NaNs(jj,ii) == 0;
ycopy(jj,ii) = y(jj,ii);
end
end
end
然后试装:
for ii = 1:3
f(ii) = fit(x(1:length(ycopy(:,ii))),ycopy(:,ii),'linearinterp');
end
并得到以下错误信息:
Error using cfit/subsasgn (line 7)
Can't assign to an empty FIT.
当我尝试在循环外拟合时(仅针对一个数据集),它工作正常:
f = fit(x(1:length(ycopy(:,1))),ycopy(:,1),'linearinterp');
f =
Linear interpolant:
f(x) = piecewise polynomial computed from p
Coefficients:
p = coefficient structure
但我仍然无法解决 f(x)=2.5 找到 y=2.5
的时间
syms x;
xbreak = solve(f(x) == 2.5,x);
Error using cfit/subsref>iParenthesesReference (line 45)
Cannot evaluate CFIT model for some reason.
Error in cfit/subsref (line 15)
out = iParenthesesReference( obj, currsubs );
任何关于其他方法的建议或想法将不胜感激。我需要能够对许多数据集执行此操作,所有这些数据集都有不同数量的 NaN 值。
正如您提到的 y=2.5
不在您的数据集中,因此对应于此的 x
的值取决于您使用的插值方法。对于线性插值,你可以使用类似下面的东西
x = [0;300;600;900;1200;1500;1800;2100;2400;2700;3000];
y(:,1) = [4.65;3.67;2.92;2.39;2.02;1.67;1.36;1.07;NaN;NaN;NaN];
y(:,2) = [4.65;2.65;2.33;2.18;2.03;1.89;1.75;1.61;1.48;1.36;1.24];
y(:,3) = [4.65;2.73;1.99;1.49;1.05;NaN;NaN;NaN;NaN;NaN;NaN];
N = size(y, 2);
x_interp = NaN(N, 1);
for i = 1:N
idx = find(y(:,i) >= 2.5, 1, 'last');
x_interp(i) = interp1(y(idx:idx+1, i), x(idx:idx+1), 2.5);
end
figure
hold on
plot(x, y)
scatter(x_interp, repmat(2.5, N, 1))
hold off
请记住,上面的代码假设您的数据是单调递减的(正如您的数据一样),但此解决方案也可以适用于单调递增。
我在同一时间段内有很多组数据,时间步长为 300 秒。在观察期结束前终止的集合(这里我将其截断为 0 到 3000 秒)在剩余空间中有 NaN:
x = [0;300;600;900;1200;1500;1800;2100;2400;2700;3000];
y(:,1) = [4.65;3.67;2.92;2.39;2.02;1.67;1.36;1.07;NaN;NaN;NaN];
y(:,2) = [4.65;2.65;2.33;2.18;2.03;1.89;1.75;1.61;1.48;1.36;1.24];
y(:,3) = [4.65;2.73;1.99;1.49;1.05;NaN;NaN;NaN;NaN;NaN;NaN];
我首先尝试找到最接近 2.5 的 y 值,然后使用关联的时间,但这不是很准确(点应该都落在同一条水平线上):
ybreak = 2.5;
for ii = 1:3
[~, index] = min(abs(y(:,ii)-ybreak));
yclosest(ii) = y(index,ii);
xbreak(ii) = x(index);
end
然后我尝试在数据点之间进行线性插值,然后在 y=2.5 处求解 x,但无法完成这项工作:
首先我删除了 NaN(似乎必须有更简单的方法?):
for ii = 1:3
NaNs(:,ii) = isnan(y(:,ii));
for jj = 1:length(x);
if NaNs(jj,ii) == 0;
ycopy(jj,ii) = y(jj,ii);
end
end
end
然后试装:
for ii = 1:3
f(ii) = fit(x(1:length(ycopy(:,ii))),ycopy(:,ii),'linearinterp');
end
并得到以下错误信息:
Error using cfit/subsasgn (line 7)
Can't assign to an empty FIT.
当我尝试在循环外拟合时(仅针对一个数据集),它工作正常:
f = fit(x(1:length(ycopy(:,1))),ycopy(:,1),'linearinterp');
f =
Linear interpolant:
f(x) = piecewise polynomial computed from p
Coefficients:
p = coefficient structure
但我仍然无法解决 f(x)=2.5 找到 y=2.5
的时间syms x;
xbreak = solve(f(x) == 2.5,x);
Error using cfit/subsref>iParenthesesReference (line 45)
Cannot evaluate CFIT model for some reason.
Error in cfit/subsref (line 15)
out = iParenthesesReference( obj, currsubs );
任何关于其他方法的建议或想法将不胜感激。我需要能够对许多数据集执行此操作,所有这些数据集都有不同数量的 NaN 值。
正如您提到的 y=2.5
不在您的数据集中,因此对应于此的 x
的值取决于您使用的插值方法。对于线性插值,你可以使用类似下面的东西
x = [0;300;600;900;1200;1500;1800;2100;2400;2700;3000];
y(:,1) = [4.65;3.67;2.92;2.39;2.02;1.67;1.36;1.07;NaN;NaN;NaN];
y(:,2) = [4.65;2.65;2.33;2.18;2.03;1.89;1.75;1.61;1.48;1.36;1.24];
y(:,3) = [4.65;2.73;1.99;1.49;1.05;NaN;NaN;NaN;NaN;NaN;NaN];
N = size(y, 2);
x_interp = NaN(N, 1);
for i = 1:N
idx = find(y(:,i) >= 2.5, 1, 'last');
x_interp(i) = interp1(y(idx:idx+1, i), x(idx:idx+1), 2.5);
end
figure
hold on
plot(x, y)
scatter(x_interp, repmat(2.5, N, 1))
hold off
请记住,上面的代码假设您的数据是单调递减的(正如您的数据一样),但此解决方案也可以适用于单调递增。