rads.rpn

Reverse Polish Notation calculator.

Functions

Constants

Keyword

Value

PI

3.141592653589793

E

2.718281828459045

Operators

Keyword

Description

SUB

a = x - y

ADD

a = x + y

MUL

a = x*y

POP

remove top of stack

NEG

a = -x

ABS

a = |x|

INV

a = 1/x

SQRT

a = sqrt(x)

SQR

a = x*x

EXP

a = exp(x)

LOG

a = ln(x)

LOG10

a = log10(x)

SIN

a = sin(x)

COS

a = cos(x)

TAN

a = tan(x)

SIND

a = sin(x) [x in degrees]

COSD

a = cos(x) [x in degrees]

TAND

a = tan(x) [x in degrees]

SINH

a = sinh(x)

COSH

a = cosh(x)

TANH

a = tanh(x)

ASIN

a = arcsin(x)

ACOS

a = arccos(x)

ATAN

a = arctan(x)

ASIND

a = arcsin(x) [a in degrees]

ACOSD

a = arccos(x) [a in degrees]

ATAND

a = arctan(x) [a in degrees]

ASINH

a = arcsinh(x)

ACOSH

a = arccosh(x)

ATANH

a = arctanh(x)

ISNAN

a = 1 if x is NaN; a = 0 otherwise

ISAN

a = 0 if x is NaN; a = 1 otherwise

RINT

a is nearest integer to x

NINT

a is nearest integer to x

CEIL

a is nearest integer greater or equal to x

CEILING

a is nearest integer greater or equal to x

FLOOR

a is nearest integer less or equal to x

D2R

convert x from degrees to radians

R2D

convert x from radian to degrees

YMDHMS

convert from seconds since 1985 to YYMMDDHHMMSS format (float)

SUM

a[i] = x[1] + … + x[i] while skipping all NaN

DIF

a[i] = x[i]-x[i-1]; a[1] = NaN

DUP

duplicate the last item on the stack

DIV

a = x/y

POW

a = x**y

FMOD

a = x modulo y

MIN

a = the lesser of x and y [element wise]

MAX

a = the greater of x and y [element wise]

ATAN2

a = arctan2(x, y)

HYPOT

a = sqrt(x*x+y*y)

R2

a = x*x + y*y

EQ

a = 1 if x == y; a = 0 otherwise

NE

a = 0 if x == y; a = 1 otherwise

LT

a = 1 if x < y; a = 0 otherwise

LE

a = 1 if x ≤ y; a = 0 otherwise

GT

a = 1 if x > y; a = 0 otherwise

GE

a = 1 if x ≥ y; a = 0 otherwise

NAN

a = NaN if x == y; a = x otherwise

AND

a = y if x is NaN; a = x otherwise

OR

a = NaN if y is NaN; a = x otherwise

IAND

a = bitwise AND of x and y

IOR

a = bitwise OR of x and y

BTEST

a = 1 if bit y of x is set; a = 0 otherwise

AVG

a = 0.5*(x+y) [when x or y is NaN a returns the other value]

DXDY

a[i] = (x[i+1]-x[i-1])/(y[i+1]-y[i-1]); a[1] = a[n] = NaN

EXCH

exchange the top two stack elements

INRANGE

a = 1 if x is between y and z (inclusive); a = 0 otherwise

BOXCAR

filter x along dimension y with boxcar of length z

GAUSS

filter x along dimension y with Gaussian of width sigma z

exception rads.rpn.StackUnderflowError[source]

Bases: Exception

Raised when the stack is too small for the operation.

When this is raised the stack will exist in the state that it was before the operation was attempted. Therefore, it is not necessary to repair the stack.

class rads.rpn.Token[source]

Bases: abc.ABC

Base class of all RPN tokens.

See also

Literal

A literal numeric/array value.

Variable

A variable to be looked up from the environment.

Operator

Base class of operators that modify the stack.

abstract property pops

Elements removed off the stack by calling the token.

abstract property puts

Elements placed on the stack by calling the token.

abstract __call__(stack: MutableSequence[Union[float, numpy.generic, numpy.ndarray]], environment: Mapping[str, Union[float, numpy.generic, numpy.ndarray]]) → None[source]

