2016-03-14 4 views
2

SymPy документации имеет этот пример для создания матрицы, используя правило:Создание SymPy матрицы с помощью функции

>>> def f(i,j): 
     if i == j: 
      return 1 
     else: 
      return 0 
>>> Matrix(4, 4, f) 
[1 0 0 0] 
[   ] 
[0 1 0 0] 
[   ] 
[0 0 1 0] 
[   ] 
[0 0 0 1] 

Как бы я идти об использовании правила с аргументами? Например, используя функцию:

>>> def f(i,j,l=1): 
     if i == j: 
      return 1*l 
     else: 
      return 0 

Я не знаю, как назвать такую ​​функцию.

EDIT: Чтобы уточнить, я не ищу решение, которое решает этот конкретный пример. Я ищу более общее решение. Предположим, что функция, являющаяся правилом для создания матрицы, то есть f в примере, является сколь угодно сложной. То есть, он не может просто/легко реплицироваться с помощью лямбда-функции. Иными словами, аргументы (l в примере) должны быть включены в вызов функции (f). Можно ли сделать это?

EDIT 2: В основном я хочу, чтобы иметь возможность указать f в самостоятельной функции (я имею в виду не лямбда-функции), а затем вызвать его в качестве части Matrix конструкции с любыми дополнительными аргументами (дополнительно к первому 2 обязательных аргументы). Я попытался вызова пример функции с кодом, как:

>>> Matrix(4,4,f,l=7) 

в надежде, что он будет возвращать:

[7 0 0 0] 
[   ] 
[0 7 0 0] 
[   ] 
[0 0 7 0] 
[   ] 
[0 0 0 7] 

Но это не работает.

>>> Matrix(4,4,f,{l=7}) 

Не работает. Можно ли сделать это?

ответ

0

Вы можете использовать lambda выражение как это:

l = 5 
Matrix(4, 4, lambda i,j: l if i==j else 0) 

или непосредственно

Matrix(4, 4, lambda i,j: 5 if i==j else 0) 

, который затем даст вам:

Matrix([ 
[5, 0, 0, 0], 
[0, 5, 0, 0], 
[0, 0, 5, 0], 
[0, 0, 0, 5]]) 

Конечно, Вы можете также использовать более сложный такие выражения, как

Matrix(4, 4, lambda i,j: i*j if i==j else i-j) 

, который даст вам

Matrix([ 
[0, -1, -2, -3], 
[1, 1, -1, -2], 
[2, 1, 4, -1], 
[3, 2, 1, 9]]) 
+0

См. Мое редактирование. – Charlie

+0

@Charlie: Не могли бы вы также добавить более сложный пример 'f' i.e, пример того, что вы на самом деле пытаетесь выполнить? – Cleb

+0

Хорошо, см. Второе редактирование. – Charlie

1

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

def diagonal(l): 
    def f(i, j): 
     if i == j: 
      return l 
     else: 
      return 0 
    return Matrix(4, 4, f) 

(и, кстати, для этого конкретного примера, вы можете просто использовать diag(*[l]*4) или eye(4)*l).

Вы также можете сделать так, чтобы ваша функция вызывалась как Matrix(4, 4, f(l)).

def f(l): 
    def _inner(i, j): 
     if i == j: 
      return l 
     else: 
      return 0 
    return _inner 

Другими словами, f(l) генерирует функцию, которая дает значения матрицы для этой l.

Невозможно изменить конструктор Matrix, чтобы вы могли написать Matrix(4, 4, f, l). Но одно из них должно быть работоспособным (напишите функцию, которая генерирует матрицы, или напишите функцию, которая генерирует функции).

+0

Знаете ли вы способ сделать то, что я прошу, если '' f'' имеет ту же структуру, что и в вопросе (т. Е. С '' l'' в качестве аргумента)? Если можно, я бы согласился, потому что я думаю, что это был бы более «пифонический» ответ. – Charlie

+1

@Charlie Я действительно не понимаю, что вы ищете. Как вы представляете, как передается аргумент 'l'? Проблема в том, что у вас уже есть функция 'f', которая представляет собой три аргумента? Если это так, вы можете использовать 'functools.partial', чтобы преобразовать его в версию с двумя аргументами. – asmeurer

+0

Возможно, что то, что я хочу сделать, невозможно, хотя я не уверен. Кажется, что вы на правильном пути для лучшей альтернативы с '' functools.partial''. Для будущих читателей вы могли бы отредактировать свой ответ, чтобы продемонстрировать '' functools.partial''? – Charlie

Смежные вопросы