# How to convert an expression to a function with lossless precision?

7 views (last 30 days)
chenguang yan on 27 Sep 2020
Commented: Walter Roberson on 28 Sep 2020
I use matlabFunction to convert an expression to an anonymous function, but the convertion of matlabFunction has a loss of precision. Is there a lossless conversion method? If not, is there any conversion method to improve accuracy?

Show 1 older comment
chenguang yan on 27 Sep 2020
When I copy the expression in the code, I can't seem to reproduce the problem, because result_subs will also get a non-zero result. However, if the expression is in the workspace, the result of result_subs is 0.
By the way, the func and f_func in the picture are the same. I forgot to unify the variable names when I took the screenshot.
chenguang yan on 27 Sep 2020
I read the answer to the following question. The conversion of matlabFucntion did lose accuracy, but I did not find a solution to the problem
Ameer Hamza on 27 Sep 2020
As Walter mentioned in his answer, you will lose precision once you convert from symbolic maths to finite-precision. To get exact results, you must stick to variable precision or symbolic mathematics.

Walter Roberson on 27 Sep 2020
Is there a lossless conversion method?
NO, there is no lossless conversion method.
A few years ago I encountered a paper that showed an explicit function that had the property that for any given finite numeric precision, there were inputs to the function for which the error due to rounding could be made arbitrarily large compared to the actual value of the function at the location. The paper showed that no matter how many guard digits you used for rounding purposes, the rounding error could be arbitrarily large relative to the correct value.
I do not recall now what the demonstration function used was, but it was not a complicated function. Something along the lines of x+(1/x) but a bit more developed.
I have myself encountered nonlinear equalities that when I evaluated to a million digits, I still could not decide if the equality was true. The symbolic manipulations said that the equalities held, but because the expressions were so different I was trying to verify whether the symbolic package had made a conversion mistake... and I couldn't decide based on numeric techniques. The rounding issues even at a million digits were substantial.
So, NO. There cannot be any finite numeric technique that can give enough precision to solve arbitrary nonlinear least squares.

Show 3 older comments
Walter Roberson on 28 Sep 2020
Yup, But I think you need to reconsider your goals.
>> 29/7 * 7 - 29
ans =
3.5527136788005e-15
Now suppose I gave the objective function 7 * x - 29 and asked you to find the numeric solution to it. The algebraic solution is trivial, the rational 29/7, but there is no double precision floating point number that multiplies by 7 to give exactly 29.
Could we do better by using decimal to a fixed precision?
NO, we cannot. Consider the rational number 1/3 expressed as decimal to any fixed number of decimal points. Multiply it by 3 and you will get 0.9<repeating> for that number of decimal points. If you use any fixed precision decimal, you cannot exactly solve the simple equation 3 * x - 1 .
These are just simple linear functions, and they have no solution in binary floating point and they have no solution in any finite precision decimal.
Nonlinear equations are worse: they often have no exact solution. x^2 - 1 has no exact solution in finite precision: there is no finite precision number that, when squared, gives exactly 2 -- not without taking advantage of rounding, which is in antagonism to your goal to use "lossless" calculations.
For every integer greater than 1, the number (B)/(B + 1) is not exactly representable in integer base B. We do not have to worry about theoretical calculations involving finding prime factors to prove that we can construct "some" number that cannot be finitely represented: we can skip all that and go directly to B/(B+1) which will definitely not be representable in a finite sequence using that base. 2/3 for base 2, 10/11 for base 10, 12/13 for base 12, 60/61 for base 60...
To avoid these simple finite base problems, we would have to work in rationals, in pairs (A,B) representing A/B . But there is no rational number such that (A/B)^2 == 2 .
Therefore for lossless nonlinear work, at the very least we have to extend our calculations to rationals combined with sqrt() -- the "algebraic numbers". But then comes the inconvenient Able-Ruffin theory, that most polynomials of degree 5 or higher do not have roots that are algebraic numbers; x^5 + 2*x + 1 is an example. So for lossless nonlinear work we would have to extend to general placeholders of roots of polynomials. There are good routines for approximating the numeric roots of polynomials, but they are not generally representable as algebraic numbers...
By now you should have lost most hope of lossless solutions to even fairly simple nonlinear equations. Add in an exp() and the rest of your hope for solutions that are somehow less complex than "symbolic" implies, should be completely abandoned.
There may be particular nonlinear problems that can be rewritten in terms of rationals, but most nonlinear problems cannot be rewritten that way. Not even x^2 == 2.
chenguang yan on 28 Sep 2020
Thank you very much for your reply, which has benefited me a lot. I will reconsider my question based on your suggestions.
When using the solution algorithms provided by matlab, does the following statement hold true?
Statement: When functionTolerance == 0 is used as the only iteration termination condition and the solution is obtained, the solution obtained is the same as the exact solution under double precision.
Walter Roberson on 28 Sep 2020
The truth of that statement would depend on which solver you were using. Most of the Mathworks ones do not permit you to turn off everything else and use exact 0 as the termination. Solvers would, in many cases, narrow down to the double precision numbers that are on either side of the exact solution, and if exact 0 residue was required and everything else was turned off for termination, the solver would then cycle infinitely between the two adjacent numbers.

### More Answers (2)

madhan ravi on 27 Sep 2020
vpa(f_func(sym(sol1), sym(sol2)))

chenguang yan on 27 Sep 2020
The loss of precision actually occurs during the conversion process of matlabFunction, sorry that this does not solve the problem.
madhan ravi on 27 Sep 2020
When you use matlabFunction() , it converts it into double precision, why not use subs()?
chenguang yan on 27 Sep 2020
This expression represents a nonlinear least squares problem, and I need to convert the expression into an objective function (the global minimum value is zero, and I don’t know the values of sol1 and sol2 in the actual problem). However, the precision loss of matlabFunction() means that even if I find the global minimum value, the corresponding value will not be the same as sol1 and sol2.

chenguang yan on 27 Sep 2020
Edited: chenguang yan on 27 Sep 2020
I uploaded the compressed package, which includes a .mat file and a .m file. After decompression, the problem should be reproduced by executing the .m file.

### Community Treasure Hunt

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

Start Hunting!

Translated by