1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
module Trit (Trit, rationalToTrit, getIntegral, getFraction, getFraction',
neg, addTrits, subTrits, shiftLeft, shiftRight, multiply
) where
import Stream
import Utilities
import Data.Ratio
type Mantissa = Stream
type Fraction = Stream
type Trit = (Mantissa, Fraction)
-- Convert from a Rational number to its Trit representation (Integral, Fraction)
rationalToTrit :: Rational -> Trit
rationalToTrit x
|x<1 = ([0], rationalToStream x)
|otherwise = (u', rationalToStream v)
where u = n `div` d
u' = toBinary u
v = x - (toRational u)
n = numerator x
d = denominator x
-- Get the integral part of Trit
getIntegral :: Trit -> Mantissa
getIntegral = fst
-- Get the fraction part of Trit, with n digit of the stream
getFraction :: Int -> Trit -> Stream
getFraction n = take n. snd
-- Get the fraction part of Trit
getFraction' :: Trit -> Stream
getFraction' = snd
-- Negate a Trit
neg :: Trit -> Trit
neg (a, b) = (negate' a, negate' b)
-- Add two Trits
addTrits :: Trit -> Trit -> Trit
addTrits (m1, (x1:x2:xs)) (m2, (y1:y2:ys)) = (u,addStream (x1:x2:xs) (y1:y2:ys))
where u' = addFiniteStream m1 m2
c = [carry x1 x2 y1 y2]
u = addFiniteStream u' c
-- Substraction of 2 Trits
subTrits :: Trit -> Trit -> Trit
subTrits x y = addTrits x (neg y)
-- Shift left = *2 opertaion with Trit
shiftLeft :: Trit -> Trit
shiftLeft (x, (y:ys)) = (x++ [y], ys)
-- Shift right = /2 operation with Trit
shiftRight :: Trit -> Integer -> Trit
shiftRight (x, xs) 1 = (init x, (u:xs))
where u = last x
shiftRight (x, xs) n = shiftRight (init x, (u:xs)) (n-1)
where u = last x
-- Multiply a Trit stream by 1,0 or -1, simply return the stream
mulOneDigit :: Integer -> Stream -> Stream
mulOneDigit x xs
|x==1 = xs
|x==0 = zero'
|otherwise = negate' xs
where zero' = (0:zero')
-- Multiplication of two streams
multiply :: Stream -> Stream -> Stream
multiply (a0:a1:x) (b0:b1:y) = average p q
where p = average (a1*b0: (average (mulOneDigit b1 x)
(mulOneDigit a1 y)))
(average (mulOneDigit b0 x)
(mulOneDigit a0 y))
q = (a0*b0:a0*b1:a1*b1:(multiply x y))
start0 = take 30 (multiply (rationalToStream (1%2)) zo)
zo :: Stream
zo = 1:(-1):zero
where zero = 0:zero
start1 = take 30 (average (rationalToStream (1%2)) (negate' (rationalToStream (1%4))))
|