Haskell牛顿法

时间:2017-07-12 11:51:52

标签: haskell newtons-method

我试图在haskell中实现牛顿方法,但我每次都在" Stackoverflow"例外..我花了很多时间没有解决方案.. -.-

data Term = Monom(Integer, Integer)
            | Add(Term, Term)
            | Mul(Term, Term)
            | Div(Term, Term);

iterate :: (a -> a) -> a -> [a]
iterate f a0 = a0 : (Main.iterate f (f(a0)))

stop1 :: Float -> [Float] -> Float
stop1 eps (a1 : (a2:as))
  | abs(a1-a2) < eps = a2
  | otherwise = stop1 eps (a2:as)

step1 :: Term -> Float -> Float
--step1 f f' a = a - (f a) / (f' a)
step1 f a = a - (eval f a) / (eval (diff f) a)

--newton :: (Float -> Float) -> (Float -> Float) -> Float -> Float -> Float
newton :: Term -> Float -> Float -> Float
newton f a0 eps = stop1 eps (Main.iterate (step1 f) a0)

quadrieren (Monom(a,b)) = Monom(a*a, b*b)

diff :: Term -> Term
diff (Monom(a,b)) = if b>0 then Monom(a*b, b-1) else Monom(0,0)                
diff (Add(x,y)) = Add(diff(x), diff(y))                                        
diff (Mul(x,y)) = Add(Mul(diff(x), y), Mul(diff(y), x))                        
diff (Div(x,y)) = Div(Add(Mul(diff(x), y), Mul(diff(y), x)), quadrieren(y)) 

eval :: Term -> Float -> Float
eval (Monom(a,b)) f = (evalMonom (Monom(a,b)) f)
eval (Add(Monom(a,b), Monom(c,d))) f = (evalMonom (Monom(a,b)) f) + (evalMonom (Monom(c,d)) f)
eval (Mul(Monom(a,b), Monom(c,d))) f = (evalMonom (Monom(a,b)) f) * (evalMonom (Monom(c,d)) f)
eval (Div(Monom(a,b), Monom(c,d))) f = (evalMonom (Monom(a,b)) f) / (evalMonom (Monom(c,d)) f)

evalMonom :: Term -> Float -> Float
evalMonom (Monom(a,b)) x = fromInteger(a) * fromInteger(pow (toInt(x)) b)

pow :: Integer -> Integer -> Integer 
pow x 0 = 1
pow x n = x * pow x (n-1)

toInt :: Float -> Integer
toInt x = round x

我认为问题可能在于pow功能,但我不确定.. 提前感谢您的帮助!

0 个答案:

没有答案