dress-graph 0.6.1 → 0.8.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 CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  **A Continuous Framework for Structural Graph Refinement**
4
4
 
5
- DRESS is a deterministic, parameter-free framework that iteratively refines the structural similarity of edges in a graph to produce a canonical fingerprint: a real-valued edge vector, obtained by converging a non-linear dynamical system to its unique fixed point. The fingerprint is isomorphism-invariant by construction, guaranteed bitwise-equal across any vertex labeling, numerically stable (no overflow, no error amplification, no undefined behavior), fast and embarrassingly parallel to compute: DRESS total runtime is O(I * m * d_max) for I iterations to convergence, and convergence is guaranteed by Birkhoff contraction.
5
+ DRESS is a deterministic, parameter-free framework that iteratively refines the structural similarity of edges in a graph to produce a canonical fingerprint: a real-valued edge vector, obtained by converging a non-linear dynamical system to its unique fixed point. The fingerprint is self-contained, isomorphism-invariant by construction, guaranteed bitwise-equal across any vertex labeling, numerically stable (no overflow, no error amplification, no undefined behavior), fast and embarrassingly parallel to compute: DRESS total runtime is O(I * m * d_max) for I iterations to convergence, and convergence is guaranteed by Birkhoff contraction.
6
6
 
7
7
  ## Quick start
8
8
 
