jsxgraph 1.4.4 → 1.4.6

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.
Files changed (56) hide show
  1. package/README.md +24 -0
  2. package/build/Readme.md +17 -0
  3. package/build/bin/jsxcompressor.js +1 -0
  4. package/build/bin/jsxgraphcore-min.js +7 -0
  5. package/build/bin/jsxgraphcore.js +83017 -0
  6. package/build/bin/jsxgraphcore.min.js +67 -0
  7. package/build/compressor.build.json +14 -0
  8. package/build/compressor.deps.js +8 -0
  9. package/build/core-amd.build.json +14 -0
  10. package/build/core-amd.deps.js +81 -0
  11. package/build/core.build.json +14 -0
  12. package/build/core.deps.js +102 -0
  13. package/build/plot.build.json +15 -0
  14. package/distrib/README.md +24 -0
  15. package/distrib/geogebra.min.js +1 -1
  16. package/distrib/geonext.min.js +1 -1
  17. package/distrib/index.d.ts +28 -7
  18. package/distrib/intergeo.min.js +1 -1
  19. package/distrib/jsxgraph.css +6 -0
  20. package/distrib/jsxgraphcore.js +3 -3
  21. package/distrib/jsxgraphsrc.js +3558 -1857
  22. package/distrib/sketch.min.js +1 -1
  23. package/package.json +1 -1
  24. package/src/3d/box3d.js +43 -38
  25. package/src/3d/curve3d.js +157 -53
  26. package/src/3d/element3d.js +84 -0
  27. package/src/3d/linspace3d.js +427 -146
  28. package/src/3d/point3d.js +360 -123
  29. package/src/3d/surface3d.js +140 -42
  30. package/src/3d/view3d.js +319 -164
  31. package/src/base/board.js +163 -78
  32. package/src/base/constants.js +8 -1
  33. package/src/base/curve.js +51 -9
  34. package/src/base/polygon.js +111 -69
  35. package/src/base/text.js +122 -19
  36. package/src/base/ticks.js +12 -3
  37. package/src/element/button.js +7 -3
  38. package/src/element/checkbox.js +8 -4
  39. package/src/element/composition.js +7 -1
  40. package/src/element/conic.js +2 -2
  41. package/src/element/input.js +9 -5
  42. package/src/jsxgraph.js +4 -1
  43. package/src/loadjsxgraph.js +13 -8
  44. package/src/math/clip.js +34 -134
  45. package/src/math/geometry.js +204 -3
  46. package/src/math/math.js +1 -2
  47. package/src/math/nlp.js +865 -774
  48. package/src/options.js +185 -12
  49. package/src/options3d.js +24 -7
  50. package/src/parser/jessiecode.js +9 -3
  51. package/src/renderer/abstract.js +26 -15
  52. package/src/renderer/canvas.js +2 -2
  53. package/src/renderer/svg.js +15 -2
  54. package/src/utils/env.js +36 -53
  55. package/src/utils/type.js +75 -2
  56. package/src/3d/threed.js +0 -38
package/src/math/nlp.js CHANGED
@@ -1,75 +1,77 @@
1
1
  /*
2
- Copyright 2008-2022
3
- Matthias Ehmann,
4
- Carsten Miller,
5
- Reinhard Oldenburg,
6
- Alfred Wassermann
2
+ Copyright 2008-2022
3
+ Matthias Ehmann,
4
+ Carsten Miller,
5
+ Reinhard Oldenburg,
6
+ Andreas Walter,
7
+ Alfred Wassermann
7
8
 
8
- This file is part of JSXGraph.
9
+ This file is part of JSXGraph.
9
10
 
10
- JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
11
+ JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
11
12
 
12
- You can redistribute it and/or modify it under the terms of the
13
+ You can redistribute it and/or modify it under the terms of the
13
14
 
14
- * GNU Lesser General Public License as published by
15
- the Free Software Foundation, either version 3 of the License, or
16
- (at your option) any later version
17
- OR
18
- * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
15
+ * GNU Lesser General Public License as published by
16
+ the Free Software Foundation, either version 3 of the License, or
17
+ (at your option) any later version
18
+ OR
19
+ * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
19
20
 
20
- JSXGraph is distributed in the hope that it will be useful,
21
- but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- GNU Lesser General Public License for more details.
21
+ JSXGraph is distributed in the hope that it will be useful,
22
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
+ GNU Lesser General Public License for more details.
24
25
 
25
- You should have received a copy of the GNU Lesser General Public License and
26
- the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
27
- and <http://opensource.org/licenses/MIT/>.
26
+ You should have received a copy of the GNU Lesser General Public License and
27
+ the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
28
+ and <http://opensource.org/licenses/MIT/>.
28
29
 
29
- This is a port of jcobyla
30
+ This is a port of jcobyla
30
31
 
31
- - to JavaScript by Reihard Oldenburg and
32
- - to JSXGraph By Alfred Wassermann
33
- */
32
+ - to JavaScript by Reihard Oldenburg and
33
+ - to JSXGraph by Alfred Wassermann
34
+ - optimized by Andreas Walter
35
+ */
34
36
  /*
35
37
  * jcobyla
36
- *
38
+ *
37
39
  * The MIT License
38
40
  *
39
41
  * Copyright (c) 2012 Anders Gustafsson, Cureos AB.
40
42
  *
41
43
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
42
- * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
43
- * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
44
+ * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
45
+ * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
44
46
  * subject to the following conditions:
45
47
  *
46
48
  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
47
49
  *
48
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
50
- * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
50
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
52
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
51
53
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52
- *
54
+ *
53
55
  * Remarks:
54
- *
56
+ *
55
57
  * The original Fortran 77 version of this code was by Michael Powell (M.J.D.Powell @ damtp.cam.ac.uk)
56
58
  * The Fortran 90 version was by Alan Miller (Alan.Miller @ vic.cmis.csiro.au). Latest revision - 30 October 1998
57
59
  */
58
60
 
59
61
  /**
60
62
  * Constrained Optimization BY Linear Approximation in Java.
61
- *
63
+ *
62
64
  * COBYLA2 is an implementation of Powell's nonlinear derivative free constrained optimization that uses
63
65
  * a linear approximation approach. The algorithm is a sequential trust region algorithm that employs linear
64
66
  * approximations to the objective and constraint functions, where the approximations are formed by linear
65
67
  * interpolation at n + 1 points in the space of the variables and tries to maintain a regular shaped simplex
66
68
  * over iterations.
67
- *
69
+ *
68
70
  * It solves nonsmooth NLP with a moderate number of variables (about 100). Inequality constraints only.
69
- *
71
+ *
70
72
  * The initial point X is taken as one vertex of the initial simplex with zero being another, so, X should
71
73
  * not be entered as the zero vector.
72
- *
74
+ *
73
75
  * @author Anders Gustafsson, Cureos AB. Translation to Javascript by Reinhard Oldenburg, Goethe-University
74
76
  */
75
77
 
@@ -82,7 +84,7 @@
82
84
  utils/type
83
85
  */
84
86
 
