Ошибка в RecurrenceTable с символьным вводом - PullRequest
6 голосов
/ 26 апреля 2011

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

zi = {0.1, 0.2, 0.3}
ai = {0.904837, 1.05171, -0.499584}

Quiet[ RecurrenceTable[ {A[0] == 0, A[1] == ai[[1]],
          A[n+1]==A[n] + (z - zi[[n]]) ai[[n+1]] A[n-1]},
          A, {n, Length@ai -1 } ],
   {Part::pspec}]

(Использование Quiet необходимо, поскольку Part жалуется на zi[[n]] и ai[[n+1]], когда n является чисто символическим.) Сам код является частью функции, от которой я хочу получить символический результат, следовательно, z является Symbol. Но когда я запускаю приведенный выше код, я получаю сообщение об ошибке:

RecurrenceTable::nlnum1: 
  The function value {0.904837,0.904837+0. z} is not a list of numbers with 
  dimensions {2} when the arguments are {0,0.,0.904837}.

Обратите внимание на термин {0.904837,0.904837+0. z}, где 0. z не сводится к нулю. Что мне нужно сделать, чтобы заставить его оценить до нуля, так как кажется, что это источник проблемы? Есть ли альтернативы?

Кроме того, в качестве общей жалобы на справочную систему для сотрудников Wolfram Research, которые преследуют stackoverflow: в v.7 RecurrenceTable::nlnum1 недоступен для поиска! Кроме того, ссылка >> в конце ошибки не приводит вас к определению ошибки, но вместо этого приводит к определению RecurrenceTable, где общие ошибки не имеют перекрестных ссылок.

Редактировать : После просмотра моего кода решение, которое я нашел, состояло в том, чтобы полностью символически оценить RecurrenceTable, включая начальные условия. Рабочий код выглядит следующим образом:

Clear[NPointPade, NPointPadeFcn]
NPointPade[pts : {{_, _} ..}] := NPointPade @@ Transpose[pts]

NPointPade[zi_List, fi_List] /; Length[zi] == Length[fi] :=
 Module[{ap, fcn, rec},
  ap = {fi[[1]]};
  fcn = Module[{gp = #, zp, res},
     zp =  zi[[-Length@gp ;;]];
     res = (gp[[1]] - #)/((#2 - zp[[1]]) #) &[Rest@gp, Rest@zp];
     AppendTo[ap, res[[1]]];
     res
  ] &;

  NestWhile[fcn, fi, (Length[#] > 1 &)];

 (*
  The recurrence relation is used twice, with different initial conditions, so
  pre-evaluate it to pass along to NPointPadeFcn
 *)
 rec[aif_, zif_, a_, b_][z_] := 
  Evaluate[RecurrenceTable[
     {A[n + 1] == A[n] + (z - zif[n])*aif[n + 1]*A[n - 1], 
      A[0] == a, A[1] == b}, 
     A, {n, {Length@ap - 1}}][[1]]];

  NPointPadeFcn[{zi, ap, rec }]
 ]

NPointPadeFcn[{zi_List, ai_List, rec_}][z_] /; Length[zi] == Length[ai] :=
 Module[{aif, zif},
  zif[n_Integer] /; 1 <= n <= Length[zi] := zi[[n]];
  aif[n_Integer] /; 1 <= n <= Length[zi] := ai[[n]];
  rec[aif, zif, 0, ai[[1]]][z]/rec[aif, zif, 1, 1][z]
 ]

Format[NPointPadeFcn[x_List]] := NPointPadeFcn[Shallow[x, 1]];

Как и встроенные функции интерполяции, NPointPade выполняет некоторую предварительную обработку и возвращает функцию, которая может быть оценена, NPointPadeFcn. Предварительная обработка, выполняемая NPointPade, генерирует список ai s из zi s и значений функций в этих точках в дополнение к предварительной оценке отношений повторения. Когда NPointPadeFcn снабжено значением z, оно оценивает два линейных рекуррентных отношения, предоставляя ему соответствующие значения.

Редактировать : для любопытных вот NPointPade в действии

NPointPade in action

На первом графике трудно определить разницу между двумя функциями, но на втором графике показаны абсолютные (синие) и относительные (красные) ошибки. Как написано, создание Pade за 20 очков занимает очень много времени, поэтому мне нужно поработать над его ускорением. Но пока это работает.

Ответы [ 2 ]

6 голосов
/ 26 апреля 2011

Вы можете скрыть извлечение деталей за функцией:

In[122]:= zi = {0.1, 0.2, 0.3};
ai = {0.904837, 1.05171, -0.499584};

In[124]:= zif[n_Integer] /; 1 <= n <= Length[zi] := zi[[n]]
aif[n_Integer] /; 1 <= n <= Length[ai] := ai[[n]]

In[127]:= RecurrenceTable[{A[0] == 0, A[1] == aif[1], 
  A[n + 1] == 
   A[n] + (z - zif[n]) aif[n + 1] A[n - 1]}, A, {n, (Length@ai) - 1}]

Out[127]= {0.904837, 0.904837, 
 0.904837 - 0.271451 aif[4] + 0.904837 z aif[4]}


EDIT

Вот обходной путь для проблемы:

In[4]:= zi = {0.1, 0.2, 0.3};
ai = {0.904837, 1.05171, -0.499584};

In[6]:= zif[n_Integer] /; 1 <= n <= Length[zi] := zi[[n]]
aif[n_Integer] /; 1 <= n <= Length[ai] := ai[[n]]

In[8]:= Block[{aif, zif}, 
 RecurrenceTable[{A[0] == 0, A[1] == aif[1], 
   A[n + 1] == A[n] + (z - zif[n]) aif[n + 1] A[n - 1]}, 
  A, {n, 0, (Length@ai) - 1}]]

Out[8]= {0, 0.904837, 0.904837}

Block служит для временного удаления определений aif и zif, пока выполняется RecurrenceTable. Затем, когда Block выходит, значения восстанавливаются, и вывод RecurrenceTable оценивается.

3 голосов
/ 26 апреля 2011

Мне кажется, что подход Саши можно имитировать, просто Block ing Part.

zi = {0.1, 0.2, 0.3};
ai = {0.904837, 1.05171, -0.499584};

Block[{Part},
 RecurrenceTable[{A[0] == 0, A[1] == ai[[1]], 
   A[n + 1] == A[n] + (z - zi[[n]]) ai[[n + 1]] A[n - 1]}, 
  A, {n, Length@ai - 1}]
]
<b>   {0, 0.904837, 0.904837} </b>

Обращаясь к критике Саши, вот два других подхода к этому:

With[{Part = $z}, 
  RecurrenceTable[{A[0] == 0, A[1] == ai[[1]], 
    A[n + 1] == A[n] + (z - zi[[n]]) ai[[n + 1]] A[n - 1]}, 
   A, {n, Length@ai - 1}]
] /. $z -> Part

-

With[{Part = Hold[Part]}, 
  RecurrenceTable[{A[0] == 0, A[1] == ai[[1]], 
    A[n + 1] == A[n] + (z - zi[[n]]) ai[[n + 1]] A[n - 1]}, 
   A, {n, Length@ai - 1}]
] // ReleaseHold
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...