1

我在 MuPAD 5.7.0 版(MATLAB R2011b)中发现了一个奇怪的行为,我想知道这是否是一个错误,如果不是,我做错了什么。理想情况下,我还想知道为什么 MuPAD 会这样做。

考虑大小为 3x3 的数组C,其中的元素具有一些示例值。我想将此数组视为数组数组,因此使用级联索引。

当两个索引都是不同嵌套范围的局部变量时,即当第一个索引的范围比第二个索引的范围宽时,显然会出现问题。如果第一个索引是常数,则没有问题。

当我输入:

reset();
C := [[a,b,c],[d,e,f],[g,h,i]];
sum((C[3])[t], t = 1..3);
S := j -> sum((C[j])[t], t = 1..3);
S(3);

我得到以下结果:

来自代码的结果

我希望代码中的第 3 行和第 5 行(输出中的第 2 行和第 4 行)产生相同的结果g+h+i:相反,第 5 行产生a+e+i,这似乎是 的对角线C

当我对product而不是做同样的事情时sum,结果甚至更奇怪,但可能会揭示更多关于“错误”来源的信息,特别是 DOM_VAR(0,2)

reset();
C := [[a,b,c],[d,e,f],[g,h,i]];
product((C[3])[t], t = 1..3);
eval(product((C[3])[t], t = 1..3));
S := j -> product((C[j])[t], t = 1..3);
S(3);
eval(S(3));

我得到:

产品代码的结果

我可能在这里走错了路,但我怀疑创建了一个闭包,试图保存周围作用域的局部变量,这些变量在创建闭包时是不确定的。此外,替换似乎在某个时候停止,它被eval().

实际问题

我试图解决的实际问题如下:

reset();
aVec := Symbol::accentUnderBar(Symbol::alpha)

在此处输入图像描述

问题:计算形式的多项式

hold(sum(x(i), i=i_0..i_k)^n)

在此处输入图像描述

Wikipedia上,定义了以下形式:

sumf := freeze(sum):
hold(sum(x[i], i=1..m)^n)=sumf(binomial(n,aVec)*product(x[t]^aVec[t], t = 1..m), abs(aVec)=n);

在此处输入图像描述

为了实现这一点,我们需要定义向量 alpha 的集合,其和等于 m。这些对应于长度为 m 和可能的零元素的 n 的可能组合的集合:

C := (n,m) -> combinat::compositions(n, MinPart = 0, Length = m)

在此处输入图像描述

例如,总和

n := 3:
m := 3:
sumf(x[i], i=1..m)^n = sum(x[i], i=1..m)^n;

在此处输入图像描述

将要求这些权力组合,其中每一个都是一个向量 alpha:

A := C(n,m)

在此处输入图像描述

此外,我们需要多项式系数。每个这样的系数取决于向量 alpha 和幂 n:

multinomial := (n, aVec) -> fact(n) / product(fact(aVec[k]), k = 1..nops(aVec))

在此处输入图像描述

例如,第二个组合出现的次数是:

multinomial(n, A[2])

在此处输入图像描述

对所有组合求和产生:

sum(multinomial(n,A[i])*product(x[t]^A[i][t], t = 1..m), i = 1..nops(A))

在此处输入图像描述

幂是正确的,但系数不正确。这似乎与此问题中首先陈述的归结抽象问题有关。

4

2 回答 2

1

该表达式[[a,b,c],[d,e,f],[g,h,i]]不是 MuPAD 中的数组。它是一个“列表列表”。我猜这不是你想要的。列表通常用于初始化数组矩阵以及其他对象(更多在这里)。对于这些示例,数组或矩阵都可以,但请注意这两种数据类型具有不同的优势

使用array

reset();
C := array([[a,b,c],[d,e,f],[g,h,i]]);
sum(C[3, t],t=1..3);
S := j -> sum(C[j, t], t = 1..3);
S(3);

返回

          MuPAD 输出 1

请注意,相对于您的问题,行/列索引的表示方式不同。同样,修改您的其他示例

reset();
C := matrix([[a,b,c],[d,e,f],[g,h,i]]);
product(C[3, t], t = 1..3);
S := j -> product(C[j, t], t = 1..3);
S(3);

结果是

          MuPAD 输出 2


如果您确实想为此使用列表,则可以这样做

reset();
C := [[a,b,c],[d,e,f],[g,h,i]];
_plus(op(C[3]));
S := j -> _plus(op(C[j]));
S(3);

返回

          MuPAD 输出 3

这是从列表中提取每个元素_plus的函数形式。还有其他方法可以做到这一点,但这是最简单的方法之一。+op

于 2015-05-26T22:59:17.827 回答
0

我发布此答案只是为了提供问题中实际问题的工作示例。horchler通过建议使用矩阵而不是列表列表提供了决定性的解决方案。

基本上,这是对实际问题的修改抄本。

实用解决方案

我试图解决的实际问题如下:

reset();
aVec := Symbol::accentUnderBar(Symbol::alpha)

在此处输入图像描述

问题:计算形式的多项式

hold(sum(x(i), i=i_0..i_k)^n)

在此处输入图像描述

Wikipedia上,定义了以下形式:

sumf := freeze(sum):
hold(sum(x[i], i=1..m)^n)=sumf(binomial(n,aVec)*product(x[t]^aVec[t], t = 1..m), abs(aVec)=n);

在此处输入图像描述

为了实现这一点,我们需要定义向量 alpha 的集合,其和等于 m。这些对应于长度为 m 和可能的零元素的 n 的可能组合的集合:

C := (n,m) -> combinat::compositions(n, MinPart = 0, Length = m)

在此处输入图像描述

例如,总和

n := 3:
m := 3:
sumf(x[i], i=1..m)^n = sum(x[i], i=1..m)^n;

在此处输入图像描述

将要求这些权力组合,其中每一个都是一个向量 alpha:

A := matrix(nops(C(n,m)),m,C(n,m));

在此处输入图像描述

此外,我们需要多项式系数。每个这样的系数取决于向量 alpha 和幂 n:

multinomial := (n, aVec) -> fact(n) / product(fact(aVec[k]), k = 1..nops(aVec))

在此处输入图像描述

例如,第二个组合出现的次数是:

multinomial(n,A[2,1..m])

在此处输入图像描述

对所有组合求和产生:

sum(multinomial(n,A[i,1..m])*product(x[t]^A[i,t], t = 1..m), i = 1..nops(C(n,m)));

在此处输入图像描述

最后,证明结果转换回来:

simplify(%)

在此处输入图像描述

于 2015-05-27T11:47:20.883 回答