Error using matlab.internal.math.interp1, Sample points must be unique.
古いコメントを表示

I am getting this error when I run the attached matlab code. I couldn't figure out how to solve it and I would be very happy if you can help me.
Thanks in advance.
12 件のコメント
Torsten
2023 年 10 月 24 日
Your input file is missing.
But the error seems quite well explained: in a call to interp1, you seem to use some dupliciate values for the independent variable (in the below case x):
yq = interp1(x,y,xq)
Furkan Sencer Kaçar
2023 年 10 月 24 日
Torsten
2023 年 10 月 24 日
As you said, I am trying to use some duplicate values, is it not possible?
No. To use interp1, x must be strictly monotone and unique.
Maybe you could prescribe y for non-unique x values as the arithmetic mean of the corresponding y-values ?
Star Strider
2023 年 10 月 24 日
x — Sample points
vector
Sample points, specified as a row or column vector of real numbers. The values in x must be distinct. ...
type ddt_MatRANS
which it wasn't but shows trying to interpolate over a time vector. You'll have to use distinct time points to use the function as it was written--not knowing what it is you're trying to do as to why you would have duplicated times, the closest thing you could do would be to introduce a slight difference between points that hopefully wouldn't otherwise effect the results by introducing huge gradients if, for example, the corresponding y values are grossly different as in a step change; the model is likely not designed to handle such transients anyway.
Furkan Sencer Kaçar
2023 年 10 月 24 日
編集済み: Torsten
2023 年 10 月 24 日
M = readmatrix('Inputs.txt')
numel(unique(M(:,1)))
numel(unique(M(:,2)))
The first column has 4001 unique values out of 4004 rows. So not distinct.
No, they are not distinct (see above).
data=readmatrix('Inputs.txt');
[u,iu]=unique(data(:,1));
subplot(2,2,[1,2])
plot(u,data(iu,2),'k-')
hold on
ix=find(diff(data(:,1))==0);
plot(data(ix,1),data(ix,2),'r*')
ylim([0 0.6])
subplot(2,2,3)
plot(u,data(iu,2),'k-')
hold on
plot(data(ix(1),1),data(ix(1),2),'r*')
xlim(data(ix(1))+[-5 +5])
ylim([0.5455 0.5505])
subplot(2,2,4)
plot(u,data(iu,2),'k-')
hold on
plot(data(ix(3),1),data(ix(3),2),'r*')
xlim(data(ix(3))+[-5 +5])
ylim([0.5455 0.5505])
shows the trace is smooth and that the duplicated points could be safely discarded...looks like maybe somebody/some prior function augmented the original response with the peak locations and the end point of the first transient with a pretrigger interval before the second...I didn't check to see, but maybe the second is a replication of the first????
FYI if users want to mark the peak values, one way to do that without duplicating the peak values (assuming you ONLY want those peaks marked) is to use the MarkerIndices property of line objects.
x = 1:10;
y = x.^2;
plot(x, y, 'o-', 'MarkerIndices', 1:2:10) % Mark every other point
xline(1:2:10, ':')
You can use islocalmax to identify the maximum points.
figure
x = 0:720;
y = sind(x);
loc = islocalmax(y);
plot(x, y, 'o-', 'MarkerIndices', find(loc))
Good sidebar comment @Steven Lord -- I wasn't aware that 'MarkerIndices' had been added to line properties....or maybe it's always been there and I just didn't recall it; I know I've combed the list in its entirety before.
Steven Lord
2023 年 10 月 25 日
回答 (2 件)
interp1 is not intended to fit equations. There are other tools to do that. If you insist on using this function, you will either have to calculate some consensus value for each unique x (e.g. the mean, the median, the maximum, the minimum, ...), or you should adjust the x values slightly so each value becomes unique.
Note that the order of your x-values suddenly matters for the second option, because each element will have a different offset based on the position.
x = [1 1 1 2 3];
y = [0 1 2 3 4];
xq = 1:3;
[x2,y2]=AdjustWithMedian(x,y)
[x3,y3]=AdjustWithEps(x,y)
[x4,y4]=AdjustWithPolyfit(x,y)
plot(x,y,'b*','DisplayName','raw data'),axis([0.5 3.5 -0.5 4.5])
hold on
plot(xq,interp1(x2,y2,xq),'m--o','DisplayName','Adjusted with median')
plot(xq,interp1(x3,y3,xq),'k:o','DisplayName','Adjusted with eps')
plot(xq,interp1(x4,y4,xq),'g-.o','DisplayName','Adjusted with polyfit')
hold off
legend('Location','SouthEast')
function [x_adj,y]=AdjustWithEps(x,y)
% Add a different amount to each x-value to make them unique.
% The sum of the shift should be equal to 0 to avoid an overall drift.
shift = 1:numel(x);
shift = shift - mean(shift);
x_adj = x(:) + shift(:)*eps;
x_adj = reshape(x_adj,size(x));
end
function [new_x,new_y]=AdjustWithMedian(x,y)
% For each unique x, only keep the median y-value
[new_x,ignore,ind] = unique(x);
new_y = accumarray(ind,y,[numel(new_x) 1],@median);
if isrow(x),new_y = new_y.';end % Keep directions consistent
end
function [x,y]=AdjustWithPolyfit(x,y)
p=polyfit(x,y,1);
x=unique(x);
y=polyval(p,x);
end
As the follow on comment above shows, you can safely ignore the duplicate points and retain the original function -- use
[~,iu]=unique(data(:,1));
data=data(iu,:);
in place of the full data array to reduce it to the set of unique times and associated values; then pass the resulting time, response vectors to the function instead and all should work just fine...although there might be a question regarding there being two transients in the overall trace? Or is this an input concentration to be modelled its dispersion, maybe, in which case it could be intended and correct--we don't know anything about the problem trying to solve, just that there were duplicated times in this input trace that aren't allowed by the construction of the function.
カテゴリ
ヘルプ センター および File Exchange で Data Distribution Plots についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



