我在MuPAD 5.7.0版(MATLAB R2011b)中发现了一个奇怪的行为,我想知道这是不是一个bug,如果不是这样,我做错了什么。理想情况下,我也想知道为什么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)
此外,我们需要多项式系数。 每个这样的系数取决于矢量α和幂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))
权力是正确的,但系数不是。这似乎与这个问题中首先提到的抽象抽象问题有关。
答案 0 :(得分:1)
表达式[[a,b,c],[d,e,f],[g,h,i]]
不是MuPAD中的数组。这是一个“list列表。”我猜这不是你想要的。列表通常用于初始化arrays和matrices以及其他对象(more here)。对于这些示例,数组或矩阵都可以使用,但请注意,这两种数据类型都有different advantages。
使用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);
返回
请注意,行/列索引的表示方式与您问题中的行/列索引的表示方式不同。同样,修改您的其他示例
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);
结果
<小时/> 如果你碰巧想要使用列表,你可以这样做
reset();
C := [[a,b,c],[d,e,f],[g,h,i]];
_plus(op(C[3]));
S := j -> _plus(op(C[j]));
S(3);
返回
答案 1 :(得分:0)
我发布此答案只是为了提供问题中实际问题的实例。 horchler provided the decisive solution建议使用矩阵而不是列表列表。
基本上,这是一个修改过的实际问题的转录本。
我想解决的实际问题如下:
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));
此外,我们需要多项式系数。 每个这样的系数取决于矢量α和幂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(%)