New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move use fpu reciprocal
to the fpu
library
#861
Comments
This key fix a precision problem --- you can see it in circuitikz/circuitikz#367 --- when big coordinates are used. For a test where |
One example where this key removes the |
Thanks again to @tallmarmot. See pgf-tikz/pgf#861
@Rmano No, it is not a precision problem, but a problem with the range that can be represented. In fact, precision is much worse when using the FPU. For example: \documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fpu}
\begin{document}
\pgfmathparse{12/4}\pgfmathresult
\tikzset{/pgf/fpu=true,/pgf/fpu/output format=fixed}
\pgfmathparse{12/4}\pgfmathresult
\end{document} @tallmarmot I hope this definition you posted is a joke and you are not actually using this. |
@hmenke I am absolutely using it, it is absolutely not a joke, and you should not use examples where the use of \documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fpu}
\begin{document}
\pgfmathparse{12.34/0.001234}\pgfmathresult
\tikzset{/pgf/fpu=true,/pgf/fpu/output format=fixed}
\pgfmathparse{12.34/0.001234}\pgfmathresult
\end{document} There is a reason why @Rmano and I are using it. While the discrepancy for integer divisions does not have any visible impact on paths, the difference for non-integer fractions is HUGE and can be seen in https://tex.stackexchange.com/questions/529099/path-joining-in-to-path-with-non-integer-scale-factors/ as well as all the cases in which you get these very unnecessary |
Aha, I see. And instead of improving the built-in code we must load 3000 lines of library code that has the capability of breaking basic drawing. No, thanks. |
@hmenke That's why you can switch it on and off. (I actually do not see how the changing the reciprocal can break drawings, but as I said the change is local.) Here is a code that allows you to see what happens. It assumes that \documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{xfp}
\usepackage{etoolbox}
\usepackage{longtable}
\usepackage{tikz}
\usetikzlibrary{fpu}
\newcommand{\pgfmathsetmacroFPU}[2]{\begingroup
\pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}%
\pgfmathsetmacro{#1}{#2}%
\pgfmathsmuggle#1\endgroup}
\begin{document}
\pgfmathsetseed{\number\pdfrandomseed}%
\edef\iloop{0}%
\edef\maxerrorplain{0}*
\edef\maxerrorfpu{0}*
\loop
\pgfmathsetmacro{\myx}{pow(0.1*(rnd+0.1),2)}%
\pgfmathsetmacro{\myy}{pow(0.1*(rnd+0.4),3)}%
\pgfmathtruncatemacro{\itest}{\myy>0.001}%
\ifnum\itest=1
\pgfmathsetmacro{\plainresult}{\myx/\myy}%
\pgfmathsetmacroFPU{\fpuresult}{\myx/\myy}%
\edef\xfpresult{\fpeval{\myx/\myy}}%
\edef\errorplain{\fpeval{(\plainresult-\xfpresult)/\xfpresult}}%
\edef\errorfpu{\fpeval{(\fpuresult-\xfpresult)/\xfpresult}}%
\pgfmathsetmacro{\maxerrorplain}{max(abs(\errorplain),\maxerrorplain)}%
\pgfmathsetmacro{\maxerrorfpu}{max(abs(\errorfpu),\maxerrorfpu)}%
\xappto\mytablecontents{$\myx$ & $\myy$ & $\plainresult$ & $\fpuresult$
& $\xfpresult$ & $\errorplain$ & $\errorfpu$}
\gappto\mytablecontents{\\}
\edef\iloop{\the\numexpr\iloop+1}%
\fi
\ifnum\iloop<500\repeat
max error plain: $\maxerrorplain$, max error fpu: $\maxerrorfpu$\par\bigskip
\begin{longtable}{lllllll}
$x$ & $y$ & plain & fpu & xfp & error plain & error fpu\\
\endhead
\endlastfoot
\mytablecontents
\end{longtable}
\end{document} The upshot of my run with this document is
So you can easily have errors larger than 5% with the built in reciprocal but at least in this comparison the fpu errors are well below the permille level. Let me stress that I did not design this snippet to maximize the error of the plain code. In fact, I had to filter out the cases where it is particularly bad, which is when it is close to It is IMHO evident that fpu does NOT generally decrease the precision. In all but exceptional cases it makes the results more precise. It does certainly help tremendously with avoiding If you want to tell the users that you do not want allow them to locally switch on the fpu reciprocal, this is your choice. I would not want to make this choice personally. How can we proceed in a constructive way? The only real alternatives I see is to rewrite the built in reciprocal, but this is something I personally would want to try out, or to load |
I think that the Also please don't post huge code blocks. Use a GitHub Gist or some other paste service for that. |
@hmenke You started out with the statement that |
I don't mean to dismiss these great ideas, but you have to be aware that including this is a massive regression. It replaces one class of errors ( The reason why I don't like the |
@hmenke The error of the traditional reciprocal can be larger than 13%. \documentclass{article}
\usepackage{pgf}
\usepackage{xfp}
\begin{document}
\edef\myx{0.000069}
\pgfmathparse{1/\myx}\pgfmathresult
\fpeval{1/\myx}
\fpeval{(\pgfmathresult-\fpeval{1/\myx})/\fpeval{1/\myx}}
\end{document} The problem is the code/case pgf/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex Lines 232 to 245 in 670edf4
Here |
@hmenke Final comment on issue 678. Switching on |
The problem occurs much earlier before even entering pgf/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex Lines 68 to 69 in 670edf4
The key issue with |
Maybe this is not the right place add my thoughts as well, but I'll give it a try and you -- of course -- decide what to do with it. Please also note that your math knowledge and understanding is way higher than mine, so I might be completely wrong. My feeling about the math precision stuff is that it would be best to add another option (or two) as well.
Here I link two TUGBoat articles of Joseph Wright that deal with the above.
Of course I don't have any clue how much work that would imply, but hopefully it will be worth it. What I know is that PGFPlots already did something to use Lua as calculation engine in some circumstances (see section 6.3.1 in the PGFPlots manual (v1.17)). Maybe this helps!? |
@hmenke So far there is no issue with the key, and I seriously doubt it will be raining bug messages. If anything, this key will decrease the number because it can cure the problems of decorations. I am also not sure if the conversion to dimensions is the main effect. At least I understand the huge error of over 13% more or less entirely from the code of the reciprocal. If you want to clean up on the Q & A sites, tell people even more strongly not to nest (I had the last discussion of this type just yesterday, see here. The answer is still unchanged, and if you add |
@Mo-Gul I am very sure that adding any of these will be absolutely nontrivial. It would amount to rewrite a huge amount of code. IMHO LuaLaTeX is not an option, the arXiv does not support it. This would give TikZ the status of PSTricks: you cannot really use it for arXiv submissions. As for |
I am probably mathematically less knowledgable than @Mo-Gul here (I am just an electronic engineer, and an analog one --- we're in process of extinction) but I am working in instrumentation so I am quite used to errors. I think that the When using fixed arithmetic, the range is a problem, and there is nothing you can do for the loss of precision for very small numbers --- short of switching to mantissa+exponent, which has the representation limits problems (this is why for example in Python you have a Decimal class...). So I reckon it's a hard problem. The Universe is mean. I agree that a real solution should be to change the internal math to have a more correct value (and all my kudos for trying to integrate But again, it's not so fundamental. I agree that opinions can differ, and I agree that sometime stopgap solutions can be bad on long time scales. My opinion is that this one, used sparingly, can help. |
To summarize: @hmenke made three completely false statement: precision of |
This key will selectively install the specified functions from the fpu library to be able to avoid `Dimension too large' errors in specific cases. Be aware that under certain circumstances the fpu comes with a loss of precision due to the underlying fixed-point arithmetic of TeX. These situations are rare but have be looked out for. [[ Example: In general the fpu increases the range of permissible number substantially but sometimes has precision problems. \usetikzlibrary{fpu} \pgfkeys{/pgf/fpu/install only={divide}} \pgfmathparse{12.34/0.001234}\pgfmathresult % 10000.000000 (good) \pgfmathparse{12/4}\pgfmathresult % 2.9999000000000 (bad) ]]
How about this? 494bd67 (Docs 1612b81) This doesn't come with the massive overhead of reparsing the expression, even though at this point we already know it's a number and it is generic, i.e. you can temporarily install any function from the FPU. Currently this issues a warning because I have not tested this thoroughly and I'm not so happy with the implementation, so I might change/rename/remove this again. |
I tried it with the issue in https://gist.github.com/Rmano/e7c48d09be4cea71ea5e7d3b20f9808b (I hope to have copied all the relevant bits). It works for |
Yes, I can confirm that installing |
First of all, sorry, this is to a large extent my bad. When writing the update of the
bbox
library, I added theuse fpu reciprocal
key. At this point I had sort of forgotten that this key gets also used in CircuitikZ. The definitions are the same (in the sense that the functionality is the same). The key is defined viaI wonder if we can move it to the
fpu
library.P.S. According to my experience this key can be very useful beyond CircuitikZ and
bbox
. It does cure a large fraction ofdimension too large
errors that occur in decorations.The text was updated successfully, but these errors were encountered: