matlab - How to avoid loss of accuracy when converting symbolic expressions to functions? -
tl;dr: observe complete loss of accuracy when converting symbolic expression function handle matlabfunction
. wonder if there ways improve conversion in order avoid loss of accuracy.
i have symbolic variable x
1 <= x && x <= 2
holds true:
syms x real assumealso(1 <= x & x <= 2);
i have many computer-generated, lengthy symbolic expression in variable. 1 of them looks this:
expression = ( ... 1015424780204960143215273323910078528628754663952913658657288835138029704791686717561885487746105223164496264397062144000 ... *( ... 60345244216851610523130575942127473698515638085026410114070496399315754724985170479034760688327679099512793302302720*2^(1/2) ... - 85341062796188128379389251264141456937242003828816791711306294886439805159655912635773490018204138847163921224639041 ... )*(x - 2)^2 ... ) ... /31504288346872372712061562812941419427167561153216213605146864117586323331155800294021400857537041202039565879856190821729945216935526707438840242294801134287960934949194864204307116208568439380511702602881;
edit: have construct (pasting above make expression
constant 0)
expression = sym('(1015424780204960143215273323910078528628754663952913658657288835138029704791686717561885487746105223164496264397062144000*(60345244216851610523130575942127473698515638085026410114070496399315754724985170479034760688327679099512793302302720*2^(1/2) - 85341062796188128379389251264141456937242003828816791711306294886439805159655912635773490018204138847163921224639041)*(x - 2)^2)/31504288346872372712061562812941419427167561153216213605146864117586323331155800294021400857537041202039565879856190821729945216935526707438840242294801134287960934949194864204307116208568439380511702602881');
calling double(subs(expression, x, 1))
evaluates expression approximately -5.9492e+03
without problems, correct value. however, evaluation takes far long , huge (or rather tiny?) bottleneck in application. that’s why intend convert expression anonymous function operates on doubles , faster, so:
evaluator = matlabfunction(expression, 'vars', x);
the result being
@(x) (sqrt(2.0).*6.034524421685161e115-8.534106279618813e115) ... .*(x-2.0).^2.*3.223131940086397e-86
i had success approach in past. unfortunately in case, evaluator(x)
evaluates 0 value of x, because first row zero. obviously, has limited number of significant digits doubles.
are there ways work around this? can tell matlab consider range of x
can find better representation of constants?
the problem can fixed variable-precision arithmetic:
>> expr = vpa(expression) expr = -5949.2156936801140978790460880789*(x - 2.0)^2
convert function
>> func = function_handle value: @(x)(x-2.0).^2.*-5.949215693680114e3
then evaluate it
>> func(1) ans = -5.9492e+03
Comments
Post a Comment