interval-arithmetic-eval

Interprets/evaluates mathematical expressions using interval arithmetic

Usage no npm install needed!

<script type="module">
  import intervalArithmeticEval from 'https://cdn.skypack.dev/interval-arithmetic-eval';
</script>

README

interval-arithmetic-eval

NPM Build Status Coverage Status Stability

js-standard-style

Interprets/evaluates mathematical expressions using interval arithmetic

Table of Contents generated with DocToc

Description

This module evaluates the generated code from math-codegen for the namespace interval-arithmetic providing the necessary adapter methods

Installation

$ npm install --save interval-arithmetic-eval

API

var compile = require('interval-arithmetic-eval');

code = compile(expression)

params

  • expression {string} the expression to be parsed

expression syntax:

  • literals
  • 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
  • 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)

returns {Object}

  • return.eval {function} The compiled function to be called with some scope variables

code.eval([scope])

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 the lo and hi properties is converted into an interval NOTE: this method checks empty intervals

returns {Interval} Returns an instance of the interval-arithmetic module

compile.policies

Policies used during the evaluation of an expression

compile.policies.identifierAllowed

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;
}

compile.policies.disableRounding

Call this function to disable rounding interval bounds to the next/previous floating point number (rounding is enabled by default)

compile.policies.enableRounding

Call this function to enable rounding interval bounds to the next/previous floating point number (rounding is enabled by default)

Examples

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 }

Basic operations

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 }

Function calls

// 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 }

Scope substitution

// 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