@knowvah/dot-engine 2.6.11 → 2.7.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/README.md +1 -1
- package/dist/api.js +18 -4
- package/dist/api.js.map +3 -3
- package/dist/async/render-async.d.ts.map +1 -1
- package/dist/common/agerr.d.ts +37 -0
- package/dist/common/agerr.d.ts.map +1 -0
- package/dist/common/arrows-shapes-poly.d.ts.map +1 -1
- package/dist/common/color.d.ts.map +1 -1
- package/dist/common/crand.d.ts +0 -20
- package/dist/common/crand.d.ts.map +1 -1
- package/dist/common/emit-once.d.ts +6 -0
- package/dist/common/emit-once.d.ts.map +1 -0
- package/dist/common/graph-init.d.ts.map +1 -1
- package/dist/common/htmltable-attr-warn.d.ts.map +1 -1
- package/dist/common/htmltable-emit-fill.d.ts +29 -2
- package/dist/common/htmltable-emit-fill.d.ts.map +1 -1
- package/dist/common/htmltable-emit-rules.d.ts.map +1 -1
- package/dist/common/htmltable-emit.d.ts.map +1 -1
- package/dist/common/htmltable-lex-expat.d.ts +1 -6
- package/dist/common/htmltable-lex-expat.d.ts.map +1 -1
- package/dist/common/htmltable-pos-runs.d.ts +7 -4
- package/dist/common/htmltable-pos-runs.d.ts.map +1 -1
- package/dist/common/htmltable.d.ts +1 -7
- package/dist/common/htmltable.d.ts.map +1 -1
- package/dist/common/libm-trig.d.ts +5 -0
- package/dist/common/libm-trig.d.ts.map +1 -0
- package/dist/common/multicolor.d.ts +21 -13
- package/dist/common/multicolor.d.ts.map +1 -1
- package/dist/common/poly-gencode.d.ts +1 -2
- package/dist/common/poly-gencode.d.ts.map +1 -1
- package/dist/common/poly-init.d.ts.map +1 -1
- package/dist/common/postproc.d.ts.map +1 -1
- package/dist/common/random.d.ts.map +1 -1
- package/dist/common/render-state.d.ts +8 -0
- package/dist/common/render-state.d.ts.map +1 -0
- package/dist/common/splines-clip.d.ts +7 -0
- package/dist/common/splines-clip.d.ts.map +1 -1
- package/dist/common/splines-geom.d.ts +8 -0
- package/dist/common/splines-geom.d.ts.map +1 -1
- package/dist/common/splines-routespl.d.ts.map +1 -1
- package/dist/common/textmeasure-lookup.d.ts.map +1 -1
- package/dist/common/textmeasure.d.ts.map +1 -1
- package/dist/gvc/anchor.d.ts.map +1 -1
- package/dist/gvc/context.d.ts +6 -0
- package/dist/gvc/context.d.ts.map +1 -1
- package/dist/gvc/device-cluster.d.ts +15 -0
- package/dist/gvc/device-cluster.d.ts.map +1 -1
- package/dist/gvc/device-labels.d.ts +14 -0
- package/dist/gvc/device-labels.d.ts.map +1 -1
- package/dist/gvc/device.d.ts.map +1 -1
- package/dist/gvc/first-layer.d.ts +9 -0
- package/dist/gvc/first-layer.d.ts.map +1 -0
- package/dist/gvc/gvrender-set-style.d.ts +28 -0
- package/dist/gvc/gvrender-set-style.d.ts.map +1 -0
- package/dist/gvc/usershape.d.ts +18 -0
- package/dist/gvc/usershape.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3169 -1296
- package/dist/index.js.map +4 -4
- package/dist/layout/dot/cluster.d.ts.map +1 -1
- package/dist/layout/dot/compound.d.ts.map +1 -1
- package/dist/layout/dot/conc.d.ts.map +1 -1
- package/dist/layout/dot/decomp.d.ts.map +1 -1
- package/dist/layout/dot/edge-route-clip.d.ts +32 -14
- package/dist/layout/dot/edge-route-clip.d.ts.map +1 -1
- package/dist/layout/dot/edge-route-routing.d.ts.map +1 -1
- package/dist/layout/dot/mincross-build.d.ts.map +1 -1
- package/dist/layout/dot/mincross-cross.d.ts.map +1 -1
- package/dist/layout/dot/rank.d.ts.map +1 -1
- package/dist/layout/dot/splines.d.ts.map +1 -1
- package/dist/layout/fdp/index.d.ts.map +1 -1
- package/dist/layout/fdp/tlayout-parms.d.ts.map +1 -1
- package/dist/layout/fdp/xlayout.d.ts.map +1 -1
- package/dist/layout/neato/__fixtures__/dijkstra-f.d.ts +11 -0
- package/dist/layout/neato/__fixtures__/dijkstra-f.d.ts.map +1 -0
- package/dist/layout/neato/__fixtures__/hier-imds.d.ts +36 -0
- package/dist/layout/neato/__fixtures__/hier-imds.d.ts.map +1 -0
- package/dist/layout/neato/__fixtures__/hier-majorization.d.ts +32 -0
- package/dist/layout/neato/__fixtures__/hier-majorization.d.ts.map +1 -0
- package/dist/layout/neato/cdt-surface.d.ts.map +1 -1
- package/dist/layout/neato/compute-hierarchy.d.ts +24 -0
- package/dist/layout/neato/compute-hierarchy.d.ts.map +1 -0
- package/dist/layout/neato/conjgrad-mkernel.d.ts +20 -0
- package/dist/layout/neato/conjgrad-mkernel.d.ts.map +1 -0
- package/dist/layout/neato/conjgrad.d.ts +19 -0
- package/dist/layout/neato/conjgrad.d.ts.map +1 -1
- package/dist/layout/neato/constrained-majorization.d.ts +26 -0
- package/dist/layout/neato/constrained-majorization.d.ts.map +1 -0
- package/dist/layout/neato/dijkstra.d.ts +33 -16
- package/dist/layout/neato/dijkstra.d.ts.map +1 -1
- package/dist/layout/neato/edge-len.d.ts.map +1 -1
- package/dist/layout/neato/fdp-adjust.d.ts.map +1 -1
- package/dist/layout/neato/gts-triangle.d.ts +14 -0
- package/dist/layout/neato/gts-triangle.d.ts.map +1 -0
- package/dist/layout/neato/init.d.ts +6 -22
- package/dist/layout/neato/init.d.ts.map +1 -1
- package/dist/layout/neato/kk.d.ts.map +1 -1
- package/dist/layout/neato/kkutils.d.ts +20 -0
- package/dist/layout/neato/kkutils.d.ts.map +1 -0
- package/dist/layout/neato/make-graph-data.d.ts +43 -0
- package/dist/layout/neato/make-graph-data.d.ts.map +1 -0
- package/dist/layout/neato/matrix-ops.d.ts +46 -0
- package/dist/layout/neato/matrix-ops.d.ts.map +1 -1
- package/dist/layout/neato/multispline-router.d.ts.map +1 -1
- package/dist/layout/neato/multispline.d.ts.map +1 -1
- package/dist/layout/neato/opt-arrangement.d.ts +20 -0
- package/dist/layout/neato/opt-arrangement.d.ts.map +1 -0
- package/dist/layout/neato/poly.d.ts.map +1 -1
- package/dist/layout/neato/quad-prog-solve.d.ts +44 -0
- package/dist/layout/neato/quad-prog-solve.d.ts.map +1 -0
- package/dist/layout/neato/sgd.d.ts.map +1 -1
- package/dist/layout/neato/smart-ini-x.d.ts +9 -0
- package/dist/layout/neato/smart-ini-x.d.ts.map +1 -0
- package/dist/layout/neato/splines.d.ts +1 -1
- package/dist/layout/neato/splines.d.ts.map +1 -1
- package/dist/layout/neato/start.d.ts +4 -1
- package/dist/layout/neato/start.d.ts.map +1 -1
- package/dist/layout/neato/stress.d.ts +8 -0
- package/dist/layout/neato/stress.d.ts.map +1 -1
- package/dist/model/edge.d.ts +1 -1
- package/dist/model/edge.d.ts.map +1 -1
- package/dist/model/lazy-attrs.d.ts +10 -0
- package/dist/model/lazy-attrs.d.ts.map +1 -0
- package/dist/model/node.d.ts +1 -1
- package/dist/model/node.d.ts.map +1 -1
- package/dist/ortho/index.d.ts.map +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/render/color-resolve.d.ts +49 -1
- package/dist/render/color-resolve.d.ts.map +1 -1
- package/dist/render/dot/edge-draw.d.ts +1 -1
- package/dist/render/dot/edge-draw.d.ts.map +1 -1
- package/dist/render/public.d.ts.map +1 -1
- package/dist/render/svg-edge-split.d.ts +2 -0
- package/dist/render/svg-edge-split.d.ts.map +1 -1
- package/dist/render/svg-multicolor.d.ts +2 -2
- package/dist/render/svg-multicolor.d.ts.map +1 -1
- package/dist/render/xdot-public.d.ts.map +1 -1
- package/dist/render.js +2799 -927
- package/dist/render.js.map +4 -4
- package/package.json +1 -1
- package/src/async/render-async.ts +6 -0
- package/src/common/agerr.ts +96 -0
- package/src/common/arrows-shapes-poly.ts +19 -5
- package/src/common/color.ts +38 -10
- package/src/common/crand.ts +8 -2
- package/src/common/emit-once.ts +27 -0
- package/src/common/graph-init.ts +2 -1
- package/src/common/htmltable-attr-warn.ts +3 -4
- package/src/common/htmltable-emit-fill.ts +104 -11
- package/src/common/htmltable-emit-rules.ts +2 -0
- package/src/common/htmltable-emit.ts +4 -3
- package/src/common/htmltable-lex-expat.ts +96 -23
- package/src/common/htmltable-pos-runs.ts +11 -6
- package/src/common/htmltable.ts +28 -117
- package/src/common/libm-trig.ts +43 -0
- package/src/common/multicolor.ts +88 -24
- package/src/common/poly-gencode.ts +30 -10
- package/src/common/poly-init.ts +20 -1
- package/src/common/postproc.ts +4 -1
- package/src/common/random.ts +11 -1
- package/src/common/render-state.ts +36 -0
- package/src/common/splines-clip.ts +15 -12
- package/src/common/splines-geom.ts +8 -4
- package/src/common/splines-routespl.ts +2 -1
- package/src/common/textmeasure-lookup.ts +9 -2
- package/src/common/textmeasure.ts +45 -2
- package/src/gvc/anchor.ts +1 -12
- package/src/gvc/context.ts +8 -0
- package/src/gvc/device-cluster.ts +93 -10
- package/src/gvc/device-labels.ts +27 -0
- package/src/gvc/device.ts +34 -8
- package/src/gvc/first-layer.ts +26 -0
- package/src/gvc/gvrender-set-style.ts +114 -0
- package/src/gvc/usershape.ts +26 -0
- package/src/index.ts +3 -0
- package/src/layout/dot/cluster.ts +2 -1
- package/src/layout/dot/compound.ts +3 -4
- package/src/layout/dot/conc.ts +6 -5
- package/src/layout/dot/decomp.ts +3 -0
- package/src/layout/dot/edge-route-clip.ts +46 -28
- package/src/layout/dot/edge-route-routing.ts +11 -3
- package/src/layout/dot/fastgr.ts +2 -2
- package/src/layout/dot/mincross-build.ts +2 -0
- package/src/layout/dot/mincross-cross.ts +2 -0
- package/src/layout/dot/rank.ts +2 -0
- package/src/layout/dot/splines.ts +2 -1
- package/src/layout/fdp/index.ts +2 -1
- package/src/layout/fdp/tlayout-parms.ts +9 -2
- package/src/layout/fdp/xlayout.ts +10 -2
- package/src/layout/neato/__fixtures__/dijkstra-f.ts +17 -0
- package/src/layout/neato/__fixtures__/hier/c1554.gv +33 -0
- package/src/layout/neato/__fixtures__/hier/c1554.plain +26 -0
- package/src/layout/neato/__fixtures__/hier/c1554.xdot +161 -0
- package/src/layout/neato/__fixtures__/hier/cases/cycle.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/cycle.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/cycle.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/dirnone.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/dirnone.plain +11 -0
- package/src/layout/neato/__fixtures__/hier/cases/dirnone.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/epsilon.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/epsilon.plain +13 -0
- package/src/layout/neato/__fixtures__/hier/cases/epsilon.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/levelsgap.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/levelsgap.plain +8 -0
- package/src/layout/neato/__fixtures__/hier/cases/levelsgap.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/mds.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/mds.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/mds.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/multiedge.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/multiedge.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/multiedge.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/neglevelsgap.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/neglevelsgap.plain +8 -0
- package/src/layout/neato/__fixtures__/hier/cases/neglevelsgap.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/startrandom.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/startrandom.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/startrandom.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/startregular.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/startregular.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/startregular.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/tdist.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/tdist.plain +13 -0
- package/src/layout/neato/__fixtures__/hier/cases/tdist.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/cases/undirected.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/cases/undirected.plain +10 -0
- package/src/layout/neato/__fixtures__/hier/cases/undirected.stderr +0 -0
- package/src/layout/neato/__fixtures__/hier/hier-probe.gv +1 -0
- package/src/layout/neato/__fixtures__/hier/hier-probe.plain +16 -0
- package/src/layout/neato/__fixtures__/hier/hier-probe.xdot +62 -0
- package/src/layout/neato/__fixtures__/hier-imds.ts +151 -0
- package/src/layout/neato/__fixtures__/hier-majorization.ts +145 -0
- package/src/layout/neato/cdt-surface.ts +12 -22
- package/src/layout/neato/compute-hierarchy.ts +90 -0
- package/src/layout/neato/conjgrad-mkernel.ts +141 -0
- package/src/layout/neato/conjgrad.ts +208 -0
- package/src/layout/neato/constrained-majorization.ts +479 -0
- package/src/layout/neato/dijkstra.ts +218 -92
- package/src/layout/neato/edge-len.ts +2 -1
- package/src/layout/neato/fdp-adjust.ts +3 -2
- package/src/layout/neato/gts-triangle.ts +42 -0
- package/src/layout/neato/init.ts +68 -68
- package/src/layout/neato/kk.ts +2 -1
- package/src/layout/neato/kkutils.ts +96 -0
- package/src/layout/neato/make-graph-data.ts +166 -0
- package/src/layout/neato/matrix-ops.ts +138 -0
- package/src/layout/neato/multispline-router.ts +3 -3
- package/src/layout/neato/multispline.ts +3 -2
- package/src/layout/neato/opt-arrangement.ts +86 -0
- package/src/layout/neato/poly.ts +3 -2
- package/src/layout/neato/quad-prog-solve.ts +489 -0
- package/src/layout/neato/sgd.ts +5 -2
- package/src/layout/neato/smart-ini-x.ts +503 -0
- package/src/layout/neato/splines.ts +4 -4
- package/src/layout/neato/start.ts +19 -14
- package/src/layout/neato/stress.ts +28 -0
- package/src/model/edge.ts +3 -2
- package/src/model/lazy-attrs.ts +36 -0
- package/src/model/node.ts +3 -2
- package/src/ortho/index.ts +2 -1
- package/src/parser/dot.js +4 -1
- package/src/parser/dot.pegjs +5 -1
- package/src/parser/index.ts +4 -3
- package/src/render/color-resolve.ts +193 -4
- package/src/render/dot/edge-draw.ts +6 -3
- package/src/render/dot.ts +1 -1
- package/src/render/public.ts +2 -0
- package/src/render/svg-edge-split.ts +6 -4
- package/src/render/svg-multicolor.ts +4 -3
- package/src/render/svg-parallel-edge.ts +2 -2
- package/src/render/xdot-public.ts +2 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EPL-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Expected layouts for the T22 stress_majorization_with_hierarchy tests, captured
|
|
4
|
+
* from a native clang -O3 -flto=thin -arch arm64 (-DDIGCOLA) harness that links the
|
|
5
|
+
* oracle's own lib/neatogen (graphviz 16.1.0) and calls the function with a fresh
|
|
6
|
+
* libc rand()/drand48() stream (srand(1), srand48(seed)). Graphs are neato vtx_data
|
|
7
|
+
* with haveDir (edists); `g40` is a seeded random DAG (40 nodes, 70 edges).
|
|
8
|
+
* Generated data: do not hand-edit.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** One harness invocation and its native result. */
|
|
12
|
+
export interface MajorizationCase {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly graph: 'probe' | 'c1554' | 'rdag' | 'g40';
|
|
15
|
+
readonly dim: number;
|
|
16
|
+
readonly opts: number;
|
|
17
|
+
readonly maxi: number;
|
|
18
|
+
readonly levelsGap: number;
|
|
19
|
+
readonly epsilon: number;
|
|
20
|
+
/** `srand48` seed before the call. */
|
|
21
|
+
readonly seed: number;
|
|
22
|
+
/** Native return value (iterations). */
|
|
23
|
+
readonly rv: number;
|
|
24
|
+
/** Native `d_coords`, one array per axis. */
|
|
25
|
+
readonly coords: readonly (readonly number[])[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** `vtx_data` rows of the `g40` graph. */
|
|
29
|
+
export const G40_ROWS: readonly { edges: number[]; ewgts: number[]; edists: number[] }[] = [{"edges":[0,1,3,7,9,15,19,25],"ewgts":[0,1,1,1,1,1,1,1],"edists":[0,-1,-1,-1,-1,-1,-1,-1]},{"edges":[1,0,2,6,8],"ewgts":[0,1,1,1,1],"edists":[0,1,-1,-1,-1]},{"edges":[2,1],"ewgts":[0,1],"edists":[0,1]},{"edges":[3,0,4,5,18,22],"ewgts":[0,1,1,1,1,1],"edists":[0,1,-1,-1,-1,-1]},{"edges":[4,3,12],"ewgts":[0,1,1],"edists":[0,1,-1]},{"edges":[5,3,8,21,36],"ewgts":[0,1,1,1,1],"edists":[0,1,-1,-1,-1]},{"edges":[6,1,10,24,31],"ewgts":[0,1,1,1,1],"edists":[0,1,-1,-1,-1]},{"edges":[7,0,16],"ewgts":[0,1,1],"edists":[0,1,-1]},{"edges":[8,1,5,11,20,23,28,30],"ewgts":[0,1,1,1,1,1,1,1],"edists":[0,1,1,-1,-1,-1,-1,-1]},{"edges":[9,0,31],"ewgts":[0,1,1],"edists":[0,1,-1]},{"edges":[10,6,32],"ewgts":[0,1,1],"edists":[0,1,-1]},{"edges":[11,8,19,23],"ewgts":[0,1,1,1],"edists":[0,1,-1,-1]},{"edges":[12,4,13,14,15,26],"ewgts":[0,1,1,1,1,1],"edists":[0,1,-1,-1,-1,-1]},{"edges":[13,12],"ewgts":[0,1],"edists":[0,1]},{"edges":[14,12,24],"ewgts":[0,1,1],"edists":[0,1,-1]},{"edges":[15,0,12,19,21,31],"ewgts":[0,1,1,1,1,1],"edists":[0,1,1,-1,-1,-1]},{"edges":[16,7,17,18],"ewgts":[0,1,1,1],"edists":[0,1,-1,-1]},{"edges":[17,16,18,20,36],"ewgts":[0,1,1,1,1],"edists":[0,1,-1,-1,-1]},{"edges":[18,3,16,17,32,33,34],"ewgts":[0,1,1,1,1,1,1],"edists":[0,1,1,1,-1,-1,-1]},{"edges":[19,0,11,15,33,36],"ewgts":[0,1,1,1,1,1],"edists":[0,1,1,1,-1,-1]},{"edges":[20,8,17,24,26],"ewgts":[0,1,1,1,1],"edists":[0,1,1,-1,-1]},{"edges":[21,5,15,27,37],"ewgts":[0,1,1,1,1],"edists":[0,1,1,-1,-1]},{"edges":[22,3],"ewgts":[0,1],"edists":[0,1]},{"edges":[23,8,11,35],"ewgts":[0,1,1,1],"edists":[0,1,1,-1]},{"edges":[24,6,14,20,38],"ewgts":[0,1,1,1,1],"edists":[0,1,1,1,-1]},{"edges":[25,0,27,29],"ewgts":[0,1,1,1],"edists":[0,1,-1,-1]},{"edges":[26,12,20,30],"ewgts":[0,1,1,1],"edists":[0,1,1,-1]},{"edges":[27,21,25,37,39],"ewgts":[0,1,1,1,1],"edists":[0,1,1,-1,-1]},{"edges":[28,8,31,33],"ewgts":[0,1,1,1],"edists":[0,1,-1,-1]},{"edges":[29,25,34],"ewgts":[0,1,1],"edists":[0,1,-1]},{"edges":[30,8,26,36],"ewgts":[0,1,1,1],"edists":[0,1,1,-1]},{"edges":[31,6,9,15,28],"ewgts":[0,1,1,1,1],"edists":[0,1,1,1,1]},{"edges":[32,10,18,39],"ewgts":[0,1,1,1],"edists":[0,1,1,-1]},{"edges":[33,18,19,28,38],"ewgts":[0,1,1,1,1],"edists":[0,1,1,1,-1]},{"edges":[34,18,29],"ewgts":[0,1,1],"edists":[0,1,1]},{"edges":[35,23,37,38],"ewgts":[0,1,1,1],"edists":[0,1,-1,-1]},{"edges":[36,5,17,19,30,39],"ewgts":[0,1,1,1,1,1],"edists":[0,1,1,1,1,-1]},{"edges":[37,21,27,35,39],"ewgts":[0,1,1,1,1],"edists":[0,1,1,1,-1]},{"edges":[38,24,33,35],"ewgts":[0,1,1,1],"edists":[0,1,1,1]},{"edges":[39,27,32,36,37],"ewgts":[0,1,1,1,1],"edists":[0,1,1,1,1]}];
|
|
30
|
+
|
|
31
|
+
export const MAJORIZATION_CASES: readonly MajorizationCase[] = [
|
|
32
|
+
{
|
|
33
|
+
name: "probe smart", graph: 'probe', dim: 2, opts: 6, maxi: 200,
|
|
34
|
+
levelsGap: 0, epsilon: 0.0001, seed: 1, rv: 25,
|
|
35
|
+
coords: [
|
|
36
|
+
[-0.8872857689857483, 0.09007769823074341, 0.6606655120849609, -0.6603541970252991, -0.0897926613688469, 0.8866894245147705],
|
|
37
|
+
[1.0345146656036377, 0.6522425413131714, 0.00009558413876220584, 0.00009558413876220584, -0.6516568064689636, -1.0352916717529297],
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "probe smart levelsgap", graph: 'probe', dim: 2, opts: 6, maxi: 200,
|
|
42
|
+
levelsGap: 0.5, epsilon: 0.0001, seed: 1, rv: 12,
|
|
43
|
+
coords: [
|
|
44
|
+
[-0.9963757991790771, -0.015388643369078636, 0.7450122237205505, -0.7450122833251953, 0.015388717874884605, 0.9963758587837219],
|
|
45
|
+
[1.25, 0.7500000596046448, 0.2500000596046448, -0.24999994039535522, -0.7499999403953552, -1.25],
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "probe smart one iteration", graph: 'probe', dim: 2, opts: 6, maxi: 1,
|
|
50
|
+
levelsGap: 0, epsilon: 0.0001, seed: 1, rv: 1,
|
|
51
|
+
coords: [
|
|
52
|
+
[-0.6022335886955261, 0.0778207927942276, 0.6716713309288025, -0.6716711521148682, -0.07782091200351715, 0.6022335290908813],
|
|
53
|
+
[1.225775957107544, 0.5940203070640564, 0.00004230230115354061, 0.00004230230115354061, -0.5944178700447083, -1.2254630327224731],
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "probe smart no iterations (initial layout only)", graph: 'probe', dim: 2, opts: 6, maxi: 0,
|
|
58
|
+
levelsGap: 0, epsilon: 0.0001, seed: 1, rv: 0,
|
|
59
|
+
coords: [
|
|
60
|
+
[-0.52421848664645, 0.07426209500899247, 0.6209262062730561, -0.6209262062730563, -0.07426209500899264, 0.52421848664645],
|
|
61
|
+
[1.250000000000003, 0.5833333333333612, 0.08333333333334564, -0.08333333333333418, -0.5833333333333085, -1.2499999999999796],
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "c1554 smart", graph: 'c1554', dim: 2, opts: 6, maxi: 200,
|
|
66
|
+
levelsGap: 0, epsilon: 0.0001, seed: 1, rv: 3,
|
|
67
|
+
coords: [
|
|
68
|
+
[-0.2410670518875122, -0.2410670518875122, -0.2410670518875122, -0.5535792112350464, -0.2410670518875122, 0.9464221000671387, 0.5714253187179565],
|
|
69
|
+
[0, 0, 0, -0, -0, 0, -0],
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "c1554 plain init", graph: 'c1554', dim: 2, opts: 2, maxi: 200,
|
|
74
|
+
levelsGap: 0, epsilon: 0.0001, seed: 7, rv: 43,
|
|
75
|
+
coords: [
|
|
76
|
+
[-0.2458767145872116, -0.2458767145872116, -0.22192083299160004, -0.7836974859237671, 0.8581828474998474, 0.7025991082191467, -0.06341015547513962],
|
|
77
|
+
[0.6164672374725342, 0.6164672374725342, 0.6364861130714417, -1.054526448249817, -0.7265203595161438, 0.27123403549194336, -0.35960766673088074],
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "rdag smart", graph: 'rdag', dim: 2, opts: 6, maxi: 200,
|
|
82
|
+
levelsGap: 0, epsilon: 0.0001, seed: 1, rv: 72,
|
|
83
|
+
coords: [
|
|
84
|
+
[2.106701612472534, -8.845921516418457, 1.4982528686523438, -2.2527546882629395, 2.649675130844116, -2.313718318939209, -1.8075244426727295, -1.0636497735977173, 0.8014016151428223, -0.03322816640138626, -1.123450517654419, -1.6615859270095825, 0.2914482355117798, 0.2493419051170349, 0.6228430271148682, -0.3555810749530792, -0.4617708921432495, 2.9189040660858154, 1.533380150794983, 0.7932320237159729, 0.1701584756374359, 1.095284104347229, 0.38050132989883423, 1.773295283317566, 1.6413025856018066, 1.0647715330123901, 0.2310933619737625, 0.4141763746738434, 0.9322999119758606, -0.6915730237960815, -1.4681257009506226, 1.2065339088439941, -0.40464577078819275, 0.10893333703279495],
|
|
85
|
+
[3.935408592224121, 3.935408592224121, 3.128432273864746, 3.128432273864746, 3.128432273864746, 1.9458963871002197, 1.9458963871002197, 1.726983666419983, 2.210876226425171, 1.726983666419983, 1.0466965436935425, 1.0466965436935425, 1.0466965436935425, 1.0466965436935425, 0.32058167457580566, 0.2997589111328125, 0.2997589111328125, -1.0779701471328735, -0.2633209824562073, -0.3105449080467224, -1.0779701471328735, -1.0779701471328735, -1.0779701471328735, -1.1902680397033691, -1.716605544090271, -1.716605544090271, -2.100672960281372, -2.100672960281372, -2.3096060752868652, -2.475639581680298, -3.3348419666290283, -3.3348419666290283, -3.3348419666290283, -3.41929292678833],
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "rdag smart levelsgap", graph: 'rdag', dim: 2, opts: 6, maxi: 200,
|
|
90
|
+
levelsGap: 0.5, epsilon: 0.0001, seed: 1, rv: 39,
|
|
91
|
+
coords: [
|
|
92
|
+
[-12301.8642578125, -40660.5, -9774.89453125, 11809.7578125, -6476.82958984375, -8734.6494140625, 6348.06201171875, -4525.720703125, -6536.2080078125, -3894.280517578125, 1880.763916015625, -4501.078125, -2043.1739501953125, 7986.6591796875, 3269.953857421875, -404.2750549316406, 1482.980224609375, 12090.8525390625, 8846.69921875, 6487.10302734375, 2671.696044921875, -1566.1962890625, 4674.43212890625, 3535.6015625, 4471.04833984375, 6479.380859375, -0.44706612825393677, -958.3173217773438, 8040.14599609375, 5781.75244140625, 420.898193359375, 1973.5867919921875, -157.3118438720703, 4284.37109375],
|
|
93
|
+
[4969.9560546875, 4970.4560546875, 4969.4560546875, 4968.9560546875, 4968.4560546875, 4967.4560546875, 4966.9560546875, 4965.9560546875, 4967.9560546875, 4966.4560546875, 4965.4560546875, 4963.9560546875, 4964.4560546875, 4964.9560546875, 3209.87158203125, 3208.87158203125, 3209.37158203125, -1517.34619140625, 941.6177978515625, 941.6177978515625, -1518.34619140625, -1517.84619140625, -1518.34619140625, -3001.77978515625, -3002.27978515625, -3002.77978515625, -5185.4501953125, -5185.9501953125, -6037.169921875, -8404.357421875, -10032.125, -10032.625, -10033.125, -11062.6962890625],
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "rdag smart negative levelsgap", graph: 'rdag', dim: 2, opts: 6, maxi: 200,
|
|
98
|
+
levelsGap: -1, epsilon: 0.0001, seed: 1, rv: 131,
|
|
99
|
+
coords: [
|
|
100
|
+
[0.975033164024353, -8.91601276397705, 0.5004842877388, 2.977956771850586, 1.6438225507736206, -0.07275602966547012, 2.1174063682556152, -1.1853382587432861, -0.04999632015824318, 0.354489266872406, 1.2431221008300781, 1.073130488395691, -0.6186935305595398, -1.086130976676941, 0.2677907943725586, -0.048997968435287476, 0.09275322407484055, 2.133812665939331, 1.1161925792694092, -0.7022860050201416, -0.21006172895431519, -0.41585826873779297, 0.19944527745246887, 1.0232882499694824, -0.009082501754164696, 0.6798028349876404, -0.6689338088035583, -1.152896523475647, 0.559933066368103, -1.5303906202316284, 1.2292211055755615, -1.478786587715149, -0.5989389419555664, 0.557475209236145],
|
|
101
|
+
[4.457009792327881, 3.457009792327881, 3.5111281871795654, 2.554044723510742, 3.554044723510742, 2.9412379264831543, 1.7162097692489624, 2.3648476600646973, 2.371692657470703, 1.4127448797225952, 1.007383108139038, 2.004547595977783, 1.4327563047409058, 0.4327562749385834, 0.0988132432103157, 0.9681377410888672, 0.3813791871070862, -2.0102105140686035, -0.47968974709510803, -0.47968974709510803, -0.9354557394981384, -1.598078727722168, -0.9982943534851074, -1.6566381454467773, -2.1973824501037598, -1.1973823308944702, -2.3070976734161377, -1.5450495481491089, -2.3397669792175293, -2.5018789768218994, -4.301966190338135, -3.3019661903381348, -3.345038414001465, -3.470165967941284],
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "rdag plain init levelsgap", graph: 'rdag', dim: 2, opts: 2, maxi: 200,
|
|
106
|
+
levelsGap: 1.5, epsilon: 0.0001, seed: 7, rv: 10,
|
|
107
|
+
coords: [
|
|
108
|
+
[-0.1714787483215332, -6.736390590667725, 0.16777358949184418, 0.7151613831520081, -0.3481586277484894, 0.7005362510681152, 0.5633029341697693, 0.25387802720069885, 0.16892887651920319, 0.2626030147075653, 0.32713907957077026, 0.8732405304908752, 0.017587635666131973, 0.18712081015110016, 0.1815183013677597, -0.21678774058818817, 0.039015546441078186, -0.8158586621284485, 0.37755346298217773, 0.8203425407409668, 0.6037594079971313, 0.3468809425830841, -0.022601669654250145, 0.09913724660873413, 0.14511209726333618, 0.3509961664676666, 0.3168884813785553, 0.2200707346200943, 0.10131124407052994, 0.3687672019004822, -0.5803648233413696, 0.3717065453529358, 0.3560970425605774, -0.04478844627737999],
|
|
109
|
+
[20.38235092163086, 21.88235092163086, 18.88235092163086, 17.38235092163086, 15.882349967956543, 12.882349967956543, 11.382349967956543, 8.382349967956543, 14.382349967956543, 9.882349967956543, 6.882349967956543, 2.382349967956543, 3.882349967956543, 5.382349967956543, 2.382349967956543, -0.6176499724388123, 0.8823500275611877, -2.117650032043457, -0.6176499724388123, -0.6176499724388123, -5.117650032043457, -3.617650032043457, -5.117650032043457, -6.617650032043457, -8.117650032043457, -9.617650032043457, -11.117650032043457, -12.617650032043457, -14.117650032043457, -15.617650032043457, -17.11764907836914, -18.61764907836914, -20.11764907836914, -21.61764907836914],
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: "rdag plain init 3-D", graph: 'rdag', dim: 3, opts: 2, maxi: 200,
|
|
114
|
+
levelsGap: 0, epsilon: 0.0001, seed: 7, rv: 200,
|
|
115
|
+
coords: [
|
|
116
|
+
[1.9230509996414185, -4.450254917144775, 1.3397730588912964, -2.589007616043091, 2.468080759048462, -1.613430142402649, -2.190492868423462, -0.6790580153465271, 0.5338876843452454, 0.2040603905916214, -1.497606635093689, -1.385814905166626, -0.343102365732193, -0.14492037892341614, 0.7068026661872864, -0.5179460048675537, -0.762558102607727, 2.3182451725006104, 1.2608115673065186, 0.6364292502403259, 0.9157735705375671, 0.7901390194892883, -0.35626527667045593, 0.9255744218826294, 1.3133991956710815, 0.1679213047027588, 0.9619991779327393, 0.06195592135190964, -0.10869356244802475, 0.672370970249176, -1.7973697185516357, 1.6563245058059692, 0.33709609508514404, -0.7571752667427063],
|
|
117
|
+
[3.637824296951294, 3.637824296951294, 2.7765800952911377, 2.7765800952911377, 2.7765800952911377, 1.5580389499664307, 1.5580389499664307, 1.0393105745315552, 1.9450687170028687, 1.0393105745315552, 0.9515085220336914, 0.9515085220336914, 0.9515085220336914, 0.9515085220336914, 0.34407156705856323, 0.34407156705856323, 0.34407156705856323, -0.8591142892837524, -0.7320063710212708, -0.01923421397805214, -0.8591142892837524, -0.8591142892837524, -0.8845171928405762, -1.159713864326477, -1.2608681917190552, -1.2608681917190552, -1.7222142219543457, -1.7222142219543457, -1.967499017715454, -2.4355876445770264, -2.9603357315063477, -2.9603357315063477, -2.9603357315063477, -2.9603357315063477],
|
|
118
|
+
[1.6783900260925293, -7.6042938232421875, 1.5541224479675293, 0.6140518188476562, 1.7654837369918823, 2.535907030105591, 0.8192742466926575, 2.5690112113952637, 1.3691827058792114, 1.4288212060928345, 0.41665998101234436, 1.5223040580749512, 1.2993186712265015, -0.6007012724876404, 0.6095350384712219, 0.6627642512321472, -0.005488100461661816, -0.4538416862487793, 0.8484395146369934, -0.45605137944221497, 0.2692951560020447, -1.310333013534546, -0.4890795946121216, -0.3461270034313202, -1.5077654123306274, 0.27062326669692993, -0.7134277820587158, -1.548409104347229, -0.2979923188686371, -1.650607943534851, -1.3032701015472412, -0.3259759843349457, -0.9536048769950867, -0.6662144064903259],
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: "rdag plain init tight epsilon", graph: 'rdag', dim: 2, opts: 5, maxi: 200,
|
|
123
|
+
levelsGap: 0.3, epsilon: 0.000001, seed: 3, rv: 138,
|
|
124
|
+
coords: [
|
|
125
|
+
[4881.32666015625, -11929.93359375, 3984.729736328125, 5013.54052734375, 5451.97216796875, 3440.62744140625, 3713.17822265625, 2185.936279296875, 2424.29541015625, 1528.0205078125, 2568.227783203125, 2554.77880859375, 830.9662475585938, 1267.5498046875, 58.524845123291016, 1124.128173828125, 921.0764770507812, 422.65399169921875, -1197.61767578125, -679.9918212890625, -1911.75341796875, -1896.5244140625, -523.93017578125, -913.9660034179688, -2868.36865234375, -1473.961669921875, -2835.732177734375, -2314.52685546875, -1578.99365234375, -3544.86962890625, -133.86082458496094, -4183.23779296875, -2921.099609375, -1463.163330078125],
|
|
126
|
+
[1197.1910400390625, 1197.4910888671875, 1015.1022338867188, 60.00261306762695, 59.702613830566406, 57.60552215576172, 57.30552291870117, 56.705509185791016, 59.40261459350586, 57.005523681640625, 56.40550994873047, 55.505496978759766, 55.805511474609375, 56.10551071166992, 55.50551223754883, 54.90549850463867, 55.20549774169922, 54.605499267578125, 54.90549850463867, 54.90549850463867, 54.00550079345703, 54.30550003051758, 54.00550079345703, 53.705501556396484, 53.40550231933594, 53.10550308227539, -177.1049041748047, -177.4049072265625, -177.7049102783203, -178.00491333007812, -178.30491638183594, -178.60491943359375, -1689.3165283203125, -1937.4561767578125],
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "g40 smart levelsgap", graph: 'g40', dim: 2, opts: 6, maxi: 200,
|
|
131
|
+
levelsGap: 0.4, epsilon: 0.0001, seed: 3, rv: 24,
|
|
132
|
+
coords: [
|
|
133
|
+
[-1.0094189643859863, 0.46773967146873474, -3.3577399253845215, -1.9939782619476318, 2.1472113132476807, -0.442900151014328, 0.8790810704231262, -3.9394562244415283, 2.4742016792297363, -1.820883870124817, -2.4455490112304688, 3.7843005657196045, 4.557663917541504, 7.654958724975586, 6.022160053253174, 0.9374023675918579, -3.5004780292510986, -1.2619199752807617, -3.0502116680145264, 0.0648970827460289, 2.897508382797241, -0.8611336350440979, -5.626335620880127, 4.28245735168457, 3.9111220836639404, -4.367393493652344, 5.062668323516846, -3.247391939163208, 1.5867946147918701, -6.725042819976807, 2.8278207778930664, 0.9058087468147278, -3.64738392829895, -0.300179660320282, -5.379117965698242, 2.9269683361053467, -0.2548547387123108, -0.4261185824871063, 2.303642749786377, -2.0369181632995605],
|
|
134
|
+
[6.885787487030029, 5.685787200927734, 0.8857858777046204, 6.485787391662598, 5.285787105560303, 4.085786819458008, 1.2857857942581177, 6.085787296295166, 3.6857869625091553, 3.2857868671417236, -2.718261241912842, 2.0857865810394287, 4.4857869148254395, -0.7182613015174866, 0.08173868805170059, 2.885786771774292, 4.885787010192871, 2.0857865810394287, -0.3182613253593445, 0.08173868805170059, 0.4817386865615845, -1.9182612895965576, 1.685786485671997, -1.5182613134384155, -4.318261623382568, 2.4857866764068604, -1.1182613372802734, -3.518261432647705, 0.4817386865615845, -2.31826114654541, -2.718261241912842, -3.1182613372802734, -5.138027667999268, -4.738027572631836, -5.138027667999268, -4.338027477264404, -3.9182615280151367, -5.538027763366699, -5.938027858734131, -6.3380279541015625],
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "g40 plain init", graph: 'g40', dim: 2, opts: 2, maxi: 200,
|
|
139
|
+
levelsGap: 0, epsilon: 0.0001, seed: 1, rv: 40,
|
|
140
|
+
coords: [
|
|
141
|
+
[-0.12023495882749557, -0.10719820857048035, 1.5805704593658447, 0.5768365263938904, 1.8122634887695312, -0.9591823816299438, -1.3762669563293457, 0.8809503316879272, -0.8322945237159729, 0.5418577790260315, -2.370654582977295, -2.0197994709014893, 1.8294569253921509, 3.072965145111084, 1.4248172044754028, 0.17721407115459442, -0.6475740671157837, -0.23643508553504944, -0.005045577418059111, -0.8544038534164429, 0.32631435990333557, -0.5968142151832581, 2.3127048015594482, -2.3471274375915527, -0.21284359693527222, 1.1981782913208008, 1.7212520837783813, 0.49165067076683044, -1.7203251123428345, 2.2751946449279785, 0.5792899131774902, -0.48429036140441895, -1.4397521018981934, -1.0145349502563477, 1.3649485111236572, -2.1717777252197266, -0.17960841953754425, -0.4082253575325012, -1.3772825002670288, -0.684794008731842],
|
|
142
|
+
[1.6038932800292969, 1.6038932800292969, 0.66395103931427, 1.6038932800292969, 1.6038932800292969, 0.7164790034294128, 0.66395103931427, 1.6038932800292969, 0.7164790034294128, 0.7164790034294128, -0.44643980264663696, 0.66395103931427, 0.7164790034294128, -0.2532619833946228, -0.2532619833946228, 0.66395103931427, 1.5865058898925781, 0.66395103931427, -0.2532619833946228, 0.07963717728853226, 0.07963717728853226, -0.44643980264663696, 0.66395103931427, -0.2532619833946228, -1.063781499862671, 0.66395103931427, -0.2532619833946228, -1.063781499862671, 0.07963717728853226, -0.44643980264663696, -0.44643980264663696, -0.44643980264663696, -1.1681492328643799, -1.1681492328643799, -1.3430408239364624, -1.1681492328643799, -1.063781499862671, -1.8904457092285156, -1.8904457092285156, -2.0402238368988037],
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
];
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
import { incircle, orient2d } from './delaunay.js';
|
|
38
38
|
import { InternalError } from '../../errors.js';
|
|
39
|
+
import { gtsTriangleEnclosing } from './gts-triangle.js';
|
|
39
40
|
|
|
40
41
|
/** Triangulated surface. @see lib/neatogen/delaunay.h:surface_t */
|
|
41
42
|
export interface Surface {
|
|
@@ -354,14 +355,14 @@ class Cdt {
|
|
|
354
355
|
|
|
355
356
|
if (this.inCircle(v1, v2, v3, v4) > 0) {
|
|
356
357
|
const en = this.edgeOrNew(v3, v4);
|
|
357
|
-
// f3
|
|
358
|
-
//
|
|
359
|
-
// (
|
|
360
|
-
//
|
|
358
|
+
// C: f3 = gts_face_new(en, e5, e2), f4 = gts_face_new(en, e3, e4).
|
|
359
|
+
// The stored ring starts at C's t->e1 (en) because gts_triangle_vertices
|
|
360
|
+
// reads (e1-only, e1∩e2, e2-only): f3 → (v3, v4, v2), f4 → (v4, v3, v1).
|
|
361
|
+
// That is the vertex order mkSurface emits and triCenter sums in.
|
|
361
362
|
this.removeFace(f1);
|
|
362
363
|
this.removeFace(f2);
|
|
363
|
-
const f3 = this.addFace([v4, v2,
|
|
364
|
-
const f4 = this.addFace([
|
|
364
|
+
const f3 = this.addFace([v3, v4, v2], [en, e5, e2]);
|
|
365
|
+
const f4 = this.addFace([v4, v3, v1], [en, e3, e4]);
|
|
365
366
|
|
|
366
367
|
this.swapIfInCircle(f3, v4, v2, v3, e5, e2, en);
|
|
367
368
|
this.swapIfInCircle(f4, v1, v4, v3, e4, en, e3);
|
|
@@ -644,8 +645,6 @@ class Cdt {
|
|
|
644
645
|
}
|
|
645
646
|
}
|
|
646
647
|
|
|
647
|
-
const SQRT3 = 1.73205080756887729;
|
|
648
|
-
|
|
649
648
|
/**
|
|
650
649
|
* Build the constrained Delaunay surface over n points with nsegs directed
|
|
651
650
|
* constraint segments (segs[2k], segs[2k+1]), removing hole faces.
|
|
@@ -659,21 +658,12 @@ export function mkSurface(
|
|
|
659
658
|
const py = y.slice(0, n);
|
|
660
659
|
|
|
661
660
|
// gts_triangle_enclosing(points, scale=100)
|
|
662
|
-
let xmin = px[0]!; let xmax = px[0]!;
|
|
663
|
-
let ymin = py[0]!; let ymax = py[0]!;
|
|
664
|
-
for (let i = 1; i < n; i++) {
|
|
665
|
-
if (px[i]! > xmax) xmax = px[i]!;
|
|
666
|
-
else if (px[i]! < xmin) xmin = px[i]!;
|
|
667
|
-
if (py[i]! > ymax) ymax = py[i]!;
|
|
668
|
-
else if (py[i]! < ymin) ymin = py[i]!;
|
|
669
|
-
}
|
|
670
|
-
const xo = (xmax + xmin) / 2;
|
|
671
|
-
const yo = (ymax + ymin) / 2;
|
|
672
|
-
let r = 100 * Math.hypot(xmax - xo, ymax - yo);
|
|
673
|
-
if (r === 0) r = 100;
|
|
674
661
|
const s0 = n;
|
|
675
|
-
|
|
676
|
-
|
|
662
|
+
const enc = gtsTriangleEnclosing(px, py, n, 100);
|
|
663
|
+
for (const [ex, ey] of enc) {
|
|
664
|
+
px.push(ex);
|
|
665
|
+
py.push(ey);
|
|
666
|
+
}
|
|
677
667
|
|
|
678
668
|
const cdt = new Cdt(px, py);
|
|
679
669
|
// tri(): constraint edges are created BEFORE the vertices are inserted,
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EPL-2.0
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Partition graph nodes into levels by the minimizer of the hierarchy energy.
|
|
5
|
+
*
|
|
6
|
+
* @see lib/neatogen/compute_hierarchy.c
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { VtxData } from './dijkstra.js';
|
|
10
|
+
import { quicksortPlace } from './kkutils.js';
|
|
11
|
+
import { computeYCoords } from './opt-arrangement.js';
|
|
12
|
+
|
|
13
|
+
/** Result of `compute_hierarchy` on success (C return value 0). */
|
|
14
|
+
export interface Hierarchy {
|
|
15
|
+
/** Node ids sorted by `y`; level `k` is `ordering[levels[k-1]..levels[k])`. */
|
|
16
|
+
ordering: Int32Array;
|
|
17
|
+
/** Start index (in `ordering`) of every level but the first; `[n]` when there is one level. */
|
|
18
|
+
levels: Int32Array;
|
|
19
|
+
/** C `*num_levelsp` (0 means a single level, `levels = [n]`). */
|
|
20
|
+
numLevels: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Count the gaps wider than `tol` between consecutive sorted `y` values.
|
|
25
|
+
* @see lib/neatogen/compute_hierarchy.c:compute_hierarchy
|
|
26
|
+
*/
|
|
27
|
+
function countLevels(y: Float64Array, ordering: Int32Array, n: number, tol: number): number {
|
|
28
|
+
let numLevels = 0;
|
|
29
|
+
for (let i = 1; i < n; i++) {
|
|
30
|
+
if (y[ordering[i]!]! - y[ordering[i - 1]!]! > tol) numLevels++;
|
|
31
|
+
}
|
|
32
|
+
return numLevels;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Fill the level start indices (a SINGLE_LINK clustering).
|
|
37
|
+
* @see lib/neatogen/compute_hierarchy.c:compute_hierarchy
|
|
38
|
+
*/
|
|
39
|
+
function fillLevels(
|
|
40
|
+
y: Float64Array,
|
|
41
|
+
ordering: Int32Array,
|
|
42
|
+
n: number,
|
|
43
|
+
tol: number,
|
|
44
|
+
numLevels: number,
|
|
45
|
+
): Int32Array {
|
|
46
|
+
if (numLevels === 0) {
|
|
47
|
+
const levels = new Int32Array(1);
|
|
48
|
+
levels[0] = n;
|
|
49
|
+
return levels;
|
|
50
|
+
}
|
|
51
|
+
const levels = new Int32Array(numLevels);
|
|
52
|
+
let count = 0;
|
|
53
|
+
for (let i = 1; i < n; i++) {
|
|
54
|
+
if (y[ordering[i]!]! - y[ordering[i - 1]!]! > tol) levels[count++] = i;
|
|
55
|
+
}
|
|
56
|
+
return levels;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Order the nodes by `y` (computed by `computeYCoords` unless `given` is
|
|
61
|
+
* supplied) and cut a new level wherever consecutive values differ by more
|
|
62
|
+
* than `max(absTol, relTol * span / (n - 1))`. Returns `null` where C returns
|
|
63
|
+
* nonzero (`compute_y_coords` failed).
|
|
64
|
+
* @see lib/neatogen/compute_hierarchy.c:compute_hierarchy
|
|
65
|
+
*/
|
|
66
|
+
export function computeHierarchy(
|
|
67
|
+
graph: VtxData[],
|
|
68
|
+
n: number,
|
|
69
|
+
absTol: number,
|
|
70
|
+
relTol: number,
|
|
71
|
+
given: Float64Array | null,
|
|
72
|
+
): Hierarchy | null {
|
|
73
|
+
let y: Float64Array;
|
|
74
|
+
if (given) {
|
|
75
|
+
y = given;
|
|
76
|
+
} else {
|
|
77
|
+
y = new Float64Array(n);
|
|
78
|
+
if (computeYCoords(graph, n, y, n)) return null;
|
|
79
|
+
}
|
|
80
|
+
const ordering = new Int32Array(n);
|
|
81
|
+
for (let i = 0; i < n; i++) ordering[i] = i;
|
|
82
|
+
quicksortPlace(y, ordering, n);
|
|
83
|
+
|
|
84
|
+
const hierarchySpan = y[ordering[n - 1]!]! - y[ordering[0]!]!;
|
|
85
|
+
// C `MAX(a, b)` is `a > b ? a : b` (differs from Math.max only for NaN operands)
|
|
86
|
+
const relative = relTol * hierarchySpan / (n - 1);
|
|
87
|
+
const tol = absTol > relative ? absTol : relative;
|
|
88
|
+
const numLevels = countLevels(y, ordering, n, tol);
|
|
89
|
+
return { ordering, levels: fillLevels(y, ordering, n, tol, numLevels), numLevels };
|
|
90
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EPL-2.0
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `conjugate_gradient_mkernel` and `right_mult_with_vector_ff` as the 16.1
|
|
5
|
+
* oracle executes them. The oracle is built `-O3 -flto=thin` for arm64, so a
|
|
6
|
+
* C statement `a += b * c` on floats is one `fmadd`/`fmla` (clang's default
|
|
7
|
+
* contraction), and a reduction the vectoriser took in blocks of 16 rounds
|
|
8
|
+
* the products of those leading elements before its in-order adds (strict FP
|
|
9
|
+
* forbids reassociation) while the scalar remainder is fused. `stress-kernel.ts`
|
|
10
|
+
* keeps the unfused rounding of these loops; the constrained-majorization driver
|
|
11
|
+
* needs the oracle's bits.
|
|
12
|
+
*
|
|
13
|
+
* @see lib/neatogen/conjgrad.c:conjugate_gradient_mkernel
|
|
14
|
+
* @see lib/neatogen/matrix_ops.c:right_mult_with_vector_ff
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { agerrorf } from '../../common/agerr.js';
|
|
18
|
+
import {
|
|
19
|
+
copyVectorF, maxAbsF, orthog1f, vectorsInnerProductF, vectorsSubtractionF,
|
|
20
|
+
} from './matrix-ops.js';
|
|
21
|
+
import { fmaf } from './quad-prog-solve.js';
|
|
22
|
+
|
|
23
|
+
const fr = Math.fround;
|
|
24
|
+
|
|
25
|
+
/** Width of the vectorised reduction block of `right_mult_with_vector_ff`. */
|
|
26
|
+
const RIGHT_MULT_BLOCK = 16;
|
|
27
|
+
|
|
28
|
+
/** The unexpected-zero-residual diagnostic. @see lib/neatogen/conjgrad.c */
|
|
29
|
+
const ZERO_LENGTH_MESSAGE = 'conjugate_gradient: unexpected length 0 vector\n';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* `result = packed_matrix * vector` for the packed upper triangle of a
|
|
33
|
+
* symmetric matrix: per row the first `16*floor(len/16)` products of the
|
|
34
|
+
* reduction are rounded before their adds, the rest fused; the scatter into
|
|
35
|
+
* `result[j]` is fused throughout.
|
|
36
|
+
* @see lib/neatogen/matrix_ops.c:right_mult_with_vector_ff
|
|
37
|
+
*/
|
|
38
|
+
export function rightMultWithVectorFFFused(
|
|
39
|
+
m: Float32Array, n: number, vector: Float32Array, result: Float32Array,
|
|
40
|
+
): void {
|
|
41
|
+
for (let i = 0; i < n; i++) result[i] = 0;
|
|
42
|
+
let index = 0;
|
|
43
|
+
for (let i = 0; i < n; i++) {
|
|
44
|
+
const vi = vector[i]!;
|
|
45
|
+
let res = fmaf(m[index++]!, vi, 0); // deal with main diag
|
|
46
|
+
const len = n - i - 1;
|
|
47
|
+
const blockEnd = i + 1 + (len - (len % RIGHT_MULT_BLOCK));
|
|
48
|
+
for (let j = i + 1; j < n; j++, index++) {
|
|
49
|
+
const mij = m[index]!;
|
|
50
|
+
res = j < blockEnd ? fr(res + fr(mij * vector[j]!)) : fmaf(mij, vector[j]!, res);
|
|
51
|
+
result[j] = fmaf(mij, vi, result[j]!);
|
|
52
|
+
}
|
|
53
|
+
result[i] = result[i]! + res;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** `vector1 += alpha * vector2`, fused. @see lib/neatogen/matrix_ops.c:vectors_mult_additionf */
|
|
58
|
+
function vectorsMultAdditionFused(n: number, v1: Float32Array, alpha: number, v2: Float32Array): void {
|
|
59
|
+
for (let i = 0; i < n; i++) v1[i] = fmaf(alpha, v2[i]!, v1[i]!);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Conjugate-gradient working vectors and the running `r.r`. */
|
|
63
|
+
interface CgState {
|
|
64
|
+
n: number;
|
|
65
|
+
r: Float32Array;
|
|
66
|
+
p: Float32Array;
|
|
67
|
+
Ap: Float32Array;
|
|
68
|
+
rR: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** What one conjugate-gradient iteration decided. */
|
|
72
|
+
const CgStep = { CONTINUE: 0, STOP: 1, ERROR: 2 } as const;
|
|
73
|
+
|
|
74
|
+
/** Options of {@link conjugateGradientMkernelFused} (C's trailing `tol`, `max_iterations`). */
|
|
75
|
+
export interface CgMkernelOptions {
|
|
76
|
+
tol: number;
|
|
77
|
+
maxIterations: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The residual `r = b - A*x` of the centred inputs, and `p = r`.
|
|
82
|
+
* @see lib/neatogen/conjgrad.c:conjugate_gradient_mkernel
|
|
83
|
+
*/
|
|
84
|
+
function initialState(A: Float32Array, x: Float32Array, b: Float32Array, n: number): CgState {
|
|
85
|
+
const Ax = new Float32Array(n);
|
|
86
|
+
const st: CgState = { n, r: new Float32Array(n), p: new Float32Array(n), Ap: new Float32Array(n), rR: 0 };
|
|
87
|
+
orthog1f(n, x); // centering x and b
|
|
88
|
+
orthog1f(n, b);
|
|
89
|
+
rightMultWithVectorFFFused(A, n, x, Ax);
|
|
90
|
+
orthog1f(n, Ax); // centering Ax
|
|
91
|
+
vectorsSubtractionF(n, b, Ax, st.r);
|
|
92
|
+
copyVectorF(n, st.r, st.p);
|
|
93
|
+
st.rR = vectorsInnerProductF(n, st.r, st.r);
|
|
94
|
+
return st;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* One iteration: the step along `p`, then (unless last) the new residual and
|
|
99
|
+
* search direction.
|
|
100
|
+
* @see lib/neatogen/conjgrad.c:conjugate_gradient_mkernel
|
|
101
|
+
*/
|
|
102
|
+
function cgIteration(A: Float32Array, x: Float32Array, st: CgState, last: boolean): number {
|
|
103
|
+
const { n, r, p, Ap } = st;
|
|
104
|
+
orthog1f(n, p);
|
|
105
|
+
orthog1f(n, x);
|
|
106
|
+
orthog1f(n, r);
|
|
107
|
+
rightMultWithVectorFFFused(A, n, p, Ap);
|
|
108
|
+
orthog1f(n, Ap); // centering Ap
|
|
109
|
+
const pAp = vectorsInnerProductF(n, p, Ap);
|
|
110
|
+
if (pAp === 0) return CgStep.STOP;
|
|
111
|
+
const alpha = st.rR / pAp;
|
|
112
|
+
vectorsMultAdditionFused(n, x, fr(alpha), p); // derive new x
|
|
113
|
+
if (last) return CgStep.CONTINUE;
|
|
114
|
+
vectorsMultAdditionFused(n, r, fr(-alpha), Ap);
|
|
115
|
+
const rRNew = vectorsInnerProductF(n, r, r);
|
|
116
|
+
if (st.rR === 0) {
|
|
117
|
+
agerrorf(ZERO_LENGTH_MESSAGE);
|
|
118
|
+
return CgStep.ERROR;
|
|
119
|
+
}
|
|
120
|
+
const beta = fr(rRNew / st.rR);
|
|
121
|
+
st.rR = rRNew;
|
|
122
|
+
for (let j = 0; j < n; j++) p[j] = fmaf(beta, p[j]!, r[j]!);
|
|
123
|
+
return CgStep.CONTINUE;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Solve `A*x = b` by conjugate gradients, `A` packed symmetric; `x` and `b` are
|
|
128
|
+
* centred. Returns 1 on an unexpected zero residual, else 0.
|
|
129
|
+
* @see lib/neatogen/conjgrad.c:conjugate_gradient_mkernel
|
|
130
|
+
*/
|
|
131
|
+
export function conjugateGradientMkernelFused(
|
|
132
|
+
A: Float32Array, x: Float32Array, b: Float32Array, n: number, o: CgMkernelOptions,
|
|
133
|
+
): number {
|
|
134
|
+
const st = initialState(A, x, b, n);
|
|
135
|
+
for (let i = 0; i < o.maxIterations && maxAbsF(n, st.r) > o.tol; i++) {
|
|
136
|
+
const step = cgIteration(A, x, st, i >= o.maxIterations - 1);
|
|
137
|
+
if (step === CgStep.STOP) break;
|
|
138
|
+
if (step === CgStep.ERROR) return 1;
|
|
139
|
+
}
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EPL-2.0
|
|
2
|
+
import { agerrorf } from '../../common/agerr.js';
|
|
3
|
+
import type { VtxData } from './dijkstra.js';
|
|
4
|
+
import {
|
|
5
|
+
BLOCK_NONE,
|
|
6
|
+
copyVector,
|
|
7
|
+
innerProduct,
|
|
8
|
+
maxAbs,
|
|
9
|
+
orthog1,
|
|
10
|
+
rightMultWithVector,
|
|
11
|
+
rightMultWithVectorF,
|
|
12
|
+
vectorsAddition,
|
|
13
|
+
vectorsScalarMult,
|
|
14
|
+
vectorsSubtraction,
|
|
15
|
+
} from './matrix-ops.js';
|
|
16
|
+
|
|
2
17
|
/**
|
|
3
18
|
* Conjugate gradient solvers for packed symmetric float matrices.
|
|
4
19
|
* @see lib/neatogen/conjgrad.c
|
|
@@ -157,3 +172,196 @@ export function conjugateGradientMkernel(
|
|
|
157
172
|
}
|
|
158
173
|
return 0;
|
|
159
174
|
}
|
|
175
|
+
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
// Double-precision solvers (conjugate_gradient, conjugate_gradient_f)
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Unfused block widths of the 16.1 arm64 `-O3 -flto=thin` build, which inlines
|
|
182
|
+
* `vectors_inner_product` into `conjugate_gradient` and compiles each of the
|
|
183
|
+
* three call sites differently (disassembly of `libgvplugin_neato_layout`):
|
|
184
|
+
* the initial `r.r` is vectorized in blocks of 4, `p.Ap` in blocks of 8, and
|
|
185
|
+
* the in-loop `r.r` is a plain scalar loop. In a vectorized block the products
|
|
186
|
+
* are rounded before the in-order adds; the scalar loop contracts to fmadd.
|
|
187
|
+
*/
|
|
188
|
+
const BLOCK_INITIAL_RR = 4;
|
|
189
|
+
const BLOCK_P_AP = 8;
|
|
190
|
+
|
|
191
|
+
/** Working vectors of `conjugate_gradient`. @internal */
|
|
192
|
+
interface CgWork {
|
|
193
|
+
r: Float64Array;
|
|
194
|
+
p: Float64Array;
|
|
195
|
+
Ap: Float64Array;
|
|
196
|
+
alphap: Float64Array;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* One CG step after `x += alpha*p`: update residual and direction.
|
|
201
|
+
* Returns the new `r.r`, or null for C's `goto cleanup0` (rv = 1).
|
|
202
|
+
* @see lib/neatogen/conjgrad.c:conjugate_gradient
|
|
203
|
+
*/
|
|
204
|
+
function cgNextDirection(n: number, w: CgWork, alpha: number, rR: number): number | null {
|
|
205
|
+
vectorsScalarMult(n, w.Ap, alpha, w.Ap);
|
|
206
|
+
vectorsSubtraction(n, w.r, w.Ap, w.r); // fast computation of r, the residual
|
|
207
|
+
const rRNew = innerProduct(n, w.r, w.r, BLOCK_NONE);
|
|
208
|
+
if (rR === 0) {
|
|
209
|
+
agerrorf('conjugate_gradient: unexpected length 0 vector\n');
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
const beta = rRNew / rR;
|
|
213
|
+
vectorsScalarMult(n, w.p, beta, w.p);
|
|
214
|
+
vectorsAddition(n, w.r, w.p, w.p);
|
|
215
|
+
return rRNew;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Residual setup of `conjugate_gradient`: `r = orth_b - A x`, `p = r`; `x` and
|
|
220
|
+
* `b` are orthogonalized against 1.
|
|
221
|
+
* @see lib/neatogen/conjgrad.c:conjugate_gradient
|
|
222
|
+
*/
|
|
223
|
+
function cgStart(A: VtxData[], x: Float64Array, b: Float64Array, n: number): CgWork {
|
|
224
|
+
const w: CgWork = {
|
|
225
|
+
r: new Float64Array(n), p: new Float64Array(n),
|
|
226
|
+
Ap: new Float64Array(n), alphap: new Float64Array(n),
|
|
227
|
+
};
|
|
228
|
+
const Ax = new Float64Array(n);
|
|
229
|
+
const orthB = Float64Array.from(b.subarray(0, n));
|
|
230
|
+
orthog1(n, orthB);
|
|
231
|
+
orthog1(n, x);
|
|
232
|
+
rightMultWithVector(A, n, x, Ax);
|
|
233
|
+
vectorsSubtraction(n, orthB, Ax, w.r);
|
|
234
|
+
w.p.set(w.r.subarray(0, n));
|
|
235
|
+
return w;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Solve `A x = b` by conjugate gradients; `x` and `b` are orthogonalized
|
|
240
|
+
* against 1. Returns C's `rv` (1 on the zero-length-residual failure).
|
|
241
|
+
* @see lib/neatogen/conjgrad.c:conjugate_gradient
|
|
242
|
+
*/
|
|
243
|
+
export function conjugateGradient(
|
|
244
|
+
A: VtxData[],
|
|
245
|
+
x: Float64Array,
|
|
246
|
+
b: Float64Array,
|
|
247
|
+
n: number,
|
|
248
|
+
tol: number,
|
|
249
|
+
maxIterations: number,
|
|
250
|
+
): number {
|
|
251
|
+
const w = cgStart(A, x, b, n);
|
|
252
|
+
let rR = innerProduct(n, w.r, w.r, BLOCK_INITIAL_RR);
|
|
253
|
+
|
|
254
|
+
for (let i = 0; i < maxIterations && maxAbs(n, w.r) > tol; i++) {
|
|
255
|
+
rightMultWithVector(A, n, w.p, w.Ap);
|
|
256
|
+
const pAp = innerProduct(n, w.p, w.Ap, BLOCK_P_AP);
|
|
257
|
+
if (pAp === 0) break;
|
|
258
|
+
const alpha = rR / pAp;
|
|
259
|
+
vectorsScalarMult(n, w.p, alpha, w.alphap); // derive new x
|
|
260
|
+
vectorsAddition(n, x, w.alphap, x);
|
|
261
|
+
if (i < maxIterations - 1) { // not last iteration
|
|
262
|
+
const next = cgNextDirection(n, w, alpha, rR);
|
|
263
|
+
if (next === null) return 1;
|
|
264
|
+
rR = next;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Block widths of conjugate_gradient_f's inlined sites in the same build:
|
|
272
|
+
* the initial `A x` and the in-loop `A p` row reductions and the initial
|
|
273
|
+
* `r.r` are blocks of 4, `p.Ap` blocks of 8, the in-loop `r.r` scalar.
|
|
274
|
+
* Verified bit for bit against the oracle's own libneatogen.a over random
|
|
275
|
+
* float matrices (n = 5..40, ortho1 on and off).
|
|
276
|
+
*/
|
|
277
|
+
const CGF_BLOCK_AX = 4;
|
|
278
|
+
const CGF_BLOCK_AP = 4;
|
|
279
|
+
const CGF_BLOCK_INITIAL_RR = 4;
|
|
280
|
+
const CGF_BLOCK_P_AP = 8;
|
|
281
|
+
|
|
282
|
+
/** Work vectors of one conjugate_gradient_f call. @internal */
|
|
283
|
+
interface CgfState {
|
|
284
|
+
r: Float64Array;
|
|
285
|
+
p: Float64Array;
|
|
286
|
+
Ap: Float64Array;
|
|
287
|
+
alphap: Float64Array;
|
|
288
|
+
rr: number;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Residual setup: r = orth_b - A x, p = r. `x` is centred when `ortho1`.
|
|
293
|
+
* @see lib/neatogen/conjgrad.c:conjugate_gradient_f
|
|
294
|
+
*/
|
|
295
|
+
function cgfInit(
|
|
296
|
+
A: readonly Float32Array[], x: Float64Array, b: Float64Array, n: number, ortho1: boolean,
|
|
297
|
+
): CgfState {
|
|
298
|
+
const orthB = new Float64Array(n);
|
|
299
|
+
copyVector(n, b, orthB);
|
|
300
|
+
if (ortho1) {
|
|
301
|
+
orthog1(n, orthB);
|
|
302
|
+
orthog1(n, x);
|
|
303
|
+
}
|
|
304
|
+
const Ax = new Float64Array(n);
|
|
305
|
+
rightMultWithVectorF(A, n, x, Ax, CGF_BLOCK_AX);
|
|
306
|
+
const r = new Float64Array(n);
|
|
307
|
+
vectorsSubtraction(n, orthB, Ax, r);
|
|
308
|
+
const p = new Float64Array(n);
|
|
309
|
+
copyVector(n, r, p);
|
|
310
|
+
return {
|
|
311
|
+
r, p, Ap: new Float64Array(n), alphap: new Float64Array(n),
|
|
312
|
+
rr: innerProduct(n, r, r, CGF_BLOCK_INITIAL_RR),
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Residual and direction update of a non-last iteration; returns C's `rv`
|
|
318
|
+
* (1 after reporting a zero-length residual).
|
|
319
|
+
* @see lib/neatogen/conjgrad.c:conjugate_gradient_f
|
|
320
|
+
*/
|
|
321
|
+
function cgfUpdate(n: number, alpha: number, st: CgfState): number {
|
|
322
|
+
vectorsScalarMult(n, st.Ap, alpha, st.Ap);
|
|
323
|
+
vectorsSubtraction(n, st.r, st.Ap, st.r);
|
|
324
|
+
const rrNew = innerProduct(n, st.r, st.r, BLOCK_NONE);
|
|
325
|
+
if (st.rr === 0) {
|
|
326
|
+
agerrorf('conjugate_gradient: unexpected length 0 vector\n');
|
|
327
|
+
return 1;
|
|
328
|
+
}
|
|
329
|
+
const beta = rrNew / st.rr;
|
|
330
|
+
st.rr = rrNew;
|
|
331
|
+
vectorsScalarMult(n, st.p, beta, st.p);
|
|
332
|
+
vectorsAddition(n, st.r, st.p, st.p);
|
|
333
|
+
return 0;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** Stopping rule and centring of {@link conjugateGradientF} (C's trailing parameters). */
|
|
337
|
+
export interface CgfOptions {
|
|
338
|
+
tol: number;
|
|
339
|
+
maxIterations: number;
|
|
340
|
+
ortho1: boolean;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Solves A x = b for a float** matrix with double x, b (x, b centred when
|
|
345
|
+
* `ortho1`). Returns 0, or 1 after a zero-length residual (callers test `< 0`).
|
|
346
|
+
* @see lib/neatogen/conjgrad.c:conjugate_gradient_f
|
|
347
|
+
*/
|
|
348
|
+
export function conjugateGradientF(
|
|
349
|
+
A: readonly Float32Array[],
|
|
350
|
+
x: Float64Array,
|
|
351
|
+
b: Float64Array,
|
|
352
|
+
n: number,
|
|
353
|
+
opts: CgfOptions,
|
|
354
|
+
): number {
|
|
355
|
+
const { tol, maxIterations, ortho1 } = opts;
|
|
356
|
+
const st = cgfInit(A, x, b, n, ortho1);
|
|
357
|
+
for (let i = 0; i < maxIterations && maxAbs(n, st.r) > tol; i++) {
|
|
358
|
+
rightMultWithVectorF(A, n, st.p, st.Ap, CGF_BLOCK_AP);
|
|
359
|
+
const pAp = innerProduct(n, st.p, st.Ap, CGF_BLOCK_P_AP);
|
|
360
|
+
if (pAp === 0) break;
|
|
361
|
+
const alpha = st.rr / pAp;
|
|
362
|
+
vectorsScalarMult(n, st.p, alpha, st.alphap);
|
|
363
|
+
vectorsAddition(n, x, st.alphap, x);
|
|
364
|
+
if (i < maxIterations - 1 && cgfUpdate(n, alpha, st) === 1) return 1;
|
|
365
|
+
}
|
|
366
|
+
return 0;
|
|
367
|
+
}
|