MuPAD оценка локальных переменных, сумма строки массива

Я обнаружил странное поведение в MuPAD версии 5.7.0 (MATLAB R2011b), и я хотел бы знать, является ли это ошибкой, а если нет, то что я делаю неправильно. В идеале я также хотел бы знать, почему MuPAD делает то, что делает.

Рассмотрим массив C размером 3x3, элементы которого имеют несколько примерных значений. Я хотел бы рассматривать этот массив как массив массивов и поэтому использовать каскадную индексацию.

Проблема, по-видимому, возникает, когда оба индекса являются локальными переменными разных вложенных областей, а именно, когда область действия первого индекса шире, чем область второго индекса. Нет проблем, если первый индекс постоянный.

Когда я вхожу:

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)

введите описание изображения здесь

В Википедии определена следующая форма:

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);

введите описание изображения здесь

Чтобы реализовать это, нам нужно определить набор векторов альфа, сумма которых равна m. Они соответствуют множеству возможных композиций n длины m и возможных нулевых элементов:

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;

введите описание изображения здесь

потребует этих комбинаций полномочий, каждая из которых является одним вектором альфа:

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))

введите описание изображения здесь

Степени верны, а коэффициенты - нет. Кажется, это связано с упрощенной абстрактной проблемой, поставленной первой в этом вопросе.


person Ingo Schalk-Schupp    schedule 26.05.2015    source источник
comment
Вы вызываете C := [[a,b,c],[d,e,f],[g,h,i]]; массив. Вы действительно пытаетесь построить матрицу 3 на 3?   -  person horchler    schedule 27.05.2015
comment
На самом деле нет, ты прав. Думаю, я имею в виду список списков, который вы упомянули в своем ответе.   -  person Ingo Schalk-Schupp    schedule 27.05.2015


Ответы (2)


Выражение [[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 ouput 2


Если вы действительно хотите использовать для этого списки, вы можете сделать это следующим образом

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

который возвращается

Выход 3 MuPAD

_plus - это функциональная форма + и _ 8_ извлекает каждый элемент из списка. Есть и другие способы сделать это, но это один из самых простых.

person horchler    schedule 26.05.2015
comment
Спасибо за предупреждение. Я собираюсь попробовать это на работе. Теперь я уверен, что мне действительно нужен список списков, потому что это то, что я получаю от другой функции. Я подробно остановлюсь на этом на работе через несколько часов. В любом случае меня могут заставить использовать product(). - person Ingo Schalk-Schupp; 27.05.2015
comment
Я добавил к вопросу актуальную проблему. Сейчас я попробую составить матрицу из списка списков и последую вашему совету. - person Ingo Schalk-Schupp; 27.05.2015
comment
Виноват! Я использовал sumf вместо sum в моей реальной проблеме. - person Ingo Schalk-Schupp; 27.05.2015

Я отправляю этот ответ только для того, чтобы предоставить рабочий пример практической проблемы из вопроса. Хорхлер предоставил решающее решение, предложив использовать матрицу вместо списка списков.

По сути, это модифицированный транскрипт практической задачи.

Практическое решение

Практическая проблема, которую я пытаюсь решить, заключается в следующем:

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

введите описание изображения здесь

Задача: вычислить многочлены вида

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

введите описание изображения здесь

В Википедии определена следующая форма:

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);

введите описание изображения здесь

Чтобы реализовать это, нам нужно определить набор векторов альфа, сумма которых равна m. Они соответствуют множеству возможных композиций n длины m и возможных нулевых элементов:

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;

введите описание изображения здесь

потребует этих комбинаций полномочий, каждая из которых является одним вектором альфа:

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(%)

введите описание изображения здесь

person Ingo Schalk-Schupp    schedule 27.05.2015