在Mathematica中,几乎所有命令都自动在列表上进行线程化(或映射).
在Maple中,如何确定哪个命令自动作用于列表或集合的条目?
例如:
y+p*x=2*sqrt(x*y);
r:=[solve(%,y)];
Run Code Online (Sandbox Code Playgroud)
这给出了两个条目的列表(解决方案)
#r := [-p*x+(2*(1+sqrt(1-p)))*x, -p*x+(2*(1-sqrt(1-p)))*x]
Run Code Online (Sandbox Code Playgroud)
现在我发现collect自动映射每个列表条目
collect(r,x);
# [(-p+2+2*sqrt(1-p))*x, (-p+2-2*sqrt(1-p))*x]
Run Code Online (Sandbox Code Playgroud)
但是另一个命令没有(我刚刚选了这个)
MmaTranslator[Mma][LeafCount](r);
#37
Run Code Online (Sandbox Code Playgroud)
对于上面的内容,需要显式迭代列表或集合的条目.
map(MmaTranslator[Mma][LeafCount],r)
#[17, 19]
Run Code Online (Sandbox Code Playgroud)
在Maple中是否有一种方法可以找到哪个命令自动对列表的条目或除试验和错误之外的集合进行线程化?
Maple 2018.1
我不知道文档中是否有任何地方确切说明哪些命令将自动映射到列表。
但此类命令的集合并不大。绝大多数命令不会自动映射到列表。大多数在列表上自动映射的内容与表达式的简化或相关操作有关。自动映射列表的命令集合至少包含以下内容:
collect, combine, expand,
evala, evalc, evalf,
factor, normal, radnormal, rationalize, simplify
Run Code Online (Sandbox Code Playgroud)
对这些命令的列表进行自动映射主要是为了提供比用命令显式包装更短的语法map。
还有一些保留结构的命令(除非通过选项明确告知,外部列表结构是要更改的内容),因此通常对列表完成与映射列表相同的事情:
convert, eval, evalindets, subs, subsindets
Run Code Online (Sandbox Code Playgroud)
现代 Maple 有另一种更短的语法,可以将命令映射到列表(或集合、向量等)。它称为“逐元素”操作,其语法包括~在命令后附加(波形符)。
例如,
discont~( [ csc(x), sec(x) ], x );
[{Pi _Z1~}, {Pi _Z2~ + 1/2 Pi}]
Run Code Online (Sandbox Code Playgroud)
就您的其他示例而言,请注意,LeafCount计算第一个参数的值(度量)被视为单个表达式。但项目列表仍然是单个表达式。~因此,(没有)它作为一个整体作用于列表,而不是自动映射它,这当然不应该令人惊讶。它将包含的列表视为附加的“叶子”。
MmaTranslator:-Mma:-LeafCount( L0 );
8
L0 := [ sin(x), 1/2*x*cos(x) ]:
MmaTranslator:-Mma:-LeafCount~( L0 );
[2, 5]
map( MmaTranslator:-Mma:-LeafCount, L0 );
[2, 5]
Run Code Online (Sandbox Code Playgroud)
collect对于与原始示例类似的示例,应用(自动映射)和使用 逐元素应用它没有区别collect~。在这里,前两个结果是相同的,因为附加参数x恰好是标量。例如,
r := [p*x+(2*(x^2+p^2))*x, p*x+(2*(x^2-p^2))*x]:
collect(r, x);
3 2 3 2
[2 x + (2 p + p) x, 2 x + (-2 p + p) x]
collect~(r, x);
3 2 3 2
[2 x + (2 p + p) x, 2 x + (-2 p + p) x]
map(collect, r, x);
3 2 3 2
[2 x + (2 p + p) x, 2 x + (-2 p + p) x]
Run Code Online (Sandbox Code Playgroud)
我应该提到,如果第二个参数是列表(例如)[x,p]而不是标量(例如),则上述示例的行为会有所不同x。
s := [a*b+(2*(a^2*b+b^2))*a, a*b+(2*(a^2*b-b^2))*a]:
collect(s, [a,b]);
3 2 3 2
[2 b a + (2 b + b) a, 2 b a + (-2 b + b) a]
map(collect, s, [a,b]);
3 2 3 2
[2 b a + (2 b + b) a, 2 b a + (-2 b + b) a]
collect~(s, [a,b]);
3 2 2 3
[2 b a + (2 b + b) a, -2 a b + (2 a + a) b]
zip(collect, s, [a,b]);
3 2 2 3
[2 b a + (2 b + b) a, -2 a b + (2 a + a) b]
Run Code Online (Sandbox Code Playgroud)
在上面,elementiwisecollect~示例的行为就像zip第二个参数也是列表时一样。也就是说,第一个参数中的第一项针对第二个参数中的第一项进行收集,第一个参数中的第二项针对第二个参数中的第二项进行收集。
元素运算符语法的另一个特征是它不会将命令映射到标量表达式的操作数(即不是列表、集合、向量等)。这与 形成鲜明对比map,后者可用于将运算映射到表达式的操作数上。
以下是两个示例,其中map将命令应用于标量表达式的操作数,而使用 elementwise~则将命令仅应用于标量表达式本身。在第一个示例中,操作数是项和的被加数。在第二个示例中,操作数是未计算的函数调用的参数。
T := x^2 * sin(x) + y^2 * cos(x):
F( T );
2 2
F(x sin(x) + y cos(x))
F~( T );
2 2
F(x sin(x) + y cos(x))
map( F, T );
2 2
F(x sin(x)) + F(y cos(x))
G( arctan(a, b) );
G(arctan(a, b))
G~( arctan(a, b) );
G(arctan(a, b))
map( G, arctan(a, b) );
arctan(G(a), G(b))
Run Code Online (Sandbox Code Playgroud)
因此,如果您不想无意中将命令映射到标量表达式的操作数(加数、被乘数等),那么您可以使用元素语法,而~不必首先测试第一个表达式是标量还是列表( ETC)。
同样,如果有一个附加参数,那么它是否是列表的标量就会有所不同。
F( T, a );
F(sin(x) + cos(x), a)
F~( T, a );
F(sin(x) + cos(x), a)
map( F, T, a );
F(sin(x), a) + F(cos(x), a)
F( T, [a,b] );
F(sin(x) + cos(x), [a, b])
map( F, T, [a,b] );
F(sin(x), [a, b]) + F(cos(x), [a, b])
F~( T, [a,b] );
[F(sin(x) + cos(x), a), F(sin(x) + cos(x), b)]
zip( F, T, [a,b] );
[F(sin(x) + cos(x), a), F(sin(x) + cos(x), b)]
Run Code Online (Sandbox Code Playgroud)