[Решено] скрипт maxima - странное поведение (в цикле while)

Модератор: Модераторы разделов

Аватара пользователя
anjolio
Сообщения: 663
Статус: радист
ОС: debian squeeze

[Решено] скрипт maxima - странное поведение

Сообщение anjolio »

Ребят, в программировании не силен, но вопрос больше программистский, чем новичковый.

Пишу скрипт обработки сигнала для курсача. Задача - по превышению сигналом уровня 0.5 произвести вычисления. Сигнал задан дискретно в массиве fim_discrete_noise.

Привожу логически понятный скрипт для любого, кто хоть немного программированием занимается (если какие-то функции непонятны - напишу что это):

Код:

array(num,7)$ array(fim_output,7)$ period:0$ l:0$ for i:0 thru 7 do ( k:period, mark:0, if (l=0) then l:1 else l:0, while mark=0 do ( for j:k thru k+62 do ( if (fim_discrete_noise[j]>0.5) then ( sig:(j-period)/6.25, mark:1, num[i]:j ) ), mark:1 ), fim_output[i]:round(sig), period:period+62+l )$ fim_output_list_1:create_list("Result:")$ fim_output_list_2:create_list(fim_output[j], j,0,7)$ fim_output_list: append (fim_output_list_1,fim_output_list_2)$ fim_output_list; listarray(num);

Результат (вторая строка - j при которых срабатывает цикл):

Код: Выделить всё

[Result:,1,9,0,4,1,9,8,8]
[11,125,130,217,261,374,430,492]


А теперь привожу просто прогонку массива fim_discrete_noise на превышение уровня 0.5:

Код: Выделить всё

for i:0 thru 499 do (if (fim_discrete_noise[i]>0.5) then display(i));
Результат (оставил только те i, на которых появляется превышение уровня 0.5):

Код: Выделить всё

i=6

i=118

i=130

i=212

i=256

i=368

i=425

i=487


Как видим в цикле идет явное запаздывание на 5 тактов. Я вот сижу и не могу вкурить, откуда такое могло взяться.. Нет догадок, где тут вкралась ошибка?

Я в принципе нашел выход - вычитать 5 из j. Но это как-то не гламурно.
The two most common things in the Universe are hydrogen and stupidity. (Harlan Ellison)
Спасибо сказали:
Аватара пользователя
Mage-Warrior
Сообщения: 869
Статус: Семь раз понюхай, один раз откуси!
ОС: SlackWare 12.1

Re: [Решено] скрипт maxima - странное поведение

Сообщение Mage-Warrior »

Так. Не пойму, зачем нужен цикл ... while mark=0 do (... mark:1)$. Язык разве имеет возможность проверять значение условия внутри цикла (и прерывать его), а не только после выполнения последней вложенной операции? Если нет, то зачем делать заведомо 1 цикл. То есть 5 строк в скрипте уже лишние.
Ещё одно - вычитание 5 из j - не решение, так как в показанных примерах третьи элементы массивов совпадают. Логически проблема заключается либо в том, что здесь:

Код: Выделить всё