Perform token’s action on the given stack.

The actions currently supported are:

  • Place literal value on the stack.

  • Place variable on the stack from the environment.

  • Perform operation on the stack.

  • Any combination of the above.

Note

This must be overridden for all tokens.

Parameters
  • stack – The stack of numbers/arrays to operate on.

  • environment – The dictionary like object providing the immutable environment.

class rads.rpn.Literal(value: Union[int, float, bool])[source]

Bases: rads.rpn.Token

Literal value token.

Parameters

value – Value of the literal.

Raises

ValueError – If value is not a number.

property pops

Elements removed off the stack by calling the token.

property puts

Elements placed on the stack by calling the token.

property value

Value of the literal.

__call__(stack: MutableSequence[Union[float, numpy.generic, numpy.ndarray]], environment: Mapping[str, Union[float, numpy.generic, numpy.ndarray]]) → None[source]

Place literal value on top of the given stack.

Parameters
  • stack – The stack of numbers/arrays to place the value on.

  • environment – The dictionary like object providing the immutable environment. Not used by this method.

class rads.rpn.Variable(name: str)[source]

Bases: rads.rpn.Token

Environment variable token.

This is a place holder to lookup and place a number/array from an environment mapping onto the stack.

Parameters

name – Name of the variable, this is what will be used to lookup the variables value in the environment mapping.

property pops

Elements removed off the stack by calling the token.

property puts

Elements placed on the stack by calling the token.

property name

Name of the variable, used to lookup value in the environment.

__call__(stack: MutableSequence[Union[float, numpy.generic, numpy.ndarray]], environment: Mapping[str, Union[float, numpy.generic, numpy.ndarray]]) → None[source]

Get variable value from environment and place on stack.

Parameters
  • stack – The stack of numbers/arrays to place value on.

  • environment – The dictionary like object to lookup the variable’s value from.

Raises

KeyError – If the variable cannot be found in the given environment.

class rads.rpn.Operator(name: str)[source]

Bases: rads.rpn.Token, abc.ABC

Base class of all RPN operators.

Parameters

name – Name of the operator.

class rads.rpn.Expression(tokens: Union[str, Iterable[Union[float, str, rads.rpn.Token]]])[source]

Bases: collections.abc.Sequence, typing.Generic, rads.rpn.Token

Reverse Polish Notation expression.

Note

Expressions cannot be evaluated as they may not be syntactically correct. For evaluation CompleteExpressions are required.

Expressions can be used in three ways:

See also

CompleteExpression

For a expression that can be evaluated on it’s own.

Parameters

tokens

A Reverse Polish Notation expression given as a sequence of tokens or a string of tokens.

Note

This parameter is very forgiving. If given a sequence of tokens and some of the elements are not Tokens then an attempt will be made to convert them to Tokens. Because of this both numbers and strings can be given in the sequence of tokens.

pops() → int[source]

Elements removed off the stack by calling the token.

puts() → int[source]

Elements placed on the stack by calling the token.

variables() → AbstractSet[str][source]

Set of variables needed to evaluate the expression.

complete() → rads.rpn.CompleteExpression[source]

Upgrade to a CompleteExpression if possible.

Returns

A complete expression, assuming this partial expression takes zero inputs and provides one output.

Raises

ValueError – If the partial expression is not a valid expression.

is_complete() → bool[source]

Determine if can be upgraded to CompleteExpression.

Returns

True if this expression can be upgraded to a CompleteExpression without error with the complete() method.

__call__(stack: MutableSequence[Union[float, numpy.generic, numpy.ndarray]], environment: Mapping[str, Union[float, numpy.generic, numpy.ndarray]]) → None[source]

Evaluate the expression as a token on the given stack.

Parameters
  • stack – The stack of numbers/arrays to operate on.

  • environment – The dictionary like object providing the immutable environment.

Raises

StackUnderflowError – If the expression underflows the stack.

__add__(other: Any) → rads.rpn.Expression[source]
class rads.rpn.CompleteExpression(tokens: Union[str, Iterable[Union[float, str, rads.rpn.Token]]])[source]

Bases: rads.rpn.Expression

Reverse Polish Notation expression that can be evaluated.

Parameters

tokens

