@explorable-viz/fluid 0.7.9 → 0.7.11
Sign up to get free protection for your applications and to get access to all the features.
- package/.spago/{argonaut-codecs/v9.0.0 → affjax-node/v1.0.0}/.editorconfig +1 -1
- package/.spago/affjax-node/v1.0.0/.eslintrc.json +30 -0
- package/.spago/affjax-node/v1.0.0/.gitignore +13 -0
- package/.spago/pathy/v9.0.0/.editorconfig +13 -0
- package/dist/fluid/fluid/dataset/methane-emissions.fld +123 -0
- package/dist/fluid/fluid/dataset/mini-non-renewables.fld +3 -0
- package/dist/fluid/fluid/dataset/mini-renewables.fld +6 -0
- package/dist/fluid/fluid/dataset/non-renewables.fld +67 -0
- package/dist/fluid/fluid/dataset/renewables-new.fld +301 -0
- package/dist/fluid/fluid/dataset/renewables-restricted.fld +139 -0
- package/dist/fluid/fluid/dataset/renewables.fld +100 -0
- package/dist/fluid/fluid/example/arithmetic.fld +1 -0
- package/dist/fluid/fluid/example/array.fld +2 -0
- package/dist/fluid/fluid/example/compose.fld +2 -0
- package/dist/fluid/fluid/example/desugar/list-comp-1.fld +1 -0
- package/dist/fluid/fluid/example/desugar/list-comp-10.fld +1 -0
- package/dist/fluid/fluid/example/desugar/list-comp-2.fld +1 -0
- package/dist/fluid/fluid/example/desugar/list-comp-3.fld +1 -0
- package/dist/fluid/fluid/example/desugar/list-comp-4.fld +1 -0
- package/dist/fluid/fluid/example/desugar/list-comp-5.fld +1 -0
- package/dist/fluid/fluid/example/desugar/list-comp-6.fld +1 -0
- package/dist/fluid/fluid/example/desugar/list-comp-7.fld +1 -0
- package/dist/fluid/fluid/example/desugar/list-comp-8.fld +1 -0
- package/dist/fluid/fluid/example/desugar/list-comp-9.fld +1 -0
- package/dist/fluid/fluid/example/desugar/list-enum.fld +1 -0
- package/dist/fluid/fluid/example/dict-list-comp.fld +1 -0
- package/dist/fluid/fluid/example/dicts.fld +10 -0
- package/dist/fluid/fluid/example/div-mod-quot-rem.fld +4 -0
- package/dist/fluid/fluid/example/factorial.fld +6 -0
- package/dist/fluid/fluid/example/filter.fld +1 -0
- package/dist/fluid/fluid/example/first-class-constr.fld +1 -0
- package/dist/fluid/fluid/example/flatten.fld +12 -0
- package/dist/fluid/fluid/example/foldr-sumSquares.fld +1 -0
- package/dist/fluid/fluid/example/graphics/background.fld +7 -0
- package/dist/fluid/fluid/example/graphics/grouped-bar-chart.fld +9 -0
- package/dist/fluid/fluid/example/graphics/line-chart.fld +13 -0
- package/dist/fluid/fluid/example/graphics/stacked-bar-chart.fld +3 -0
- package/dist/fluid/fluid/example/include-input-into-output.fld +1 -0
- package/dist/fluid/fluid/example/length.fld +1 -0
- package/dist/fluid/fluid/example/lexicalScoping.fld +3 -0
- package/dist/fluid/fluid/example/lib/some-constants.fld +1 -0
- package/dist/fluid/fluid/example/linked-inputs/energyscatter.fld +24 -0
- package/dist/fluid/fluid/example/linked-inputs/mini-energyscatter.fld +30 -0
- package/dist/fluid/fluid/example/linked-outputs/convolution-data.fld +5 -0
- package/dist/fluid/fluid/example/linked-outputs/convolution.fld +12 -0
- package/dist/fluid/fluid/example/linked-outputs/line-chart.fld +15 -0
- package/dist/fluid/fluid/example/linked-outputs/moving-average.fld +19 -0
- package/dist/fluid/fluid/example/linked-outputs/pairs-data.fld +1 -0
- package/dist/fluid/fluid/example/linked-outputs/pairs.fld +2 -0
- package/dist/fluid/fluid/example/lookup.fld +15 -0
- package/dist/fluid/fluid/example/map.fld +1 -0
- package/dist/fluid/fluid/example/mergeSort.fld +22 -0
- package/dist/fluid/fluid/example/normalise.fld +3 -0
- package/dist/fluid/fluid/example/nub.fld +1 -0
- package/dist/fluid/fluid/example/pattern-match.fld +12 -0
- package/dist/fluid/fluid/example/percent.fld +1 -0
- package/dist/fluid/fluid/example/plot/methane.fld +14 -0
- package/dist/fluid/fluid/example/plot/non-renewables.fld +22 -0
- package/dist/fluid/fluid/example/range.fld +4 -0
- package/dist/fluid/fluid/example/record-lookup.fld +3 -0
- package/dist/fluid/fluid/example/records.expect.fld +0 -0
- package/dist/fluid/fluid/example/records.fld +11 -0
- package/dist/fluid/fluid/example/reverse.fld +1 -0
- package/dist/fluid/fluid/example/scratchpad.fld +6 -0
- package/dist/fluid/fluid/example/slicing/add.expect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/add.fld +1 -0
- package/dist/fluid/fluid/example/slicing/array/array.expect.fld +2 -0
- package/dist/fluid/fluid/example/slicing/array/array.fld +4 -0
- package/dist/fluid/fluid/example/slicing/array/dims.expect.fld +3 -0
- package/dist/fluid/fluid/example/slicing/array/dims.fld +3 -0
- package/dist/fluid/fluid/example/slicing/array/lookup.expect.fld +3 -0
- package/dist/fluid/fluid/example/slicing/array/lookup.fld +5 -0
- package/dist/fluid/fluid/example/slicing/array/renewables.fld +100 -0
- package/dist/fluid/fluid/example/slicing/convolution/edgeDetect.expect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/convolution/edgeDetect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/convolution/emboss-wrap.fld +1 -0
- package/dist/fluid/fluid/example/slicing/convolution/emboss.expect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/convolution/emboss.fld +1 -0
- package/dist/fluid/fluid/example/slicing/convolution/filter/edge-detect.fld +5 -0
- package/dist/fluid/fluid/example/slicing/convolution/filter/emboss.fld +5 -0
- package/dist/fluid/fluid/example/slicing/convolution/filter/gaussian.fld +5 -0
- package/dist/fluid/fluid/example/slicing/convolution/gaussian.expect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/convolution/gaussian.fld +1 -0
- package/dist/fluid/fluid/example/slicing/convolution/test-image.fld +7 -0
- package/dist/fluid/fluid/example/slicing/dict/create.expect.fld +2 -0
- package/dist/fluid/fluid/example/slicing/dict/create.fld +1 -0
- package/dist/fluid/fluid/example/slicing/dict/difference.expect.fld +4 -0
- package/dist/fluid/fluid/example/slicing/dict/difference.fld +3 -0
- package/dist/fluid/fluid/example/slicing/dict/disjointUnion.expect.fld +2 -0
- package/dist/fluid/fluid/example/slicing/dict/disjointUnion.fld +1 -0
- package/dist/fluid/fluid/example/slicing/dict/foldl.expect.fld +3 -0
- package/dist/fluid/fluid/example/slicing/dict/foldl.fld +1 -0
- package/dist/fluid/fluid/example/slicing/dict/get.expect.fld +5 -0
- package/dist/fluid/fluid/example/slicing/dict/get.fld +3 -0
- package/dist/fluid/fluid/example/slicing/dict/intersectionWith.expect.fld +5 -0
- package/dist/fluid/fluid/example/slicing/dict/intersectionWith.fld +4 -0
- package/dist/fluid/fluid/example/slicing/dict/map.expect.fld +8 -0
- package/dist/fluid/fluid/example/slicing/dict/map.fld +5 -0
- package/dist/fluid/fluid/example/slicing/dict/match.expect.fld +6 -0
- package/dist/fluid/fluid/example/slicing/dict/match.fld +5 -0
- package/dist/fluid/fluid/example/slicing/divide.expect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/divide.fld +1 -0
- package/dist/fluid/fluid/example/slicing/dtw/average-series.expect.fld +8 -0
- package/dist/fluid/fluid/example/slicing/dtw/average-series.fld +8 -0
- package/dist/fluid/fluid/example/slicing/dtw/compute-dtw.expect.fld +6 -0
- package/dist/fluid/fluid/example/slicing/dtw/compute-dtw.fld +6 -0
- package/dist/fluid/fluid/example/slicing/explained.expect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/explained.fld +1 -0
- package/dist/fluid/fluid/example/slicing/filter.expect.fld +4 -0
- package/dist/fluid/fluid/example/slicing/filter.fld +6 -0
- package/dist/fluid/fluid/example/slicing/intersperse-1.expect.fld +4 -0
- package/dist/fluid/fluid/example/slicing/intersperse-2.expect.fld +4 -0
- package/dist/fluid/fluid/example/slicing/intersperse.fld +5 -0
- package/dist/fluid/fluid/example/slicing/length.expect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/length.fld +1 -0
- package/dist/fluid/fluid/example/slicing/linked-outputs/bar-chart-line-chart.expect.fld +0 -0
- package/dist/fluid/fluid/example/slicing/linked-outputs/bar-chart-line-chart.fld +29 -0
- package/dist/fluid/fluid/example/slicing/linked-outputs/stacked-bar-scatter-plot.expect.fld +0 -0
- package/dist/fluid/fluid/example/slicing/linked-outputs/stacked-bar-scatter-plot.fld +39 -0
- package/dist/fluid/fluid/example/slicing/list-comp-1.expect.fld +6 -0
- package/dist/fluid/fluid/example/slicing/list-comp-2.expect.fld +6 -0
- package/dist/fluid/fluid/example/slicing/list-comp.fld +8 -0
- package/dist/fluid/fluid/example/slicing/lookup.expect.fld +6 -0
- package/dist/fluid/fluid/example/slicing/lookup.fld +14 -0
- package/dist/fluid/fluid/example/slicing/map.expect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/map.fld +1 -0
- package/dist/fluid/fluid/example/slicing/matrix-update.expect.fld +5 -0
- package/dist/fluid/fluid/example/slicing/matrix-update.fld +10 -0
- package/dist/fluid/fluid/example/slicing/multiply.expect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/multiply.fld +1 -0
- package/dist/fluid/fluid/example/slicing/nth.expect.fld +1 -0
- package/dist/fluid/fluid/example/slicing/nth.fld +1 -0
- package/dist/fluid/fluid/example/slicing/output-not-source.expect.fld +2 -0
- package/dist/fluid/fluid/example/slicing/output-not-source.fld +1 -0
- package/dist/fluid/fluid/example/slicing/section-5-example-1.expect.fld +10 -0
- package/dist/fluid/fluid/example/slicing/section-5-example-2.expect.fld +10 -0
- package/dist/fluid/fluid/example/slicing/section-5-example-3.expect.fld +10 -0
- package/dist/fluid/fluid/example/slicing/section-5-example.fld +14 -0
- package/dist/fluid/fluid/example/slicing/zeros-1.expect.fld +3 -0
- package/dist/fluid/fluid/example/slicing/zeros-2.expect.fld +3 -0
- package/dist/fluid/fluid/example/slicing/zeros.fld +4 -0
- package/dist/fluid/fluid/example/slicing/zipWith-1.expect.fld +4 -0
- package/dist/fluid/fluid/example/slicing/zipWith.fld +4 -0
- package/dist/fluid/fluid/example/text-viz/explainable-table.fld +7 -0
- package/dist/fluid/fluid/example/text-viz/fake-probabilities.fld +3 -0
- package/dist/fluid/fluid/example/text-viz/figure-spm-4.fld +42 -0
- package/dist/fluid/fluid/example/text-viz/left-barchart-table.fld +5 -0
- package/dist/fluid/fluid/example/text-viz/likelihoods.fld +9 -0
- package/dist/fluid/fluid/example/text-viz/right-barchart-table.fld +5 -0
- package/dist/fluid/fluid/example/text-viz/table-spm-1.fld +30 -0
- package/dist/fluid/fluid/lib/convolution.fld +16 -0
- package/dist/fluid/fluid/lib/dtw.fld +47 -0
- package/dist/fluid/fluid/lib/fnum.fld +22 -0
- package/dist/fluid/fluid/lib/graphics.fld +221 -0
- package/dist/fluid/fluid/lib/prelude.fld +266 -0
- package/dist/fluid/fluid/lib/text-viz.fld +18 -0
- package/dist/fluid/fluid.mjs +28285 -0
- package/package.json +1 -1
- package/.spago/node-process/v11.0.0/.eslintrc.json +0 -29
- package/.spago/node-process/v11.0.0/.gitignore +0 -8
- package/.spago/node-process/v11.1.0/.eslintrc.json +0 -29
- package/.spago/node-process/v11.1.0/.gitignore +0 -8
- package/.spago/node-process/v11.2.0/.eslintrc.json +0 -29
- package/.spago/node-process/v11.2.0/.gitignore +0 -8
- package/.spago/optparse/v6.0.0/.gitignore +0 -8
- package/.spago/optparse/v6.0.0/.npmrc +0 -1
- /package/.spago/{argonaut-codecs → pathy}/v9.0.0/.gitignore +0 -0
- /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,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,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,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,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';
|