MATLAB: интерполяция, чтобы найти значение x пересечения между линией и кривой

Вот график, который у меня сейчас есть:

Синяя пунктирная линия представляет собой значение y, соответствующее значению x, которое я ищу. Я пытаюсь найти x  значения пересечения линии с синей кривой (верхняя)

Пунктирная синяя линия представляет значение y, которое соответствует значению x, которое я ищу. Я пытаюсь найти значения x пересечений линии с синей кривой (верхняя). Поскольку пересечения не попадают в точку, которая уже определена, нам нужно интерполировать точку, которая попадает на верхний график.

Вот информация, которой я располагаю:

LineValue — значение y пересечения и значение пунктирной линии ( y = LineValue). Frequency — массив, содержащий координаты значения x, видимые на этом графике. Интерполированные значения частоты, соответствующие LineValue, — это то, что мы ищем. Верхний/нижний — массивы, содержащие информацию о значении y для этого графика.


person Alex Nichols    schedule 04.08.2011    source источник
comment
возможный дубликат matlab, как мне написать оператор, который даст мне время по оси x от y=0,3   -  person Amro    schedule 05.08.2011


Ответы (3)


Пример решения с использованием FZERO:

%# data resembling your curve
x = linspace(-100,100,100);
f = @(x) 1-2.*exp(-0.5*x.^2./20)./(2*pi) + randn(size(x))*0.002;
VALUE = 0.8;

%# solve f(x)=VALUE
z1 = fzero(@(x)f(x)-VALUE, -10);  %# find solution near x=-10
z2 = fzero(@(x)f(x)-VALUE, 10);   %# find solution near x=+10

%# plot
plot(x,f(x),'b.-'), hold on
plot(z1, VALUE, 'go', z2, VALUE, 'go')
line(xlim(), [VALUE VALUE], 'Color',[0.4 0.4 0.4], 'LineStyle',':')
hold off

скриншот

person Amro    schedule 04.08.2011

Это решение является улучшением Ответ Амро. Вместо использования fzero вы можете просто вычислить пересечение линии, ища переход в первой разности ряда, созданного логическим сравнением с LineValue. Итак, используя образцы данных Amro:

>> x = linspace(-100,100,100);
>> y =  1-2.*exp(-0.5*x.^2./20)./(2*pi) + randn(size(x))*0.002;
>> LineValue = 0.8;

Найдите начальные индексы тех сегментов последовательных точек, которые превышают LineValue:

>> idx = find(diff(y >= LineValue))

idx =

    48    52

Затем вы можете рассчитать позиции x точек пересечения, используя средневзвешенные значения (т.е. линейную интерполяцию):

>> x2 = x(idx) + (LineValue - y(idx)) .* (x(idx+1) - x(idx)) ./ (y(idx+1) - y(idx))

x2 =

         -4.24568579887939          4.28720287203057

Постройте их, чтобы проверить результаты:

>> figure;
>> plot(x, y, 'b.-', x2, LineValue, 'go', [x(1) x(end)], LineValue*[1 1], 'k:');

введите здесь описание изображения

Преимущества этого подхода:

  • Определение точек пересечения векторизовано, поэтому будет работать независимо от количества точек пересечения.
  • Арифметическое определение точек пересечения, по-видимому, быстрее, чем использование fzero.
person b3.    schedule 04.08.2011

Одинаковы ли размеры шагов в ваших рядах данных? Предполагается ли, что управляющее уравнение кубическое, синусоидальное и т. д.?

doc interpl Найдите пересечение нуля

person Jacob M    schedule 04.08.2011
comment
Данные должны быть синусоидальными - person Alex Nichols; 05.08.2011