Heron's method in haskell - haskell

I'm getting divide by zero exceptions in this code of heron's method, and I am kind of lost here.
epsilon:: Integral a => a
epsilon = 1
heron:: Integral a => a -> a
heron r = help 0
where
help x
| abs (heron' x - heron' (x + 1)) < epsilon = heron' (x + 1)
| otherwise = help (x + 1)
heron' 0 = 1
heron' x = (1 `div` 2) * (heron' (x-1) + (r `div` heron' (x-1)))
Any suggestions where in this code I have to look to solve this problem?
(1 `div` 2) is definitely a problem , but what do I need to write instead?

If you need division of this kind, you probably want to use (/) instead of div and Fractional instead of Integral. So:
epsilon:: Fractional a => a
epsilon = 1
heron:: (Fractional a, Ord a) => a -> a
heron r = help 0
where
help x
| abs (heron' x - heron' (x + 1)) < epsilon = heron' (x + 1)
| otherwise = help (x + 1)
heron' 0 = 1
heron' x = (1 / 2) * (heron' (x-1) + (r / heron' (x-1)))

Related

How do I get the sums of digits of the negative large number in Haskell?

sumOfDigitsPosNeg x =
if x == 0 then 0
else if x < 0 then sumOfDigitsPosNeg ((-1)*x `div` 10) + mod ((-1)*x) 10
else sumOfDigitsPosNeg (x `div` 10) + mod x 10
I've tried with these code, but if the input is more than one digit, the output is wrong. I'm just confused how to convert the negative numbers into positive. How do I approach this problem?
Using abs this is quite easy. We just operate on the absolute value of the number input.
sumDigits :: Integral t => t -> t
sumDigits 0 = 0
sumDigits n = a `mod` 10 + sumDigits (a `div` 10)
where a = abs n
You can work with a helper go function that will only retrieve the absolute value. We thus call go with the abs :: Num a => a -> a of the item:
sumOfDigitsPosNeg :: Integral a => a -> a
sumOfDigitsPosNeg = go . abs
where go 0 = 0
go n = r + go q
where (q, r) = quotRem n 10

Why does this recursive function for square-roots give the wrong result?

I made this tail-recursive function for computing square roots:
sqrt x n a = if n == 0 then a else sqrt x (n - 1) (a + x/a)/2
For some reason, it gives the wrong result when n is greater than 1, meaning when it's asked to improve the approximation, a, more than once. It returns a number that's closer and closer to 0 as n grows. I tried implementing the same recursive formula in different ways like this:
sqrt x n = if n == 0 then 1 else (a + x/a)/2 where a = sqrt x (n - 1)
sqrt x = 1:map (\a -> (a + x/a)/2) (sqrt x)
And that all works fine. It's only the first example that doesn't work and I can't figure out why, as much as I try.
The expression:
sqrt x n a = if n == 0 then a else sqrt x (n - 1) (a + x/a) / 2
is parsed as:
sqrt x n a = if n == 0 then a else (sqrt x (n - 1) (a + x/a)) / 2
So the sqrt x (n-1) (a+x/a) is seen as the numerator of a division by two. You should add brackets here:
sqrt x n a = if n == 0 then a else sqrt x (n - 1) ((a + x/a) / 2)
With the given, fix, we can for example calculate the square root of five as:
Prelude> sqrt 5 10 1
2.23606797749979
According to Wikipedia, it is:
2.23606797749978969640917366873127623544061835961152572427089…
so this is already quite close.

Weird behavior of (^) in Haskell

Why does GHCi give incorrect answer below?
GHCi
λ> ((-20.24373193905347)^12)^2 - ((-20.24373193905347)^24)
4.503599627370496e15
Python3
>>> ((-20.24373193905347)**12)**2 - ((-20.24373193905347)**24)
0.0
UPDATE
I would implement Haskell's (^) function as follows.
powerXY :: Double -> Int -> Double
powerXY x 0 = 1
powerXY x y
| y < 0 = powerXY (1/x) (-y)
| otherwise =
let z = powerXY x (y `div` 2)
in if odd y then z*z*x else z*z
main = do
let x = -20.24373193905347
print $ powerXY (powerXY x 12) 2 - powerXY x 24 -- 0
print $ ((x^12)^2) - (x ^ 24) -- 4.503599627370496e15
Although my version doesn't appear any more correct than the one provided below by #WillemVanOnsem, it strangely gives the correct answer for this particular case at least.
Python is similar.
def pw(x, y):
if y < 0:
return pw(1/x, -y)
if y == 0:
return 1
z = pw(x, y//2)
if y % 2 == 1:
return z*z*x
else:
return z*z
# prints 0.0
print(pw(pw(-20.24373193905347, 12), 2) - pw(-20.24373193905347, 24))
Short answer: there is a difference between (^) :: (Num a, Integral b) => a -> b -> a and (**) :: Floating a => a -> a -> a.
The (^) function works only on integral exponents. It will normally make use of an iterative algorithm that will each time check if the power is divisible by two, and divide the power by two (and if non-divisible multiply the result with x). This thus means that for 12, it will perform a total of six multiplications. If a multiplication has a certain rounding-off error, that error can "explode". As we can see in the source code, the (^) function is implemented as:
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
The (**) function is, at least for Floats and Doubles implemented to work on the floating point unit. Indeed, if we take a look at the implementation of (**), we see:
instance Floating Float where
-- …
(**) x y = powerFloat x y
-- …
This thus redirect to the powerFloat# :: Float# -> Float# -> Float# function, which will, normally be linked to the corresponding FPU operation(s) by the compiler.
If we use (**) instead, we obtain zero as well for a 64-bit floating point unit:
Prelude> (a**12)**2 - a**24
0.0
We can for example implement the iterative algorithm in Python:
def pw(x0, y0):
if y0 < 0:
raise Error()
if y0 == 0:
return 1
return f(x0, y0)
def f(x, y):
if (y % 2 == 0):
return f(x*x, y//2)
if y == 1:
return x
return g(x*x, y // 2, x)
def g(x, y, z):
if (y % 2 == 0):
return g(x*x, y//2, z)
if y == 1:
return x*z
return g(x*x, y//2, x*z)
If we then perform the same operation, I get locally:
>>> pw(pw(-20.24373193905347, 12), 2) - pw(-20.24373193905347, 24)
4503599627370496.0
Which is the same value as what we get for (^) in GHCi.

why do I get a type error here?

I'm sitting on this for over 4 hours and can't wrap my head aroud it.
I try to run the following code:
top = 100 :: Int
couplesToOne num
|num<0 = error "num<0"
|num==0 = 0
|num `mod` 2 == 0 = num `div` 2
|num `mod` 2 == 1 = (num+1) `div` 2
|otherwise = error "otherwise"
numInBig n bigSide
|(bigSide^2 <= n) = couplesToOne (n-1)
|(bigSide^2 > n) = couplesToOne (n-1) - (couplesToOne (floor(sqrt(bigSide^2 - n))))
|otherwise = error "otherwise"
ans = map (numInBig top) [3..((div top 4) + 1)]
and I get the following error message:
No instance for (RealFrac Int) arising from a use of `numInBig'
In the first argument of `map', namely `(numInBig top)'
In the expression: map (numInBig top) [3 .. ((div top 4) + 1)]
In an equation for `ans':
ans = map (numInBig top) [3 .. ((div top 4) + 1)]
enter code here
I figured out (probably?) that this is because of the "sqrt" that returns a float but that's why I added the floor that's supposed to return an Integral.
can you please help me?
This works:
top = 100 :: Int
couplesToOne num
|num<0 = error "num<0"
|num==0 = 0
|num `mod` 2 == 0 = num `div` 2
|num `mod` 2 == 1 = (num+1) `div` 2
|otherwise = error "otherwise"
numInBig n bigSide
|(bigSide^2 <= n) = couplesToOne (n-1)
|(bigSide^2 > n) = couplesToOne (n-1) - couplesToOne (floor(sqrt(fromIntegral(bigSide^2 - n))))
|otherwise = error "otherwise"
ans = map (numInBig top) [3..((div top 4) + 1)]
You need an extra fromIntegral because sqrt::Floating a => a -> a is not defined on Int.
> ans
[50,50,50,50,50,50,50,50,48,47,46,45,44,44,43,43,42,41,41]

How can I calculate Σ_{i=m}^n (m+i)^n?

I'm currently trying to calculate the following sum:
sum2015 :: Integer->Integer->Integer
sum2015 m n
| m>n = 0
| otherwise = (m+m)^n + sum2015 (m+1) n
As an example, sum2015 0 1 should return 1. However, it returns 2. What did I do wrong?
You're not calculating that sum. Note that m in (m + i)^n must stay fixed, but you use a new m here:
| otherwise = … + sum2015 (m+1) n
-- ^^^^^
-- oh oh
Therefore you get:
sum2015 0 1
= (0 + 0)^1 + sum2015 (0 + 1) 1
= (0 + 0)^1 + (1 + 1)^1 + sum2015 (1 + 1) 1
= (0 + 0)^1 + (1 + 1)^1 + 0
= 0 + 2
= 2
Instead, calculate all (m + i)^n and sum them afterwards:
sum2015 :: Integer -> Integer -> Integer
sum2015 m n = sum . map (\i -> (m + i) ^ n) $ [m..n]
Or, if you're not allowed to use that, use a worker:
sum2015 :: Integer -> Integer -> Integer
sum2015 m n = go m
where go i = ...
I can offer this option:
sum2015 m n = sum [(m + i) ** n | i <- [m..n]]
Firstly, I created list of numbers from m to n "[m..n]".
After for each i in this list, I computing terms of the sum.
Finally, just use "sum" function for obtained result list.
'**' - Pow function

Resources