2017-01-22 44 views
11

Building na przykład mam znalezionego here, Próbuję utworzyć funkcję od przekątnej matrycy, który został utworzony przy użyciu sumpy.diagSymPy: tworzenie funkcji numpy od przekątnej matrycy, która pobiera tablicę numpy

myM = Matrix([ 
[x1, 4, 4], 
[4, x2, 4], 
[4, 4, x3]]) 

gdzie ten został stworzony przy użyciu tej procedury na przykład:

import sympy as sp 
import numpy as np 

x1 = sp.Symbol('x1') 
x2 = sp.Symbol('x2') 
x3 = sp.Symbol('x3') 
X = sp.Matrix([x1, x2, x3]) 

myM = 4 * sp.ones(3, 3) 
sp.diag(*X) + myM - sp.diag(*np.diag(myM)) 

teraz będę chciał utworzyć funkcję, za pomocą lambdify z ufuncify, że trwa numpy.array lub długość 3 (jak np.array([0.1,0.2,0.3])) jako sygnał wejściowy, i podaje na wyjście jako matrycy według myM

myM = Matrix([ 
[0.1, 4, 4], 
[4, 0.2, 4], 
[4, 4, 0.3]]) 

końcu trzeba utworzyć jakobian matrycy symbolicznie za pomocą tej metody: Jacobian i jako funkcjonalna forma może się zmieniać w trakcie obliczeń następnie bardzo użyteczne byłoby obliczenie symboliczne według Jakuba.

Odpowiedz

10

Stworzenie numerycznej macierzy 3 na 3 z wektora numerycznego nie jest tak naprawdę rzeczą SymPy, ponieważ nie ma w tym celu żadnych symboli. Rozważmy następującą, gdzie argument d jest tablicą zawierającą przekątne elementy.

def mat(d): 
    return np.diag(d-4) + 4 

Powyższa funkcja zwraca tablicę 2d NumPy. Aby powrócić do matrycy SymPy Zamiast używać

def mat(d): 
    return sp.Matrix(np.diag(d-4) + 4) 

jeśli D ma bardzo małe wartości, odejmowanie, a następnie dodatkowo może prowadzić do utraty dokładności, na przykład (1e-20 - 4) + 4 ma wartość zero. Bezpieczniejsze alternatywą jest

def mat(d): 
    diagmat = np.diag(d) 
    return diagmat + np.fromfunction(lambda i, j: (i != j)*4, diagmat.shape) 
+0

Nie dokładnie to, co miałem na myśli, ale jestem Wykorzystam to, dzięki – Ohm

5

można .subs() Wartości pływak do odpowiednich symboli:

import sympy as sp 
import numpy as np 

x1 = sp.Symbol('x1') 
x2 = sp.Symbol('x2') 
x3 = sp.Symbol('x3') 
X = sp.Matrix([x1, x2, x3]) 

myM = 4 * sp.ones(3, 3) 
smyM=sp.diag(*X) + myM - sp.diag(*np.diag(myM)) 

fcoefs = [(a, f) for a, f in (zip([x1, x2, x3], np.array([0.1,0.2,0.3])))] 

fmyM = smyM.subs(fcoefs) 

smyM 
Out[105]: 
Matrix([ 
[x1, 4, 4], 
[ 4, x2, 4], 
[ 4, 4, x3]]) 

fmyM 
Out[106]: 
Matrix([ 
[0.1, 4, 4], 
[ 4, 0.2, 4], 
[ 4, 4, 0.3]]) 

wydaje się być w porządku sympy.matrices.dense.MutableDenseMatrix Matrix po:

fmyM @ myM 
Out[107]: 
Matrix([ 
[32.4, 32.4, 32.4], 
[32.8, 32.8, 32.8], 
[33.2, 33.2, 33.2]]) 

mogą wymagać konwersji do np.array do pełnego wykorzystania z numpy

poniżej jest niektóre z mojego kodu pokazującego mo Re wzoru użyłem:

def ysolv(coeffs): 
    x,y,a,b,c,d,e = symbols('x y a b c d e') 
    ellipse = a*y**2 + b*x*y + c*x + d*y + e - x**2 
    y_sols = solve(ellipse, y) 
    print(*y_sols, sep='\n') 

    num_coefs = [(a, f) for a, f in (zip([a,b,c,d,e], coeffs))] 
    y_solsf0 = y_sols[0].subs(num_coefs) 
    y_solsf1 = y_sols[1].subs(num_coefs) 

    f0 = lambdify([x], y_solsf0) 
    f1 = lambdify([x], y_solsf1) 
    return f0, f1 

f0, f1 = ysolv(t[0]) 

y0 = [f0(x) for x in xs] 
y1 = [f1(x) for x in xs] 
...  

od: https://stackoverflow.com/a/41232062/6876009 (tak, mój „feeloutXrange” nie jest hack tak źle, to musiał być pokazany)