@explorable-viz/fluid 0.10.5 → 0.11.0
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.
- package/dist/fluid/fluid/lib/matrix.fld +14 -18
- package/dist/fluid/fluid/lib/prelude.fld +79 -8
- package/dist/fluid/fluid/lib/stats.fld +25 -28
- package/dist/fluid/shared/fluid.mjs +3207 -2262
- package/dist/fluid/shared/load-figure.js +11059 -4058
- package/dist/fluid/shared/webtest-lib.js +29073 -29877
- package/package.json +8 -5
- package/website/article/convolution/index.html +5 -5
- package/website/article/dataset/annual-temp-anomaly.json +413 -0
- package/website/article/dataset/ccra3-risks.json +2015 -0
- package/website/article/energy-scatter/index.html +47 -0
- package/website/article/fluid/bar-chart-line-chart.fld +5 -5
- package/website/article/fluid/convolution/emboss.fld +5 -1
- package/website/article/fluid/dataset/scigen/_1805_02474v1_10.fld +1 -1
- package/website/article/fluid/energyscatter.fld +27 -0
- package/website/article/fluid/methane.fld +23 -1
- package/website/article/fluid/methane_data.fld +1 -0
- package/website/article/fluid/moving-average.fld +1 -1
- package/website/article/fluid/nonRenewables.fld +2 -2
- package/website/article/fluid/renewables.fld +1 -1
- package/website/article/methane/index.html +46 -0
- package/website/article/moving-average/index.html +2 -2
- package/website/article/non-renewables/index.html +2 -2
- package/website/article/renewables-linked/index.html +2 -2
- package/website/article/scigen-1805.02474v1-10/index.html +2 -2
- package/website/article/test.mjs +3 -1
- /package/website/article/{fluid/dataset/scigen → dataset/SciGen}/1805.02474v1-10.json +0 -0
- /package/website/article/{fluid/dataset → dataset}/methane-emissions.json +0 -0
- /package/website/article/{fluid/dataset → dataset}/non-renewables.json +0 -0
- /package/website/article/{fluid/dataset → dataset}/renewable-new.json +0 -0
- /package/website/article/{fluid/dataset → dataset}/renewable.json +0 -0
@@ -1,44 +1,40 @@
|
|
1
1
|
def zero(m, n, image):
|
2
|
-
def (m_max, n_max): dims(image)
|
3
|
-
|
2
|
+
def (m_max, n_max): dims(image)
|
4
3
|
if m >= 1 |and| m <= m_max |and| n >= 1 |and| n <= n_max: image ! (m, n)
|
5
|
-
else: 0
|
4
|
+
else: 0
|
6
5
|
|
7
6
|
def wrap(m, n, image):
|
8
|
-
def (m_max, n_max): dims(image)
|
9
|
-
|
10
|
-
image ! (((m - 1) |mod| m_max) + 1, ((n - 1) |mod| n_max) + 1);
|
7
|
+
def (m_max, n_max): dims(image)
|
8
|
+
image ! (((m - 1) |mod| m_max) + 1, ((n - 1) |mod| n_max) + 1)
|
11
9
|
|
12
10
|
def extend(m, n, image):
|
13
11
|
def (m_max, n_max): dims(image)
|
14
12
|
def m':
|
15
13
|
min(max(m, 1), m_max)
|
16
14
|
def n':
|
17
|
-
min(max(n, 1), n_max)
|
18
|
-
|
19
|
-
image ! (m', n');
|
15
|
+
min(max(n, 1), n_max)
|
16
|
+
image ! (m', n')
|
20
17
|
|
21
18
|
def matrixSum(matr):
|
22
|
-
def (m, n): dims(matr)
|
23
|
-
|
24
|
-
foldl((+), 0, [matr ! (i, j) for (i, j) in range((1, 1), (m, n))]);
|
19
|
+
def (m, n): dims(matr)
|
20
|
+
foldl((+), 0, [matr ! (i, j) for (i, j) in range((1, 1), (m, n))])
|
25
21
|
|
26
22
|
def convolve(image, kernel, lookup):
|
27
23
|
def ((m, n), (i, j)):
|
28
24
|
(dims(image), dims(kernel))
|
29
25
|
def (half_i, half_j):
|
30
26
|
(i |quot| 2, j |quot| 2)
|
31
|
-
def area: i * j
|
27
|
+
def area: i * j
|
32
28
|
def interMatrix(m', n'):
|
33
|
-
|
34
|
-
[| @doc("""Multiply these two elements""") lookup(((m' + i') - 1) - half_i, ((n' + j') - 1) - half_j, image) * kernel ! (i', j') for (i', j') in (i, j) |];
|
29
|
+
[| lookup(((m' + i') - 1) - half_i, ((n' + j') - 1) - half_j, image) * kernel ! (i', j') for (i', j') in (i, j) |]
|
35
30
|
|
36
|
-
[| matrixSum(interMatrix(m', n')) |quot| area for (m', n') in (m, n) |]
|
31
|
+
[| matrixSum(interMatrix(m', n')) |quot| area for (m', n') in (m, n) |]
|
37
32
|
|
38
33
|
def matMul(a, b):
|
39
|
-
def ((m, n), (i, j)): (dims(a), dims(b))
|
34
|
+
def ((m, n), (i, j)): (dims(a), dims(b))
|
40
35
|
|
41
36
|
if not(n == i):
|
42
37
|
error("Dimensions don't line up")
|
43
38
|
else:
|
44
|
-
@doc("""Intermediate matrix""")
|
39
|
+
@doc("""Intermediate matrix""")
|
40
|
+
[| sum([a!(i_, k) * b!(k, j_) for k in enumFromTo(1, n)]) for (i_, j_) in (m, j) |]
|
@@ -1,74 +1,103 @@
|
|
1
|
+
# "Num" throughout means (Int + Float).
|
2
|
+
|
3
|
+
# Bool -> Bool
|
1
4
|
def and(False, y): False
|
2
5
|
def and(True, y): y
|
3
6
|
|
7
|
+
# Bool -> Bool
|
4
8
|
def or(True, y): True
|
5
9
|
def or(False, y): y
|
6
10
|
|
11
|
+
# Bool -> Bool
|
7
12
|
def not(True): False
|
8
13
|
def not(False): True
|
9
14
|
|
15
|
+
# Int -> Int -> Ordering
|
10
16
|
def compare(x, y):
|
11
17
|
if x > y: GT
|
12
18
|
else:
|
13
19
|
if x < y: LT
|
14
20
|
else: EQ
|
15
21
|
|
22
|
+
# Num -> Num
|
16
23
|
def negate: (-)(0)
|
17
24
|
|
25
|
+
# Log of x in base y.
|
26
|
+
# Float -> Float -> Float
|
18
27
|
def logBase(x, y): log(y) / log(x)
|
19
28
|
|
29
|
+
# Float -> Float -> Float
|
20
30
|
def ceilingToNearest(n, m): ceiling(n / m) * m
|
21
31
|
|
32
|
+
# (b -> c) -> (a -> b) -> a -> c
|
33
|
+
# Want infix <<<
|
22
34
|
def compose(f, g, x): f(g(x))
|
23
35
|
|
36
|
+
# ((a, b) -> c) -> a -> b -> c
|
24
37
|
def curry(f, x, y): f((x, y))
|
25
38
|
|
39
|
+
# (a -> b -> c) -> (a, b) -> c
|
26
40
|
def uncurry(f, (x, y)): f(x, y)
|
27
41
|
|
42
|
+
# a -> b -> a
|
28
43
|
def const(x, _): x
|
29
44
|
|
45
|
+
# (a -> b) -> (a, c) -> (b, c)
|
30
46
|
def first(f, (a, c)): (f(a), c)
|
31
47
|
|
48
|
+
# (a, b) -> b
|
32
49
|
def snd((_, y)): y
|
33
50
|
|
51
|
+
# (a -> b) -> (c, a) -> (c, b)
|
34
52
|
def second(f, (c, a)): (c, f(a))
|
35
53
|
|
54
|
+
# (a -> b -> c) -> b -> a -> c
|
36
55
|
def flip(f, x, y): f(y, x)
|
37
56
|
|
57
|
+
# (a, b) -> a
|
38
58
|
def fst((x, _)): x
|
39
59
|
|
60
|
+
# a -> a
|
40
61
|
def id(x): x
|
41
62
|
|
63
|
+
# (a -> b) -> (a -> c) -> a -> (b, c)
|
64
|
+
# Want infix &&&
|
42
65
|
def prod(f, g, x): (f(x), g(x))
|
43
66
|
|
67
|
+
# (a, b) -> (b, a)
|
44
68
|
def swap((a, b)): (b, a)
|
45
69
|
|
70
|
+
# List a -> a
|
46
71
|
def head([]):
|
47
72
|
error("Can't take head of empty list")
|
48
73
|
def head(x :| _): x
|
49
74
|
|
75
|
+
# List a -> List a
|
50
76
|
def tail([]):
|
51
77
|
error("Can't take tail of empty list")
|
52
78
|
def tail(_ :| xs): xs
|
53
79
|
|
80
|
+
# Eq a => a -> List a -> Bool
|
54
81
|
def elem(x, []): False
|
55
82
|
def elem(x, y :| xs):
|
56
83
|
x == y |or| elem(x, xs)
|
57
84
|
|
85
|
+
# (a -> Bool) -> List a -> Option a
|
58
86
|
def find(p, []): error("not found")
|
59
87
|
def find(p, x :| xs):
|
60
88
|
if p(x): Some(x)
|
61
89
|
else: find(p, xs)
|
62
90
|
|
63
|
-
|
64
|
-
|
91
|
+
# String -> String -> List Dict -> Option Dict
|
92
|
+
def findWithKey(fname, fval, d):
|
93
|
+
find((lambda y: y[fname] == fval), d)
|
65
94
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
case Some(x): x
|
95
|
+
# Option a -> a
|
96
|
+
def fromSome(None):
|
97
|
+
error("Expected Some!")
|
98
|
+
def fromSome(Some(x)): x
|
71
99
|
|
100
|
+
# (a -> Bool) -> List a -> List a
|
72
101
|
def filter(p, []): []
|
73
102
|
def filter(p, x :| xs):
|
74
103
|
def ys: filter(p, xs)
|
@@ -76,6 +105,7 @@ def filter(p, x :| xs):
|
|
76
105
|
if p(x): x :| ys
|
77
106
|
else: ys
|
78
107
|
|
108
|
+
# (a -> Option b) -> List a -> List b
|
79
109
|
def filterMap(p, []): []
|
80
110
|
def filterMap(p, x :| xs):
|
81
111
|
match p(x):
|
@@ -83,20 +113,25 @@ def filterMap(p, x :| xs):
|
|
83
113
|
case Some(y):
|
84
114
|
y :| filterMap(f, xs)
|
85
115
|
|
116
|
+
# (a -> b -> a) -> a -> List b -> a
|
86
117
|
def foldl(op, z, []): z
|
87
118
|
def foldl(op, z, x :| xs):
|
88
119
|
foldl(op, op(z, x), xs)
|
89
120
|
|
121
|
+
# (a -> b -> a) -> List b -> a
|
90
122
|
def foldl1(op, x :| xs): foldl(op, x, xs)
|
91
123
|
|
124
|
+
# (a -> b -> b) -> b -> List a -> b
|
92
125
|
def foldr(op, z, []): z
|
93
126
|
def foldr(op, z, x :| xs):
|
94
127
|
op(x, foldr(op, z, xs))
|
95
128
|
|
129
|
+
# (a -> b -> b) -> List a -> b
|
96
130
|
def foldr1(op, [x]): x
|
97
131
|
def foldr1(op, x :| y :| xs):
|
98
132
|
op(x, foldr1(op, y :| xs))
|
99
133
|
|
134
|
+
# (a -> b -> a) -> a -> List b -> List a
|
100
135
|
def scanl1(op, z, xs):
|
101
136
|
def go(x, continue, acc):
|
102
137
|
def next: op(acc, x)
|
@@ -105,48 +140,63 @@ def scanl1(op, z, xs):
|
|
105
140
|
|
106
141
|
foldr(go, const([]), xs, z)
|
107
142
|
|
143
|
+
# (a -> b -> a) -> a -> List b -> List a
|
108
144
|
def scanl(op, z, xs):
|
109
145
|
z :| scanl1(op, z, xs)
|
110
146
|
|
147
|
+
# (a -> b) -> List a -> List b
|
111
148
|
def map(f, []): []
|
112
149
|
def map(f, x :| xs): f(x) :| map(f, xs)
|
113
150
|
|
151
|
+
# (List a, List a) -> List a
|
114
152
|
def append(([], ys)): ys
|
115
153
|
def append((x :| xs, ys)):
|
116
154
|
x :| append((xs, ys))
|
117
155
|
|
156
|
+
# List a -> List -> List a
|
157
|
+
# Want infix ++
|
118
158
|
def concat2([], ys): ys
|
119
159
|
def concat2(x :| xs, ys):
|
120
160
|
x :| concat2(xs, ys)
|
121
161
|
|
162
|
+
# List (List a) -> List a
|
122
163
|
def concat: foldl(concat2, [])
|
123
164
|
|
165
|
+
# (a -> List b) -> List a -> List b
|
124
166
|
def concatMap(f, xs): concat(map(f, xs))
|
125
167
|
|
168
|
+
# List a -> a -> List a
|
126
169
|
def intersperse([], _): []
|
127
170
|
def intersperse([x], _): [x]
|
128
171
|
def intersperse(x :| y :| ys, sep):
|
129
172
|
x :| sep :| intersperse(y :| ys, sep)
|
130
173
|
|
174
|
+
# Int -> (a -> a) -> a -> List a
|
131
175
|
def iterate(n, f, z):
|
132
176
|
if n == 0: []
|
133
177
|
else:
|
134
178
|
z :| map(f, iterate(n - 1, f, z))
|
135
179
|
|
180
|
+
# List Int -> Int
|
136
181
|
def sum: foldr((+), 0)
|
137
182
|
|
183
|
+
# List a -> a
|
138
184
|
def last([x]): x
|
139
185
|
def last(x :| y :| ys): last(y :| ys)
|
140
186
|
|
187
|
+
# List a -> Int
|
141
188
|
def length([]): 0
|
142
189
|
def length(_ :| xs): 1 + length(xs)
|
143
190
|
|
191
|
+
# List a -> List a
|
144
192
|
def reverse([]): []
|
145
193
|
def reverse(x :| xs):
|
146
194
|
append((reverse(xs), [x]))
|
147
195
|
|
196
|
+
# Int -> a -> List a
|
148
197
|
def repeat: flip(iterate, id)
|
149
198
|
|
199
|
+
# Int -> List a -> List a
|
150
200
|
def take(n, xs):
|
151
201
|
if n <= 0: []
|
152
202
|
else:
|
@@ -155,6 +205,7 @@ def take(n, xs):
|
|
155
205
|
case x :| xs:
|
156
206
|
x :| take(n - 1, xs)
|
157
207
|
|
208
|
+
# Int -> List a -> List a
|
158
209
|
def drop(n, xs):
|
159
210
|
if n <= 0: xs
|
160
211
|
else:
|
@@ -162,58 +213,76 @@ def drop(n, xs):
|
|
162
213
|
case []: []
|
163
214
|
case _ :| xs: drop(n - 1, xs)
|
164
215
|
|
216
|
+
# Int -> List a -> List a
|
165
217
|
def lastN(n, xs):
|
166
218
|
foldl(compose(const, drop(1)), xs, drop(n, xs))
|
167
219
|
|
220
|
+
# Expects non-negative integer as first argument and non-empty list as second argument.
|
221
|
+
# Int -> List a -> a
|
168
222
|
def nth(n, x :| xs):
|
169
223
|
if n == 0: x
|
170
224
|
else: nth(n - 1, xs)
|
171
225
|
|
226
|
+
# Matrix Int -> Int -> Int -> Int
|
172
227
|
def nth2(i, j, xss):
|
173
228
|
nth(j - 1, nth(i - 1, xss))
|
174
229
|
|
230
|
+
# Partial; requires k to be in the map.
|
231
|
+
# Int -> List (Int, b) -> b
|
175
232
|
def lookup(k, []):
|
176
233
|
error("Key not found in map")
|
177
234
|
def lookup(k, (k_, v) :| kvs):
|
178
235
|
if k == k_: v
|
179
236
|
else: lookup(k, kvs)
|
180
237
|
|
238
|
+
# Int -> Int -> Int
|
181
239
|
def max(n, m):
|
182
240
|
if n > m: n
|
183
241
|
else: m
|
184
242
|
|
243
|
+
# Int -> Int -> Int
|
185
244
|
def min(n, m):
|
186
245
|
if n < m: n
|
187
246
|
else: m
|
188
247
|
|
248
|
+
# List Int -> Int
|
189
249
|
def maximum: foldr1(max)
|
190
250
|
|
251
|
+
# List Int -> Int
|
191
252
|
def minimum: foldr1(min)
|
192
253
|
|
254
|
+
# List (a, b) -> (List a, List b)
|
193
255
|
def unzip([]): ([], [])
|
194
256
|
def unzip((x, y) :| zs):
|
195
257
|
def (xs, ys): unzip(zs)
|
196
|
-
|
197
258
|
(x :| xs, y :| ys)
|
198
259
|
|
260
|
+
# (a -> b -> c) -> List a -> List b -> List c
|
199
261
|
def zipWith(op, [], ys): []
|
200
262
|
def zipWith(op, x :| xs, []): []
|
201
263
|
def zipWith(op, x :| xs, y :| ys):
|
202
264
|
op(x, y) :| zipWith(op, xs, ys)
|
203
265
|
|
266
|
+
# List a -> List b -> List (a, b)
|
204
267
|
def zip: zipWith(curry(id))
|
205
268
|
|
269
|
+
# Rename to 'range'
|
270
|
+
# Int -> Int -> List Int
|
206
271
|
def enumFromTo(n, m):
|
207
272
|
if n <= m: n :| [n + 1 .. m]
|
208
273
|
else: []
|
209
274
|
|
275
|
+
# Rename to 'range2'
|
276
|
+
# (Int, Int) -> (Int, Int) -> List (Int, Int)
|
210
277
|
def range((m1, n1), (m2, n2)):
|
211
278
|
[(i1, i2) for i1 in [m1 .. m2] for i2 in [n1 .. n2]]
|
212
279
|
|
280
|
+
# Int -> Int -> Int
|
213
281
|
def abs(x, y):
|
214
282
|
if x - y < 0: negate(x - y)
|
215
283
|
else: x - y
|
216
284
|
|
285
|
+
# Eq a => [a] -> [a]
|
217
286
|
def nub(xs):
|
218
287
|
def nub_([], _): []
|
219
288
|
def nub_(x :| xs, ys):
|
@@ -223,9 +292,11 @@ def nub(xs):
|
|
223
292
|
|
224
293
|
nub_(xs, [])
|
225
294
|
|
295
|
+
# Int -> Int -> [a] -> [a]
|
226
296
|
def slice(begin, end, xs):
|
227
297
|
take(end - begin, drop(begin, xs))
|
228
298
|
|
299
|
+
# (a -> Boolean) -> List a -> (List a, List a)
|
229
300
|
def splitOn(p, data):
|
230
301
|
def go(fls, trs, []):
|
231
302
|
(reverse(fls), reverse(trs))
|
@@ -1,53 +1,50 @@
|
|
1
1
|
def split([]): ([], [])
|
2
2
|
def split(x :| xs):
|
3
|
-
def (ys, zs): split(xs)
|
4
|
-
|
5
|
-
(x :| zs, ys);
|
3
|
+
def (ys, zs): split(xs)
|
4
|
+
(x :| zs, ys)
|
6
5
|
|
7
6
|
def merge(xs, ys):
|
8
7
|
match (xs, ys):
|
9
8
|
case ([], _): ys
|
10
|
-
case (x :|
|
11
|
-
case (x :|
|
12
|
-
if x < y: x :| merge(
|
13
|
-
else: y :| merge(xs,
|
9
|
+
case (x :| xs_, []): xs
|
10
|
+
case (x :| xs_, y :| ys_):
|
11
|
+
if x < y: x :| merge(xs_, ys)
|
12
|
+
else: y :| merge(xs, ys_)
|
14
13
|
|
15
14
|
def mergesort(xs):
|
16
15
|
if length(xs) < 2: xs
|
17
16
|
else:
|
18
|
-
def (ys, zs): split(xs)
|
19
|
-
|
20
|
-
merge(mergesort(ys), mergesort(zs));
|
17
|
+
def (ys, zs): split(xs)
|
18
|
+
merge(mergesort(ys), mergesort(zs))
|
21
19
|
|
22
20
|
def findQuantile(q, p, xs):
|
23
21
|
def rank:
|
24
22
|
(p / q) * (length(xs) - 1);
|
25
23
|
|
26
|
-
if rank == floor(rank):
|
24
|
+
if rank == floor(rank):
|
25
|
+
nth(rank, xs)
|
27
26
|
else:
|
28
27
|
def x1: floor(rank)
|
29
28
|
def x2: ceiling(rank)
|
30
29
|
def left: nth(x1, xs)
|
31
|
-
def right: nth(x2, xs)
|
32
|
-
|
33
|
-
left + (rank - x1) * (right - left);
|
30
|
+
def right: nth(x2, xs)
|
31
|
+
left + (rank - x1) * (right - left)
|
34
32
|
|
35
|
-
def findPercentile: findQuantile(100)
|
33
|
+
def findPercentile: findQuantile(100)
|
36
34
|
|
37
35
|
def accumBins(data, Nil): []
|
38
36
|
def accumBins(data, [l]): []
|
39
37
|
def accumBins(data, l :| r :| es):
|
40
38
|
def (ge, le):
|
41
|
-
splitOn((lambda x: x <= r), data)
|
42
|
-
|
43
|
-
(le, r - l) :| accumBins(ge, r :| es);
|
39
|
+
splitOn((lambda x: x <= r), data)
|
40
|
+
(le, r - l) :| accumBins(ge, r :| es)
|
44
41
|
|
45
42
|
def cut(xs, nbins):
|
46
43
|
def low: minimum(xs)
|
47
44
|
def binwidth:
|
48
45
|
(maximum(xs) - low) / nbins
|
49
46
|
def edges:
|
50
|
-
[low + x * binwidth for x in enumFromTo(0, nbins)]
|
47
|
+
[low + x * binwidth for x in enumFromTo(0, nbins)]
|
51
48
|
|
52
49
|
accumBins(xs, edges);
|
53
50
|
|
@@ -55,32 +52,32 @@ def qcut(xs, qs):
|
|
55
52
|
def (low, high):
|
56
53
|
(minimum(xs), maximum(xs))
|
57
54
|
def edges:
|
58
|
-
append((low :| [findPercentile(x, xs) for x in qs], [high]))
|
55
|
+
append((low :| [findPercentile(x, xs) for x in qs], [high]))
|
59
56
|
|
60
|
-
accumBins(xs, edges)
|
57
|
+
accumBins(xs, edges)
|
61
58
|
|
62
59
|
def likelihoodLE(xs, target):
|
63
|
-
length(filter((lambda x: x <= target), xs)) / length(xs)
|
60
|
+
length(filter((lambda x: x <= target), xs)) / length(xs)
|
64
61
|
|
65
62
|
def likelihoodGE(xs, target):
|
66
|
-
length(filter((lambda x: x >= target), xs)) / length(xs)
|
63
|
+
length(filter((lambda x: x >= target), xs)) / length(xs)
|
67
64
|
|
68
65
|
def likelihoodMap(table, prob):
|
69
|
-
fromSome(find((lambda x: x.prob <= prob), table)).msg
|
66
|
+
fromSome(find((lambda x: x.prob <= prob), table)).msg
|
70
67
|
|
71
68
|
def mkPercent(num):
|
72
|
-
numToStr(num * 100) ++ "%"
|
69
|
+
numToStr(num * 100) ++ "%"
|
73
70
|
|
74
71
|
def leqP(n, m):
|
75
72
|
if n <= m: "less"
|
76
|
-
else: "more"
|
73
|
+
else: "more"
|
77
74
|
|
78
75
|
def gradedLeqP(n, m):
|
79
|
-
def ratio: n / m
|
76
|
+
def ratio: n / m
|
80
77
|
|
81
78
|
if ratio <= 1.0:
|
82
79
|
if ratio <= 0.5: "much less"
|
83
80
|
else: "less"
|
84
81
|
else:
|
85
82
|
if ratio >= 2.0: "much more"
|
86
|
-
else: "more"
|
83
|
+
else: "more"
|