A Reverse Polish Notation expression given as a sequence of tokens or a string of tokens.

Note

This parameter is very forgiving. If given a sequence of tokens and some of the elements are not Tokens then then an attempt will be made to convert them to Tokens. Because of this both numbers and strings can be given in the sequence of tokens.

Raises

ValueError – If the sequence or string of tokens represents an invalid expression. This exception also indicates which token makes the expression invalid.

complete() → rads.rpn.CompleteExpression[source]

Return this expression as it is already complete.

Returns

This complete expression.

eval(environment: Optional[Mapping[str, Union[float, numpy.generic, numpy.ndarray]]] = None) → Union[float, numpy.generic, numpy.ndarray][source]

Evaluate the expression and return a numerical or logical result.

Parameters

environment

A mapping to lookup variables in when evaluating the expression. If not provided an empty mapping will be used, this is fine as long as the expression does not contain any variables. This can be ascertained by checking the with the variables attribute:

if not expression.variables:
    expression.eval()

If the evaluation is lengthy or there are side effects to key lookup in the environment it may be beneficial to check for any missing variables first:

missing_vars = expression.variables.difference(environment)

Returns

The numeric or logical result of the expression.

Raises
  • TypeError

    If there is a type mismatch with one of the operators and a value.

    Note

    While this class includes a static syntax checker that runs upon initialization it does not know the type of variables in the given environment ahead of time.

  • KeyError – If the expression contains a variable that is not within the given environment.

  • IndexError, ValueError, RuntimeError, ZeroDivisionError – If arguments to operators in the expression do not have the proper dimensions or values for the operators to produce a result. See the documentation of each operator for specifics.

rads.rpn.token(string: str) → rads.rpn.Token[source]

Parse string token into a Token.

There are three types of tokens that can result from this function:

  • Literal - a literal integer or float

  • Variable - a variable to looked up in the environment

  • Operator - an operator to modify the stack

Parameters

string – String to parse into a Token.

Returns

Parsed token.

Raises
rads.rpn.SUB = SUB

Subtract one number/array from another.

x y SUB a

a = x - y

rads.rpn.ADD = ADD

Add two numbers/arrays.

x y ADD a

a = x + y

rads.rpn.MUL = MUL

Multiply two numbers/arrays.

x y MUL a

a = x*y

rads.rpn.POP = POP

Remove top of stack.

x POP

remove last item from stack

rads.rpn.NEG = NEG

Negate number/array.

x NEG a

a = -x

rads.rpn.ABS = ABS

Absolute value of number/array.

x ABS a

a = |x|

rads.rpn.INV = INV

Invert number/array.

x INV a

a = 1/x

rads.rpn.SQRT = SQRT

Compute square root of number/array.

x SQRT a

a = sqrt(x)

rads.rpn.SQR = SQR

Square number/array.

x SQR a

a = x*x

rads.rpn.EXP = EXP

Exponential of number/array.

x EXP a

a = exp(x)

rads.rpn.LOG = LOG

Natural logarithm of number/array.

x LOG a

a = ln(x)

rads.rpn.LOG10 = LOG10

Compute base 10 logarithm of number/array.

x LOG10 a

a = log10(x)

rads.rpn.SIN = SIN

Sine of number/array [in radians].

x SIN a

a = sin(x)

rads.rpn.COS = COS

Cosine of number/array [in radians].

x COS a

a = cos(x)

rads.rpn.TAN = TAN

Tangent of number/array [in radians].

x TAN a

a = tan(x)

rads.rpn.SIND = SIND

Sine of number/array [in degrees].

x SIND a

a = sin(x) [x in degrees]

rads.rpn.COSD = COSD

Cosine of number/array [in degrees].

x COSD a

a = cos(x) [x in degrees]

rads.rpn.TAND = TAND

Tangent of number/array [in degrees].

x TAND a

a = tan(x) [x in degrees]

rads.rpn.SINH = SINH

Hyperbolic sine of number/array.

x SINH a

a = sinh(x)

rads.rpn.COSH = COSH

Hyperbolic cosine of number/array.

x COSH a

a = cosh(x)

rads.rpn.TANH = TANH

Hyperbolic tangent of number/array.

x TANH a

a = tanh(x)

