Majority logic decoding Haskell - haskell

I have to calculate the probability of the proper decoding of a bit copied n times.
The following formula is supposed to be the answer:
In Haskell, I coded it as follows:
fac 1 = 1
fac n = fac (n-1) * n
--prob :: (Integral b, Fractional b) => (b, b) -> b
--prob :: (Int,Int) -> Double
prob (n, k)
| n==k = (0.01**k)
| otherwise = factor (n, k) * (0.01 ** k) * (0.99**(n-k)) + prob (n, (k+1))
where
factor (n, k) = (fac n / ((fac k)* (fac n-k)))
1 - prob (3,2) gives the result 0.99992575, which is incorrect, as it should be 0.99970. Does anyone know where I went wrong?

The reason is function precedence.
if you would look into the definition of prob you will see this:
(fac n-k)
because function application has the most precedence this is parsed as
((fac n) - k)
so your code should be
(fac (n-k))
which gives a result of 0.999702 on my computer.

These are a couple of best-practices the code is lacking. I infact already answered the question itself.
1- do not use tuples as input. in Haskell, functions can have multiple parameters. the syntax is f x y for calling f on x and y. the types also have similar syntax. this transforms your code to:
fac 1 = 1
fac n = fac (n-1) * n
--prob :: (Integral b, Fractional b) => b -> b -> b (two parameters of type b and output of type b)
--prob :: Int -> Int -> Double
prob n k
| n==k = (0.01**k)
| otherwise = factor n k * (0.01 ** k) * (0.99**(n-k)) + prob n (k+1)
where
factor n k = (fac n / ((fac k)* (fac (n-k))))
2- if you will notice, fac will only work on Integers, and similarly does factor. prob infact then has type of (Fractional a, Integral b) -> b -> b -> a or alternatively Integer -> Integer -> Float. why not give them their true type?
this transformation requires changing ** (which gets two floating point numbers) to ^ (which gets an Integer as it's second parameter) and using the function fromIntegral which casts an Integer to an arbitrary number Data.
fac :: Integral a => a -> a -- or alternatively Integer -> Integer
fac 1 = 1
fac n = fac (n-1) * n
prob n k
| n==k = (0.01 ^^ k)
| otherwise = fromIntegral (factor n k) * (0.01 ^^ k) * (0.99 ^^ (n-k) + prob n (k+1)
where
factor n k = div (fac n) (fac k * fac (n-k)) -- div is Integer division operator.
now prob has type of (Integral a, Floating b) => a -> a -> b which means it gets two parameters of type a (which is an Integral instance) and returns a value of type b.

Related

How to create a tail recursion for this in Haskell [T = 1/x + x/2 + 3/x +x/4 + ...]

I tried this
recursion n x = if mod n 2 == 0
then x/n + (recursion (n-1) x)**(-1)
else n/x + (recursion (n-1) x)**(-1)
but there's a problem
Ambiguous type variable ‘a0’ arising from a use of ‘print’
prevents the constraint ‘(Show a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
...plus 22 others
...plus 18 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In a stmt of an interactive GHCi command: print it
how to solve that problem and what's wrong with my code?
The mod n 2 == 0 constraints n to be an Integral type, but then you use x/n and since the (/) function has signature (/) :: Fractional a => a -> a -> a, this means that x and n have the same Fractional type. It makes no sense that a number type is both Integral and Fractional.
You can work with fromIntegral to convert n to a Fractional type:
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x = if mod n 2 == 0
then x/fromIntegral n + (recursion (n-1) x)**(-1)
else fromIntegral n/x + (recursion (n-1) x)**(-1)
Another problem with your function is that there is no stop condition. You need to add an extra clause:
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x
| n <= 0 = 0
| mod n 2 == 0 = x/fromIntegral n + (recursion (n-1) x)**(-1)
| otherwise = fromIntegral n/x + (recursion (n-1) x)**(-1)
This then produces for example:
Prelude> recursion 10 2
0.3481658094621751
Other answers have already explained the errors here. A nice Haskell way to solve this problem is as follows:
import Data.List (scanl')
getNthApprox n x = approximations !! n where
approximations = scanl' (+) 0 $ fmap term [1..]
term n = if n `mod` 2 == 0
then x / fromIntegral n
else fromIntegral n / x
It turns out that due to the magic of laziness, getNthApprox works out to have the same performance characteristics as tail recursion. This is because elements of scanl' (+) 0 $ fmap term [1..] are constructed only as they are needed in the calculation of approximations !! n.
Probably not an answer but this one would correspond more closely to the caption:
tSumToN :: (Enum a, Fractional a) => Int -> a -> a
tSumToN n = sum . take n . tSeq
tSeq :: (Enum a, Fractional a) => a -> [a]
tSeq x =
interleave odds evens
where
odds = [ o / x | o <- [1,3..]]
evens = [ x / e | e <- [2,4..]]
interleave [] _ = []
interleave (y:ys) zs = y:interleave zs ys
example :: Double
example = tSumToN 4 1.1
btw: this one does obviously not converge mathematically so it seems rather pointless to take partial sums - but hey whatever
The errors you are seeing are because the compiler can't figure out the argument types for the function. Adding type constraints to the function takes care of this:
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x = if mod n 2 == 0
then x/fromIntegral n + (recursion (n-1) x)**(-1)
else fromIntegral n/x + (recursion (n-1) x)**(-1)
Now the function compiles but will not terminate because there is no check for a terminal condition (n==0). To fix this, add the check.
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x | n == 0 = 0.0
| mod n 2 == 0 = x/fromIntegral n + (recursion (n-1) x)**(-1)
| otherwise = fromIntegral n/x + (recursion (n-1) x)**(-1)
Now the function will terminate with an answer but the answer does not match the formula stated in the question title. To fix this, remove the **(-1) .
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x | n == 0 = 0.0
| mod n 2 == 0 = x/fromIntegral n + (recursion (n-1) x)
| otherwise = fromIntegral n/x + (recursion (n-1) x)
Now the function returns the correct values. The following main program verifies that this is the case:
main :: IO ()
main = do
print $ recursion 1 1.0
print $ 1/1.0
print $ recursion 2 1.0
print $ 1/1.0 + 1.0/2
print $ recursion 3 1.0
print $ 1/1.0 + 1.0/2 + 3/1.0
print $ recursion 4 1.0
print $ 1/1.0 + 1.0/2 + 3/1.0 + 1.0/4
The function returns the correct values but is not tail recursive. As a first step in making it tail recursive, reduce it to a single recursive call. To do this note that the terms in the formula come in pairs and group them together along with a n-2 recursion. The function now will only work for even n but that can be patched up later.
recursion :: (Integral a, Floating b) => a -> b -> b
recursion n x | n == 0 = 0.0
| otherwise = fromIntegral (n-1)/x + x/fromIntegral n + (recursion (n-2) x)
The function still is not tail recursive because there is additional processing (additions) done after the recursive call. One way to work around this is to introduce an accumumator argument to hold incomplete values.
recursion :: (Integral a, Floating b) => a -> b -> b -> b
recursion n x acc | n == 0 = acc
| otherwise = recursion (n-2) x (fromIntegral (n-1)/x + x/fromIntegral n + acc)
As a final step a wrapper function can be introduced to handle odd values of n and to hide the accumulator argument. Use an appropriately modified version of the above test code to verify.
no_recursion :: (Integral a, Floating b) => a -> b -> b
no_recursion n x = if mod n 2 == 0
then recursion n x 0.0
else fromIntegral n / x + recursion (n-1) x 0.0
What you apparently meant was
recursion n x = if snd (properFraction (n / 2)) > 0 -- isOdd
then x/n + recursion (n-1) (x**(-1))
else n/x + recursion (n-1) (x**(-1))
but there's two problems here. First of all correctness, since you start from nth term and go back to 0th, but use x as the starting value always, whereas it differs depending on whether n is even or odd. We fix problems like this by moving the actual work into the inner, "worker" function, and fixing the starting value of the iteration.
Second problem is that it is not tail recursive. We fix problems like that by introducing an accumulating parameter to the inner, "worker" function. One tool to fix two problems!
-- T = 1/x + x/2 + 3/x + x/4 + ...
recursion :: RealFrac a => a -> a -> a
recursion n x = if snd (properFraction (n / 2)) > 0 -- n is odd
then goOdd n 0
else goEven n 0
where
goOdd n acc = goEven (n-1) (acc + n/x)
goEven n acc
| n <= 0 = acc
| otherwise = goOdd (n-1) (acc + x/n)
Now it's correct, and tail recursive as you wanted.

(Haskell) How to convert from Ratio Integer to Ratio Rational?

How does addition of two different ratios work? For instance, ratio integer and ratio rationals don't seem to get added. I tried evaluating the continued fraction for a given list.
Here's the code :
import Data.Ratio
f :: [Integer] -> Rational
f(x:xs)
| (null xs == True) = x
| otherwise = x + (1 % f xs)
What is the correct version of the code supposed to be? Since f yields a Ratio Rational, I feel that x, if type-casted to a Ratio rational number, will suffice.
No type conversion needed, use proper division between rationals.
import Data.Ratio
f :: [Integer] -> Rational
f [] = error "empty list"
f [x] = x % 1
f (x:xs#(_:_)) = x % 1 + 1 / f xs
Here, x % 1 makes x into a Rational (ok, that's conversion, if you want). We could also have used fromInteger, I think.
Then, between Rational values, we do not use % which produces a weird Ratio Rational, but we exploit / which produces a Rational instead.
Converting x to a Rational will not be sufficient here. Since you here write 1 % f xs. The type of (%) is (%) :: Integral a => a -> a -> Ratio a, and since f xs is a Rational, and Rational is not an instance of Integral, we thus need to fix a second issue.
It is however not that hard. We can for example make a function that calculates the inverse:
inverseR :: Integral a => Ratio a -> Ratio a
inverseR r = denominator r % numerator r
Since Ratio a is an instance of Num given a is an instance of Integral, we can use fromInteger :: Num a => Integer -> a:
f :: [Integer] -> Rational
f [x] = fromInteger x
f (x:xs) = fromInteger x + inverseR (f xs)
For example:
Prelude Data.Ratio> f [1,4,2,5]
60 % 49
Since 1 + 1/(4 + 1/(2 + 1/5)) = 1 + 1/(4 + 1/(11/5)) = 1 + 1/(4 + 5/11) = 1 + 1/(49/11) = 1 + 11/49 = 60 / 49.
We can further improve this by:
using fromIntegral :: (Integral a, Num b) => a -> b to convert any integral to a Ratio; and
by using (/) :: Fractional a => a -> a -> a.
We thus can generalize this to a function:
f :: (Integral a, Fractional b) => [a] -> b
f [x] = fromIntegral x
f (x:xs) = fromIntegral x + 1 / f xs
Which yields the same value:
Prelude Data.Ratio> f [1,4,2,5] :: Rational
60 % 49
We can use a foldr pattern, and avoid the explicit recursion:
f :: (Integral a, Fractional b) => [a] -> b
f = foldr1 (\x -> (x +) . (1 /)) . map fromIntegral

Couldn't match expexted type Double with actual Int

I tried to calculate ch value without using cosh function.
ch :: Double -> Int -> Double
ch' :: Double -> Int -> Integer -> Double -> Double
fac :: Integer -> Integer
fac 0 = 1
fac k | k > 0 = k * fac (k-1)
taylor :: Double -> Int -> Double
taylor x n = ((x^2*n))/ (2*(fac n))
ch x iter = ch' x iter 0 1
ch' x iter n sum | iter == fromIntegral n = sum
| iter /= fromIntegral n = ch' x iter (n+1) (sum + (taylor x n))
But I have error:
Couldn't match expected type `Double` with actual type `Integer`
In the second argument of `(*)`, namely `n`
In the first argument of `(/)`, namely `((x ^ 2 * n))`
and
Couldn't match expected type `Double` with actual type `Integer`
In the second argument of `(*)`, namely `fac n`
In the first argument of `(/)`, namely `(2 *(fac n))`
I guess I tried to divide Double, but I've got Integer. How I can solve this problem?
Thanks a lot!
The problem is that the arithmetic operators +, *, and - have the type
Num a => a -> a -> a
Where the Num a has to be the same a on both sides of the operator. Both Double and Integer implement Num, but you can not add them directly. Instead, you have to convert your values to the correct type. Since you're returning a Double from taylor, I'm guessing that you want to convert your Integer values to Double values. You can do this easily with fromInteger (which is actually a function in the Num typeclass):
taylor x n = (x^2 * fromInteger n) / (2 * fromInteger (fac n))
Notice that you have to convert both Integer values in this computation. If this looks a bit cluttered to you, you can always use a where clause:
taylor x n = (x^2 * n')/ (2 * facn)
where
n' = fromInteger n
facn = fromInteger $ fac n

Type declaration for number division

I tried all possible type declarations but I can't make this code even compile. The trick is in handling types for division. I tried Num a, Fractional a, Float a etc.
cube x = x * x * x
sum' term a next b =
if a > b
then 0
else term a + sum' term (next a) next b
integral f a b n = (h / 3) * (sum' term 0 succ n) where
h = (b - a) / n
y k = f $ a + (k * h)
term k
| k == 0 || k == n = y k
| odd k = 4 * y k
| even k = 2 * y k
main = do
print $ integral cube 0 1 100 -- 0.25
print $ (\x -> 3 * x * x) 1 3 100 -- 26
I isolated problem by deleting (/) function. This code compiles without any type declaration at all:
cube x = x * x * x
sum' term a next b =
if a > b
then 0
else term a + sum' term (next a) next b
integral f a b n = (sum' term 0 succ n) where
h = (b - a)
y k = f $ a + (k * h)
term k
| k == 0 || k == n = y k
| odd k = 4 * y k
| even k = 2 * y k
main = do
print $ integral cube 0 1 100
Another question is how to debug cases like this? Haskell's error messages doesn't help much, it's kind of hard to understand something like The type variable a0 is ambiguous or Could not deduce (a1 ~ a).
P. S. It's ex. 1.29 from SICP.
Update
Final answer is:
cube :: Num a => a -> a
cube x = x * x * x
sum' :: (Int -> Double) -> Int -> (Int -> Int) -> Int -> Double
sum' term a next b =
if a > b
then 0
else term a + sum' term (next a) next b
integral :: (Double -> Double) -> Double -> Double -> Int -> Double
integral f a b n = (h / 3) * sum' term 0 (+1) n where
h = (b - a) / n' where n' = fromIntegral n
y k = f $ a + (k * h)
term k
| k == 0 || k == n = y k'
| odd k = 4 * y k'
| even k = 2 * y k'
where k' = fromIntegral k
main = do
print $ integral cube 0 1 100 -- 0.25
print $ integral cube 0 1 1000 -- 0.25
print $ integral (\x -> 3 * x * x) 1 3 100 -- 26
/ is only used for types that are instances of Fractional, for Integral types use quot. You can use quot as an infix operator using backticks:
h = (b - a) `quot` n
The types of the two are
(/) :: Fractional a => a -> a -> a
quot :: Integral a => a -> a -> a
There are no types that are instances of both Fractional and Integral, which is why none of the type signatures would work. Unfortunately GHC doesn't know that it's impossible for a type to be an instance of both classes, so the error messages are not very intuitive. You get used to the style of GHC error messages though, and the detail they give helps a lot.
Also, as was suggested in the comments, I completely agree that all top level definitions should be given type signatures (including main). It makes error messages a lot easier to read.
Edit: Based on the comments below, it looks like what you want is something more like this (type signature-wise)
cube :: Num a => a -> a
sum' :: (Int -> Double) -> Int -> (Int -> Int) -> Int -> Double
integral :: (Double -> Double) -> Double -> Double -> Int -> Double
You will need to use fromIntegral to convert from Int to Double in h and in k. The type errors should be at least a bit more readable with these type signatures though.

type constructor or class error

dreiNplusEins :: Integer -> [Integer]
dreiNplusEins n = if n == 1 then [1] else if n `mod` 2 == 0 then
[n] ++ dreiNplusEins (n `div` 2)
else
[n] ++ dreiNplusEins (n * 3 + 1)
maxZyklus :: UntereGrenze -> ObereGrenze -> (UntereGrenze,ObereGrenze,MaxZyklaenge)
maxZyklus m n = if m > n then (m,n,0) else if m == n then
(m,n,length(dreiNplusEins m))
else
(m,n,0)
type UntereGrenze = Integer
type ObereGrenze = Integer
type MaxZykLaenge = Integer
this is my program and this gives error as Not in scope: type constructor or class `MaxZyklaenge' how can i fix it ?
You have a typo in the type name:
In the type signature of maxZyklus you write MaxZyklaenge (lower case l), but in the type definition you write MayZykLaenge (capital L).
Even if you fix the typo you'll still get an error, since length returns an Int where you need an Integer. The following is one way to fix this (I've also rewritten your code to use guards):
import Data.List (genericLength)
dreiNplusEins :: Integer -> [Integer]
dreiNplusEins 1 = [1]
dreiNplusEins n
| n `mod` 2 == 0 = n : dreiNplusEins (n `div` 2)
| otherwise = n : dreiNplusEins (n * 3 + 1)
maxZyklus :: UntereGrenze -> ObereGrenze -> (UntereGrenze, ObereGrenze, MaxZyklaenge)
maxZyklus m n
| m == n = (m, n, genericLength $ dreiNplusEins m)
| otherwise = (m, n, 0)
type UntereGrenze = Integer
type ObereGrenze = Integer
type MaxZyklaenge = Integer
You could also use fromIntegral . length if you don't want the extra import, but I personally think genericLength is a little clearer.
Also, if you're interested, here's an arguably nicer way to write the first function:
dreiNplusEins :: Integer -> [Integer]
dreiNplusEins = (++[1]) . takeWhile (/=1) . iterate f
where
f n | even n = n `div` 2
| otherwise = n * 3 + 1
This just says "iteratively apply f until you hit a 1, and then tack a 1 on the end".
To find the number in a given range that produces the longest chain, you can use the following function:
longestBetween :: (Enum a, Integral b) => (a -> [b]) -> (a, a) -> (a, b)
longestBetween f (m, n)
= maximumBy (comparing snd)
. zip [m..n] $ map (genericLength . f) [m..n]
The first argument is the function that creates the list and the second is the range. The return value is a tuple containing the desired number in the range and the length of its list. Note that we need these additional imports:
import Data.List (genericLength, maximumBy)
import Data.Ord (comparing)
We can test as follows:
*Main> longestBetween dreiNplusEins (100, 1000)
(871,179)
Implementing the maxZyklus function you specify in the comments just takes a couple of minor changes at this point:
maxZyklus m n = (m, n, maximum $ map (genericLength . dreiNplusEins) [m..n])
maxZyklus 11 22 gives the desired (11, 22, 21).
Haskell is case sensitive.
In the type signature of maxZyklus:
... ,MaxZyklaenge)
-- # ^
But you have:
type MaxZykLaenge = Integer
-- # ^
It's defined as MaxZykLaenge (note the "L"), whereas you wrote the type as "MaxZyklaenge". Haskell is case-sensitive.

Resources