9
9
  ```javascript
10
- import { dressFit } from 'dress-graph';
10
+ import { fit } from 'dress-graph';
11
11
 
12
- const result = await dressFit({
12
+ const result = await fit({
13
13
  numVertices: 4,
14
14
  sources: [0, 1, 2, 0],
15
15
  targets: [1, 2, 3, 3],
package/dress.d.ts CHANGED
@@ -18,6 +18,8 @@ export interface DressOptions {
18
18
  targets: Int32Array | number[];
19
19
  /** Optional edge weights (same length as sources) */
20
20
  weights?: Float64Array | number[] | null;
21
+ /** Optional vertex weights (length numVertices) */
22
+ vertexWeights?: Float64Array | number[] | null;
21
23
  /** Graph variant (default: Variant.UNDIRECTED) */
22
24
  variant?: number;
23
25
  /** Maximum fitting iterations (default: 100) */
@@ -37,8 +39,8 @@ export interface DressResult {
37
39
  edgeWeight: Float64Array;
38
40
  /** Per-edge dress similarity values */
39
41
  edgeDress: Float64Array;
40
- /** Per-node aggregated dress similarity */
41
- nodeDress: Float64Array;
42
+ /** Per-vertex aggregated dress similarity */
43
+ vertexDress: Float64Array;
42
44
  /** Number of iterations performed */
43
45
  iterations: number;
44
46
  /** Final maximum per-edge change */
@@ -48,7 +50,7 @@ export interface DressResult {
48
50
  /**
49
51
  * Run the DRESS iterative fitting algorithm on an edge list.
50
52
  */
51
- export declare function dressFit(opts: DressOptions): Promise<DressResult>;
53
+ export declare function fit(opts: DressOptions): Promise<DressResult>;
52
54
 
53
55
  export interface DRESSOptions {
54
56
  /** Number of vertices (vertex ids must be in 0..numVertices-1) */
@@ -59,6 +61,8 @@ export interface DRESSOptions {
59
61
  targets: Int32Array | number[];
60
62
  /** Optional edge weights (same length as sources) */
61
63
  weights?: Float64Array | number[] | null;
64
+ /** Optional vertex weights (length numVertices) */
65
+ vertexWeights?: Float64Array | number[] | null;
62
66
  /** Graph variant (default: Variant.UNDIRECTED) */
63
67
  variant?: number;
64
68
  /** Pre-compute neighbourhood intercepts (default: false) */
@@ -86,6 +90,8 @@ export interface DeltaDressOptions {
86
90
  targets: Int32Array | number[];
87
91
  /** Optional edge weights (same length as sources) */
88
92
  weights?: Float64Array | number[] | null;
93
+ /** Optional vertex weights (length numVertices) */
94
+ vertexWeights?: Float64Array | number[] | null;
89
95
  /** Vertices to remove per subset (default: 0 = original graph) */
90
96
  k?: number;
91
97
  /** Graph variant (default: Variant.UNDIRECTED) */
@@ -94,26 +100,81 @@ export interface DeltaDressOptions {
94
100
  maxIterations?: number;
95
101
  /** Convergence threshold / bin width (default: 1e-6) */
96
102
  epsilon?: number;
103
+ /** Number of random subgraphs to sample (0 = exhaustive, default: 0) */
104
+ nSamples?: number;
105
+ /** Random seed for sampling (default: 0) */
106
+ seed?: number;
97
107
  /** Pre-compute neighbourhood intercepts (default: false) */
98
108
  precompute?: boolean;
99
109
  /** Return per-subgraph edge values (default: false) */
100
110
  keepMultisets?: boolean;
111
+ /** Compute histogram (default: true) */
112
+ computeHistogram?: boolean;
101
113
  }
102
114
 
103
115
  export interface DeltaDressResult {
104
- /** Bin counts of edge delta values (as Float64 for BigInt-free access) */
105
- histogram: Float64Array;
106
- /** Number of histogram bins (floor(dmax/epsilon) + 1; dmax = 2 unweighted) */
107
- histSize: number;
116
+ /** Exact sparse histogram entries as (value, count) pairs */
117
+ histogram: HistogramEntry[];
108
118
  /** Per-subgraph edge values, row-major C(N,k) × E (NaN = removed edge; null when not requested) */
109
119
  multisets: Float64Array | null;
110
120
  /** Number of subgraphs C(N,k) */
111
121
  numSubgraphs: number;
112
122
  }
113
123
 
124
+ export interface HistogramEntry {
125
+ value: number;
126
+ count: number;
127
+ }
128
+
114
129
  /**
115
130
  * Compute the Delta-k-DRESS histogram by exhaustively removing
116
131
  * all k-vertex subsets and measuring edge similarity changes.
117
132
  */
118
- export declare function deltaDressFit(opts: DeltaDressOptions): Promise<DeltaDressResult>;
133
+ export declare function deltaFit(opts: DeltaDressOptions): Promise<DeltaDressResult>;
134
+
135
+ export interface NablaDressOptions {
136
+ /** Number of vertices (vertex ids must be in 0..numVertices-1) */
137
+ numVertices: number;
138
+ /** Edge source vertices (0-based) */
139
+ sources: Int32Array | number[];
140
+ /** Edge target vertices (0-based) */
141
+ targets: Int32Array | number[];
142
+ /** Optional edge weights (same length as sources) */
143
+ weights?: Float64Array | number[] | null;
144
+ /** Optional vertex weights (length numVertices) */
145
+ vertexWeights?: Float64Array | number[] | null;
146
+ /** Vertices to remove per tuple (default: 0 = original graph) */
147
+ k?: number;
148
+ /** Graph variant (default: Variant.UNDIRECTED) */
149
+ variant?: number;
150
+ /** Maximum fitting iterations (default: 100) */
151
+ maxIterations?: number;
152
+ /** Convergence threshold / bin width (default: 1e-6) */
153
+ epsilon?: number;
154
+ /** Number of random tuples to sample (0 = exhaustive, default: 0) */
155
+ nSamples?: number;
156
+ /** Random seed for sampling (default: 0) */
157
+ seed?: number;
158
+ /** Pre-compute neighbourhood intercepts (default: false) */
159
+ precompute?: boolean;
160
+ /** Return per-tuple edge values (default: false) */
161
+ keepMultisets?: boolean;
162
+ /** Compute histogram (default: true) */
163
+ computeHistogram?: boolean;
164
+ }
165
+
166
+ export interface NablaDressResult {
167
+ /** Exact sparse histogram entries as (value, count) pairs */
168
+ histogram: HistogramEntry[];
169
+ /** Per-tuple edge values, row-major (null when not requested) */
170
+ multisets: Float64Array | null;
171
+ /** Number of tuples */
172
+ numTuples: number;
173
+ }
174
+
175
+ /**
176
+ * Compute the Nabla-k-DRESS histogram by exhaustively removing
177
+ * all k-vertex tuples and measuring edge similarity changes.
178
+ */
179
+ export declare function nablaFit(opts: NablaDressOptions): Promise<NablaDressResult>;
119
180
 
package/dress.js CHANGED
@@ -5,9 +5,9 @@
5
5
  *
6
6
  * Usage (ES module):
7
7
  *
8
- * import { dressFit } from './dress.js';
8
+ * import { fit } from './dress.js';
9
9
  *
10
- * const result = await dressFit({
10
+ * const result = await fit({
11
11
  * numVertices: 4,
12
12
  * sources: [0, 1, 2, 0],
13
13
  * targets: [1, 2, 3, 3],
@@ -75,7 +75,7 @@ export const Variant = Object.freeze({
75
75
  * @property {Int32Array} targets - Edge target vertices
76
76
  * @property {Float64Array} edgeWeight - Per-edge variant weights
77
77
  * @property {Float64Array} edgeDress - Per-edge dress similarity
78
- * @property {Float64Array} nodeDress - Per-node aggregated similarity
78
+ * @property {Float64Array} vertexDress - Per-vertex aggregated similarity
79
79
  * @property {number} iterations - Iterations performed
80
80
  * @property {number} delta - Final max per-edge change
81
81
  */
@@ -86,7 +86,7 @@ export const Variant = Object.freeze({
86
86
  * @param {DressOptions} opts
87
87
  * @returns {Promise<DressResult>}
88
88
  */
89
- export async function dressFit(opts) {
89
+ export async function fit(opts) {
90
90
  const M = await getModule();
91
91
 
92
92
  const N = opts.numVertices;
@@ -104,7 +104,7 @@ export async function dressFit(opts) {
104
104
  const epsilon = opts.epsilon ?? 1e-6;
105
105
  const precompute = (opts.precomputeIntercepts ?? false) ? 1 : 0;
106
106
 
107
- // Allocate C arrays (ownership transfers to dress.c — freed by free_dress_graph)
107
+ // Allocate C arrays (ownership transfers to dress.c — freed by dress_free_graph)
108
108
  const uPtr = M._malloc(E * 4);
109
109
  const vPtr = M._malloc(E * 4);
110
110
 
@@ -128,10 +128,24 @@ export async function dressFit(opts) {
128
128
  }
129
129
  }
130
130
 
131
- // Call init_dress_graph
132
- const g = M._init_dress_graph(N, E, uPtr, vPtr, wPtr, variant, precompute);
131
+ // vertex weights (nullable)
132
+ let nwPtr = 0; // NULL
133
+ if (opts.vertexWeights) {
134
+ if (opts.vertexWeights.length !== N) {
135
+ throw new Error(`vertexWeights (${opts.vertexWeights.length}) must equal vertex count (${N})`);
136
+ }
137
+ nwPtr = M._malloc(N * 8);
138
+ const heapF64 = M.HEAPF64;
139
+ const nw = opts.vertexWeights;
140
+ for (let i = 0; i < N; i++) {
141
+ heapF64[(nwPtr >> 3) + i] = nw[i];
142
+ }
143
+ }
144
+
145
+ // Call dress_init_graph
146
+ const g = M._dress_init_graph(N, E, uPtr, vPtr, wPtr, nwPtr, variant, precompute);
133
147
  if (g === 0) {
134
- throw new Error('init_dress_graph returned NULL');
148
+ throw new Error('dress_init_graph returned NULL');
135
149
  }
136
150
 
137
151
  // Allocate output params
@@ -154,20 +168,21 @@ export async function dressFit(opts) {
154
168
  // offset 20: *adj_offset (ptr32)
155
169
  // offset 24: *adj_target (ptr32)
156
170
  // offset 28: *adj_edge_idx (ptr32)
157
- // offset 32: max_degree (i32)
158
- // offset 36: *W (ptr32) raw input weights
171
+ // offset 32: max_degree (i32)
172
+ // offset 36: *W (ptr32)
159
173
  // offset 40: *edge_weight (ptr32)
160
- // offset 48: *edge_dress (ptr32)
161
- // offset 52: *edge_dress_next (ptr32)
162
- // offset 56: *node_dress (ptr32)
163
- const ewPtr = M.getValue(g + 44, 'i32'); // edge_weight pointer
164
- const edPtr = M.getValue(g + 48, 'i32'); // edge_dress pointer
165
- const ndPtr = M.getValue(g + 56, 'i32'); // node_dress pointer
174
+ // offset 44: *edge_dress (ptr32)
175
+ // offset 48: *edge_dress_next (ptr32)
176
+ // offset 52: *vertex_dress (ptr32)
177
+ // offset 56: *NW (ptr32)
178
+ const ewPtr = M.getValue(g + 40, 'i32'); // edge_weight pointer
179
+ const edPtr = M.getValue(g + 44, 'i32'); // edge_dress pointer
180
+ const ndPtr = M.getValue(g + 52, 'i32'); // vertex_dress pointer
166
181
 
167
182
  // Copy results into JS-owned typed arrays
168
183
  const edgeWeight = new Float64Array(E);
169
184
  const edgeDress = new Float64Array(E);
170
- const nodeDress = new Float64Array(N);
185
+ const vertexDress = new Float64Array(N);
171
186
 
172
187
  const heapF64 = M.HEAPF64;
173
188
  for (let i = 0; i < E; i++) {
@@ -175,7 +190,7 @@ export async function dressFit(opts) {
175
190
  edgeDress[i] = heapF64[(edPtr >> 3) + i];
176
191
  }
177
192
  for (let i = 0; i < N; i++) {
178
- nodeDress[i] = heapF64[(ndPtr >> 3) + i];
193
+ vertexDress[i] = heapF64[(ndPtr >> 3) + i];
179
194
  }
180
195
 
181
196
  // Copy sources/targets before free
@@ -187,7 +202,7 @@ export async function dressFit(opts) {
187
202
  }
188
203
 
189
204
  // Clean up
190
- M._free_dress_graph(g);
205
+ M._dress_free_graph(g);
191
206
  M._free(iterPtr);
192
207
  M._free(deltaPtr);
193
208
 
@@ -196,7 +211,7 @@ export async function dressFit(opts) {
196
211
  targets: targetsOut,
197
212
  edgeWeight: edgeWeight,
198
213
  edgeDress: edgeDress,
199
- nodeDress: nodeDress,
214
+ vertexDress: vertexDress,
200
215
  iterations: iterations,
201
216
  delta: delta,
202
217
  };
@@ -270,8 +285,16 @@ export class DRESS {
270
285
  }
271
286
  }
272
287
 
273
- const g = M._init_dress_graph(N, E, uPtr, vPtr, wPtr, variant, precompute);
274
- if (g === 0) throw new Error('init_dress_graph returned NULL');
288
+ let nwPtr = 0;
289
+ if (opts.vertexWeights && opts.vertexWeights.length === N) {
290
+ nwPtr = M._malloc(N * 8);
291
+ for (let i = 0; i < N; i++) {
292
+ M.HEAPF64[(nwPtr >> 3) + i] = opts.vertexWeights[i];
293
+ }
294
+ }
295
+
296
+ const g = M._dress_init_graph(N, E, uPtr, vPtr, wPtr, nwPtr, variant, precompute);
297
+ if (g === 0) throw new Error('dress_init_graph returned NULL');
275
298
 
276
299
  return new DRESS(M, g, N, E, opts.sources, opts.targets);
277
300
  }
@@ -317,20 +340,20 @@ export class DRESS {
317
340
  const N = this._n;
318
341
 
319
342
  // WASM32 offsets
320
- const ewPtr = M.getValue(this._g + 44, 'i32');
321
- const edPtr = M.getValue(this._g + 48, 'i32');
322
- const ndPtr = M.getValue(this._g + 56, 'i32');
343
+ const ewPtr = M.getValue(this._g + 40, 'i32');
344
+ const edPtr = M.getValue(this._g + 44, 'i32');
345
+ const ndPtr = M.getValue(this._g + 52, 'i32');
323
346
 
324
347
  const edgeWeight = new Float64Array(E);
325
348
  const edgeDress = new Float64Array(E);
326
- const nodeDress = new Float64Array(N);
349
+ const vertexDress = new Float64Array(N);
327
350
 
328
351
  for (let i = 0; i < E; i++) {
329
352
  edgeWeight[i] = M.HEAPF64[(ewPtr >> 3) + i];
330
353
  edgeDress[i] = M.HEAPF64[(edPtr >> 3) + i];
331
354
  }
332
355
  for (let i = 0; i < N; i++) {
333
- nodeDress[i] = M.HEAPF64[(ndPtr >> 3) + i];
356
+ vertexDress[i] = M.HEAPF64[(ndPtr >> 3) + i];
334
357
  }
335
358
 
336
359
  return {
@@ -338,19 +361,166 @@ export class DRESS {
338
361
  targets: new Int32Array(this._targets),
339
362
  edgeWeight,
340
363
  edgeDress,
341
- nodeDress,
364
+ vertexDress,
342
365
  iterations: 0,
343
366
  delta: 0,
344
367
  };
345
368
  }
346
369
 
370
+ /**
371
+ * Compute Δ^k-DRESS on this persistent graph.
372
+ * @param {number} [k=0]
373
+ * @param {number} [maxIterations=100]
374
+ * @param {number} [epsilon=1e-6]
375
+ * @param {number} [nSamples=0]
376
+ * @param {number} [seed=0]
377
+ * @param {boolean} [keepMultisets=false]
378
+ * @param {boolean} [computeHistogram=true]
379
+ * @returns {DeltaDressResult}
380
+ */
381
+ deltaFit(k = 0, maxIterations = 100, epsilon = 1e-6,
382
+ nSamples = 0, seed = 0,
383
+ keepMultisets = false, computeHistogram = true) {
384
+ if (!this._g) throw new Error('DRESS already freed');
385
+ const M = this._M;
386
+ const E = this._e;
387
+
388
+ const keepMS = keepMultisets ? 1 : 0;
389
+ const histSizePtr = M._malloc(4);
390
+
391
+ let msPtrPtr = 0;
392
+ let numSubPtr = 0;
393
+ if (keepMS) {
394
+ msPtrPtr = M._malloc(4);
395
+ numSubPtr = M._malloc(8);
396
+ M.setValue(msPtrPtr, 0, 'i32');
397
+ M.setValue(numSubPtr, 0, 'i32');
398
+ M.setValue(numSubPtr + 4, 0, 'i32');
399
+ }
400
+
401
+ const histPtr = M._dress_delta_fit_strided(
402
+ this._g, k, maxIterations, epsilon,
403
+ nSamples, seed,
404
+ computeHistogram ? histSizePtr : 0,
405
+ keepMS, msPtrPtr || 0, numSubPtr || 0,
406
+ 0, 1);
407
+
408
+ const histSize = M.getValue(histSizePtr, 'i32');
409
+
410
+ const histogram = new Array(histSize);
411
+ for (let i = 0; i < histSize; i++) {
412
+ const value = M.HEAPF64[(histPtr >> 3) + i * 2];
413
+ const countLo = M.HEAPU32[(histPtr >> 2) + i * 4 + 2];
414
+ const countHi = M.HEAPU32[(histPtr >> 2) + i * 4 + 3];
415
+ histogram[i] = { value, count: countHi * 4294967296 + countLo };
416
+ }
417
+
418
+ let multisets = null;
419
+ let numSubgraphs = 0;
420
+ if (keepMS && msPtrPtr) {
421
+ const msPtr = M.getValue(msPtrPtr, 'i32');
422
+ const nsLo = M.HEAPU32[(numSubPtr >> 2)];
423
+ const nsHi = M.HEAP32[(numSubPtr >> 2) + 1];
424
+ numSubgraphs = nsHi * 4294967296 + nsLo;
425
+
426
+ if (msPtr !== 0 && numSubgraphs > 0) {
427
+ const totalVals = numSubgraphs * E;
428
+ multisets = new Float64Array(totalVals);
429
+ for (let i = 0; i < totalVals; i++) {
430
+ multisets[i] = M.HEAPF64[(msPtr >> 3) + i];
431
+ }
432
+ M._free(msPtr);
433
+ }
434
+ M._free(msPtrPtr);
435
+ M._free(numSubPtr);
436
+ }
437
+
438
+ if (histPtr) M._free(histPtr);
439
+ M._free(histSizePtr);
440
+
441
+ return { histogram, multisets, numSubgraphs };
442
+ }
443
+
444
+ /**
445
+ * Compute ∇^k-DRESS on this persistent graph.
446
+ * @param {number} [k=0]
447
+ * @param {number} [maxIterations=100]
448
+ * @param {number} [epsilon=1e-6]
449
+ * @param {number} [nSamples=0]
450
+ * @param {number} [seed=0]
451
+ * @param {boolean} [keepMultisets=false]
452
+ * @param {boolean} [computeHistogram=true]
453
+ * @returns {NablaDressResult}
454
+ */
455
+ nablaFit(k = 0, maxIterations = 100, epsilon = 1e-6,
456
+ nSamples = 0, seed = 0,
457
+ keepMultisets = false, computeHistogram = true) {
458
+ if (!this._g) throw new Error('DRESS already freed');
459
+ const M = this._M;
460
+ const E = this._e;
461
+
462
+ const keepMS = keepMultisets ? 1 : 0;
463
+ const histSizePtr = M._malloc(4);
464
+
465
+ let msPtrPtr = 0;
466
+ let numTupPtr = 0;
467
+ if (keepMS) {
468
+ msPtrPtr = M._malloc(4);
469
+ numTupPtr = M._malloc(8);
470
+ M.setValue(msPtrPtr, 0, 'i32');
471
+ M.setValue(numTupPtr, 0, 'i32');
472
+ M.setValue(numTupPtr + 4, 0, 'i32');
473
+ }
474
+
475
+ const histPtr = M._dress_nabla_fit(
476
+ this._g, k, maxIterations, epsilon,
477
+ nSamples, seed,
478
+ computeHistogram ? histSizePtr : 0,
479
+ keepMS, msPtrPtr || 0, numTupPtr || 0);
480
+
481
+ const histSize = M.getValue(histSizePtr, 'i32');
482
+
483
+ const histogram = new Array(histSize);
484
+ for (let i = 0; i < histSize; i++) {
485
+ const value = M.HEAPF64[(histPtr >> 3) + i * 2];
486
+ const countLo = M.HEAPU32[(histPtr >> 2) + i * 4 + 2];
487
+ const countHi = M.HEAPU32[(histPtr >> 2) + i * 4 + 3];
488
+ histogram[i] = { value, count: countHi * 4294967296 + countLo };
489
+ }
490
+
491
+ let multisets = null;
492
+ let numTuples = 0;
493
+ if (keepMS && msPtrPtr) {
494
+ const msPtr = M.getValue(msPtrPtr, 'i32');
495
+ const ntLo = M.HEAPU32[(numTupPtr >> 2)];
496
+ const ntHi = M.HEAP32[(numTupPtr >> 2) + 1];
497
+ numTuples = ntHi * 4294967296 + ntLo;
498
+
499
+ if (msPtr !== 0 && numTuples > 0) {
500
+ const totalVals = numTuples * E;
501
+ multisets = new Float64Array(totalVals);
502
+ for (let i = 0; i < totalVals; i++) {
503
+ multisets[i] = M.HEAPF64[(msPtr >> 3) + i];
504
+ }
505
+ M._free(msPtr);
506
+ }
507
+ M._free(msPtrPtr);
508
+ M._free(numTupPtr);
509
+ }
510
+
511
+ if (histPtr) M._free(histPtr);
512
+ M._free(histSizePtr);
513
+
514
+ return { histogram, multisets, numTuples };
515
+ }
516
+
347
517
  /**
348
518
  * Free the underlying C graph.
349
519
  */
350
520
  free() {
351
521
  if (this._g) {
352
522
  const M = this._M;
353
- M._free_dress_graph(this._g);
523
+ M._dress_free_graph(this._g);
354
524
  M._free(this._iterPtr);
355
525
  M._free(this._deltaPtr);
356
526
  this._g = 0;
@@ -372,10 +542,17 @@ export class DRESS {
372
542
  * @property {boolean} [precompute=false] - Pre-compute intercepts
373
543
  */
374
544
 
545
+ /**
546
+ * @typedef {Object} HistogramEntry
547
+ * @property {number} value - Exact DRESS value
548
+ * @property {number} count - Number of occurrences of that value
549
+ */
550
+
375
551
  /**
376
552
  * @typedef {Object} DeltaDressResult
377
- * @property {Float64Array} histogram - Bin counts (as Float64 for BigInt-free access)
378
- * @property {number} histSize - Number of bins
553
+ * @property {HistogramEntry[]} histogram - Exact sparse histogram entries
554
+ * @property {Float64Array|null} multisets - Per-subgraph edge values, row-major C(N,k) x E
555
+ * @property {number} numSubgraphs - Number of subgraphs C(N,k)
379
556
  */
380
557
 
381
558
  /**
@@ -387,7 +564,7 @@ export class DRESS {
387
564
  * @param {DeltaDressOptions} opts
388
565
  * @returns {Promise<DeltaDressResult>}
389
566
  */
390
- export async function deltaDressFit(opts) {
567
+ export async function deltaFit(opts) {
391
568
  const M = await getModule();
392
569
 
393
570
  const N = opts.numVertices;
@@ -401,12 +578,13 @@ export async function deltaDressFit(opts) {
401
578
  const variant = opts.variant ?? Variant.UNDIRECTED;
402
579
  const maxIter = opts.maxIterations ?? 100;
403
580
  const epsilon = opts.epsilon ?? 1e-6;
581
+ const nSamples = opts.nSamples ?? 0;
582
+ const seed = opts.seed ?? 0;
404
583
  const precompute = (opts.precompute ?? false) ? 1 : 0;
405
584
  const keepMS = (opts.keepMultisets ?? false) ? 1 : 0;
406
- const offset = opts.offset ?? 0;
407
- const stride = opts.stride ?? 1;
585
+ const computeHist = (opts.computeHistogram ?? true) ? 1 : 0;
408
586
 
409
- // Allocate C arrays (ownership transfers to init_dress_graph)
587
+ // Allocate C arrays (ownership transfers to dress_init_graph)
410
588
  const uPtr = M._malloc(E * 4);
411
589
  const vPtr = M._malloc(E * 4);
412
590
 
@@ -427,10 +605,19 @@ export async function deltaDressFit(opts) {
427
605
  }
428
606
  }
429
607
 
608
+ let nwPtr = 0;
609
+ if (opts.vertexWeights && opts.vertexWeights.length === N) {
610
+ nwPtr = M._malloc(N * 8);
611
+ const heapF64 = M.HEAPF64;
612
+ for (let i = 0; i < N; i++) {
613
+ heapF64[(nwPtr >> 3) + i] = opts.vertexWeights[i];
614
+ }
615
+ }
616
+
430
617
  // Build graph
431
- const g = M._init_dress_graph(N, E, uPtr, vPtr, wPtr, variant, precompute);
618
+ const g = M._dress_init_graph(N, E, uPtr, vPtr, wPtr, nwPtr, variant, precompute);
432
619
  if (g === 0) {
433
- throw new Error('init_dress_graph returned NULL');
620
+ throw new Error('dress_init_graph returned NULL');
434
621
  }
435
622
 
436
623
  // Allocate out-param for hist_size
@@ -447,19 +634,24 @@ export async function deltaDressFit(opts) {
447
634
  M.setValue(numSubPtr + 4, 0, 'i32');
448
635
  }
449
636
 
450
- // Call delta_dress_fit_strided (returns int64_t* — pointer to histogram on heap)
451
- const histPtr = M._delta_dress_fit_strided(g, k, maxIter, epsilon, histSizePtr,
452
- keepMS, msPtrPtr, numSubPtr, offset, stride);
637
+ // Call dress_delta_fit_strided (returns dress_hist_pair_t* on heap)
638
+ const histPtr = M._dress_delta_fit_strided(g, k, maxIter, epsilon,
639
+ nSamples, seed,
640
+ computeHist ? histSizePtr : 0,
641
+ keepMS, msPtrPtr, numSubPtr, 0, 1);
453
642
 
454
643
  const histSize = M.getValue(histSizePtr, 'i32');
455
644
 
456
- // Copy histogram into JS Float64Array (int64 values cast to double)
457
- // WASM int64_t is 8 bytes; read as pairs of i32 (little-endian)
458
- const histogram = new Float64Array(histSize);
645
+ // Copy histogram pairs into JS objects.
646
+ const histogram = new Array(histSize);
459
647
  for (let i = 0; i < histSize; i++) {
460
- const lo = M.HEAPU32[(histPtr >> 2) + i * 2];
461
- const hi = M.HEAP32[(histPtr >> 2) + i * 2 + 1];
462
- histogram[i] = hi * 4294967296 + lo;
648
+ const value = M.HEAPF64[(histPtr >> 3) + i * 2];
649
+ const countLo = M.HEAPU32[(histPtr >> 2) + i * 4 + 2];
650
+ const countHi = M.HEAPU32[(histPtr >> 2) + i * 4 + 3];
651
+ histogram[i] = {
652
+ value,
653
+ count: countHi * 4294967296 + countLo,
654
+ };
463
655
  }
464
656
 
465
657
  // Extract multisets if requested
@@ -487,13 +679,145 @@ export async function deltaDressFit(opts) {
487
679
  // Cleanup
488
680
  M._free(histPtr);
489
681
  M._free(histSizePtr);
490
- M._free_dress_graph(g);
682
+ M._dress_free_graph(g);
491
683
 
492
684
  return {
493
685
  histogram: histogram,
494
- histSize: histSize,
495
686
  multisets: multisets,
496
687
  numSubgraphs: numSubgraphs,
497
688
  };
498
689
  }
499
690
 
691
+ /**
692
+ * Compute the Nabla-k-DRESS histogram.
693
+ *
694
+ * Exhaustively removes all k-vertex tuples and measures
695
+ * the change in edge similarity values.
696
+ *
697
+ * @param {NablaDressOptions} opts
698
+ * @returns {Promise<NablaDressResult>}
699
+ */
700
+ export async function nablaFit(opts) {
701
+ const M = await getModule();
702
+
703
+ const N = opts.numVertices;
704
+ const E = opts.sources.length;
705
+
706
+ if (opts.targets.length !== E) {
707
+ throw new Error(`sources (${E}) and targets (${opts.targets.length}) must have equal length`);
708
+ }
709
+
710
+ const k = opts.k ?? 0;
711
+ const variant = opts.variant ?? Variant.UNDIRECTED;
712
+ const maxIter = opts.maxIterations ?? 100;
713
+ const epsilon = opts.epsilon ?? 1e-6;
714
+ const nSamples = opts.nSamples ?? 0;
715
+ const seed = opts.seed ?? 0;
716
+ const precompute = (opts.precompute ?? false) ? 1 : 0;
717
+ const keepMS = (opts.keepMultisets ?? false) ? 1 : 0;
718
+ const computeHist = (opts.computeHistogram ?? true) ? 1 : 0;
719
+
720
+ // Allocate C arrays (ownership transfers to dress_init_graph)
721
+ const uPtr = M._malloc(E * 4);
722
+ const vPtr = M._malloc(E * 4);
723
+
724
+ const heap32 = M.HEAP32;
725
+ const src = opts.sources;
726
+ const tgt = opts.targets;
727
+ for (let i = 0; i < E; i++) {
728
+ heap32[(uPtr >> 2) + i] = src[i];
729
+ heap32[(vPtr >> 2) + i] = tgt[i];
730
+ }
731
+
732
+ let wPtr = 0;
733
+ if (opts.weights && opts.weights.length === E) {
734
+ wPtr = M._malloc(E * 8);
735
+ const heapF64 = M.HEAPF64;
736
+ for (let i = 0; i < E; i++) {
737
+ heapF64[(wPtr >> 3) + i] = opts.weights[i];
738
+ }
739
+ }
740
+
741
+ let nwPtr = 0;
742
+ if (opts.vertexWeights && opts.vertexWeights.length === N) {
743
+ nwPtr = M._malloc(N * 8);
744
+ const heapF64 = M.HEAPF64;
745
+ for (let i = 0; i < N; i++) {
746
+ heapF64[(nwPtr >> 3) + i] = opts.vertexWeights[i];
747
+ }
748
+ }
749
+
750
+ // Build graph
751
+ const g = M._dress_init_graph(N, E, uPtr, vPtr, wPtr, nwPtr, variant, precompute);
752
+ if (g === 0) {
753
+ throw new Error('dress_init_graph returned NULL');
754
+ }
755
+
756
+ // Allocate out-param for hist_size
757
+ const histSizePtr = M._malloc(4);
758
+
759
+ // Allocate out-params for multisets (pointer-to-pointer and num_tuples)
760
+ let msPtrPtr = 0;
761
+ let numTupPtr = 0;
762
+ if (keepMS) {
763
+ msPtrPtr = M._malloc(4); // pointer to double*
764
+ numTupPtr = M._malloc(8); // int64_t
765
+ M.setValue(msPtrPtr, 0, 'i32');
766
+ M.setValue(numTupPtr, 0, 'i32');
767
+ M.setValue(numTupPtr + 4, 0, 'i32');
768
+ }
769
+
770
+ // Call dress_nabla_fit (returns dress_hist_pair_t* on heap)
771
+ const histPtr = M._dress_nabla_fit(g, k, maxIter, epsilon,
772
+ nSamples, seed,
773
+ computeHist ? histSizePtr : 0,
774
+ keepMS, msPtrPtr, numTupPtr);
775
+
776
+ const histSize = M.getValue(histSizePtr, 'i32');
777
+
778
+ // Copy histogram pairs into JS objects.
779
+ const histogram = new Array(histSize);
780
+ for (let i = 0; i < histSize; i++) {
781
+ const value = M.HEAPF64[(histPtr >> 3) + i * 2];
782
+ const countLo = M.HEAPU32[(histPtr >> 2) + i * 4 + 2];
783
+ const countHi = M.HEAPU32[(histPtr >> 2) + i * 4 + 3];
784
+ histogram[i] = {
785
+ value,
786
+ count: countHi * 4294967296 + countLo,
787
+ };
788
+ }
789
+
790
+ // Extract multisets if requested
791
+ let multisets = null;
792
+ let numTuples = 0;
793
+ if (keepMS && msPtrPtr) {
794
+ const msPtr = M.getValue(msPtrPtr, 'i32'); // double*
795
+ // Read int64 num_tuples as lo/hi pair
796
+ const ntLo = M.HEAPU32[(numTupPtr >> 2)];
797
+ const ntHi = M.HEAP32[(numTupPtr >> 2) + 1];
798
+ numTuples = ntHi * 4294967296 + ntLo;
799
+
800
+ if (msPtr !== 0 && numTuples > 0) {
801
+ const totalVals = numTuples * E;
802
+ multisets = new Float64Array(totalVals);
803
+ for (let i = 0; i < totalVals; i++) {
804
+ multisets[i] = M.HEAPF64[(msPtr >> 3) + i];
805
+ }
806
+ M._free(msPtr);
807
+ }
808
+ M._free(msPtrPtr);
809
+ M._free(numTupPtr);
810
+ }
811
+
812
+ // Cleanup
813
+ M._free(histPtr);
814
+ M._free(histSizePtr);
815
+ M._dress_free_graph(g);
816
+
817
+ return {
818
+ histogram: histogram,
819
+ multisets: multisets,
820
+ numTuples: numTuples,
821
+ };
822
+ }
823
+
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dress-graph",
3
- "version": "0.6.1",
4
- "description": "DRESS is a deterministic, parameter-free framework that iteratively refines the structural similarity of edges in a graph to produce a canonical fingerprint: a real-valued edge vector, obtained by converging a non-linear dynamical system to its unique fixed point. The fingerprint is isomorphism-invariant by construction, numerically stable (no overflow, no error amplification, no undefined behavior), fast and embarrassingly parallel to compute: DRESS total runtime is O(I * m * d_max) for I iterations to convergence, and convergence is guaranteed by Birkhoff contraction.",
3
+ "version": "0.8.0",
4
+ "description": "DRESS is a deterministic, parameter-free framework that iteratively refines the structural similarity of edges in a graph to produce a canonical fingerprint: a real-valued edge vector, obtained by converging a non-linear dynamical system to its unique fixed point. The fingerprint is self-contained, isomorphism-invariant by construction, numerically stable (no overflow, no error amplification, no undefined behavior), fast and embarrassingly parallel to compute: DRESS total runtime is O(I * m * d_max) for I iterations to convergence, and convergence is guaranteed by Birkhoff contraction.",
5
5
  "type": "module",
6
6
  "main": "dress.js",
7
7
  "types": "dress.d.ts",
package/dress_wasm.cjs DELETED
@@ -1,2 +0,0 @@
1
- var createDressModule=(()=>{var _scriptName=globalThis.document?.currentScript?.src;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=!!globalThis.window;var ENVIRONMENT_IS_WORKER=!!globalThis.WorkerGlobalScope;var ENVIRONMENT_IS_NODE=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename}else{}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("node:fs");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");var readyPromiseResolve,readyPromiseReject;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["c"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("dress_wasm.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={a:wasmImports};return imports}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(inst,mod)=>{resolve(receiveInstance(inst,mod))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);function getValue(ptr,type="i8"){if(type.endsWith("*"))type="*";switch(type){case"i1":return HEAP8[ptr];case"i8":return HEAP8[ptr];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP64[ptr>>3];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];case"*":return HEAPU32[ptr>>2];default:abort(`invalid type for getValue: ${type}`)}}var noExitRuntime=true;function setValue(ptr,value,type="i8"){if(type.endsWith("*"))type="*";switch(type){case"i1":HEAP8[ptr]=value;break;case"i8":HEAP8[ptr]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":HEAP64[ptr>>3]=BigInt(value);break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;case"*":HEAPU32[ptr>>2]=value;break;default:abort(`invalid type for setValue: ${type}`)}}var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i<str.length;++i){var c=str.charCodeAt(i);if(c<=127){len++}else if(c<=2047){len+=2}else if(c>=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.codePointAt(i);if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx<endPtr){var u0=heapOrArray[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heapOrArray[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heapOrArray[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heapOrArray[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func(...cArgs);function onDone(ret){if(stack!==0)stackRestore(stack);return convertReturnValue(ret)}ret=onDone(ret);return ret};var cwrap=(ident,returnType,argTypes,opts)=>{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["setValue"]=setValue;Module["getValue"]=getValue;var _init_dress_graph,_malloc,_free,_dress_fit,_free_dress_graph,_dress_get,_delta_dress_fit,_delta_dress_fit_strided,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,memory,__indirect_function_table,wasmMemory;function assignWasmExports(wasmExports){_init_dress_graph=Module["_init_dress_graph"]=wasmExports["d"];_malloc=Module["_malloc"]=wasmExports["e"];_free=Module["_free"]=wasmExports["f"];_dress_fit=Module["_dress_fit"]=wasmExports["g"];_free_dress_graph=Module["_free_dress_graph"]=wasmExports["h"];_dress_get=Module["_dress_get"]=wasmExports["i"];_delta_dress_fit=Module["_delta_dress_fit"]=wasmExports["j"];_delta_dress_fit_strided=Module["_delta_dress_fit_strided"]=wasmExports["k"];__emscripten_stack_restore=wasmExports["l"];__emscripten_stack_alloc=wasmExports["m"];_emscripten_stack_get_current=wasmExports["n"];memory=wasmMemory=wasmExports["b"];__indirect_function_table=wasmExports["__indirect_function_table"]}var wasmImports={a:_emscripten_resize_heap};function run(){preRun();function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}var wasmExports;wasmExports=await (createWasm());run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})}
2
- ;return moduleRtn}})();if(typeof exports==="object"&&typeof module==="object"){module.exports=createDressModule;module.exports.default=createDressModule}else if(typeof define==="function"&&define["amd"])define([],()=>createDressModule);
package/dress_wasm.wasm DELETED
Binary file