rads.rpn.ASIN = ASIN

Inverse sine of number/array [in radians].

x ASIN a

a = arcsin(x)

rads.rpn.ACOS = ACOS

Inverse cosine of number/array [in radians].

x ACOS a

a = arccos(x)

rads.rpn.ATAN = ATAN

Inverse tangent of number/array [in radians].

x ATAN a

a = arctan(x)

rads.rpn.ASIND = ASIND

Inverse sine of number/array [in degrees].

x ASIND a

a = arcsin(x) [a in degrees]

rads.rpn.ACOSD = ACOSD

Inverse cosine of number/array [in degrees].

x ACOSD a

a = arccos(x) [a in degrees]

rads.rpn.ATAND = ATAND

Inverse tangent of number/array [in degrees].

x ATAND a

a = arctan(x) [a in degrees]

rads.rpn.ASINH = ASINH

Inverse hyperbolic sine of number/array.

x ASINH a

a = arcsinh(x)

rads.rpn.ACOSH = ACOSH

Inverse hyperbolic cosine of number/array.

x ACOSH a

a = arccosh(x)

rads.rpn.ATANH = ATANH

Inverse hyperbolic tangent of number/array.

x ATANH a

a = arctanh(x)

rads.rpn.ISNAN = ISNAN

Determine if number/array is NaN.

x ISNAN a

a = 1 if x is NaN; a = 0 otherwise

Note

Instead of using 1 and 0 pyrads uses True and False which behave as 1 and 0 when treated as numbers.

rads.rpn.ISAN = ISAN

Determine if number/array is not NaN.

x ISAN a

a = 0 if x is NaN; a = 1 otherwise

Note

Instead of using 1 and 0 pyrads uses True and False which behave as 1 and 0 when treated as numbers.

rads.rpn.RINT = RINT

Round number/array to nearest integer.

x RINT a

a is nearest integer to x

rads.rpn.NINT = NINT

Round number/array to nearest integer.

x NINT a

a is nearest integer to x

rads.rpn.CEIL = CEIL

Round number/array up to nearest integer.

x CEIL a

a is nearest integer greater or equal to x

rads.rpn.CEILING = CEILING

Round number/array up to nearest integer.

x CEILING a

a is nearest integer greater or equal to x

rads.rpn.FLOOR = FLOOR

Round number/array down to nearest integer.

x FLOOR a

a is nearest integer less or equal to x

rads.rpn.D2R = D2R

Convert number/array from degrees to radians.

x D2R a

convert x from degrees to radians

rads.rpn.R2D = R2D

Convert number/array from radians to degrees.

x R2D a

convert x from radian to degrees

rads.rpn.YMDHMS = YMDHMS

Convert number/array from seconds since RADS epoch to YYMMDDHHMMSS.

x YMDHMS a

convert seconds of 1985 to format YYMMDDHHMMSS

Note

The top of the stack should be in seconds since the RADS epoch which is currently 1985-01-01 00:00:00 UTC

Note

The RADS documentation says this format uses a 4 digit year, but RADS uses a 2 digit year so that is what is used here.

rads.rpn.SUM = SUM

Compute sum over number/array [ignoring NaNs].

x SUM a

a[i] = x[1] + … + x[i] while skipping all NaN

rads.rpn.DIF = DIF

Compute difference over number/array.

x DIF a

a[i] = x[i]-x[i-1]; a[1] = NaN

rads.rpn.DUP = DUP

Duplicate top of stack.

x DUP a b

duplicate the last item on the stack

Note

This is duplication by reference, no copy is made.

rads.rpn.DIV = DIV

Divide one number/array from another.

x y DIV a

a = x/y

rads.rpn.POW = POW

Raise a number/array to the power of another number/array.

x y POW a

a = x**y

rads.rpn.FMOD = FMOD

Remainder of dividing one number/array by another.

x y FMOD a

a = x modulo y

rads.rpn.MIN = MIN

Minimum of two numbers/arrays [element wise].

x y MIN a

a = the lesser of x and y

rads.rpn.MAX = MAX

Maximum of two numbers/arrays [element wise].

x y MAX a

a = the greater of x and y

rads.rpn.ATAN2 = ATAN2

