symtegration-0.4.0: Library for symbolic integration of mathematical expressions.
CopyrightCopyright 2024 Yoo Chung
LicenseApache-2.0
Maintainerdev@chungyc.org
Safe HaskellNone
LanguageGHC2021

Symtegration.Symbolic

Description

 
Synopsis

Representation

data Expression Source #

Symbolic representation of a mathematical expression. It is an instance of the Num, Fractional, and Floating type classes, so normal Haskell expressions can be used, although the expressions are limited to using the functions defined by these type classses. The type is also an instance of the IsString type class, so symbols can be expressed as Haskell string with the OverloadedStrings extension. The structure of these values is intended to be visible.

>>> 2 :: Expression
Number 2
>>> "x" :: Expression
Symbol "x"
>>> 2 + sin "x" :: Expression
BinaryApply Add (Number 2) (UnaryApply Sin (Symbol "x"))

A somewhat more concise representation can be obtained using toHaskell:

>>> toHaskell $ 2 * "y" + sin "x"
"2 * y + sin x"

Constructors

Number Integer

Represents a concrete number.

Symbol Text

Represents a symbol, which could either be a variable or a constant.

UnaryApply UnaryFunction Expression

Represents the application of an unary function.

BinaryApply BinaryFunction Expression Expression

Represents the application of a binary function.

Instances

Instances details
IsString Expression Source # 
Instance details

Defined in Symtegration.Symbolic

Floating Expression Source # 
Instance details

Defined in Symtegration.Symbolic

Generic Expression Source # 
Instance details

Defined in Symtegration.Symbolic

Num Expression Source # 
Instance details

Defined in Symtegration.Symbolic

Read Expression Source # 
Instance details

Defined in Symtegration.Symbolic

Fractional Expression Source # 
Instance details

Defined in Symtegration.Symbolic

Show Expression Source # 
Instance details

Defined in Symtegration.Symbolic

Eq Expression Source #

Structural equality, not semantic equality. E.g., "a" - "a" /= 0.

Instance details

Defined in Symtegration.Symbolic

TextShow Expression Source # 
Instance details

Defined in Symtegration.Symbolic

type Rep Expression Source # 
Instance details

Defined in Symtegration.Symbolic

data UnaryFunction Source #

Symbolic representation for unary functions.

Instances

Instances details
Bounded UnaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

Enum UnaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

Generic UnaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

Associated Types

type Rep UnaryFunction 
Instance details

Defined in Symtegration.Symbolic

type Rep UnaryFunction = D1 ('MetaData "UnaryFunction" "Symtegration.Symbolic" "symtegration-0.4.0-731kqytrP2e45Ltbn6eY7b" 'False) ((((C1 ('MetaCons "Negate" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Abs" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Signum" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Exp" 'PrefixI 'False) (U1 :: Type -> Type))) :+: ((C1 ('MetaCons "Log" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Sqrt" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Sin" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Cos" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Tan" 'PrefixI 'False) (U1 :: Type -> Type))))) :+: (((C1 ('MetaCons "Asin" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Acos" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Atan" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Sinh" 'PrefixI 'False) (U1 :: Type -> Type))) :+: ((C1 ('MetaCons "Cosh" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Tanh" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Asinh" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Acosh" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Atanh" 'PrefixI 'False) (U1 :: Type -> Type))))))
Read UnaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

Show UnaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

Eq UnaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

TextShow UnaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

type Rep UnaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

type Rep UnaryFunction = D1 ('MetaData "UnaryFunction" "Symtegration.Symbolic" "symtegration-0.4.0-731kqytrP2e45Ltbn6eY7b" 'False) ((((C1 ('MetaCons "Negate" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Abs" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Signum" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Exp" 'PrefixI 'False) (U1 :: Type -> Type))) :+: ((C1 ('MetaCons "Log" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Sqrt" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Sin" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Cos" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Tan" 'PrefixI 'False) (U1 :: Type -> Type))))) :+: (((C1 ('MetaCons "Asin" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Acos" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Atan" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Sinh" 'PrefixI 'False) (U1 :: Type -> Type))) :+: ((C1 ('MetaCons "Cosh" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Tanh" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Asinh" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Acosh" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Atanh" 'PrefixI 'False) (U1 :: Type -> Type))))))

data BinaryFunction Source #

Symbolic representation for binary functions.

Instances

Instances details
Bounded BinaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

Enum BinaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

Generic BinaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

Associated Types

type Rep BinaryFunction 
Instance details

Defined in Symtegration.Symbolic

