我看到了这段J代码
(**+)&.+.
在RosettaCode FFT部分。它应该清除FFT结果的无关紧要的数字。例如
(** +)及; +。 4e_16j2
给出
0j2
例如,它类似于Mathematica的Chop
函数。
然而
(**+)&.+. _4j_2
给出
4j2 (instead of _4j_2)
这显然是不正确的。
问题是J在切断无效数字方面的正确方法是什么?
答案 0 :(得分:2)
monad +
(而不是 dyad +
)是" complex conjugate",这是生产的罪魁祸首4j2
而不是_4j_2
。
RosettaCode负责(**+)&.+.
的编辑可能会使用|
,absolute value代替+
,因此:
(**|)&.+. _4j_2 4e_16j2
_4j_2 0j2
答案 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
除以x
,这样如果您将0.3579舍入到两位小数,由0.01 0.5 +
表示,那么您的第一步就是35.79。然后你添加0.5([: <.
)并发言(x
),这与舍入到零的位置相同(35.79 + 0.5 = 36.29,其中底板为36)。最后一步是乘以[ *
(%~
)来撤消对round
的处理。
虽然很有可能使用[ * [: <. 0.5j0.5 + %~
创建<.
的复杂版本,但在复数上使用round
会生成complex floor,这可能不是您的意思之后。如果您希望虚构和实数组件独立舍入,请在+.
下应用 <. 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
:
{{1}}
答案 2 :(得分:0)
我一直使用的是(**@|)
,它没有这个问题。
特别是在这种情况下,这似乎可以做你想要的:
(**@|)&.+.