Inverse tangent of two numbers/arrays giving x and y.

x y ATAN2 a

a = arctan2(x, y)

rads.rpn.HYPOT = HYPOT

Hypotenuse from numbers/arrays giving legs.

x y HYPOT a

a = sqrt(x*x+y*y)

rads.rpn.R2 = R2

Sum of squares of two numbers/arrays.

x y R2 a

a = x*x + y*y

rads.rpn.EQ = EQ

Compare two numbers/arrays for equality [element wise].

x y EQ a

a = 1 if x == y; a = 0 otherwise

Note

Instead of using 1 and 0 pyrads uses True and False which behave as 1 and 0 when treated as numbers.

rads.rpn.NE = NE

Compare two numbers/arrays for inequality [element wise].

x y NE a

a = 0 if x == y; a = 1 otherwise

Note

Instead of using 1 and 0 pyrads uses True and False which behave as 1 and 0 when treated as numbers.

rads.rpn.LT = LT

Compare two numbers/arrays with < [element wise].

x y LT a

a = 1 if x < y; a = 0 otherwise

Note

Instead of using 1 and 0 pyrads uses True and False which behave as 1 and 0 when treated as numbers.

rads.rpn.LE = LE

Compare two numbers/arrays with <= [element wise].

x y LE a

a = 1 if x ≤ y; a = 0 otherwise

Note

Instead of using 1 and 0 pyrads uses True and False which behave as 1 and 0 when treated as numbers.

rads.rpn.GT = GT

Compare two numbers/arrays with > [element wise].

x y GT a

a = 1 if x > y; a = 0 otherwise

Note

Instead of using 1 and 0 pyrads uses True and False which behave as 1 and 0 when treated as numbers.

rads.rpn.GE = GE

Compare two numbers/arrays with >= [element wise].

x y GE a

a = 1 if x ≥ y; a = 0 otherwise

Note

Instead of using 1 and 0 pyrads uses True and False which behave as 1 and 0 when treated as numbers.

rads.rpn.NAN = NAN

Replace number/array with NaN where it is equal to another.

x y NAN a

a = NaN if x == y; a = x otherwise

rads.rpn.AND = AND

Fallback to second number/array when first is NaN [element wise].

x y AND a

a = y if x is NaN; a = x otherwise

rads.rpn.OR = OR

Replace number/array with NaN where second is NaN.

x y OR a

a = NaN if y is NaN; a = x otherwise

rads.rpn.IAND = IAND

Bitwise AND of two numbers/arrays [element wise].

x y IAND a

a = bitwise AND of x and y

rads.rpn.IOR = IOR

Bitwise OR of two numbers/arrays [element wise].

x y IOR a

a = bitwise OR of x and y

rads.rpn.BTEST = BTEST

Test bit, given by second number/array, in first [element wise].

x y BTEST a

a = 1 if bit y of x is set; a = 0 otherwise

rads.rpn.AVG = AVG

Average of two numbers/arrays ignoring NaNs [element wise].

x y AVG a

a = 0.5*(x+y) [when x or y is NaN a returns the other value]

rads.rpn.DXDY = DXDY

Compute dx/dy from two numbers/arrays.

x y DXDY a

a[i] = (x[i+1]-x[i-1])/(y[i+1]-y[i-1]); a[1] = a[n] = NaN

rads.rpn.EXCH = EXCH

Exchange top two elements of stack.

x y EXCH a b

exchange the last two items on the stack (NaNs have no influence)

rads.rpn.INRANGE = INRANGE

Determine if number/array is between two numbers [element wise].

x y z INRANGE a

a = 1 if x is between y and z (inclusive) a = 0 otherwise (also in case of any NaN)

rads.rpn.BOXCAR = BOXCAR

Filter number/array with a boxcar filter along a given dimension.

x y z BOXCAR a

a = filter x along monotonic dimension y with boxcar of length z (NaNs are skipped)

Note

This may behave slightly differently than the official RADS software at boundaries and at NaN values.

Raises
rads.rpn.GAUSS = GAUSS

Filter number/array with a gaussian filter along a given dimension.

x y z GAUSS a

a = filter x along monotonic dimension y with Gauss function with sigma z (NaNs are skipped)

Raises