Interprets/evaluates mathematical expressions using interval arithmetic
Table of Contents generated with DocToc
This module evaluates the generated code from math-codegen for the namespace interval-arithmetic providing the necessary adapter methods
$ npm install --save interval-arithmetic-eval
var compile = require('interval-arithmetic-eval');
params
expression
{string} the expression to be parsed
expression
syntax:
- literals
- numbers are turned into singleton intervals
- identifiers
- All the methods/utilities/constants available in interval-arithmetic
- The properties declared in a scope object (top level only)
- binary expressions
+
addition-
subtraction*
multiplication/
division^
power (with the condition that the exponent is a signed integer)
- unary expressions
+
identity-
negative
- array expressions
- numbers are turned into intervals
- call expressions
- All the methods/utilities/constants available in interval-arithmetic
except
pow
(which is a special operator) - The functions declared in a scope object (top level only)
- All the methods/utilities/constants available in interval-arithmetic
except
returns {Object}
return.eval
{function} The compiled function to be called with some scope variables
params
scope
{Object}
An optional object which holds some variables used in the original expression to be substituted, the following transformations are done with the values when evaluated
- a single
number
is converted to a singleton interval - an
array
is converted to an unbounded interval, NOTE: this method checks empty intervals - an
object
which has thelo
andhi
properties is converted into an interval NOTE: this method checks empty intervals
returns {Interval} Returns an instance of the interval-arithmetic module
Policies used during the evaluation of an expression
Assign a function which determines if the given name to be resolved from the scope is valid
default value
compile.policies.identifierAllowed = function (name) {
// any name from the scope is valid
return true;
}
Call this function to disable rounding interval bounds to the next/previous floating point number (rounding is enabled by default)
Call this function to enable rounding interval bounds to the next/previous floating point number (rounding is enabled by default)
Boilerplate code for the examples:
compile(expression).eval(scope)
// e.g.
compile('1').eval({}); // { lo: 1, hi: 1 }
compile('x').eval({x: 1}) // { lo: 1, hi: 1 }
1
> { lo: 1, hi: 1 }
// unary minus
-1
> { lo: -1, hi: -1 }
// floating point error is carried over in the operations
-1 + 3
> { lo: 1.9999999999999998, hi: 2.0000000000000004 }
// [1, 1] / [3, 3]
1 / 3
> { lo: 0.33333333333333326, hi: 0.33333333333333337 }
-1 / 3
> { lo: -0.33333333333333337, hi: -0.33333333333333326 }
-(1 / 3)
> { lo: -0.33333333333333337, hi: -0.33333333333333326 }
-1 / -3
> { lo: 0.33333333333333326, hi: 0.33333333333333337 }
2 * 3
> { lo: 5.999999999999999, hi: 6.000000000000001 }
[1, 2]
> { lo: 1, hi: 2 }
-[1, 2]
> { lo: -2, hi: -1 }
[1, 2] + [-1, 2]
> { lo: -5e-324, hi: 4.000000000000001 }
// means [1, 2] + [-2, 1]
[1, 2] - [-1, 2]
> { lo: -1.0000000000000002, hi: 3.0000000000000004 }
[1, 2] * [-1, 2]
> { lo: -2.0000000000000004, hi: 4.000000000000001 }
[1, 2] / [2, 3]
> { lo: 0.33333333333333326, hi: 1.0000000000000002 }
// if the upper interval has zero the result will also contain a zero
[-1, 1] / [2, 3]
> { lo: -0.5000000000000001, hi: 0.5000000000000001 }
// division by an interval that has zero results in a whole interval
[1, 2] / [-1, 1]
> { lo: -Infinity, hi: Infinity }
// integer power
[-3, 2]^2
> { lo: 0, hi: 9.000000000000004 }
// integer negative power, 1 / [-3, 2]^2 = 1 / [0, 9]
[-3, 2]^-2
> { lo: 0.11111111111111105, hi: Infinity }
// integer power (odd power)
[-3, 2]^3
> { lo: -26.99999999999999, hi: 8.000000000000004 }
// constants available in interval-arithmetic
ZERO + ONE
> { lo: 0.9999999999999999, hi: 1.0000000000000002 }
// constant available in interval-arithmetic
PI
> { lo: 3.141592653589793, hi: 3.1415926535897936 }
// same as -1
negative(1)
> { lo: -1, hi: -1 }
// same as -1 + 3
add(-1, 3)
> { lo: 1.9999999999999998, hi: 2.0000000000000004 }
// same as [1, 2] + [-1, 2]
add([1, 2], [-1, 2])
> { lo: -5e-324, hi: 4.000000000000001 }
// cosine of the interval [0, 0]
cos(0)
> { lo: 0.9999999999999999, hi: 1.0000000000000002 }
// cosine of the interval [PI_low, PI_high]
cos(PI)
> { lo: -1, hi: -0.9999999999999999 }
// cosine of the interval [PI_low / 2, PI_high / 2] which contains zero
cos(PI_HALF)
> { lo: -3.82856869892695e-16, hi: 2.8327694488239903e-16 }
// all the available values for cosine
cos([0, 3.15])
> { lo: -1, hi: 1.0000000000000002 }
sin(PI_HALF)
> { lo: 0.9999999999999999, hi: 1 }
// absolute value of the interval [-1, 1]
abs(-1)
> { lo: 1, hi: 1 }
// absolute value of the interval [-3, -2]
abs([-3, -2])
> { lo: 2, hi: 3 }
// absolute value of the interval [-2, 3]
abs([-2, 3])
> { lo: 0, hi: 3 }
// 1 / 2
multiplicativeInverse(2)
> { lo: 0.49999999999999994, hi: 0.5000000000000001 }
// using the number 4 stored in scope.x
// scope: { x: 4 }
x
> { lo: 4, hi: 4 }
// using the interval [2, 3] stored in scope.x
// scope: { x: [ 2, 3 ] }
x
> { lo: 2, hi: 3 }
// using the interval Instance stored in scope.x
// scope: { x: { lo: 2, hi: 3 } }
x
> { lo: 2, hi: 3 }
// adding a constant and a scope variable
// scope: { x: [ 1, 1 ] }
ONE + x
> { lo: 1.9999999999999998, hi: 2.0000000000000004 }
// division between two variables stored in the scope
// scope: { x: [ 2, 3 ], y: [ 1, 2 ] }
x / y
> { lo: 0.9999999999999999, hi: 3.0000000000000004 }
// complex expression
// scope: { x: [ 0, 1 ] }
sin(exp(x)) + tan(x) - 1/cos(PI) * ([1, 3]^2)
> { lo: 1.410781290502905, hi: 11.557407724654913 }
2015 © Mauricio Poppe