@sdeverywhere/cli 0.7.3 → 0.7.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdeverywhere/cli",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "Contains the `sde` command line interface for the SDEverywhere tool suite.",
5
5
  "type": "module",
6
6
  "files": [
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@sdeverywhere/build": "^0.2.0",
15
- "@sdeverywhere/compile": "^0.7.0",
15
+ "@sdeverywhere/compile": "^0.7.2",
16
16
  "bufx": "^1.0.5",
17
17
  "byline": "^5.0.0",
18
18
  "ramda": "^0.27.0",
package/src/c/vensim.c CHANGED
@@ -434,11 +434,19 @@ FixedDelay* __new_fixed_delay(FixedDelay* fixed_delay, double delay_time, double
434
434
  // The delay time is quantized to an integral number of time steps.
435
435
  // The FixedDelay should be constructed at init time to latch the delay time and initial value.
436
436
  // Allocate memory on the first call only. Pass the same pointer back in on subsequent runs.
437
+ size_t n = (size_t)ceil(delay_time / _time_step);
438
+ size_t bufsize = n * sizeof(double);
437
439
  if (fixed_delay == NULL) {
440
+ // Create the FixedDelay object and allocate its data buffer.
438
441
  fixed_delay = malloc(sizeof(FixedDelay));
439
- fixed_delay->n = (size_t)ceil(delay_time / _time_step);
440
- fixed_delay->data = malloc(sizeof(double) * fixed_delay->n);
442
+ fixed_delay->data = malloc(bufsize);
443
+ } else if (fixed_delay->n != n) {
444
+ // The delay time has changed since a previous run. Reallocate the data buffer.
445
+ free(fixed_delay->data);
446
+ fixed_delay->data = malloc(bufsize);
441
447
  }
448
+ // Reset state at the start of each run.
449
+ fixed_delay->n = n;
442
450
  fixed_delay->data_index = 0;
443
451
  fixed_delay->initial_value = initial_value;
444
452
  return fixed_delay;
@@ -464,3 +472,54 @@ double _DELAY_FIXED(double input, FixedDelay* fixed_delay) {
464
472
  }
465
473
  return result;
466
474
  }
475
+
476
+ //
477
+ // DEPRECIATE STRAIGHTLINE
478
+ //
479
+ Depreciation* __new_depreciation(Depreciation* depreciation, double dtime, double initial_value) {
480
+ // Construct a Depreciation struct with a ring buffer for the time steps in the depreciation time.
481
+ // We don't know the size until runtime, so it must be dynamically allocated.
482
+ // The depreciation time is quantized to an integral number of time steps.
483
+ // The Depreciation should be constructed at init time to latch the depreciation time and initial value.
484
+ // Allocate memory on the first call only. Pass the same pointer back in on subsequent runs.
485
+ size_t n = (size_t)ceil(dtime / _time_step);
486
+ size_t bufsize = n * sizeof(double);
487
+ if (depreciation == NULL) {
488
+ // Create the Depreciation object and allocate its data buffer.
489
+ depreciation = malloc(sizeof(Depreciation));
490
+ depreciation->data = malloc(bufsize);
491
+ } else if (depreciation->n != n) {
492
+ // The depreciation time has changed since a previous run. Reallocate the data buffer.
493
+ free(depreciation->data);
494
+ depreciation->data = malloc(bufsize);
495
+ }
496
+ // Reset state at the start of each run.
497
+ memset(depreciation->data, 0, bufsize);
498
+ depreciation->n = n;
499
+ depreciation->data_index = 0;
500
+ depreciation->dtime = dtime;
501
+ depreciation->initial_value = initial_value;
502
+ return depreciation;
503
+ }
504
+ double _DEPRECIATE_STRAIGHTLINE(double input, Depreciation* depreciation) {
505
+ // Distribute the input at this time step over the depreciation time in a ring buffer.
506
+ // Return the depreciation amout at the current time.
507
+ double result;
508
+ // Require the buffer size to be positive to protect from buffer overflows.
509
+ if (depreciation->n > 0) {
510
+ // Distribute input from the stream over the depreciation time.
511
+ double distribution = input / depreciation->dtime;
512
+ for (size_t i = 0; i < depreciation->n; i++) {
513
+ size_t pos = (depreciation->data_index + i) % depreciation->n;
514
+ depreciation->data[pos] += distribution;
515
+ }
516
+ result = depreciation->data[depreciation->data_index];
517
+ // Move to the next time step by pushing zero and shifting.
518
+ depreciation->data[depreciation->data_index] = 0;
519
+ depreciation->data_index = (depreciation->data_index + 1) % depreciation->n;
520
+ } else {
521
+ // For a zero deprecitation time, take the value directly from the input.
522
+ result = input;
523
+ }
524
+ return result;
525
+ }
package/src/c/vensim.h CHANGED
@@ -26,6 +26,7 @@ extern "C" {
26
26
  #define _MAX(a, b) fmax(a, b)
27
27
  #define _MIN(a, b) fmin(a, b)
28
28
  #define _MODULO(a, b) fmod(a, b)
29
+ #define _POWER(a, b) pow(a, b)
29
30
  #define _QUANTUM(a, b) ((b) <= 0 ? (a) : (b) * trunc((a) / (b)))
30
31
  #define _SAMPLE_IF_TRUE(current, condition, input) (bool_cond(condition) ? (input) : (current))
31
32
  #define _SIN(x) sin(x)
@@ -84,6 +85,20 @@ typedef struct {
84
85
  double _DELAY_FIXED(double input, FixedDelay* fixed_delay);
85
86
  FixedDelay* __new_fixed_delay(FixedDelay* fixed_delay, double delay_time, double initial_value);
86
87
 
88
+ //
89
+ // DEPRECIATE STRAIGHTLINE
90
+ //
91
+ typedef struct {
92
+ double* data;
93
+ size_t n;
94
+ size_t data_index;
95
+ double dtime;
96
+ double initial_value;
97
+ } Depreciation;
98
+
99
+ double _DEPRECIATE_STRAIGHTLINE(double input, Depreciation* depreciation);
100
+ Depreciation* __new_depreciation(Depreciation* depreciation, double dtime, double initial_value);
101
+
87
102
  #ifdef __cplusplus
88
103
  }
89
104
  #endif