Using symbolic math to retain accuracy. Arrays
Show older comments
Hi folks. I am trying to avoid numerical underflow using symbolic math.
Basically at some point in my algorithm I have a matrix
Which I call C. The values of C are very lagre. Now I would like to perform some operations on C by using some inbuilt matlab functions, but without loosing numerical accuracy.
Which I call C. The values of C are very lagre. Now I would like to perform some operations on C by using some inbuilt matlab functions, but without loosing numerical accuracy. The operations in words, and then in code are as follows : 1. Take the exponential of each element of
( pointwise )
a=exp(-C)
2. Sum the rows of C, so we are left with a
array of the sum of each row of 
b=sum(a,2)
3. Take the pointwise logarithm of each element in the array
.
ans=log(b)
Of course if the elements of C are too large then matlab reads the elements of
as 0. I think there may be a way around this ( since in the end we take logarithms ) by using symbolic math, but I dont know how (im very new to matlab). Anyone have any ideas?
I would like to mention that in practice my matrix C is of dimension
, and these operations are performed at every iteration of a for loop, hence Im worried that using symbolic math will increases the run time of my code too much.
3 Comments
John D'Errico
on 1 Dec 2021
The use of symbolic math is a crutch here, one that you will not be happy with due to the huge penalty in speed. Instead, learn to use good numerical techniques to avoid the problems. That may be of the form of rescaling things as necessary - @Bjorn Gustavsson has a good suggestion there. (One that probably should be an answer. You may wish to rescale by the maximum of -C in each column, instead of the average as a slightly better way to avoid numerical issues.) It may involve other approximations.
Be careful to catch any cases where all of the elements in a column of C are zero. That will be a problem when you try to rescale the columns.
Bjorn Gustavsson
on 1 Dec 2021
@John D'Errico, ops, should've caught that one - factoring out the max of each row is better. But maybe rows with all zeros in C is not that bad - if the factoring out of the max will only lead to a term of the type of log(exp(0)) then this should be OK? (The original formulation seemed a bit vague as I speed-read it...)
daniel adams
on 1 Dec 2021
Answers (1)
Bjorn Gustavsson
on 1 Dec 2021
0 votes
Factor out the average of each row of C. That should give you one term of the row-averages of C and then the sum of the logs of the exponential of the deviations relative to the average - these are hopefully small enough that your worries about nummerical accuracy are quenched...
HTH
3 Comments
daniel adams
on 1 Dec 2021
Bjorn Gustavsson
on 2 Dec 2021
TRY!
exp([1 2 3]) = exp(3).*exp([-2 -1 0]);
Sum and take the log of both expressions and compare the results:
S1 = log(sum(exp([1 2 3])));
S2 = log(exp(3)) + log(sum(exp([-2 -1 0])));
isequal(S1,S2) % Yeah this is a numerically dodgy comparison
TRY, if you "think", dont, check and work things out instead.
If this is not the expression you want your problem description is either too vague or inaccurate.
HTH
Bjorn Gustavsson
on 7 Dec 2021
Was this advice sufficient to solve your problem?
Categories
Find more on Numerical Integration and Differentiation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!