Crates.io | realistic |
lib.rs | realistic |
version | 0.5.2 |
source | src |
created_at | 2024-08-21 12:35:33.053665 |
updated_at | 2024-12-11 00:37:54.133004 |
description | Towards an API for the Real Numbers |
homepage | |
repository | https://github.com/tialaramex/realistic/ |
max_upload_size | |
id | 1346486 |
size | 119,255 |
Realistic is an implementation of Hans Boehm's "Towards an API for the Real Numbers" paper
The core idea here is that while by definition almost all Real numbers are non-computable and so we can't expect them to be well behaved in our computer, many useful Real numbers are quite well behaved if we provide a better API.
The Real type in this crate represents a number which is a composite of a rational (a ratio between two potentially large integers) and some real value which we may not be able to compute exactly and so must be approximated for display, but which sometimes has a precise description we can track to take advantage of in further calculations.
The built-in example interactive evaluates Simple Expressions entered by hand and displays the answer
This library is incomplete, some features which were whole and useful in the Java API described in the paper are unfinished or partial here.
The library does now have trigonometric functions but it still does not have interrupt capability, if you've set another thread the goal of computing a complex calculation or for a great deal of precision this library does not yet provide a mechanism to stop the calculation early.
To the extent this implementation reflects the intent of the original paper, credit should go to the author of that paper, Hans Boehm.
On the other hand, if you encounter bugs or inadequacies in this code, chances are blame for those lies entirely with me as its programmer
In some places the natural way to express the API in Rust differs from Java and I intend to explain such deviatione below, but for now the nature of the work often makes that impractical.
Unlike Java, Rust has "Operator overloading" or rather, we can implement many arithmetic operators for user defined types. This means that where the Java API provides named functions, in many cases the Rust API provides operators, such as + (impl Add) and * (impl Multiply)
I have chosen not to provide this capability for Computable, this might be revisited later
BoundedRational::to_big_integer
has a different name because in Rust as
signifies that this conversion is cheap
No attempt has been made to measure the current performance of this Rust, compare it against the Java, or against similar code. Although the code was not specifically written with performance in mind, some care was taken to avoid needless re-calculations even beyond the core idea of the Computable type.
Parsing for a simple fairly human readable expression syntax is provided, this syntax has a LISP-like structure with each list consisting of exactly one operator, then one or more sub-expressions consisting of either another list, a numeric literal or a name. The type for a parsed expression of this type is named Simple.
We can parse these expressions in the usual way, and we can evaluate such an expression.
Currently the provided operators are the + - * and / expected in programming for addition, subtraction, multiplication and division plus e or exp for the natural exponenitation, l or ln for the natural log, and s, sqrt or √ for square roots.
Also the cosine (cos) and sine (sin) functions are provided.
(ln (exp 1)) == (e (l 1)) == 1
(sqrt 9) == 3
(cos (* pi 2.5)) == 0
Numeric literals are written in decimal, 2.75 is exactly two and three quarters.
Today the built-in names are only e (the mathematical constant and base of the natural logarithm) and pi (the mathematical constant π)
However in the built-in evaluator names are also given to the previous answer (last) and all numbered answers (#1, #2 and so on)
When results are not whole numbers, scientific notation is used to display the decimal fraction
(+ 1 2 3 4) == 10
(* 1 2 3 4) == 24
(- 1) == -1 negates the number
(- 1 2) == -1 basic subtraction
(= 1 2 3) == -4 all subsequent arguments are also subtracted
(/ 1) == 1 inverts the number
(/ 1 2) == 0.5 basic division
(/ 1 2 3) == a sixth, all subsequent arguments are also divided