1 /* $Id: CoinSimpFactorization.cpp 2083 2019-01-06 19:38:09Z unxusr $ */
2 // Copyright (C) 2008, International Business Machines
3 // Corporation and others. All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5 #if COIN_BIG_INDEX == 0
6 #include "CoinUtilsConfig.h"
7
8 #include <cassert>
9 #include "CoinPragma.hpp"
10 #include "CoinSimpFactorization.hpp"
11 #include "CoinIndexedVector.hpp"
12 #include "CoinHelperFunctions.hpp"
13 #include "CoinPackedMatrix.hpp"
14 #include "CoinFinite.hpp"
15 #include <stdio.h>
16
17 #define ARRAY 0
18
FactorPointers(int numRows,int numColumns,int * UrowLengths_,int * UcolLengths_)19 FactorPointers::FactorPointers(int numRows, int numColumns,
20 int *UrowLengths_,
21 int *UcolLengths_)
22 {
23
24 rowMax = new double[numRows];
25 double *current = rowMax;
26 const double *end = current + numRows;
27 for (; current != end; ++current)
28 *current = -1.0;
29
30 firstRowKnonzeros = new int[numRows + 1];
31 CoinFillN(firstRowKnonzeros, numRows + 1, -1);
32
33 prevRow = new int[numRows];
34 nextRow = new int[numRows];
35 firstColKnonzeros = new int[numRows + 1];
36 memset(firstColKnonzeros, -1, (numRows + 1) * sizeof(int));
37
38 prevColumn = new int[numColumns];
39 nextColumn = new int[numColumns];
40 newCols = new int[numRows];
41
42 for (int i = numRows - 1; i >= 0; --i) {
43 int length = UrowLengths_[i];
44 prevRow[i] = -1;
45 nextRow[i] = firstRowKnonzeros[length];
46 if (nextRow[i] != -1)
47 prevRow[nextRow[i]] = i;
48 firstRowKnonzeros[length] = i;
49 }
50 for (int i = numColumns - 1; i >= 0; --i) {
51 int length = UcolLengths_[i];
52 prevColumn[i] = -1;
53 nextColumn[i] = firstColKnonzeros[length];
54 if (nextColumn[i] != -1)
55 prevColumn[nextColumn[i]] = i;
56 firstColKnonzeros[length] = i;
57 }
58 }
~FactorPointers()59 FactorPointers::~FactorPointers()
60 {
61 delete[] rowMax;
62 delete[] firstRowKnonzeros;
63 delete[] prevRow;
64 delete[] nextRow;
65 delete[] firstColKnonzeros;
66 delete[] prevColumn;
67 delete[] nextColumn;
68 delete[] newCols;
69 }
70
71 //:class CoinSimpFactorization. Deals with Factorization and Updates
72 // CoinSimpFactorization. Constructor
CoinSimpFactorization()73 CoinSimpFactorization::CoinSimpFactorization()
74 : CoinOtherFactorization()
75 {
76 gutsOfInitialize();
77 }
78
79 /// Copy constructor
CoinSimpFactorization(const CoinSimpFactorization & other)80 CoinSimpFactorization::CoinSimpFactorization(const CoinSimpFactorization &other)
81 : CoinOtherFactorization(other)
82 {
83 gutsOfInitialize();
84 gutsOfCopy(other);
85 }
86 // Clone
87 CoinOtherFactorization *
clone() const88 CoinSimpFactorization::clone() const
89 {
90 return new CoinSimpFactorization(*this);
91 }
92 /// The real work of constructors etc
gutsOfDestructor()93 void CoinSimpFactorization::gutsOfDestructor()
94 {
95 delete[] elements_;
96 delete[] pivotRow_;
97 delete[] workArea_;
98 elements_ = NULL;
99 pivotRow_ = NULL;
100 workArea_ = NULL;
101 numberRows_ = 0;
102 numberColumns_ = 0;
103 numberGoodU_ = 0;
104 status_ = -1;
105 maximumRows_ = 0;
106 maximumSpace_ = 0;
107 numberSlacks_ = 0;
108 firstNumberSlacks_ = 0;
109 //
110 delete[] denseVector_;
111 delete[] workArea2_;
112 delete[] workArea3_;
113 delete[] vecLabels_;
114 delete[] indVector_;
115
116 delete[] auxVector_;
117 delete[] auxInd_;
118
119 delete[] vecKeep_;
120 delete[] indKeep_;
121
122 delete[] LrowStarts_;
123 delete[] LrowLengths_;
124 delete[] Lrows_;
125 delete[] LrowInd_;
126
127 delete[] LcolStarts_;
128 delete[] LcolLengths_;
129 delete[] Lcolumns_;
130 delete[] LcolInd_;
131
132 delete[] UrowStarts_;
133 delete[] UrowLengths_;
134 #ifdef COIN_SIMP_CAPACITY
135 delete[] UrowCapacities_;
136 #endif
137 delete[] Urows_;
138 delete[] UrowInd_;
139
140 delete[] prevRowInU_;
141 delete[] nextRowInU_;
142
143 delete[] UcolStarts_;
144 delete[] UcolLengths_;
145 #ifdef COIN_SIMP_CAPACITY
146 delete[] UcolCapacities_;
147 #endif
148 delete[] Ucolumns_;
149 delete[] UcolInd_;
150 delete[] prevColInU_;
151 delete[] nextColInU_;
152 delete[] colSlack_;
153
154 delete[] invOfPivots_;
155
156 delete[] colOfU_;
157 delete[] colPosition_;
158 delete[] rowOfU_;
159 delete[] rowPosition_;
160 delete[] secRowOfU_;
161 delete[] secRowPosition_;
162
163 delete[] EtaPosition_;
164 delete[] EtaStarts_;
165 delete[] EtaLengths_;
166 delete[] EtaInd_;
167 delete[] Eta_;
168
169 denseVector_ = NULL;
170 workArea2_ = NULL;
171 workArea3_ = NULL;
172 vecLabels_ = NULL;
173 indVector_ = NULL;
174
175 auxVector_ = NULL;
176 auxInd_ = NULL;
177
178 vecKeep_ = NULL;
179 indKeep_ = NULL;
180
181 LrowStarts_ = NULL;
182 LrowLengths_ = NULL;
183 Lrows_ = NULL;
184 LrowInd_ = NULL;
185
186 LcolStarts_ = NULL;
187 LcolLengths_ = NULL;
188 Lcolumns_ = NULL;
189 LcolInd_ = NULL;
190
191 UrowStarts_ = NULL;
192 UrowLengths_ = NULL;
193 #ifdef COIN_SIMP_CAPACITY
194 UrowCapacities_ = NULL;
195 #endif
196 Urows_ = NULL;
197 UrowInd_ = NULL;
198
199 prevRowInU_ = NULL;
200 nextRowInU_ = NULL;
201
202 UcolStarts_ = NULL;
203 UcolLengths_ = NULL;
204 #ifdef COIN_SIMP_CAPACITY
205 UcolCapacities_ = NULL;
206 #endif
207 Ucolumns_ = NULL;
208 UcolInd_ = NULL;
209 prevColInU_ = NULL;
210 nextColInU_ = NULL;
211 colSlack_ = NULL;
212
213 invOfPivots_ = NULL;
214
215 colOfU_ = NULL;
216 colPosition_ = NULL;
217 rowOfU_ = NULL;
218 rowPosition_ = NULL;
219 secRowOfU_ = NULL;
220 secRowPosition_ = NULL;
221
222 EtaPosition_ = NULL;
223 EtaStarts_ = NULL;
224 EtaLengths_ = NULL;
225 EtaInd_ = NULL;
226 Eta_ = NULL;
227 }
gutsOfInitialize()228 void CoinSimpFactorization::gutsOfInitialize()
229 {
230 pivotTolerance_ = 1.0e-1;
231 zeroTolerance_ = 1.0e-13;
232 #ifndef COIN_FAST_CODE
233 slackValue_ = -1.0;
234 #endif
235 maximumPivots_ = 200;
236 relaxCheck_ = 1.0;
237 numberRows_ = 0;
238 numberColumns_ = 0;
239 numberGoodU_ = 0;
240 status_ = -1;
241 numberPivots_ = 0;
242 maximumRows_ = 0;
243 maximumSpace_ = 0;
244 numberSlacks_ = 0;
245 firstNumberSlacks_ = 0;
246 elements_ = NULL;
247 pivotRow_ = NULL;
248 workArea_ = NULL;
249
250 denseVector_ = NULL;
251 workArea2_ = NULL;
252 workArea3_ = NULL;
253 vecLabels_ = NULL;
254 indVector_ = NULL;
255
256 auxVector_ = NULL;
257 auxInd_ = NULL;
258
259 vecKeep_ = NULL;
260 indKeep_ = NULL;
261
262 LrowStarts_ = NULL;
263 LrowLengths_ = NULL;
264 Lrows_ = NULL;
265 LrowInd_ = NULL;
266
267 LcolStarts_ = NULL;
268 LcolLengths_ = NULL;
269 Lcolumns_ = NULL;
270 LcolInd_ = NULL;
271
272 UrowStarts_ = NULL;
273 UrowLengths_ = NULL;
274 #ifdef COIN_SIMP_CAPACITY
275 UrowCapacities_ = NULL;
276 #endif
277 Urows_ = NULL;
278 UrowInd_ = NULL;
279
280 prevRowInU_ = NULL;
281 nextRowInU_ = NULL;
282
283 UcolStarts_ = NULL;
284 UcolLengths_ = NULL;
285 #ifdef COIN_SIMP_CAPACITY
286 UcolCapacities_ = NULL;
287 #endif
288 Ucolumns_ = NULL;
289 UcolInd_ = NULL;
290 prevColInU_ = NULL;
291 nextColInU_ = NULL;
292 colSlack_ = NULL;
293
294 invOfPivots_ = NULL;
295
296 colOfU_ = NULL;
297 colPosition_ = NULL;
298 rowOfU_ = NULL;
299 rowPosition_ = NULL;
300 secRowOfU_ = NULL;
301 secRowPosition_ = NULL;
302
303 EtaPosition_ = NULL;
304 EtaStarts_ = NULL;
305 EtaLengths_ = NULL;
306 EtaInd_ = NULL;
307 Eta_ = NULL;
308 }
initialSomeNumbers()309 void CoinSimpFactorization::initialSomeNumbers()
310 {
311 keepSize_ = -1;
312 LrowSize_ = -1;
313 // LrowCap_ in allocateSomeArrays
314 LcolSize_ = -1;
315 // LcolCap_ in allocateSomeArrays
316 // UrowMaxCap_ in allocateSomeArrays
317 UrowEnd_ = -1;
318 firstRowInU_ = -1;
319 lastRowInU_ = -1;
320 firstColInU_ = -1;
321 lastColInU_ = -1;
322 //UcolMaxCap_ in allocateSomeArrays
323 UcolEnd_ = -1;
324
325 EtaSize_ = 0;
326 lastEtaRow_ = -1;
327 //maxEtaRows_ in allocateSomeArrays
328 //EtaMaxCap_ in allocateSomeArrays
329
330 // minIncrease_ in allocateSomeArrays
331 updateTol_ = 1.0e12;
332
333 doSuhlHeuristic_ = true;
334 maxU_ = -1.0;
335 maxGrowth_ = 1.e12;
336 maxA_ = -1.0;
337 pivotCandLimit_ = 4;
338 minIncrease_ = 10;
339 }
340
341 // ~CoinSimpFactorization. Destructor
~CoinSimpFactorization()342 CoinSimpFactorization::~CoinSimpFactorization()
343 {
344 gutsOfDestructor();
345 }
346 // =
operator =(const CoinSimpFactorization & other)347 CoinSimpFactorization &CoinSimpFactorization::operator=(const CoinSimpFactorization &other)
348 {
349 if (this != &other) {
350 gutsOfDestructor();
351 gutsOfInitialize();
352 gutsOfCopy(other);
353 }
354 return *this;
355 }
gutsOfCopy(const CoinSimpFactorization & other)356 void CoinSimpFactorization::gutsOfCopy(const CoinSimpFactorization &other)
357 {
358 pivotTolerance_ = other.pivotTolerance_;
359 zeroTolerance_ = other.zeroTolerance_;
360 #ifndef COIN_FAST_CODE
361 slackValue_ = other.slackValue_;
362 #endif
363 relaxCheck_ = other.relaxCheck_;
364 numberRows_ = other.numberRows_;
365 numberColumns_ = other.numberColumns_;
366 maximumRows_ = other.maximumRows_;
367 maximumSpace_ = other.maximumSpace_;
368 numberGoodU_ = other.numberGoodU_;
369 maximumPivots_ = other.maximumPivots_;
370 numberPivots_ = other.numberPivots_;
371 factorElements_ = other.factorElements_;
372 status_ = other.status_;
373 numberSlacks_ = other.numberSlacks_;
374 firstNumberSlacks_ = other.firstNumberSlacks_;
375 if (other.pivotRow_) {
376 pivotRow_ = new int[2 * maximumRows_ + maximumPivots_];
377 memcpy(pivotRow_, other.pivotRow_, (2 * maximumRows_ + numberPivots_) * sizeof(int));
378 elements_ = new CoinFactorizationDouble[maximumSpace_];
379 memcpy(elements_, other.elements_, (maximumRows_ + numberPivots_) * maximumRows_ * sizeof(CoinFactorizationDouble));
380 workArea_ = new CoinFactorizationDouble[maximumRows_];
381 } else {
382 elements_ = NULL;
383 pivotRow_ = NULL;
384 workArea_ = NULL;
385 }
386
387 keepSize_ = other.keepSize_;
388
389 LrowSize_ = other.LrowSize_;
390 LrowCap_ = other.LrowCap_;
391
392 LcolSize_ = other.LcolSize_;
393 LcolCap_ = other.LcolCap_;
394
395 UrowMaxCap_ = other.UrowMaxCap_;
396 UrowEnd_ = other.UrowEnd_;
397 firstRowInU_ = other.firstRowInU_;
398 lastRowInU_ = other.lastRowInU_;
399
400 firstColInU_ = other.firstColInU_;
401 lastColInU_ = other.lastColInU_;
402 UcolMaxCap_ = other.UcolMaxCap_;
403 UcolEnd_ = other.UcolEnd_;
404
405 EtaSize_ = other.EtaSize_;
406 lastEtaRow_ = other.lastEtaRow_;
407 maxEtaRows_ = other.maxEtaRows_;
408 EtaMaxCap_ = other.EtaMaxCap_;
409
410 minIncrease_ = other.minIncrease_;
411 updateTol_ = other.updateTol_;
412
413 if (other.denseVector_) {
414 denseVector_ = new double[maximumRows_];
415 memcpy(denseVector_, other.denseVector_, maximumRows_ * sizeof(double));
416 } else
417 denseVector_ = NULL;
418 if (other.workArea2_) {
419 workArea2_ = new double[maximumRows_];
420 memcpy(workArea2_, other.workArea2_, maximumRows_ * sizeof(double));
421 } else
422 workArea2_ = NULL;
423 if (other.workArea3_) {
424 workArea3_ = new double[maximumRows_];
425 memcpy(workArea3_, other.workArea3_, maximumRows_ * sizeof(double));
426 } else
427 workArea3_ = NULL;
428 if (other.vecLabels_) {
429 vecLabels_ = new int[maximumRows_];
430 memcpy(vecLabels_, other.vecLabels_, maximumRows_ * sizeof(int));
431 } else
432 vecLabels_ = NULL;
433 if (other.indVector_) {
434 indVector_ = new int[maximumRows_];
435 memcpy(indVector_, other.indVector_, maximumRows_ * sizeof(int));
436 } else
437 indVector_ = NULL;
438
439 if (other.auxVector_) {
440 auxVector_ = new double[maximumRows_];
441 memcpy(auxVector_, other.auxVector_, maximumRows_ * sizeof(double));
442 } else
443 auxVector_ = NULL;
444 if (other.auxInd_) {
445 auxInd_ = new int[maximumRows_];
446 memcpy(auxInd_, other.auxInd_, maximumRows_ * sizeof(int));
447 } else
448 auxInd_ = NULL;
449
450 if (other.vecKeep_) {
451 vecKeep_ = new double[maximumRows_];
452 memcpy(vecKeep_, other.vecKeep_, maximumRows_ * sizeof(double));
453 } else
454 vecKeep_ = NULL;
455 if (other.indKeep_) {
456 indKeep_ = new int[maximumRows_];
457 memcpy(indKeep_, other.indKeep_, maximumRows_ * sizeof(int));
458 } else
459 indKeep_ = NULL;
460 if (other.LrowStarts_) {
461 LrowStarts_ = new int[maximumRows_];
462 memcpy(LrowStarts_, other.LrowStarts_, maximumRows_ * sizeof(int));
463 } else
464 LrowStarts_ = NULL;
465 if (other.LrowLengths_) {
466 LrowLengths_ = new int[maximumRows_];
467 memcpy(LrowLengths_, other.LrowLengths_, maximumRows_ * sizeof(int));
468 } else
469 LrowLengths_ = NULL;
470 if (other.Lrows_) {
471 Lrows_ = new double[other.LrowCap_];
472 memcpy(Lrows_, other.Lrows_, other.LrowCap_ * sizeof(double));
473 } else
474 Lrows_ = NULL;
475 if (other.LrowInd_) {
476 LrowInd_ = new int[other.LrowCap_];
477 memcpy(LrowInd_, other.LrowInd_, other.LrowCap_ * sizeof(int));
478 } else
479 LrowInd_ = NULL;
480
481 if (other.LcolStarts_) {
482 LcolStarts_ = new int[maximumRows_];
483 memcpy(LcolStarts_, other.LcolStarts_, maximumRows_ * sizeof(int));
484 } else
485 LcolStarts_ = NULL;
486 if (other.LcolLengths_) {
487 LcolLengths_ = new int[maximumRows_];
488 memcpy(LcolLengths_, other.LcolLengths_, maximumRows_ * sizeof(int));
489 } else
490 LcolLengths_ = NULL;
491 if (other.Lcolumns_) {
492 Lcolumns_ = new double[other.LcolCap_];
493 memcpy(Lcolumns_, other.Lcolumns_, other.LcolCap_ * sizeof(double));
494 } else
495 Lcolumns_ = NULL;
496 if (other.LcolInd_) {
497 LcolInd_ = new int[other.LcolCap_];
498 memcpy(LcolInd_, other.LcolInd_, other.LcolCap_ * sizeof(int));
499 } else
500 LcolInd_ = NULL;
501
502 if (other.UrowStarts_) {
503 UrowStarts_ = new int[maximumRows_];
504 memcpy(UrowStarts_, other.UrowStarts_, maximumRows_ * sizeof(int));
505 } else
506 UrowStarts_ = NULL;
507 if (other.UrowLengths_) {
508 UrowLengths_ = new int[maximumRows_];
509 memcpy(UrowLengths_, other.UrowLengths_, maximumRows_ * sizeof(int));
510 } else
511 UrowLengths_ = NULL;
512 #ifdef COIN_SIMP_CAPACITY
513 if (other.UrowCapacities_) {
514 UrowCapacities_ = new int[maximumRows_];
515 memcpy(UrowCapacities_, other.UrowCapacities_, maximumRows_ * sizeof(int));
516 } else
517 UrowCapacities_ = NULL;
518 #endif
519 if (other.Urows_) {
520 Urows_ = new double[other.UrowMaxCap_];
521 memcpy(Urows_, other.Urows_, other.UrowMaxCap_ * sizeof(double));
522 } else
523 Urows_ = NULL;
524 if (other.UrowInd_) {
525 UrowInd_ = new int[other.UrowMaxCap_];
526 memcpy(UrowInd_, other.UrowInd_, other.UrowMaxCap_ * sizeof(int));
527 } else
528 UrowInd_ = NULL;
529
530 if (other.prevRowInU_) {
531 prevRowInU_ = new int[maximumRows_];
532 memcpy(prevRowInU_, other.prevRowInU_, maximumRows_ * sizeof(int));
533 } else
534 prevRowInU_ = NULL;
535 if (other.nextRowInU_) {
536 nextRowInU_ = new int[maximumRows_];
537 memcpy(nextRowInU_, other.nextRowInU_, maximumRows_ * sizeof(int));
538 } else
539 nextRowInU_ = NULL;
540
541 if (other.UcolStarts_) {
542 UcolStarts_ = new int[maximumRows_];
543 memcpy(UcolStarts_, other.UcolStarts_, maximumRows_ * sizeof(int));
544 } else
545 UcolStarts_ = NULL;
546 if (other.UcolLengths_) {
547 UcolLengths_ = new int[maximumRows_];
548 memcpy(UcolLengths_, other.UcolLengths_, maximumRows_ * sizeof(int));
549 } else
550 UcolLengths_ = NULL;
551 #ifdef COIN_SIMP_CAPACITY
552 if (other.UcolCapacities_) {
553 UcolCapacities_ = new int[maximumRows_];
554 memcpy(UcolCapacities_, other.UcolCapacities_, maximumRows_ * sizeof(int));
555 } else
556 UcolCapacities_ = NULL;
557 #endif
558 if (other.Ucolumns_) {
559 Ucolumns_ = new double[other.UcolMaxCap_];
560 memcpy(Ucolumns_, other.Ucolumns_, other.UcolMaxCap_ * sizeof(double));
561 } else
562 Ucolumns_ = NULL;
563 if (other.UcolInd_) {
564 UcolInd_ = new int[other.UcolMaxCap_];
565 memcpy(UcolInd_, other.UcolInd_, other.UcolMaxCap_ * sizeof(int));
566 } else
567 UcolInd_ = NULL;
568 if (other.prevColInU_) {
569 prevColInU_ = new int[maximumRows_];
570 memcpy(prevColInU_, other.prevColInU_, maximumRows_ * sizeof(int));
571 } else
572 prevColInU_ = NULL;
573 if (other.nextColInU_) {
574 nextColInU_ = new int[maximumRows_];
575 memcpy(nextColInU_, other.nextColInU_, maximumRows_ * sizeof(int));
576 } else
577 nextColInU_ = NULL;
578 if (other.colSlack_) {
579 colSlack_ = new int[maximumRows_];
580 memcpy(colSlack_, other.colSlack_, maximumRows_ * sizeof(int));
581 }
582
583 if (other.invOfPivots_) {
584 invOfPivots_ = new double[maximumRows_];
585 memcpy(invOfPivots_, other.invOfPivots_, maximumRows_ * sizeof(double));
586 } else
587 invOfPivots_ = NULL;
588
589 if (other.colOfU_) {
590 colOfU_ = new int[maximumRows_];
591 memcpy(colOfU_, other.colOfU_, maximumRows_ * sizeof(int));
592 } else
593 colOfU_ = NULL;
594 if (other.colPosition_) {
595 colPosition_ = new int[maximumRows_];
596 memcpy(colPosition_, other.colPosition_, maximumRows_ * sizeof(int));
597 } else
598 colPosition_ = NULL;
599 if (other.rowOfU_) {
600 rowOfU_ = new int[maximumRows_];
601 memcpy(rowOfU_, other.rowOfU_, maximumRows_ * sizeof(int));
602 } else
603 rowOfU_ = NULL;
604 if (other.rowPosition_) {
605 rowPosition_ = new int[maximumRows_];
606 memcpy(rowPosition_, other.rowPosition_, maximumRows_ * sizeof(int));
607 } else
608 rowPosition_ = NULL;
609 if (other.secRowOfU_) {
610 secRowOfU_ = new int[maximumRows_];
611 memcpy(secRowOfU_, other.secRowOfU_, maximumRows_ * sizeof(int));
612 } else
613 secRowOfU_ = NULL;
614 if (other.secRowPosition_) {
615 secRowPosition_ = new int[maximumRows_];
616 memcpy(secRowPosition_, other.secRowPosition_, maximumRows_ * sizeof(int));
617 } else
618 secRowPosition_ = NULL;
619
620 if (other.EtaPosition_) {
621 EtaPosition_ = new int[other.maxEtaRows_];
622 memcpy(EtaPosition_, other.EtaPosition_, other.maxEtaRows_ * sizeof(int));
623 } else
624 EtaPosition_ = NULL;
625 if (other.EtaStarts_) {
626 EtaStarts_ = new int[other.maxEtaRows_];
627 memcpy(EtaStarts_, other.EtaStarts_, other.maxEtaRows_ * sizeof(int));
628 } else
629 EtaStarts_ = NULL;
630 if (other.EtaLengths_) {
631 EtaLengths_ = new int[other.maxEtaRows_];
632 memcpy(EtaLengths_, other.EtaLengths_, other.maxEtaRows_ * sizeof(int));
633 } else
634 EtaLengths_ = NULL;
635 if (other.EtaInd_) {
636 EtaInd_ = new int[other.EtaMaxCap_];
637 memcpy(EtaInd_, other.EtaInd_, other.EtaMaxCap_ * sizeof(int));
638 } else
639 EtaInd_ = NULL;
640 if (other.Eta_) {
641 Eta_ = new double[other.EtaMaxCap_];
642 memcpy(Eta_, other.Eta_, other.EtaMaxCap_ * sizeof(double));
643 } else
644 Eta_ = NULL;
645
646 doSuhlHeuristic_ = other.doSuhlHeuristic_;
647 maxU_ = other.maxU_;
648 maxGrowth_ = other.maxGrowth_;
649 maxA_ = other.maxA_;
650 pivotCandLimit_ = other.pivotCandLimit_;
651 }
652
653 // getAreas. Gets space for a factorization
654 //called by constructors
getAreas(int numberOfRows,int numberOfColumns,int,int)655 void CoinSimpFactorization::getAreas(int numberOfRows,
656 int numberOfColumns,
657 int,
658 int)
659 {
660
661 numberRows_ = numberOfRows;
662 numberColumns_ = numberOfColumns;
663 int size = numberRows_ * (numberRows_ + CoinMax(maximumPivots_, (numberRows_ + 1) >> 1));
664 if (size > maximumSpace_) {
665 delete[] elements_;
666 elements_ = new CoinFactorizationDouble[size];
667 maximumSpace_ = size;
668 }
669 if (numberRows_ > maximumRows_) {
670 maximumRows_ = numberRows_;
671 delete[] pivotRow_;
672 delete[] workArea_;
673 pivotRow_ = new int[2 * maximumRows_ + maximumPivots_];
674 workArea_ = new CoinFactorizationDouble[maximumRows_];
675 allocateSomeArrays();
676 }
677 }
678
679 // preProcess.
preProcess()680 void CoinSimpFactorization::preProcess()
681 {
682 int put = numberRows_ * numberRows_;
683 int *indexRow = reinterpret_cast< int * >(elements_ + put);
684 int *starts = reinterpret_cast< int * >(pivotRow_);
685 initialSomeNumbers();
686
687 // compute sizes for Urows_ and Ucolumns_
688 //for ( int row=0; row < numberRows_; ++row )
689 //UrowLengths_[row]=0;
690 int k = 0;
691 for (int column = 0; column < numberColumns_; ++column) {
692 UcolStarts_[column] = k;
693 //for (int j=starts[column];j<starts[column+1];j++) {
694 // int iRow = indexRow[j];
695 // ++UrowLengths_[iRow];
696 // }
697 UcolLengths_[column] = starts[column + 1] - starts[column];
698 #ifdef COIN_SIMP_CAPACITY
699 UcolCapacities_[column] = numberRows_;
700 #endif
701 //k+=UcolLengths_[column]+minIncrease_;
702 k += numberRows_;
703 }
704
705 // create space for Urows_
706 k = 0;
707 for (int row = 0; row < numberRows_; ++row) {
708 prevRowInU_[row] = row - 1;
709 nextRowInU_[row] = row + 1;
710 UrowStarts_[row] = k;
711 //k+=UrowLengths_[row]+minIncrease_;
712 k += numberRows_;
713 UrowLengths_[row] = 0;
714 #ifdef COIN_SIMP_CAPACITY
715 UrowCapacities_[row] = numberRows_;
716 #endif
717 }
718 UrowEnd_ = k;
719 nextRowInU_[numberRows_ - 1] = -1;
720 firstRowInU_ = 0;
721 lastRowInU_ = numberRows_ - 1;
722 maxA_ = -1.0;
723 // build Ucolumns_ and Urows_
724 int colBeg, colEnd;
725 for (int column = 0; column < numberColumns_; ++column) {
726 prevColInU_[column] = column - 1;
727 nextColInU_[column] = column + 1;
728 k = 0;
729 colBeg = starts[column];
730 colEnd = starts[column + 1];
731 // identify slacks
732 if (colEnd == colBeg + 1 && elements_[colBeg] == slackValue_)
733 colSlack_[column] = 1;
734 else
735 colSlack_[column] = 0;
736 //
737 for (int j = colBeg; j < colEnd; j++) {
738 // Ucolumns_
739 int iRow = indexRow[j];
740 UcolInd_[UcolStarts_[column] + k] = iRow;
741 ++k;
742 // Urow_
743 int ind = UrowStarts_[iRow] + UrowLengths_[iRow];
744 UrowInd_[ind] = column;
745 Urows_[ind] = elements_[j];
746 //maxA_=CoinMax( maxA_, fabs(Urows_[ind]) );
747 ++UrowLengths_[iRow];
748 }
749 }
750 nextColInU_[numberColumns_ - 1] = -1;
751 firstColInU_ = 0;
752 lastColInU_ = numberColumns_ - 1;
753
754 // Initialize L
755 LcolSize_ = 0;
756 //LcolCap_=numberRows_*minIncrease_;
757 memset(LrowStarts_, -1, numberRows_ * sizeof(int));
758 memset(LrowLengths_, 0, numberRows_ * sizeof(int));
759 memset(LcolStarts_, -1, numberRows_ * sizeof(int));
760 memset(LcolLengths_, 0, numberRows_ * sizeof(int));
761
762 // initialize permutations
763 for (int i = 0; i < numberRows_; ++i) {
764 rowOfU_[i] = i;
765 rowPosition_[i] = i;
766 }
767 for (int i = 0; i < numberColumns_; ++i) {
768 colOfU_[i] = i;
769 colPosition_[i] = i;
770 }
771 //
772
773 doSuhlHeuristic_ = true;
774 }
775
factorize(int numberOfRows,int numberOfColumns,const int colStarts[],const int indicesRow[],const double elements[])776 void CoinSimpFactorization::factorize(int numberOfRows,
777 int numberOfColumns,
778 const int colStarts[],
779 const int indicesRow[],
780 const double elements[])
781 {
782 int maximumL = 0;
783 int maximumU = 0;
784 getAreas(numberOfRows, numberOfColumns, maximumL, maximumU);
785
786 int put = numberRows_ * numberRows_;
787 int *indexRow = reinterpret_cast< int * >(elements_ + put);
788 int *starts = reinterpret_cast< int * >(pivotRow_);
789 for (int column = 0; column <= numberColumns_; ++column) {
790 starts[column] = colStarts[column];
791 }
792 const int limit = colStarts[numberColumns_];
793 for (int i = 0; i < limit; ++i) {
794 indexRow[i] = indicesRow[i];
795 elements_[i] = elements[i];
796 }
797
798 preProcess();
799 factor();
800 }
801
802 //Does factorization
factor()803 int CoinSimpFactorization::factor()
804 {
805 numberPivots_ = 0;
806 status_ = 0;
807
808 FactorPointers pointers(numberRows_, numberColumns_, UrowLengths_, UcolLengths_);
809 int rc = mainLoopFactor(pointers);
810 // rc=0 success
811 if (rc != 0) { // failure
812 status_ = -1;
813 //return status_; // failure
814 }
815 //if ( rc == -3 ) { // numerical instability
816 // status_ = -1;
817 // return status_;
818 //}
819
820 //copyLbyRows();
821 copyUbyColumns();
822 copyRowPermutations();
823 firstNumberSlacks_ = numberSlacks_;
824 // row permutations
825 if (status_ == -1 || numberColumns_ < numberRows_) {
826 for (int j = 0; j < numberRows_; j++)
827 pivotRow_[j + numberRows_] = rowOfU_[j];
828 for (int j = 0; j < numberRows_; j++) {
829 int k = pivotRow_[j + numberRows_];
830 pivotRow_[k] = j;
831 }
832 } else // no permutations
833 for (int j = 0; j < numberRows_; j++) {
834 pivotRow_[j] = j;
835 pivotRow_[j + numberRows_] = j;
836 }
837
838 return status_;
839 }
840 //
841
842 // Makes a non-singular basis by replacing variables
makeNonSingular(int * sequence,int numberColumns)843 void CoinSimpFactorization::makeNonSingular(int *sequence, int numberColumns)
844 {
845 // Replace bad ones by correct slack
846 int *workArea = reinterpret_cast< int * >(workArea_);
847 int i;
848 for (i = 0; i < numberRows_; i++)
849 workArea[i] = -1;
850 for (i = 0; i < numberGoodU_; i++) {
851 int iOriginal = pivotRow_[i + numberRows_];
852 workArea[iOriginal] = i;
853 //workArea[i]=iOriginal;
854 }
855 int lastRow = -1;
856 for (i = 0; i < numberRows_; i++) {
857 if (workArea[i] == -1) {
858 lastRow = i;
859 break;
860 }
861 }
862 assert(lastRow >= 0);
863 for (i = numberGoodU_; i < numberRows_; i++) {
864 assert(lastRow < numberRows_);
865 // Put slack in basis
866 sequence[i] = lastRow + numberColumns;
867 lastRow++;
868 for (; lastRow < numberRows_; lastRow++) {
869 if (workArea[lastRow] == -1)
870 break;
871 }
872 }
873 }
874 // Does post processing on valid factorization - putting variables on correct rows
postProcess(const int * sequence,int * pivotVariable)875 void CoinSimpFactorization::postProcess(const int *sequence, int *pivotVariable)
876 {
877 for (int i = 0; i < numberRows_; i++) {
878 int k = sequence[i];
879 pivotVariable[pivotRow_[i + numberRows_]] = k;
880 }
881 }
882 /* Replaces one Column to basis,
883 returns 0=OK, 1=Probably OK, 2=singular, 3=no room
884 If checkBeforeModifying is true will do all accuracy checks
885 before modifying factorization. Whether to set this depends on
886 speed considerations. You could just do this on first iteration
887 after factorization and thereafter re-factorize
888 partial update already in U */
replaceColumn(CoinIndexedVector *,int pivotRow,double pivotCheck,bool,double)889 int CoinSimpFactorization::replaceColumn(CoinIndexedVector *,
890 int pivotRow,
891 double pivotCheck,
892 bool,
893 double)
894 {
895 if (numberPivots_ == maximumPivots_)
896 return 3;
897
898 double pivotValue = pivotCheck;
899 if (fabs(pivotValue) < zeroTolerance_)
900 return 2;
901 int realPivotRow = pivotRow_[pivotRow];
902
903 LUupdate(pivotRow);
904
905 pivotRow_[2 * numberRows_ + numberPivots_] = realPivotRow;
906 numberPivots_++;
907
908 return 0;
909 }
updateColumn(CoinIndexedVector * regionSparse,CoinIndexedVector * regionSparse2,bool noPermute) const910 int CoinSimpFactorization::updateColumn(CoinIndexedVector *regionSparse,
911 CoinIndexedVector *regionSparse2,
912 bool noPermute) const
913 {
914 return upColumn(regionSparse, regionSparse2, noPermute, false);
915 }
updateColumnFT(CoinIndexedVector * regionSparse,CoinIndexedVector * regionSparse2,bool noPermute)916 int CoinSimpFactorization::updateColumnFT(CoinIndexedVector *regionSparse,
917 CoinIndexedVector *regionSparse2,
918 bool noPermute)
919 {
920
921 int rc = upColumn(regionSparse, regionSparse2, noPermute, true);
922 return rc;
923 }
924
upColumn(CoinIndexedVector * regionSparse,CoinIndexedVector * regionSparse2,bool,bool save) const925 int CoinSimpFactorization::upColumn(CoinIndexedVector *regionSparse,
926 CoinIndexedVector *regionSparse2,
927 bool, bool save) const
928 {
929 assert(numberRows_ == numberColumns_);
930 double *region2 = regionSparse2->denseVector();
931 int *regionIndex = regionSparse2->getIndices();
932 int numberNonZero = regionSparse2->getNumElements();
933 double *region = regionSparse->denseVector();
934 if (!regionSparse2->packedMode()) {
935 region = regionSparse2->denseVector();
936 } else { // packed mode
937 for (int j = 0; j < numberNonZero; j++) {
938 region[regionIndex[j]] = region2[j];
939 region2[j] = 0.0;
940 }
941 }
942
943 double *solution = workArea2_;
944 ftran(region, solution, save);
945
946 // get nonzeros
947 numberNonZero = 0;
948 if (!regionSparse2->packedMode()) {
949 for (int i = 0; i < numberRows_; i++) {
950 const double value = solution[i];
951 if (fabs(value) > zeroTolerance_) {
952 region[i] = value;
953 regionIndex[numberNonZero++] = i;
954 } else
955 region[i] = 0.0;
956 }
957 } else { // packed mode
958 memset(region, 0, numberRows_ * sizeof(double));
959 for (int i = 0; i < numberRows_; i++) {
960 const double value = solution[i];
961 if (fabs(value) > zeroTolerance_) {
962 region2[numberNonZero] = value;
963 regionIndex[numberNonZero++] = i;
964 }
965 }
966 }
967 regionSparse2->setNumElements(numberNonZero);
968 return 0;
969 }
970
updateTwoColumnsFT(CoinIndexedVector * regionSparse1,CoinIndexedVector * regionSparse2,CoinIndexedVector * regionSparse3,bool)971 int CoinSimpFactorization::updateTwoColumnsFT(CoinIndexedVector *regionSparse1,
972 CoinIndexedVector *regionSparse2,
973 CoinIndexedVector *regionSparse3,
974 bool)
975 {
976 assert(numberRows_ == numberColumns_);
977
978 double *region2 = regionSparse2->denseVector();
979 int *regionIndex2 = regionSparse2->getIndices();
980 int numberNonZero2 = regionSparse2->getNumElements();
981
982 double *vec1 = regionSparse1->denseVector();
983 if (!regionSparse2->packedMode()) {
984 vec1 = regionSparse2->denseVector();
985 } else { // packed mode
986 for (int j = 0; j < numberNonZero2; j++) {
987 vec1[regionIndex2[j]] = region2[j];
988 region2[j] = 0.0;
989 }
990 }
991 //
992 double *region3 = regionSparse3->denseVector();
993 int *regionIndex3 = regionSparse3->getIndices();
994 int numberNonZero3 = regionSparse3->getNumElements();
995 double *vec2 = auxVector_;
996 if (!regionSparse3->packedMode()) {
997 vec2 = regionSparse3->denseVector();
998 } else { // packed mode
999 memset(vec2, 0, numberRows_ * sizeof(double));
1000 for (int j = 0; j < numberNonZero3; j++) {
1001 vec2[regionIndex3[j]] = region3[j];
1002 region3[j] = 0.0;
1003 }
1004 }
1005
1006 double *solution1 = workArea2_;
1007 double *solution2 = workArea3_;
1008 ftran2(vec1, solution1, vec2, solution2);
1009
1010 // get nonzeros
1011 numberNonZero2 = 0;
1012 if (!regionSparse2->packedMode()) {
1013 double value;
1014 for (int i = 0; i < numberRows_; i++) {
1015 value = solution1[i];
1016 if (fabs(value) > zeroTolerance_) {
1017 vec1[i] = value;
1018 regionIndex2[numberNonZero2++] = i;
1019 } else
1020 vec1[i] = 0.0;
1021 }
1022 } else { // packed mode
1023 double value;
1024 for (int i = 0; i < numberRows_; i++) {
1025 vec1[i] = 0.0;
1026 value = solution1[i];
1027 if (fabs(value) > zeroTolerance_) {
1028 region2[numberNonZero2] = value;
1029 regionIndex2[numberNonZero2++] = i;
1030 }
1031 }
1032 }
1033 regionSparse2->setNumElements(numberNonZero2);
1034 //
1035 numberNonZero3 = 0;
1036 if (!regionSparse3->packedMode()) {
1037 double value;
1038 for (int i = 0; i < numberRows_; i++) {
1039 value = solution2[i];
1040 if (fabs(value) > zeroTolerance_) {
1041 vec2[i] = value;
1042 regionIndex3[numberNonZero3++] = i;
1043 } else
1044 vec2[i] = 0.0;
1045 }
1046 } else { // packed mode
1047 double value;
1048 for (int i = 0; i < numberRows_; i++) {
1049 value = solution2[i];
1050 if (fabs(value) > zeroTolerance_) {
1051 region3[numberNonZero3] = value;
1052 regionIndex3[numberNonZero3++] = i;
1053 }
1054 }
1055 }
1056 regionSparse3->setNumElements(numberNonZero3);
1057 return 0;
1058 }
1059
updateColumnTranspose(CoinIndexedVector * regionSparse,CoinIndexedVector * regionSparse2) const1060 int CoinSimpFactorization::updateColumnTranspose(CoinIndexedVector *regionSparse,
1061 CoinIndexedVector *regionSparse2) const
1062 {
1063 upColumnTranspose(regionSparse, regionSparse2);
1064 return 0;
1065 }
1066
upColumnTranspose(CoinIndexedVector * regionSparse,CoinIndexedVector * regionSparse2) const1067 int CoinSimpFactorization::upColumnTranspose(CoinIndexedVector *regionSparse,
1068 CoinIndexedVector *regionSparse2) const
1069 {
1070 assert(numberRows_ == numberColumns_);
1071 double *region2 = regionSparse2->denseVector();
1072 int *regionIndex = regionSparse2->getIndices();
1073 int numberNonZero = regionSparse2->getNumElements();
1074 double *region = regionSparse->denseVector();
1075 if (!regionSparse2->packedMode()) {
1076 region = regionSparse2->denseVector();
1077 } else { // packed
1078 for (int j = 0; j < numberNonZero; j++) {
1079 region[regionIndex[j]] = region2[j];
1080 region2[j] = 0.0;
1081 }
1082 }
1083 double *solution = workArea2_;
1084 btran(region, solution);
1085 // get nonzeros
1086 numberNonZero = 0;
1087 if (!regionSparse2->packedMode()) {
1088 double value;
1089 for (int i = 0; i < numberRows_; i++) {
1090 value = solution[i];
1091 if (fabs(value) > zeroTolerance_) {
1092 region[i] = value;
1093 regionIndex[numberNonZero++] = i;
1094 } else
1095 region[i] = 0.0;
1096 }
1097 } else { // packed mode
1098 memset(region, 0, numberRows_ * sizeof(double));
1099 for (int i = 0; i < numberRows_; i++) {
1100 const double value = solution[i];
1101 if (fabs(value) > zeroTolerance_) {
1102 region2[numberNonZero] = value;
1103 regionIndex[numberNonZero++] = i;
1104 }
1105 }
1106 }
1107 regionSparse2->setNumElements(numberNonZero);
1108 return 0;
1109 }
1110
mainLoopFactor(FactorPointers & pointers)1111 int CoinSimpFactorization::mainLoopFactor(FactorPointers &pointers)
1112 {
1113 numberGoodU_ = 0;
1114 numberSlacks_ = 0;
1115 bool ifSlack = true;
1116 for (int i = 0; i < numberColumns_; ++i) {
1117 int r, s;
1118 //s=i;
1119 if (findPivot(pointers, r, s, ifSlack)) {
1120 return -1;
1121 }
1122 if (ifSlack)
1123 ++numberSlacks_;
1124 const int rowPos = rowPosition_[r];
1125 const int colPos = colPosition_[s];
1126 assert(i <= rowPos && rowPos < numberRows_);
1127 assert(i <= colPos && colPos < numberColumns_);
1128 // permute columns
1129 int j = colOfU_[i];
1130 colOfU_[i] = colOfU_[colPos];
1131 colOfU_[colPos] = j;
1132 colPosition_[colOfU_[i]] = i;
1133 colPosition_[colOfU_[colPos]] = colPos;
1134 // permute rows
1135 j = rowOfU_[i];
1136 rowOfU_[i] = rowOfU_[rowPos];
1137 rowOfU_[rowPos] = j;
1138 rowPosition_[rowOfU_[i]] = i;
1139 rowPosition_[rowOfU_[rowPos]] = rowPos;
1140 GaussEliminate(pointers, r, s);
1141 //if ( maxU_ > maxGrowth_ * maxA_ ){
1142 // return -3;
1143 //}
1144 ++numberGoodU_;
1145 }
1146 return 0;
1147 }
1148 /// find a pivot in the active part of U
findPivot(FactorPointers & pointers,int & r,int & s,bool & ifSlack)1149 int CoinSimpFactorization::findPivot(FactorPointers &pointers, int &r,
1150 int &s, bool &ifSlack)
1151 {
1152 int *firstRowKnonzeros = pointers.firstRowKnonzeros;
1153 int *nextRow = pointers.nextRow;
1154 int *firstColKnonzeros = pointers.firstColKnonzeros;
1155 int *prevColumn = pointers.prevColumn;
1156 int *nextColumn = pointers.nextColumn;
1157 r = s = -1;
1158 int numCandidates = 0;
1159 double bestMarkowitzCount = COIN_DBL_MAX;
1160 // if there is a column with one element choose it as pivot
1161 int column = firstColKnonzeros[1];
1162 if (column != -1) {
1163 assert(UcolLengths_[column] == 1);
1164 r = UcolInd_[UcolStarts_[column]];
1165 s = column;
1166 if (!colSlack_[column])
1167 ifSlack = false;
1168 return 0;
1169 }
1170 // from now on no more slacks
1171 ifSlack = false;
1172 // if there is a row with one element choose it
1173 int row = firstRowKnonzeros[1];
1174 if (row != -1) {
1175 assert(UrowLengths_[row] == 1);
1176 s = UrowInd_[UrowStarts_[row]];
1177 r = row;
1178 return 0;
1179 }
1180 // consider other rows and columns
1181 for (int length = 2; length <= numberRows_; ++length) {
1182 int nextCol = -1;
1183 for (column = firstColKnonzeros[length]; column != -1; column = nextCol) {
1184 nextCol = nextColumn[column];
1185 int minRow, minRowLength;
1186 int rc = findShortRow(column, length, minRow, minRowLength, pointers);
1187 if (rc == 0) {
1188 r = minRow;
1189 s = column;
1190 return 0;
1191 }
1192 if (minRow != -1) {
1193 ++numCandidates;
1194 double MarkowitzCount = static_cast< double >(minRowLength - 1) * (length - 1);
1195 if (MarkowitzCount < bestMarkowitzCount) {
1196 r = minRow;
1197 s = column;
1198 bestMarkowitzCount = MarkowitzCount;
1199 }
1200 if (numCandidates == pivotCandLimit_)
1201 return 0;
1202 } else {
1203 if (doSuhlHeuristic_) {
1204 // this column did not give a candidate, it will be
1205 // removed until it becomes a singleton
1206 removeColumnFromActSet(column, pointers);
1207 prevColumn[column] = nextColumn[column] = column;
1208 }
1209 }
1210 } // end for ( column= ....
1211 // now rows
1212 for (row = firstRowKnonzeros[length]; row != -1; row = nextRow[row]) {
1213 int minCol, minColLength;
1214 int rc = findShortColumn(row, length, minCol, minColLength, pointers);
1215 if (rc == 0) {
1216 r = row;
1217 s = minCol;
1218 return 0;
1219 }
1220 if (minCol != -1) {
1221 ++numCandidates;
1222 double MarkowitzCount = static_cast< double >(minColLength - 1) * (length - 1);
1223 if (MarkowitzCount < bestMarkowitzCount) {
1224 r = row;
1225 s = minCol;
1226 bestMarkowitzCount = MarkowitzCount;
1227 }
1228 if (numCandidates == pivotCandLimit_)
1229 return 0;
1230 }
1231 //else abort();
1232 } // end for ( row= ...
1233 } // end for ( int length= ...
1234 if (r == -1 || s == -1)
1235 return 1;
1236 else
1237 return 0;
1238 }
1239 //
findPivotShCol(FactorPointers & pointers,int & r,int & s)1240 int CoinSimpFactorization::findPivotShCol(FactorPointers &pointers, int &r, int &s)
1241 {
1242 int *firstColKnonzeros = pointers.firstColKnonzeros;
1243 r = s = -1;
1244 // if there is a column with one element choose it as pivot
1245 int column = firstColKnonzeros[1];
1246 if (column != -1) {
1247 assert(UcolLengths_[column] == 1);
1248 r = UcolInd_[UcolStarts_[column]];
1249 s = column;
1250 return 0;
1251 }
1252 // consider other columns
1253 for (int length = 2; length <= numberRows_; ++length) {
1254 column = firstColKnonzeros[length];
1255 if (column != -1)
1256 break;
1257 }
1258 if (column == -1)
1259 return 1;
1260 // find largest element
1261 const int colBeg = UcolStarts_[column];
1262 const int colEnd = colBeg + UcolLengths_[column];
1263 double largest = 0.0;
1264 int rowLargest = -1;
1265 for (int j = colBeg; j < colEnd; ++j) {
1266 const int row = UcolInd_[j];
1267 const int columnIndx = findInRow(row, column);
1268 assert(columnIndx != -1);
1269 double coeff = fabs(Urows_[columnIndx]);
1270 if (coeff < largest)
1271 continue;
1272 largest = coeff;
1273 rowLargest = row;
1274 }
1275 assert(rowLargest != -1);
1276 s = column;
1277 r = rowLargest;
1278 return 0;
1279 }
1280
findPivotSimp(FactorPointers &,int & r,int & s)1281 int CoinSimpFactorization::findPivotSimp(FactorPointers &, int &r, int &s)
1282 {
1283 r = -1;
1284 int column = s;
1285 const int colBeg = UcolStarts_[column];
1286 const int colEnd = colBeg + UcolLengths_[column];
1287 double largest = 0.0;
1288 int rowLargest = -1;
1289 for (int j = colBeg; j < colEnd; ++j) {
1290 const int row = UcolInd_[j];
1291 const int columnIndx = findInRow(row, column);
1292 assert(columnIndx != -1);
1293 double coeff = fabs(Urows_[columnIndx]);
1294 if (coeff < largest)
1295 continue;
1296 largest = coeff;
1297 rowLargest = row;
1298 }
1299 if (rowLargest != -1) {
1300 r = rowLargest;
1301 return 0;
1302 } else
1303 return 1;
1304 }
1305
findShortRow(const int column,const int length,int & minRow,int & minRowLength,FactorPointers & pointers)1306 int CoinSimpFactorization::findShortRow(const int column,
1307 const int length,
1308 int &minRow,
1309 int &minRowLength,
1310 FactorPointers &pointers)
1311 {
1312 const int colBeg = UcolStarts_[column];
1313 const int colEnd = colBeg + UcolLengths_[column];
1314 minRow = -1;
1315 minRowLength = COIN_INT_MAX;
1316 for (int j = colBeg; j < colEnd; ++j) {
1317 int row = UcolInd_[j];
1318 if (UrowLengths_[row] >= minRowLength)
1319 continue;
1320 double largestInRow = findMaxInRrow(row, pointers);
1321 // find column in row
1322 int columnIndx = findInRow(row, column);
1323 assert(columnIndx != -1);
1324 double coeff = Urows_[columnIndx];
1325 if (fabs(coeff) < pivotTolerance_ * largestInRow)
1326 continue;
1327 minRow = row;
1328 minRowLength = UrowLengths_[row];
1329 if (UrowLengths_[row] <= length)
1330 return 0;
1331 }
1332 return 1;
1333 }
findShortColumn(const int row,const int length,int & minCol,int & minColLength,FactorPointers & pointers)1334 int CoinSimpFactorization::findShortColumn(const int row,
1335 const int length,
1336 int &minCol,
1337 int &minColLength,
1338 FactorPointers &pointers)
1339 {
1340 const int rowBeg = UrowStarts_[row];
1341 const int rowEnd = rowBeg + UrowLengths_[row];
1342 minCol = -1;
1343 minColLength = COIN_INT_MAX;
1344 double largestInRow = findMaxInRrow(row, pointers);
1345 for (int i = rowBeg; i < rowEnd; ++i) {
1346 int column = UrowInd_[i];
1347 if (UcolLengths_[column] >= minColLength)
1348 continue;
1349 double coeff = Urows_[i];
1350 if (fabs(coeff) < pivotTolerance_ * largestInRow)
1351 continue;
1352 minCol = column;
1353 minColLength = UcolLengths_[column];
1354 if (minColLength <= length)
1355 return 0;
1356 }
1357 return 1;
1358 }
1359 // Gaussian elimination
GaussEliminate(FactorPointers & pointers,int & pivotRow,int & pivotCol)1360 void CoinSimpFactorization::GaussEliminate(FactorPointers &pointers, int &pivotRow, int &pivotCol)
1361 {
1362 assert(pivotRow >= 0 && pivotRow < numberRows_);
1363 assert(pivotCol >= 0 && pivotCol < numberRows_);
1364 int *firstColKnonzeros = pointers.firstColKnonzeros;
1365 int *prevColumn = pointers.prevColumn;
1366 int *nextColumn = pointers.nextColumn;
1367 int *colLabels = vecLabels_;
1368 double *denseRow = denseVector_;
1369 removeRowFromActSet(pivotRow, pointers);
1370 removeColumnFromActSet(pivotCol, pointers);
1371 // find column s
1372 int indxColS = findInRow(pivotRow, pivotCol);
1373 assert(indxColS >= 0);
1374 // store the inverse of the pivot and remove it from row
1375 double invPivot = 1.0 / Urows_[indxColS];
1376 invOfPivots_[pivotRow] = invPivot;
1377 int rowBeg = UrowStarts_[pivotRow];
1378 int rowEnd = rowBeg + UrowLengths_[pivotRow];
1379 Urows_[indxColS] = Urows_[rowEnd - 1];
1380 UrowInd_[indxColS] = UrowInd_[rowEnd - 1];
1381 --UrowLengths_[pivotRow];
1382 --rowEnd;
1383 // now remove pivot from column
1384 int indxRowR = findInColumn(pivotCol, pivotRow);
1385 assert(indxRowR >= 0);
1386 const int pivColEnd = UcolStarts_[pivotCol] + UcolLengths_[pivotCol];
1387 UcolInd_[indxRowR] = UcolInd_[pivColEnd - 1];
1388 --UcolLengths_[pivotCol];
1389 // go through pivot row
1390 for (int i = rowBeg; i < rowEnd; ++i) {
1391 int column = UrowInd_[i];
1392 colLabels[column] = 1;
1393 denseRow[column] = Urows_[i];
1394 // remove this column from bucket because it will change
1395 removeColumnFromActSet(column, pointers);
1396 // remove element (pivotRow, column) from column
1397 int indxRow = findInColumn(column, pivotRow);
1398 assert(indxRow >= 0);
1399 const int colEnd = UcolStarts_[column] + UcolLengths_[column];
1400 UcolInd_[indxRow] = UcolInd_[colEnd - 1];
1401 --UcolLengths_[column];
1402 }
1403 //
1404 pivoting(pivotRow, pivotCol, invPivot, pointers);
1405 //
1406 rowBeg = UrowStarts_[pivotRow];
1407 rowEnd = rowBeg + UrowLengths_[pivotRow];
1408 for (int i = rowBeg; i < rowEnd; ++i) {
1409 int column = UrowInd_[i];
1410 // clean back these two arrays
1411 colLabels[column] = 0;
1412 denseRow[column] = 0.0;
1413 // column goes into a bucket, if Suhl' heuristic had removed it, it
1414 // can go back only if it is a singleton
1415 if (UcolLengths_[column] != 1 || prevColumn[column] != column || nextColumn[column] != column) {
1416 prevColumn[column] = -1;
1417 nextColumn[column] = firstColKnonzeros[UcolLengths_[column]];
1418 if (nextColumn[column] != -1)
1419 prevColumn[nextColumn[column]] = column;
1420 firstColKnonzeros[UcolLengths_[column]] = column;
1421 }
1422 }
1423 }
pivoting(const int pivotRow,const int pivotColumn,const double invPivot,FactorPointers & pointers)1424 void CoinSimpFactorization::pivoting(const int pivotRow,
1425 const int pivotColumn,
1426 const double invPivot,
1427 FactorPointers &pointers)
1428 {
1429 // initialize the new column of L
1430 LcolStarts_[pivotRow] = LcolSize_;
1431 // go trough pivot column
1432 const int colBeg = UcolStarts_[pivotColumn];
1433 int colEnd = colBeg + UcolLengths_[pivotColumn];
1434 for (int i = colBeg; i < colEnd; ++i) {
1435 int row = UcolInd_[i];
1436 // remove row from bucket because it will change
1437 removeRowFromActSet(row, pointers);
1438 // find pivot column
1439 int pivotColInRow = findInRow(row, pivotColumn);
1440 assert(pivotColInRow >= 0);
1441 const double multiplier = Urows_[pivotColInRow] * invPivot;
1442 // remove element (row,pivotColumn) from row
1443 const int currentRowEnd = UrowStarts_[row] + UrowLengths_[row];
1444 Urows_[pivotColInRow] = Urows_[currentRowEnd - 1];
1445 UrowInd_[pivotColInRow] = UrowInd_[currentRowEnd - 1];
1446 --UrowLengths_[row];
1447 int newNonZeros = UrowLengths_[pivotRow];
1448 updateCurrentRow(pivotRow, row, multiplier, pointers,
1449 newNonZeros);
1450 // store multiplier
1451 if (LcolSize_ == LcolCap_)
1452 increaseLsize();
1453 Lcolumns_[LcolSize_] = multiplier;
1454 LcolInd_[LcolSize_++] = row;
1455 ++LcolLengths_[pivotRow];
1456 }
1457 // remove elements of pivot column
1458 UcolLengths_[pivotColumn] = 0;
1459 // remove pivot column from Ucol_
1460 if (prevColInU_[pivotColumn] == -1)
1461 firstColInU_ = nextColInU_[pivotColumn];
1462 else {
1463 nextColInU_[prevColInU_[pivotColumn]] = nextColInU_[pivotColumn];
1464 #ifdef COIN_SIMP_CAPACITY
1465 UcolCapacities_[prevColInU_[pivotColumn]] += UcolCapacities_[pivotColumn];
1466 UcolCapacities_[pivotColumn] = 0;
1467 #endif
1468 }
1469 if (nextColInU_[pivotColumn] == -1)
1470 lastColInU_ = prevColInU_[pivotColumn];
1471 else
1472 prevColInU_[nextColInU_[pivotColumn]] = prevColInU_[pivotColumn];
1473 }
1474
updateCurrentRow(const int pivotRow,const int row,const double multiplier,FactorPointers & pointers,int & newNonZeros)1475 void CoinSimpFactorization::updateCurrentRow(const int pivotRow,
1476 const int row,
1477 const double multiplier,
1478 FactorPointers &pointers,
1479 int &newNonZeros)
1480 {
1481 double *rowMax = pointers.rowMax;
1482 int *firstRowKnonzeros = pointers.firstRowKnonzeros;
1483 int *prevRow = pointers.prevRow;
1484 int *nextRow = pointers.nextRow;
1485 int *colLabels = vecLabels_;
1486 double *denseRow = denseVector_;
1487 const int rowBeg = UrowStarts_[row];
1488 int rowEnd = rowBeg + UrowLengths_[row];
1489 // treat old nonzeros
1490 for (int i = rowBeg; i < rowEnd; ++i) {
1491 const int column = UrowInd_[i];
1492 if (colLabels[column]) {
1493 Urows_[i] -= multiplier * denseRow[column];
1494 const double absNewCoeff = fabs(Urows_[i]);
1495 colLabels[column] = 0;
1496 --newNonZeros;
1497 if (absNewCoeff < zeroTolerance_) {
1498 // remove it from row
1499 UrowInd_[i] = UrowInd_[rowEnd - 1];
1500 Urows_[i] = Urows_[rowEnd - 1];
1501 --UrowLengths_[row];
1502 --i;
1503 --rowEnd;
1504 // remove it from column
1505 int indxRow = findInColumn(column, row);
1506 assert(indxRow >= 0);
1507 const int colEnd = UcolStarts_[column] + UcolLengths_[column];
1508 UcolInd_[indxRow] = UcolInd_[colEnd - 1];
1509 --UcolLengths_[column];
1510 } else {
1511 if (maxU_ < absNewCoeff)
1512 maxU_ = absNewCoeff;
1513 }
1514 }
1515 }
1516 // now add the new nonzeros to the row
1517 #ifdef COIN_SIMP_CAPACITY
1518 if (UrowLengths_[row] + newNonZeros > UrowCapacities_[row])
1519 increaseRowSize(row, UrowLengths_[row] + newNonZeros);
1520 #endif
1521 const int pivotRowBeg = UrowStarts_[pivotRow];
1522 const int pivotRowEnd = pivotRowBeg + UrowLengths_[pivotRow];
1523 int numNew = 0;
1524 int *newCols = pointers.newCols;
1525 for (int i = pivotRowBeg; i < pivotRowEnd; ++i) {
1526 const int column = UrowInd_[i];
1527 if (colLabels[column]) {
1528 const double value = -multiplier * denseRow[column];
1529 const double absNewCoeff = fabs(value);
1530 if (absNewCoeff >= zeroTolerance_) {
1531 const int newInd = UrowStarts_[row] + UrowLengths_[row];
1532 Urows_[newInd] = value;
1533 UrowInd_[newInd] = column;
1534 ++UrowLengths_[row];
1535 newCols[numNew++] = column;
1536 if (maxU_ < absNewCoeff)
1537 maxU_ = absNewCoeff;
1538 }
1539 } else
1540 colLabels[column] = 1;
1541 }
1542 // add the new nonzeros to the columns
1543 for (int i = 0; i < numNew; ++i) {
1544 const int column = newCols[i];
1545 #ifdef COIN_SIMP_CAPACITY
1546 if (UcolLengths_[column] + 1 > UcolCapacities_[column]) {
1547 increaseColSize(column, UcolLengths_[column] + 1, false);
1548 }
1549 #endif
1550 const int newInd = UcolStarts_[column] + UcolLengths_[column];
1551 UcolInd_[newInd] = row;
1552 ++UcolLengths_[column];
1553 }
1554 // the row goes to a new bucket
1555 prevRow[row] = -1;
1556 nextRow[row] = firstRowKnonzeros[UrowLengths_[row]];
1557 if (nextRow[row] != -1)
1558 prevRow[nextRow[row]] = row;
1559 firstRowKnonzeros[UrowLengths_[row]] = row;
1560 //
1561 rowMax[row] = -1.0;
1562 }
1563 #ifdef COIN_SIMP_CAPACITY
1564
increaseRowSize(const int row,const int newSize)1565 void CoinSimpFactorization::increaseRowSize(const int row,
1566 const int newSize)
1567 {
1568 assert(newSize > UrowCapacities_[row]);
1569 const int newNumElements = newSize + minIncrease_;
1570 if (UrowMaxCap_ < UrowEnd_ + newNumElements) {
1571 enlargeUrow(UrowEnd_ + newNumElements - UrowMaxCap_);
1572 }
1573 int currentCapacity = UrowCapacities_[row];
1574 memcpy(&Urows_[UrowEnd_], &Urows_[UrowStarts_[row]],
1575 UrowLengths_[row] * sizeof(double));
1576 memcpy(&UrowInd_[UrowEnd_], &UrowInd_[UrowStarts_[row]],
1577 UrowLengths_[row] * sizeof(int));
1578 UrowStarts_[row] = UrowEnd_;
1579 UrowCapacities_[row] = newNumElements;
1580 UrowEnd_ += UrowCapacities_[row];
1581 if (firstRowInU_ == lastRowInU_)
1582 return; // only one element
1583 // remove row from list
1584 if (prevRowInU_[row] == -1)
1585 firstRowInU_ = nextRowInU_[row];
1586 else {
1587 nextRowInU_[prevRowInU_[row]] = nextRowInU_[row];
1588 UrowCapacities_[prevRowInU_[row]] += currentCapacity;
1589 }
1590 if (nextRowInU_[row] == -1)
1591 lastRowInU_ = prevRowInU_[row];
1592 else
1593 prevRowInU_[nextRowInU_[row]] = prevRowInU_[row];
1594 // add row at the end of list
1595 nextRowInU_[lastRowInU_] = row;
1596 nextRowInU_[row] = -1;
1597 prevRowInU_[row] = lastRowInU_;
1598 lastRowInU_ = row;
1599 }
1600 #endif
1601 #ifdef COIN_SIMP_CAPACITY
increaseColSize(const int column,const int newSize,const bool ifElements)1602 void CoinSimpFactorization::increaseColSize(const int column,
1603 const int newSize,
1604 const bool ifElements)
1605 {
1606 assert(newSize > UcolCapacities_[column]);
1607 const int newNumElements = newSize + minIncrease_;
1608 if (UcolMaxCap_ < UcolEnd_ + newNumElements) {
1609 enlargeUcol(UcolEnd_ + newNumElements - UcolMaxCap_,
1610 ifElements);
1611 }
1612 int currentCapacity = UcolCapacities_[column];
1613 memcpy(&UcolInd_[UcolEnd_], &UcolInd_[UcolStarts_[column]],
1614 UcolLengths_[column] * sizeof(int));
1615 if (ifElements) {
1616 memcpy(&Ucolumns_[UcolEnd_], &Ucolumns_[UcolStarts_[column]],
1617 UcolLengths_[column] * sizeof(double));
1618 }
1619 UcolStarts_[column] = UcolEnd_;
1620 UcolCapacities_[column] = newNumElements;
1621 UcolEnd_ += UcolCapacities_[column];
1622 if (firstColInU_ == lastColInU_)
1623 return; // only one column
1624 // remove from list
1625 if (prevColInU_[column] == -1)
1626 firstColInU_ = nextColInU_[column];
1627 else {
1628 nextColInU_[prevColInU_[column]] = nextColInU_[column];
1629 UcolCapacities_[prevColInU_[column]] += currentCapacity;
1630 }
1631 if (nextColInU_[column] == -1)
1632 lastColInU_ = prevColInU_[column];
1633 else
1634 prevColInU_[nextColInU_[column]] = prevColInU_[column];
1635 // add column at the end
1636 nextColInU_[lastColInU_] = column;
1637 nextColInU_[column] = -1;
1638 prevColInU_[column] = lastColInU_;
1639 lastColInU_ = column;
1640 }
1641 #endif
findMaxInRrow(const int row,FactorPointers & pointers)1642 double CoinSimpFactorization::findMaxInRrow(const int row,
1643 FactorPointers &pointers)
1644 {
1645 double *rowMax = pointers.rowMax;
1646 double largest = rowMax[row];
1647 if (largest >= 0.0)
1648 return largest;
1649 const int rowBeg = UrowStarts_[row];
1650 const int rowEnd = rowBeg + UrowLengths_[row];
1651 for (int i = rowBeg; i < rowEnd; ++i) {
1652 const double absValue = fabs(Urows_[i]);
1653 if (absValue > largest)
1654 largest = absValue;
1655 }
1656 rowMax[row] = largest;
1657 return largest;
1658 }
increaseLsize()1659 void CoinSimpFactorization::increaseLsize()
1660 {
1661 int newcap = LcolCap_ + minIncrease_;
1662
1663 double *aux = new double[newcap];
1664 memcpy(aux, Lcolumns_, LcolCap_ * sizeof(double));
1665 delete[] Lcolumns_;
1666 Lcolumns_ = aux;
1667
1668 int *iaux = new int[newcap];
1669 memcpy(iaux, LcolInd_, LcolCap_ * sizeof(int));
1670 delete[] LcolInd_;
1671 LcolInd_ = iaux;
1672
1673 LcolCap_ = newcap;
1674 }
enlargeUcol(const int numNewElements,const bool ifElements)1675 void CoinSimpFactorization::enlargeUcol(const int numNewElements, const bool ifElements)
1676 {
1677 int *iaux = new int[UcolMaxCap_ + numNewElements];
1678 memcpy(iaux, UcolInd_, UcolMaxCap_ * sizeof(int));
1679 delete[] UcolInd_;
1680 UcolInd_ = iaux;
1681
1682 if (ifElements) {
1683 double *aux = new double[UcolMaxCap_ + numNewElements];
1684 memcpy(aux, Ucolumns_, UcolMaxCap_ * sizeof(double));
1685 delete[] Ucolumns_;
1686 Ucolumns_ = aux;
1687 }
1688
1689 UcolMaxCap_ += numNewElements;
1690 }
enlargeUrow(const int numNewElements)1691 void CoinSimpFactorization::enlargeUrow(const int numNewElements)
1692 {
1693 int *iaux = new int[UrowMaxCap_ + numNewElements];
1694 memcpy(iaux, UrowInd_, UrowMaxCap_ * sizeof(int));
1695 delete[] UrowInd_;
1696 UrowInd_ = iaux;
1697
1698 double *aux = new double[UrowMaxCap_ + numNewElements];
1699 memcpy(aux, Urows_, UrowMaxCap_ * sizeof(double));
1700 delete[] Urows_;
1701 Urows_ = aux;
1702
1703 UrowMaxCap_ += numNewElements;
1704 }
1705
copyUbyColumns()1706 void CoinSimpFactorization::copyUbyColumns()
1707 {
1708 memset(UcolLengths_, 0, numberColumns_ * sizeof(int));
1709 for (int column = 0; column < numberColumns_; ++column) {
1710 prevColInU_[column] = column - 1;
1711 nextColInU_[column] = column + 1;
1712 }
1713 nextColInU_[numberColumns_ - 1] = -1;
1714 firstColInU_ = 0;
1715 lastColInU_ = numberColumns_ - 1;
1716 //int nonZeros=0;
1717 //for ( int row=0; row<numberRows_; ++row ){
1718 //const int rowBeg=UrowStarts_[row];
1719 //const int rowEnd=rowBeg+UrowLengths_[row];
1720 //for ( int j=rowBeg; j<rowEnd; ++j )
1721 // ++UcolCapacities_[UrowInd_[j]];
1722 // nonZeros+=UrowLengths_[row];
1723 // }
1724 //
1725 //memset(UcolCapacities_, numberRows_, numberColumns_ * sizeof(int));
1726 #ifdef COIN_SIMP_CAPACITY
1727 for (int i = 0; i < numberColumns_; ++i)
1728 UcolCapacities_[i] = numberRows_;
1729 #endif
1730 int k = 0;
1731 for (int column = 0; column < numberColumns_; ++column) {
1732 UcolStarts_[column] = k;
1733 //UcolCapacities_[column]+=minIncrease_;
1734 //k+=UcolCapacities_[column];
1735 k += numberRows_;
1736 }
1737 UcolEnd_ = k;
1738 // go through the rows and fill the columns, assume UcolLengths_[]=0
1739 for (int row = 0; row < numberRows_; ++row) {
1740 const int rowBeg = UrowStarts_[row];
1741 int rowEnd = rowBeg + UrowLengths_[row];
1742 for (int j = rowBeg; j < rowEnd; ++j) {
1743 // remove els close to zero
1744 while (fabs(Urows_[j]) < zeroTolerance_) {
1745 --UrowLengths_[row];
1746 --rowEnd;
1747 if (j < rowEnd) {
1748 Urows_[j] = Urows_[rowEnd];
1749 UrowInd_[j] = UrowInd_[rowEnd];
1750 } else
1751 break;
1752 }
1753 if (j == rowEnd)
1754 continue;
1755 //
1756 const int column = UrowInd_[j];
1757 const int indx = UcolStarts_[column] + UcolLengths_[column];
1758 Ucolumns_[indx] = Urows_[j];
1759 UcolInd_[indx] = row;
1760 ++UcolLengths_[column];
1761 }
1762 }
1763 }
copyLbyRows()1764 void CoinSimpFactorization::copyLbyRows()
1765 {
1766 int nonZeros = 0;
1767 memset(LrowLengths_, 0, numberRows_ * sizeof(int));
1768 for (int column = 0; column < numberRows_; ++column) {
1769 const int colBeg = LcolStarts_[column];
1770 const int colEnd = colBeg + LcolLengths_[column];
1771 for (int j = colBeg; j < colEnd; ++j)
1772 ++LrowLengths_[LcolInd_[j]];
1773 nonZeros += LcolLengths_[column];
1774 }
1775 //
1776 LrowSize_ = nonZeros;
1777 int k = 0;
1778 for (int row = 0; row < numberRows_; ++row) {
1779 LrowStarts_[row] = k;
1780 k += LrowLengths_[row];
1781 }
1782 #ifdef COIN_SIMP_CAPACITY
1783 //memset(LrowLengths_,0,numberRows_*sizeof(int));
1784 // fill the rows
1785 for (int column = 0; column < numberRows_; ++column) {
1786 const int colBeg = LcolStarts_[column];
1787 const int colEnd = colBeg + LcolLengths_[column];
1788 for (int j = colBeg; j < colEnd; ++j) {
1789 const int row = LcolInd_[j];
1790 const int indx = LrowStarts_[row]++;
1791 Lrows_[indx] = Lcolumns_[j];
1792 LrowInd_[indx] = column;
1793 }
1794 }
1795 // Put back starts
1796 k = 0;
1797 for (int row = 0; row < numberRows_; ++row) {
1798 int next = LrowStarts_[row];
1799 LrowStarts_[row] = k;
1800 k = next;
1801 }
1802 #else
1803 memset(LrowLengths_, 0, numberRows_ * sizeof(int));
1804 // fill the rows
1805 for (int column = 0; column < numberRows_; ++column) {
1806 const int colBeg = LcolStarts_[column];
1807 const int colEnd = colBeg + LcolLengths_[column];
1808 for (int j = colBeg; j < colEnd; ++j) {
1809 const int row = LcolInd_[j];
1810 const int indx = LrowStarts_[row] + LrowLengths_[row];
1811 Lrows_[indx] = Lcolumns_[j];
1812 LrowInd_[indx] = column;
1813 ++LrowLengths_[row];
1814 }
1815 }
1816 #endif
1817 }
1818
findInRow(const int row,const int column)1819 int CoinSimpFactorization::findInRow(const int row,
1820 const int column)
1821 {
1822 const int rowBeg = UrowStarts_[row];
1823 const int rowEnd = rowBeg + UrowLengths_[row];
1824 int columnIndx = -1;
1825 for (int i = rowBeg; i < rowEnd; ++i) {
1826 if (UrowInd_[i] == column) {
1827 columnIndx = i;
1828 break;
1829 }
1830 }
1831 return columnIndx;
1832 }
findInColumn(const int column,const int row)1833 int CoinSimpFactorization::findInColumn(const int column,
1834 const int row)
1835 {
1836 int indxRow = -1;
1837 const int colBeg = UcolStarts_[column];
1838 const int colEnd = colBeg + UcolLengths_[column];
1839 for (int i = colBeg; i < colEnd; ++i) {
1840 if (UcolInd_[i] == row) {
1841 indxRow = i;
1842 break;
1843 }
1844 }
1845 return indxRow;
1846 }
removeRowFromActSet(const int row,FactorPointers & pointers)1847 void CoinSimpFactorization::removeRowFromActSet(const int row,
1848 FactorPointers &pointers)
1849 {
1850 int *firstRowKnonzeros = pointers.firstRowKnonzeros;
1851 int *prevRow = pointers.prevRow;
1852 int *nextRow = pointers.nextRow;
1853 if (prevRow[row] == -1)
1854 firstRowKnonzeros[UrowLengths_[row]] = nextRow[row];
1855 else
1856 nextRow[prevRow[row]] = nextRow[row];
1857 if (nextRow[row] != -1)
1858 prevRow[nextRow[row]] = prevRow[row];
1859 }
removeColumnFromActSet(const int column,FactorPointers & pointers)1860 void CoinSimpFactorization::removeColumnFromActSet(const int column,
1861 FactorPointers &pointers)
1862 {
1863 int *firstColKnonzeros = pointers.firstColKnonzeros;
1864 int *prevColumn = pointers.prevColumn;
1865 int *nextColumn = pointers.nextColumn;
1866 if (prevColumn[column] == -1)
1867 firstColKnonzeros[UcolLengths_[column]] = nextColumn[column];
1868 else
1869 nextColumn[prevColumn[column]] = nextColumn[column];
1870 if (nextColumn[column] != -1)
1871 prevColumn[nextColumn[column]] = prevColumn[column];
1872 }
allocateSomeArrays()1873 void CoinSimpFactorization::allocateSomeArrays()
1874 {
1875 if (denseVector_)
1876 delete[] denseVector_;
1877 denseVector_ = new double[numberRows_];
1878 memset(denseVector_, 0, numberRows_ * sizeof(double));
1879 if (workArea2_)
1880 delete[] workArea2_;
1881 workArea2_ = new double[numberRows_];
1882 if (workArea3_)
1883 delete[] workArea3_;
1884 workArea3_ = new double[numberRows_];
1885
1886 if (vecLabels_)
1887 delete[] vecLabels_;
1888 vecLabels_ = new int[numberRows_];
1889 memset(vecLabels_, 0, numberRows_ * sizeof(int));
1890 if (indVector_)
1891 delete[] indVector_;
1892 indVector_ = new int[numberRows_];
1893
1894 if (auxVector_)
1895 delete[] auxVector_;
1896 auxVector_ = new double[numberRows_];
1897 if (auxInd_)
1898 delete[] auxInd_;
1899 auxInd_ = new int[numberRows_];
1900
1901 if (vecKeep_)
1902 delete[] vecKeep_;
1903 vecKeep_ = new double[numberRows_];
1904 if (indKeep_)
1905 delete[] indKeep_;
1906 indKeep_ = new int[numberRows_];
1907
1908 if (LrowStarts_)
1909 delete[] LrowStarts_;
1910 LrowStarts_ = new int[numberRows_];
1911 if (LrowLengths_)
1912 delete[] LrowLengths_;
1913 LrowLengths_ = new int[numberRows_];
1914
1915 LrowCap_ = (numberRows_ * (numberRows_ - 1)) / 2;
1916 if (Lrows_)
1917 delete[] Lrows_;
1918 Lrows_ = new double[LrowCap_];
1919 if (LrowInd_)
1920 delete[] LrowInd_;
1921 LrowInd_ = new int[LrowCap_];
1922
1923 if (LcolStarts_)
1924 delete[] LcolStarts_;
1925 LcolStarts_ = new int[numberRows_];
1926 if (LcolLengths_)
1927 delete[] LcolLengths_;
1928 LcolLengths_ = new int[numberRows_];
1929 LcolCap_ = LrowCap_;
1930 if (Lcolumns_)
1931 delete[] Lcolumns_;
1932 Lcolumns_ = new double[LcolCap_];
1933 if (LcolInd_)
1934 delete[] LcolInd_;
1935 LcolInd_ = new int[LcolCap_];
1936
1937 if (UrowStarts_)
1938 delete[] UrowStarts_;
1939 UrowStarts_ = new int[numberRows_];
1940 if (UrowLengths_)
1941 delete[] UrowLengths_;
1942 UrowLengths_ = new int[numberRows_];
1943 #ifdef COIN_SIMP_CAPACITY
1944 if (UrowCapacities_)
1945 delete[] UrowCapacities_;
1946 UrowCapacities_ = new int[numberRows_];
1947 #endif
1948
1949 minIncrease_ = 10;
1950 UrowMaxCap_ = numberRows_ * (numberRows_ + minIncrease_);
1951 if (Urows_)
1952 delete[] Urows_;
1953 Urows_ = new double[UrowMaxCap_];
1954 if (UrowInd_)
1955 delete[] UrowInd_;
1956 UrowInd_ = new int[UrowMaxCap_];
1957
1958 if (prevRowInU_)
1959 delete[] prevRowInU_;
1960 prevRowInU_ = new int[numberRows_];
1961 if (nextRowInU_)
1962 delete[] nextRowInU_;
1963 nextRowInU_ = new int[numberRows_];
1964
1965 if (UcolStarts_)
1966 delete[] UcolStarts_;
1967 UcolStarts_ = new int[numberRows_];
1968 if (UcolLengths_)
1969 delete[] UcolLengths_;
1970 UcolLengths_ = new int[numberRows_];
1971 #ifdef COIN_SIMP_CAPACITY
1972 if (UcolCapacities_)
1973 delete[] UcolCapacities_;
1974 UcolCapacities_ = new int[numberRows_];
1975 #endif
1976
1977 UcolMaxCap_ = UrowMaxCap_;
1978 if (Ucolumns_)
1979 delete[] Ucolumns_;
1980 Ucolumns_ = new double[UcolMaxCap_];
1981 if (UcolInd_)
1982 delete[] UcolInd_;
1983 UcolInd_ = new int[UcolMaxCap_];
1984
1985 if (prevColInU_)
1986 delete[] prevColInU_;
1987 prevColInU_ = new int[numberRows_];
1988 if (nextColInU_)
1989 delete[] nextColInU_;
1990 nextColInU_ = new int[numberRows_];
1991 if (colSlack_)
1992 delete[] colSlack_;
1993 colSlack_ = new int[numberRows_];
1994
1995 if (invOfPivots_)
1996 delete[] invOfPivots_;
1997 invOfPivots_ = new double[numberRows_];
1998
1999 if (colOfU_)
2000 delete[] colOfU_;
2001 colOfU_ = new int[numberRows_];
2002 if (colPosition_)
2003 delete[] colPosition_;
2004 colPosition_ = new int[numberRows_];
2005 if (rowOfU_)
2006 delete[] rowOfU_;
2007 rowOfU_ = new int[numberRows_];
2008 if (rowPosition_)
2009 delete[] rowPosition_;
2010 rowPosition_ = new int[numberRows_];
2011 if (secRowOfU_)
2012 delete[] secRowOfU_;
2013 secRowOfU_ = new int[numberRows_];
2014 if (secRowPosition_)
2015 delete[] secRowPosition_;
2016 secRowPosition_ = new int[numberRows_];
2017
2018 if (EtaPosition_)
2019 delete[] EtaPosition_;
2020 EtaPosition_ = new int[maximumPivots_];
2021 if (EtaStarts_)
2022 delete[] EtaStarts_;
2023 EtaStarts_ = new int[maximumPivots_];
2024 if (EtaLengths_)
2025 delete[] EtaLengths_;
2026 EtaLengths_ = new int[maximumPivots_];
2027 maxEtaRows_ = maximumPivots_;
2028
2029 EtaMaxCap_ = maximumPivots_ * minIncrease_;
2030 if (EtaInd_)
2031 delete[] EtaInd_;
2032 EtaInd_ = new int[EtaMaxCap_];
2033 if (Eta_)
2034 delete[] Eta_;
2035 Eta_ = new double[EtaMaxCap_];
2036 }
2037
Lxeqb(double * b) const2038 void CoinSimpFactorization::Lxeqb(double *b) const
2039 {
2040 double *rhs = b;
2041 int k, colBeg, *ind, *indEnd;
2042 double xk, *Lcol;
2043 // now solve
2044 for (int j = firstNumberSlacks_; j < numberRows_; ++j) {
2045 k = rowOfU_[j];
2046 xk = rhs[k];
2047 if (xk != 0.0) {
2048 //if ( fabs(xk)>zeroTolerance_ ) {
2049 colBeg = LcolStarts_[k];
2050 ind = LcolInd_ + colBeg;
2051 indEnd = ind + LcolLengths_[k];
2052 Lcol = Lcolumns_ + colBeg;
2053 for (; ind != indEnd; ++ind) {
2054 rhs[*ind] -= (*Lcol) * xk;
2055 ++Lcol;
2056 }
2057 }
2058 }
2059 }
2060
Lxeqb2(double * b1,double * b2) const2061 void CoinSimpFactorization::Lxeqb2(double *b1, double *b2) const
2062 {
2063 double *rhs1 = b1;
2064 double *rhs2 = b2;
2065 double x1, x2, *Lcol;
2066 int k, colBeg, *ind, *indEnd, j;
2067 // now solve
2068 for (j = firstNumberSlacks_; j < numberRows_; ++j) {
2069 k = rowOfU_[j];
2070 x1 = rhs1[k];
2071 x2 = rhs2[k];
2072 if (x1 == 0.0) {
2073 if (x2 == 0.0) {
2074 } else {
2075 colBeg = LcolStarts_[k];
2076 ind = LcolInd_ + colBeg;
2077 indEnd = ind + LcolLengths_[k];
2078 Lcol = Lcolumns_ + colBeg;
2079 for (; ind != indEnd; ++ind) {
2080 #if 0
2081 rhs2[ *ind ]-= (*Lcol) * x2;
2082 #else
2083 double value = rhs2[*ind];
2084 rhs2[*ind] = value - (*Lcol) * x2;
2085 #endif
2086 ++Lcol;
2087 }
2088 }
2089 } else {
2090 if (x2 == 0.0) {
2091 colBeg = LcolStarts_[k];
2092 ind = LcolInd_ + colBeg;
2093 indEnd = ind + LcolLengths_[k];
2094 Lcol = Lcolumns_ + colBeg;
2095 for (; ind != indEnd; ++ind) {
2096 #if 0
2097 rhs1[ *ind ]-= (*Lcol) * x1;
2098 #else
2099 double value = rhs1[*ind];
2100 rhs1[*ind] = value - (*Lcol) * x1;
2101 #endif
2102 ++Lcol;
2103 }
2104 } else {
2105 colBeg = LcolStarts_[k];
2106 ind = LcolInd_ + colBeg;
2107 indEnd = ind + LcolLengths_[k];
2108 Lcol = Lcolumns_ + colBeg;
2109 for (; ind != indEnd; ++ind) {
2110 #if 0
2111 rhs1[ *ind ]-= (*Lcol) * x1;
2112 rhs2[ *ind ]-= (*Lcol) * x2;
2113 #else
2114 double value1 = rhs1[*ind];
2115 rhs1[*ind] = value1 - (*Lcol) * x1;
2116 double value2 = rhs2[*ind];
2117 rhs2[*ind] = value2 - (*Lcol) * x2;
2118 #endif
2119 ++Lcol;
2120 }
2121 }
2122 }
2123 }
2124 }
2125
Uxeqb(double * b,double * sol) const2126 void CoinSimpFactorization::Uxeqb(double *b, double *sol) const
2127 {
2128 double *rhs = b;
2129 int row, column, colBeg, *ind, *indEnd, k;
2130 double x, *uCol;
2131 // now solve
2132 for (k = numberRows_ - 1; k >= numberSlacks_; --k) {
2133 row = secRowOfU_[k];
2134 x = rhs[row];
2135 column = colOfU_[k];
2136 if (x != 0.0) {
2137 //if ( fabs(x) > zeroTolerance_ ) {
2138 x *= invOfPivots_[row];
2139 colBeg = UcolStarts_[column];
2140 ind = UcolInd_ + colBeg;
2141 indEnd = ind + UcolLengths_[column];
2142 uCol = Ucolumns_ + colBeg;
2143 for (; ind != indEnd; ++ind) {
2144 #if 0
2145 rhs[ *ind ]-= (*uCol) * x;
2146 #else
2147 double value = rhs[*ind];
2148 rhs[*ind] = value - (*uCol) * x;
2149 #endif
2150 ++uCol;
2151 }
2152 sol[column] = x;
2153 } else
2154 sol[column] = 0.0;
2155 }
2156 for (k = numberSlacks_ - 1; k >= 0; --k) {
2157 row = secRowOfU_[k];
2158 column = colOfU_[k];
2159 sol[column] = -rhs[row];
2160 }
2161 }
2162
Uxeqb2(double * b1,double * sol1,double * b2,double * sol2) const2163 void CoinSimpFactorization::Uxeqb2(double *b1, double *sol1, double *b2, double *sol2) const
2164 {
2165 double *rhs1 = b1;
2166 double *rhs2 = b2;
2167 int row, column, colBeg, *ind, *indEnd;
2168 double x1, x2, *uCol;
2169 // now solve
2170 for (int k = numberRows_ - 1; k >= numberSlacks_; --k) {
2171 row = secRowOfU_[k];
2172 x1 = rhs1[row];
2173 x2 = rhs2[row];
2174 column = colOfU_[k];
2175 if (x1 == 0.0) {
2176 if (x2 == 0.0) {
2177 sol1[column] = 0.0;
2178 sol2[column] = 0.0;
2179 } else {
2180 x2 *= invOfPivots_[row];
2181 colBeg = UcolStarts_[column];
2182 ind = UcolInd_ + colBeg;
2183 indEnd = ind + UcolLengths_[column];
2184 uCol = Ucolumns_ + colBeg;
2185 for (; ind != indEnd; ++ind) {
2186 #if 0
2187 rhs2[ *ind ]-= (*uCol) * x2;
2188 #else
2189 double value = rhs2[*ind];
2190 rhs2[*ind] = value - (*uCol) * x2;
2191 #endif
2192 ++uCol;
2193 }
2194 sol1[column] = 0.0;
2195 sol2[column] = x2;
2196 }
2197 } else {
2198 if (x2 == 0.0) {
2199 x1 *= invOfPivots_[row];
2200 colBeg = UcolStarts_[column];
2201 ind = UcolInd_ + colBeg;
2202 indEnd = ind + UcolLengths_[column];
2203 uCol = Ucolumns_ + colBeg;
2204 for (; ind != indEnd; ++ind) {
2205 #if 0
2206 rhs1[ *ind ]-= (*uCol) * x1;
2207 #else
2208 double value = rhs1[*ind];
2209 rhs1[*ind] = value - (*uCol) * x1;
2210 #endif
2211 ++uCol;
2212 }
2213 sol1[column] = x1;
2214 sol2[column] = 0.0;
2215 } else {
2216 x1 *= invOfPivots_[row];
2217 x2 *= invOfPivots_[row];
2218 colBeg = UcolStarts_[column];
2219 ind = UcolInd_ + colBeg;
2220 indEnd = ind + UcolLengths_[column];
2221 uCol = Ucolumns_ + colBeg;
2222 for (; ind != indEnd; ++ind) {
2223 #if 0
2224 rhs1[ *ind ]-= (*uCol) * x1;
2225 rhs2[ *ind ]-= (*uCol) * x2;
2226 #else
2227 double value1 = rhs1[*ind];
2228 rhs1[*ind] = value1 - (*uCol) * x1;
2229 double value2 = rhs2[*ind];
2230 rhs2[*ind] = value2 - (*uCol) * x2;
2231 #endif
2232 ++uCol;
2233 }
2234 sol1[column] = x1;
2235 sol2[column] = x2;
2236 }
2237 }
2238 }
2239 for (int k = numberSlacks_ - 1; k >= 0; --k) {
2240 row = secRowOfU_[k];
2241 column = colOfU_[k];
2242 sol1[column] = -rhs1[row];
2243 sol2[column] = -rhs2[row];
2244 }
2245 }
2246
xLeqb(double * b) const2247 void CoinSimpFactorization::xLeqb(double *b) const
2248 {
2249 double *rhs = b;
2250 int k, *ind, *indEnd, j;
2251 int colBeg;
2252 double x, *Lcol;
2253 // find last nonzero
2254 int last;
2255 for (last = numberColumns_ - 1; last >= 0; --last) {
2256 if (rhs[rowOfU_[last]])
2257 break;
2258 }
2259 // this seems to be faster
2260 if (last >= 0) {
2261 for (j = last; j >= firstNumberSlacks_; --j) {
2262 k = rowOfU_[j];
2263 x = rhs[k];
2264 colBeg = LcolStarts_[k];
2265 ind = LcolInd_ + colBeg;
2266 indEnd = ind + LcolLengths_[k];
2267 Lcol = Lcolumns_ + colBeg;
2268 for (; ind != indEnd; ++ind) {
2269 x -= (*Lcol) * rhs[*ind];
2270 ++Lcol;
2271 }
2272 rhs[k] = x;
2273 }
2274 } // if ( last >= 0 ){
2275 }
2276
xUeqb(double * b,double * sol) const2277 void CoinSimpFactorization::xUeqb(double *b, double *sol) const
2278 {
2279 double *rhs = b;
2280 int row, col, *ind, *indEnd, k;
2281 double xr;
2282 // now solve
2283 #if 1
2284 int rowBeg;
2285 double *uRow;
2286 for (k = 0; k < numberSlacks_; ++k) {
2287 row = secRowOfU_[k];
2288 col = colOfU_[k];
2289 xr = rhs[col];
2290 if (xr != 0.0) {
2291 //if ( fabs(xr)> zeroTolerance_ ) {
2292 xr = -xr;
2293 rowBeg = UrowStarts_[row];
2294 ind = UrowInd_ + rowBeg;
2295 indEnd = ind + UrowLengths_[row];
2296 uRow = Urows_ + rowBeg;
2297 for (; ind != indEnd; ++ind) {
2298 rhs[*ind] -= (*uRow) * xr;
2299 ++uRow;
2300 }
2301 sol[row] = xr;
2302 } else
2303 sol[row] = 0.0;
2304 }
2305 for (k = numberSlacks_; k < numberRows_; ++k) {
2306 row = secRowOfU_[k];
2307 col = colOfU_[k];
2308 xr = rhs[col];
2309 if (xr != 0.0) {
2310 //if ( fabs(xr)> zeroTolerance_ ) {
2311 xr *= invOfPivots_[row];
2312 rowBeg = UrowStarts_[row];
2313 ind = UrowInd_ + rowBeg;
2314 indEnd = ind + UrowLengths_[row];
2315 uRow = Urows_ + rowBeg;
2316 for (; ind != indEnd; ++ind) {
2317 rhs[*ind] -= (*uRow) * xr;
2318 ++uRow;
2319 }
2320 sol[row] = xr;
2321 } else
2322 sol[row] = 0.0;
2323 }
2324 #else
2325 for (k = 0; k < numberSlacks_; ++k) {
2326 row = secRowOfU_[k];
2327 col = colOfU_[k];
2328 sol[row] = -rhs[col];
2329 }
2330 for (k = numberSlacks_; k < numberRows_; ++k) {
2331 row = secRowOfU_[k];
2332 col = colOfU_[k];
2333 xr = rhs[col];
2334 int colBeg = UcolStarts_[col];
2335 ind = UcolInd_ + colBeg;
2336 indEnd = ind + UcolLengths_[col];
2337 double *uCol = Ucolumns_ + colBeg;
2338 for (; ind != indEnd; ++ind, ++uCol) {
2339 int iRow = *ind;
2340 double value = sol[iRow];
2341 double elementValue = *uCol;
2342 xr -= value * elementValue;
2343 }
2344 if (xr != 0.0) {
2345 xr *= invOfPivots_[row];
2346 sol[row] = xr;
2347 } else
2348 sol[row] = 0.0;
2349 }
2350 #endif
2351 }
2352
LUupdate(int newBasicCol)2353 int CoinSimpFactorization::LUupdate(int newBasicCol)
2354 {
2355 //checkU();
2356 // recover vector kept in ftran
2357 double *newColumn = vecKeep_;
2358 int *indNewColumn = indKeep_;
2359 int sizeNewColumn = keepSize_;
2360
2361 // remove elements of new column of U
2362 const int colBeg = UcolStarts_[newBasicCol];
2363 const int colEnd = colBeg + UcolLengths_[newBasicCol];
2364 for (int i = colBeg; i < colEnd; ++i) {
2365 const int row = UcolInd_[i];
2366 const int colInRow = findInRow(row, newBasicCol);
2367 assert(colInRow >= 0);
2368 // remove from row
2369 const int rowEnd = UrowStarts_[row] + UrowLengths_[row];
2370 Urows_[colInRow] = Urows_[rowEnd - 1];
2371 UrowInd_[colInRow] = UrowInd_[rowEnd - 1];
2372 --UrowLengths_[row];
2373 }
2374 UcolLengths_[newBasicCol] = 0;
2375 // now add new column to U
2376 int lastRowInU = -1;
2377 for (int i = 0; i < sizeNewColumn; ++i) {
2378 //if ( fabs(newColumn[i]) < zeroTolerance_ ) continue;
2379 const int row = indNewColumn[i];
2380 // add to row
2381 #ifdef COIN_SIMP_CAPACITY
2382 if (UrowLengths_[row] + 1 > UrowCapacities_[row])
2383 increaseRowSize(row, UrowLengths_[row] + 1);
2384 #endif
2385 const int rowEnd = UrowStarts_[row] + UrowLengths_[row];
2386 UrowInd_[rowEnd] = newBasicCol;
2387 Urows_[rowEnd] = newColumn[i];
2388 ++UrowLengths_[row];
2389 if (lastRowInU < secRowPosition_[row])
2390 lastRowInU = secRowPosition_[row];
2391 }
2392 // add to Ucolumns
2393 #ifdef COIN_SIMP_CAPACITY
2394 if (sizeNewColumn > UcolCapacities_[newBasicCol])
2395 increaseColSize(newBasicCol, sizeNewColumn, true);
2396 #endif
2397 memcpy(&Ucolumns_[UcolStarts_[newBasicCol]], &newColumn[0],
2398 sizeNewColumn * sizeof(double));
2399 memcpy(&UcolInd_[UcolStarts_[newBasicCol]], &indNewColumn[0],
2400 sizeNewColumn * sizeof(int));
2401 UcolLengths_[newBasicCol] = sizeNewColumn;
2402
2403 const int posNewCol = colPosition_[newBasicCol];
2404 if (lastRowInU < posNewCol) {
2405 // matrix is singular
2406 return 1;
2407 }
2408 // permutations
2409 const int rowInU = secRowOfU_[posNewCol];
2410 const int colInU = colOfU_[posNewCol];
2411 for (int i = posNewCol; i < lastRowInU; ++i) {
2412 int indx = secRowOfU_[i + 1];
2413 secRowOfU_[i] = indx;
2414 secRowPosition_[indx] = i;
2415 int jndx = colOfU_[i + 1];
2416 colOfU_[i] = jndx;
2417 colPosition_[jndx] = i;
2418 }
2419 secRowOfU_[lastRowInU] = rowInU;
2420 secRowPosition_[rowInU] = lastRowInU;
2421 colOfU_[lastRowInU] = colInU;
2422 colPosition_[colInU] = lastRowInU;
2423 if (posNewCol < numberSlacks_) {
2424 if (lastRowInU >= numberSlacks_)
2425 --numberSlacks_;
2426 else
2427 numberSlacks_ = lastRowInU;
2428 }
2429 // rowInU will be transformed
2430 // denseVector_ is assumed to be initialized to zero
2431 const int rowBeg = UrowStarts_[rowInU];
2432 const int rowEnd = rowBeg + UrowLengths_[rowInU];
2433 for (int i = rowBeg; i < rowEnd; ++i) {
2434 const int column = UrowInd_[i];
2435 denseVector_[column] = Urows_[i];
2436 // remove element
2437 const int indxRow = findInColumn(column, rowInU);
2438 assert(indxRow >= 0);
2439 const int colEnd = UcolStarts_[column] + UcolLengths_[column];
2440 UcolInd_[indxRow] = UcolInd_[colEnd - 1];
2441 Ucolumns_[indxRow] = Ucolumns_[colEnd - 1];
2442 --UcolLengths_[column];
2443 }
2444 UrowLengths_[rowInU] = 0;
2445 // rowInU is empty
2446 // increase Eta by (lastRowInU-posNewCol) elements
2447 newEta(rowInU, lastRowInU - posNewCol);
2448 assert(!EtaLengths_[lastEtaRow_]);
2449 int saveSize = EtaSize_;
2450 ;
2451 for (int i = posNewCol; i < lastRowInU; ++i) {
2452 const int row = secRowOfU_[i];
2453 const int column = colOfU_[i];
2454 if (denseVector_[column] == 0.0)
2455 continue;
2456 const double multiplier = denseVector_[column] * invOfPivots_[row];
2457 denseVector_[column] = 0.0;
2458 const int rowBeg = UrowStarts_[row];
2459 const int rowEnd = rowBeg + UrowLengths_[row];
2460 #if ARRAY
2461 for (int j = rowBeg; j < rowEnd; ++j) {
2462 denseVector_[UrowInd_[j]] -= multiplier * Urows_[j];
2463 }
2464 #else
2465 int *ind = UrowInd_ + rowBeg;
2466 int *indEnd = UrowInd_ + rowEnd;
2467 double *uRow = Urows_ + rowBeg;
2468 for (; ind != indEnd; ++ind) {
2469 denseVector_[*ind] -= multiplier * (*uRow);
2470 ++uRow;
2471 }
2472 #endif
2473 // store multiplier
2474 Eta_[EtaSize_] = multiplier;
2475 EtaInd_[EtaSize_++] = row;
2476 }
2477 if (EtaSize_ != saveSize)
2478 EtaLengths_[lastEtaRow_] = EtaSize_ - saveSize;
2479 else
2480 --lastEtaRow_;
2481 // inverse of diagonal
2482 invOfPivots_[rowInU] = 1.0 / denseVector_[colOfU_[lastRowInU]];
2483 denseVector_[colOfU_[lastRowInU]] = 0.0;
2484 // now store row
2485 int newEls = 0;
2486 for (int i = lastRowInU + 1; i < numberColumns_; ++i) {
2487 const int column = colOfU_[i];
2488 const double coeff = denseVector_[column];
2489 denseVector_[column] = 0.0;
2490 if (fabs(coeff) < zeroTolerance_)
2491 continue;
2492 #ifdef COIN_SIMP_CAPACITY
2493 if (UcolLengths_[column] + 1 > UcolCapacities_[column]) {
2494 increaseColSize(column, UcolLengths_[column] + 1, true);
2495 }
2496 #endif
2497 const int newInd = UcolStarts_[column] + UcolLengths_[column];
2498 UcolInd_[newInd] = rowInU;
2499 Ucolumns_[newInd] = coeff;
2500 ++UcolLengths_[column];
2501 workArea2_[newEls] = coeff;
2502 indVector_[newEls++] = column;
2503 }
2504 #ifdef COIN_SIMP_CAPACITY
2505 if (UrowCapacities_[rowInU] < newEls)
2506 increaseRowSize(rowInU, newEls);
2507 #endif
2508 const int startRow = UrowStarts_[rowInU];
2509 memcpy(&Urows_[startRow], &workArea2_[0], newEls * sizeof(double));
2510 memcpy(&UrowInd_[startRow], &indVector_[0], newEls * sizeof(int));
2511 UrowLengths_[rowInU] = newEls;
2512 //
2513 if (fabs(invOfPivots_[rowInU]) > updateTol_)
2514 return 2;
2515
2516 return 0;
2517 }
2518
newEta(int row,int numNewElements)2519 void CoinSimpFactorization::newEta(int row, int numNewElements)
2520 {
2521 if (lastEtaRow_ == maxEtaRows_ - 1) {
2522 int *iaux = new int[maxEtaRows_ + minIncrease_];
2523 memcpy(iaux, EtaPosition_, maxEtaRows_ * sizeof(int));
2524 delete[] EtaPosition_;
2525 EtaPosition_ = iaux;
2526
2527 int *jaux = new int[maxEtaRows_ + minIncrease_];
2528 memcpy(jaux, EtaStarts_, maxEtaRows_ * sizeof(int));
2529 delete[] EtaStarts_;
2530 EtaStarts_ = jaux;
2531
2532 int *kaux = new int[maxEtaRows_ + minIncrease_];
2533 memcpy(kaux, EtaLengths_, maxEtaRows_ * sizeof(int));
2534 delete[] EtaLengths_;
2535 EtaLengths_ = kaux;
2536
2537 maxEtaRows_ += minIncrease_;
2538 }
2539 if (EtaSize_ + numNewElements > EtaMaxCap_) {
2540 int number = CoinMax(EtaSize_ + numNewElements - EtaMaxCap_, minIncrease_);
2541
2542 int *iaux = new int[EtaMaxCap_ + number];
2543 memcpy(iaux, EtaInd_, EtaSize_ * sizeof(int));
2544 delete[] EtaInd_;
2545 EtaInd_ = iaux;
2546
2547 double *aux = new double[EtaMaxCap_ + number];
2548 memcpy(aux, Eta_, EtaSize_ * sizeof(double));
2549 delete[] Eta_;
2550 Eta_ = aux;
2551
2552 EtaMaxCap_ += number;
2553 }
2554 EtaPosition_[++lastEtaRow_] = row;
2555 EtaStarts_[lastEtaRow_] = EtaSize_;
2556 EtaLengths_[lastEtaRow_] = 0;
2557 }
copyRowPermutations()2558 void CoinSimpFactorization::copyRowPermutations()
2559 {
2560 memcpy(&secRowOfU_[0], &rowOfU_[0],
2561 numberRows_ * sizeof(int));
2562 memcpy(&secRowPosition_[0], &rowPosition_[0],
2563 numberRows_ * sizeof(int));
2564 }
2565
Hxeqb(double * b) const2566 void CoinSimpFactorization::Hxeqb(double *b) const
2567 {
2568 double *rhs = b;
2569 int row, rowBeg, *ind, *indEnd;
2570 double xr, *eta;
2571 // now solve
2572 for (int k = 0; k <= lastEtaRow_; ++k) {
2573 row = EtaPosition_[k];
2574 rowBeg = EtaStarts_[k];
2575 xr = 0.0;
2576 ind = EtaInd_ + rowBeg;
2577 indEnd = ind + EtaLengths_[k];
2578 eta = Eta_ + rowBeg;
2579 for (; ind != indEnd; ++ind) {
2580 xr += rhs[*ind] * (*eta);
2581 ++eta;
2582 }
2583 rhs[row] -= xr;
2584 }
2585 }
2586
Hxeqb2(double * b1,double * b2) const2587 void CoinSimpFactorization::Hxeqb2(double *b1, double *b2) const
2588 {
2589 double *rhs1 = b1;
2590 double *rhs2 = b2;
2591 int row, rowBeg, *ind, *indEnd;
2592 double x1, x2, *eta;
2593 // now solve
2594 for (int k = 0; k <= lastEtaRow_; ++k) {
2595 row = EtaPosition_[k];
2596 rowBeg = EtaStarts_[k];
2597 x1 = 0.0;
2598 x2 = 0.0;
2599 ind = EtaInd_ + rowBeg;
2600 indEnd = ind + EtaLengths_[k];
2601 eta = Eta_ + rowBeg;
2602 for (; ind != indEnd; ++ind) {
2603 x1 += rhs1[*ind] * (*eta);
2604 x2 += rhs2[*ind] * (*eta);
2605 ++eta;
2606 }
2607 rhs1[row] -= x1;
2608 rhs2[row] -= x2;
2609 }
2610 }
2611
xHeqb(double * b) const2612 void CoinSimpFactorization::xHeqb(double *b) const
2613 {
2614 double *rhs = b;
2615 int row, rowBeg, *ind, *indEnd;
2616 double xr, *eta;
2617 // now solve
2618 for (int k = lastEtaRow_; k >= 0; --k) {
2619 row = EtaPosition_[k];
2620 xr = rhs[row];
2621 if (xr == 0.0)
2622 continue;
2623 //if ( fabs(xr) <= zeroTolerance_ ) continue;
2624 rowBeg = EtaStarts_[k];
2625 ind = EtaInd_ + rowBeg;
2626 indEnd = ind + EtaLengths_[k];
2627 eta = Eta_ + rowBeg;
2628 for (; ind != indEnd; ++ind) {
2629 rhs[*ind] -= xr * (*eta);
2630 ++eta;
2631 }
2632 }
2633 }
2634
ftran(double * b,double * sol,bool save) const2635 void CoinSimpFactorization::ftran(double *b, double *sol, bool save) const
2636 {
2637 Lxeqb(b);
2638 Hxeqb(b);
2639 if (save) {
2640 // keep vector
2641 keepSize_ = 0;
2642 for (int i = 0; i < numberRows_; ++i) {
2643 if (fabs(b[i]) < zeroTolerance_)
2644 continue;
2645 vecKeep_[keepSize_] = b[i];
2646 indKeep_[keepSize_++] = i;
2647 }
2648 }
2649 Uxeqb(b, sol);
2650 }
2651
ftran2(double * b1,double * sol1,double * b2,double * sol2) const2652 void CoinSimpFactorization::ftran2(double *b1, double *sol1, double *b2, double *sol2) const
2653 {
2654 Lxeqb2(b1, b2);
2655 Hxeqb2(b1, b2);
2656 // keep vector
2657 keepSize_ = 0;
2658 for (int i = 0; i < numberRows_; ++i) {
2659 if (fabs(b1[i]) < zeroTolerance_)
2660 continue;
2661 vecKeep_[keepSize_] = b1[i];
2662 indKeep_[keepSize_++] = i;
2663 }
2664 Uxeqb2(b1, sol1, b2, sol2);
2665 }
2666
btran(double * b,double * sol) const2667 void CoinSimpFactorization::btran(double *b, double *sol) const
2668 {
2669 xUeqb(b, sol);
2670 xHeqb(sol);
2671 xLeqb(sol);
2672 }
2673
2674 #endif
2675
2676 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
2677 */
2678