Code : Tout sélectionner
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The GaussSolverMatrix Operator <<<<<
Procedure.b GaussSolverMatrix(*EquationSystem.Matrix, *Constant.Matrix, *Solution.Matrix)
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Notes :
;
; This Gauss Solver try to solve the system : A·X = B
;
; Do to so we have to create an augmented Matrix : [A|B] = X
; Then we try to eliminate the 1st variable in the 2nd, 3rd, 4th, ... lines
; Then we try to eliminate the 2nd variable in the 3rd, 4th, 5th, ... lines
; and so on until all line is processed.
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Initialize the Solution Matrix
ZeroMatrix(*Solution, GetMatrixRow(*EquationSystem), GetMatrixRow(*Constant))
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Merge EquationSystem and Constant to create the Augmented Matrix
AugmentMatrixRow(Augmented.Matrix, *EquationSystem.Matrix, *Constant.Matrix)
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Application of elementary line operations to obtain the equavalent echelon matrix
For Oper = 0 To GetMatrixLine(Augmented) - 2
S1.d = PeekMatrixElement(Augmented, Oper, Oper)
For LineID = Oper + 1 To GetMatrixLine(Augmented) - 1
S2.d = PeekMatrixElement(Augmented, LineID, Oper)
For RowID = 0 To GetMatrixRow(Augmented) - 1
PokeMatrixElement(Augmented, LineID, RowID, S1 * PeekMatrixElement(Augmented, LineID, RowID) - S2 * PeekMatrixElement(Augmented, Oper, RowID))
Next
Next
Next
; DebugAugmentedMatrixRow(Augmented, GetMatrixRow(*EquationSystem), 4)
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Now we scan the matrix to verify if the system has single or infinite solution
; or if the system is impossible to solve. To do this, we try to find an impossible
; equation like : 0·x1 + 0·x2 + 0·x3 + 0·x4 = 10
For LineID = 0 To GetMatrixLine(Augmented) - 1
For RowID = 0 To GetMatrixRow(*EquationSystem) - 1
Sum.d = Sum + Abs(PeekMatrixElement(Augmented, LineID, RowID))
Next
If Sum <> 0.0
NotEmptyLineCount + 1
EndIf
For RowID2 = GetMatrixRow(*EquationSystem) To GetMatrixRow(Augmented) - 1
If Sum = 0.0
If PeekMatrixElement(Augmented, LineID, RowID2) <> Sum
ResetMatrix(*Solution)
ResetMatrix(Augmented)
ProcedureReturn #GAUSS_SOLVER_IMPOSSIBLE_SOLUTION
EndIf
EndIf
Next
Sum = 0.0
Next
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Now we have two possibility, the Not empty line count match the variable count,
; the solution is unique. The other possibility, we have some Free variables in the
; system. So we have to find them before to solve the system.
If NotEmptyLineCount = GetMatrixRow(*EquationSystem)
; The Not empty line count equal the Variable count, the solution is unique
SoluceMax = GetMatrixLine(*Solution) - 1
For SolutionRowID = 0 To GetMatrixRow(*Solution) - 1
For SoluceLineID = SoluceMax To 0 Step -1
If SoluceLineID = SoluceMax
Sum.d = 0.0
Else
For RowID = SoluceLineID + 1 To SoluceMax
Sum = Sum + PeekMatrixElement(Augmented, SoluceLineID, RowID) * PeekMatrixElement(*Solution, RowID, SolutionRowID)
Next
EndIf
PokeMatrixElement(*Solution, SoluceLineID, SolutionRowID, (PeekMatrixElement(Augmented, SoluceLineID, GetMatrixRow(*EquationSystem) + SolutionRowID) - Sum) / PeekMatrixElement(Augmented, SoluceLineID, SoluceLineID))
Sum = 0.0
Next
Next
SolverSuccess.b = #GAUSS_SOLVER_SINGLE_SOLUTION
Else
SoluceMax = NotEmptyLineCount - 1
; Debug "Presence of " + Str(GetMatrixRow(*EquationSystem) - NotEmptyLineCount) + " free variables"
For SolutionRowID = 0 To GetMatrixRow(*Solution) - 1
For LineID = NotEmptyLineCount - 1 To 0 Step - 1
For RowID = 0 To GetMatrixRow(*EquationSystem) - 1 ; This loop is used to find the first linked variable
If PeekMatrixElement(Augmented, LineID, RowID) <> 0.0
Break
EndIf
Next
For RowID2 = RowID + 1 To GetMatrixRow(*EquationSystem) - 1
Sum.d = Sum + PeekMatrixElement(Augmented, LineID, RowID2) * PeekMatrixElement(*Solution, RowID2, SolutionRowID)
Next
PokeMatrixElement(*Solution, RowID, SolutionRowID, (PeekMatrixElement(Augmented, LineID, GetMatrixRow(*EquationSystem) + SolutionRowID) - Sum) / PeekMatrixElement(Augmented, LineID, RowID))
Next
Next
SolverSuccess = #GAUSS_SOLVER_INFINITE_SOLUTION
EndIf
ResetMatrix(Augmented)
ProcedureReturn SolverSuccess
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The GaussSolverMatrixEx Operator <<<<<
Procedure.s GaussSolverMatrixEx(*EquationSystem.Matrix, *Constant.Matrix, *Solution.Matrix, P_Decimal.b = 6)
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Notes :
;
; This Gauss Solver try to solve the system : A·X = B
;
; Do to so we have to create an augmented Matrix : [A|B] = X
; Then we try to eliminate the 1st variable in the 2nd, 3rd, 4th, ... lines
; Then we try to eliminate the 2nd variable in the 3rd, 4th, 5th, ... lines
; and so on until all line is processed.
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Initialize the Solution Matrix
ZeroMatrix(*Solution, GetMatrixRow(*EquationSystem), GetMatrixRow(*Constant))
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Merge EquationSystem and Constant to create the Augmented Matrix
AugmentMatrixRow(Augmented.Matrix, *EquationSystem.Matrix, *Constant.Matrix)
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Application of elementary line operations to obtain the equavalent echelon matrix
For Oper = 0 To GetMatrixLine(Augmented) - 2
S1.d = PeekMatrixElement(Augmented, Oper, Oper)
For LineID = Oper + 1 To GetMatrixLine(Augmented) - 1
S2.d = PeekMatrixElement(Augmented, LineID, Oper)
For RowID = 0 To GetMatrixRow(Augmented) - 1
PokeMatrixElement(Augmented, LineID, RowID, S1 * PeekMatrixElement(Augmented, LineID, RowID) - S2 * PeekMatrixElement(Augmented, Oper, RowID))
Next
Next
Next
; DebugAugmentedMatrixRow(Augmented, GetMatrixRow(*EquationSystem), 4)
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Now we scan the matrix to verify if the system has single or infinite solution
; or if the system is impossible to solve.
For LineID = 0 To GetMatrixLine(Augmented) - 1
For RowID = 0 To GetMatrixRow(*EquationSystem) - 1
Sum.d = Sum + Abs(PeekMatrixElement(Augmented, LineID, RowID))
Next
If Sum <> 0.0
NotEmptyLineCount + 1
EndIf
For RowID2 = GetMatrixRow(*EquationSystem) To GetMatrixRow(Augmented) - 1
If Sum = 0.0
If PeekMatrixElement(Augmented, LineID, RowID2) <> Sum
ResetMatrix(*Solution)
ResetMatrix(Augmented)
ProcedureReturn "IMPOSSIBLE"
EndIf
EndIf
Next
Sum = 0.0
Next
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Now we have two possibility, the Not empty line count match the variable count,
; the solution is unique. The other possibility, we have some Free variables in the
; system. So we have to find them before to solve the system.
If NotEmptyLineCount = GetMatrixRow(*EquationSystem)
; The Not empty line count equal the Variable count, the solution is unique
SoluceMax = GetMatrixLine(*Solution) - 1
For SolutionRowID = 0 To GetMatrixRow(*Solution) - 1
For SoluceLineID = SoluceMax To 0 Step -1
If SoluceLineID = SoluceMax
Sum.d = 0.0
Else
For RowID = SoluceLineID + 1 To SoluceMax
Sum = Sum + PeekMatrixElement(Augmented, SoluceLineID, RowID) * PeekMatrixElement(*Solution, RowID, SolutionRowID)
Next
EndIf
PokeMatrixElement(*Solution, SoluceLineID, SolutionRowID, (PeekMatrixElement(Augmented, SoluceLineID, GetMatrixRow(*EquationSystem) + SolutionRowID) - Sum) / PeekMatrixElement(Augmented, SoluceLineID, SoluceLineID))
Sum = 0.0
Next
Next
GeneralSolution.s = Matrix_To_String(*Solution, P_Decimal)
Else
VarFlag = NewUnicodeVector(GetMatrixRow(*EquationSystem))
SoluceMax = NotEmptyLineCount - 1
; Debug "Presence of " + Str(GetMatrixRow(*EquationSystem) - NotEmptyLineCount) + " free variables"
For LineID = 0 To NotEmptyLineCount - 1
For RowID = 0 To GetMatrixRow(*EquationSystem) - 1
If PeekMatrixElement(Augmented, LineID, RowID) <> 0.0
Break
EndIf
Next
For Index = RowID To GetMatrixRow(*EquationSystem) - 1
If Index = RowID
PokeUnicodeVectorElement(VarFlag, Index, #False)
Else
PokeUnicodeVectorElement(VarFlag, Index, #True)
EndIf
Next
Next
For SolutionRowID = 0 To GetMatrixRow(*Solution) - 1
For LineID = NotEmptyLineCount - 1 To 0 Step - 1
For RowID = 0 To GetMatrixRow(*EquationSystem) - 1
If PeekMatrixElement(Augmented, LineID, RowID) <> 0.0
Break
EndIf
Next
For RowID2 = RowID + 1 To GetMatrixRow(*EquationSystem) - 1
Sum.d = Sum + PeekMatrixElement(Augmented, LineID, RowID2) * PeekMatrixElement(*Solution, RowID2, SolutionRowID)
Next
PokeMatrixElement(*Solution, RowID, SolutionRowID, (PeekMatrixElement(Augmented, LineID, GetMatrixRow(*EquationSystem) + SolutionRowID) - Sum) / PeekMatrixElement(Augmented, LineID, RowID))
Next
Next
GeneralSolution = Private_GaussSolverSymbolicMatrix(Augmented, NotEmptyLineCount, VarFlag, P_Decimal)
DeleteUnicodeVector(VarFlag)
EndIf
ResetMatrix(Augmented)
ProcedureReturn GeneralSolution
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The GaussJordanInverse Operator <<<<<
Procedure.b GaussJordanInverseMatrix(*Inverse.Matrix, *MatrixA.Matrix)
If GetMatrixLine(*MatrixA) = GetMatrixRow(*MatrixA)
Result.b = #True
CopyMatrix(*MatrixA, CopyA.Matrix)
IdentityMatrix(*Inverse, GetMatrixLine(*MatrixA))
If PeekMatrixElement(CopyA, 0, 0) = 0.0
If PeekMatrixElement(CopyA, GetMatrixLine(*MatrixA) - 1, 0) <> 0.0
; Debug "On additonne la dernière ligne à la première"
For Row = 0 To GetMatrixRow(*MatrixA) - 1
PokeMatrixElement(CopyA, 0, Row, PeekMatrixElement(CopyA, 0, Row) + PeekMatrixElement(CopyA, GetMatrixLine(*MatrixA) - 1, Row))
PokeMatrixElement(*Inverse, 0, Row, PeekMatrixElement(*Inverse, 0, Row) + PeekMatrixElement(*Inverse, GetMatrixLine(*MatrixA) - 1, Row))
Next
Else
; Debug "La matrice est singulière 1"
ResetMatrix(CopyA)
ResetMatrix(*Inverse)
ProcedureReturn #False
EndIf
EndIf
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Manipulation afin d'avoir des zéros sous la diagonale.
For Oper = 0 To GetMatrixLine(*MatrixA) - 2
S1.d = PeekMatrixElement(CopyA, Oper, Oper)
For LineID = Oper + 1 To GetMatrixLine(*MatrixA) - 1
S2.d = PeekMatrixElement(CopyA, LineID, Oper)
For RowID = 0 To GetMatrixRow(*MatrixA) - 1
PokeMatrixElement(CopyA, LineID, RowID, S1 * PeekMatrixElement(CopyA, LineID, RowID) - S2 * PeekMatrixElement(CopyA, Oper, RowID))
PokeMatrixElement(*Inverse, LineID, RowID, S1 * PeekMatrixElement(*Inverse, LineID, RowID) - S2 * PeekMatrixElement(*Inverse, Oper, RowID))
Next
Next
Next
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Manipulation afin d'avoir des zéros au dessus de la diagonale.
For Oper = GetMatrixLine(*MatrixA) - 1 To 1 Step - 1
S1.d = PeekMatrixElement(CopyA, Oper, Oper)
For LineID = Oper - 1 To 0 Step -1
S2.d = PeekMatrixElement(CopyA, LineID, Oper)
For RowID = GetMatrixLine(*MatrixA) - 1 To 0 Step -1
PokeMatrixElement(CopyA, LineID, RowID, S1 * PeekMatrixElement(CopyA, LineID, RowID) - S2 * PeekMatrixElement(CopyA, Oper, RowID))
PokeMatrixElement(*Inverse, LineID, RowID, S1 * PeekMatrixElement(*Inverse, LineID, RowID) - S2 * PeekMatrixElement(*Inverse, Oper, RowID))
Next
Next
Next
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Normalisation par rapport à la diagonale
For Line = 0 To GetMatrixRow(*MatrixA) - 1
Pivot.d = PeekMatrixElement(CopyA, Line, Line)
If Pivot <> 0.0
For Row = 0 To GetMatrixRow(*MatrixA) - 1
PokeMatrixElement(CopyA, Line, Row, PeekMatrixElement(CopyA, Line, Row) / Pivot)
PokeMatrixElement(*Inverse, Line, Row, PeekMatrixElement(*Inverse, Line, Row) / Pivot)
Next
Else
ResetMatrix(CopyA)
ResetMatrix(*Inverse)
Result = #False
Break
EndIf
Next
Else
; La matrice n'est pas carrée
Result = #False
EndIf
ProcedureReturn Result
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The LUDecomposeMatrix Operator <<<<<
Procedure.b LUDecomposeMatrix(*MatrixA.Matrix, *L.Matrix, *U.matrix)
If GetMatrixLine(*MatrixA) = GetMatrixRow(*MatrixA)
CopyMatrix(*MatrixA, *U)
IdentityMatrix(*L, GetMatrixLine(*MatrixA))
LUDecomposeSuccess.b = #True
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Manipulation afin d'avoir des zéros sous la diagonale.
For Oper = 0 To GetMatrixLine(*MatrixA) - 2
For Line = Oper + 1 To GetMatrixLine(*MatrixA) - 1
If PeekMatrixElement(*MatrixA, Oper, Oper) <> 0.0
Fract.d = PeekMatrixElement(*U, Line, Oper) / PeekMatrixElement(*U, Oper, Oper)
PokeMatrixElement(*L, Line, Oper, Fract)
For Row = 0 To GetMatrixLine(*MatrixA) - 1
PokeMatrixElement(*U, Line, Row, PeekMatrixElement(*U, Line, Row) - Fract * PeekMatrixElement(*U, Oper, Row))
Next
Else
; Debug "La matrice est singulière"
ResetMatrix(*U)
ResetMatrix(*L)
LUDecomposeSuccess.b = #False
Break 2
EndIf
Next
Next
EndIf
ProcedureReturn LUDecomposeSuccess
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The DeterminantMatrix Operator <<<<<
Procedure.d DeterminantMatrix(*MatrixA.Matrix)
If GetMatrixLine(*MatrixA) = GetMatrixRow(*MatrixA)
Result.b = #True
CopyMatrix(*MatrixA, CopyA.Matrix)
If PeekMatrixElement(CopyA, 0, 0) = 0.0
If PeekMatrixElement(CopyA, GetMatrixLine(*MatrixA) - 1, Row) <> 0.0
; On additonne la dernière ligne à la première
For Row = 0 To GetMatrixRow(*MatrixA) - 1
PokeMatrixElement(CopyA, 0, Row, PeekMatrixElement(CopyA, 0, Row) + PeekMatrixElement(CopyA, GetMatrixLine(*MatrixA) - 1, Row))
Next
Else
; La matrice n'est pas inversible
Determinant.d = 0.0
Result = #False
EndIf
EndIf
If Result = #True
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Manipulation afin d'avoir des zéros sous la diagonale.
For Oper = 0 To GetMatrixLine(*MatrixA) - 2
For Line = Oper + 1 To GetMatrixLine(*MatrixA) - 1
If PeekMatrixElement(CopyA, Oper, Oper) <> 0.0
Fract.d = PeekMatrixElement(CopyA, Line, Oper) / PeekMatrixElement(CopyA, Oper, Oper)
For Row = 0 To GetMatrixLine(*MatrixA) - 1
PokeMatrixElement(CopyA, Line, Row, PeekMatrixElement(CopyA, Line, Row) - Fract * PeekMatrixElement(CopyA, Oper, Row))
Next
Else
; La matrice est singulière
Result = #False
Break 2
EndIf
Next
Next
EndIf
If Result = #True
Determinant = 1.0
For Line = 0 To GetMatrixLine(*MatrixA) - 1
Determinant = Determinant * PeekMatrixElement(CopyA, Line, Line)
Next
Else
Determinant = 0.0
EndIf
Else
; La matrice n'est pas carrée
Determinant = 0.0
EndIf
ResetMatrix(CopyA)
ProcedureReturn Determinant
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Read in Binary file <<<<<
Procedure ReadMatrix(FileID.l, *MatrixA.Matrix)
SetMatrixLine(*MatrixA, ReadUnicodeCharacter(FileID))
SetMatrixRow(*MatrixA, ReadUnicodeCharacter(FileID))
SetMatrixSize(*MatrixA, ReadLong(FileID))
AllocateMatrixElementsMemory(*MatrixA)
If GetMatrixElements(*MatrixA) = #Null
MessageRequester("Fatal Error", "ReadMatrix() - Impossible To Allocate Memory !")
End
Else
ReadData(FileID, GetMatrixElements(*MatrixA), MemoryMatrixElementsSize(*MatrixA))
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Write in Binary file <<<<<
Procedure WriteMatrix(FileID.l, *MatrixA.Matrix)
WriteUnicodeCharacter(FileID, GetMatrixLine(*MatrixA))
WriteUnicodeCharacter(FileID, GetMatrixRow(*MatrixA))
WriteLong(FileID, GetMatrixSize(*MatrixA))
If GetMatrixElements(*MatrixA) <> #Null
WriteData(FileID, GetMatrixElements(*MatrixA), MemoryMatrixElementsSize(*MatrixA))
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Set - Noeud avec noeuds enfants <<<<<
Procedure SetMatrixXMLNode(CurrentNode, *MatrixA.Matrix, P_Decimal.b = 6)
If ParentXMLNode(CurrentNode) = #Null
StructNode = CreateXMLNode(CurrentNode)
SetXMLNodeName(StructNode, "Matrix")
SetXMLAttribute(StructNode, "LineCount", Str(GetMatrixLine(*MatrixA)))
SetXMLAttribute(StructNode, "RowCount", Str(GetMatrixRow(*MatrixA)))
Else
StructNode = CurrentNode
EndIf
For LineID = 0 To GetMatrixLine(*MatrixA) - 1
FieldNode = CreateXMLNode(StructNode)
SetXMLNodeName(FieldNode, "Line" + Str(LineID + 1))
For RowID = 0 To GetMatrixRow(*MatrixA) - 1
SetXMLAttribute(FieldNode, "L" + Str(LineID + 1) + "_R" + Str(RowID + 1), StrD(PeekMatrixElement(*MatrixA, LineID, RowID), P_Decimal))
Next
Next
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Get - Noeud avec noeuds enfants <<<<<
Procedure GetMatrixXMLNode(CurrentNode, *MatrixA.Matrix)
If ParentXMLNode(CurrentNode) = #Null
StructNode = ChildXMLNode(CurrentNode)
If GetXMLNodeName(StructNode) = "Matrix"
Success = #True
EndIf
Else
Success = #True
StructNode = CurrentNode
EndIf
If Success = #True
LineCount.u = Val(GetXMLAttribute(StructNode, "LineCount"))
RowCount.u = Val(GetXMLAttribute(StructNode, "RowCount"))
ZeroMatrix(*MatrixA, LineCount, RowCount)
FieldNode = ChildXMLNode(StructNode)
For LineID = 0 To GetMatrixLine(*MatrixA) - 1
For RowID = 0 To GetMatrixRow(*MatrixA) - 1
PokeMatrixElement(*MatrixA, LineID, RowID, ValD_Patch_PB(GetXMLAttribute(FieldNode, "L" + Str(LineID + 1) + "_R" + Str(RowID + 1))))
Next
FieldNode = NextXMLNode(FieldNode)
Next
EndIf
ProcedureReturn Success
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Create XML file <<<<<
Procedure CreateMatrixXMLFile(FileID.l, FileName.s, *MatrixA.Matrix)
If CreateXML(FileID)
SetMatrixXMLNode(RootXMLNode(FileID), *MatrixA)
FormatXML(FileID, #PB_XML_ReFormat | #PB_XML_ReIndent)
SaveXML(FileID, FileName)
FreeXML(FileID)
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Load XML file <<<<<
Procedure LoadMatrixXMLFile(FileID.l, FileName.s, *MatrixA.Matrix)
If LoadXML(FileID, FileName)
FormatXML(FileID, #PB_XML_CutNewline)
GetMatrixXMLNode(RootXMLNode(FileID), *MatrixA)
FreeXML(FileID)
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Catch XML file <<<<<
Procedure CatchMatrixXMLFile(FileID.l, *Buffer, BufferSize.l, *MatrixA.Matrix)
If CatchXML(FileID, *Buffer, BufferSize)
FormatXML(FileID, #PB_XML_CutNewline)
GetMatrixXMLNode(RootXMLNode(FileID), *MatrixA)
FreeXML(FileID)
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Read preferences Matrix <<<<<
Procedure ReadPreferenceMatrix(Keyword.s, *MatrixA.Matrix, DefaultMatrix.s = "[0.0]")
String_To_Matrix(*MatrixA, ReadPreferenceString(Keyword, DefaultMatrix))
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Write preferences Matrix <<<<<
Procedure WritePreferenceMatrix(Keyword.s, *MatrixA.Matrix, P_Decimal.b = 6)
WritePreferenceString(Keyword, Matrix_To_String(*MatrixA.Matrix, P_Decimal))
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Save Matrix To CSV File <<<<<
Procedure SaveMatrixToCSVFile(FileID.l, FileName.s, *MatrixA.Matrix, P_Decimal.b = 6)
If CreateFile(FileID, FileName)
For LineID = 0 To GetMatrixLine(*MatrixA) - 1
For RowID = 0 To GetMatrixRow(*MatrixA) - 1
Line.s = Line + StrD(PeekMatrixElement(*MatrixA, LineID, RowID), P_Decimal)
If RowID < GetMatrixRow(*MatrixA) - 1
Line + ";"
EndIf
Next
WriteStringN(FileID, Line)
Line = ""
Next
CloseFile(FileID)
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Load Matrix From CSV File <<<<<
Procedure LoadMatrixFromCSVFile(FileID.l, FileName.s, *MatrixA.Matrix)
NewList CSVLine.s()
If ReadFile(FileID, FileName)
While Eof(FileID) = 0
Line.s = Trim(ReadString(FileID))
If Line <> ""
AddElement(CSVLine())
CSVLine() = Line
EndIf
Wend
CloseFile(FileID)
EndIf
FirstElement(CSVLine())
Max = CountString(CSVLine(), ";")
ZeroMatrix(*MatrixA, ListSize(CSVLine()), Max + 1)
ForEach CSVLine()
For RowID = 0 To Max
PokeMatrixElement(*MatrixA, LineID, RowID, ValD_Patch_PB(StringField(CSVLine(), RowID + 1, ";")))
Next
LineID + 1
CSVLine() = ""
Next
ClearList(CSVLine())
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Trefoil Knot Waypoint Matrix Operator : 3D Curves <<<<<
Procedure TrefoilKnotWaypointMatrix(*InterpolationValue.Matrix, *Path.Matrix, P_LeafCount.l = 3, P_e.l = 1)
ZeroMatrix(*Path, GetMatrixLine(*InterpolationValue), 3)
For U_ParamID = 0 To GetMatrixLine(*InterpolationValue) - 1
P_u.d = PeekMatrixElement(*InterpolationValue, U_ParamID, 0)
PokeMatrixElement(*Path, U_ParamID, 0, Cos(P_u) + 2 * Cos(P_LeafCount * P_u - P_u))
PokeMatrixElement(*Path, U_ParamID, 1, Sin(P_u) - 2 * Sin(P_LeafCount * P_u - P_u))
PokeMatrixElement(*Path, U_ParamID, 2, 2 * P_e * Sin(P_LeafCount * P_u))
Next
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The LagrangePolynomialMatrix Operator <<<<<
Procedure LagrangePolynomialMatrix(P_PointCount.u, *Coefficient.Matrix, *CoefficientInverse.Matrix)
ZeroMatrix(*Coefficient, P_PointCount, P_PointCount)
Increment.d = 1 / (P_PointCount - 1)
For Row = 0 To GetMatrixRow(*Coefficient) - 1
Var.d = 0.0
For Line = 0 To GetMatrixLine(*Coefficient) - 1
PokeMatrixElement(*Coefficient, Line, Row, Pow(Var, Row))
Var + Increment
Next
Next
GaussJordanInverseMatrix(*CoefficientInverse, *Coefficient)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The LagrangePathFromWaypoints Operator <<<<<
Procedure LagrangePathFromWaypoints(*Waypoint.Matrix, *InterpolationValue.Matrix, *Path.Matrix)
LagrangePolynomialMatrix(GetMatrixLine(*Waypoint), Lagrange.Matrix, LagrangeInverse.Matrix)
ProductMatrix(Equations.Matrix, LagrangeInverse, *Waypoint)
EvaluatePolynomialMatrix(Equations, *InterpolationValue, *Path)
ResetMatrix(Lagrange)
ResetMatrix(LagrangeInverse)
ResetMatrix(Equations)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The CatmullRomInverseCoefficient Operator <<<<<
Procedure CatmullRomInverseCoefficient(*InverseCoeff.Matrix)
CreateNewMatrix(*InverseCoeff, 4, 4, "CatmullRomInverseCoefficient()")
; <<<<<<<<<<<<<<<<<<<<
; <<<<< Ligne 1 <<<<<<
PokeMatrixElement(*InverseCoeff, 0, 0, 0.0)
PokeMatrixElement(*InverseCoeff, 0, 1, 1.0)
PokeMatrixElement(*InverseCoeff, 0, 2, 0.0)
PokeMatrixElement(*InverseCoeff, 0, 3, 0.0)
; <<<<<<<<<<<<<<<<<<<<
; <<<<< Ligne 2 <<<<<<
PokeMatrixElement(*InverseCoeff, 1, 0, -0.5)
PokeMatrixElement(*InverseCoeff, 1, 1, 0.0)
PokeMatrixElement(*InverseCoeff, 1, 2, 0.5)
PokeMatrixElement(*InverseCoeff, 1, 3, 0.0)
; <<<<<<<<<<<<<<<<<<<<
; <<<<< Ligne 3 <<<<<<
PokeMatrixElement(*InverseCoeff, 2, 0, 1.0)
PokeMatrixElement(*InverseCoeff, 2, 1, -2.5)
PokeMatrixElement(*InverseCoeff, 2, 2, 2.0)
PokeMatrixElement(*InverseCoeff, 2, 3, -0.5)
; <<<<<<<<<<<<<<<<<<<<
; <<<<< Ligne 4 <<<<<<
PokeMatrixElement(*InverseCoeff, 3, 0, -0.5)
PokeMatrixElement(*InverseCoeff, 3, 1, 1.5)
PokeMatrixElement(*InverseCoeff, 3, 2, -1.5)
PokeMatrixElement(*InverseCoeff, 3, 3, 0.5)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The CatmullRomPathFromWaypoint Operator <<<<<
Procedure CatmullRomPathFromWaypoint(*Waypoint.Matrix, *InterpolationValue.Matrix, *Path.Matrix)
CatmullRomInverseCoefficient(CatmullKInv.Matrix)
ProductMatrix(Equations.Matrix, CatmullKInv, *Waypoint)
EvaluatePolynomialMatrix(Equations, *InterpolationValue, *Path)
ResetMatrix(CatmullKInv)
ResetMatrix(Equations)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The CatmullRomPathFusion Operator <<<<<
Procedure CatmullRomPathFusion(*Fusion.Matrix, *PathA.Matrix, *PathB.Matrix)
If GetMatrixRow(*PathA) = GetMatrixRow(*PathB)
ZeroMatrix(*Fusion, GetMatrixLine(*PathA) + GetMatrixLine(*PathB) - 1, GetMatrixRow(*PathA))
CopyMemory(GetMatrixElements(*PathA), GetMatrixElements(*Fusion), MemoryMatrixElementsSize(*PathA) - 3 * SizeOf(Double))
CopyMemory(GetMatrixElements(*PathB), GetMatrixElements(*Fusion) + MemoryMatrixElementsSize(*PathA) - 3 * SizeOf(Double), MemoryMatrixElementsSize(*PathB))
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The CatmullRomInsertWaypoint Operator <<<<<
Procedure CatmullRomInsertWaypoint(*Waypoint.Matrix, *NewPoint.Matrix)
If GetMatrixRow(*Waypoint) = GetMatrixRow(*NewPoint)
For LineID = 1 To GetMatrixLine(*Waypoint) - 1
For RowID = 0 To GetMatrixRow(*Waypoint) - 1
PokeMatrixElement(*Waypoint, LineID - 1, RowID, PeekMatrixElement(*Waypoint, LineID, RowID))
If LineID = GetMatrixLine(*Waypoint) - 1
PokeMatrixElement(*Waypoint, LineID, RowID, PeekMatrixElement(*NewPoint, 0, RowID))
EndIf
Next
Next
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The InitializeHermite Operator <<<<<
Procedure HermiteInverseCoefficient(*InverseCoeff.Matrix)
CreateNewMatrix(*InverseCoeff, 4, 4, "HermiteInverseCoefficient()")
; <<<<<<<<<<<<<<<<<<<<
; <<<<< Ligne 1 <<<<<<
PokeMatrixElement(*InverseCoeff, 0, 0, 1.0)
PokeMatrixElement(*InverseCoeff, 0, 1, 0.0)
PokeMatrixElement(*InverseCoeff, 0, 2, 0.0)
PokeMatrixElement(*InverseCoeff, 0, 3, 0.0)
; <<<<<<<<<<<<<<<<<<<<
; <<<<< Ligne 2 <<<<<<
PokeMatrixElement(*InverseCoeff, 1, 0, 0.0)
PokeMatrixElement(*InverseCoeff, 1, 1, 0.0)
PokeMatrixElement(*InverseCoeff, 1, 2, 1.0)
PokeMatrixElement(*InverseCoeff, 1, 3, 0.0)
; <<<<<<<<<<<<<<<<<<<<
; <<<<< Ligne 3 <<<<<<
PokeMatrixElement(*InverseCoeff, 2, 0, -3.0)
PokeMatrixElement(*InverseCoeff, 2, 1, 3.0)
PokeMatrixElement(*InverseCoeff, 2, 2, -2.0)
PokeMatrixElement(*InverseCoeff, 2, 3, -1.0)
; <<<<<<<<<<<<<<<<<<<<
; <<<<< Ligne 4 <<<<<<
PokeMatrixElement(*InverseCoeff, 3, 0, 2.0)
PokeMatrixElement(*InverseCoeff, 3, 1, -2.0)
PokeMatrixElement(*InverseCoeff, 3, 2, 1.0)
PokeMatrixElement(*InverseCoeff, 3, 3, 1.0)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The De Casteljau Matrix <<<<<
Procedure DeCasteljauMatrix(Order.u, *D_Zero.Matrix, *D_One.Matrix)
If Order >= 2
ZeroMatrix(*D_Zero, Order, Order)
For RowID = 0 To Order - 1
For LineID = 0 To Order - 1
If RowID <= LineID
PokeMatrixElement(*D_Zero, LineID, RowID, BernsteinPolynomial(LineID, RowID, 0.5))
Else
PokeMatrixElement(*D_Zero, LineID, RowID, 0.0)
EndIf
Next
Next
CopyMatrix(*D_Zero, *D_One)
Min.u = 0
Max.u = Order - 1
While Min < Max
SwapMatrixLine(*D_One, Min, Max)
SwapMatrixRow(*D_One, Min, Max)
Min + 1
Max - 1
Wend
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The BezierPathFromControlpoints Operator <<<<<
Procedure BezierPathFromControlpoints(*Controlpoint.Matrix, *InterpolationValue.Matrix, *Path.Matrix)
ZeroMatrix(*Path, GetMatrixLine(*InterpolationValue), GetMatrixRow(*Controlpoint))
For U_ID = 0 To GetMatrixLine(*InterpolationValue) - 1
For RowID = 0 To GetMatrixRow(*Controlpoint) - 1
For LineID = 0 To GetMatrixLine(*Controlpoint) - 1
Sum.d = Sum + BernsteinPolynomial(GetMatrixLine(*Controlpoint) - 1, LineID, PeekMatrixElement(*InterpolationValue, U_ID, 0)) * PeekMatrixElement(*Controlpoint, LineID, RowID)
Next
PokeMatrixElement(*Path, U_ID, RowID, Sum)
Sum = 0.0
Next
Next
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<