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

21 views (last 30 days)
petit on 18 Apr 2021
Answered: petit on 25 Apr 2021
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
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 ?

Joss Knight on 18 Apr 2021
Sorry, but Symbolic Math in MATLAB does not have GPU support.
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."

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.
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.

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 ?

R2020a

Community Treasure Hunt

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

Start Hunting!