INDEX u.Kronecker-Produkt (3/4-Tensor - 4.Forts.)
15.04.2018 01:12:04
Luc:-?
dass sich snb erneut an der dort verlinkten Diskussion auf OL beteiligt hat, indem er ein „Dessert“ nachgeliefert hat. Ich werde nun im dortigen Thread darauf eingehen und ein „Sahnehäubchen“ nachliefern (Link folgt hier später). Hier geht's mir aber in 1.Linie um Erweiterungen und Korrekturen.
1. Wenn man 2 ungleichgroße Matrizen nach Art des Kronecker-Produkts miteinander multipliziert, merkt man schnell, dass die plurale MatrixFml unter Pkt 1.2, …
AB7[:AC8]: {=INDEX(INDEX($W$2:$X$3;ZEILE(A1:B2);SPALTE(A1:B2))*INDEX(Z2:AA3;;;1^Z2:AA3);0;0)}
…so nicht stimmen kann. Das Konstrukt 1^Z2:AA3 als 4.INDEX-Argument muss sich natürlich auf die 1.Matrix beziehen, nicht die 2., um die 2.Matrix oft genug bereit zu stellen und ggf alle Ergebnisse (1.Werte der Sekundärmatrizen = komplette 1.Subebene) abzurufen! Die Fml müsste also so lauten:
AB7:AC8: {=INDEX(W2:X3;ZEILE(A1:B2);SPALTE(A1:B2))*INDEX(Z2:AA3;;;1^W2:X3)} bzw …
AB7:AC8: {=INDEX(INDEX(W2:X3;ZEILE(A1:B2);SPALTE(A1:B2))*INDEX(Z2:AA3;;;1^W2:X3);;;1^W2:X3)}
Das würde dann analog auch für den Pkt 2.0 gelten, statt …
W12:X13: {=VJoin(INDEX(INDEX(W2:X3;ZEILE(A1:A2);SPALTE(A1:B1))*INDEX(Z2:AA3;;;1^Z2:AA3);;;1^Z2:AA3);",;";2)}
…wäre Folgendes zu verwenden:
W12:X13: {=VJoin(INDEX(INDEX(W2:X3;ZEILE(A1:B2);SPALTE(A1:B2))*INDEX(Z2:AA3;;;1^W2:X3);;;1^W2:X3);",;";2)}
2. Die zuletzt genannte Fml erzeugt ja MatrixKonstanten in TextForm*. Diese Ergebnisse können aber nur aus ihren Zellen als Quelle genutzt wdn. Speichert man sie als Werte mit vorangestelltem = und berechnet man dann die EinzelFmln, entsteht genau wieder das xlErgebnis lt 1.Subebene des 4Tensors. Man kann ihre Zellen aber als Argument der UDF TensEx verwenden (s. im verlinkten Archiv-Thread!). In Vs1.0 wdn dann die Werte dieser MxKonstantenTexte auf die übliche (2dimensionale) Ergebnismatrix (2Tensor) expandiert (Sekundärmatrizen-Darstellung). Mit der Vs1.1 (herstellbar aus 1.0 per im Archiv-Thread angegebener Ergänzung) kann man dann auch die Subebenen aus diesen Hilfszellen extendieren. Wenn man die beiden FaktorMatrizen ggeinander austauscht, wdn übrigens auch Sekundärmatrizen- und Subebenen-Darstellung ggeinander ausgetauscht.
__________
* Wer nicht über die dafür erforderliche Vs1.5 der UDF VJoin verfügt, kann auch die Vs1.4 benutzen und muss die Ergebnisse entsprd ergänzen, wenn er die UDF TensEx zwecks Weiterverarbeitung benutzen will.
3. Inzwischen habe ich aber auch eine weitere UDF fertiggestellt, die direkt das TensorProdukt ermittelt, es aber als Matrix, deren Elemente ebenfalls Matrizen sind, anlegt. So etwas kann normalerweise nicht auf einen ZellBereich abgebildet wdn, weshalb Xl hier zwar sicher analog rechnet (Beweis: die VJoin-Fmln!), die xlSteuerung aber trotzdem die 1.Subebene abbildbar isoliert. Das habe ich auch in dieser UDF simuliert (bei fehlendem 3.Argument). Ansonsten können alle TensorWerte nur als MxKonstantenText, wahlweise in US-Original- bzw lokaler Notation ausgegeben wdn (spart VJoin ein). Eine solche Fml kann man dann auch der UDF TensEx als Argument übergeben, die dann Expansion bzw Extension besorgt.
Rem Ermittelt Kronecker-Tensor-Produkt von 2 Matrizen als 2/2d-Array,
' was einem 4-Tensor gleichkommt; Arg1-2: jedes Element v.Arg1 wird
' mit allen Elementen von Arg2 multipliziert u.die Ergebnismatrizen
' in einer Matrix gleicher Größe wie Arg1 elementweise gespeichert;
' Arg3: fehlt/0 Ausgabe der 1.Subebene (xlSimulation) um F-Werte zu
' vmeiden, ±1/2 Rückgabe aller Werte als Texte in Matrixkonstanten-
' form (Sekundärmatrizen), ±2 erzeugt US-Notation, die v.UDF TensEx
' benötigt wird (m. dieser können die Texte zu 2d-Matrizen üblicher
' Form expandiert bzw auf d.Subebenen d. 4d-Modells extendiert wdn.
' Vs1.0 - LSr:CyWorXxl -cd:20180414 -1pub:20180415h -lupd:20180414t
Function TensorProd(ByVal Matrix1, ByVal Matrix2, Optional ByVal alsMxKText As VbTriState)
Const txMxForm$ = "{#}"
Dim cx1 As Long, cx2 As Long, ix As Long, rx1 As Long, rx2 As Long, _
MxCSep, MxRSep, zlErg() As String, el, erg, it, zwErg As Variant
On Error GoTo fx
With Application
MxCSep = Array(",", .International(xlColumnSeparator))
MxRSep = Array(";", .International(xlRowSeparator))
End With
alsMxKText = -Abs(alsMxKText): erg = Matrix1: zwErg = Matrix2
Matrix1 = erg: Matrix2 = zwErg
ReDim erg(UBound(erg, 1) - LBound(erg, 1), UBound(erg, 2) - LBound(erg, 2))
ReDim zwErg(UBound(zwErg, 1) - LBound(zwErg, 1), _
UBound(zwErg, 2) - LBound(zwErg, 2))
For Each el In Matrix1
For Each it In Matrix2
zwErg(rx2, cx2) = el * it
rx2 = (rx2 + 1) Mod (UBound(zwErg, 1) + 1)
cx2 = (cx2 - CInt(rx2 = 0)) Mod (UBound(zwErg, 2) + 1)
Next it
If CBool(alsMxKText) Then
ReDim zlErg(LBound(zwErg, 1) To UBound(zwErg, 1))
For ix = LBound(zwErg, 1) To UBound(zwErg, 1)
zlErg(ix) = Join(WorksheetFunction.Index(zwErg, ix + 1, 0), _
MxCSep(alsMxKText + 2))
Next ix
erg(rx1, cx1) = Replace(txMxForm, "#", Join(zlErg, _
MxRSep(alsMxKText + 2)))
Else: erg(rx1, cx1) = zwErg
End If
rx1 = (rx1 + 1) Mod (UBound(erg, 1) + 1)
cx1 = (cx1 - CInt(rx1 = 0)) Mod (UBound(erg, 2) + 1)
Next el
If alsMxKText = vbFalse Then
With Application.Caller 'Simulation der Xl-Ausgabe m.INDEX
ReDim zwErg(.Rows.Count - 1, .Columns.Count - 1)
For rx1 = 0 To .Rows.Count - 1
For cx1 = 0 To .Columns.Count - 1
zwErg(rx1, cx1) = erg(rx1, cx1)(0, 0)
Next cx1
Next rx1
End With
TensorProd = zwErg
Else: TensorProd = erg
End If
fx: If CBool(Err.Number) Then TensorProd = CVErr(Err.Number)
End Function
Morrn, Luc :-?„Die Intelligenzmenge ist auf diesem Planeten eine Konstante, die Bevölkerung nimmt aber zu!“ Auch deshalb informieren mit …