In this short tutorial we want to use common Matlab commands within the BoSSS framework.
For our matrix analysis we use the following random matrix: $$ A = \begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9 \end{bmatrix} $$ and the symmetric matrix: $$ S = \begin{bmatrix} 1 & 2 & 3\\ 2 & 3 & 2\\ 3 & 2 & 1 \end{bmatrix} $$ We are going to evaluate some exemplary properties of the matrices and check if the matrices are symmetric, both in the BoSSS framework and in Matlab.
First, we have to initialize the new project:
#r "BoSSSpad.dll"
using System;
using System.Collections.Generic;
using System.Linq;
using ilPSP;
using ilPSP.Utils;
using BoSSS.Platform;
using BoSSS.Platform.LinAlg;
using BoSSS.Foundation;
using BoSSS.Foundation.XDG;
using BoSSS.Foundation.Grid;
using BoSSS.Foundation.Grid.Classic;
using BoSSS.Foundation.Grid.RefElements;
using BoSSS.Foundation.IO;
using BoSSS.Solution;
using BoSSS.Solution.Control;
using BoSSS.Solution.GridImport;
using BoSSS.Solution.Statistic;
using BoSSS.Solution.Utils;
using BoSSS.Solution.AdvancedSolvers;
using BoSSS.Solution.Gnuplot;
using BoSSS.Application.BoSSSpad;
using BoSSS.Application.XNSE_Solver;
using static BoSSS.Application.BoSSSpad.BoSSSshell;
Init();
using ilPSP.LinSolvers;
using ilPSP.Connectors.Matlab;
We want to implement the two 3x3 matrices in BoSSSpad
int Dim = 3;
MsrMatrix A = new MsrMatrix(Dim,Dim);
MsrMatrix S = new MsrMatrix(Dim,Dim);
double[] A_firstRow = new double[]{1,2,3};
double[] A_secondRow = new double[]{4,5,6};
double[] A_thirdRow = new double[]{7,8,9};
double[] S_firstRow = new double[]{1,2,3};
double[] S_secondRow = new double[]{2,3,2};
double[] S_thirdRow = new double[]{3,2,1};
for(int i=0; i<Dim; i++){
A[0, i] = A_firstRow[i];
S[0, i] = S_firstRow[i];
}
for(int i=0; i<Dim; i++){
A[1, i] = A_secondRow[i];
S[1, i] = S_secondRow[i];
}
for(int i=0; i<Dim; i++){
A[2, i] = A_thirdRow[i];
S[2, i] = S_thirdRow[i];
}
To analyze if the matrices are symmetric, we need to compare the original matrix with the transpose:
MsrMatrix AT = A.Transpose();
MsrMatrix ST = S.Transpose();
bool SymmTest_A;
bool SymmTest_S;
for(int i = 0; i<Dim; i++){
for(int j = 0; j<Dim; j++){
if(A[i,j] == AT[i,j]){
SymmTest_A = true;
}
else{
SymmTest_A = false;
break;
}
}
}
for(int i = 0; i<Dim; i++){
for(int j = 0; j<Dim; j++){
if(S[i,j] == ST[i,j]){
SymmTest_S = true;
}
else{
SymmTest_S = false;
break;
}
}
}
if(SymmTest_A == true){
Console.WriteLine("Matrix A seems to be symmetric.");
}
else{
Console.WriteLine("Matrix A seems NOT to be symmetric.");
}
if(SymmTest_S == true){
Console.WriteLine("Matrix S seems to be symmetric.");
}
else{
Console.WriteLine("Matrix S seems NOT to be symmetric.");
}
Matrix A seems NOT to be symmetric. Matrix S seems to be symmetric.
The BatchmodeConnector initializes an interface to Matlab:
Troubleshoot¶
In case that BoSSS cant find the path to matlab you will need to modify (if Matlab is installed) a file called MatlabConnectorConfig.json which you can find in your BoSSS binary under the following path:
cs ...\.BoSSS\etc\MatlabConnectorConfig.json
Inside the file add a path to your matlab.exe (e.g.): ```py { "MatlabExecuteable": "C:\ProgramFiles\MATLAB\R2021a\bin\win64\MATLAB.exe", "Flav": "Matlab" }
Console.WriteLine("Calling MATLAB/Octave...");
BatchmodeConnector bmc = new BatchmodeConnector();
Calling MATLAB/Octave...
We have to transfer out matrices to Matlab:
bmc.PutSparseMatrix(A, "Matrix_A");
bmc.PutSparseMatrix(S, "Matrix_S");
/// Now we can do calculations in Matlab within the \BoSSSpad{} using the \code{Cmd} command. It commits the Matlab commands as a string. We can calculate e.g. the rank of the matrix or the eigenvalues:
bmc.Cmd("Full_A = full(Matrix_A)");
bmc.Cmd("Full_S = full(Matrix_S)");
bmc.Cmd("Rank_A = rank(Full_A)");
bmc.Cmd("Rank_S = rank(Full_S)");
bmc.Cmd("EV_A = eig(Full_A)");
bmc.Cmd("EV_S = eig(Full_S)");
bmc.Cmd("Det_A = det(Full_A)");
bmc.Cmd("Det_S = det(Full_S)");
bmc.Cmd("Trace_A = trace(Full_A)");
bmc.Cmd("Trace_S = trace(Full_S)");
/// We can transfer matrices or arrays from Matlab to \BoSSSpad{} as well, here we want to have the results:
MultidimensionalArray Results = MultidimensionalArray.Create(2, 3);
bmc.Cmd("Results = [Rank_A, Det_A, Trace_A; Rank_S, Det_S, Trace_S]");
bmc.GetMatrix(Results, "Results");
/// and the eigenvalues:
MultidimensionalArray EV_A = MultidimensionalArray.Create(3, 1);
bmc.GetMatrix(EV_A, "EV_A");
MultidimensionalArray EV_S = MultidimensionalArray.Create(3, 1);
bmc.GetMatrix(EV_S, "EV_S");
/// After finishing using Matlab we need to close the interface to Matlab:
bmc.Execute(false);
Console.WriteLine("MATLAB/Octave closed, return to BoSSSPad");
MATLAB/Octave closed, return to BoSSSPad
And here are our results back in the BoSSSpad:
double Rank_A = Results[0,0];
double Rank_S = Results[1,0];
double Det_A = Results[0,1];
double Det_S = Results[1,1];
double Trace_A = Results[0,2];
double Trace_S = Results[1,2];
Console.WriteLine("The results of matrix A are: rank: " + Rank_A + ", trace: " + Trace_A + ", dterminant: " + Det_A);
Console.WriteLine("The results of matrix S are: rank: " + Rank_S + ", trace: " + Trace_S + ", determinant: " + Det_S);
Console.WriteLine();
Console.WriteLine("The eigenvalues of matrix A are: " + EV_A[0,0] + ", " + EV_A[1,0] + " and " + EV_A[2,0]);
Console.WriteLine("The eigenvalues of matrix S are: " + EV_S[0,0] + ", " + EV_S[1,0] + " and " + EV_S[2,0]);
The results of matrix A are: rank: 2, trace: 15, dterminant: 6.661338147750939E-16 The results of matrix S are: rank: 3, trace: 5, determinant: -7.999999999999998 The eigenvalues of matrix A are: 16.11684396980704, -1.116843969807043 and -1.303677726474702E-15 The eigenvalues of matrix S are: -1.999999999999999, 0.6277186767309848 and 6.372281323269013
We do the same test for symmetry for both matrices. In Matlab we can use the convenient command isequal:
Console.WriteLine("Calling MATLAB/Octave...");
BatchmodeConnector bmc = new BatchmodeConnector();
bmc.PutSparseMatrix(A, "Matrix_A");
bmc.PutSparseMatrix(S, "Matrix_S");
bmc.Cmd("Full_A = full(Matrix_A)");
bmc.Cmd("Full_S = full(Matrix_S)");
bmc.Cmd("A_Transpose = transpose(Full_A)");
bmc.Cmd("S_Transpose = transpose(Full_S)");
bmc.Cmd("SymmTest_A = isequal(Full_A, A_Transpose)");
bmc.Cmd("SymmTest_S = isequal(Full_S, S_Transpose)");
MultidimensionalArray SymmTest_A = MultidimensionalArray.Create(1, 1);
bmc.GetMatrix(SymmTest_A, "SymmTest_A");
MultidimensionalArray SymmTest_S = MultidimensionalArray.Create(1, 1);
bmc.GetMatrix(SymmTest_S, "SymmTest_S");
bmc.Execute(false);
Console.WriteLine("MATLAB/Octave closed, return to BoSSSPad");
Calling MATLAB/Octave... MATLAB/Octave closed, return to BoSSSPad
if(SymmTest_A[0,0] == 1){
Console.WriteLine("Matrix A seems to be symmetric.");
}
else{
Console.WriteLine("Matrix A seems NOT to be symmetric.");
}
if(SymmTest_S[0,0] == 1){
Console.WriteLine("Matrix S seems to be symmetric.");
}
else{
Console.WriteLine("Matrix S seems NOT to be symmetric.");
}
Matrix A seems NOT to be symmetric. Matrix S seems to be symmetric.