-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Equation solver and calculator à la metafont -- -- An equation solver and calculator in the spirit of Metafont. -- -- 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. @package mfsolve @version 0.3.2.2 -- | 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 -- | sine Sin :: UnaryOp -- | cosine Cos :: UnaryOp -- | absolute value Abs :: UnaryOp -- | reciprocal (1/x) Recip :: UnaryOp -- | sign Signum :: UnaryOp -- | natural exponential (e^x) Exp :: UnaryOp -- | natural logarithm (log x) Log :: UnaryOp -- | hyperbolic cosine Cosh :: UnaryOp -- | inverse hyperbolic tangent Atanh :: UnaryOp -- | tangent Tan :: UnaryOp -- | hyperbolic tangent Tanh :: UnaryOp -- | hyperbolic sine Sinh :: UnaryOp -- | inverse sine Asin :: UnaryOp -- | inverse cosine Acos :: UnaryOp -- | inverse hyperbolic sine Asinh :: UnaryOp -- | inverse hyperbolic cosine Acosh :: UnaryOp -- | inverse tangent Atan :: UnaryOp data BinaryOp -- | Addition Add :: BinaryOp -- | Multiplication 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 -- | map a simple expression using the given substitution. mapSimple :: (Floating m, Floating n) => (n -> m) -> (v -> u) -> SimpleExpr v n -> SimpleExpr u m -- | map an expression using the given substitution. mapExpr :: (Floating m, Floating n, Ord u, Ord v, Eq n, Ord m) => (n -> m) -> (v -> u) -> Expr v n -> Expr u m -- | 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: -- -- -- -- 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 -> Expr v n -> DepError v n -- | The equation was reduced to the redundant equation `0 == 0`, which -- means it doesn't add any information. RedundantEq :: Expr v n -> 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 () infixr 1 === -- | 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 () infixr 1 =&= -- | 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, Ord n, Num n) => 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 :: (Num n, Ord n, Show n, Show v, Typeable n, Typeable v, Monad m) => Dependencies v n -> MFSolverT v n m a -> m a instance GHC.Classes.Eq Math.MFSolve.BinaryOp instance GHC.Generics.Generic Math.MFSolve.UnaryOp instance GHC.Classes.Eq Math.MFSolve.UnaryOp instance GHC.Generics.Generic Math.MFSolve.SimpleVar instance GHC.Classes.Ord Math.MFSolve.SimpleVar instance GHC.Classes.Eq Math.MFSolve.SimpleVar instance (GHC.Show.Show n, GHC.Show.Show v) => GHC.Show.Show (Math.MFSolve.LinExpr v n) instance (GHC.Classes.Eq n, GHC.Classes.Eq v) => GHC.Classes.Eq (Math.MFSolve.LinExpr v n) instance GHC.Generics.Generic (Math.MFSolve.LinExpr v n) instance GHC.Generics.Generic (Math.MFSolve.Expr v n) instance (GHC.Classes.Eq n, GHC.Classes.Eq v) => GHC.Classes.Eq (Math.MFSolve.Expr v n) instance GHC.Generics.Generic (Math.MFSolve.NonLinExpr v n) instance (GHC.Classes.Eq v, GHC.Classes.Eq n) => GHC.Classes.Eq (Math.MFSolve.NonLinExpr v n) instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (Math.MFSolve.MFSolverT v n m) instance Control.Monad.Writer.Class.MonadWriter s m => Control.Monad.Writer.Class.MonadWriter s (Math.MFSolve.MFSolverT v n m) instance Control.Monad.Reader.Class.MonadReader s m => Control.Monad.Reader.Class.MonadReader s (Math.MFSolve.MFSolverT v n m) instance GHC.Base.Monad m => Control.Monad.Error.Class.MonadError (Math.MFSolve.DepError v n) (Math.MFSolve.MFSolverT v n m) instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (Math.MFSolve.Dependencies v n) (Math.MFSolve.MFSolverT v n m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Math.MFSolve.MFSolverT v n m) instance GHC.Base.Monad m => GHC.Base.Monad (Math.MFSolve.MFSolverT v n m) instance GHC.Base.Monad m => GHC.Base.Applicative (Math.MFSolve.MFSolverT v n m) instance GHC.Base.Functor m => GHC.Base.Functor (Math.MFSolve.MFSolverT v n m) instance Control.Monad.Trans.Class.MonadTrans (Math.MFSolve.MFSolverT v n) instance (GHC.Classes.Ord n, GHC.Num.Num n, GHC.Show.Show v, GHC.Show.Show n, Data.Typeable.Internal.Typeable v, Data.Typeable.Internal.Typeable n) => GHC.Exception.Type.Exception (Math.MFSolve.DepError v n) instance (GHC.Num.Num n, GHC.Classes.Ord n, GHC.Show.Show n, GHC.Show.Show v) => GHC.Show.Show (Math.MFSolve.DepError v n) instance (GHC.Show.Show n, GHC.Float.Floating n, GHC.Classes.Ord n, GHC.Classes.Ord v, GHC.Show.Show v) => GHC.Show.Show (Math.MFSolve.Dependencies v n) instance (Data.Hashable.Class.Hashable v, Data.Hashable.Class.Hashable n) => Data.Hashable.Class.Hashable (Math.MFSolve.NonLinExpr v n) instance (Data.Hashable.Class.Hashable v, Data.Hashable.Class.Hashable n) => Data.Hashable.Class.Hashable (Math.MFSolve.Expr v n) instance (GHC.Classes.Ord n, GHC.Num.Num n, GHC.Classes.Eq n, GHC.Show.Show v, GHC.Show.Show n) => GHC.Show.Show (Math.MFSolve.Expr v n) instance (GHC.Float.Floating n, GHC.Classes.Ord n, GHC.Classes.Ord v) => GHC.Num.Num (Math.MFSolve.Expr v n) instance (GHC.Float.Floating n, GHC.Classes.Ord n, GHC.Classes.Ord v) => GHC.Real.Fractional (Math.MFSolve.Expr v n) instance (GHC.Float.Floating n, GHC.Classes.Ord n, GHC.Classes.Ord v) => GHC.Float.Floating (Math.MFSolve.Expr v n) instance (Data.Hashable.Class.Hashable v, Data.Hashable.Class.Hashable n) => Data.Hashable.Class.Hashable (Math.MFSolve.LinExpr v n) instance Data.Hashable.Class.Hashable Math.MFSolve.SimpleVar instance GHC.Show.Show Math.MFSolve.SimpleVar instance (GHC.Show.Show v, GHC.Classes.Ord n, GHC.Show.Show n, GHC.Num.Num n, GHC.Classes.Eq n) => GHC.Show.Show (Math.MFSolve.SimpleExpr v n) instance Data.Hashable.Class.Hashable Math.MFSolve.UnaryOp instance GHC.Show.Show Math.MFSolve.UnaryOp instance GHC.Show.Show Math.MFSolve.BinaryOp