MATLAB Answers

Out of memory when converting symbolic matrix into function or by simplifying it

6 views (last 30 days)
Andrea Raviola
Andrea Raviola on 23 Sep 2020
Commented: Andrea Raviola on 3 Oct 2020
Hello everyone!
I am kindly asking your help to solve a MATLAB “out of memory” issue that I am facing with both a PC with 16 GB of RAM and the university server with 128 GB of RAM.
I am using MATLAB 2020a and my goal would be to convert, using the matlabFunction command, a 6x52 symbolic matrix (YB) with which I need to do some calculations. The reason I need to convert the matrix into a function handle is that the same operation is way faster if YB is a function than by using the subs command. Moreover, I would need to use this matrix/function as an objective function within a genetic algorithm, so I really need YB to be a function. YB is a sparse matrix (density of 50.3%), so I tried to set the matlabFucntion MATLAB command as:
YB_fnc=matlabFunction(YB,'Optimize',false,'Sparse',true);
But by using either the Optimize option set to true or false the “out of memory” problem still remains. The same thing happens with the Sparse option set to true or false. If I run the command whos, the answer is that the YB matrix occupies 8 Bytes. Even if not the ideal solution at all, I tried to use the matlabFunction on each element of the YB matrix using a for loop, but the “out of memory” problem persists.
I tried to simplify the matrix elements using vpa and/or combine to see if the matlabFunction would be affected, but the result is always the same. I also tried to use the simplify command, both on the full YB matrix and on its single elements, but I still get “out of memory”. If trying to simplify one single element of the YB matrix at the time (using a for loop as reported), the “out of memory” message appears when trying to simplify the element (1,17) of YB.
% Simplification of hte frist row of YB
YB_simpl_1=sym(zeros(1,Nc));
for j=1:52
YB_simpl_1(j)=simplify(YB(1,j));
end
I really don’t understand what makes the algorithm to use so much memory or how to fix this problem. My only guess is that the mathematical expressions on each elements of the YB matrix are too long (if I try to print the content of an element of the YB matrix on the Command Window I get an expression with a long series of sin and cos functions that, at the end, is truncated by the text exceeds the maximum line length for Command Window), but I cannot modify them because they are a result of previous calculations.
Could you please help me? I really have no idea of how to fix this problem.
Thank you very much!
Andrea

Accepted Answer

Dana
Dana on 23 Sep 2020
First, it's worth pointing out that if you call whos, symbolic variables always show up as 8 bytes. That's not because that's literally how much space they take up, but because whos doesn't really work for symbolic variables.
One thing you might try is to use simplify at an earlier stage in your construction of YB. Presumably YB is the result of some intermediate calculations. If you tried to use simplify at each step of the intermediate calculations, it would "break up" the simplification task into a series of smaller ones that may help you avoid an out-of-memory problem. This isn't guaranteed to work, though.
A better option is to re-think your use of symbolic math in the first place. I can see three good reasons to use symbolic math:
  1. You want your eventual output to be symbolic (i.e., you're directly interested in an algebraic expression).
  2. You need to apply a symbolic operation somewhere (e.g., differentiation).
  3. You have a bunch of intermediate steps to your operations, which you expect will lead to opportunities for significant algebraic simplifications along the way, whereas if you did all those steps numerically you might accumulate unacceptable numerical inaccuracies
A contrived example of #3 would be:
% numerically:
a = 1e18;
x = 1;
y = x+a;
z = y-a; % should equal 1, but instead returns 0
% symbolically:
a = sym(1e18);
x = sym(1);
y = x+a;
z = y-a: % returns 1 as desired
Since you're making this function, I'm assuming #1 doesn't apply. If #3 applies, you're kind of stuck (though in that case using simplify at all intermediate steps as I suggested above is more likely to help).
If #2 applies, is there any way you can "isolate" that symbolic-operation step and use matlabFunction only for that part? As a somewhat contrived example, suppose you initially had
x = sym('x',[2,1]);
y = [log(x(1)+x(2));log(x(1)-x(2))];
yJac = jacobian(y,x);
A = sym('A',[2,2]);
z = A.'*yJac*A;
fz = matlabFunction(z,'Vars',{x,A});
Here, it's really only the Jacobian step that you need to do symbolically, and that step returns a relatively simple expression. However, because z ends up being a somewhat complicated symbolic expression, the resulting function fz is also pretty complicated. An alternative way to do this that would make the matlabFunction step much simpler (and therefore less likely to cause memory problems in more complicated examples) is:
x = sym('x',[2,1]);
y = [log(x(1)+x(2));log(x(1)-x(2))];
yJac = jacobian(y,x);
fyJac = matlabFunction(yJac,'Vars',{x});
fz2 = @(x2,A) A.'*fyJac(x2)*A;
Here, we've stopped using symbolics after the Jacobian step, and in particular we're now only evaluating z numerically, rather than first creating it symbolically and then converting that to a numeric function. Since yJac is a much simpler expression than the symbolic z was, fyJac is in turn much simpler than fz. Hopefully you can see how this kind of strategy can greatly reduce the computation and memory burden of the call to matlabFunction.

  2 Comments

Dana
Dana on 23 Sep 2020
I should have added, if none of #1-#3 actually apply in your case, then there's a good chance you should be able to do away with the symbolic math altogether and just convert your computations to regular numeric ones.
Andrea Raviola
Andrea Raviola on 3 Oct 2020
Thank you very muhc for your suggestions Dana, they helped a lot! I simplified the single parts which where calculated in order to get the elements of the matrix, but the main cause of the problem was that I did not know that, in symbolic calculation, if I want to transpose a vector, I have to write "v.' " to get the v transponse, if nto MATLAB automatically calculate the conjuate transpose and this was adding a lot of complexity to the calculations and so I was facing the "out of memory" issue.
Thanks again
Andrea

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!