High Precision math in Nodebox
Hello all and John. I have a question about precision. I am doing math with some big numbers and I have been using mpmath in Python to make this work in Python scripts, but I wonder if I can use this in nodebox? I know you can run external Python scripts, but what about libraries? I have attached my nodebox files and the output with the same values from a Python script to show that I don't have enough decimal places to plot these lines accurately. I could be using faulty logic and not need to calculate something so insanely large, but I don't know any better.
- exp_poly.zip 2.19 MB
Keyboard shortcuts
Generic
| ? | Show this help |
|---|---|
| ESC | Blurs the current field |
Comment Form
| r | Focus the comment reply box |
|---|---|
| ^ + ↩ | Submit the comment |
You can use Command ⌘ instead of Control ^ on Mac
Support Staff 1 Posted by john on 30 Aug, 2025 09:47 AM
Hi Gabriel,
Always good to hear from you!
MPMath apparently works with Python 2 so should be able to work as an external code library called from Nodebox. You just have to place an import statement at the top of your Python script.
The one catch is that you do have to install the MPMath library on your computer, but I'm guessing you have already done this. Once installed it should work fine - on your computer. But the same Nodebox program would not work on someone else's computer unless they, too, had first installed MPMath.
This is the only reason I don't use Python libraries not already included with Nodebox. I want all my Nodebox projects to work on anyone's computer with no dependencies, especially the nodes in my Cartan Node Library. But since you are only writing code to create your own art, this shouldn't matter to you.
Is the slightly sharper Visual Studio file what you are trying to achieve in Nodebox? Did you use MPMath to generate the Visual Studio output? Was there any anti-aliasing when you JPEG'd the VS Studio output?
Nodebox floating point numbers are based on Java doubles which should give you about 15 digits of precision (as you can see with pi). Rounding errors certainly do accumulate, reducing this precision as you exponentiate, multiply, divide, and apply trigonometric functions. But I'm still a tad surprised that 15 digits is not enough.
I was able to simplify the calculations to eliminate the trig functions and fit node, but that didn't make any noticeable difference. Microscopic improvements to the coordinates would not be visible after the drawing is rasterized on export or when drawn or plotted. I guess a sharper image would have to come from more accurate mod values for very large numbers, which would affect the positions of consecutive point pairs around the circle.
If you implement the same algorithm in Python using MPMath and call it from Nodebox to draw the same ball - and get noticeably different results, I would LOVE to see the comparison!
You are always working on interesting projects. Please keep me posted!
John
Support Staff 2 Posted by john on 31 Aug, 2025 04:45 AM
Hello again Gabriel,
After I posted my response last night, I got to thinking...
Once I simplified your algorithm I saw that all the visual noise and rounding errors in your example stem from a single source: taking large numbers (like 3490^5 = 5.18 x 10^17) and finding that value modulo 3490. To find the mod you have to divide that large number by 3490 - and that's where the rounding errors creep in.
It occurred to me, though, that for this purpose you don't actually have to perform the mod function all at once. 3490^5 is just 3490 * 3490 * 3490 * 3490 * 3490. You can take the mod after each multiplication and still come up with the same answer. That way none of the intermediate values will ever get bigger than 3490^2 = 12,180,100, which only requires 7 or 8 digits of precision.
To try this I made a node, pow_mod, that raises a to the b modulo c one multiple at a time. This required some hardwired recursion, so for this test I only allowed the exponent to be 2, 3, 4, or 5. Higher exponents would be slower (it's already rather slow) but would be easy to add. I could also handle fractional exponents if need be.
Anyway I tried it and IT WORKS! The resultant drawing is crystal clear, even clearer than the Visual Studio output you shared.
See attached UI and "Before and After" screenshots, which compares your initial draft NodeBox output with this new cleaner output. Have a look inside my exp_poly_plus subnetwork to see how I did it. I left your original nodes in place so that you can compare and contrast. Note that my updated version asks for the diameter of the circle so that you don't have to use a fit node.
I would still be curious to see the output of a MPMath module called from Nodebox, so if you've already done that please share. But you now have an alternative method that works using ordinary Nodebox with no libraries needed.
John
3 Posted by gabriel sim-lar... on 02 Sep, 2025 11:41 PM
Thanks, John! As is sometimes the case, It took a minute for me to understand the math of what you were saying. I want to explain in steps what we did if anybody who is slower with the terms (like me) stumbles across this, but it's long so I will write an article for my website and link here when it is finished.
The basic idea is taking of a list of numbers from 0 to N. and we calculate the sine and cosine this number, times the angles of a circle divided by the largest number in the list. This creates the vertices of a regular polygon. There are patterns that emerge when each number of the list has first been raised to the 5th power before doing sine and cosine.
The problem is that when you raise a number to the 5th power, you quickly run out of decimal places to do accurate sine and cosine. My first idea was to do modulo (return the remainder of division) but to do even this requires an accuracy that most software doesn't have.
John's idea was to do modulo every time you multiply the number by itself. This keeps the number of decimal places down. This absolutely works!
It's also insanely slow. It begs the question of what we are trying to achieve with all of this many-sided polygon craziness. I wanted to know if I could exceed the amount of detail that can be rendered with a reasonable-sized image. That limit is within sight.
I think the best use of Nodebox here is for some of the lower number sides as a way to render every polygon. I want to make a taxonomy of the shapes possible. I think I can sort them by eye fairly quickly and then it will be interesting to see the progression. I assume there is some connection between factoring and composite numbers and the specific patterns.
- Gabriel
Support Staff 4 Posted by john on 03 Sep, 2025 04:20 AM
Gabriel,
You are right about how slow my technique is - not too bad for a one-off drawing, but annoying if you want to turn the knobs and quickly scan through many variations.
You could still follow through with your original plan: write some code in Python and call it from Nodebox. You could use MPMath or just implement my recursive mod function (easier in Python since it supports recursive functions). Either way it should be a lot faster and you could still use Nodebox for the rendering and adjustments.
Plan B is to use your original Nodebox code to scan through first drafts. The display would be muddy but still detailed enough to spot interesting variations. For each quick discovery you could then apply the settings to my version and wait a few seconds to see a sharper version.
I would greatly enjoy reading another of your articles. Do please send us a link when you crank it out.
John