Moltiplicazione e esponenziazione della catena di matrici


13

Se ho due matrici e B , rispettivamente di dimensioni 1000 × 2 e 2 × 1000 , e voglio calcolare ( A B ) 5000 , è più efficiente riscrivere prima l'espressione come A ( B A ) 4999 B e solo allora valutare numericamente, perché A B è di dimensione 1000 × 1000 ma B A è di dimensione 2 × 2 .AB1000×22×1000(AB)5000A(BA)4999BAB1000×1000BA2×2

Voglio risolvere una versione generalizzata di questo problema. Esiste un algoritmo ragionevolmente efficiente (non forza bruta) per ottimizzare un'espressione contenente:

  • Variabili di matrice libere di dimensioni note
  • Prodotti di sottoespressioni arbitrarie
  • Sottoespressioni arbitrarie elevate al potere naturale

... in modo che ci voglia la minima quantità di lavoro per valutare numericamente, dopo aver sostituito le variabili di matrice libera con valori di matrice concreti?

Il problema di moltiplicazione della catena di matrici è un caso speciale del mio problema.


Modificare:

Questa è una risposta provvisoria. Mi sembra intuitivamente giusto, ma non ho prove che sia corretto. Se risulta corretto, sono ancora interessato alla prova. (Se non è corretto, ovviamente, per favore correggimi.)

Per ogni prodotto elevato a una potenza, diciamo, , considera ogni permutazione ciclica dei fattori:(A1A2Ak)n

  • (A1A2Ak)n
  • A1(A2AkA1)n1A2Ak
  • A1A2(A3AkA1A2)n1A3Ak
  • ...
  • A1A2Ak1(AkA1A2Ak1)n1Ak

... ricorsivamente. Ciascuna potenza deve essere calcolata usando l'espiazione mediante quadratura (ovviamente) e tutti gli altri prodotti devono essere calcolati usando l'ordine ottimale restituito dall'algoritmo di moltiplicazione della catena di matrici.


Modificare:

L'idea delineata nella mia modifica precedente è ancora in qualche modo non ottimale. L'algoritmo di esponenziazione mediante quadratura in realtà valuta le espressioni della forma o A n K , dove K non è necessariamente la matrice dell'identità. Ma il mio algoritmo non considera la possibilità di usare l'esponenziazione quadrando l'algoritmo con K non uguale alla matrice identità.KAnAnKKK


@ gnasher729: mi dispiace, avrei dovuto essere più esplicito. Non voglio forzare tutte le possibilità, per la stessa ragione per cui non vorresti risolvere la moltiplicazione della catena di matrici per forza bruta. Ho appena modificato la domanda di conseguenza.
pyon

A(BA)4999B
A(BA)2(21249+1)+1B

A(BA)n1BAB(AB)n2ABABA(BA)n3BAB

Cambiamo la base in vettore di Eigen per l'esponiazione della matrice e quando tutta la matrice ha potenza 1, allora possiamo usare la moltiplicazione della catena della matrice.
Deep Joshi,

n×nn

Risposte:


3

Disclaimer: il seguente metodo non è stato rigorosamente dimostrato di essere ottimale. Viene fornita una prova informale.

Il problema si riduce a trovare l'ordinamento più efficiente quando si considera il quadrato del prodotto.

(ABC)50(ABC)2ABCABCABC

ABCABC

A(B(CA))BCA(B(CA))49BC


(A1A2An)m(A1A2An)2
(A1A2An)2
GA1A2Gm1An


(AB)nABX×YY×XAB

X×Y
Y×X
Y×Y
X×X

X<YYX

X<Y
ABX×XAB(AB)n

YX
BAY×YABA(BA)n1B

ABAB

Utilizzando più matrici, l'argomento è simile. Forse è possibile una prova induttiva? L'idea generale è che la risoluzione dell'MCM per il quadrato troverà la dimensione ottimale per le operazioni con tutte le matrici coinvolte considerate.

Argomento di studio:

julia> a=rand(1000,2);
julia> b=rand(2,1000);
julia> c=rand(1000,100);
julia> d=rand(100,1000);
julia> e=rand(1000,1000);

julia> @time (a*b*c*d*e)^30;
  0.395549 seconds (26 allocations: 77.058 MB, 1.58% gc time)

# Here I use an MCM solver to find out the optimal ordering for the square problem
julia> Using MatrixChainMultiply
julia> matrixchainmultiply("SOLVE_SQUARED", a,b,c,d,e,a,b,c,d,e)
Operation: SOLVE_SQUARED(A...) = begin  # none, line 1:
    A[1] * (((((A[2] * A[3]) * (A[4] * (A[5] * A[6]))) * (A[7] * A[8])) * A[9]) * A[10])
  end
Cost: 6800800

# Use the ordering found, note that exponentiation is applied to the group of 5 elements
julia> @time a*(((((b*c)*(d*(e*a)))^29*(b*c))*d)*e);
  0.009990 seconds (21 allocations: 7.684 MB)

# I also tried using the MCM for solving the problem directly
julia> @time matrixchainmultiply([30 instances of a,b,c,d,e]);
  0.094490 seconds (4.02 k allocations: 9.073 MB)

1
(ABC)2

ABCABC(ABC)n(ABC)nA(BCA)n1BCAB(CAB)n1C

@DavidRicherby è la prova informale aggiunta di qualsiasi uso?
matteyas,

@matteyas: Questo è più o meno quello che ho detto nella prima modifica alla mia domanda, giusto?
pyon,

ABCABC

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.