In pure functional languages, is there an algorithm to get the inverse function?

前端 未结 10 1225
野的像风
野的像风 2020-12-04 06:10

In pure functional languages like Haskell, is there an algorithm to get the inverse of a function, (edit) when it is bijective? And is there a specific way to program your f

10条回答
  •  生来不讨喜
    2020-12-04 06:39

    In some cases, it is possible to find the inverse of a bijective function by converting it into a symbolic representation. Based on this example, I wrote this Haskell program to find inverses of some simple polynomial functions:

    bijective_function x = x*2+1
    
    main = do
        print $ bijective_function 3
        print $ inverse_function bijective_function (bijective_function 3)
    
    data Expr = X | Const Double |
                Plus Expr Expr | Subtract Expr Expr | Mult Expr Expr | Div Expr Expr |
                Negate Expr | Inverse Expr |
                Exp Expr | Log Expr | Sin Expr | Atanh Expr | Sinh Expr | Acosh Expr | Cosh Expr | Tan Expr | Cos Expr |Asinh Expr|Atan Expr|Acos Expr|Asin Expr|Abs Expr|Signum Expr|Integer
           deriving (Show, Eq)
    
    instance Num Expr where
        (+) = Plus
        (-) = Subtract
        (*) = Mult
        abs = Abs
        signum = Signum
        negate = Negate
        fromInteger a = Const $ fromIntegral a
    
    instance Fractional Expr where
        recip = Inverse
        fromRational a = Const $ realToFrac a
        (/) = Div
    
    instance Floating Expr where
        pi = Const pi
        exp = Exp
        log = Log
        sin = Sin
        atanh = Atanh
        sinh = Sinh
        cosh = Cosh
        acosh = Acosh
        cos = Cos
        tan = Tan
        asin = Asin
        acos = Acos
        atan = Atan
        asinh = Asinh
    
    fromFunction f = f X
    
    toFunction :: Expr -> (Double -> Double)
    toFunction X = \x -> x
    toFunction (Negate a) = \a -> (negate a)
    toFunction (Const a) = const a
    toFunction (Plus a b) = \x -> (toFunction a x) + (toFunction b x)
    toFunction (Subtract a b) = \x -> (toFunction a x) - (toFunction b x)
    toFunction (Mult a b) = \x -> (toFunction a x) * (toFunction b x)
    toFunction (Div a b) = \x -> (toFunction a x) / (toFunction b x)
    
    
    with_function func x = toFunction $ func $ fromFunction x
    
    simplify X = X
    simplify (Div (Const a) (Const b)) = Const (a/b)
    simplify (Mult (Const a) (Const b)) | a == 0 || b == 0 = 0 | otherwise = Const (a*b)
    simplify (Negate (Negate a)) = simplify a
    simplify (Subtract a b) = simplify ( Plus (simplify a) (Negate (simplify b)) )
    simplify (Div a b) | a == b = Const 1.0 | otherwise = simplify (Div (simplify a) (simplify b))
    simplify (Mult a b) = simplify (Mult (simplify a) (simplify b))
    simplify (Const a) = Const a
    simplify (Plus (Const a) (Const b)) = Const (a+b)
    simplify (Plus a (Const b)) = simplify (Plus (Const b) (simplify a))
    simplify (Plus (Mult (Const a) X) (Mult (Const b) X)) = (simplify (Mult (Const (a+b)) X))
    simplify (Plus (Const a) b) = simplify (Plus (simplify b) (Const a))
    simplify (Plus X a) = simplify (Plus (Mult 1 X) (simplify a))
    simplify (Plus a X) = simplify (Plus (Mult 1 X) (simplify a))
    simplify (Plus a b) = (simplify (Plus (simplify a) (simplify b)))
    simplify a = a
    
    inverse X = X
    inverse (Const a) = simplify (Const a)
    inverse (Mult (Const a) (Const b)) = Const (a * b)
    inverse (Mult (Const a) X) = (Div X (Const a))
    inverse (Plus X (Const a)) = (Subtract X (Const a))
    inverse (Negate x) = Negate (inverse x)
    inverse a = inverse (simplify a)
    
    inverse_function x = with_function inverse x
    

    This example only works with arithmetic expressions, but it could probably be generalized to work with lists as well. There are also several implementations of computer algebra systems in Haskell that may be used to find the inverse of a bijective function.

提交回复
热议问题