if (fim_discrete_noise[j]>0.5) then
                                (
                                sig:(j-period)/6.25,
                                mark:1,
                                num[i]:j

...успевает изменяться значение j (не вижу, где бы это могло произойти). Либо в том, что массивы fim_discrete_noise[] банально отличаются - что гораздо более вероятно. Вставьте:

Код: Выделить всё

for s:0 thru 499 do (if (fim_discrete_noise[s]>0.5) then display(s));

... перед циклом for приведенной программы и проверьте результат.
*- Большинство проблем, дружок, завсегда покажет лог! -*
Спасибо сказали:
Аватара пользователя
anjolio
Сообщения: 663
Статус: радист
ОС: debian squeeze

Re: [Решено] скрипт maxima - странное поведение

Сообщение anjolio »

Mage-Warrior писал(а):
03.06.2008 12:52
Так. Не пойму, зачем нужен цикл ... while mark=0 do (... mark:1)$. Язык разве имеет возможность проверять значение условия внутри цикла (и прерывать его), а не только после выполнения последней вложенной операции? Если нет, то зачем делать заведомо 1 цикл. То есть 5 строк в скрипте уже лишние.

Ну в таком случае может проблема как раз в том, что цикл не прерывается у меня.
Я специально приложу график, чтобы словами не растекаться тут. Тогда у меня на выходе цикла while переменная sig равна не первому значению сигнала, при котором превышен уровень 0.5, а последнему, при котором больше 0.5...
Mage-Warrior, спасибо большое, я если честно не знал, что while не может проверять условия внутри себя..

Операции break я не нашел, но длина импульса у меня постоянна, поэтому ограничусь простым вычитаением 5. Теперь я хотя бы могу предсказать как работает мой цикл (:
А совпадение 3-го элемента (i=130) из-за того, что там 2 импульса сливаются.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
The two most common things in the Universe are hydrogen and stupidity. (Harlan Ellison)
Спасибо сказали:
Аватара пользователя
Mage-Warrior
Сообщения: 869
Статус: Семь раз понюхай, один раз откуси!
ОС: SlackWare 12.1

Re: [Решено] скрипт maxima - странное поведение

Сообщение Mage-Warrior »

Можете меня бить ногами ;) , но я не согласен с тем, что обозначенная проблема заключается в непрерываемом цикле.
Этот код:

Код: Выделить всё

for s:0 thru 499 do (if (fim_discrete_noise[s]>0.5) then display(s));

... по сути должен выводить все номера массива, где значение элемента выше 0,5. Тогда бы мы в выводе увидели и i=11 тоже. Я бы всё-таки попробовал вставить эту строчку в начало скрипта для контроля.
*- Большинство проблем, дружок, завсегда покажет лог! -*
Спасибо сказали:
Аватара пользователя
anjolio
Сообщения: 663
Статус: радист
ОС: debian squeeze

Re: [Решено] скрипт maxima - странное поведение

Сообщение anjolio »

Вот получившийся скрипт

Код:

array(fim_output,7)$ period:0$ l:0$ for s:0 thru 499 do (if (fim_discrete_noise[s]>0.5) then display(s)); for i:0 thru 7 do ( k:period, if (l=0) then l:1 else l:0, for j:k thru k+62 do if (fim_discrete_noise[j]>0.5) then (sig:(j-period-5)/6.25), fim_output[i]:round(sig), period:period+62+l )$ fim_output_list_1:create_list("Result:")$ fim_output_list_2:create_list(fim_output[j], j,0,7)$ fim_output_list: append (fim_output_list_1,fim_output_list_2)$ fim_output_list;
и результат выполнения:

Код:

s=6 s=7 s=8 s=9 s=10 s=11 s=118 s=119 s=120 s=121 s=122 s=123 s=124 s=125 s=126 s=127 s=128 s=129 s=130 s=212 s=213 s=214 s=215 s=216 s=217 s=256 s=257 s=258 s=259 s=260 s=261 s=368 s=369 s=370 s=371 s=372 s=373 s=374 s=425 s=426 s=427 s=428 s=429 s=430 s=487 s=488 s=489 s=490 s=491 s=492

Код: Выделить всё

[Result:,1,9,0,4,1,9,8,8]
The two most common things in the Universe are hydrogen and stupidity. (Harlan Ellison)
Спасибо сказали:
Аватара пользователя
Mage-Warrior
Сообщения: 869
Статус: Семь раз понюхай, один раз откуси!
ОС: SlackWare 12.1

Re: [Решено] скрипт maxima - странное поведение

Сообщение Mage-Warrior »

Вот. Теперь понятно - Ваше предположение верно. И не поспоришь :tongue: Удачи!
*- Большинство проблем, дружок, завсегда покажет лог! -*
Спасибо сказали:
Аватара пользователя
anjolio
Сообщения: 663
Статус: радист
ОС: debian squeeze

Re: [Решено] скрипт maxima - странное поведение

Сообщение anjolio »

Mage-Warrior писал(а):
04.06.2008 07:52
Удачи!
Спасибо, сегодня защитил курсач (: Если интересно, то получившийся скрипт тут.
The two most common things in the Universe are hydrogen and stupidity. (Harlan Ellison)
Спасибо сказали: