@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.
Files changed (31) hide show
  1. package/dist/fluid/fluid/lib/matrix.fld +14 -18
  2. package/dist/fluid/fluid/lib/prelude.fld +79 -8
  3. package/dist/fluid/fluid/lib/stats.fld +25 -28
  4. package/dist/fluid/shared/fluid.mjs +3207 -2262
  5. package/dist/fluid/shared/load-figure.js +11059 -4058
  6. package/dist/fluid/shared/webtest-lib.js +29073 -29877
  7. package/package.json +8 -5
  8. package/website/article/convolution/index.html +5 -5
  9. package/website/article/dataset/annual-temp-anomaly.json +413 -0
  10. package/website/article/dataset/ccra3-risks.json +2015 -0
  11. package/website/article/energy-scatter/index.html +47 -0
  12. package/website/article/fluid/bar-chart-line-chart.fld +5 -5
  13. package/website/article/fluid/convolution/emboss.fld +5 -1
  14. package/website/article/fluid/dataset/scigen/_1805_02474v1_10.fld +1 -1
  15. package/website/article/fluid/energyscatter.fld +27 -0
  16. package/website/article/fluid/methane.fld +23 -1
  17. package/website/article/fluid/methane_data.fld +1 -0
  18. package/website/article/fluid/moving-average.fld +1 -1
  19. package/website/article/fluid/nonRenewables.fld +2 -2
  20. package/website/article/fluid/renewables.fld +1 -1
  21. package/website/article/methane/index.html +46 -0
  22. package/website/article/moving-average/index.html +2 -2
  23. package/website/article/non-renewables/index.html +2 -2
  24. package/website/article/renewables-linked/index.html +2 -2
  25. package/website/article/scigen-1805.02474v1-10/index.html +2 -2
  26. package/website/article/test.mjs +3 -1
  27. /package/website/article/{fluid/dataset/scigen → dataset/SciGen}/1805.02474v1-10.json +0 -0
  28. /package/website/article/{fluid/dataset → dataset}/methane-emissions.json +0 -0
  29. /package/website/article/{fluid/dataset → dataset}/non-renewables.json +0 -0
  30. /package/website/article/{fluid/dataset → dataset}/renewable-new.json +0 -0
  31. /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
- @doc("""Intermediate matrix for element ( ${m'} , ${n'} )""")
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""") [| sum([a ! (i', k) * b ! (k, j') for k in enumFromTo(1, n)]) for (i', j') in (m, j) |];
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
- def findWithKey(fname, fval, table):
64
- find((lambda y: y[fname] == fval), table)
91
+ # String -> String -> List Dict -> Option Dict
92
+ def findWithKey(fname, fval, d):
93
+ find((lambda y: y[fname] == fval), d)
65
94
 
66
- def fromSome(option):
67
- match option:
68
- case None:
69
- error("Expected Some!")
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 :| xs', []): xs
11
- case (x :| xs', y :| ys'):
12
- if x < y: x :| merge(xs', ys)
13
- else: y :| merge(xs, ys');
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): nth(rank, xs)
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"