Перейти к содержанию
    

Как бы вычислить модуль разности побыстрее?

Хочу найти, насколько далеко новые данные отклонились от старых. Например, 7 - 5 = 2. А 5 - 7 = -2. И я должен преобразовать -2 в 2, теряя производительность. А нельзя ли сразу из чисел 5 и 7 получить 2?

 

Уточню. Мне не сам модуль нужен, а превышает ли он такой же предыдущий модуль разности (для предыдущей выборки). В-общем, творю хитрый (голь на выдумку хитра) пиковый детектор.

Придумал такой способ. Разность должна быть или больше предыдущей, или меньше (-предыдущей).

 

Напишу формулами. dd - текущее значение, pp - относительно него определяется изменение, pc - текущий пик.

 

Решение, что есть новый пик:

 

|dd - pp| > |pc - pp|

 

Переделал в такое:

 

((dd - pp) > (pc - pp)) || ((dd - pp) < (pp - pc))

 

что-то здесь не правильно!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Конвейеризация вычисления невозможна?

Можно. Здесь больше математический вопрос, чем технический.

Нет, нельзя! Нужно же к приходу новой выборки уже определиться, у нас новый экстремум нашелся или старый остался.

 

Разность должна быть или больше предыдущей, или меньше (-предыдущей).
Это уже неправильно.

 

Если представить эти разности в виде A и B, получается 4 уравнения.

|A| > |B|, если:

A > B при A > 0, B > 0

-A > B при A < 0, B > 0

A > -B при A > 0, B < 0

-A > -B при A < 0, B < 0

Не вижу просвета, как упростить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из предыдущих формул вышло:

 

if (pc > pp) && ((dd > pc) || (dd < 2*pp - pc))

if (pc < pp) && ((dd < pc) || (dd > 2*pp - pc))

 

Это упрощение, или как, не пойму. :rolleyes:

 

По-моему, проще, все-таки, модуль вычислить.

|a - b| = (a - b )[MSB] ? (b - a) : (a - b )

Обе разности вычислять параллельно, а записывать по значению старшего бита разности. Числа, естественно, знаковые.

 

И никак администрация не выкинет этих смайликов дурных! Эх, Рассея...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По-моему, проще, все-таки, модуль вычислить.

|a - b| = (a - b )[MSB] ? (b - a) : (a - b )

Обе разности вычислять параллельно, а записывать по значению старшего бита разности. Числа, естественно, знаковые.

зависит от архитектуры плис, а именно есть мультиплексор в люте или нет.

 

assign pipa = a - b; 

assign popa = (pipa ^ {$size(pipa){pipa[$high(pipa)]}})+ pipa[$high(pipa)];

зависит есть ли LUT на входе сумматора или нет. Если коррекцию знакового бита отбросить, то не зависит от сумматора

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно. Здесь больше математический вопрос, чем технический.

Нет, нельзя! Нужно же к приходу новой выборки уже определиться, у нас новый экстремум нашелся или старый остался.

Действительно, так нельзя. Напишите, пожалуйста, полный алгоритм на Си, а то не совсем понятно, что требуется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На определенном интервале (для определенного количества последовательных выборок данных dd)

if (|dd - pp| > |pc - pp|) pc = dd;

На следующем таком же интервале в качестве pp выступает pc, найденный в предыдущем интервале (показанный выше).

Для начального интервала pp нет. Пусть нулем будет, не важно.

Я хочу на каждом интервале находить значение, максимально далеко ушедшее от предыдущего интервала. По нормальному, пиковый детектор находит максимум и минимум, но у меня памяти нет. До этого записывал то максимум, то минимум попеременно. Теперь хочу хитрее сделать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На определенном интервале (для определенного количества последовательных выборок данных dd)

if (|dd - pp| > |pc - pp|) pc = dd;

На следующем таком же интервале в качестве pp выступает pc, найденный в предыдущем интервале (показанный выше).

Понятно, тогда сначала можно посчитать минимум и максимум на интервале, с обратной связью в один или два такта, а затем уже неспеша посчитать pp на основе минимума или максимума:

next_pp = abs(interval_min-pp) > abs(interval_max-pp) ? interval_min:interval_max;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Понятно, тогда сначала можно посчитать минимум и максимум на интервале, с обратной связью в один или два такта, а затем уже неспеша посчитать pp на основе минимума или максимума:

next_pp = abs(interval_min-pp) > abs(interval_max-pp) ? interval_min:interval_max;

Правильно. Но это выражение тоже должно вычислиться за такт. Потому что время-не-ждет. То есть, именно это выражение можно вычислять постоянно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 assign popa = (pipa ^ {$size(pipa){pipa[$high(pipa)]}})+ pipa[$high(pipa)];

Полистал стандарт на SV, вижу, $size и $high относятся к массивам, выдают количество элементов и номер бита размерности. А у меня разве массив (pipa, popa)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Полистал стандарт на SV, вижу, $size и $high относятся к массивам, выдают количество элементов и номер бита размерности. А у меня разве массив (pipa, popa)?

если полистаете еще немного, то увидите что и векторов в этом стандарте тоже нет

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Например, 7 - 5 = 2. А 5 - 7 = -2. И я должен преобразовать -2 в 2, теряя производительность. А нельзя ли сразу из чисел 5 и 7 получить 2?

Есть возможность просто отбросить знак результата? В какой форме числа? В дополнительном коде?

 

И никак администрация не выкинет этих смайликов дурных!

Какие проблема со смайликами? :) Есть же специальный тег code 8)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть возможность просто отбросить знак результата? В какой форме числа? В дополнительном коде?

Вообще-то, до сих пор данные были беззнаковые байты. Но при вычитании получу уже в дополнительном коде? Просто отбросить знак не получится.

Какие проблема со смайликами? :) Есть же специальный тег code 8)

code, так code. B)

 

Склоняюсь к использованию формул из сообщения 4, верхних. Упростить бы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Правильно. Но это выражение тоже должно вычислиться за такт. Потому что время-не-ждет. То есть, именно это выражение можно вычислять постоянно.

Повторю более развернуто - за такт должны вычисляться простые выражения:

t_min <= reset_min_max? dd: min(t_min, dd);

t_max <= reset_min_max? dd: max(t_max, dd);

reset_min_max устанавливается на такт в начале интервала

по завершении интервала сохранить min, max:

interval_min <= t_min; interval_max <= t_max;

далее выражение

next_pp <= abs(interval_min-pp) > abs(interval_max-pp) ? interval_min: interval_max;

может вычисляться несколько тактов в течение всего следующего итервала.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Значение из последнего выражения должно быть готово к приходу следующей выборки, первой из следующего интервала. А они, выборки, идут непрерывным потоком, через 4 нс.

О, понял! Вы правы, сравнивать-то можно в конце интервала. Спасибо!!

P.S. имел в виду, не в конце интервала, а в течение всего интервала. Для последнего выражения. Оно не требуется для нахождения минимума и максимума на интервале.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...