85
- define(['jxg'], function (JXG) {
87
+ define(['jxg', 'utils/type'], function (JXG, Type) {
86
88
 
87
89
  "use strict";
88
90
 
@@ -90,20 +92,16 @@ define(['jxg'], function (JXG) {
90
92
  * The JXG.Math.Nlp namespace holds numerical algorithms for non-linear optimization.
91
93
  * @name JXG.Math.Nlp
92
94
  * @namespace
93
- *
95
+ *
94
96
  */
95
- JXG.Math.Nlp = {
97
+ JXG.Math.Nlp = {
96
98
 
97
- arr: function(n) {
98
- var a = new Array(n),
99
- i;
100
- for (i = 0; i <n ; i++) {
101
- a[i] = 0.0;
102
- }
103
- return a;
99
+ arr: function (n) {
100
+ // Is 0 initialized
101
+ return new Float64Array(n);
104
102
  },
105
103
 
106
- arr2: function(n, m) {
104
+ arr2: function (n, m) {
107
105
  var i = 0,
108
106
  a = new Array(n);
109
107
 
@@ -114,7 +112,7 @@ define(['jxg'], function (JXG) {
114
112
  return a;
115
113
  },
116
114
 
117
- arraycopy: function(x, a, iox, b, n) {
115
+ arraycopy: function (x, a, iox, b, n) {
118
116
  var i = 0;
119
117
  while (i < n) {
120
118
  iox[i + b] = x[i + a];
@@ -144,7 +142,7 @@ define(['jxg'], function (JXG) {
144
142
  * @param maxfun Maximum number of function evaluations before terminating.
145
143
  * @returns {Number} Exit status of the COBYLA2 optimization.
146
144
  */
147
- FindMinimum: function(calcfc, n, m, x, rhobeg, rhoend, iprint, maxfun) {
145
+ FindMinimum: function (calcfc, n, m, x, rhobeg, rhoend, iprint, maxfun) {
148
146
  // CobylaExitStatus FindMinimum(final Calcfc calcfc, int n, int m, double[] x, double rhobeg, double rhoend, int iprint, int maxfun)
149
147
  // This subroutine minimizes an objective function F(X) subject to M
150
148
  // inequality constraints on X, where X is a vector of variables that has
@@ -208,16 +206,16 @@ define(['jxg'], function (JXG) {
208
206
 
209
207
  // Internal representation of the objective and constraints calculation method,
210
208
  // accounting for that X and CON arrays in the cobylb method are base-1 arrays.
211
- fcalcfc = function(n, m, thisx, con) { // int n, int m, double[] x, double[] con
212
- var ix = that.arr(n),
213
- ocon, f;
209
+ fcalcfc = function (n, m, thisx, con) { // int n, int m, double[] x, double[] con
210
+ var ix = that.arr(n),
211
+ ocon, f;
214
212
 
215
- that.arraycopy(thisx, 1, ix, 0, n);
216
- ocon = that.arr(m);
217
- f = calcfc(n, m, ix, ocon);
218
- that.arraycopy(ocon, 0, con, 1, m);
219
- return f;
220
- };
213
+ that.arraycopy(thisx, 1, ix, 0, n);
214
+ ocon = that.arr(m);
215
+ f = calcfc(n, m, ix, ocon);
216
+ that.arraycopy(ocon, 0, con, 1, m);
217
+ return f;
218
+ };
221
219
 
222
220
  status = this.cobylb(fcalcfc, n, m, mpp, iox, rhobeg, rhoend, iprint, maxfun);
223
221
  this.arraycopy(iox, 1, x, 0, n);
@@ -229,18 +227,18 @@ define(['jxg'], function (JXG) {
229
227
  // double rhobeg, double rhoend, int iprint, int maxfun)
230
228
  /**
231
229
  * JavaScript implementation of the non-linear optimization method COBYLA.
232
- * @param {Function} calcfc
233
- * @param {Number} n
234
- * @param {Number} m
235
- * @param {Number} mpp
236
- * @param {Number} x
237
- * @param {Number} rhobeg
238
- * @param {Number} rhoend
239
- * @param {Number} iprint
240
- * @param {Number} maxfun
230
+ * @param {Function} calcfc
231
+ * @param {Number} n
232
+ * @param {Number} m
233
+ * @param {Number} mpp
234
+ * @param {Number} x
235
+ * @param {Number} rhobeg
236
+ * @param {Number} rhoend
237
+ * @param {Number} iprint
238
+ * @param {Number} maxfun
241
239
  * @returns {Number} Exit status of the COBYLA2 optimization
242
240
  */
243
- cobylb: function (calcfc, n, m, mpp, x, rhobeg, rhoend, iprint, maxfun) {
241
+ cobylb: function (calcfc, n, m, mpp, x, rhobeg, rhoend, iprint, maxfun) {
244
242
  // calcf ist funktion die aufgerufen wird wie calcfc(n, m, ix, ocon)
245
243
  // N.B. Arguments CON, SIM, SIMI, DATMAT, A, VSIG, VETA, SIGBAR, DX, W & IACT
246
244
  // have been removed.
@@ -316,409 +314,426 @@ define(['jxg'], function (JXG) {
316
314
  // the algorithm.
317
315
  //alert("Iteration "+nfvals+" x="+x);
318
316
  L_40:
319
- do {
320
- if (nfvals >= maxfun && nfvals > 0) {
321
- status = this.MaxIterationsReached;
322
- break L_40;
323
- }
317
+ do {
318
+ if (nfvals >= maxfun && nfvals > 0) {
319
+ status = this.MaxIterationsReached;
320
+ break L_40;
321
+ }
324
322
 
325
- ++nfvals;
326
- f = calcfc(n, m, x, con);
327
- resmax = 0.0;
328
- for (k = 1; k <= m; ++k) {
329
- resmax = Math.max(resmax, -con[k]);
330
- }
331
- //alert( " f="+f+" resmax="+resmax);
323
+ ++nfvals;
324
+ f = calcfc(n, m, x, con);
325
+ resmax = 0.0;
326
+ for (k = 1; k <= m; ++k) {
327
+ resmax = Math.max(resmax, -con[k]);
328
+ }
329
+ //alert( " f="+f+" resmax="+resmax);
332
330
 
333
- if (nfvals === iprint - 1 || iprint === 3) {
334
- this.PrintIterationResult(nfvals, f, resmax, x, n, iprint);
335
- }
331
+ if (nfvals === iprint - 1 || iprint === 3) {
332
+ this.PrintIterationResult(nfvals, f, resmax, x, n, iprint);
333
+ }
336
334
 
337
- con[mp] = f;
338
- con[mpp] = resmax;
335
+ con[mp] = f;
336
+ con[mpp] = resmax;
339
337
 
340
- // Set the recently calculated function values in a column of DATMAT. This
341
- // array has a column for each vertex of the current simplex, the entries of
342
- // each column being the values of the constraint functions (if any)
343
- // followed by the objective function and the greatest constraint violation
344
- // at the vertex.
345
- skipVertexIdent = true;
346
- if (!ibrnch) {
347
- skipVertexIdent = false;
338
+ // Set the recently calculated function values in a column of DATMAT. This
339
+ // array has a column for each vertex of the current simplex, the entries of
340
+ // each column being the values of the constraint functions (if any)
341
+ // followed by the objective function and the greatest constraint violation
342
+ // at the vertex.
343
+ skipVertexIdent = true;
344
+ if (!ibrnch) {
345
+ skipVertexIdent = false;
348
346
 
349
- for (i = 1; i <= mpp; ++i) {
350
- datmat[i][jdrop] = con[i];
351
- }
347
+ for (i = 1; i <= mpp; ++i) {
348
+ datmat[i][jdrop] = con[i];
349
+ }
352
350
 
353
- if (nfvals <= np) {
354
- // Exchange the new vertex of the initial simplex with the optimal vertex if
355
- // necessary. Then, if the initial simplex is not complete, pick its next
356
- // vertex and calculate the function values there.
357
-
358
- if (jdrop <= n) {
359
- if (datmat[mp][np] <= f) {
360
- x[jdrop] = sim[jdrop][np];
361
- } else {
362
- sim[jdrop][np] = x[jdrop];
363
- for (k = 1; k <= mpp; ++k) {
364
- datmat[k][jdrop] = datmat[k][np];
365
- datmat[k][np] = con[k];
366
- }
367
- for (k = 1; k <= jdrop; ++k) {
368
- sim[jdrop][k] = -rho;
369
- temp = 0.0;
370
- for (i = k; i <= jdrop; ++i) {
371
- temp -= simi[i][k];
351
+ if (nfvals <= np) {
352
+ // Exchange the new vertex of the initial simplex with the optimal vertex if
353
+ // necessary. Then, if the initial simplex is not complete, pick its next
354
+ // vertex and calculate the function values there.
355
+
356
+ if (jdrop <= n) {
357
+ if (datmat[mp][np] <= f) {
358
+ x[jdrop] = sim[jdrop][np];
359
+ } else {
360
+ sim[jdrop][np] = x[jdrop];
361
+ for (k = 1; k <= mpp; ++k) {
362
+ datmat[k][jdrop] = datmat[k][np];
363
+ datmat[k][np] = con[k];
364
+ }
365
+ for (k = 1; k <= jdrop; ++k) {
366
+ sim[jdrop][k] = -rho;
367
+ temp = 0.0;
368
+ for (i = k; i <= jdrop; ++i) {
369
+ temp -= simi[i][k];
370
+ }
371
+ simi[jdrop][k] = temp;
372
372
  }
373
- simi[jdrop][k] = temp;
374
373
  }
375
374
  }
375
+ if (nfvals <= n) {
376
+ jdrop = nfvals;
377
+ x[jdrop] += rho;
378
+ continue L_40;
379
+ }
376
380
  }
377
- if (nfvals <= n) {
378
- jdrop = nfvals;
379
- x[jdrop] += rho;
380
- continue L_40;
381
- }
381
+ ibrnch = true;
382
382
  }
383
- ibrnch = true;
384
- }
385
383
 
386
- L_140:
387
- do {
388
- L_550:
389
- do {
390
- if (!skipVertexIdent) {
391
- // Identify the optimal vertex of the current simplex.
392
- phimin = datmat[mp][np] + parmu * datmat[mpp][np];
393
- nbest = np;
394
-
395
- for (j = 1; j <= n; ++j) {
396
- temp = datmat[mp][j] + parmu * datmat[mpp][j];
397
- if (temp < phimin) {
398
- nbest = j;
399
- phimin = temp;
400
- } else if (temp === phimin && parmu === 0.0 && datmat[mpp][j] < datmat[mpp][nbest]) {
401
- nbest = j;
402
- }
403
- }
384
+ L_140:
385
+ do {
386
+ L_550:
387
+ do {
388
+ if (!skipVertexIdent) {
389
+ // Identify the optimal vertex of the current simplex.
390
+ phimin = datmat[mp][np] + parmu * datmat[mpp][np];
391
+ nbest = np;
392
+
393
+ for (j = 1; j <= n; ++j) {
394
+ temp = datmat[mp][j] + parmu * datmat[mpp][j];
395
+ if (temp < phimin) {
396
+ nbest = j;
397
+ phimin = temp;
398
+ } else if (temp === phimin && parmu === 0.0 && datmat[mpp][j] < datmat[mpp][nbest]) {
399
+ nbest = j;
400
+ }
401
+ }
404
402
 
405
- // Switch the best vertex into pole position if it is not there already,
406
- // and also update SIM, SIMI and DATMAT.
407
- if (nbest <= n) {
408
- for (i = 1; i <= mpp; ++i) {
409
- temp = datmat[i][np];
410
- datmat[i][np] = datmat[i][nbest];
411
- datmat[i][nbest] = temp;
412
- }
413
- for (i = 1; i <= n; ++i) {
414
- temp = sim[i][nbest];
415
- sim[i][nbest] = 0.0;
416
- sim[i][np] += temp;
417
-
418
- tempa = 0.0;
419
- for (k = 1; k <= n; ++k)
420
- {
421
- sim[i][k] -= temp;
422
- tempa -= simi[k][i];
423
- }
424
- simi[nbest][i] = tempa;
425
- }
426
- }
403
+ // Switch the best vertex into pole position if it is not there already,
404
+ // and also update SIM, SIMI and DATMAT.
405
+ if (nbest <= n) {
406
+ for (i = 1; i <= mpp; ++i) {
407
+ temp = datmat[i][np];
408
+ datmat[i][np] = datmat[i][nbest];
409
+ datmat[i][nbest] = temp;
410
+ }
411
+ for (i = 1; i <= n; ++i) {
412
+ temp = sim[i][nbest];
413
+ sim[i][nbest] = 0.0;
414
+ sim[i][np] += temp;
415
+
416
+ tempa = 0.0;
417
+ for (k = 1; k <= n; ++k) {
418
+ sim[i][k] -= temp;
419
+ tempa -= simi[k][i];
420
+ }
421
+ simi[nbest][i] = tempa;
422
+ }
423
+ }
427
424
 
428
- // Make an error return if SIGI is a poor approximation to the inverse of
429
- // the leading N by N submatrix of SIG.
430
- error = 0.0;
431
- for (i = 1; i <= n; ++i) {
432
- for (j = 1; j <= n; ++j) {
433
- temp = this.DOT_PRODUCT(
434
- this.PART(this.ROW(simi, i), 1, n),
435
- this.PART(this.COL(sim, j), 1, n)
436
- ) - (i === j ? 1.0 : 0.0);
437
- error = Math.max(error, Math.abs(temp));
438
- }
439
- }
440
- if (error > 0.1) {
441
- status = this.DivergingRoundingErrors;
442
- break L_40;
443
- }
425
+ // Make an error return if SIGI is a poor approximation to the inverse of
426
+ // the leading N by N submatrix of SIG.
427
+ error = 0.0;
428
+ if (false) {
429
+ for (i = 1; i <= n; ++i) {
430
+ for (j = 1; j <= n; ++j) {
431
+ temp = this.DOT_PRODUCT_ROW_COL(simi, i, sim, j, 1, n) - (i === j ? 1.0 : 0.0);
432
+ // temp = this.DOT_PRODUCT(
433
+ // this.PART(this.ROW(simi, i), 1, n),
434
+ // this.PART(this.COL(sim, j), 1, n)
435
+ // ) - (i === j ? 1.0 : 0.0);
436
+
437
+ error = Math.max(error, Math.abs(temp));
438
+ }
439
+ }
440
+ }
441
+ if (error > 0.1) {
442
+ status = this.DivergingRoundingErrors;
443
+ break L_40;
444
+ }
444
445
 
445
- // Calculate the coefficients of the linear approximations to the objective
446
- // and constraint functions, placing minus the objective function gradient
447
- // after the constraint gradients in the array A. The vector W is used for
448
- // working space.
449
- for (k = 1; k <= mp; ++k) {
450
- con[k] = -datmat[k][np];
451
- for (j = 1; j <= n; ++j) {
452
- w[j] = datmat[k][j] + con[k];
453
- }
446
+ // Calculate the coefficients of the linear approximations to the objective
447
+ // and constraint functions, placing minus the objective function gradient
448
+ // after the constraint gradients in the array A. The vector W is used for
449
+ // working space.
450
+ for (k = 1; k <= mp; ++k) {
451
+ con[k] = -datmat[k][np];
452
+ for (j = 1; j <= n; ++j) {
453
+ w[j] = datmat[k][j] + con[k];
454
+ }
454
455
 
455
- for (i = 1; i <= n; ++i) {
456
- a[i][k] = (k === mp ? -1.0 : 1.0) * this.DOT_PRODUCT(
457
- this.PART(w, 1, n), this.PART(this.COL(simi, i), 1, n));
458
- }
459
- }
456
+ for (i = 1; i <= n; ++i) {
457
+ a[i][k] = (k === mp ? -1.0 : 1.0) *
458
+ this.DOT_PRODUCT_ROW_COL(w, -1, simi, i, 1, n);
459
+ // this.DOT_PRODUCT(this.PART(w, 1, n), this.PART(this.COL(simi, i), 1, n));
460
+ }
461
+ }
460
462
 
461
- // Calculate the values of sigma and eta, and set IFLAG = 0 if the current
462
- // simplex is not acceptable.
463
- iflag = true;
464
- parsig = alpha * rho;
465
- pareta = beta * rho;
463
+ // Calculate the values of sigma and eta, and set IFLAG = 0 if the current
464
+ // simplex is not acceptable.
465
+ iflag = true;
466
+ parsig = alpha * rho;
467
+ pareta = beta * rho;
468
+
469
+ for (j = 1; j <= n; ++j) {
470
+ wsig = 0.0;
471
+ weta = 0.0;
472
+ for (k = 1; k <= n; ++k) {
473
+ wsig += simi[j][k] * simi[j][k];
474
+ weta += sim[k][j] * sim[k][j];
475
+ }
476
+ vsig[j] = 1.0 / Math.sqrt(wsig);
477
+ veta[j] = Math.sqrt(weta);
478
+ if (vsig[j] < parsig || veta[j] > pareta) {
479
+ iflag = false;
480
+ }
481
+ }
466
482
 
467
- for (j = 1; j <= n; ++j) {
468
- wsig = 0.0;
469
- for (k = 1; k <= n; ++k) {
470
- wsig += simi[j][k] * simi[j][k];
471
- }
472
- weta = 0.0;
473
- for (k = 1; k <= n; ++k) {
474
- weta += sim[k][j] * sim[k][j];
475
- }
476
- vsig[j] = 1.0 / Math.sqrt(wsig);
477
- veta[j] = Math.sqrt(weta);
478
- if (vsig[j] < parsig || veta[j] > pareta) { iflag = false; }
479
- }
483
+ // If a new vertex is needed to improve acceptability, then decide which
484
+ // vertex to drop from the simplex.
485
+ if (!ibrnch && !iflag) {
486
+ jdrop = 0;
487
+ temp = pareta;
488
+ for (j = 1; j <= n; ++j) {
489
+ if (veta[j] > temp) {
490
+ jdrop = j;
491
+ temp = veta[j];
492
+ }
493
+ }
494
+ if (jdrop === 0) {
495
+ for (j = 1; j <= n; ++j) {
496
+ if (vsig[j] < temp) {
497
+ jdrop = j;
498
+ temp = vsig[j];
499
+ }
500
+ }
501
+ }
480
502
 
481
- // If a new vertex is needed to improve acceptability, then decide which
482
- // vertex to drop from the simplex.
483
- if (!ibrnch && !iflag) {
484
- jdrop = 0;
485
- temp = pareta;
486
- for (j = 1; j <= n; ++j) {
487
- if (veta[j] > temp) {
488
- jdrop = j;
489
- temp = veta[j];
490
- }
491
- }
492
- if (jdrop === 0) {
493
- for (j = 1; j <= n; ++j) {
494
- if (vsig[j] < temp) {
495
- jdrop = j;
496
- temp = vsig[j];
503
+ // Calculate the step to the new vertex and its sign.
504
+ temp = gamma * rho * vsig[jdrop];
505
+ for (k = 1; k <= n; ++k) {
506
+ dx[k] = temp * simi[jdrop][k];
507
+ }
508
+ cvmaxp = 0.0;
509
+ cvmaxm = 0.0;
510
+ total = 0.0;
511
+ for (k = 1; k <= mp; ++k) {
512
+ // total = this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));
513
+ total = this.DOT_PRODUCT_ROW_COL(dx, -1, a, k, 1, n);
514
+ if (k < mp) {
515
+ temp = datmat[k][np];
516
+ cvmaxp = Math.max(cvmaxp, -total - temp);
517
+ cvmaxm = Math.max(cvmaxm, total - temp);
518
+ }
519
+ }
520
+ dxsign = parmu * (cvmaxp - cvmaxm) > 2.0 * total ? -1.0 : 1.0;
521
+
522
+ // Update the elements of SIM and SIMI, and set the next X.
523
+ temp = 0.0;
524
+ for (i = 1; i <= n; ++i) {
525
+ dx[i] = dxsign * dx[i];
526
+ sim[i][jdrop] = dx[i];
527
+ temp += simi[jdrop][i] * dx[i];
528
+ }
529
+ for (k = 1; k <= n; ++k) {
530
+ simi[jdrop][k] /= temp;
531
+ }
532
+
533
+ for (j = 1; j <= n; ++j) {
534
+ if (j !== jdrop) {
535
+ // temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));
536
+ temp = this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n);
537
+ for (k = 1; k <= n; ++k) {
538
+ simi[j][k] -= temp * simi[jdrop][k];
539
+ }
540
+ }
541
+ x[j] = sim[j][np] + dx[j];
542
+ }
543
+ continue L_40;
497
544
  }
498
- }
499
- }
500
545
 
501
- // Calculate the step to the new vertex and its sign.
502
- temp = gamma * rho * vsig[jdrop];
503
- for (k = 1; k <= n; ++k) {
504
- dx[k] = temp * simi[jdrop][k];
505
- }
506
- cvmaxp = 0.0;
507
- cvmaxm = 0.0;
508
- total = 0.0;
509
- for (k = 1; k <= mp; ++k) {
510
- total = this.DOT_PRODUCT(
511
- this.PART(this.COL(a, k), 1, n),
512
- this.PART(dx, 1, n)
513
- );
514
- if (k < mp) {
515
- temp = datmat[k][np];
516
- cvmaxp = Math.max(cvmaxp, -total - temp);
517
- cvmaxm = Math.max(cvmaxm, total - temp);
518
- }
519
- }
520
- dxsign = parmu * (cvmaxp - cvmaxm) > 2.0 * total ? -1.0 : 1.0;
546
+ // Calculate DX = x(*)-x(0).
547
+ // Branch if the length of DX is less than 0.5*RHO.
548
+ ifull = this.trstlp(n, m, a, con, rho, dx);
549
+ if (!ifull) {
550
+ temp = 0.0;
551
+ for (k = 1; k <= n; ++k) {
552
+ temp += dx[k] * dx[k];
553
+ }
554
+ if (temp < 0.25 * rho * rho) {
555
+ ibrnch = true;
556
+ break L_550;
557
+ }
558
+ }
521
559
 
522
- // Update the elements of SIM and SIMI, and set the next X.
523
- temp = 0.0;
524
- for (i = 1; i <= n; ++i) {
525
- dx[i] = dxsign * dx[i];
526
- sim[i][jdrop] = dx[i];
527
- temp += simi[jdrop][i] * dx[i];
528
- }
529
- for (k = 1; k <= n; ++k) {
530
- simi[jdrop][k] /= temp;
531
- }
560
+ // Predict the change to F and the new maximum constraint violation if the
561
+ // variables are altered from x(0) to x(0) + DX.
562
+ total = 0.0;
563
+ resnew = 0.0;
564
+ con[mp] = 0.0;
565
+ for (k = 1; k <= mp; ++k) {
566
+ //total = con[k] - this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));
567
+ total = con[k] - this.DOT_PRODUCT_ROW_COL(dx, -1, a, k, 1, n);
568
+ if (k < mp) {
569
+ resnew = Math.max(resnew, total);
570
+ }
571
+ }
532
572
 
533
- for (j = 1; j <= n; ++j) {
534
- if (j !== jdrop) {
535
- temp = this.DOT_PRODUCT(
536
- this.PART(this.ROW(simi, j), 1, n),
537
- this.PART(dx, 1, n)
538
- );
573
+ // Increase PARMU if necessary and branch back if this change alters the
574
+ // optimal vertex. Otherwise PREREM and PREREC will be set to the predicted
575
+ // reductions in the merit function and the maximum constraint violation
576
+ // respectively.
577
+ prerec = datmat[mpp][np] - resnew;
578
+ barmu = prerec > 0.0 ? total / prerec : 0.0;
579
+ if (parmu < 1.5 * barmu) {
580
+ parmu = 2.0 * barmu;
581
+ if (iprint >= 2) {
582
+ console.log("Increase in PARMU to " + parmu);
583
+ }
584
+ phi = datmat[mp][np] + parmu * datmat[mpp][np];
585
+ for (j = 1; j <= n; ++j) {
586
+ temp = datmat[mp][j] + parmu * datmat[mpp][j];
587
+ if (temp < phi || (temp === phi && parmu === 0.0 && datmat[mpp][j] < datmat[mpp][np])) {
588
+ continue L_140;
589
+ }
590
+ }
591
+ }
592
+ prerem = parmu * prerec - total;
593
+
594
+ // Calculate the constraint and objective functions at x(*).
595
+ // Then find the actual reduction in the merit function.
539
596
  for (k = 1; k <= n; ++k) {
540
- simi[j][k] -= temp * simi[jdrop][k];
597
+ x[k] = sim[k][np] + dx[k];
541
598
  }
599
+ ibrnch = true;
600
+ continue L_40;
542
601
  }
543
- x[j] = sim[j][np] + dx[j];
544
- }
545
- continue L_40;
546
- }
547
602
 
548
- // Calculate DX = x(*)-x(0).
549
- // Branch if the length of DX is less than 0.5*RHO.
550
- ifull = this.trstlp(n, m, a, con, rho, dx);
551
- if (!ifull) {
552
- temp = 0.0;
553
- for (k = 1; k <= n; ++k) {
554
- temp += dx[k] * dx[k];
555
- }
556
- if (temp < 0.25 * rho * rho) {
557
- ibrnch = true;
558
- break L_550;
559
- }
560
- }
603
+ skipVertexIdent = false;
604
+ vmold = datmat[mp][np] + parmu * datmat[mpp][np];
605
+ vmnew = f + parmu * resmax;
606
+ trured = vmold - vmnew;
607
+ if (parmu === 0.0 && f === datmat[mp][np]) {
608
+ prerem = prerec;
609
+ trured = datmat[mpp][np] - resmax;
610
+ }
561
611
 
562
- // Predict the change to F and the new maximum constraint violation if the
563
- // variables are altered from x(0) to x(0) + DX.
564
- total = 0.0;
565
- resnew = 0.0;
566
- con[mp] = 0.0;
567
- for (k = 1; k <= mp; ++k) {
568
- total = con[k] - this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));
569
- if (k < mp) { resnew = Math.max(resnew, total); }
570
- }
612
+ // Begin the operations that decide whether x(*) should replace one of the
613
+ // vertices of the current simplex, the change being mandatory if TRURED is
614
+ // positive. Firstly, JDROP is set to the index of the vertex that is to be
615
+ // replaced.
616
+ ratio = trured <= 0.0 ? 1.0 : 0.0;
617
+ jdrop = 0;
618
+ for (j = 1; j <= n; ++j) {
619
+ // temp = Math.abs(this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n)));
620
+ temp = Math.abs(this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n));
621
+ if (temp > ratio) {
622
+ jdrop = j;
623
+ ratio = temp;
624
+ }
625
+ sigbar[j] = temp * vsig[j];
626
+ }
571
627
 
572
- // Increase PARMU if necessary and branch back if this change alters the
573
- // optimal vertex. Otherwise PREREM and PREREC will be set to the predicted
574
- // reductions in the merit function and the maximum constraint violation
575
- // respectively.
576
- prerec = datmat[mpp][np] - resnew;
577
- barmu = prerec > 0.0 ? total / prerec : 0.0;
578
- if (parmu < 1.5 * barmu) {
579
- parmu = 2.0 * barmu;
580
- if (iprint >= 2) { console.log("Increase in PARMU to " + parmu); }
581
- phi = datmat[mp][np] + parmu * datmat[mpp][np];
582
- for (j = 1; j <= n; ++j) {
583
- temp = datmat[mp][j] + parmu * datmat[mpp][j];
584
- if (temp < phi || (temp === phi && parmu === 0.0 && datmat[mpp][j] < datmat[mpp][np])) {
585
- continue L_140;
628
+ // Calculate the value of ell.
629
+
630
+ edgmax = delta * rho;
631
+ l = 0;
632
+ for (j = 1; j <= n; ++j) {
633
+ if (sigbar[j] >= parsig || sigbar[j] >= vsig[j]) {
634
+ temp = veta[j];
635
+ if (trured > 0.0) {
636
+ temp = 0.0;
637
+ for (k = 1; k <= n; ++k) {
638
+ temp += Math.pow(dx[k] - sim[k][j], 2.0);
639
+ }
640
+ temp = Math.sqrt(temp);
641
+ }
642
+ if (temp > edgmax) {
643
+ l = j;
644
+ edgmax = temp;
645
+ }
646
+ }
647
+ }
648
+ if (l > 0) {
649
+ jdrop = l;
586
650
  }
587
- }
588
- }
589
- prerem = parmu * prerec - total;
590
651
 
591
- // Calculate the constraint and objective functions at x(*).
592
- // Then find the actual reduction in the merit function.
593
- for (k = 1; k <= n; ++k) {
594
- x[k] = sim[k][np] + dx[k];
595
- }
596
- ibrnch = true;
597
- continue L_40;
598
- }
652
+ if (jdrop !== 0) {
653
+ // Revise the simplex by updating the elements of SIM, SIMI and DATMAT.
654
+ temp = 0.0;
655
+ for (i = 1; i <= n; ++i) {
656
+ sim[i][jdrop] = dx[i];
657
+ temp += simi[jdrop][i] * dx[i];
658
+ }
659
+ for (k = 1; k <= n; ++k) {
660
+ simi[jdrop][k] /= temp;
661
+ }
662
+ for (j = 1; j <= n; ++j) {
663
+ if (j !== jdrop) {
664
+ // temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));
665
+ temp = this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n);
666
+ for (k = 1; k <= n; ++k) {
667
+ simi[j][k] -= temp * simi[jdrop][k];
668
+ }
669
+ }
670
+ }
671
+ for (k = 1; k <= mpp; ++k) {
672
+ datmat[k][jdrop] = con[k];
673
+ }
599
674
 
600
- skipVertexIdent = false;
601
- vmold = datmat[mp][np] + parmu * datmat[mpp][np];
602
- vmnew = f + parmu * resmax;
603
- trured = vmold - vmnew;
604
- if (parmu === 0.0 && f === datmat[mp][np]) {
605
- prerem = prerec;
606
- trured = datmat[mpp][np] - resmax;
607
- }
675
+ // Branch back for further iterations with the current RHO.
676
+ if (trured > 0.0 && trured >= 0.1 * prerem) {
677
+ continue L_140;
678
+ }
679
+ }
680
+ } while (false);
608
681
 
609
- // Begin the operations that decide whether x(*) should replace one of the
610
- // vertices of the current simplex, the change being mandatory if TRURED is
611
- // positive. Firstly, JDROP is set to the index of the vertex that is to be
612
- // replaced.
613
- ratio = trured <= 0.0 ? 1.0 : 0.0;
614
- jdrop = 0;
615
- for (j = 1; j <= n; ++j) {
616
- temp = Math.abs(this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n)));
617
- if (temp > ratio) {
618
- jdrop = j;
619
- ratio = temp;
682
+ if (!iflag) {
683
+ ibrnch = false;
684
+ continue L_140;
620
685
  }
621
- sigbar[j] = temp * vsig[j];
622
- }
623
-
624
- // Calculate the value of ell.
625
686
 
626
- edgmax = delta * rho;
627
- l = 0;
628
- for (j = 1; j <= n; ++j) {
629
- if (sigbar[j] >= parsig || sigbar[j] >= vsig[j]) {
630
- temp = veta[j];
631
- if (trured > 0.0) {
632
- temp = 0.0;
633
- for (k = 1; k <= n; ++k) {
634
- temp += Math.pow(dx[k] - sim[k][j], 2.0);
635
- }
636
- temp = Math.sqrt(temp);
637
- }
638
- if (temp > edgmax) {
639
- l = j;
640
- edgmax = temp;
641
- }
687
+ if (rho <= rhoend) {
688
+ status = this.Normal;
689
+ break L_40;
642
690
  }
643
- }
644
- if (l > 0) { jdrop = l; }
645
-
646
- if (jdrop !== 0) {
647
- // Revise the simplex by updating the elements of SIM, SIMI and DATMAT.
648
- temp = 0.0;
649
- for (i = 1; i <= n; ++i) {
650
- sim[i][jdrop] = dx[i];
651
- temp += simi[jdrop][i] * dx[i];
691
+
692
+ // Otherwise reduce RHO if it is not at its least value and reset PARMU.
693
+ cmin = 0.0;
694
+ cmax = 0.0;
695
+ rho *= 0.5;
696
+ if (rho <= 1.5 * rhoend) {
697
+ rho = rhoend;
652
698
  }
653
- for (k = 1; k <= n; ++k) { simi[jdrop][k] /= temp; }
654
- for (j = 1; j <= n; ++j) {
655
- if (j !== jdrop) {
656
- temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));
657
- for (k = 1; k <= n; ++k) {
658
- simi[j][k] -= temp * simi[jdrop][k];
699
+ if (parmu > 0.0) {
700
+ denom = 0.0;
701
+ for (k = 1; k <= mp; ++k) {
702
+ cmin = datmat[k][np];
703
+ cmax = cmin;
704
+ for (i = 1; i <= n; ++i) {
705
+ cmin = Math.min(cmin, datmat[k][i]);
706
+ cmax = Math.max(cmax, datmat[k][i]);
707
+ }
708
+ if (k <= m && cmin < 0.5 * cmax) {
709
+ temp = Math.max(cmax, 0.0) - cmin;
710
+ denom = denom <= 0.0 ? temp : Math.min(denom, temp);
659
711
  }
660
712
  }
713
+ if (denom === 0.0) {
714
+ parmu = 0.0;
715
+ } else if (cmax - cmin < parmu * denom) {
716
+ parmu = (cmax - cmin) / denom;
717
+ }
661
718
  }
662
- for (k = 1; k <= mpp; ++k) {
663
- datmat[k][jdrop] = con[k];
664
- }
665
-
666
- // Branch back for further iterations with the current RHO.
667
- if (trured > 0.0 && trured >= 0.1 * prerem) {
668
- continue L_140;
669
- }
670
- }
671
- } while (false);
672
-
673
- if (!iflag) {
674
- ibrnch = false;
675
- continue L_140;
676
- }
677
-
678
- if (rho <= rhoend) {
679
- status = this.Normal;
680
- break L_40;
681
- }
682
-
683
- // Otherwise reduce RHO if it is not at its least value and reset PARMU.
684
- cmin = 0.0;
685
- cmax = 0.0;
686
- rho *= 0.5;
687
- if (rho <= 1.5 * rhoend) { rho = rhoend; }
688
- if (parmu > 0.0) {
689
- denom = 0.0;
690
- for (k = 1; k <= mp; ++k) {
691
- cmin = datmat[k][np];
692
- cmax = cmin;
693
- for (i = 1; i <= n; ++i) {
694
- cmin = Math.min(cmin, datmat[k][i]);
695
- cmax = Math.max(cmax, datmat[k][i]);
719
+ if (iprint >= 2) {
720
+ console.log("Reduction in RHO to " + rho + " and PARMU = " + parmu);
696
721
  }
697
- if (k <= m && cmin < 0.5 * cmax) {
698
- temp = Math.max(cmax, 0.0) - cmin;
699
- denom = denom <= 0.0 ? temp : Math.min(denom, temp);
722
+ if (iprint === 2) {
723
+ this.PrintIterationResult(nfvals, datmat[mp][np], datmat[mpp][np], this.COL(sim, np), n, iprint);
700
724
  }
701
- }
702
- if (denom === 0.0) {
703
- parmu = 0.0;
704
- } else if (cmax - cmin < parmu * denom) {
705
- parmu = (cmax - cmin) / denom;
706
- }
707
- }
708
- if (iprint >= 2) {
709
- console.log("Reduction in RHO to "+rho+" and PARMU = "+parmu);
710
- }
711
- if (iprint === 2) {
712
- this.PrintIterationResult(nfvals, datmat[mp][np], datmat[mpp][np], this.COL(sim, np), n, iprint);
713
- }
725
+ } while (true);
714
726
  } while (true);
715
- } while (true);
716
727
 
717
728
  switch (status) {
718
729
  case this.Normal:
719
- if (iprint >= 1) { console.log("%nNormal return from subroutine COBYLA%n"); }
730
+ if (iprint >= 1) {
731
+ console.log("%nNormal return from subroutine COBYLA%n");
732
+ }
720
733
  if (ifull) {
721
- if (iprint >= 1) { this.PrintIterationResult(nfvals, f, resmax, x, n, iprint); }
734
+ if (iprint >= 1) {
735
+ this.PrintIterationResult(nfvals, f, resmax, x, n, iprint);
736
+ }
722
737
  return status;
723
738
  }
724
739
  break;
@@ -734,15 +749,19 @@ define(['jxg'], function (JXG) {
734
749
  break;
735
750
  }
736
751
 
737
- for (k = 1; k <= n; ++k) { x[k] = sim[k][np]; }
752
+ for (k = 1; k <= n; ++k) {
753
+ x[k] = sim[k][np];
754
+ }
738
755
  f = datmat[mp][np];
739
756
  resmax = datmat[mpp][np];
740
- if (iprint >= 1) { this.PrintIterationResult(nfvals, f, resmax, x, n, iprint); }
757
+ if (iprint >= 1) {
758
+ this.PrintIterationResult(nfvals, f, resmax, x, n, iprint);
759
+ }
741
760
 
742
761
  return status;
743
762
  },
744
763
 
745
- trstlp: function(n, m, a, b, rho, dx) { //(int n, int m, double[][] a, double[] b, double rho, double[] dx)
764
+ trstlp: function (n, m, a, b, rho, dx) { //(int n, int m, double[][] a, double[] b, double rho, double[] dx)
746
765
  // N.B. Arguments Z, ZDOTA, VMULTC, SDIRN, DXNEW, VMULTD & IACT have been removed.
747
766
 
748
767
  // This subroutine calculates an N-component vector DX by applying the
@@ -840,385 +859,426 @@ define(['jxg'], function (JXG) {
840
859
  first = true;
841
860
  do {
842
861
  L_60:
843
- do {
844
- if (!first || (first && resmax === 0.0)) {
845
- mcon = m + 1;
846
- icon = mcon;
847
- iact[mcon] = mcon;
848
- vmultc[mcon] = 0.0;
849
- }
850
- first = false;
851
-
852
- optold = 0.0;
853
- icount = 0;
854
- step = 0;
855
- stpful = 0;
856
-
857
- L_70:
858
862
  do {
859
- optnew = (mcon === m) ? resmax : -this.DOT_PRODUCT(
860
- this.PART(dx, 1, n), this.PART(this.COL(a, mcon), 1, n)
861
- );
862
-
863
- if (icount === 0 || optnew < optold) {
864
- optold = optnew;
865
- nactx = nact;
866
- icount = 3;
867
- } else if (nact > nactx) {
868
- nactx = nact;
869
- icount = 3;
870
- } else {
871
- --icount;
863
+ if (!first || (first && resmax === 0.0)) {
864
+ mcon = m + 1;
865
+ icon = mcon;
866
+ iact[mcon] = mcon;
867
+ vmultc[mcon] = 0.0;
872
868
  }
873
- if (icount === 0) { break L_60; }
874
-
875
- // If ICON exceeds NACT, then we add the constraint with index IACT(ICON) to
876
- // the active set. Apply Givens rotations so that the last N-NACT-1 columns
877
- // of Z are orthogonal to the gradient of the new constraint, a scalar
878
- // product being set to zero if its nonzero value could be due to computer
879
- // rounding errors. The array DXNEW is used for working space.
880
- ratio = 0;
881
- if (icon <= nact) {
882
- if (icon < nact) {
883
- // Delete the constraint that has the index IACT(ICON) from the active set.
884
-
885
- isave = iact[icon];
886
- vsave = vmultc[icon];
887
- k = icon;
888
- do {
889
- kp = k + 1;
890
- kk = iact[kp];
891
- sp = this.DOT_PRODUCT(
892
- this.PART(this.COL(z, k), 1, n),
893
- this.PART(this.COL(a, kk), 1, n)
894
- );
895
- temp = Math.sqrt(sp * sp + zdota[kp] * zdota[kp]);
896
- alpha = zdota[kp] / temp;
897
- beta = sp / temp;
898
- zdota[kp] = alpha * zdota[k];
899
- zdota[k] = temp;
900
- for (i = 1; i <= n; ++i) {
901
- temp = alpha * z[i][kp] + beta * z[i][k];
902
- z[i][kp] = alpha * z[i][k] - beta * z[i][kp];
903
- z[i][k] = temp;
904
- }
905
- iact[k] = kk;
906
- vmultc[k] = vmultc[kp];
907
- k = kp;
908
- } while (k < nact);
869
+ first = false;
909
870
 
910
- iact[k] = isave;
911
- vmultc[k] = vsave;
912
- }
913
- --nact;
914
-
915
- // If stage one is in progress, then set SDIRN to the direction of the next
916
- // change to the current vector of variables.
917
- if (mcon > m) {
918
- // Pick the next search direction of stage two.
919
- temp = 1.0 / zdota[nact];
920
- for (k = 1; k <= n; ++k) { sdirn[k] = temp * z[k][nact]; }
921
- } else {
922
- temp = this.DOT_PRODUCT(
923
- this.PART(sdirn, 1, n), this.PART(this.COL(z, nact + 1), 1, n)
924
- );
925
- for (k = 1; k <= n; ++k) { sdirn[k] -= temp * z[k][nact + 1]; }
926
- }
927
- } else {
928
- kk = iact[icon];
929
- for (k = 1; k <= n; ++k) { dxnew[k] = a[k][kk]; }
930
- tot = 0.0;
931
-
932
- // {
933
- k = n;
934
- while (k > nact) {
935
- sp = 0.0;
936
- spabs = 0.0;
937
- for (i = 1; i <= n; ++i) {
938
- temp = z[i][k] * dxnew[i];
939
- sp += temp;
940
- spabs += Math.abs(temp);
871
+ optold = 0.0;
872
+ icount = 0;
873
+ step = 0;
874
+ stpful = 0;
875
+
876
+ L_70:
877
+ do {
878
+ // optnew = (mcon === m) ? resmax : -this.DOT_PRODUCT(this.PART(dx, 1, n), this.PART(this.COL(a, mcon), 1, n));
879
+ optnew = (mcon === m) ? resmax : -this.DOT_PRODUCT_ROW_COL(dx, -1, a, mcon, 1, n);
880
+
881
+ if (icount === 0 || optnew < optold) {
882
+ optold = optnew;
883
+ nactx = nact;
884
+ icount = 3;
885
+ } else if (nact > nactx) {
886
+ nactx = nact;
887
+ icount = 3;
888
+ } else {
889
+ --icount;
890
+ }
891
+ if (icount === 0) {
892
+ break L_60;
893
+ }
894
+
895
+ // If ICON exceeds NACT, then we add the constraint with index IACT(ICON) to
896
+ // the active set. Apply Givens rotations so that the last N-NACT-1 columns
897
+ // of Z are orthogonal to the gradient of the new constraint, a scalar
898
+ // product being set to zero if its nonzero value could be due to computer
899
+ // rounding errors. The array DXNEW is used for working space.
900
+ ratio = 0;
901
+ if (icon <= nact) {
902
+ if (icon < nact) {
903
+ // Delete the constraint that has the index IACT(ICON) from the active set.
904
+
905
+ isave = iact[icon];
906
+ vsave = vmultc[icon];
907
+ k = icon;
908
+ do {
909
+ kp = k + 1;
910
+ kk = iact[kp];
911
+ sp = this.DOT_PRODUCT(
912
+ this.PART(this.COL(z, k), 1, n),
913
+ this.PART(this.COL(a, kk), 1, n)
914
+ );
915
+ temp = Math.sqrt(sp * sp + zdota[kp] * zdota[kp]);
916
+ alpha = zdota[kp] / temp;
917
+ beta = sp / temp;
918
+ zdota[kp] = alpha * zdota[k];
919
+ zdota[k] = temp;
920
+ for (i = 1; i <= n; ++i) {
921
+ temp = alpha * z[i][kp] + beta * z[i][k];
922
+ z[i][kp] = alpha * z[i][k] - beta * z[i][kp];
923
+ z[i][k] = temp;
924
+ }
925
+ iact[k] = kk;
926
+ vmultc[k] = vmultc[kp];
927
+ k = kp;
928
+ } while (k < nact);
929
+
930
+ iact[k] = isave;
931
+ vmultc[k] = vsave;
941
932
  }
942
- acca = spabs + 0.1 * Math.abs(sp);
943
- accb = spabs + 0.2 * Math.abs(sp);
944
- if (spabs >= acca || acca >= accb) { sp = 0.0; }
945
- if (tot === 0.0) {
946
- tot = sp;
933
+ --nact;
934
+
935
+ // If stage one is in progress, then set SDIRN to the direction of the next
936
+ // change to the current vector of variables.
937
+ if (mcon > m) {
938
+ // Pick the next search direction of stage two.
939
+ temp = 1.0 / zdota[nact];
940
+ for (k = 1; k <= n; ++k) {
941
+ sdirn[k] = temp * z[k][nact];
942
+ }
947
943
  } else {
948
- kp = k + 1;
949
- temp = Math.sqrt(sp * sp + tot * tot);
950
- alpha = sp / temp;
951
- beta = tot / temp;
952
- tot = temp;
953
- for (i = 1; i <= n; ++i) {
954
- temp = alpha * z[i][k] + beta * z[i][kp];
955
- z[i][kp] = alpha * z[i][kp] - beta * z[i][k];
956
- z[i][k] = temp;
944
+ // temp = this.DOT_PRODUCT(this.PART(sdirn, 1, n), this.PART(this.COL(z, nact + 1), 1, n));
945
+ temp = this.DOT_PRODUCT_ROW_COL(sdirn, -1, z, nact + 1, 1, n);
946
+ for (k = 1; k <= n; ++k) {
947
+ sdirn[k] -= temp * z[k][nact + 1];
957
948
  }
958
949
  }
959
- --k;
960
- }
961
- // }
962
-
963
- if (tot === 0.0) {
964
- // The next instruction is reached if a deletion has to be made from the
965
- // active set in order to make room for the new active constraint, because
966
- // the new constraint gradient is a linear combination of the gradients of
967
- // the old active constraints. Set the elements of VMULTD to the multipliers
968
- // of the linear combination. Further, set IOUT to the index of the
969
- // constraint to be deleted, but branch if no suitable index can be found.
970
-
971
- ratio = -1.0;
972
- //{
973
- k = nact;
974
- do {
975
- zdotv = 0.0;
976
- zdvabs = 0.0;
950
+ } else {
951
+ kk = iact[icon];
952
+ for (k = 1; k <= n; ++k) {
953
+ dxnew[k] = a[k][kk];
954
+ }
955
+ tot = 0.0;
977
956
 
957
+ // {
958
+ k = n;
959
+ while (k > nact) {
960
+ sp = 0.0;
961
+ spabs = 0.0;
978
962
  for (i = 1; i <= n; ++i) {
979
963
  temp = z[i][k] * dxnew[i];
980
- zdotv += temp;
981
- zdvabs += Math.abs(temp);
964
+ sp += temp;
965
+ spabs += Math.abs(temp);
966
+ }
967
+ acca = spabs + 0.1 * Math.abs(sp);
968
+ accb = spabs + 0.2 * Math.abs(sp);
969
+ if (spabs >= acca || acca >= accb) {
970
+ sp = 0.0;
982
971
  }
983
- acca = zdvabs + 0.1 * Math.abs(zdotv);
984
- accb = zdvabs + 0.2 * Math.abs(zdotv);
985
- if (zdvabs < acca && acca < accb) {
986
- temp = zdotv / zdota[k];
987
- if (temp > 0.0 && iact[k] <= m) {
988
- tempa = vmultc[k] / temp;
989
- if (ratio < 0.0 || tempa < ratio) { ratio = tempa; }
972
+ if (tot === 0.0) {
973
+ tot = sp;
974
+ } else {
975
+ kp = k + 1;
976
+ temp = Math.sqrt(sp * sp + tot * tot);
977
+ alpha = sp / temp;
978
+ beta = tot / temp;
979
+ tot = temp;
980
+ for (i = 1; i <= n; ++i) {
981
+ temp = alpha * z[i][k] + beta * z[i][kp];
982
+ z[i][kp] = alpha * z[i][kp] - beta * z[i][k];
983
+ z[i][k] = temp;
990
984
  }
985
+ }
986
+ --k;
987
+ }
988
+ // }
991
989
 
992
- if (k >= 2) {
993
- kw = iact[k];
994
- for (i = 1; i <= n; ++i) { dxnew[i] -= temp * a[i][kw]; }
990
+ if (tot === 0.0) {
991
+ // The next instruction is reached if a deletion has to be made from the
992
+ // active set in order to make room for the new active constraint, because
993
+ // the new constraint gradient is a linear combination of the gradients of
994
+ // the old active constraints. Set the elements of VMULTD to the multipliers
995
+ // of the linear combination. Further, set IOUT to the index of the
996
+ // constraint to be deleted, but branch if no suitable index can be found.
997
+
998
+ ratio = -1.0;
999
+ //{
1000
+ k = nact;
1001
+ do {
1002
+ zdotv = 0.0;
1003
+ zdvabs = 0.0;
1004
+
1005
+ for (i = 1; i <= n; ++i) {
1006
+ temp = z[i][k] * dxnew[i];
1007
+ zdotv += temp;
1008
+ zdvabs += Math.abs(temp);
995
1009
  }
996
- vmultd[k] = temp;
997
- } else {
998
- vmultd[k] = 0.0;
1010
+ acca = zdvabs + 0.1 * Math.abs(zdotv);
1011
+ accb = zdvabs + 0.2 * Math.abs(zdotv);
1012
+ if (zdvabs < acca && acca < accb) {
1013
+ temp = zdotv / zdota[k];
1014
+ if (temp > 0.0 && iact[k] <= m) {
1015
+ tempa = vmultc[k] / temp;
1016
+ if (ratio < 0.0 || tempa < ratio) {
1017
+ ratio = tempa;
1018
+ }
1019
+ }
1020
+
1021
+ if (k >= 2) {
1022
+ kw = iact[k];
1023
+ for (i = 1; i <= n; ++i) {
1024
+ dxnew[i] -= temp * a[i][kw];
1025
+ }
1026
+ }
1027
+ vmultd[k] = temp;
1028
+ } else {
1029
+ vmultd[k] = 0.0;
1030
+ }
1031
+ } while (--k > 0);
1032
+ //}
1033
+ if (ratio < 0.0) {
1034
+ break L_60;
999
1035
  }
1000
- } while (--k > 0);
1001
- //}
1002
- if (ratio < 0.0) { break L_60; }
1003
1036
 
1004
- // Revise the Lagrange multipliers and reorder the active constraints so
1005
- // that the one to be replaced is at the end of the list. Also calculate the
1006
- // new value of ZDOTA(NACT) and branch if it is not acceptable.
1037
+ // Revise the Lagrange multipliers and reorder the active constraints so
1038
+ // that the one to be replaced is at the end of the list. Also calculate the
1039
+ // new value of ZDOTA(NACT) and branch if it is not acceptable.
1007
1040
 
1008
- for (k = 1; k <= nact; ++k) {
1009
- vmultc[k] = Math.max(0.0, vmultc[k] - ratio * vmultd[k]);
1010
- }
1011
- if (icon < nact) {
1012
- isave = iact[icon];
1013
- vsave = vmultc[icon];
1014
- k = icon;
1015
- do {
1016
- kp = k + 1;
1017
- kw = iact[kp];
1041
+ for (k = 1; k <= nact; ++k) {
1042
+ vmultc[k] = Math.max(0.0, vmultc[k] - ratio * vmultd[k]);
1043
+ }
1044
+ if (icon < nact) {
1045
+ isave = iact[icon];
1046
+ vsave = vmultc[icon];
1047
+ k = icon;
1048
+ do {
1049
+ kp = k + 1;
1050
+ kw = iact[kp];
1051
+ sp = this.DOT_PRODUCT(
1052
+ this.PART(this.COL(z, k), 1, n),
1053
+ this.PART(this.COL(a, kw), 1, n)
1054
+ );
1055
+ temp = Math.sqrt(sp * sp + zdota[kp] * zdota[kp]);
1056
+ alpha = zdota[kp] / temp;
1057
+ beta = sp / temp;
1058
+ zdota[kp] = alpha * zdota[k];
1059
+ zdota[k] = temp;
1060
+ for (i = 1; i <= n; ++i) {
1061
+ temp = alpha * z[i][kp] + beta * z[i][k];
1062
+ z[i][kp] = alpha * z[i][k] - beta * z[i][kp];
1063
+ z[i][k] = temp;
1064
+ }
1065
+ iact[k] = kw;
1066
+ vmultc[k] = vmultc[kp];
1067
+ k = kp;
1068
+ } while (k < nact);
1069
+ iact[k] = isave;
1070
+ vmultc[k] = vsave;
1071
+ }
1072
+ temp = this.DOT_PRODUCT(
1073
+ this.PART(this.COL(z, nact), 1, n),
1074
+ this.PART(this.COL(a, kk), 1, n)
1075
+ );
1076
+ if (temp === 0.0) {
1077
+ break L_60;
1078
+ }
1079
+ zdota[nact] = temp;
1080
+ vmultc[icon] = 0.0;
1081
+ vmultc[nact] = ratio;
1082
+ } else {
1083
+ // Add the new constraint if this can be done without a deletion from the
1084
+ // active set.
1085
+
1086
+ ++nact;
1087
+ zdota[nact] = tot;
1088
+ vmultc[icon] = vmultc[nact];
1089
+ vmultc[nact] = 0.0;
1090
+ }
1091
+
1092
+ // Update IACT and ensure that the objective function continues to be
1093
+ // treated as the last active constraint when MCON>M.
1094
+
1095
+ iact[icon] = iact[nact];
1096
+ iact[nact] = kk;
1097
+ if (mcon > m && kk !== mcon) {
1098
+ k = nact - 1;
1018
1099
  sp = this.DOT_PRODUCT(
1019
- this.PART(this.COL(z, k), 1, n),
1020
- this.PART(this.COL(a, kw), 1, n)
1021
- );
1022
- temp = Math.sqrt(sp * sp + zdota[kp] * zdota[kp]);
1023
- alpha = zdota[kp] / temp;
1100
+ this.PART(this.COL(z, k), 1, n),
1101
+ this.PART(this.COL(a, kk), 1, n)
1102
+ );
1103
+ temp = Math.sqrt(sp * sp + zdota[nact] * zdota[nact]);
1104
+ alpha = zdota[nact] / temp;
1024
1105
  beta = sp / temp;
1025
- zdota[kp] = alpha * zdota[k];
1106
+ zdota[nact] = alpha * zdota[k];
1026
1107
  zdota[k] = temp;
1027
1108
  for (i = 1; i <= n; ++i) {
1028
- temp = alpha * z[i][kp] + beta * z[i][k];
1029
- z[i][kp] = alpha * z[i][k] - beta * z[i][kp];
1109
+ temp = alpha * z[i][nact] + beta * z[i][k];
1110
+ z[i][nact] = alpha * z[i][k] - beta * z[i][nact];
1030
1111
  z[i][k] = temp;
1031
1112
  }
1032
- iact[k] = kw;
1033
- vmultc[k] = vmultc[kp];
1034
- k = kp;
1035
- } while (k < nact);
1036
- iact[k] = isave;
1037
- vmultc[k] = vsave;
1113
+ iact[nact] = iact[k];
1114
+ iact[k] = kk;
1115
+ temp = vmultc[k];
1116
+ vmultc[k] = vmultc[nact];
1117
+ vmultc[nact] = temp;
1118
+ }
1119
+
1120
+ // If stage one is in progress, then set SDIRN to the direction of the next
1121
+ // change to the current vector of variables.
1122
+ if (mcon > m) {
1123
+ // Pick the next search direction of stage two.
1124
+ temp = 1.0 / zdota[nact];
1125
+ for (k = 1; k <= n; ++k) {
1126
+ sdirn[k] = temp * z[k][nact];
1127
+ }
1128
+ } else {
1129
+ kk = iact[nact];
1130
+ // temp = (this.DOT_PRODUCT(this.PART(sdirn, 1, n),this.PART(this.COL(a, kk), 1, n)) - 1.0) / zdota[nact];
1131
+ temp = (this.DOT_PRODUCT_ROW_COL(sdirn, -1, a, kk, 1, n) - 1.0) / zdota[nact];
1132
+ for (k = 1; k <= n; ++k) {
1133
+ sdirn[k] -= temp * z[k][nact];
1134
+ }
1135
+ }
1038
1136
  }
1039
- temp = this.DOT_PRODUCT(
1040
- this.PART(this.COL(z, nact), 1, n),
1041
- this.PART(this.COL(a, kk), 1, n)
1042
- );
1043
- if (temp === 0.0) { break L_60; }
1044
- zdota[nact] = temp;
1045
- vmultc[icon] = 0.0;
1046
- vmultc[nact] = ratio;
1047
- } else {
1048
- // Add the new constraint if this can be done without a deletion from the
1049
- // active set.
1050
-
1051
- ++nact;
1052
- zdota[nact] = tot;
1053
- vmultc[icon] = vmultc[nact];
1054
- vmultc[nact] = 0.0;
1055
- }
1056
1137
 
1057
- // Update IACT and ensure that the objective function continues to be
1058
- // treated as the last active constraint when MCON>M.
1059
-
1060
- iact[icon] = iact[nact];
1061
- iact[nact] = kk;
1062
- if (mcon > m && kk !== mcon) {
1063
- k = nact - 1;
1064
- sp = this.DOT_PRODUCT(
1065
- this.PART(this.COL(z, k), 1, n),
1066
- this.PART(this.COL(a, kk), 1, n)
1067
- );
1068
- temp = Math.sqrt(sp * sp + zdota[nact] * zdota[nact]);
1069
- alpha = zdota[nact] / temp;
1070
- beta = sp / temp;
1071
- zdota[nact] = alpha * zdota[k];
1072
- zdota[k] = temp;
1138
+ // Calculate the step to the boundary of the trust region or take the step
1139
+ // that reduces RESMAX to zero. The two statements below that include the
1140
+ // factor 1.0E-6 prevent some harmless underflows that occurred in a test
1141
+ // calculation. Further, we skip the step if it could be zero within a
1142
+ // reasonable tolerance for computer rounding errors.
1143
+ dd = rho * rho;
1144
+ sd = 0.0;
1145
+ ss = 0.0;
1073
1146
  for (i = 1; i <= n; ++i) {
1074
- temp = alpha * z[i][nact] + beta * z[i][k];
1075
- z[i][nact] = alpha * z[i][k] - beta * z[i][nact];
1076
- z[i][k] = temp;
1147
+ if (Math.abs(dx[i]) >= 1.0E-6 * rho) {
1148
+ dd -= dx[i] * dx[i];
1149
+ }
1150
+ sd += dx[i] * sdirn[i];
1151
+ ss += sdirn[i] * sdirn[i];
1152
+ }
1153
+ if (dd <= 0.0) {
1154
+ break L_60;
1155
+ }
1156
+ temp = Math.sqrt(ss * dd);
1157
+ if (Math.abs(sd) >= 1.0E-6 * temp) {
1158
+ temp = Math.sqrt(ss * dd + sd * sd);
1159
+ }
1160
+ stpful = dd / (temp + sd);
1161
+ step = stpful;
1162
+ if (mcon === m) {
1163
+ acca = step + 0.1 * resmax;
1164
+ accb = step + 0.2 * resmax;
1165
+ if (step >= acca || acca >= accb) {
1166
+ break L_70;
1167
+ }
1168
+ step = Math.min(step, resmax);
1077
1169
  }
1078
- iact[nact] = iact[k];
1079
- iact[k] = kk;
1080
- temp = vmultc[k];
1081
- vmultc[k] = vmultc[nact];
1082
- vmultc[nact] = temp;
1083
- }
1084
1170
 
1085
- // If stage one is in progress, then set SDIRN to the direction of the next
1086
- // change to the current vector of variables.
1087
- if (mcon > m) {
1088
- // Pick the next search direction of stage two.
1089
- temp = 1.0 / zdota[nact];
1090
- for (k = 1; k <= n; ++k) { sdirn[k] = temp * z[k][nact]; }
1091
- } else {
1092
- kk = iact[nact];
1093
- temp = (this.DOT_PRODUCT(
1094
- this.PART(sdirn, 1, n),
1095
- this.PART(this.COL(a, kk), 1, n)
1096
- ) - 1.0) / zdota[nact];
1097
- for (k = 1; k <= n; ++k) { sdirn[k] -= temp * z[k][nact]; }
1098
- }
1099
- }
1171
+ // Set DXNEW to the new variables if STEP is the steplength, and reduce
1172
+ // RESMAX to the corresponding maximum residual if stage one is being done.
1173
+ // Because DXNEW will be changed during the calculation of some Lagrange
1174
+ // multipliers, it will be restored to the following value later.
1175
+ for (k = 1; k <= n; ++k) {
1176
+ dxnew[k] = dx[k] + step * sdirn[k];
1177
+ }
1178
+ if (mcon === m) {
1179
+ resold = resmax;
1180
+ resmax = 0.0;
1181
+ for (k = 1; k <= nact; ++k) {
1182
+ kk = iact[k];
1183
+ // temp = b[kk] - this.DOT_PRODUCT(this.PART(this.COL(a, kk), 1, n), this.PART(dxnew, 1, n));
1184
+ temp = b[kk] - this.DOT_PRODUCT_ROW_COL(dxnew, -1, a, kk, 1, n);
1185
+ resmax = Math.max(resmax, temp);
1186
+ }
1187
+ }
1100
1188
 
1101
- // Calculate the step to the boundary of the trust region or take the step
1102
- // that reduces RESMAX to zero. The two statements below that include the
1103
- // factor 1.0E-6 prevent some harmless underflows that occurred in a test
1104
- // calculation. Further, we skip the step if it could be zero within a
1105
- // reasonable tolerance for computer rounding errors.
1106
- dd = rho * rho;
1107
- sd = 0.0;
1108
- ss = 0.0;
1109
- for (i = 1; i <= n; ++i) {
1110
- if (Math.abs(dx[i]) >= 1.0E-6 * rho) { dd -= dx[i] * dx[i]; }
1111
- sd += dx[i] * sdirn[i];
1112
- ss += sdirn[i] * sdirn[i];
1113
- }
1114
- if (dd <= 0.0) { break L_60; }
1115
- temp = Math.sqrt(ss * dd);
1116
- if (Math.abs(sd) >= 1.0E-6 * temp) { temp = Math.sqrt(ss * dd + sd * sd); }
1117
- stpful = dd / (temp + sd);
1118
- step = stpful;
1119
- if (mcon === m) {
1120
- acca = step + 0.1 * resmax;
1121
- accb = step + 0.2 * resmax;
1122
- if (step >= acca || acca >= accb) { break L_70; }
1123
- step = Math.min(step, resmax);
1124
- }
1189
+ // Set VMULTD to the VMULTC vector that would occur if DX became DXNEW. A
1190
+ // device is included to force VMULTD(K) = 0.0 if deviations from this value
1191
+ // can be attributed to computer rounding errors. First calculate the new
1192
+ // Lagrange multipliers.
1193
+ //{
1194
+ k = nact;
1195
+ do {
1196
+ zdotw = 0.0;
1197
+ zdwabs = 0.0;
1198
+ for (i = 1; i <= n; ++i) {
1199
+ temp = z[i][k] * dxnew[i];
1200
+ zdotw += temp;
1201
+ zdwabs += Math.abs(temp);
1202
+ }
1203
+ acca = zdwabs + 0.1 * Math.abs(zdotw);
1204
+ accb = zdwabs + 0.2 * Math.abs(zdotw);
1205
+ if (zdwabs >= acca || acca >= accb) {
1206
+ zdotw = 0.0;
1207
+ }
1208
+ vmultd[k] = zdotw / zdota[k];
1209
+ if (k >= 2) {
1210
+ kk = iact[k];
1211
+ for (i = 1; i <= n; ++i) {
1212
+ dxnew[i] -= vmultd[k] * a[i][kk];
1213
+ }
1214
+ }
1215
+ } while (k-- >= 2);
1216
+ if (mcon > m) {
1217
+ vmultd[nact] = Math.max(0.0, vmultd[nact]);
1218
+ }
1219
+ //}
1125
1220
 
1126
- // Set DXNEW to the new variables if STEP is the steplength, and reduce
1127
- // RESMAX to the corresponding maximum residual if stage one is being done.
1128
- // Because DXNEW will be changed during the calculation of some Lagrange
1129
- // multipliers, it will be restored to the following value later.
1130
- for (k = 1; k <= n; ++k) { dxnew[k] = dx[k] + step * sdirn[k]; }
1131
- if (mcon === m) {
1132
- resold = resmax;
1133
- resmax = 0.0;
1134
- for (k = 1; k <= nact; ++k) {
1135
- kk = iact[k];
1136
- temp = b[kk] - this.DOT_PRODUCT(
1137
- this.PART(this.COL(a, kk), 1, n), this.PART(dxnew, 1, n)
1138
- );
1139
- resmax = Math.max(resmax, temp);
1140
- }
1141
- }
1221
+ // Complete VMULTC by finding the new constraint residuals.
1142
1222
 
1143
- // Set VMULTD to the VMULTC vector that would occur if DX became DXNEW. A
1144
- // device is included to force VMULTD(K) = 0.0 if deviations from this value
1145
- // can be attributed to computer rounding errors. First calculate the new
1146
- // Lagrange multipliers.
1147
- //{
1148
- k = nact;
1149
- do {
1150
- zdotw = 0.0;
1151
- zdwabs = 0.0;
1152
- for (i = 1; i <= n; ++i) {
1153
- temp = z[i][k] * dxnew[i];
1154
- zdotw += temp;
1155
- zdwabs += Math.abs(temp);
1156
- }
1157
- acca = zdwabs + 0.1 * Math.abs(zdotw);
1158
- accb = zdwabs + 0.2 * Math.abs(zdotw);
1159
- if (zdwabs >= acca || acca >= accb) { zdotw = 0.0; }
1160
- vmultd[k] = zdotw / zdota[k];
1161
- if (k >= 2) {
1162
- kk = iact[k];
1163
- for (i = 1; i <= n; ++i) { dxnew[i] -= vmultd[k] * a[i][kk]; }
1223
+ for (k = 1; k <= n; ++k) {
1224
+ dxnew[k] = dx[k] + step * sdirn[k];
1164
1225
  }
1165
- } while (k-- >= 2);
1166
- if (mcon > m) { vmultd[nact] = Math.max(0.0, vmultd[nact]); }
1167
- //}
1168
-
1169
- // Complete VMULTC by finding the new constraint residuals.
1170
-
1171
- for (k = 1; k <= n; ++k) { dxnew[k] = dx[k] + step * sdirn[k]; }
1172
- if (mcon > nact) {
1173
- kl = nact + 1;
1174
- for (k = kl; k <= mcon; ++k) {
1175
- kk = iact[k];
1176
- total = resmax - b[kk];
1177
- sumabs = resmax + Math.abs(b[kk]);
1178
- for (i = 1; i <= n; ++i) {
1179
- temp = a[i][kk] * dxnew[i];
1180
- total += temp;
1181
- sumabs += Math.abs(temp);
1226
+ if (mcon > nact) {
1227
+ kl = nact + 1;
1228
+ for (k = kl; k <= mcon; ++k) {
1229
+ kk = iact[k];
1230
+ total = resmax - b[kk];
1231
+ sumabs = resmax + Math.abs(b[kk]);
1232
+ for (i = 1; i <= n; ++i) {
1233
+ temp = a[i][kk] * dxnew[i];
1234
+ total += temp;
1235
+ sumabs += Math.abs(temp);
1236
+ }
1237
+ acca = sumabs + 0.1 * Math.abs(total);
1238
+ accb = sumabs + 0.2 * Math.abs(total);
1239
+ if (sumabs >= acca || acca >= accb) {
1240
+ total = 0.0;
1241
+ }
1242
+ vmultd[k] = total;
1243
+ }
1182
1244
  }
1183
- acca = sumabs + 0.1 * Math.abs(total);
1184
- accb = sumabs + 0.2 * Math.abs(total);
1185
- if (sumabs >= acca || acca >= accb) { total = 0.0; }
1186
- vmultd[k] = total;
1187
- }
1188
- }
1189
1245
 
1190
- // Calculate the fraction of the step from DX to DXNEW that will be taken.
1246
+ // Calculate the fraction of the step from DX to DXNEW that will be taken.
1191
1247
 
1192
- ratio = 1.0;
1193
- icon = 0;
1194
- for (k = 1; k <= mcon; ++k) {
1195
- if (vmultd[k] < 0.0) {
1196
- temp = vmultc[k] / (vmultc[k] - vmultd[k]);
1197
- if (temp < ratio) {
1198
- ratio = temp;
1199
- icon = k;
1248
+ ratio = 1.0;
1249
+ icon = 0;
1250
+ for (k = 1; k <= mcon; ++k) {
1251
+ if (vmultd[k] < 0.0) {
1252
+ temp = vmultc[k] / (vmultc[k] - vmultd[k]);
1253
+ if (temp < ratio) {
1254
+ ratio = temp;
1255
+ icon = k;
1256
+ }
1257
+ }
1200
1258
  }
1201
- }
1202
- }
1203
1259
 
1204
- // Update DX, VMULTC and RESMAX.
1260
+ // Update DX, VMULTC and RESMAX.
1205
1261
 
1206
- temp = 1.0 - ratio;
1207
- for (k = 1; k <= n; ++k) { dx[k] = temp * dx[k] + ratio * dxnew[k]; }
1208
- for (k = 1; k <= mcon; ++k) {
1209
- vmultc[k] = Math.max(0.0, temp * vmultc[k] + ratio * vmultd[k]);
1210
- }
1211
- if (mcon === m) { resmax = resold + ratio * (resmax - resold); }
1262
+ temp = 1.0 - ratio;
1263
+ for (k = 1; k <= n; ++k) {
1264
+ dx[k] = temp * dx[k] + ratio * dxnew[k];
1265
+ }
1266
+ for (k = 1; k <= mcon; ++k) {
1267
+ vmultc[k] = Math.max(0.0, temp * vmultc[k] + ratio * vmultd[k]);
1268
+ }
1269
+ if (mcon === m) {
1270
+ resmax = resold + ratio * (resmax - resold);
1271
+ }
1212
1272
 
1213
- // If the full step is not acceptable then begin another iteration.
1214
- // Otherwise switch to stage two or end the calculation.
1215
- } while (icon > 0);
1273
+ // If the full step is not acceptable then begin another iteration.
1274
+ // Otherwise switch to stage two or end the calculation.
1275
+ } while (icon > 0);
1216
1276
 
1217
- if (step === stpful) {
1218
- return true;
1219
- }
1277
+ if (step === stpful) {
1278
+ return true;
1279
+ }
1220
1280
 
1221
- } while (true);
1281
+ } while (true);
1222
1282
 
1223
1283
  // We employ any freedom that may be available to reduce the objective
1224
1284
  // function before returning a DX whose length is less than RHO.
@@ -1228,12 +1288,16 @@ define(['jxg'], function (JXG) {
1228
1288
  return false;
1229
1289
  },
1230
1290
 
1231
- PrintIterationResult: function(nfvals, f, resmax, x, n, iprint) {
1232
- if (iprint > 1) { console.log("NFVALS = "+nfvals+" F = "+f+" MAXCV = "+resmax); }
1233
- if (iprint > 1) { console.log("X = " + this.PART(x, 1, n)); }
1291
+ PrintIterationResult: function (nfvals, f, resmax, x, n, iprint) {
1292
+ if (iprint > 1) {
1293
+ console.log("NFVALS = " + nfvals + " F = " + f + " MAXCV = " + resmax);
1294
+ }
1295
+ if (iprint > 1) {
1296
+ console.log("X = " + this.PART(x, 1, n));
1297
+ }
1234
1298
  },
1235
1299
 
1236
- ROW: function(src, rowidx) {
1300
+ ROW: function (src, rowidx) {
1237
1301
  return src[rowidx].slice();
1238
1302
  // var col,
1239
1303
  // cols = src[0].length,
@@ -1245,17 +1309,18 @@ define(['jxg'], function (JXG) {
1245
1309
  // return dest;
1246
1310
  },
1247
1311
 
1248
- COL: function(src, colidx) {
1312
+ COL: function (src, colidx) {
1249
1313
  var row,
1250
1314
  rows = src.length,
1251
- dest = this.arr(rows);
1315
+ dest = []; // this.arr(rows);
1316
+
1252
1317
  for (row = 0; row < rows; ++row) {
1253
1318
  dest[row] = src[row][colidx];
1254
1319
  }
1255
1320
  return dest;
1256
1321
  },
1257
1322
 
1258
- PART: function(src, from, to) {
1323
+ PART: function (src, from, to) {
1259
1324
  return src.slice(from, to + 1);
1260
1325
  // var srcidx,
1261
1326
  // dest = this.arr(to - from + 1),
@@ -1266,7 +1331,7 @@ define(['jxg'], function (JXG) {
1266
1331
  // return dest;
1267
1332
  },
1268
1333
 
1269
- FORMAT: function(x) {
1334
+ FORMAT: function (x) {
1270
1335
  return x.join(',');
1271
1336
  // var i, fmt = "";
1272
1337
  // for (i = 0; i < x.length; ++i) {
@@ -1275,12 +1340,38 @@ define(['jxg'], function (JXG) {
1275
1340
  // return fmt;
1276
1341
  },
1277
1342
 
1278
- DOT_PRODUCT: function(lhs, rhs) {
1343
+ DOT_PRODUCT: function (lhs, rhs) {
1279
1344
  var i, sum = 0.0,
1280
1345
  len = lhs.length;
1281
1346
  for (i = 0; i < len; ++i) {
1282
1347
  sum += lhs[i] * rhs[i];
1283
1348
  }
1349
+ return sum;
1350
+ },
1351
+
1352
+ DOT_PRODUCT_ROW_COL: function (lhs, row, rhs, col, start, end) {
1353
+ var i, sum = 0.0;
1354
+
1355
+ if (row === -1) {
1356
+ // lhs is vector
1357
+ for (i = start; i <= end; ++i) {
1358
+ sum += lhs[i] * rhs[i][col];
1359
+ }
1360
+ } else {
1361
+ // lhs is row of matrix
1362
+ if (col === -1) {
1363
+ // rhs is vector
1364
+ for (i = start; i <= end; ++i) {
1365
+ sum += lhs[row][i] * rhs[i];
1366
+ }
1367
+ } else {
1368
+ // rhs is column of matrix
1369
+ for (i = start; i <= end; ++i) {
1370
+ sum += lhs[row][i] * rhs[i][col];
1371
+ }
1372
+ }
1373
+ }
1374
+
1284
1375
  return sum;
1285
1376
  }
1286
1377