@sdeverywhere/cli 0.7.46 → 0.7.47
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/package.json +3 -3
- package/src/c/allocation.c +7 -7
- package/src/c/sde.h +0 -2
- package/src/c/vensim.c +5 -31
- package/src/c/vensim.h +48 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdeverywhere/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.47",
|
|
4
4
|
"description": "Contains the `sde` command line interface for the SDEverywhere tool suite.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"sde": "src/main.js"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@sdeverywhere/build": "^0.3.
|
|
15
|
-
"@sdeverywhere/compile": "^0.7.
|
|
14
|
+
"@sdeverywhere/build": "^0.3.16",
|
|
15
|
+
"@sdeverywhere/compile": "^0.7.34",
|
|
16
16
|
"byline": "^5.0.0",
|
|
17
17
|
"ramda": "^0.27.0",
|
|
18
18
|
"shelljs": "^0.10.0",
|
package/src/c/allocation.c
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
// #define PRINT_ALLOCATIONS_DEBUG_INFO
|
|
25
25
|
|
|
26
26
|
// Return true if the value is near zero up to the epsilon tolerance.
|
|
27
|
-
static inline bool __isZero(double value) { return fabs(value) <
|
|
27
|
+
static inline bool __isZero(double value) { return fabs(value) < SDE_EPSILON; }
|
|
28
28
|
// Compute the absolute difference when x or y is near zero, otherwise compute
|
|
29
29
|
// the relative difference, with y considered as the baseline.
|
|
30
30
|
static inline double __difference(double x, double y) {
|
|
@@ -37,7 +37,7 @@ static inline double __difference(double x, double y) {
|
|
|
37
37
|
return diff;
|
|
38
38
|
}
|
|
39
39
|
// Return true if the values are equal up to the tolerance.
|
|
40
|
-
static inline bool __isEqual(double x, double y) { return __difference(x, y) <
|
|
40
|
+
static inline bool __isEqual(double x, double y) { return __difference(x, y) < SDE_EPSILON; }
|
|
41
41
|
// Clamp x to the interval [0,1].
|
|
42
42
|
static inline double __clamp01(double x) {
|
|
43
43
|
if (x < 0.0) return 0.0;
|
|
@@ -440,7 +440,7 @@ double* _ALLOCATE_BY_PRIORITY(
|
|
|
440
440
|
|
|
441
441
|
// Validate request values (must be non-negative)
|
|
442
442
|
for (size_t i = 0; i < num_requesters; i++) {
|
|
443
|
-
if (request_quantities[i] < -
|
|
443
|
+
if (request_quantities[i] < -SDE_EPSILON) {
|
|
444
444
|
fprintf(stderr,
|
|
445
445
|
"_ALLOCATE_BY_PRIORITY encountered negative request value at index %zu: %f\n",
|
|
446
446
|
i, request_quantities[i]);
|
|
@@ -449,7 +449,7 @@ double* _ALLOCATE_BY_PRIORITY(
|
|
|
449
449
|
}
|
|
450
450
|
|
|
451
451
|
// Validate width (must not be negative)
|
|
452
|
-
if (width < -
|
|
452
|
+
if (width < -SDE_EPSILON) {
|
|
453
453
|
fprintf(stderr,
|
|
454
454
|
"_ALLOCATE_BY_PRIORITY encountered invalid width value: %f\n"
|
|
455
455
|
"Width must not be negative.\n",
|
|
@@ -458,7 +458,7 @@ double* _ALLOCATE_BY_PRIORITY(
|
|
|
458
458
|
}
|
|
459
459
|
|
|
460
460
|
// Validate supply (must not be negative)
|
|
461
|
-
if (supply < -
|
|
461
|
+
if (supply < -SDE_EPSILON) {
|
|
462
462
|
fprintf(stderr,
|
|
463
463
|
"_ALLOCATE_BY_PRIORITY encountered invalid supply value: %f\n"
|
|
464
464
|
"Supply must not be negative.\n",
|
|
@@ -472,7 +472,7 @@ double* _ALLOCATE_BY_PRIORITY(
|
|
|
472
472
|
}
|
|
473
473
|
|
|
474
474
|
// If supply = 0, all targets get allocated 0
|
|
475
|
-
if(fabs(supply) <
|
|
475
|
+
if(fabs(supply) < SDE_EPSILON) {
|
|
476
476
|
return allocations;
|
|
477
477
|
}
|
|
478
478
|
|
|
@@ -539,7 +539,7 @@ double* _ALLOCATE_BY_PRIORITY(
|
|
|
539
539
|
size_t c_i = 0;
|
|
540
540
|
|
|
541
541
|
// Continue allocating until supply is exhausted
|
|
542
|
-
while (supply >
|
|
542
|
+
while (supply > SDE_EPSILON) {
|
|
543
543
|
// Check if there are any active targets left
|
|
544
544
|
bool any_active = false;
|
|
545
545
|
for (size_t i = 0; i < m; i++) {
|
package/src/c/sde.h
CHANGED
package/src/c/vensim.c
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
#include "sde.h"
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
//
|
|
4
|
+
// Note: This file only contains implementations of complex functions. Simple
|
|
5
|
+
// (inline-friendly) functions are defined as `static inline` functions in `vensim.h`
|
|
6
|
+
// so that they can be inlined at each call site (for improved performance).
|
|
7
|
+
//
|
|
4
8
|
|
|
5
9
|
//
|
|
6
10
|
// Vensim functions
|
|
7
11
|
// See the Vensim Reference Manual for descriptions of the functions.
|
|
8
12
|
// http://www.vensim.com/documentation/index.html?22300.htm
|
|
9
13
|
//
|
|
10
|
-
double _PULSE(double start, double width) {
|
|
11
|
-
double time_plus = _time + _time_step / 2.0;
|
|
12
|
-
if (width == 0.0) {
|
|
13
|
-
width = _time_step;
|
|
14
|
-
}
|
|
15
|
-
return (time_plus > start && time_plus < start + width) ? 1.0 : 0.0;
|
|
16
|
-
}
|
|
17
14
|
double _PULSE_TRAIN(double start, double width, double interval, double end) {
|
|
18
15
|
double n = floor((end - start) / interval);
|
|
19
16
|
for (double k = 0; k <= n; k++) {
|
|
@@ -23,29 +20,6 @@ double _PULSE_TRAIN(double start, double width, double interval, double end) {
|
|
|
23
20
|
}
|
|
24
21
|
return 0.0;
|
|
25
22
|
}
|
|
26
|
-
double _RAMP(double slope, double start_time, double end_time) {
|
|
27
|
-
// Return 0 until the start time is exceeded.
|
|
28
|
-
// Interpolate from start time to end time.
|
|
29
|
-
// Hold at the end time value.
|
|
30
|
-
// Allow start time > end time.
|
|
31
|
-
if (_time > start_time) {
|
|
32
|
-
if (_time < end_time || start_time > end_time) {
|
|
33
|
-
return slope * (_time - start_time);
|
|
34
|
-
} else {
|
|
35
|
-
return slope * (end_time - start_time);
|
|
36
|
-
}
|
|
37
|
-
} else {
|
|
38
|
-
return 0.0;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
double _XIDZ(double a, double b, double x) { return fabs(b) < _epsilon ? x : a / b; }
|
|
42
|
-
double _ZIDZ(double a, double b) {
|
|
43
|
-
if (fabs(b) < _epsilon) {
|
|
44
|
-
return 0.0;
|
|
45
|
-
} else {
|
|
46
|
-
return a / b;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
23
|
|
|
50
24
|
//
|
|
51
25
|
// Lookups
|
package/src/c/vensim.h
CHANGED
|
@@ -10,6 +10,14 @@ extern "C" {
|
|
|
10
10
|
#define _NA_ (-DBL_MAX)
|
|
11
11
|
#define bool_cond(cond) ((double)(cond) != 0.0)
|
|
12
12
|
|
|
13
|
+
// The tolerance used by the functions that guard against division by zero.
|
|
14
|
+
#define SDE_EPSILON 1e-6
|
|
15
|
+
|
|
16
|
+
// Note: The `_time` and `_time_step` variables are declared in `sde.h`, but `sde.h` includes
|
|
17
|
+
// this header, so we declare them here for use by the inline functions below.
|
|
18
|
+
extern double _time;
|
|
19
|
+
extern double _time_step;
|
|
20
|
+
|
|
13
21
|
//
|
|
14
22
|
// Vensim functions
|
|
15
23
|
// See the Vensim Reference Manual for descriptions of the functions.
|
|
@@ -44,13 +52,49 @@ double* _DEMAND_AT_PRICE(double* demand_quantities, double* demand_profiles, dou
|
|
|
44
52
|
double _FIND_MARKET_PRICE(double* demand_quantities, double* demand_profiles, double* supply_quantities,
|
|
45
53
|
double* supply_profiles, size_t num_demanders, size_t num_suppliers);
|
|
46
54
|
double* _INVERT_MATRIX(double* matrix, size_t n);
|
|
47
|
-
double _PULSE(double start, double width);
|
|
48
55
|
double _PULSE_TRAIN(double start, double width, double interval, double end);
|
|
49
|
-
double _RAMP(double slope, double start_time, double end_time);
|
|
50
56
|
double* _SUPPLY_AT_PRICE(double* supply_quantities, double* supply_profiles, double price, size_t num_suppliers);
|
|
51
57
|
double* _VECTOR_SORT_ORDER(double* vector, size_t size, double direction);
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
|
|
59
|
+
//
|
|
60
|
+
// Note: The following functions are defined here as `static inline` (rather than as
|
|
61
|
+
// out-of-line functions in `vensim.c`) because they are called very frequently (millions of
|
|
62
|
+
// times per run for a large model). Defining them in the header allows the compiler to
|
|
63
|
+
// inline them at each call site, which avoids the call overhead and allows repeated
|
|
64
|
+
// identical calls to be replaced with a single one.
|
|
65
|
+
//
|
|
66
|
+
|
|
67
|
+
static inline double _PULSE(double start, double width) {
|
|
68
|
+
double time_plus = _time + _time_step / 2.0;
|
|
69
|
+
if (width == 0.0) {
|
|
70
|
+
width = _time_step;
|
|
71
|
+
}
|
|
72
|
+
return (time_plus > start && time_plus < start + width) ? 1.0 : 0.0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static inline double _RAMP(double slope, double start_time, double end_time) {
|
|
76
|
+
// Return 0 until the start time is exceeded.
|
|
77
|
+
// Interpolate from start time to end time.
|
|
78
|
+
// Hold at the end time value.
|
|
79
|
+
// Allow start time > end time.
|
|
80
|
+
if (_time > start_time) {
|
|
81
|
+
if (_time < end_time || start_time > end_time) {
|
|
82
|
+
return slope * (_time - start_time);
|
|
83
|
+
} else {
|
|
84
|
+
return slope * (end_time - start_time);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
return 0.0;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static inline double _XIDZ(double a, double b, double x) {
|
|
92
|
+
return fabs(b) < SDE_EPSILON ? x : a / b;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static inline double _ZIDZ(double a, double b) {
|
|
96
|
+
return fabs(b) < SDE_EPSILON ? 0.0 : a / b;
|
|
97
|
+
}
|
|
54
98
|
|
|
55
99
|
//
|
|
56
100
|
// Lookups
|