Вы можете создать пользовательский подкласс функций, который не оценивается по умолчанию:
class r(Function):
@classmethod
def eval(cls, i, j):
return
def doit(self, **kwargs):
i, j = self.args
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
eval
указывает, когда выполнять оценку.Поскольку он всегда возвращает None, он никогда не оценивает.Он также сообщает SymPy, что функция имеет два аргумента.Вы также можете получить явные значения в некоторых случаях, если хотите.Например, вы можете захотеть, чтобы он вычислял, являются ли i
и j
явными числами.
@classmethod
def eval(cls, i, j):
if i.is_Number and j.is_Number:
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
При этом вы можете использовать его по своему усмотрению и вызывать expr.doit()
, когда хотите, чтобы он вычислялся,Вы также можете специально определить оценку для определенных функций, чтобы избежать doit
.Например, производные:
def _eval_derivative(self, x):
return self.doit()._eval_derivative(x)
Это приведет к немедленной оценке r(i, j).diff(i)
без необходимости вызова doit
.
Другие функции имеют аналогичные методы, которые вы можете определить.Смотрите документацию SymPy.