Aktualisiert: hinzugefügt Implementierung scipy.sparse mit
Dies gibt die Lösung in der Reihenfolge N_max,...,N_0,M_max,...,M_1
.
Das zu lösende lineare System hat die Form A dot x == const 1-vector
. x
ist der gefragte Lösungsvektor.
Hier habe ich die Gleichungen bestellt, so dass x
N_max,...,N_0,M_max,...,M_1
ist.
Dann baue ich die A
-Koeffizienten-Matrix aus 4 Blockmatrizen.
Hier ist ein Schnappschuss für den Beispielfall n=50
, der zeigt, wie Sie die Koeffizientenmatrix ableiten und die Blockstruktur verstehen können. Die Koeffizientenmatrix A
ist hellblau, die konstante rechte Seite ist orange. Der gesuchte Lösungsvektor x
ist hier hellgrün und dient zur Beschriftung der Säulen. Die erste Spalte zeigt, von welchem der oben angegebenen Gleichungen. die Reihe (= Gl.) wurde abgeleitet:
Wie Jaime vorgeschlagen hat, multipliziert durch multiplizieren n
den Code. Dies ist nicht in der Tabelle spiegelt sich oben, jedoch im folgenden Code implementiert:
Implementierung mit numpy:
import numpy as np
import numpy.linalg as linalg
def solve(n):
# upper left block
n_to_M = -2. * np.eye(n-1)
# lower left block
n_to_N = (n * np.eye(n-1)) - np.diag(np.arange(n-2, 0, -1), 1)
# upper right block
m_to_M = n_to_N.copy()
m_to_M[1:, 0] = -np.arange(1, n-1)
# lower right block
m_to_N = np.zeros((n-1, n-1))
m_to_N[:,0] = -np.arange(1,n)
# build A, combine all blocks
coeff_mat = np.hstack(
(np.vstack((n_to_M, n_to_N)),
np.vstack((m_to_M, m_to_N))))
# const vector, right side of eq.
const = n * np.ones((2 * (n-1),1))
return linalg.solve(coeff_mat, const)
Lösung mit scipy.sparse:
from scipy.sparse import spdiags, lil_matrix, vstack, hstack
from scipy.sparse.linalg import spsolve
import numpy as np
def solve(n):
nrange = np.arange(n)
diag = np.ones(n-1)
# upper left block
n_to_M = spdiags(-2. * diag, 0, n-1, n-1)
# lower left block
n_to_N = spdiags([n * diag, -nrange[-1:0:-1]], [0, 1], n-1, n-1)
# upper right block
m_to_M = lil_matrix(n_to_N)
m_to_M[1:, 0] = -nrange[1:-1].reshape((n-2, 1))
# lower right block
m_to_N = lil_matrix((n-1, n-1))
m_to_N[:, 0] = -nrange[1:].reshape((n-1, 1))
# build A, combine all blocks
coeff_mat = hstack(
(vstack((n_to_M, n_to_N)),
vstack((m_to_M, m_to_N))))
# const vector, right side of eq.
const = n * np.ones((2 * (n-1),1))
return spsolve(coeff_mat.tocsr(), const).reshape((-1,1))
Beispiel für n=4
:
[[ 7.25 ]
[ 7.76315789]
[ 8.10526316]
[ 9.47368421] # <<< your result
[ 9.69736842]
[ 9.78947368]]
Beispiel für n=10
:
[[ 24.778976 ]
[ 25.85117842]
[ 26.65015984]
[ 27.26010007]
[ 27.73593401]
[ 28.11441922]
[ 28.42073207]
[ 28.67249606]
[ 28.88229939]
[ 30.98033266] # <<< your result
[ 31.28067182]
[ 31.44628982]
[ 31.53365219]
[ 31.57506477]
[ 31.58936225]
[ 31.58770694]
[ 31.57680467]
[ 31.560726 ]]
Diese sehen nicht wie lineare Gleichungen aus, also glaube ich nicht, dass Sie sie mit einem linearen Algebra-Löser lösen können. –
Kannst du die mit '*' ausdrücken? Es fällt mir schwer, die Operatorpräzedenz mit den impliziten Multiplikationen – Eric
@ lip1 zu lösen: Dies sind keine linearen Gleichungen. Der letzte Term des 'M (p)' enthält das Produkt von 'p' und' M (p-1) '. Dies steht im Gegensatz zu der Definition einer [linearen Gleichung] (http://mathworld.wolfram.com/LinearEquation.html), die erfordert, dass jeder Ausdruck ein konstanter oder ein Ausdruck erster Ordnung ist. – Dancrumb