@explorable-viz/fluid 0.7.8 → 0.7.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. package/.spago/{argonaut-codecs/v9.0.0 → affjax-node/v1.0.0}/.editorconfig +1 -1
  2. package/.spago/affjax-node/v1.0.0/.eslintrc.json +30 -0
  3. package/.spago/affjax-node/v1.0.0/.gitignore +13 -0
  4. package/.spago/pathy/v9.0.0/.editorconfig +13 -0
  5. package/dist/fluid/fluid/dataset/methane-emissions.fld +123 -0
  6. package/dist/fluid/fluid/dataset/mini-non-renewables.fld +3 -0
  7. package/dist/fluid/fluid/dataset/mini-renewables.fld +6 -0
  8. package/dist/fluid/fluid/dataset/non-renewables.fld +67 -0
  9. package/dist/fluid/fluid/dataset/renewables-new.fld +301 -0
  10. package/dist/fluid/fluid/dataset/renewables-restricted.fld +139 -0
  11. package/dist/fluid/fluid/dataset/renewables.fld +100 -0
  12. package/dist/fluid/fluid/example/arithmetic.fld +1 -0
  13. package/dist/fluid/fluid/example/array.fld +2 -0
  14. package/dist/fluid/fluid/example/compose.fld +2 -0
  15. package/dist/fluid/fluid/example/desugar/list-comp-1.fld +1 -0
  16. package/dist/fluid/fluid/example/desugar/list-comp-10.fld +1 -0
  17. package/dist/fluid/fluid/example/desugar/list-comp-2.fld +1 -0
  18. package/dist/fluid/fluid/example/desugar/list-comp-3.fld +1 -0
  19. package/dist/fluid/fluid/example/desugar/list-comp-4.fld +1 -0
  20. package/dist/fluid/fluid/example/desugar/list-comp-5.fld +1 -0
  21. package/dist/fluid/fluid/example/desugar/list-comp-6.fld +1 -0
  22. package/dist/fluid/fluid/example/desugar/list-comp-7.fld +1 -0
  23. package/dist/fluid/fluid/example/desugar/list-comp-8.fld +1 -0
  24. package/dist/fluid/fluid/example/desugar/list-comp-9.fld +1 -0
  25. package/dist/fluid/fluid/example/desugar/list-enum.fld +1 -0
  26. package/dist/fluid/fluid/example/dict-list-comp.fld +1 -0
  27. package/dist/fluid/fluid/example/dicts.fld +10 -0
  28. package/dist/fluid/fluid/example/div-mod-quot-rem.fld +4 -0
  29. package/dist/fluid/fluid/example/factorial.fld +6 -0
  30. package/dist/fluid/fluid/example/filter.fld +1 -0
  31. package/dist/fluid/fluid/example/first-class-constr.fld +1 -0
  32. package/dist/fluid/fluid/example/flatten.fld +12 -0
  33. package/dist/fluid/fluid/example/foldr-sumSquares.fld +1 -0
  34. package/dist/fluid/fluid/example/graphics/background.fld +7 -0
  35. package/dist/fluid/fluid/example/graphics/grouped-bar-chart.fld +9 -0
  36. package/dist/fluid/fluid/example/graphics/line-chart.fld +13 -0
  37. package/dist/fluid/fluid/example/graphics/stacked-bar-chart.fld +3 -0
  38. package/dist/fluid/fluid/example/include-input-into-output.fld +1 -0
  39. package/dist/fluid/fluid/example/length.fld +1 -0
  40. package/dist/fluid/fluid/example/lexicalScoping.fld +3 -0
  41. package/dist/fluid/fluid/example/lib/some-constants.fld +1 -0
  42. package/dist/fluid/fluid/example/linked-inputs/energyscatter.fld +24 -0
  43. package/dist/fluid/fluid/example/linked-inputs/mini-energyscatter.fld +30 -0
  44. package/dist/fluid/fluid/example/linked-outputs/convolution-data.fld +5 -0
  45. package/dist/fluid/fluid/example/linked-outputs/convolution.fld +12 -0
  46. package/dist/fluid/fluid/example/linked-outputs/line-chart.fld +15 -0
  47. package/dist/fluid/fluid/example/linked-outputs/moving-average.fld +19 -0
  48. package/dist/fluid/fluid/example/linked-outputs/pairs-data.fld +1 -0
  49. package/dist/fluid/fluid/example/linked-outputs/pairs.fld +2 -0
  50. package/dist/fluid/fluid/example/lookup.fld +15 -0
  51. package/dist/fluid/fluid/example/map.fld +1 -0
  52. package/dist/fluid/fluid/example/mergeSort.fld +22 -0
  53. package/dist/fluid/fluid/example/normalise.fld +3 -0
  54. package/dist/fluid/fluid/example/nub.fld +1 -0
  55. package/dist/fluid/fluid/example/pattern-match.fld +12 -0
  56. package/dist/fluid/fluid/example/percent.fld +1 -0
  57. package/dist/fluid/fluid/example/plot/methane.fld +14 -0
  58. package/dist/fluid/fluid/example/plot/non-renewables.fld +22 -0
  59. package/dist/fluid/fluid/example/range.fld +4 -0
  60. package/dist/fluid/fluid/example/record-lookup.fld +3 -0
  61. package/dist/fluid/fluid/example/records.expect.fld +0 -0
  62. package/dist/fluid/fluid/example/records.fld +11 -0
  63. package/dist/fluid/fluid/example/reverse.fld +1 -0
  64. package/dist/fluid/fluid/example/scratchpad.fld +6 -0
  65. package/dist/fluid/fluid/example/slicing/add.expect.fld +1 -0
  66. package/dist/fluid/fluid/example/slicing/add.fld +1 -0
  67. package/dist/fluid/fluid/example/slicing/array/array.expect.fld +2 -0
  68. package/dist/fluid/fluid/example/slicing/array/array.fld +4 -0
  69. package/dist/fluid/fluid/example/slicing/array/dims.expect.fld +3 -0
  70. package/dist/fluid/fluid/example/slicing/array/dims.fld +3 -0
  71. package/dist/fluid/fluid/example/slicing/array/lookup.expect.fld +3 -0
  72. package/dist/fluid/fluid/example/slicing/array/lookup.fld +5 -0
  73. package/dist/fluid/fluid/example/slicing/array/renewables.fld +100 -0
  74. package/dist/fluid/fluid/example/slicing/convolution/edgeDetect.expect.fld +1 -0
  75. package/dist/fluid/fluid/example/slicing/convolution/edgeDetect.fld +1 -0
  76. package/dist/fluid/fluid/example/slicing/convolution/emboss-wrap.fld +1 -0
  77. package/dist/fluid/fluid/example/slicing/convolution/emboss.expect.fld +1 -0
  78. package/dist/fluid/fluid/example/slicing/convolution/emboss.fld +1 -0
  79. package/dist/fluid/fluid/example/slicing/convolution/filter/edge-detect.fld +5 -0
  80. package/dist/fluid/fluid/example/slicing/convolution/filter/emboss.fld +5 -0
  81. package/dist/fluid/fluid/example/slicing/convolution/filter/gaussian.fld +5 -0
  82. package/dist/fluid/fluid/example/slicing/convolution/gaussian.expect.fld +1 -0
  83. package/dist/fluid/fluid/example/slicing/convolution/gaussian.fld +1 -0
  84. package/dist/fluid/fluid/example/slicing/convolution/test-image.fld +7 -0
  85. package/dist/fluid/fluid/example/slicing/dict/create.expect.fld +2 -0
  86. package/dist/fluid/fluid/example/slicing/dict/create.fld +1 -0
  87. package/dist/fluid/fluid/example/slicing/dict/difference.expect.fld +4 -0
  88. package/dist/fluid/fluid/example/slicing/dict/difference.fld +3 -0
  89. package/dist/fluid/fluid/example/slicing/dict/disjointUnion.expect.fld +2 -0
  90. package/dist/fluid/fluid/example/slicing/dict/disjointUnion.fld +1 -0
  91. package/dist/fluid/fluid/example/slicing/dict/foldl.expect.fld +3 -0
  92. package/dist/fluid/fluid/example/slicing/dict/foldl.fld +1 -0
  93. package/dist/fluid/fluid/example/slicing/dict/get.expect.fld +5 -0
  94. package/dist/fluid/fluid/example/slicing/dict/get.fld +3 -0
  95. package/dist/fluid/fluid/example/slicing/dict/intersectionWith.expect.fld +5 -0
  96. package/dist/fluid/fluid/example/slicing/dict/intersectionWith.fld +4 -0
  97. package/dist/fluid/fluid/example/slicing/dict/map.expect.fld +8 -0
  98. package/dist/fluid/fluid/example/slicing/dict/map.fld +5 -0
  99. package/dist/fluid/fluid/example/slicing/dict/match.expect.fld +6 -0
  100. package/dist/fluid/fluid/example/slicing/dict/match.fld +5 -0
  101. package/dist/fluid/fluid/example/slicing/divide.expect.fld +1 -0
  102. package/dist/fluid/fluid/example/slicing/divide.fld +1 -0
  103. package/dist/fluid/fluid/example/slicing/dtw/average-series.expect.fld +8 -0
  104. package/dist/fluid/fluid/example/slicing/dtw/average-series.fld +8 -0
  105. package/dist/fluid/fluid/example/slicing/dtw/compute-dtw.expect.fld +6 -0
  106. package/dist/fluid/fluid/example/slicing/dtw/compute-dtw.fld +6 -0
  107. package/dist/fluid/fluid/example/slicing/explained.expect.fld +1 -0
  108. package/dist/fluid/fluid/example/slicing/explained.fld +1 -0
  109. package/dist/fluid/fluid/example/slicing/filter.expect.fld +4 -0
  110. package/dist/fluid/fluid/example/slicing/filter.fld +6 -0
  111. package/dist/fluid/fluid/example/slicing/intersperse-1.expect.fld +4 -0
  112. package/dist/fluid/fluid/example/slicing/intersperse-2.expect.fld +4 -0
  113. package/dist/fluid/fluid/example/slicing/intersperse.fld +5 -0
  114. package/dist/fluid/fluid/example/slicing/length.expect.fld +1 -0
  115. package/dist/fluid/fluid/example/slicing/length.fld +1 -0
  116. package/dist/fluid/fluid/example/slicing/linked-outputs/bar-chart-line-chart.expect.fld +0 -0
  117. package/dist/fluid/fluid/example/slicing/linked-outputs/bar-chart-line-chart.fld +29 -0
  118. package/dist/fluid/fluid/example/slicing/linked-outputs/stacked-bar-scatter-plot.expect.fld +0 -0
  119. package/dist/fluid/fluid/example/slicing/linked-outputs/stacked-bar-scatter-plot.fld +39 -0
  120. package/dist/fluid/fluid/example/slicing/list-comp-1.expect.fld +6 -0
  121. package/dist/fluid/fluid/example/slicing/list-comp-2.expect.fld +6 -0
  122. package/dist/fluid/fluid/example/slicing/list-comp.fld +8 -0
  123. package/dist/fluid/fluid/example/slicing/lookup.expect.fld +6 -0
  124. package/dist/fluid/fluid/example/slicing/lookup.fld +14 -0
  125. package/dist/fluid/fluid/example/slicing/map.expect.fld +1 -0
  126. package/dist/fluid/fluid/example/slicing/map.fld +1 -0
  127. package/dist/fluid/fluid/example/slicing/matrix-update.expect.fld +5 -0
  128. package/dist/fluid/fluid/example/slicing/matrix-update.fld +10 -0
  129. package/dist/fluid/fluid/example/slicing/multiply.expect.fld +1 -0
  130. package/dist/fluid/fluid/example/slicing/multiply.fld +1 -0
  131. package/dist/fluid/fluid/example/slicing/nth.expect.fld +1 -0
  132. package/dist/fluid/fluid/example/slicing/nth.fld +1 -0
  133. package/dist/fluid/fluid/example/slicing/output-not-source.expect.fld +2 -0
  134. package/dist/fluid/fluid/example/slicing/output-not-source.fld +1 -0
  135. package/dist/fluid/fluid/example/slicing/section-5-example-1.expect.fld +10 -0
  136. package/dist/fluid/fluid/example/slicing/section-5-example-2.expect.fld +10 -0
  137. package/dist/fluid/fluid/example/slicing/section-5-example-3.expect.fld +10 -0
  138. package/dist/fluid/fluid/example/slicing/section-5-example.fld +14 -0
  139. package/dist/fluid/fluid/example/slicing/zeros-1.expect.fld +3 -0
  140. package/dist/fluid/fluid/example/slicing/zeros-2.expect.fld +3 -0
  141. package/dist/fluid/fluid/example/slicing/zeros.fld +4 -0
  142. package/dist/fluid/fluid/example/slicing/zipWith-1.expect.fld +4 -0
  143. package/dist/fluid/fluid/example/slicing/zipWith.fld +4 -0
  144. package/dist/fluid/fluid/example/text-viz/explainable-table.fld +7 -0
  145. package/dist/fluid/fluid/example/text-viz/fake-probabilities.fld +3 -0
  146. package/dist/fluid/fluid/example/text-viz/figure-spm-4.fld +42 -0
  147. package/dist/fluid/fluid/example/text-viz/left-barchart-table.fld +5 -0
  148. package/dist/fluid/fluid/example/text-viz/likelihoods.fld +9 -0
  149. package/dist/fluid/fluid/example/text-viz/right-barchart-table.fld +5 -0
  150. package/dist/fluid/fluid/example/text-viz/table-spm-1.fld +30 -0
  151. package/dist/fluid/fluid/lib/convolution.fld +16 -0
  152. package/dist/fluid/fluid/lib/dtw.fld +47 -0
  153. package/dist/fluid/fluid/lib/fnum.fld +22 -0
  154. package/dist/fluid/fluid/lib/graphics.fld +221 -0
  155. package/dist/fluid/fluid/lib/prelude.fld +266 -0
  156. package/dist/fluid/fluid/lib/text-viz.fld +18 -0
  157. package/dist/fluid/fluid.mjs +28285 -0
  158. package/package.json +1 -1
  159. package/.spago/node-process/v11.0.0/.eslintrc.json +0 -29
  160. package/.spago/node-process/v11.0.0/.gitignore +0 -8
  161. package/.spago/node-process/v11.1.0/.eslintrc.json +0 -29
  162. package/.spago/node-process/v11.1.0/.gitignore +0 -8
  163. package/.spago/node-process/v11.2.0/.eslintrc.json +0 -29
  164. package/.spago/node-process/v11.2.0/.gitignore +0 -8
  165. package/.spago/optparse/v6.0.0/.gitignore +0 -8
  166. package/.spago/optparse/v6.0.0/.npmrc +0 -1
  167. /package/.spago/{argonaut-codecs → pathy}/v9.0.0/.gitignore +0 -0
  168. /package/.spago/{argonaut-codecs → pathy}/v9.0.0/.tidyrc.json +0 -0
