2015-01-29 3 views
2

Я видел этот кусок кода JJ код Чоп ничтожные цифры

(**+)&.+. 

в разделе RosettaCode FFT. Предполагается очистить незначительные цифры результата БПФ. Например,

(** +) &. +. 4e_16j2

дает

0j2 

Он похож на Chop функции Mathematica, например.

Однако

(**+)&.+. _4j_2 

дает

4j2 (instead of _4j_2) 

, который, очевидно, неверно.

Вопрос в том, что является правильным способом в J, чтобы отрубить незначительные цифры?

+1

Изменить это '(** |) & +'.. Рассказ: '+' комплексно сопряжен; не то, что нужно; '|' является абсолютной величиной, вероятно, тем, что было предназначено. –

ответ

0

round в "цифровой" пакет является [ * [: <. 0.5 + %~. Вы можете использовать его следующим образом:

require 'numeric' 
    (0.01&round)&.+. _1.5j_4.6 4e_16j2 2j4e_16 
_1.5j_4.6 0j2 2 

код, указанный в вопросе, исправленное использовать | вместо + является (**|)&.+. и использует побочный работает над числами, чтобы закруглить их. Вы принимаете каждую часть комплексного номера (&.+.) и умножаете (*) на его значение (|) по его знаку (*). Вы могли бы добиться такого же эффекта, добавляя и вычитая константу из своего номера с чем-то вроде 10j10 -~ 10j10 + ].

[ * [: <. 0.5 + %~ не использует побочные продукты, а скорее округляет число до нужной точности. %~ делит y на x, так что если вы округляете 0.3579 до двух знаков после запятой, указанную x из 0,01, ваш первый шаг - 35.79. Затем добавьте 0,5 (0.5 +) и возьмите слово ([: <.), что совпадает с округлением до нулевых мест (35,79 + 0,5 = 36,29, пол которого составляет 36). Последний шаг - умножить на x ([ *), чтобы отменить то, что было сделано с помощью %~.

Хотя заманчиво создать комплексную версию round с [ * [: <. 0.5j0.5 + %~, используя <. на комплексное число производит complex floor, который, вероятно, не то, что вы после этого.Если вы ожидаете, что мнимые и реальные компоненты будут закруглены независимо, перейдите к применению round под номером +.. Я думаю, что следующий дает вам вкус того, как комплекс пол отличается берет слово каждой части комплексного числа:

<. 0.7 0j0.7 0.6j0.7 0.7j0.6 
0 0 0j1 1 

Это помогает объяснить следующее:

1 ([ * [: <. 0.5j0.5 + %~) 0.2 0j0.2 0.1j0.2 0.2j0.1 
1 0j1 0j1 1 

«Округление» 0.2 до 1 поймал меня на страже, но это потому, что 0.2 + 0.5i0.5 = 0.7i0.5 и <. 07j0.5 имеет комплексный этаж 1. То же самое касается 0j0.2 «округление» до 0j1.

Если вы просто хотите, ближайший номер, где обе части комплексного числа являются целыми числами, вы можете использовать ([: <. 0.5 + ])&.+.:

([: <. 0.5 + ])&.+. 0.2 0j0.2 0.1j0.2 0.2j0.1 
0 0 0 0 
    ([: <. 0.5 + ])&.+. 0.7 0j0.7 0.6j0.7 0.7j0.6 
1 0j1 1j1 1j1 
2

Монада + (в отличие от диады+) является «complex conjugate», который является виновником в производстве 4j2, в отличие от _4j_2.

Редактор отвечает за (**+)&.+. на RosettaCode, вероятно, намеревался использовать |, absolute value, вместо +, таким образом:

(**|)&.+. _4j_2 4e_16j2 
_4j_2 0j2 
+0

Как P.S., 'round' в числовом пакете' '[* [: <. 0,5 +% ~ '. Например. '1e_3 round 1.12345678' дает' 1.123' – Eelvex

+0

@Eelvex Да, проблема с 'round' заключается в том, что он не предназначен для работы со сложными числами, например. оба 'round _4j_2 4e_16j2' и' round &. +. round _4j_2 4e_16j2' идентичны '_4j_2 4e_16j2'. –

+1

@DanBron '1 round _4j_2 4e_16j2' приводит к' _4j_2 0j2' – Dane

0

Один я использую это (**@|), который не имеет этой проблемы.

В частности, в данном случае, это, кажется, что вы хотите:.

(**@|)&.+.