在 Raku 中表示双求和序列
Expressing the double summation sequence in Raku
如何在Perl 6中表达双变量双求和序列?
有关双变量双求和序列的示例,请参阅此
它必须按原样表示,即没有在数学上将双求和简化为单求和。谢谢。
X
(交叉运算符)和 [+]
(归约元运算符 [ ]
与加法运算符 +
)使这出奇地简单:
表示1二重求和∑³x = 1 ∑⁵y = 1 2x + y ,您可以执行以下操作:
[+] do for 1..3 X 1..5 -> ($x, $y) { 2 * $x + $y }
# for 1..3 X 1..5 # loop cross values
# -> ($x, $y) # plug into x/y
# { 2 * $x + $y } # calculate each iteration
# do # collect loop return vals
# [+] # sum them all
如果你想为此创建一个sub
,你可以这样写2
sub ΣΣ (
Int $aₒ, Int $aₙ, # to / from for the outer
Int $bₒ, Int $bₙ, # to / from for the inner
&f where .arity = 2 # 'where' clause guarantees only two params
) {
[+] do for $aₒ..$aₙ X $bₒ..$bₙ -> ($a, $b) { &f(a,b) }
}
say ΣΣ 1,3, 1,5, { 2 * $^x + $^y }
甚至可以将事情简化为
sub ΣΣ (
Iterable \a, # outer values
Iterable \b, # inner values
&f where .arity = 2) { # ensure only two parameters
[+] do f(|$_) for a X b
}
# All of the following are equivalent
say ΣΣ 1..3, 1..5, -> $x, $y { 2 * $x + $y }; # Anonymous block
say ΣΣ 1..3, 1..5, { 2 * $^x + $^y }; # Alphabetic args
say ΣΣ 1..3, 1..5, 2 * * + * ; # Overkill, but Whatever ;-)
请注意,通过键入它,我们可以确保传递范围,但是通过将其键入 Iterable
而不是 Range
我们可以允许更有趣的求和序列,例如 ΣΣ (1..∞).grep(*.is-prime)[^99], 1..10, { … }
让我们使用前 100 个素数的序列。
事实上,如果我们真的想要,我们可以过火,允许任意深度求和运算符,将函数移到左侧最容易:
sub ΣΣ (
&function,
**@ranges where # slurp in the ranges
.all ~~ Iterable && # make sure they're Iterables
.elems == &function.arity # one per argument in the function
) {
[+] do function(|$_) for [X] @ranges;
};
就像 [+]
求和我们 f()
函数的所有值一样,[X]
迭代计算交叉,例如,[X] 0..1, 3..4, 5..6
首先做 0..1 X 3..4
或 (0,3),(0,4),(1,3),(1,4)
,然后 (0,3),(0,4),(1,3),(1,4) X 5..6
,或 (0,3,5),(0,4,5),(1,3,5),(1,4,5),(0,3,6),(0,4,6),(1,3,6),(1,4,6)
。
1. 对不起,所以不让我做 LaTeX,但你应该明白了。 2. 是的,我知道这是一个下标字母 O 不是零,下标数字通常不是有效的标识符,但您可以使用 Slang::Subscripts 来启用它们。
如何在Perl 6中表达双变量双求和序列?
有关双变量双求和序列的示例,请参阅此
它必须按原样表示,即没有在数学上将双求和简化为单求和。谢谢。
X
(交叉运算符)和 [+]
(归约元运算符 [ ]
与加法运算符 +
)使这出奇地简单:
表示1二重求和∑³x = 1 ∑⁵y = 1 2x + y ,您可以执行以下操作:
[+] do for 1..3 X 1..5 -> ($x, $y) { 2 * $x + $y }
# for 1..3 X 1..5 # loop cross values
# -> ($x, $y) # plug into x/y
# { 2 * $x + $y } # calculate each iteration
# do # collect loop return vals
# [+] # sum them all
如果你想为此创建一个sub
,你可以这样写2
sub ΣΣ (
Int $aₒ, Int $aₙ, # to / from for the outer
Int $bₒ, Int $bₙ, # to / from for the inner
&f where .arity = 2 # 'where' clause guarantees only two params
) {
[+] do for $aₒ..$aₙ X $bₒ..$bₙ -> ($a, $b) { &f(a,b) }
}
say ΣΣ 1,3, 1,5, { 2 * $^x + $^y }
甚至可以将事情简化为
sub ΣΣ (
Iterable \a, # outer values
Iterable \b, # inner values
&f where .arity = 2) { # ensure only two parameters
[+] do f(|$_) for a X b
}
# All of the following are equivalent
say ΣΣ 1..3, 1..5, -> $x, $y { 2 * $x + $y }; # Anonymous block
say ΣΣ 1..3, 1..5, { 2 * $^x + $^y }; # Alphabetic args
say ΣΣ 1..3, 1..5, 2 * * + * ; # Overkill, but Whatever ;-)
请注意,通过键入它,我们可以确保传递范围,但是通过将其键入 Iterable
而不是 Range
我们可以允许更有趣的求和序列,例如 ΣΣ (1..∞).grep(*.is-prime)[^99], 1..10, { … }
让我们使用前 100 个素数的序列。
事实上,如果我们真的想要,我们可以过火,允许任意深度求和运算符,将函数移到左侧最容易:
sub ΣΣ (
&function,
**@ranges where # slurp in the ranges
.all ~~ Iterable && # make sure they're Iterables
.elems == &function.arity # one per argument in the function
) {
[+] do function(|$_) for [X] @ranges;
};
就像 [+]
求和我们 f()
函数的所有值一样,[X]
迭代计算交叉,例如,[X] 0..1, 3..4, 5..6
首先做 0..1 X 3..4
或 (0,3),(0,4),(1,3),(1,4)
,然后 (0,3),(0,4),(1,3),(1,4) X 5..6
,或 (0,3,5),(0,4,5),(1,3,5),(1,4,5),(0,3,6),(0,4,6),(1,3,6),(1,4,6)
。
1. 对不起,所以不让我做 LaTeX,但你应该明白了。 2. 是的,我知道这是一个下标字母 O 不是零,下标数字通常不是有效的标识符,但您可以使用 Slang::Subscripts 来启用它们。