-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Equation solver and calculator à la metafont -- @package mfsolve @version 0.1.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. -- --
-- let [x, y, t, a] = map (makeVariable . SimpleVar) ["x", "y", "t", "a"] ---- -- Solve linear equations: -- --
-- showVars $ solveEqs emptyDeps -- [ 2*x + y === 5, -- x - y === 1] ---- --
-- x = 2.0 -- y = 1.0 ---- -- Solve for angle (pi/4): -- --
-- showVars $ solveEqs emptyDeps -- [ sin(t) === 1/sqrt(2) ] ---- --
-- t = 0.7853981633974484 ---- -- Solve for angle (pi/3) and amplitude: -- --
-- showVars $ solveEqs emptyDeps -- [ a*sin(x) === sqrt 3, -- a*cos(x) === 1 ] ---- --
-- x = 1.0471975511965979 -- a = 2.0 ---- -- Allow nonlinear expression with unknown variables: -- --
-- showVars $ solveEqs emptyDeps -- [ sin(sqrt(x)) === y, -- x === 2] ---- --
-- x = 2.0 -- y = 0.9877659459927355 ---- -- Find the angle and amplitude when using a rotation matrix: -- --
-- showVars $ solveEqs emptyDeps -- [ 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 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 -- | An mathematical expression of several variables. 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 -- | An opaque datatype containing the dependencies of each variable. A -- variable who's dependency is just a number is called known. A -- variables which depends on other variables is called dependend. -- A variable which is neither known or dependend is called -- independend. A variable can only depend on other -- independend variables. It also contains nonlinear equations -- which it couldn't reduce to a linear equation yet. data Dependencies v n -- | An error type for ===, =&= and solveEq: data DepError n -- | InconsistentEq a: 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 n -- | RedundantEq: The equation was reduced to the redundant equation -- 0 == 0, which means it doesn't add any information. RedundantEq :: DepError n newtype SimpleVar SimpleVar :: String -> SimpleVar -- | Return the value of the variable, or a list of variables it depends -- on. Only linear dependencies are shown. getKnown :: (Eq v, Hashable v) => Dependencies v n -> v -> 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) => Dependencies v n -> v -> Bool -- | Give all nonlinear equations as an Expr equal to 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)] -- | Convert an Expr to a SimpleExpr. simpleExpr :: (Num n, Eq n) => Expr v n -> SimpleExpr v n -- | An empty set of dependencies. emptyDeps :: Dependencies v n -- | Create an expression from a variable makeVariable :: Num n => v -> Expr v n -- | Create an expression from a constant makeConstant :: n -> Expr v n -- | Make the expressions on both sides equal, and add the result to the -- Set of dependencies. (===) :: (Hashable n, Hashable v, RealFrac (Phase n), Ord v, Floating n) => Expr v n -> Expr v n -> Dependencies v n -> Either (DepError n) (Dependencies v n) -- | Make the pairs of expressions on both sides equal, and add the result -- to the Set of dependencies. No error is signaled if the equation for -- one of the sides is redundant for example in (x, 0) == (y, 0). (=&=) :: (Hashable n, Hashable v, RealFrac (Phase n), Ord v, Floating n) => (Expr v n, Expr v n) -> (Expr v n, Expr v n) -> Dependencies v n -> Either (DepError n) (Dependencies v n) -- | Solve a list of equations in order. Returns either a new set of -- dependencies, or signals an error. solveEqs :: Dependencies v n -> [Dependencies v n -> Either (DepError n) (Dependencies v n)] -> Either (DepError n) (Dependencies v n) -- | Show all variables and equations. showVars :: (Show n, Show v, Show a, Ord n, Ord v, Floating n) => Either (DepError a) (Dependencies v n) -> IO () 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 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 (DepError 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 (Ord n, Num n, Eq n, Show v, Show n) => Show (Expr v n) instance Show SimpleVar instance Hashable SimpleVar instance (Hashable v, Hashable n) => Hashable (Expr v n) instance Hashable UnaryOp instance Hashable n => Hashable (UnaryFun n) instance (Hashable v, Hashable n) => Hashable (NonLinExpr v n) instance (Hashable v, Hashable n) => Hashable (LinExpr v n)