Как сказать Mathematica заменить 0 на степень 0 на 1? - PullRequest
9 голосов
/ 06 декабря 2011

Эксперты;

Дано

f = (#1^#2) &

Есть ли способ определить «f» выше так, что если # 1 и # 2 оба равны нулю, то значение чистой функции 'f' должно быть 1?

так что когда я пишу

f[0,0]

он вернет 1, а не неопределенный?

кстати, я знаю, что могу написать

f = (If[#1 == 0 && #2 == 0, 1, #1^#2]) &

Но я хотел общее правило или шаблон, поэтому мне не нужно писать эти проверки, так как чистая функция может быть более сложной (много # в ней), и я не хочу делать многие из этих «если тогда еще» 'проверяет каждый возможный 0 ^ 0, который может появиться.

спасибо

Обновление:

Может быть, я должен уточнить, почему я делаю это.
У меня есть пользователь выбирает функцию из меню. Функция

a x^n0 + b y^n1 + c x^n2 y^n3

Где выше, параметры 'n0', 'n1', 'n2' и 'n3' также могут быть выбраны из ползунков, и они могут быть нулевыми.

Теперь 'x' и 'y' - это координаты, и они также могут быть равны нулю.

Следовательно, возможно, что 0 ^ 0 может встретиться при оценке вышеупомянутой функции.

Есть много случаев, чтобы проверить, когда делаю это сам. Например, 'y ^ n3' может быть 0 ^ 0, а не другим, y ^ n1 может быть 0 ^ 0, а не другим, x ^ n2 y ^ n3 может быть и 0 ^ 0, и не другими, и т. Д. и поэтому я должен определить много разных случаев. (16 возможных случаев, я думаю).

И я пытаюсь избежать этого. Если я скажу Mathematica заменить 0 ^ 0 на 1 на более низком уровне, тогда жизнь будет проще.

Обновление 12/7/11 Спасибо всем за ответы и комментарии, все они очень полезны и решают мою проблему, и я учился у них.

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

Вот небольшой пример

Manipulate[Row[{format[x, n], "=", eval[x, n]}],
 {{x, 0.0, "x="}, 0, 1, .1, Appearance -> "Labeled"},
 {{n, 0.0, "n="}, 0, 1, .1, Appearance -> "Labeled"},
 Initialization :>
  (
   format[x_, n_] := HoldForm["(" x ")"^n];
   eval = Unevaluated[#1^#2] /. HoldPattern[0.0^0.0] :> 0.0 &
   )
 ]

Я везде использую действительные числа в своем коде (это числовой решатель pde), поэтому я использовал 0.0 выше, а не 0 ^ 0, чтобы соответствовать тому, что я делаю.

enter image description here

Ответы [ 4 ]

16 голосов
/ 06 декабря 2011

Конечно, есть много способов сделать что-то в Mathematica , но идиома дизайна, которую я часто использую, состоит в том, чтобы написать «функцию» (на самом деле, шаблон) с уменьшающейся специфичностью. Mathematica обладает свойством, что он будет применять более конкретные шаблоны, прежде чем менее конкретные.

Итак, для вашего случая я бы просто написал:

Clear[f];
f[0, 0] = 1;
f[a_, b_] := a^b;

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

10 голосов
/ 06 декабря 2011

Я согласен с ответом @Deep Yellow, но если вы настаиваете на чистой функции, вот один из способов:

f = Unevaluated[#1^#2] /. HoldPattern[0^0] :> 1 &

EDIT

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

z2zProtect[Function[body_]] := 
   Function[Unevaluated[body] /. HoldPattern[0^0] :> 1]

Тогда мой предыдущий код можно переписать так:

 f = z2zProtect[#1^#2 &]

Но вы можете это более широко, например:

ff = z2zProtect[#1^#2 + 2 #2^#3 + 3 #3^#4 &]

In[26]:= ff[0,0,0,0]
Out[26]= 6
4 голосов
/ 06 декабря 2011

Вы можете попробовать написать это как f = Quiet[Check[#1^#2,1]] &.

Quiet подавит сообщение "Power::indet: "Indeterminate expression 0^0 encountered.", а Check заменит результат на 1, если он неопределенный.

Вероятно, лучше использовать некоторую функцию, например s = Quiet[Check[#1, 1]], и обернуть в нее свои выражения.

3 голосов
/ 14 октября 2013

Я немного удивлен, что тривиальное (хотя и немного опасное) исправление не упоминалось ранее.Если вы действительно не ожидаете, что выражение 0^0 встретится в каком-либо контексте, в котором вы (а) будете обеспокоены тем, что оно произошло, или (б) хотели бы, чтобы оно сравнивалось с чем-то отличным от 1, вы можете простоtry

Unprotect[Power];
Power[0, 0] = 1;
Protect[Power];
0^0

Это исправление потребовалось мне в ситуации, когда сложная функция имела несколько вызовов выражений вида x^n, где x - действительное, а n - целое число, в которомcase 0^0 следует рассматривать как предел x^0=1, так как x переходит на 0.

Важно отметить, однако, что при этом "загрязнение" Power для текущего сеанса ядраи, следовательно, может сломать другие ноутбуки, которые работают одновременно и для которых условия (a) и (b) могут не выполняться.Поскольку Power находится в контексте System՝ вместо Global՝, может быть трудно разделить контексты разных ноутбуков, чтобы избежать столкновений, вызванных этим исправлением.

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