linny-r 1.9.0 → 1.9.1
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
package/static/index.html
CHANGED
@@ -750,6 +750,13 @@ NOTE: Unit symbols are case-sensitive, so BTU ≠ Btu">
|
|
750
750
|
placeholder="1e-4" type="text" autocomplete="off">
|
751
751
|
</td>
|
752
752
|
</tr>
|
753
|
+
<tr title="When checked, small slack uses are reported in monitor">
|
754
|
+
<td style="padding: 0px; width: 20px">
|
755
|
+
<div id="solver-show-notices" class="box clear"></div>
|
756
|
+
</td>
|
757
|
+
<td style="padding-bottom:4px">Report small slack uses</td>
|
758
|
+
</td>
|
759
|
+
</tr>
|
753
760
|
</table>
|
754
761
|
</div>
|
755
762
|
</div>
|
@@ -3689,6 +3689,7 @@ console.log('HERE name conflicts', name_conflicts, mapping);
|
|
3689
3689
|
md.element('preference').innerHTML = html.join('');
|
3690
3690
|
md.element('int-feasibility').value = MODEL.integer_tolerance;
|
3691
3691
|
md.element('mip-gap').value = MODEL.MIP_gap;
|
3692
|
+
this.setBox('solver-show-notices', MODEL.show_notices);
|
3692
3693
|
md.show();
|
3693
3694
|
}
|
3694
3695
|
|
@@ -3717,6 +3718,7 @@ console.log('HERE name conflicts', name_conflicts, mapping);
|
|
3717
3718
|
}
|
3718
3719
|
MODEL.integer_tolerance = Math.max(1e-9, Math.min(0.1, itol));
|
3719
3720
|
MODEL.MIP_gap = Math.max(0, Math.min(0.5, mgap));
|
3721
|
+
MODEL.show_notices = this.boxChecked('solver-show-notices');
|
3720
3722
|
// Close the dialog.
|
3721
3723
|
md.hide();
|
3722
3724
|
}
|
@@ -66,6 +66,7 @@ Attributes, however, are case sensitive!">[Actor X|CF]</code> for cash flow.
|
|
66
66
|
<code title="Relative time step (t − t₀ + 1)">rt</code>,
|
67
67
|
<code title="Number of current block">b</code>,
|
68
68
|
<code title="Time step within current block">bt</code>,
|
69
|
+
<code title="Time step within current chunk">ct</code>,
|
69
70
|
<code title="Duration of 1 time step (in hours)">dt</code>,
|
70
71
|
<code title="Run length (# time steps)">N</code>,
|
71
72
|
<code title="Block length (# time steps)">n</code>,
|
@@ -107,6 +107,7 @@ class LinnyRModel {
|
|
107
107
|
this.integer_tolerance = 5e-7; // integer feasibility tolerance
|
108
108
|
this.MIP_gap = 1e-4; // relative MIP gap
|
109
109
|
this.always_diagnose = true;
|
110
|
+
this.show_notices = true;
|
110
111
|
|
111
112
|
// Sensitivity-related properties
|
112
113
|
this.base_case_selectors = '';
|
@@ -2670,6 +2671,7 @@ class LinnyRModel {
|
|
2670
2671
|
this.report_results = nodeParameterValue(node, 'report-results') === '1';
|
2671
2672
|
this.show_block_arrows = nodeParameterValue(node, 'block-arrows') === '1';
|
2672
2673
|
this.always_diagnose = nodeParameterValue(node, 'diagnose') === '1';
|
2674
|
+
this.show_notices = nodeParameterValue(node, 'show-notices') === '1';
|
2673
2675
|
this.name = xmlDecoded(nodeContentByTag(node, 'name'));
|
2674
2676
|
this.author = xmlDecoded(nodeContentByTag(node, 'author'));
|
2675
2677
|
this.comments = xmlDecoded(nodeContentByTag(node, 'notes'));
|
@@ -3023,6 +3025,7 @@ class LinnyRModel {
|
|
3023
3025
|
if(this.report_results) p += ' report-results="1"';
|
3024
3026
|
if(this.show_block_arrows) p += ' block-arrows="1"';
|
3025
3027
|
if(this.always_diagnose) p += ' diagnose="1"';
|
3028
|
+
if(this.show_notices) p += ' show-notices="1"';
|
3026
3029
|
let xml = this.xml_header + ['<model', p, '><name>', xmlEncoded(this.name),
|
3027
3030
|
'</name><author>', xmlEncoded(this.author),
|
3028
3031
|
'</author><notes>', xmlEncoded(this.comments),
|
@@ -430,20 +430,25 @@ class Expression {
|
|
430
430
|
}
|
431
431
|
|
432
432
|
result(t, number=false) {
|
433
|
-
//
|
433
|
+
// Compute (only if needed) and then returns result for time step t.
|
434
434
|
// The `number` is passed only by the VMI_push_dataset_modifier
|
435
|
-
// instruction so as to force recomputation of the expression
|
436
|
-
//
|
437
|
-
// "initial value" (these follow from the variables used in the expression)
|
438
|
-
// Select the vector to use
|
435
|
+
// instruction so as to force recomputation of the expression.
|
436
|
+
// Select the vector to use.
|
439
437
|
const v = this.chooseVector(number);
|
440
438
|
if(!Array.isArray(v)) {
|
441
439
|
console.log('ANOMALY: No vector for result(t)');
|
442
440
|
return VM.UNDEFINED;
|
443
441
|
}
|
442
|
+
// NOTE: For t < 1 return the value for t = 1, since expressions have
|
443
|
+
// no "initial value" (these follow from the variables used in the
|
444
|
+
// expression).
|
444
445
|
if(t < 0 || this.isStatic) t = 0;
|
445
446
|
if(t >= v.length) return VM.UNDEFINED;
|
446
|
-
|
447
|
+
// NOTE: When VM is setting up a tableau, values computed for the
|
448
|
+
// look-ahead period must be recomputed.
|
449
|
+
if(v[t] === VM.NOT_COMPUTED || v[t] === VM.COMPUTING ||
|
450
|
+
(!this.isStatic && VM.inLookAhead(t))) {
|
451
|
+
v[t] = VM.NOT_COMPUTED;
|
447
452
|
this.compute(t, number);
|
448
453
|
}
|
449
454
|
// NOTE: when this expression is the "active" parameter for sensitivity
|
@@ -2477,8 +2482,19 @@ class VirtualMachine {
|
|
2477
2482
|
this.t = 0;
|
2478
2483
|
// Prepare for halt.
|
2479
2484
|
this.halted = false;
|
2485
|
+
// Flag to indicate that VM is executing its tableau construction code.
|
2486
|
+
// This affects how chunk time (ct) is computed, and whether expression
|
2487
|
+
// results must be recomputed (see inLookAhead below).
|
2488
|
+
this.executing_tableau_code = false;
|
2480
2489
|
UI.readyToSolve();
|
2481
2490
|
}
|
2491
|
+
|
2492
|
+
inLookAhead(t) {
|
2493
|
+
// Return TRUE if VM is executing its tableau construction code AND
|
2494
|
+
// time step `t` falls in the look-ahead period of the previous block.
|
2495
|
+
return this.executing_tableau_code &&
|
2496
|
+
t - (this.block_count - 1) * MODEL.block_length <= MODEL.look_ahead;
|
2497
|
+
}
|
2482
2498
|
|
2483
2499
|
errorMessage(n) {
|
2484
2500
|
// VM errors are very big NEGATIVE numbers, so start comparing `n`
|
@@ -2871,7 +2887,7 @@ class VirtualMachine {
|
|
2871
2887
|
const
|
2872
2888
|
bm = r.block_messages[i],
|
2873
2889
|
err = (bm.messages.indexOf('Solver status = 0') < 0 ||
|
2874
|
-
bm.messages.indexOf(
|
2890
|
+
bm.messages.indexOf(this.WARNING) >= 0);
|
2875
2891
|
this.solver_times.push(bm.solver_time);
|
2876
2892
|
this.messages.push(bm.messages);
|
2877
2893
|
this.variables.push(this.no_variables);
|
@@ -4657,7 +4673,7 @@ class VirtualMachine {
|
|
4657
4673
|
ppc[ci].usesSlack(b, v[1], v[0]);
|
4658
4674
|
}
|
4659
4675
|
}
|
4660
|
-
} else if(
|
4676
|
+
} else if(MODEL.show_notices) {
|
4661
4677
|
this.logMessage(block, '---- Notice: (t=' + b + round + ') ' +
|
4662
4678
|
v[1].displayName + ' ' + v[0] + ' slack = ' +
|
4663
4679
|
slack.toPrecision(1));
|
@@ -5223,7 +5239,7 @@ class VirtualMachine {
|
|
5223
5239
|
}
|
5224
5240
|
|
5225
5241
|
addTableauSegment(start, abl) {
|
5226
|
-
if(
|
5242
|
+
if(this.halted) {
|
5227
5243
|
this.hideSetUpOrWriteProgress();
|
5228
5244
|
this.stopSolving();
|
5229
5245
|
return;
|
@@ -5233,6 +5249,7 @@ class VirtualMachine {
|
|
5233
5249
|
var l;
|
5234
5250
|
const next_start = (start + this.tsl * 1.2 < abl ? start + this.tsl : abl);
|
5235
5251
|
for(let i = start; i < next_start; i++) {
|
5252
|
+
this.executing_tableau_code = true;
|
5236
5253
|
this.logTrace('EXECUTE for t=' + this.t);
|
5237
5254
|
l = this.code.length;
|
5238
5255
|
for(let j = 0; j < l; j++) {
|
@@ -5244,6 +5261,7 @@ class VirtualMachine {
|
|
5244
5261
|
this.logTrace([(' ' + j).slice(-5), ': coeff = ',
|
5245
5262
|
JSON.stringify(this.coefficients), '; rhs = ', this.rhs].join(''));
|
5246
5263
|
}
|
5264
|
+
this.executing_tableau_code = false;
|
5247
5265
|
this.logTrace('STOP executing block code');
|
5248
5266
|
// Add constraints for paced process variables.
|
5249
5267
|
// NOTE: This is effectuated by *executing* VM instructions.
|
@@ -6268,11 +6286,26 @@ function VMI_push_block_time(x) {
|
|
6268
6286
|
const
|
6269
6287
|
lt = x.step[x.step.length - 1] - 1,
|
6270
6288
|
bnr = Math.floor(lt / MODEL.block_length),
|
6271
|
-
t = lt - bnr * MODEL.block_length + 1;
|
6289
|
+
t = lt - bnr * MODEL.block_length + 1;
|
6272
6290
|
if(DEBUGGING) console.log('push block time bt = ' + t);
|
6273
6291
|
x.push(t);
|
6274
6292
|
}
|
6275
6293
|
|
6294
|
+
function VMI_push_chunk_time(x) {
|
6295
|
+
// Push the time step for which the VM is preparing the tableau.
|
6296
|
+
// NOTE: Chunk time is meaningful only while the VM is solving a block.
|
6297
|
+
// If not, the block time is pushed.
|
6298
|
+
if(VM.executing_tableau_code) {
|
6299
|
+
const
|
6300
|
+
ct = VM.t - (VM.block_count - 1) * MODEL.block_length;
|
6301
|
+
if(DEBUGGING) console.log('push chunk time ct = ' + ct);
|
6302
|
+
x.push(ct);
|
6303
|
+
} else {
|
6304
|
+
if(DEBUGGING) console.log('push chunk time: NOT constructing tableau');
|
6305
|
+
VMI_push_block_time(x);
|
6306
|
+
}
|
6307
|
+
}
|
6308
|
+
|
6276
6309
|
function VMI_push_block_number(x) {
|
6277
6310
|
// Push the number of the block currently being optimized.
|
6278
6311
|
// NOTE: Block numbering starts at 1.
|
@@ -8683,11 +8716,12 @@ const
|
|
8683
8716
|
SEPARATOR_CHARS = PARENTHESES + OPERATOR_CHARS + "[ '",
|
8684
8717
|
COMPOUND_OPERATORS = ['!=', '<>', '>=', '<='],
|
8685
8718
|
CONSTANT_SYMBOLS = [
|
8686
|
-
't', 'rt', 'bt', 'b', 'N', 'n', 'l', 'r', 'lr', 'nr', 'x', 'nx',
|
8719
|
+
't', 'rt', 'bt', 'ct', 'b', 'N', 'n', 'l', 'r', 'lr', 'nr', 'x', 'nx',
|
8687
8720
|
'random', 'dt', 'true', 'false', 'pi', 'infinity', '#',
|
8688
8721
|
'i', 'j', 'k', 'yr', 'wk', 'd', 'h', 'm', 's'],
|
8689
8722
|
CONSTANT_CODES = [
|
8690
8723
|
VMI_push_time_step, VMI_push_relative_time, VMI_push_block_time,
|
8724
|
+
VMI_push_chunk_time,
|
8691
8725
|
VMI_push_block_number, VMI_push_run_length, VMI_push_block_length,
|
8692
8726
|
VMI_push_look_ahead, VMI_push_round, VMI_push_last_round,
|
8693
8727
|
VMI_push_number_of_rounds, VMI_push_run_number, VMI_push_number_of_runs,
|
@@ -8696,7 +8730,7 @@ const
|
|
8696
8730
|
VMI_push_i, VMI_push_j, VMI_push_k,
|
8697
8731
|
VMI_push_year, VMI_push_week, VMI_push_day, VMI_push_hour,
|
8698
8732
|
VMI_push_minute, VMI_push_second],
|
8699
|
-
DYNAMIC_SYMBOLS = ['t', 'rt', 'bt', 'b', 'r', 'random', 'i', 'j', 'k'],
|
8733
|
+
DYNAMIC_SYMBOLS = ['t', 'rt', 'bt', 'ct', 'b', 'r', 'random', 'i', 'j', 'k'],
|
8700
8734
|
MONADIC_OPERATORS = [
|
8701
8735
|
'~', 'not', 'abs', 'sin', 'cos', 'atan', 'ln',
|
8702
8736
|
'exp', 'sqrt', 'round', 'int', 'fract', 'min', 'max',
|