Haskell 哈斯克尔-牛顿法

Haskell 哈斯克尔-牛顿法,haskell,newtons-method,Haskell,Newtons Method,我试图在haskell中实现Newton方法,但每次都以“Stackoverflow”异常结束。。我花了很多时间,却没有找到解决办法- data Term = Monom(Integer, Integer) | Add(Term, Term) | Mul(Term, Term) | Div(Term, Term); iterate :: (a -> a) -> a -> [a] iterate f a0

我试图在haskell中实现Newton方法,但每次都以“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
数据项=Monom(整数,整数)
|添加(期限,期限)
|Mul(任期,任期)
|部门(任期、任期);
迭代::(a->a)->a->[a]
迭代f a0=a0:(Main.iterate f(f(a0)))
stop1::Float->[Float]->Float
stop1 eps(a1:(a2:as))
|abs(a1-a2)浮动->浮动
--步骤1 f'a=a-(f'a)/(f'a)
步骤1 f a=a-(评估f a)/(评估(差异f)a)
--牛顿::(浮动->浮动)->(浮动->浮动)->浮动->浮动->浮动
牛顿:术语->浮点数->浮点数->浮点数
牛顿f a0每股收益=停止1每股收益(Main.iterate(step1 f)a0)
四元(单体(a,b))=单体(a*a,b*b)
术语->术语
diff(monm(a,b))=如果b>0,那么monm(a*b,b-1)或者monm(0,0)
微分(加(x,y))=加(微分(x,微分(y))
diff(Mul(x,y))=添加(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(单体(a,b))f=(evalMonom(单体(a,b))f)
eval(加上单数(a,b),单数(c,d))f=(evalMonom(单数(a,b))f)+(evalMonom(单数(c,d))f)
eval(Mul(单体(a,b),单体(c,d)))f=(evalMonom(单体(a,b))f)*(evalMonom(单体(c,d))f)
eval(Div(单体(a,b),单体(c,d))f=(evalMonom(单体(a,b))f)/(evalMonom(单体(c,d))f)
evalMonom::Term->Float->Float
evalMonom(Monom(a,b))x=fromInteger(a)*fromInteger(pow(toInt(x))b)
整数->整数->整数
功率x 0=1
功率x n=x*功率x(n-1)
toInt::浮点->整数
toInt x=圆形x
我假设问题可能在pow函数中,但我不确定。。
提前感谢您的帮助

我还没有看完所有的代码,但是当
b<0
调用
b<0
时,
pow a b
将绝对以无限递归结束,如果使用
b<0
调用它的话,
。。。你可以试着抓住这个案例,然后给出你可以解释的答案,以检查这是否是正在发生的事情……无论如何,你为什么要首先自己实现
pow
?如果
n
为正,则使用与之完全相同的方法(对于较大的ish指数,只需更快),如果
n为负,则不会发散。同时说明您是如何遇到该问题的。没有例子。@leftaroundabout:将pow更改为^1表示“没有因使用^而产生的(整数浮点)实例”,我还没有看完所有代码,但是当
b<0
b<0
调用
b<0
时,如果使用
b<0
调用它,那么
pow a b
很可能抛出该异常。。。你可以试着抓住这个案例,然后给出你可以解释的答案,以检查这是否是正在发生的事情……无论如何,你为什么要首先自己实现
pow
?如果
n
为正,则使用与之完全相同的方法(对于较大的ish指数,只需更快),如果
n为负,则不会发散。同时说明您是如何遇到该问题的。没有例子。@leftaroundabout:将pow更改为“^”表示“没有因使用“^”而产生的(整数浮点)实例”