magick 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/magick/loops.rb +1 -0
- data/lib/magick/maths.rb +84 -9
- data/lib/magick/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b0239f6b8fc615275fa674559061c52c111913e971a49b3ab292630cca826b96
|
|
4
|
+
data.tar.gz: fa2a9c746508d7d10d89d883a84745509435e8ca2e931f8b862ef9a0409ec184
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 16881788b5f302b8a6a06276351ec676e65cd97c21818347ce76910190e7068cce0cb52dc0338d28cbb1d5f747d64ab2129b3f71b19d482e917c00ae7497eeeb
|
|
7
|
+
data.tar.gz: 077b86c81e1e46d236fea5b4ed40492d9f646ae89da69c89987a5fdc1d0e7c6587b6c5a11a80a69e5b7797297ee5a12910537cb98278d5091ec38eee71172de2
|
data/lib/magick/loops.rb
CHANGED
data/lib/magick/maths.rb
CHANGED
|
@@ -11,21 +11,30 @@ module Magick
|
|
|
11
11
|
def subtract = ->(x){ ->(y) { add.(x).(negate.(y)) }}
|
|
12
12
|
|
|
13
13
|
def multiply
|
|
14
|
-
|
|
14
|
+
power_2.(add)
|
|
15
15
|
end
|
|
16
16
|
alias :mult :multiply
|
|
17
17
|
|
|
18
|
+
# See note on `mod`
|
|
18
19
|
def divide
|
|
19
20
|
Smullyan::Birds::Y.(->(f){
|
|
20
21
|
->(n){
|
|
21
22
|
->(d){
|
|
22
|
-
n < d ? 0 : 1 + f.(n
|
|
23
|
+
n < d ? 0 : 1 + f.(subtract.(n).(d)).(d)
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
})
|
|
26
27
|
end
|
|
27
28
|
alias :div :divide
|
|
28
29
|
|
|
30
|
+
def div
|
|
31
|
+
->(n){
|
|
32
|
+
->(d){
|
|
33
|
+
n/d
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
29
38
|
def div_to_f
|
|
30
39
|
->(n){
|
|
31
40
|
->(d){
|
|
@@ -37,18 +46,23 @@ module Magick
|
|
|
37
46
|
}
|
|
38
47
|
end
|
|
39
48
|
|
|
49
|
+
# This implementation of mod _works_ but is mostly
|
|
50
|
+
# provided as a curiousity: ie, how could we implement
|
|
51
|
+
# modulus with the Y combinator and repeated subtraction?
|
|
52
|
+
# It isn't efficient, as you will find if you ever try, say,
|
|
53
|
+
# mod.(65536).(2)
|
|
40
54
|
def mod
|
|
41
55
|
Smullyan::Birds::Y.(->(f){
|
|
42
56
|
->(n){
|
|
43
57
|
->(d){
|
|
44
|
-
n < d ? n : f.(n
|
|
58
|
+
n < d ? n : f.(subtract.(n).(d)).(d)
|
|
45
59
|
}
|
|
46
60
|
}
|
|
47
61
|
})
|
|
48
62
|
end
|
|
49
63
|
|
|
50
64
|
def exp
|
|
51
|
-
|
|
65
|
+
power_2.(multiply)
|
|
52
66
|
end
|
|
53
67
|
|
|
54
68
|
def power
|
|
@@ -63,8 +77,8 @@ module Magick
|
|
|
63
77
|
->(b) {
|
|
64
78
|
->(e) {
|
|
65
79
|
e == 1 ? b :
|
|
66
|
-
mod.(e).(2) == 0 ? f.(op.(b).(b)).(
|
|
67
|
-
op.(f.(op.(b).(b)).(
|
|
80
|
+
mod.(e).(2) == 0 ? f.(op.(b).(b)).(div.(e).(2)) :
|
|
81
|
+
op.(f.(op.(b).(b)).(div.(e).(2))).(b)
|
|
68
82
|
}
|
|
69
83
|
}
|
|
70
84
|
}).(base).(exponent)
|
|
@@ -73,6 +87,62 @@ module Magick
|
|
|
73
87
|
}
|
|
74
88
|
end
|
|
75
89
|
|
|
90
|
+
# power, as written, will have a stack trace error if we try to
|
|
91
|
+
# do something like power.(mult).(2).(32)
|
|
92
|
+
# If we eliminate the recursion, we can avoid this, but it means we need
|
|
93
|
+
# to use some regular Ruby constructs (eg, `while`, instead of the Y combinator)
|
|
94
|
+
# The following is essentially how Stepanov & McJones define `power` in
|
|
95
|
+
# Elements of Programming
|
|
96
|
+
def power_accumulate_positive
|
|
97
|
+
->(op){
|
|
98
|
+
->(r){
|
|
99
|
+
->(a){
|
|
100
|
+
->(n){
|
|
101
|
+
while (true)
|
|
102
|
+
if n % 2 != 0
|
|
103
|
+
r = op.(r).(a)
|
|
104
|
+
return r if n == 1
|
|
105
|
+
end
|
|
106
|
+
a = op.(a).(a)
|
|
107
|
+
n = div.(n).(2)
|
|
108
|
+
end
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def power_accumulate
|
|
116
|
+
->(op){
|
|
117
|
+
->(r){
|
|
118
|
+
->(n){
|
|
119
|
+
->(a){
|
|
120
|
+
return r if n == 0
|
|
121
|
+
power_accumulate_positive.(op).(r).(n).(a)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def power_2
|
|
129
|
+
->(op){
|
|
130
|
+
->(b){
|
|
131
|
+
->(e){
|
|
132
|
+
while (e % 2 == 0)
|
|
133
|
+
b = op.(b).(b)
|
|
134
|
+
e = e/2
|
|
135
|
+
end
|
|
136
|
+
e = e/2
|
|
137
|
+
return b if e == 0
|
|
138
|
+
power_accumulate.(op).(b).(op.(b).(b)).(e)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# average expects an array
|
|
145
|
+
# eg: average.([1,2,3]) => 2.0
|
|
76
146
|
def average
|
|
77
147
|
Smullyan::Birds::Phi.
|
|
78
148
|
(Magick::Maths::div_to_f).
|
|
@@ -80,19 +150,24 @@ module Magick
|
|
|
80
150
|
(Magick::Loops::length)
|
|
81
151
|
end
|
|
82
152
|
|
|
83
|
-
def powers_of_two =
|
|
153
|
+
def powers_of_two = exp.(2)
|
|
84
154
|
|
|
85
155
|
# x and y are pairs of ints
|
|
86
156
|
def fibonacci_matrix_multiply = ->(x){
|
|
87
157
|
->(y){
|
|
88
|
-
[
|
|
158
|
+
[
|
|
159
|
+
x[0] * (y[1] + y[0]) +
|
|
160
|
+
x[1] * y[0],
|
|
161
|
+
x[0] * y[0] +
|
|
162
|
+
x[1] * y[1]
|
|
163
|
+
]
|
|
89
164
|
}
|
|
90
165
|
}
|
|
91
166
|
|
|
92
167
|
def fibonacci
|
|
93
168
|
->(n){
|
|
94
169
|
n == 0 ? 0 :
|
|
95
|
-
|
|
170
|
+
power_2.(fibonacci_matrix_multiply).([1,0]).(n)[0]
|
|
96
171
|
}
|
|
97
172
|
end
|
|
98
173
|
end
|
data/lib/magick/version.rb
CHANGED