Aggiornamento: aggiunto implementazione utilizzando scipy.sparse
Questo dà la soluzione nell'ordine N_max,...,N_0,M_max,...,M_1
.
Il sistema lineare di risolvere è della forma A dot x == const 1-vector
. x
è il ricercato soluzione di vettore.
Qui ho ordinato le equazioni in modo tale che x
è N_max,...,N_0,M_max,...,M_1
.
Poi costruire la matrice A
-coefficient da 4 matrici blocco.
Ecco un'istantanea per il caso di esempio n=50
che mostra come è possibile derivare la matrice dei coefficienti e comprendere la struttura dei blocchi. La matrice dei coefficienti A
è blu chiaro, il lato destro costante è arancione. Il ricercato vettore di soluzione x
è qui verde chiaro e utilizzato per etichettare le colonne. La prima colonna mostra da quale delle eq sopra indicate. la riga (= eq.) è stato ricavato:
Come suggerito da Jaime, moltiplicando per n
migliora il codice. Questo non si riflette nel foglio di calcolo di cui sopra, ma è stato implementato nel seguente codice:
Attuazione utilizzando 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)
Soluzione utilizzando 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))
Esempio per n=4
:
[[ 7.25 ]
[ 7.76315789]
[ 8.10526316]
[ 9.47368421] # <<< your result
[ 9.69736842]
[ 9.78947368]]
Esempio per 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 ]]
Queste non sembrano equazioni lineari, quindi non penso che sarete in grado di risolverle con un risolutore algebrico lineare. –
Puoi esprimere quelli usando '*'? Sto facendo fatica a risolvere la precarietà dell'operatore con i multipli impliciti – Eric
@ lip1: queste non sono equazioni lineari. L'ultimo termine di 'M (p)' contiene il prodotto di 'p' e' M (p-1) '. Ciò è contrario alla definizione di [equazione lineare] (http://mathworld.wolfram.com/LinearEquation.html), che richiede che ogni termine sia un termine costante o di primo ordine. – Dancrumb