MATLAB : find a way with GPU NVIDIA to inverse quickly a large matrix of symbolic variables

23 views (last 30 days)
I have to solve the equality between 2 matrixes 12x12 containing a lot of symbolic variables and with which I perform inversion of matrix.
My system is solved fastly when I take for example 2 matrices 2x2, the inversion is pretty direct.
Now, with the case of 2 matrixes 12x12, I need before actually to inverse a 31x31 matrix of symbolic variables (I marginalize after), since inversion takes a lot of time.
I would like to benefit from my GPU NVIDIA Card 24GB ( QUADRO RTX 6000) to achieve this inversion faster.
I have looked at the doc on mathworks but there is not a lot of informations about GPU matrix inversion with MATLAB.
Below the script where you will find the line of inversion :
COV_ALL = inv(FISH_SYM)
clear;
clc;
format long;
% 2 Fisher Matrixes symbolic : FISH_GCsp_SYM, : 1 cosmo params + 1 bias spectro put for common
% FISH_XC_SYM : 1 cosmo params + 2 bias photo correlated
% GCsp Fisher : 7 param cosmo and 5 bias spectro which will be summed
FISH_GCsp_SYM = sym('sp_', [17,17], 'positive');
% Force symmetry for GCsp
FISH_GCsp_SYM = tril(FISH_GCsp_SYM.') + triu(FISH_GCsp_SYM,1)
% GCph Fisher : 7 param cosmo + 3 I.A + 11 bias photo correlated
FISH_XC_SYM = sym('xc_', [21,21], 'positive');
% Force symmetry for GCph
FISH_XC_SYM = tril(FISH_XC_SYM.') + triu(FISH_XC_SYM,1)
% Brutal Common Bias : sum of 7 cosmo param ans 5 bias spectro : FISH_ALL1 = first left matrix
FISH_ALL1 = sym('xc_', [12,12], 'positive');
% Sum cosmo
FISH_ALL1(1:7,1:7) = FISH_GCsp_SYM(1:7,1:7) + FISH_XC_SYM(1:7,1:7);
% Brutal sum of bias
FISH_ALL1(7:12,7:12) = FISH_GCsp_SYM(7:12,7:12) + FISH_XC_SYM(15:20,15:20);
% Adding new observable "O" terms
FISH_O_SYM = sym('o_', [2,2], 'positive');
% Definition of sigma_o
SIGMA_O = sym('sigma_o', 'positive');
FISH_O_SYM = 1/(SIGMA_O*SIGMA_O) * FISH_O_SYM
% Force symmetry
FISH_O_SYM = (tril(FISH_O_SYM.') + triu(FISH_O_SYM,1))
FISH_O_SYM
FISH_SYM = sym('xc_', [31,31], 'positive');
FISH_BIG_GCsp = sym('sp_', [31,31], 'positive');
FISH_BIG_XC = sym('xc_', [31,31], 'positive');
% Block bias spectro + pshot and correlations
FISH_BIG_GCsp(1:7,1:7) = FISH_GCsp_SYM(1:7,1:7)
FISH_BIG_GCsp(7:17,7:17) = FISH_GCsp_SYM(7:17,7:17)
FISH_BIG_GCsp(1:7,7:17) = FISH_GCsp_SYM(1:7,7:17)
FISH_BIG_GCsp(7:17,1:7) = FISH_GCsp_SYM(7:17,1:7)
% Block bias photo and correlations
FISH_BIG_XC(1:7,1:7) = FISH_XC_SYM(1:7,1:7)
FISH_BIG_XC(21:31,21:31) = FISH_XC_SYM(11:21,11:21)
FISH_BIG_XC(1:7,21:31) = FISH_XC_SYM(1:7,11:21)
FISH_BIG_XC(21:31,1:7) = FISH_XC_SYM(11:21,1:7)
% Block I.A and correlations
FISH_BIG_XC(18:20,18:20) = FISH_XC_SYM(8:10,8:10)
FISH_BIG_XC(1:7,18:20) = FISH_XC_SYM(1:7,8:10)
FISH_BIG_XC(18:20,1:7) = FISH_XC_SYM(8:10,1:7)
% Final summation
FISH_SYM = FISH_BIG_GCsp + FISH_BIG_XC
% Add O observable
FISH_SYM(6,6) = FISH_SYM(6,6) + FISH_O_SYM(1,1);
FISH_SYM(6,26) = FISH_SYM(6,26) + FISH_O_SYM(2,2);
FISH_SYM(26,6) = FISH_SYM(26,6) + FISH_O_SYM(1,2);
FISH_SYM(26,26) = FISH_SYM(26,26) + FISH_O_SYM(2,1);
% Force symmetry
FISH_SYM = (tril(FISH_SYM.') + triu(FISH_SYM,1))
% Marginalize FISH_SYM2 in order to get back a 2x2 matrix
% Invert to marginalyze
COV_ALL = inv(FISH_SYM);
% Marginalize
COV_ALL([13:31],:) = [];
COV_ALL(:,[13:31]) = [];
FISH_ALL2 = inv(COV_ALL);
FISH_ALL1
FISH_ALL2
% Matricial equation to solve
eqn = FISH_ALL1 == FISH_ALL2;
% Solving : sigma_o unknown
[solx, parameters, conditions] = solve(eqn, SIGMA_O, 'ReturnConditions', true);
solx
Could anyone give me please clues/suggestions/modifications to optimize this Matlab script with GPU NVIDIA for inverse the matrix considered ?

Answers (3)

Joss Knight
Joss Knight on 18 Apr 2021
Sorry, but Symbolic Math in MATLAB does not have GPU support.
  8 Comments
petit
petit on 22 Apr 2021
@Joss Knight Thanks for your quick answer.
So, from what I have understood, you could help me to optimize the INV function with parfor or parfeval and containing symbolic variables.
My code has been updating since some values in the Matrix 31x31 to invsere are equal to zeros : this would accelerate the computation of inverse.
Below the new code ;
clear;
clc;
format long;
% 2 Fisher Matrixes symbolic : FISH_GCsp_SYM, : 1 cosmo params + 1 bias spectro put for common
% FISH_XC_SYM : 1 cosmo params + 2 bias photo correlated
% GCsp Fisher : 7 param cosmo and 5 bias spectro which will be summed
FISH_GCsp_SYM = sym('sp_', [17,17], 'positive');
% Force symmetry for GCsp
FISH_GCsp_SYM = tril(FISH_GCsp_SYM.') + triu(FISH_GCsp_SYM,1)
% GCph Fisher : 7 param cosmo + 3 I.A + 11 bias photo correlated
FISH_XC_SYM = sym('xc_', [21,21], 'positive');
% Force symmetry for GCph
FISH_XC_SYM = tril(FISH_XC_SYM.') + triu(FISH_XC_SYM,1)
% Brutal Common Bias : sum of 7 cosmo param ans 5 bias spectro : FISH_ALL1 = first left matrix
FISH_ALL1 = sym('xc_', [12,12], 'positive');
% Sum cosmo
FISH_ALL1(1:7,1:7) = FISH_GCsp_SYM(1:7,1:7) + FISH_XC_SYM(1:7,1:7);
% Brutal sum of bias
FISH_ALL1(7:12,7:12) = FISH_GCsp_SYM(7:12,7:12) + FISH_XC_SYM(15:20,15:20);
% Adding new observable "O" terms
FISH_O_SYM = sym('o_', [2,2], 'positive');
% Definition of sigma_o
SIGMA_O = sym('sigma_o', 'positive');
FISH_O_SYM = 1/(SIGMA_O*SIGMA_O) * FISH_O_SYM
% Force symmetry
FISH_O_SYM = (tril(FISH_O_SYM.') + triu(FISH_O_SYM,1))
FISH_O_SYM
%FISH_SYM = sym('xc_', [31,31], 'positive');
%FISH_BIG_GCsp = sym('sp_', [31,31], 'positive');
%FISH_BIG_XC = sym('xc_', [31,31], 'positive');
FISH_SYM = zeros(31,31,'sym');
FISH_BIG_GCsp = zeros(31,31,'sym');
FISH_BIG_XC = zeros(31,31,'sym');
%FISH_GCsp_SYM = sym('xc_', [17,17], 'positive');
%FISH_XC_SYM = sym('sp_', [21,21], 'positive');
% Block bias spectro + pshot and correlations;
FISH_BIG_GCsp(1:7,1:7) = FISH_GCsp_SYM(1:7,1:7);
FISH_BIG_GCsp(7:17,7:17) = FISH_GCsp_SYM(7:17,7:17);
FISH_BIG_GCsp(1:7,7:17) = FISH_GCsp_SYM(1:7,7:17);
FISH_BIG_GCsp(7:17,1:7) = FISH_GCsp_SYM(7:17,1:7);
% Block bias photo and correlations;
FISH_BIG_XC(1:7,1:7) = FISH_XC_SYM(1:7,1:7);
FISH_BIG_XC(21:31,21:31) = FISH_XC_SYM(11:21,11:21);
FISH_BIG_XC(1:7,21:31) = FISH_XC_SYM(1:7,11:21);
FISH_BIG_XC(21:31,1:7) = FISH_XC_SYM(11:21,1:7);
% Block I.A and correlations;
FISH_BIG_XC(18:20,18:20) = FISH_XC_SYM(8:10,8:10);
FISH_BIG_XC(1:7,18:20) = FISH_XC_SYM(1:7,8:10);
FISH_BIG_XC(18:20,1:7) = FISH_XC_SYM(8:10,1:7);
% Final summation
FISH_SYM = FISH_BIG_GCsp + FISH_BIG_XC;
% Add O observable
FISH_SYM(6,6) = FISH_SYM(6,6) + FISH_O_SYM(1,1);
FISH_SYM(6,26) = FISH_SYM(6,26) + FISH_O_SYM(2,2);
FISH_SYM(26,6) = FISH_SYM(26,6) + FISH_O_SYM(1,2);
FISH_SYM(26,26) = FISH_SYM(26,26) + FISH_O_SYM(2,1);
% Force symmetry
FISH_SYM = (tril(FISH_SYM.') + triu(FISH_SYM,1))
% Marginalize FISH_SYM2 in order to get back a 2x2 matrix
% Invert to marginalyze : take a long long time
COV_ALL = inv(FISH_SYM);
% Marginalize
COV_ALL([13:31],:) = [];
COV_ALL(:,[13:31]) = [];
FISH_ALL2 = inv(COV_ALL);
FISH_ALL1
FISH_ALL2
% Matricial equation to solve
eqn = FISH_ALL1 == FISH_ALL2;
% Solving : sigma_o unknown
[solx, parameters, conditions] = solve(eqn, SIGMA_O, 'ReturnConditions', true);
solx
As you can see , the line COV_ALL = inv(FISH_SYM) takes a long long time to execute since 31x31 size for FISH_SYM.
And you can see also that the only symbolic that I can't substitue are matrix 2x2 FISH_O_SYM and scalar SIGMA_0.
All the rest can be subsituted by numerical values.
Anyone could help me to circumvent this hybrid system of equations, that is to say, keep FISH_O_SYM and SIGMA_O symbolic variables while insert numerical values for all the rest of elements ?
Best regards
Joss Knight
Joss Knight on 23 Apr 2021
You said "So, from what I have understood, you could help me to optimize the INV function with parfor or parfeval and containing symbolic variables."
What I said (with emphasis): "To answer your question to me, I DON'T KNOW how to optimize INV using parfor or parfeval."

Sign in to comment.


Steven Lord
Steven Lord on 22 Apr 2021
To elaborate on what John D'Errico said:
for n = 2:6
A = sym('A', [n, n]);
tic
IA = inv(A);
t = toc;
fprintf("Inverting a %d by %d symbolic matrix " + ...
"took %g seconds and the result was %d characters long\n", ...
n, n, t, strlength(char(IA)));
end
Inverting a 2 by 2 symbolic matrix took 0.080135 seconds and the result was 122 characters long Inverting a 3 by 3 symbolic matrix took 0.040322 seconds and the result was 1147 characters long Inverting a 4 by 4 symbolic matrix took 0.108877 seconds and the result was 10104 characters long Inverting a 5 by 5 symbolic matrix took 0.319783 seconds and the result was 94237 characters long Inverting a 6 by 6 symbolic matrix took 3.55863 seconds and the result was 946134 characters long
I couldn't go to n = 7 without MATLAB Answers execution timing out because the code takes longer than 55 seconds. But you can see the time increases sharply for n = 6 and the length in characters of the result is increasing roughly by a factor of 9 or 10. No matter what you do, inverting a 12-by-12 symbolic matrix is going to take a lot of time and the result is going to be very complicated and long.
If you're doing this to solve a system of equations, you don't want the inverse. Try the \ operator instead, using subs to substitute values for the symbolic variables before calling \ if possible.
  3 Comments
petit
petit on 23 Apr 2021
About my issue, I think that I have to get "known methods" to inverse a matrix, in order to avoid to apply a raw inversion with INV function.
Maybe this technique can be exploited by GPU. If not this is no bad, the most important is to find an algorithm of inversion of symbolic matrix that allows to gain in runtime.
Have you got any suggestions about all the existing algorithms to use potentially ?
Best regards
Steven Lord
Steven Lord on 23 Apr 2021
Are you absolutely, positively required to compute the explicit inverse for this matrix? If not, don't compute the inverse.
What exactly and specifically is the problem you're trying to solve where you believe you need the inverse? I would be willing to bet that likely what you actually need is to solve a system of equations, in which case the right solution would be to use the \ operator.
I'm about 95% sure GPU arrays or a parpool will not help you in any way with symbolic calculations.

Sign in to comment.


petit
petit on 25 Apr 2021
UPDATE: I have used the Schur complement suggested from the follwing remark on another forum :
So, I did the follwing modifications :
% Using Schur complement formula
D = FISH_SYM(13:31,13:31)
inv_D = inv(D)
% Apply formula of Schur complement
COV_ALL = FISH_SYM(1:12,1:12) - FISH_SYM(1:12,13:31)*inv_D*FISH_SYM(13:31,1:12)
FISH_ALL2 = inv(COV_ALL);
instead of "big" inversion with first inversion on 31x31 matrix:
COV_ALL = inv(FISH_SYM);
% Marginalize
COV_ALL([13:31],:) = [];
COV_ALL(:,[13:31]) = [];
FISH_ALL2 = inv(COV_ALL);
Do you think my modifications are right ?

Products


Release

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!