-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Equation solver and calculator à la metafont
--
@package mfsolve
@version 0.3.0
-- | This module implements an equation solver that solves and evaluates
-- expressions on the fly. It is based on Prof. D.E.Knuth's
-- metafont. The goal of mfsolve is to make the solver useful in
-- an interactive program, by enhancing the bidirectionality of the
-- solver. Like metafont, it can solve linear equations, and evaluate
-- nonlinear expressions. In addition to metafont, it also solves for
-- angles, and makes the solution independend of the order of the
-- equations.
--
-- The Expr datatype allows for calculations with constants and
-- unknown variables. The Dependencies datatype contains all
-- dependencies and known equations.
--
--
Examples:
--
-- Let's define some variables. The SimpleVar type is a simple
-- wrapper around String to provide nice output, since the Show
-- instance for String outputs quotation marks.
--
--
-- let [x, y, t, a] = map (makeVariable . SimpleVar) ["x", "y", "t", "a"]
--
--
-- Solve linear equations:
--
--
-- showVars $ flip execSolver noDeps $ do
-- 2*x + y === 5
-- x - y === 1
--
--
--
-- x = 2.0
-- y = 1.0
--
--
-- Solve for angle (pi/4):
--
--
-- showVars $ flip execSolver noDeps $ sin(t) === 1/sqrt(2)
--
--
--
-- t = 0.7853981633974484
--
--
-- Solve for angle (pi/3) and amplitude:
--
--
-- showVars $ flip execSolver noDeps $ do
-- a*sin(x) === sqrt 3
-- a*cos(x) === 1
--
--
--
-- x = 1.0471975511965979
-- a = 2.0
--
--
-- Allow nonlinear expression with unknown variables:
--
--
-- showVars $ flip execSolver noDeps $ do
-- sin(sqrt(x)) === y
-- x === 2
--
--
--
-- x = 2.0
-- y = 0.9877659459927355
--
--
-- Find the angle and amplitude when using a rotation matrix:
--
--
-- showVars $ flip execSolver noDeps $ do
-- a*cos t*x - a*sin t*y === 30
-- a*sin t*x + a*cos t*y === 40
-- x === 10
-- y === 10
--
--
--
-- x = 10.0
-- y = 10.0
-- t = 0.14189705460416402
-- a = 3.5355339059327373
--
module Math.MFSolve
-- | A simplified datatype representing an expression. This can be used to
-- inspect the structure of a Expr, which is hidden.
data SimpleExpr v n
SEBin :: BinaryOp -> (SimpleExpr v n) -> (SimpleExpr v n) -> SimpleExpr v n
SEUn :: UnaryOp -> (SimpleExpr v n) -> SimpleExpr v n
Var :: v -> SimpleExpr v n
Const :: n -> SimpleExpr v n
-- | A mathematical expression of several variables. Several Numeric
-- instances (Num, Floating and Fractional) are
-- provided, so doing calculations over Expr is more convenient.
data Expr v n
-- | A linear expression of several variables. For example: 2*a + 3*b +
-- 2 would be represented as LinExpr 2 [(a, 2), (b, 3)].
data LinExpr v n
LinExpr :: n -> [(v, n)] -> LinExpr v n
data UnaryOp
Sin :: UnaryOp
Abs :: UnaryOp
Recip :: UnaryOp
Signum :: UnaryOp
Exp :: UnaryOp
Log :: UnaryOp
Cos :: UnaryOp
Cosh :: UnaryOp
Atanh :: UnaryOp
Tan :: UnaryOp
Sinh :: UnaryOp
Asin :: UnaryOp
Acos :: UnaryOp
Asinh :: UnaryOp
Acosh :: UnaryOp
Atan :: UnaryOp
data BinaryOp
Add :: BinaryOp
Mul :: BinaryOp
newtype SimpleVar
SimpleVar :: String -> SimpleVar
-- | Create an expression from a variable
makeVariable :: Num n => v -> Expr v n
-- | Create an expression from a constant
makeConstant :: n -> Expr v n
-- | Evaluate the expression given a variable substitution.
evalExpr :: Floating n => (v -> n) -> SimpleExpr v n -> n
-- | Make a expression from a simple expression.
fromSimple :: (Floating n, Ord n, Ord v) => SimpleExpr v n -> Expr v n
-- | Convert an Expr to a SimpleExpr.
toSimple :: (Num n, Eq n) => Expr v n -> SimpleExpr v n
-- | evaluate a simple expression using the given substitution.
evalSimple :: Floating m => (n -> m) -> (v -> m) -> SimpleExpr v n -> m
-- | The expression contains the given variable.
hasVar :: (Num t, Eq v, Eq t) => v -> Expr v t -> Bool
-- | This hidden datatype represents a system of equations. It contains
-- linear dependencies on variables as well as nonlinear equations. The
-- following terminology is used from metafont:
--
--
-- - known variable: A variable who's dependency is just a
-- number.
-- - dependend variable: A variable which depends linearly on
-- other variables.
-- - independend variable: any other variable.
--
--
-- A dependend variable can only depend on other
-- independend variables. Nonlinear equations will be simplified
-- by substituting and evaluating known variables, or by reducing some
-- trigonometric equations to linear equations.
data Dependencies v n
-- | An error type for ===, =&= and addEquation:
data DepError v n
-- | The variable is not defined.
UndefinedVar :: v -> DepError v n
-- | The variable is defined but dependend an other variables.
UnknownVar :: v -> n -> DepError v n
-- | The equation was reduced to the impossible equation `a == 0` for
-- nonzero a, which means the equation is inconsistent with previous
-- equations.
InconsistentEq :: n -> DepError v n
-- | The equation was reduced to the redundant equation `0 == 0`, which
-- means it doesn't add any information.
RedundantEq :: DepError v n
-- | An empty system of equations.
noDeps :: Dependencies v n
-- | addEquation d e: Add the equation e = 0 to the
-- system d.
addEquation :: (Hashable n, Hashable v, RealFrac (Phase n), Ord v, Floating n) => Dependencies v n -> Expr v n -> Either (DepError v n) (Dependencies v n)
-- | Eliminate an variable from the equations. Returns the eliminated
-- equations. Before elimination it performs substitution to minimize the
-- number of eliminated equations.
--
-- Important: this function is still experimental and mostly
-- untested.
eliminate :: (Hashable n, Show n, Hashable v, RealFrac (Phase n), Ord v, Show v, Floating n) => Dependencies v n -> v -> (Dependencies v n, [Expr v n])
-- | Return the value of the variable, or a list of variables it depends
-- on. Only linear dependencies are shown.
getKnown :: (Eq v, Hashable v) => v -> Dependencies v n -> Either [v] n
-- | Return all known variables.
knownVars :: Dependencies v n -> [(v, n)]
-- | Return True if the variable is known or dependend.
varDefined :: (Eq v, Hashable v) => v -> Dependencies v n -> Bool
-- | Return all nonlinear equations e_i, where e_i = 0.
nonlinearEqs :: (Ord n, Ord v, Floating n) => Dependencies v n -> [Expr v n]
-- | Return all dependend variables with their dependencies.
dependendVars :: Eq n => Dependencies v n -> [(v, LinExpr v n)]
-- | Make the expressions on both sides equal
(===) :: (MonadState (Dependencies v n) m, MonadError (DepError v n) m, Eq v, Hashable v, Hashable n, RealFrac n, Floating n, Ord v) => Expr v n -> Expr v n -> m ()
-- | Make the pairs of expressions on both sides equal. No error is
-- signaled if the equation for one of the sides is Redundant
-- for example in (x, 0) == (y, 0).
(=&=) :: (MonadState (Dependencies v n) m, MonadError (DepError v n) m, Eq v, Hashable v, Hashable n, RealFrac n, Floating n, Ord v) => (Expr v n, Expr v n) -> (Expr v n, Expr v n) -> m ()
-- | Get the dependencies from a state monad. Specialized version of
-- get.
dependencies :: MonadState (Dependencies v n) m => m (Dependencies v n)
-- | Return the value of the variable or throw an error.
getValue :: (MonadState (Dependencies v n) m, MonadError (DepError v n) m, Eq v, Hashable v) => v -> m n
-- | Monadic version of getKnown.
getKnownM :: (MonadState (Dependencies v n) m, Hashable v, Eq v) => v -> m (Either [v] n)
-- | Monadic version of varDefined.
varDefinedM :: (MonadState (Dependencies v n) m, Hashable v, Eq v) => v -> m Bool
-- | Monadic version of eliminate.
eliminateM :: (MonadState (Dependencies v n) m, Hashable n, Hashable v, Show n, Show v, RealFrac n, Ord v, Floating n) => v -> m [Expr v n]
-- | Succeed even when trowing a RedundantEq error.
ignore :: MonadError (DepError v n) m => m () -> m ()
-- | A monad for solving equations. Basicly just a state and exception
-- monad over Dependencies and DepError.
type MFSolver v n a = MFSolverT v n Identity a
-- | run the solver.
runSolver :: MFSolver v n a -> Dependencies v n -> Either (DepError v n) (a, Dependencies v n)
-- | Return the result of solving the equations or an error.
evalSolver :: MFSolver v n a -> Dependencies v n -> Either (DepError v n) a
-- | Run the solver and return the dependencies or an error.
execSolver :: MFSolver v n a -> Dependencies v n -> Either (DepError v n) (Dependencies v n)
-- | Return the result of solving the equations, or throw the error as an
-- exception.
unsafeSolve :: (Typeable n, Typeable v, Show n, Show v) => Dependencies v n -> MFSolver v n a -> a
-- | Show all variables and equations. Useful in combination with
-- execSolver.
showVars :: (Show n, Show v, Ord n, Ord v, Floating n) => Either (DepError v n) (Dependencies v n) -> IO ()
-- | A monad transformer for solving equations. Basicly just a state and
-- exception monad transformer over Dependencies and
-- DepError.
data MFSolverT v n m a
runSolverT :: MFSolverT v n m a -> Dependencies v n -> m (Either (DepError v n) (a, Dependencies v n))
-- | Return the result of solving the equations or an error. Monadic
-- version.
evalSolverT :: Functor f => MFSolverT v n f b -> Dependencies v n -> f (Either (DepError v n) b)
-- | Run the solver and return the dependencies or an error. Monadic
-- version.
execSolverT :: Functor m => MFSolverT v n m a -> Dependencies v n -> m (Either (DepError v n) (Dependencies v n))
-- | Return the result of solving the equations, or throw the error as an
-- exception. Monadic version.
unsafeSolveT :: (Show n, Show v, Typeable n, Typeable v, Monad m) => Dependencies v n -> MFSolverT v n m a -> m a
instance Typeable DepError
instance Eq BinaryOp
instance Eq UnaryOp
instance Generic UnaryOp
instance Eq SimpleVar
instance Ord SimpleVar
instance Generic SimpleVar
instance Generic (LinExpr v n)
instance (Eq v, Eq n) => Eq (LinExpr v n)
instance (Show v, Show n) => Show (LinExpr v n)
instance Generic (NonLinExpr v n)
instance Generic (Expr v n)
instance Functor m => Functor (MFSolverT v n m)
instance (Monad m, Functor m) => Applicative (MFSolverT v n m)
instance Monad m => Monad (MFSolverT v n m)
instance MonadIO m => MonadIO (MFSolverT v n m)
instance Monad m => MonadState (Dependencies v n) (MFSolverT v n m)
instance Monad m => MonadError (DepError v n) (MFSolverT v n m)
instance MonadReader s m => MonadReader s (MFSolverT v n m)
instance MonadWriter s m => MonadWriter s (MFSolverT v n m)
instance MonadCont m => MonadCont (MFSolverT v n m)
instance Datatype D1UnaryOp
instance Constructor C1_0UnaryOp
instance Constructor C1_1UnaryOp
instance Constructor C1_2UnaryOp
instance Constructor C1_3UnaryOp
instance Constructor C1_4UnaryOp
instance Constructor C1_5UnaryOp
instance Constructor C1_6UnaryOp
instance Constructor C1_7UnaryOp
instance Constructor C1_8UnaryOp
instance Constructor C1_9UnaryOp
instance Constructor C1_10UnaryOp
instance Constructor C1_11UnaryOp
instance Constructor C1_12UnaryOp
instance Constructor C1_13UnaryOp
instance Constructor C1_14UnaryOp
instance Constructor C1_15UnaryOp
instance Datatype D1SimpleVar
instance Constructor C1_0SimpleVar
instance Datatype D1LinExpr
instance Constructor C1_0LinExpr
instance Datatype D1NonLinExpr
instance Constructor C1_0NonLinExpr
instance Constructor C1_1NonLinExpr
instance Constructor C1_2NonLinExpr
instance Datatype D1Expr
instance Constructor C1_0Expr
instance (Show n, Show v) => Show (DepError v n)
instance (Show n, Floating n, Ord n, Ord v, Show v) => Show (Dependencies v n)
instance (Floating n, Ord n, Ord v) => Floating (Expr v n)
instance (Floating n, Ord n, Ord v) => Fractional (Expr v n)
instance (Floating n, Ord n, Ord v) => Num (Expr v n)
instance Show UnaryOp
instance Show BinaryOp
instance (Show v, Ord n, Show n, Num n, Eq n) => Show (SimpleExpr v n)
instance MonadTrans (MFSolverT v n)
instance (Ord n, Num n, Eq n, Show v, Show n) => Show (Expr v n)
instance (Show v, Show n, Typeable v, Typeable n) => Exception (DepError v n)
instance Show SimpleVar
instance Hashable SimpleVar
instance (Hashable v, Hashable n) => Hashable (Expr v n)
instance Hashable UnaryOp
instance (Hashable v, Hashable n) => Hashable (NonLinExpr v n)
instance (Hashable v, Hashable n) => Hashable (LinExpr v n)