Генерация членов степенного ряда m-порядка по n переменным - PullRequest
5 голосов
/ 20 декабря 2011

Рассмотрим ситуацию, когда у вас есть данные в списке вида

data = {{x1, x2, x3, ..., xn, y}, {...}, ..., {...}}

Например,

data = {{0, 2, 3, 2}, {0, 0, 1, 4}, {7, 6, 8, 3}}

Я бы хотел поместить данные в многомерный полином порядка, скажем, 2. Итак, значения 3-х переменных функции:

{2, 4, 3}

в соответствующих точках

{{0, 2, 3}, {0, 0, 1}, {7, 6, 8}}

Я бы сказал что-то вроде

Fit[data, {1, x, y, z, x^2, y^2, z^2, x y , x z, y z}, {x, y, z}]

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

Для 4-х переменных даты сделать второй порядок, это будет что-то вроде:

{1, x1, x2, x3, x4, x1^2, x2^2, x3^2, x4^2, x1 x2, x1 x3, x1 x4, x2 x3, x2 x4, x3 x4}

Можно ли как-нибудь сгенерировать такой список для n переменных до m -го порядка? Подобные термины (без коэффициентов) в разложении степенных рядов m порядка n -вариантной функции.

Ответы [ 4 ]

8 голосов
/ 20 декабря 2011

Делает ли это то, что вы хотите?

Union[Times @@@ Tuples[{1, x, y, z}, 2]]
6 голосов
/ 20 декабря 2011

Хотя решение @ruebenko совершенно правильно, я хотел бы отметить, что оно будет довольно медленным для больших степеней / большего числа переменных из-за сложности Tuples и большого количества дубликатов для более высоких степеней. Вот алгебраический метод с гораздо лучшей производительностью для этих случаев (как во время выполнения, так и с точки зрения памяти):

List @@ Expand[(1 + x + y + z + t)^2] /. a_Integer*b_ :> b

Вот сравнение для большого количества переменных:

In[257]:= (res1=Union[Times@@@Tuples[{1,x,y,z,t},9]])//Short//Timing
Out[257]= {19.345,{1,t,t^2,t^3,t^4,t^5,t^6,t^7,t^8,t^9,x,<<694>>,x^2 z^7,y z^7,
      t y z^7,x y z^7,y^2 z^7,z^8,t z^8,x z^8,y z^8,z^9}}

In[259]:= (res2=List@@Expand[(1+x+y+z+t)^9]/. a_Integer*b_:>b)//Short//Timing
Out[259]= {0.016,{1,t,t^2,t^3,t^4,t^5,t^6,t^7,t^8,t^9,x,<<694>>,x^2 z^7,y z^7,
      t y z^7,x y z^7,y^2 z^7,z^8,t z^8,x z^8,y z^8,z^9}}

In[260]:= res1===res2
Out[260]= True

В этом случае мы наблюдаем ускорение в 1000 раз, но обычно оба метода имеют разные вычислительные сложности. Приведенный выше код является применением общего и приятного метода, называемого алгебраическим программированием. Интересное обсуждение этого вопроса в контексте Mathematica см. В статье Mathematica Journal * Анджей Козловский .

3 голосов
/ 20 декабря 2011

Используя аккуратное решение @ ruebenko,

varsList[y_, n_?IntegerQ, k_?IntegerQ] := 
Union[Times @@@ 
 Tuples[Prepend[Table[Subscript[y, i], {i, 1, n}], 1], k]]

Вы можете создать желаемый список через varsList[x, 4, 2].

2 голосов
/ 20 декабря 2011

Вот еще один метод, который, я считаю, стоит знать:

set = {1, x, y, z};

Union @@ Outer[Times, set, set]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...