type Rep BinaryFunction = D1 ('MetaData "BinaryFunction" "Symtegration.Symbolic" "symtegration-0.4.0-731kqytrP2e45Ltbn6eY7b" 'False) ((C1 ('MetaCons "Add" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Multiply" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Subtract" 'PrefixI 'False) (U1 :: Type -> Type))) :+: (C1 ('MetaCons "Divide" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Power" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "LogBase" 'PrefixI 'False) (U1 :: Type -> Type))))
Read BinaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

Show BinaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

Eq BinaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

TextShow BinaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

type Rep BinaryFunction Source # 
Instance details

Defined in Symtegration.Symbolic

type Rep BinaryFunction = D1 ('MetaData "BinaryFunction" "Symtegration.Symbolic" "symtegration-0.4.0-731kqytrP2e45Ltbn6eY7b" 'False) ((C1 ('MetaCons "Add" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Multiply" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Subtract" 'PrefixI 'False) (U1 :: Type -> Type))) :+: (C1 ('MetaCons "Divide" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Power" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "LogBase" 'PrefixI 'False) (U1 :: Type -> Type))))

Manipulation

substitute Source #

Arguments

:: Expression

Expression to apply substitution.

-> (Text -> Maybe Expression)

Maps symbols to expressions they are to be substituted with.

-> Expression

Expression with substitution applied.

Substitute the symbols with the corresponding expressions they are mapped to. The symbols will be replaced as is; there is no special treatment if the expression they are replaced by also contains the same symbol.

>>> toHaskell $ substitute ("x" + "y") (\case "x" -> Just ("a" * "b"); "y" -> Just 4)
"a * b + 4"

Computation

evaluate Source #

Arguments

:: Floating a 
=> Expression

Mathematical expression to evaluate.

-> (Text -> Maybe a)

Maps symbols to concrete values.

-> Maybe a

Evaluation result.

Calculates the value for a mathematical expression for a given assignment of values to symbols.

For example, when \(x=5\), then \(2x+1=11\).

>>> evaluate (2 * "x" + 1) (\case "x" -> Just 5)
Just 11.0

All symbols except for "pi" in a mathematical expression must be assigned a value. Otherwise, a value cannot be computed.

>>> evaluate (2 * "x" + 1) (const Nothing)
Nothing

The symbol "pi" is always used to represent \(\pi\), and any assignment to "pi" will be ignored. For example, the following is \(\pi - \pi\), not \(100 - \pi\).

>>> evaluate ("pi" - pi) (\case "x" -> Just 100)
Just 0.0

fractionalEvaluate Source #

Arguments

:: (Eq a, Fractional a) 
=> Expression

Mathematical expression to evaluate.

-> (Text -> Maybe a)

Maps symbols to concrete values.

-> Maybe a

Evaluation result.

Evaluates a mathematical expression with only operations available to Fractional values. In particular, this allows exact evaluations with Rational values. Nothing will be returned if a function not supported by all Fractional values is used by the mathematical expression.

As an exception, the (**) operator is allowed with constant integer exponents, even though (**) is not a function applicable to all Fractional types.

For example,

>>> let p = 1 / (3 * "x"**5 - 2 * "x" + 1) :: Expression
>>> fractionalEvaluate p (\case "x" -> Just (2 / 7 :: Rational))
Just (16807 % 7299)

Compare against evaluate, which cannot even use Rational computations because Rational is not an instance of the Floating type class:

>>> evaluate p (\case "x" -> Just (2 / 7 :: Double))
Just 2.3026441978353196

toFunction Source #

Arguments

:: Floating b 
=> Expression

The expression to be converted into a function.

-> (Text -> a -> b)

Maps how the argument to the function should be mapped to a value for a symbol. E.g., "x" could map the first element in a tuple as the value to use in its place.

-> a

The function generated from the expression.

-> b 

Returns a function based on a given expression. This requires a specification of how a symbol maps the argument to a value to be used in its place.

For example, the symbol "x" could use the argument as is as its value. I.e., "x" can be mapped to a function which maps the argument to itself.

>>> let f = toFunction ("x" ** 2 + 1) (\case "x" -> id) :: Double -> Double
>>> f 3  -- 3 ** 2 + 1
10.0
>>> f 10  -- 10 ** 2 + 1
101.0

For another example, "x" could map the first element from a tuple argument, and "y" could map the second element from the tuple argument. I.e., for a tuple argument to the function, the first element will be used as "x" and the second element will be used as "y".

>>> let m = \case "x" -> (\(x,_) -> x); "y" -> (\(_,y) -> y)
>>> let g = toFunction ("x" + 2 * "y") m :: (Double, Double) -> Double
>>> g (3,4)  -- 3 + 2 * 4
11.0
>>> g (7,1)  -- 7 + 2 * 1
9.0

getUnaryFunction :: Floating a => UnaryFunction -> a -> a Source #

Returns a function corresponding to the symbolic representation of an unary function.

>>> (getUnaryFunction Cos) pi == (cos pi :: Double)
True

getBinaryFunction :: Floating a => BinaryFunction -> a -> a -> a Source #

Returns a function corresponding to the symbolic representation of a binary function.

>>> (getBinaryFunction Add) 2 5 == (2 + 5 :: Double)
True

Pattern synonyms

Pattern synonyms are defined to make it more convenient to pattern match on Expression.

Constants

pattern Pi' :: Expression Source #

Unary functions

Binary functions