@@ -0,0 +1,14 @@
1
+ let map f [] = [];
2
+ map f (x : xs) = f x : map f xs;
3
+ let data = [
4
+ { energyType: "Bio", output: 6.2 },
5
+ { energyType: "Hydro", output: 260 },
6
+ { energyType: "Solar", output: 19.9 },
7
+ { energyType: "Wind", output: 91 },
8
+ { energyType: "Geo", output: 14.4 }
9
+ ];
10
+ output = [
11
+ row.output | type <- ["Hydro", "Solar", "Geo"],
12
+ row <- data, row.energyType == type
13
+ ] in
14
+ map (fun x -> floor (x / sum output * 100)) output
@@ -0,0 +1,3 @@
1
+ let zeros [] = ⸨[]⸩;
2
+ zeros (x : xs) = ⸨(0 : zeros xs)⸩ in
3
+ zeros ⸨[⸩ 1, 2 ⸨]⸩
@@ -0,0 +1,3 @@
1
+ let zeros [] = ⸨[]⸩;
2
+ zeros (x : xs) = (0 : zeros xs) in
3
+ zeros [1, 2 ⸨]⸩
@@ -0,0 +1,4 @@
1
+ let zeros [] = [];
2
+ zeros (x : xs) = 0 : zeros xs
3
+ in
4
+ zeros [1, 2]
@@ -0,0 +1,4 @@
1
+ let zipWith op [] ys = [];
2
+ zipWith op (x : xs) [] = [];
3
+ zipWith op (x : xs) (y : ys) = (op x y : zipWith op xs ys) in
4
+ zipWith (fun x y = x ** ⸨2⸩ + y ** ⸨2⸩) [2, ⸨3⸩, 4] [3, ⸨4⸩, 5, 6]
@@ -0,0 +1,4 @@
1
+ let zipWith op [] ys = [];
2
+ zipWith op (x : xs) [] = [];
3
+ zipWith op (x : xs) (y : ys) = op x y : zipWith op xs ys
4
+ in zipWith (fun x y -> x ** 2 + y ** 2) [2, 3, 4] [3, 4, 5, 6]
@@ -0,0 +1,7 @@
1
+ [
2
+ { scenario: "SSP1-1.9", bestEstNear: 1.5, lowNear: 1.2, highNear: 1.7, bestEstMid: 1.6, lowMid: 1.2, highMid: 2.0, bestEstLate: 1.4, lowLate: 1.0, highLate: 1.8},
3
+ { scenario: "SSP1-2.6", bestEstNear: 1.5, lowNear: 1.2, highNear: 1.8, bestEstMid: 1.7, lowMid: 1.3, highMid: 2.2, bestEstLate: 1.8, lowLate: 1.3, highLate: 2.4},
4
+ { scenario: "SSP2-4.5", bestEstNear: 1.5, lowNear: 1.2, highNear: 1.8, bestEstMid: 2.0, lowMid: 1.6, highMid: 2.5, bestEstLate: 2.7, lowLate: 2.1, highLate: 3.5},
5
+ { scenario: "SSP3-7.0", bestEstNear: 1.5, lowNear: 1.2, highNear: 1.8, bestEstMid: 2.1, lowMid: 1.7, highMid: 2.6, bestEstLate: 3.6, lowLate: 2.8, highLate: 4.6},
6
+ { scenario: "SSP5-8.5", bestEstNear: 1.6, lowNear: 1.3, highNear: 1.9, bestEstMid: 2.4, lowMid: 1.9, highMid: 3.0, bestEstLate: 4.4, lowLate: 3.3, highLate: 5.7}
7
+ ]
@@ -0,0 +1,3 @@
1
+ [
2
+ { model: "SSP1-1.9", probability: 0.92 }
3
+ ]
@@ -0,0 +1,42 @@
1
+ let getByX x table = fromSome (findWithKey "x" x table);
2
+
3
+ let referToBar bar = "the bar representing scenario " ++ bar.x ++ " has a z value of " ++ (numToStr (head bar.bars).z);
4
+
5
+ let stackedBarHeight stackedBar = sum [ bar.z | bar <- stackedBar.bars ];
6
+
7
+ let getTotal (BarChart record) = fromSome (findWithKey "x" "Total" record.stackedBars);
8
+ let getCO2 (BarChart record)= fromSome (findWithKey "x" "CO2" record.stackedBars);
9
+ let getNonCO2 (BarChart record) = fromSome (findWithKey "x" "Non-CO2" record.stackedBars);
10
+
11
+
12
+ let barHeight (BarChart bc) x =
13
+ let bar = fromSome (findWithKey "x" x bc.stackedBars)
14
+ in sum [ segment.z | segment <- bar.bars ];
15
+
16
+ let explainBars bars x =
17
+ if length bars == length (filter (fun bar -> bar.x == x) bars)
18
+ then "(°C; " ++ x ++ " bar)"
19
+ else error "absurd";
20
+
21
+ let mkBarChart scenName table =
22
+ BarChart {
23
+ caption: "Example bar chart for scenario " ++ scenName,
24
+ size: { width: 275, height: 185 },
25
+ stackedBars: map (fun record -> { x: record.type, bars: [ { y: "emissions", z: record.emissions } ]}) table
26
+ };
27
+
28
+ let getHeight bar offset = (head bar.bars).z + offset;
29
+
30
+ let ssp119 = mkBarChart "SSP1-1.9" ssp119Source;
31
+ ssp245 = mkBarChart "SSP2-4.5" ssp245Source;
32
+ total = map getTotal [ssp119, ssp245];
33
+ co2 = map getCO2 [ssp119, ssp245];
34
+ nonco2 = map getNonCO2 [ssp119, ssp245];
35
+ meanTotal = (sum (map stackedBarHeight total)) / (length total)
36
+ in MultiView {
37
+ leftBarChart: ssp119,
38
+ rightBarChart: ssp245,
39
+ explanation:
40
+ LinkedText [ "Within each scenario bar plot, the bars represent: total warming ", explainBars total "Total",
41
+ ", warming contributions from CO2 ", explainBars co2 "CO2", " and from non-CO2 GHG's ", explainBars nonco2 "Non-CO2"]
42
+ }
@@ -0,0 +1,5 @@
1
+ [
2
+ { type: "Total", emissions: 1.35 },
3
+ { type: "CO2", emissions: 1.1 },
4
+ { type: "Non-CO2", emissions: 0.41 }
5
+ ]
@@ -0,0 +1,9 @@
1
+ [
2
+ { prob: 0.99, msg: "virtually certain" },
3
+ { prob: 0.9, msg: "very likely"},
4
+ { prob: 0.66, msg: "likely"},
5
+ { prob: 0.33, msg: "about as likely as not"},
6
+ { prob: 0.1, msg: "unlikely"},
7
+ { prob: 0.01, msg: "very unlikely"},
8
+ { prob: 0.0, msg: "exceptionally unlikely"}
9
+ ]
@@ -0,0 +1,5 @@
1
+ [
2
+ { type: "Total", emissions: 2.7 },
3
+ { type: "CO2", emissions: 2.1 },
4
+ { type: "Non-CO2", emissions: 0.6 }
5
+ ]
@@ -0,0 +1,30 @@
1
+ let newDataTable offset = map (fun s -> { scenario: s.scenario, beNear: s.bestEstNear + offset, nearRange: (s.lowNear, s.highNear), beMid: s.bestEstMid, midRange: (s.lowMid, s.highMid), beLong: s.bestEstLate, longRange: (s.lowLate, s.highLate)}) tableData;
2
+
3
+ let getByScenario data scenario = fromSome (findWithKey "scenario" scenario data);
4
+
5
+ let probAsText = likelihoodMap likelihoods;
6
+
7
+ let mean list = (sum list) / (length list);
8
+
9
+ let calcLikelihood (min, max) target =
10
+ if max < target
11
+ then 0.05
12
+ else if target <= min
13
+ then 0.95
14
+ else (target - min)/(max - min);
15
+
16
+ let realTable = newDataTable 0;
17
+ getByScenario' = getByScenario realTable;
18
+ ssp119 = getByScenario' "SSP1-1.9";
19
+ ssp245 = getByScenario' "SSP2-4.5"
20
+ in MultiView {
21
+ explanation119:
22
+ LinkedText [ "Under the low GHG emissions scenario (SSP1-1.9), global warming of 2°C would ",
23
+ probAsText (calcLikelihood ssp119.longRange 2.0),
24
+ " be exceeded at the end of the 21st century." ],
25
+ explanation245:
26
+ LinkedText [ "Under the intermediate GHG emissions scenario (SSP2-4.5), global warming of 2°C would ",
27
+ probAsText (calcLikelihood ssp245.longRange 2.0),
28
+ " be exceeded by the end of the 21st century. In the mid-term period (2041-2060)",
29
+ " crossing the 2°C mark is ", probAsText (calcLikelihood ssp245.midRange 2.0), "to occur" ]
30
+ }
@@ -0,0 +1,16 @@
1
+ let zero n = const n;
2
+ wrap n n_max = ((n - 1) `mod` n_max) + 1;
3
+ extend n = min (max n 1);
4
+
5
+ let convolve image kernel method =
6
+ let ((m, n), (i, j)) = (dims image, dims kernel);
7
+ (half_i, half_j) = (i `quot` 2, j `quot` 2);
8
+ area = i * j
9
+ in [| let weightedSum = sum [
10
+ image!(x, y) * kernel!(i' + 1, j' + 1)
11
+ | (i', j') <- range (0, 0) (i - 1, j - 1),
12
+ let x = method (m' + i' - half_i) m,
13
+ let y = method (n' + j' - half_j) n,
14
+ x >= 1, x <= m, y >= 1, y <= n
15
+ ] in weightedSum `quot` area
16
+ | (m', n') in (m, n) |];
@@ -0,0 +1,47 @@
1
+ let nextIndices n m window =
2
+ [(i, j) | i <- [1 .. n],
3
+ j <- [max 1 (i - window) .. min m (i + window)]];
4
+
5
+ let costMatrixInit rows cols window =
6
+ [| let initV = if ((n == 1) `and` (m == 1)) `or` ((abs n m <= window) `and` not ((n == 1) `or` (m == 1)))
7
+ then FNum 0
8
+ else Infty
9
+ in initV | (n, m) in (rows, cols) |];
10
+
11
+ let minAndPrev (i, j) im1 jm1 ijm1 =
12
+ let minim = minimal [im1, jm1, ijm1] in
13
+ if minim `eq` im1 then
14
+ ((i, j + 1), minim)
15
+ else
16
+ if minim `eq` jm1 then
17
+ ((i + 1, j ), minim)
18
+ else ((i, j), minim);
19
+
20
+ let extractPath indmatrix (n, m) accum =
21
+ if (n == 1) `and` (m == 1)
22
+ then accum
23
+ else
24
+ extractPath indmatrix (indmatrix!(n, m)) ((n - 1, m - 1) : accum);
25
+
26
+ let localMinUpdate seq1 seq2 cost (costmatrix, indmatrix) (i, j) =
27
+ let iEntr = nth (i - 1) seq1;
28
+ jEntr = nth (j - 1) seq2;
29
+ dist = cost iEntr jEntr;
30
+ ip = i + 1;
31
+ jp = j + 1;
32
+ im1 = costmatrix!(i , jp);
33
+ jm1 = costmatrix!(ip, j);
34
+ im1jm1 = costmatrix!(i, j);
35
+ (prev, FNum minim) = minAndPrev (i, j) im1 jm1 im1jm1;
36
+ newVal = FNum (dist + minim)
37
+ in (matrixUpdate costmatrix (ip, jp) newVal, matrixUpdate indmatrix (ip, jp) prev);
38
+
39
+ let computeDTW seq1 seq2 cost window =
40
+ let n = length seq1;
41
+ m = length seq2;
42
+ initD = costMatrixInit (n + 1) (m + 1) window;
43
+ initI = [| 0 | (i,j) in (n + 1, m + 1)|];
44
+ indexing = nextIndices n m window;
45
+ (finished, indices) = foldl (localMinUpdate seq1 seq2 cost) (initD, initI) indexing
46
+ in
47
+ (finished, extractPath indices (n + 1, m + 1) Nil);
@@ -0,0 +1,22 @@
1
+ let comp Infty Infty = EQ;
2
+ comp Infty (FNum y) = GT;
3
+ comp (FNum x) Infty = LT;
4
+ comp (FNum x) (FNum y) = compare x y;
5
+
6
+ let fmin x y =
7
+ match comp x y as {
8
+ LT -> x;
9
+ EQ -> x;
10
+ GT -> y
11
+ };
12
+
13
+ let minimal = foldl1 fmin;
14
+
15
+ let add Infty _ = Infty;
16
+ add (FNum x) Infty = Infty;
17
+ add (FNum x) (FNum y) = FNum (x + y);
18
+
19
+ let eq Infty Infty = True;
20
+ eq Infty (FNum x) = False;
21
+ eq (FNum x) Infty = False;
22
+ eq (FNum x) (FNum y) = x == y;
@@ -0,0 +1,221 @@
1
+ -- typedef Colour = Str
2
+ -- typedef Colours = List Colour
3
+ -- typedef Cat = Str
4
+
5
+ -- Group has location (0, 0) because it doesn't interfere with positioning of its children.
6
+ -- GraphicsElement -> Point
7
+ let coords (Group gs) = Point 0 0;
8
+ coords (Rect x y _ _ _) = Point x y;
9
+ coords (Text x y _ _ _) = Point x y;
10
+ coords (Viewport x y _ _ _ _ _ _ _) = Point x y;
11
+
12
+ -- GraphicsElement -> Float
13
+ let get_x g = let Point x _ = coords g in x;
14
+
15
+ -- GraphicsElement -> Float
16
+ let get_y g = let Point _ y = coords g in x;
17
+
18
+ -- Want some kind of typeclass mechanism plus record accessors/updaters.
19
+ -- Float -> GraphicsElement -> GraphicsElement
20
+ let set_x x (Group gs) = error "Group has immutable coordinates";
21
+ set_x x (Rect _ y w h fill) = Rect x y w h fill;
22
+ set_x x (Text _ y str anchor baseline) = Text x y str anchor baseline;
23
+ set_x x (Viewport _ y w h fill margin scale translate g) = Viewport x y w h fill margin scale translate g;
24
+
25
+ -- (Point, Point) -> Point
26
+ let dimensions2 (Point x1 y1, Point x2 y2) = Point (max x1 x2) (max y1 y2);
27
+
28
+ -- For Group, dimensions are relative to implicit coords of (0, 0), since a Group's children are effectively
29
+ -- positioned relative to parent of Group. For Polymarker, will probably have to ignore the markers themselves,
30
+ -- since they are scale-invariant.
31
+ -- GraphicsElement -> Point
32
+ let
33
+ dimensions (Group gs) = foldl (curry dimensions2) (Point 0 0) (map (coords_op) gs);
34
+ dimensions (Polyline ps _ _) = foldl (curry dimensions2) (Point 0 0) ps;
35
+ dimensions (Rect _ _ w h _) = Point w h;
36
+ dimensions (Text _ _ _ _ _) = Point 0 0; -- treat text like markers; scale-invariant
37
+ dimensions (Viewport _ _ w h _ _ _ _ _) = Point w h;
38
+
39
+ coords_op g =
40
+ let (Point x y, Point w h) = prod coords dimensions g in
41
+ Point (x + w) (y + h);
42
+
43
+ -- GraphicsElement -> Float
44
+ let width g = let Point w _ = dimensions g in w;
45
+
46
+ -- GraphicsElement -> Float
47
+ let height g = let Point _ h = dimensions g in h;
48
+
49
+ -- Float -> Float -> List GraphicsElement -> List GraphicsElement
50
+ let spaceRight z sep gs =
51
+ zipWith set_x (iterate (length gs) ((+) sep) z) gs;
52
+
53
+ -- Bake colour decisions into the library for the time being. Provide two palettes, so we can have two
54
+ -- different sets of categorical values (e.g. countries and energy types). Palettes from colorbrewer2.org.
55
+ let colours1 = ["#66c2a5", "#a6d854", "#ffd92f", "#e5c494", "#fc8d62", "#b3b3b3", "#8da0cb", "#e78ac3"];
56
+ let colours2 = ["#e41a1c", "#377eb8", "#4daf4a", "#984ea3", "#ff7f00", "#ffff33", "#a65628", "#f781bf"];
57
+
58
+ -- Compositionality principle: child coords/dimensions are always expressed directly using parent reference
59
+ -- frame, to avoid depending on content of child, and so are not themselves scaled. Polyline can't be scaled
60
+ -- directly because it inherits its frame of reference from its parent. For Viewport, margin will shrink the
61
+ -- available area, possibly to zero, at which point nothing will be rendered.
62
+ -- Float -> GraphicsElement -> GraphicsElement
63
+ let scaleToWidth w (Rect x y _ h fill) = Rect x y w h fill;
64
+ scaleToWidth w (Viewport x y w0 h fill margin (Scale x_scale y_scale) translate g) =
65
+ let scale = Scale (x_scale * w / w0) y_scale in
66
+ Viewport x y w h fill margin scale translate g;
67
+
68
+ -- Float -> List GraphicsElement -> List GraphicsElement
69
+ let stackRight sep gs =
70
+ map (scaleToWidth (1 - sep)) (spaceRight (sep / 2) 1 gs);
71
+
72
+ -- Float -> List GraphicsElement -> GraphicsElement
73
+ let groupRight sep gs =
74
+ Viewport 0 0 (length gs) (maximum (map height gs)) "none" 0 (Scale 1 1) (Translate 0 0) (Group (stackRight sep gs));
75
+
76
+ -- Heuristic saying how often to place a tick on an axis of length n.
77
+ -- Float -> Float
78
+ let tickEvery n =
79
+ let m = floor (logBase 10 n) in
80
+ if n <= 2 * 10 ** m
81
+ then 2 * 10 ** (m - 1)
82
+ else 10 ** m;
83
+
84
+ let axisStrokeWidth = 0.5;
85
+ axisColour = "black";
86
+ backgroundColour = "white";
87
+ defaultMargin = 24;
88
+ markerRadius = 3.5;
89
+ tickLength = 4;
90
+
91
+ -- Helpers for axis functions.
92
+ -- Orient -> Colour -> Float -> GraphicsElement
93
+ let tick Horiz colour len = Line (Point 0 0) (Point 0 (0 - len)) colour axisStrokeWidth;
94
+ tick Vert colour len = Line (Point 0 0) (Point (0 - len) 0) colour axisStrokeWidth;
95
+
96
+ -- Orient -> Float -> Float -> Str -> GraphicsElement
97
+ let label Horiz x distance str = Text x (0 - distance - 4) str "middle" "hanging";
98
+ label Vert x distance str = Text (0 - distance) x str "end" "central";
99
+
100
+ -- Orient -> Colour -> Float -> Str -> GraphicsElement
101
+ let labelledTick orient colour len str =
102
+ Group [tick orient colour len, label orient 0 len str];
103
+
104
+ -- Orient -> Float -> Float -> Point
105
+ let mkPoint Horiz x y = Point y x;
106
+ mkPoint Vert x y = Point x y;
107
+
108
+ -- x is position of this axis on the other axis. Returns axis and position of last tick.
109
+ -- Orient -> Float -> Float -> Float -> GraphicsElement
110
+ let axis orient x start end =
111
+ let tickSp = tickEvery (end - start);
112
+ firstTick = ceilingToNearest start tickSp;
113
+ lastTick = ceilingToNearest end tickSp;
114
+ n = floor ((end - firstTick) / tickSp) + 1;
115
+ ys = iterate n ((+) tickSp) firstTick;
116
+ -- avoid redundant start and end points
117
+ ys = match firstTick > start as {
118
+ True -> start : ys;
119
+ False -> ys
120
+ };
121
+ ys = match lastTick > end as {
122
+ True -> concat2 ys [lastTick];
123
+ False -> ys
124
+ };
125
+ ps = map (mkPoint orient x) ys;
126
+ ax = Group [
127
+ Line (head ps) (last ps) axisColour axisStrokeWidth,
128
+ Polymarkers ps (flip map ys (compose (labelledTick orient axisColour tickLength) numToStr))
129
+ ]
130
+ in (ax, lastTick);
131
+
132
+ -- x is position of this axis on the other axis.
133
+ -- Orient -> Float -> List Cat -> GraphicsElement
134
+ let catAxis orient x catValues =
135
+ let ys = iterate (length catValues + 1) ((+) 1) 0;
136
+ ps = map (mkPoint orient x) ys
137
+ in Group [
138
+ Line (head ps) (last ps) axisColour axisStrokeWidth,
139
+ Polymarkers (tail ps) (map (const (tick orient axisColour tickLength)) catValues),
140
+ Polymarkers (flip map (tail ps) (fun (Point x y) -> Point (x - 0.5) y)) (map (label orient -0.5 0) catValues)
141
+ ];
142
+
143
+ -- Float -> Float -> Float -> Float -> List GraphicsElement -> GraphicsElement
144
+ let viewport x_start x_finish y_finish margin gs =
145
+ Viewport 0 0 (x_finish - x_start) y_finish backgroundColour margin
146
+ (Scale 1 1) (Translate (0 - x_start) 0) (Group gs);
147
+
148
+ -- Plot a map of x values to lists of (categorical value, y value) pairs. Importantly, assume all data is uniform
149
+ -- (categorical keys are the same for each x value and are ordered the same each time).
150
+ -- Bool -> Colours -> Float -> List (Float, List (Cat, Float)) -> GraphicsElement
151
+ let lineChart withAxes colours x_start data =
152
+ let xs = map fst data;
153
+ nCat = length (snd (head data));
154
+ -- (Int, Colour) -> GraphicsElement
155
+ let plot (n, colour) =
156
+ let ps = map (fun (x, kvs) -> Point x (snd (nth n kvs))) data
157
+ in Group [
158
+ Polyline ps colour 1,
159
+ Polymarkers ps (repeat (length ps) (Circle 0 0 markerRadius colour))
160
+ ];
161
+ -- List GraphicsElement
162
+ let lines = zipWith (curry plot) (iterate nCat ((+) 1) 0) colours;
163
+ x_finish = last xs;
164
+ y_finish = maximum (flip map data (fun (_, kvs) -> maximum (map snd kvs)))
165
+ in match withAxes as {
166
+ True ->
167
+ let (x_axis, x_finish) = axis Horiz 0 x_start x_finish;
168
+ (y_axis, y_finish') = axis Vert x_start 0 y_finish
169
+ in viewport x_start x_finish y_finish' defaultMargin (x_axis : y_axis : lines);
170
+ False -> viewport x_start x_finish y_finish 0 lines
171
+ };
172
+
173
+ -- Plot a chart of categorical values on the x-axis and renderings of the corresponding a-value on the y-axis.
174
+ -- (Colours -> List a -> GraphicsElement) -> Bool -> Colours -> Float -> List (Cat, a) -> GraphicsElement
175
+ let categoricalChart plotValue withAxes colours sep data =
176
+ let gs = stackRight sep (plotValue colours (map snd data));
177
+ w = length gs;
178
+ h = maximum (map height gs)
179
+ in match withAxes as {
180
+ True ->
181
+ let x_axis = catAxis Horiz 0 (map fst data);
182
+ (y_axis, h') = axis Vert 0 0 h
183
+ in viewport 0 w h' defaultMargin (concat2 gs [x_axis, y_axis]); -- axes on top
184
+ False -> viewport 0 w h 0 gs
185
+ };
186
+
187
+ -- Colours -> List a -> GraphicsElement
188
+ let rects colours ns =
189
+ zipWith (fun colour n -> Rect 0 0 1 n colour) colours ns;
190
+
191
+ -- First component of data (categorical value) currently ignored; values just mapped positionally to colors.
192
+ -- Can we use Group instead of Viewport here?
193
+ -- Colours -> List (a, Num) -> GraphicsElement
194
+ let stackedBar colours ns =
195
+ let heights = map snd ns;
196
+ subtotals = scanl1 (+) 0 heights;
197
+ dims = zip (0 : subtotals) heights;
198
+ rects = map
199
+ (fun ((y, height), colour) -> Rect 0 y 1 height colour)
200
+ (zip dims colours)
201
+ in Viewport 0 0 1 (last subtotals) "none" 0 (Scale 1 1) (Translate 0 0) (Group rects);
202
+
203
+ -- Bool -> Colours -> Float -> List (a, Float) -> GraphicsElement
204
+ let barChart = categoricalChart rects;
205
+
206
+ -- For each categorical value of type a, plot a bar chart for the corresponding b-indexed data.
207
+ -- Bool -> Colours -> Float -> List (a, List (b, Float)) -> GraphicsElement
208
+ let groupedBarChart = categoricalChart (compose map (flip (barChart False) 0));
209
+
210
+ -- See stackedBar for strong (unjustified) assumption about uniformity of data.
211
+ -- Bool -> Colours -> Num -> List (a, List (b, Num)) -> GraphicsElement
212
+ let stackedBarChart = categoricalChart (compose map stackedBar);
213
+
214
+ -- Bit of a hack, but how text fits into our model is a bit unclear at the moment.
215
+ -- Str -> GraphicsElement -> GraphicsElement
216
+ let caption str (Viewport x y w h fill margin scale translate g) =
217
+ let g' = Group [
218
+ Text (x + w / 2) -2 str "middle" "hanging",
219
+ Viewport 0 0 w h fill margin scale translate g
220
+ ]
221
+ in Viewport x y w h backgroundColour (defaultMargin / 2 + 4) (Scale 1 1) (Translate 0 0) g';