1 /* $Id: CoinOslFactorization3.cpp 2216 2019-12-27 03:28:40Z stefan $ */
2 /*
3 Copyright (C) 1987, 2009, International Business Machines
4 Corporation and others. All Rights Reserved.
5
6 This code is licensed under the terms of the Eclipse Public License (EPL).
7 */
8 #include <climits>
9 #if COIN_BIG_INDEX == 0
10 #include "CoinOslFactorization.hpp"
11 #include "CoinOslC.h"
12 #include "CoinFinite.hpp"
13 #define GO_DENSE 70
14 #define GO_DENSE_RATIO 1.8
15 int c_ekkclco(const EKKfactinfo *fact, int *hcoli,
16 int *mrstrt, int *hinrow, int xnewro);
17
18 void c_ekkclcp(const int *hcol, const double *dels, const int *mrstrt,
19 int *hrow, double *dels2, int *mcstrt,
20 int *hincol, int itype, int nnrow, int nncol,
21 int ninbas);
22
23 int c_ekkcmfc(EKKfactinfo *fact,
24 EKKHlink *rlink, EKKHlink *clink,
25 EKKHlink *mwork, void *maction_void,
26 int nnetas,
27 int *nsingp, int *xrejctp,
28 int *xnewrop, int xnewco,
29 int *ncompactionsp);
30
31 int c_ekkcmfy(EKKfactinfo *fact,
32 EKKHlink *rlink, EKKHlink *clink,
33 EKKHlink *mwork, void *maction_void,
34 int nnetas,
35 int *nsingp, int *xrejctp,
36 int *xnewrop, int xnewco,
37 int *ncompactionsp);
38
39 int c_ekkcmfd(EKKfactinfo *fact,
40 int *mcol,
41 EKKHlink *rlink, EKKHlink *clink,
42 int *maction,
43 int nnetas,
44 int *nnentlp, int *nnentup,
45 int *nsingp);
46 int c_ekkford(const EKKfactinfo *fact, const int *hinrow, const int *hincol,
47 int *hpivro, int *hpivco,
48 EKKHlink *rlink, EKKHlink *clink);
49 void c_ekkrowq(int *hrow, int *hcol, double *dels,
50 int *mrstrt,
51 const int *hinrow, int nnrow, int ninbas);
52 int c_ekkrwco(const EKKfactinfo *fact, double *dluval, int *hcoli, int *mrstrt, int *hinrow, int xnewro);
53
54 int c_ekkrwcs(const EKKfactinfo *fact, double *dluval, int *hcoli, int *mrstrt,
55 const int *hinrow, const EKKHlink *mwork,
56 int nfirst);
57
58 void c_ekkrwct(const EKKfactinfo *fact, double *dluval, int *hcoli, int *mrstrt,
59 const int *hinrow, const EKKHlink *mwork,
60 const EKKHlink *rlink,
61 const short *msort, double *dsort,
62 int nlast, int xnewro);
63
64 int c_ekkshff(EKKfactinfo *fact,
65 EKKHlink *clink, EKKHlink *rlink,
66 int xnewro);
67
68 void c_ekkshfv(EKKfactinfo *fact, EKKHlink *rlink, EKKHlink *clink,
69 int xnewro);
70 int c_ekktria(EKKfactinfo *fact,
71 EKKHlink *rlink,
72 EKKHlink *clink,
73 int *nsingp,
74 int *xnewcop, int *xnewrop,
75 int *nlrowtp,
76 const int ninbas);
77 #if 0
78 static void c_ekkafpv(int *hentry, int *hcoli,
79 double *dluval, int *mrstrt,
80 int *hinrow, int nentry)
81 {
82 int j;
83 int nel, krs;
84 int koff;
85 int irow;
86 int ientry;
87 int * index;
88
89 for (ientry = 0; ientry < nentry; ++ientry) {
90 #ifdef INTEL
91 int * els_long,maxaij_long;
92 #endif
93 double * els;
94 irow = UNSHIFT_INDEX(hentry[ientry]);
95 nel = hinrow[irow];
96 krs = mrstrt[irow];
97 index=&hcoli[krs];
98 els=&dluval[krs];
99 #ifdef INTEL
100 els_long=reinterpret_cast<int *> (els);
101 maxaij_long=0;
102 #else
103 double maxaij = 0.f;
104 #endif
105 koff = 0;
106 j=0;
107 if ((nel&1)!=0) {
108 #ifdef INTEL
109 maxaij_long = els_long[1] & 0x7fffffff;
110 #else
111 maxaij=fabs(els[0]);
112 #endif
113 j=1;
114 }
115
116 while (j<nel) {
117 #ifdef INTEL
118 UNROLL_LOOP_BODY2({
119 int d_long = els_long[1+(j<<1)] & 0x7fffffff;
120 if (maxaij_long < d_long) {
121 maxaij_long = d_long;
122 koff=j;
123 }
124 j++;
125 });
126 #else
127 UNROLL_LOOP_BODY2({
128 double d = fabs(els[j]);
129 if (maxaij < d) {
130 maxaij = d;
131 koff=j;
132 }
133 j++;
134 });
135 #endif
136 }
137
138 SWAP(int, index[koff], index[0]);
139 SWAP(double, els[koff], els[0]);
140 }
141 } /* c_ekkafpv */
142 #endif
143
144 /* Uwe H. Suhl, March 1987 */
145 /* This routine processes col singletons during the LU-factorization. */
146 /* Return codes (checked version 1.11): */
147 /* 0: ok */
148 /* 6: pivot element too small */
149 /* -43: system error at label 420 (ipivot not found) */
150 /*
151 * This routine processes singleton columns during factorization of the
152 * nucleus. It is very similar to the first part of c_ekktria,
153 * but is more complex, because we now have to maintain the length
154 * lists.
155 * The differences are:
156 * (1) here we use the length list for length 1 rather than a queue.
157 * This routine is only called if it is known that there is a singleton
158 * column.
159 *
160 * (2) here we maintain hrowi by moving the last entry into the pivot
161 * column entry; that means we don't have to search for the pivot row
162 * entry like we do in c_ekktria.
163 *
164 * (3) here the hlink data structure is in use for the length lists,
165 * so we maintain it as we shorten rows and removing columns altogether.
166 *
167 */
c_ekkcsin(EKKfactinfo * fact,EKKHlink * rlink,EKKHlink * clink,int * nsingp)168 int c_ekkcsin(EKKfactinfo *fact,
169 EKKHlink *rlink, EKKHlink *clink,
170
171 int *nsingp)
172 {
173 #if 1
174 int *hcoli = fact->xecadr;
175 double *dluval = fact->xeeadr;
176 //double *dvalpv = fact->kw3adr;
177 int *mrstrt = fact->xrsadr;
178 int *hrowi = fact->xeradr;
179 int *mcstrt = fact->xcsadr;
180 int *hinrow = fact->xrnadr;
181 int *hincol = fact->xcnadr;
182 int *hpivro = fact->krpadr;
183 int *hpivco = fact->kcpadr;
184 #endif
185 const int nrow = fact->nrow;
186 const double drtpiv = fact->drtpiv;
187
188 int j, k, kc, kce, kcs, nzj;
189 double pivot;
190 int kipis, kipie;
191 int jpivot;
192 #ifndef NDEBUG
193 int kpivot = -1;
194 #else
195 int kpivot = -1;
196 #endif
197
198 bool small_pivot = false;
199
200 /* next singleton column.
201 * Note that when the pivot column itself was removed from the
202 * list, the column in the list after it (if any) moves to the
203 * head of the list.
204 * Also, if any column from the pivot row was reduced to length 1,
205 * then it will have been added to the list and now be in front.
206 */
207 for (jpivot = hpivco[1]; jpivot > 0; jpivot = hpivco[1]) {
208 const int ipivot = hrowi[mcstrt[jpivot]]; /* (2) */
209 assert(ipivot);
210 /* The pivot row is being eliminated (3) */
211 C_EKK_REMOVE_LINK(hpivro, hinrow, rlink, ipivot);
212
213 /* Loop over nonzeros in pivot row: */
214 kipis = mrstrt[ipivot];
215 kipie = kipis + hinrow[ipivot] - 1;
216 for (k = kipis; k <= kipie; ++k) {
217 j = hcoli[k];
218
219 /*
220 * We're eliminating column jpivot,
221 * so we're eliminating the row it occurs in,
222 * so every column in this row is becoming one shorter.
223 *
224 * I don't know why we don't do the same for rejected columns.
225 *
226 * if xrejct is false, then no column has ever been rejected
227 * and this test wouldn't have to be made.
228 * However, that means this whole loop would have to be copied.
229 */
230 if (!(clink[j].pre > nrow)) {
231 C_EKK_REMOVE_LINK(hpivco, hincol, clink, j); /* (3) */
232 }
233 --hincol[j];
234
235 kcs = mcstrt[j];
236 kce = kcs + hincol[j];
237 for (kc = kcs; kc <= kce; ++kc) {
238 if (ipivot == hrowi[kc]) {
239 break;
240 }
241 }
242 /* ASSERT !(kc>kce) */
243
244 /* (2) */
245 hrowi[kc] = hrowi[kce];
246 hrowi[kce] = 0;
247
248 if (j == jpivot) {
249 /* remember the slot corresponding to the pivot column */
250 kpivot = k;
251 } else {
252 /*
253 * We just reduced the length of the column.
254 * If we haven't eliminated all of its elements completely,
255 * then we have to put it back in its new length list.
256 *
257 * If the column was rejected, we only put it back in a length
258 * list when it has been reduced to a singleton column,
259 * because it would just be rejected again.
260 */
261 nzj = hincol[j];
262 if (!(nzj <= 0) && !(clink[j].pre > nrow && nzj != 1)) {
263 C_EKK_ADD_LINK(hpivco, nzj, clink, j); /* (3) */
264 }
265 }
266 }
267 assert(kpivot > 0);
268
269 /* store pivot sequence number */
270 ++fact->npivots;
271 rlink[ipivot].pre = -fact->npivots;
272 clink[jpivot].pre = -fact->npivots;
273
274 /* compute how much room we'll need later */
275 fact->nuspike += hinrow[ipivot];
276
277 /* check the pivot */
278 pivot = dluval[kpivot];
279 if (fabs(pivot) < drtpiv) {
280 /* pivot element too small */
281 small_pivot = true;
282 rlink[ipivot].pre = -nrow - 1;
283 clink[jpivot].pre = -nrow - 1;
284 ++(*nsingp);
285 }
286
287 /* swap the pivoted column entry with the first entry in the row */
288 dluval[kpivot] = dluval[kipis];
289 dluval[kipis] = pivot;
290 hcoli[kpivot] = hcoli[kipis];
291 hcoli[kipis] = jpivot;
292 }
293
294 return (small_pivot);
295 } /* c_ekkcsin */
296
297 /* Uwe H. Suhl, March 1987 */
298 /* This routine processes row singletons during the computation of */
299 /* an LU-decomposition for the nucleus. */
300 /* Return codes (checked version 1.16): */
301 /* -5: not enough space in row file */
302 /* -6: not enough space in column file */
303 /* 7: pivot element too small */
304 /* -52: system error at label 220 (ipivot not found) */
305 /* -53: system error at label 400 (jpivot not found) */
c_ekkrsin(EKKfactinfo * fact,EKKHlink * rlink,EKKHlink * clink,EKKHlink * mwork,int nfirst,int * nsingp,int * xnewcop,int * xnewrop,int * nnentup,int * kmxetap,int * ncompactionsp,int * nnentlp)306 int c_ekkrsin(EKKfactinfo *fact,
307 EKKHlink *rlink, EKKHlink *clink,
308 EKKHlink *mwork, int nfirst,
309 int *nsingp,
310 int *xnewcop, int *xnewrop,
311 int *nnentup,
312 int *kmxetap, int *ncompactionsp,
313 int *nnentlp)
314
315 {
316 #if 1
317 int *hcoli = fact->xecadr;
318 double *dluval = fact->xeeadr;
319 //double *dvalpv = fact->kw3adr;
320 int *mrstrt = fact->xrsadr;
321 int *hrowi = fact->xeradr;
322 int *mcstrt = fact->xcsadr;
323 int *hinrow = fact->xrnadr;
324 int *hincol = fact->xcnadr;
325 int *hpivro = fact->krpadr;
326 int *hpivco = fact->kcpadr;
327 #endif
328 const int nrow = fact->nrow;
329 const double drtpiv = fact->drtpiv;
330
331 int xnewro = *xnewrop;
332 int xnewco = *xnewcop;
333 int kmxeta = *kmxetap;
334 int nnentu = *nnentup;
335 int ncompactions = *ncompactionsp;
336 int nnentl = *nnentlp;
337
338 int i, j, k, kc, kr, npr, nzi;
339 double pivot;
340 int kjpis, kjpie, knprs, knpre;
341 double elemnt, maxaij;
342 int ipivot, epivco, lstart;
343 #ifndef NDEBUG
344 int kpivot = -1;
345 #else
346 int kpivot = -1;
347 #endif
348 int irtcod = 0;
349 const int nnetas = fact->nnetas;
350
351 lstart = nnetas - nnentl + 1;
352
353 for (ipivot = hpivro[1]; ipivot > 0; ipivot = hpivro[1]) {
354 const int jpivot = hcoli[mrstrt[ipivot]];
355
356 kjpis = mcstrt[jpivot];
357 kjpie = kjpis + hincol[jpivot];
358 for (k = kjpis; k < kjpie; ++k) {
359 i = hrowi[k];
360
361 /*
362 * We're eliminating row ipivot,
363 * so we're eliminating the column it occurs in,
364 * so every row in this column is becoming one shorter.
365 *
366 * No exception is made for rejected rows.
367 */
368 C_EKK_REMOVE_LINK(hpivro, hinrow, rlink, i);
369 }
370
371 /* The pivot column is being eliminated */
372 /* I don't know why there is an exception for rejected columns */
373 if (!(clink[jpivot].pre > nrow)) {
374 C_EKK_REMOVE_LINK(hpivco, hincol, clink, jpivot);
375 }
376
377 epivco = hincol[jpivot] - 1;
378 kjpie = kjpis + epivco;
379 for (kc = kjpis; kc <= kjpie; ++kc) {
380 if (ipivot == hrowi[kc]) {
381 break;
382 }
383 }
384 /* ASSERT !(kc>kjpie) */
385
386 /* move the last column entry into this deleted one to keep */
387 /* the entries compact */
388 hrowi[kc] = hrowi[kjpie];
389
390 hrowi[kjpie] = 0;
391
392 /* store pivot sequence number */
393 ++fact->npivots;
394 rlink[ipivot].pre = -fact->npivots;
395 clink[jpivot].pre = -fact->npivots;
396
397 /* Check if row or column files have to be compressed */
398 if (!(xnewro + epivco < lstart)) {
399 if (!(nnentu + epivco < lstart)) {
400 return (-5);
401 }
402 {
403 int iput = c_ekkrwcs(fact, dluval, hcoli, mrstrt, hinrow, mwork, nfirst);
404 kmxeta += xnewro - iput;
405 xnewro = iput - 1;
406 ++ncompactions;
407 }
408 }
409 if (!(xnewco + epivco < lstart)) {
410 if (!(nnentu + epivco < lstart)) {
411 return (-5);
412 }
413 xnewco = c_ekkclco(fact, hrowi, mcstrt, hincol, xnewco);
414 ++ncompactions;
415 }
416
417 /* This column has no more entries in it */
418 hincol[jpivot] = 0;
419
420 /* Perform numerical part of elimination. */
421 pivot = dluval[mrstrt[ipivot]];
422 if (fabs(pivot) < drtpiv) {
423 irtcod = 7;
424 rlink[ipivot].pre = -nrow - 1;
425 clink[jpivot].pre = -nrow - 1;
426 ++(*nsingp);
427 }
428
429 /* If epivco is 0, then we can treat this like a singleton column (?)*/
430 if (!(epivco <= 0)) {
431 ++fact->xnetal;
432 mcstrt[fact->xnetal] = lstart - 1;
433 hpivco[fact->xnetal] = ipivot;
434
435 /* Loop over nonzeros in pivot column. */
436 kjpis = mcstrt[jpivot];
437 kjpie = kjpis + epivco;
438 nnentl += epivco;
439 nnentu -= epivco;
440 for (kc = kjpis; kc < kjpie; ++kc) {
441 npr = hrowi[kc];
442 /* zero out the row entries as we go along */
443 hrowi[kc] = 0;
444
445 /* each row in the column is getting shorter */
446 --hinrow[npr];
447
448 /* find the entry in this row for the pivot column */
449 knprs = mrstrt[npr];
450 knpre = knprs + hinrow[npr];
451 for (kr = knprs; kr <= knpre; ++kr) {
452 if (jpivot == hcoli[kr])
453 break;
454 }
455 /* ASSERT !(kr>knpre) */
456
457 elemnt = dluval[kr];
458 /* move the last pivot column entry into this one */
459 /* to keep entries compact */
460 dluval[kr] = dluval[knpre];
461 hcoli[kr] = hcoli[knpre];
462
463 /*
464 * c_ekkmltf put the largest entries in front, and
465 * we want to maintain that property.
466 * There is only a problem if we just pivoted out the first
467 * entry, and there is more than one entry in the list.
468 */
469 if (!(kr != knprs || hinrow[npr] <= 1)) {
470 maxaij = 0.f;
471 for (k = knprs; k <= knpre; ++k) {
472 if (!(fabs(dluval[k]) <= maxaij)) {
473 maxaij = fabs(dluval[k]);
474 kpivot = k;
475 }
476 }
477 assert(kpivot > 0);
478 maxaij = dluval[kpivot];
479 dluval[kpivot] = dluval[knprs];
480 dluval[knprs] = maxaij;
481
482 j = hcoli[kpivot];
483 hcoli[kpivot] = hcoli[knprs];
484 hcoli[knprs] = j;
485 }
486
487 /* store elementary row transformation */
488 --lstart;
489 dluval[lstart] = -elemnt / pivot;
490 hrowi[lstart] = SHIFT_INDEX(npr);
491
492 /* Only add the row back in a length list if it isn't empty */
493 nzi = hinrow[npr];
494 if (!(nzi <= 0)) {
495 C_EKK_ADD_LINK(hpivro, nzi, rlink, npr);
496 }
497 }
498 ++fact->nuspike;
499 }
500 }
501
502 *xnewrop = xnewro;
503 *xnewcop = xnewco;
504 *kmxetap = kmxeta;
505 *nnentup = nnentu;
506 *ncompactionsp = ncompactions;
507 *nnentlp = nnentl;
508
509 return (irtcod);
510 } /* c_ekkrsin */
511
c_ekkfpvt(const EKKfactinfo * fact,EKKHlink * rlink,EKKHlink * clink,int * nsingp,int * xrejctp,int * xipivtp,int * xjpivtp)512 int c_ekkfpvt(const EKKfactinfo *fact,
513 EKKHlink *rlink, EKKHlink *clink,
514 int *nsingp, int *xrejctp,
515 int *xipivtp, int *xjpivtp)
516 {
517 double zpivlu = fact->zpivlu;
518 #if 1
519 int *hcoli = fact->xecadr;
520 double *dluval = fact->xeeadr;
521 //double *dvalpv = fact->kw3adr;
522 int *mrstrt = fact->xrsadr;
523 int *hrowi = fact->xeradr;
524 int *mcstrt = fact->xcsadr;
525 int *hinrow = fact->xrnadr;
526 int *hincol = fact->xcnadr;
527 int *hpivro = fact->krpadr;
528 int *hpivco = fact->kcpadr;
529 #endif
530 int i, j, k, ke, kk, ks, nz, nz1, kce, kcs, kre, krs;
531 double minsze;
532 int marcst, mincst, mincnt, trials, nentri;
533 int jpivot = -1;
534 bool rjectd;
535 int ipivot;
536 const int nrow = fact->nrow;
537 int irtcod = 0;
538
539 /* this used to be initialized in c_ekklfct */
540 const int xtrial = 1;
541
542 trials = 0;
543 ipivot = 0;
544 mincst = COIN_INT_MAX;
545 mincnt = COIN_INT_MAX;
546 for (nz = 2; nz <= nrow; ++nz) {
547 nz1 = nz - 1;
548 if (mincnt <= nz) {
549 goto L900;
550 }
551
552 /* Search rows for a pivot */
553 for (i = hpivro[nz]; !(i <= 0); i = rlink[i].suc) {
554
555 ks = mrstrt[i];
556 ke = ks + nz - 1;
557 /* Determine magnitude of minimal acceptable element */
558 minsze = fabs(dluval[ks]) * zpivlu;
559 for (k = ks; k <= ke; ++k) {
560 /* Consider a column only if it passes the stability test */
561 if (!(fabs(dluval[k]) < minsze)) {
562 j = hcoli[k];
563 marcst = nz1 * hincol[j];
564 if (!(marcst >= mincst)) {
565 mincst = marcst;
566 mincnt = hincol[j];
567 ipivot = i;
568 jpivot = j;
569 if (mincnt <= nz + 1) {
570 goto L900;
571 }
572 }
573 }
574 }
575 ++trials;
576
577 if (trials >= xtrial) {
578 goto L900;
579 }
580 }
581
582 /* Search columns for a pivot */
583 j = hpivco[nz];
584 while (!(j <= 0)) {
585 /* XSEARD = XSEARD + 1 */
586 rjectd = false;
587 kcs = mcstrt[j];
588 kce = kcs + nz - 1;
589 for (k = kcs; k <= kce; ++k) {
590 i = hrowi[k];
591 nentri = hinrow[i];
592 marcst = nz1 * nentri;
593 if (!(marcst >= mincst)) {
594 /* Determine magnitude of minimal acceptable element */
595 minsze = fabs(dluval[mrstrt[i]]) * zpivlu;
596 krs = mrstrt[i];
597 kre = krs + nentri - 1;
598 for (kk = krs; kk <= kre; ++kk) {
599 if (hcoli[kk] == j)
600 break;
601 }
602 /* ASSERT (kk <= kre) */
603
604 /* perform stability test */
605 if (!(fabs(dluval[kk]) < minsze)) {
606 mincst = marcst;
607 mincnt = nentri;
608 ipivot = i;
609 jpivot = j;
610 rjectd = false;
611 if (mincnt <= nz) {
612 goto L900;
613 }
614 } else {
615 if (ipivot == 0) {
616 rjectd = true;
617 }
618 }
619 }
620 }
621 ++trials;
622 if (trials >= xtrial && ipivot > 0) {
623 goto L900;
624 }
625 if (rjectd) {
626 int jsuc = clink[j].suc;
627 ++(*xrejctp);
628 C_EKK_REMOVE_LINK(hpivco, hincol, clink, j);
629 clink[j].pre = nrow + 1;
630 j = jsuc;
631 } else {
632 j = clink[j].suc;
633 }
634 }
635 }
636
637 /* FLAG REJECTED ROWS (should this be columns ?) */
638 for (j = 1; j <= nrow; ++j) {
639 if (hinrow[j] == 0) {
640 rlink[j].pre = -nrow - 1;
641 ++(*nsingp);
642 }
643 }
644 irtcod = 10;
645
646 L900:
647 *xipivtp = ipivot;
648 *xjpivtp = jpivot;
649 return (irtcod);
650 } /* c_ekkfpvt */
c_ekkprpv(EKKfactinfo * fact,EKKHlink * rlink,EKKHlink * clink,int xrejct,int ipivot,int jpivot)651 void c_ekkprpv(EKKfactinfo *fact,
652 EKKHlink *rlink, EKKHlink *clink,
653
654 int xrejct,
655 int ipivot, int jpivot)
656 {
657 #if 1
658 int *hcoli = fact->xecadr;
659 double *dluval = fact->xeeadr;
660 //double *dvalpv = fact->kw3adr;
661 int *mrstrt = fact->xrsadr;
662 int *hrowi = fact->xeradr;
663 int *mcstrt = fact->xcsadr;
664 int *hinrow = fact->xrnadr;
665 int *hincol = fact->xcnadr;
666 int *hpivro = fact->krpadr;
667 int *hpivco = fact->kcpadr;
668 #endif
669 int i, k;
670 int kc;
671 double pivot;
672 int kipis = mrstrt[ipivot];
673 int kipie = kipis + hinrow[ipivot] - 1;
674
675 #ifndef NDEBUG
676 int kpivot = -1;
677 #else
678 int kpivot = -1;
679 #endif
680 const int nrow = fact->nrow;
681
682 /* Update data structures */
683 {
684 int kjpis = mcstrt[jpivot];
685 int kjpie = kjpis + hincol[jpivot];
686 for (k = kjpis; k < kjpie; ++k) {
687 i = hrowi[k];
688 C_EKK_REMOVE_LINK(hpivro, hinrow, rlink, i);
689 }
690 }
691
692 for (k = kipis; k <= kipie; ++k) {
693 int j = hcoli[k];
694
695 if ((xrejct == 0) || !(clink[j].pre > nrow)) {
696 C_EKK_REMOVE_LINK(hpivco, hincol, clink, j);
697 }
698
699 --hincol[j];
700 int kcs = mcstrt[j];
701 int kce = kcs + hincol[j];
702
703 for (kc = kcs; kc < kce; kc++) {
704 if (hrowi[kc] == ipivot)
705 break;
706 }
707 assert(kc < kce || hrowi[kce] == ipivot);
708 hrowi[kc] = hrowi[kce];
709 hrowi[kce] = 0;
710 if (j == jpivot) {
711 kpivot = k;
712 }
713 }
714 assert(kpivot > 0);
715
716 /* Store the pivot sequence number */
717 ++fact->npivots;
718 rlink[ipivot].pre = -fact->npivots;
719 clink[jpivot].pre = -fact->npivots;
720
721 pivot = dluval[kpivot];
722 dluval[kpivot] = dluval[kipis];
723 dluval[kipis] = pivot;
724 hcoli[kpivot] = hcoli[kipis];
725 hcoli[kipis] = jpivot;
726
727 } /* c_ekkprpv */
728
729 /*
730 * c_ekkclco is almost exactly like c_ekkrwco.
731 */
c_ekkclco(const EKKfactinfo * fact,int * hcoli,int * mrstrt,int * hinrow,int xnewro)732 int c_ekkclco(const EKKfactinfo *fact, int *hcoli, int *mrstrt, int *hinrow, int xnewro)
733 {
734 #if 0
735 int *hcoli = fact->xecadr;
736 double *dluval = fact->xeeadr;
737 double *dvalpv = fact->kw3adr;
738 int *mrstrt = fact->xrsadr;
739 int *hrowi = fact->xeradr;
740 int *mcstrt = fact->xcsadr;
741 int *hinrow = fact->xrnadr;
742 int *hincol = fact->xcnadr;
743 int *hpivro = fact->krpadr;
744 int *hpivco = fact->kcpadr;
745 #endif
746 int i, k, nz, kold;
747 int kstart;
748 const int nrow = fact->nrow;
749
750 for (i = 1; i <= nrow; ++i) {
751 nz = hinrow[i];
752 if (0 < nz) {
753 /* save the last column entry of row i in hinrow */
754 /* and replace that entry with -i */
755 k = mrstrt[i] + nz - 1;
756 hinrow[i] = hcoli[k];
757 hcoli[k] = -i;
758 }
759 }
760
761 kstart = 0;
762 kold = 0;
763 for (k = 1; k <= xnewro; ++k) {
764 if (hcoli[k] != 0) {
765 ++kstart;
766
767 /* if this is the last entry for the row... */
768 if (hcoli[k] < 0) {
769 /* restore the entry */
770 i = -hcoli[k];
771 hcoli[k] = hinrow[i];
772
773 /* update mrstart and hinrow */
774 mrstrt[i] = kold + 1;
775 hinrow[i] = kstart - kold;
776 kold = kstart;
777 }
778
779 hcoli[kstart] = hcoli[k];
780 }
781 }
782
783 /* INSERTED INCASE CALLED FROM YTRIAN JJHF */
784 mrstrt[nrow + 1] = kstart + 1;
785
786 return (kstart);
787 } /* c_ekkclco */
788
789 #undef MACTION_T
790 #define COIN_OSL_CMFC
791 #define MACTION_T short int
c_ekkcmfc(EKKfactinfo * fact,EKKHlink * rlink,EKKHlink * clink,EKKHlink * mwork,void * maction_void,int nnetas,int * nsingp,int * xrejctp,int * xnewrop,int xnewco,int * ncompactionsp)792 int c_ekkcmfc(EKKfactinfo *fact,
793 EKKHlink *rlink, EKKHlink *clink,
794 EKKHlink *mwork, void *maction_void,
795 int nnetas,
796 int *nsingp, int *xrejctp,
797 int *xnewrop, int xnewco,
798 int *ncompactionsp)
799
800 #include "CoinOslC.h"
801 #undef COIN_OSL_CMFC
802 #undef MACTION_T
803 static int c_ekkidmx(int n, const double *dx)
804 {
805 int ret_val;
806 int i;
807 double dmax;
808 --dx;
809
810 /* Function Body */
811
812 if (n < 1) {
813 return (0);
814 }
815
816 if (n == 1) {
817 return (1);
818 }
819
820 ret_val = 1;
821 dmax = fabs(dx[1]);
822 for (i = 2; i <= n; ++i) {
823 if (fabs(dx[i]) > dmax) {
824 ret_val = i;
825 dmax = fabs(dx[i]);
826 }
827 }
828
829 return ret_val;
830 } /* c_ekkidmx */
831 /* Return codes in IRTCOD/IRTCOD are */
832 /* 4: numerical problems */
833 /* 5: not enough space in row file */
834 /* 6: not enough space in column file */
c_ekkcmfd(EKKfactinfo * fact,int * mcol,EKKHlink * rlink,EKKHlink * clink,int * maction,int nnetas,int * nnentlp,int * nnentup,int * nsingp)835 int c_ekkcmfd(EKKfactinfo *fact,
836 int *mcol,
837 EKKHlink *rlink, EKKHlink *clink,
838 int *maction,
839 int nnetas,
840 int *nnentlp, int *nnentup,
841 int *nsingp)
842 {
843 int *hcoli = fact->xecadr;
844 double *dluval = fact->xeeadr;
845 int *mrstrt = fact->xrsadr;
846 int *hrowi = fact->xeradr;
847 int *mcstrt = fact->xcsadr;
848 int *hinrow = fact->xrnadr;
849 int *hincol = fact->xcnadr;
850 int *hpivro = fact->krpadr;
851 int *hpivco = fact->kcpadr;
852 int nnentl = *nnentlp;
853 int nnentu = *nnentup;
854 int storeZero = fact->ndenuc;
855
856 int mkrs[8];
857 double dpivyy[8];
858
859 /* Local variables */
860 int i, j;
861 double d0, dx;
862 int nz, ndo, krs;
863 int kend, jcol;
864 int irow, iput, jrow, krxs;
865 int mjcol[8];
866 double pivot;
867 int count;
868 int ilast, isort;
869 double dpivx, dsave;
870 double dpivxx[8];
871 double multip;
872 int lstart, ndense, krlast, kcount, idense, ipivot,
873 jdense, kchunk, jpivot;
874
875 const int nrow = fact->nrow;
876
877 int irtcod = 0;
878
879 lstart = nnetas - nnentl + 1;
880
881 /* put list of columns in last HROWI */
882 /* fix row order once for all */
883 ndense = nrow - fact->npivots;
884 iput = ndense + 1;
885 for (i = 1; i <= nrow; ++i) {
886 if (hpivro[i] > 0) {
887 irow = hpivro[i];
888 for (j = 1; j <= nrow; ++j) {
889 --iput;
890 maction[iput] = irow;
891 irow = rlink[irow].suc;
892 if (irow == 0) {
893 break;
894 }
895 }
896 }
897 }
898 if (iput != 1) {
899 ++(*nsingp);
900 } else {
901 /* Use HCOLI just for last row */
902 ilast = maction[1];
903 krlast = mrstrt[ilast];
904 /* put list of columns in last HCOLI */
905 iput = 0;
906 for (i = 1; i <= nrow; ++i) {
907 if (clink[i].pre >= 0) {
908 hcoli[krlast + iput] = i;
909 ++iput;
910 }
911 }
912 if (iput != ndense) {
913 ++(*nsingp);
914 } else {
915 ndo = ndense / 8;
916 /* do most */
917 for (kcount = 1; kcount <= ndo; ++kcount) {
918 idense = ndense;
919 isort = 8;
920 for (count = ndense; count >= ndense - 7; --count) {
921 ipivot = maction[count];
922 krs = mrstrt[ipivot];
923 --isort;
924 mkrs[isort] = krs;
925 }
926 isort = 8;
927 for (count = ndense; count >= ndense - 7; --count) {
928 /* Find a pivot element */
929 --isort;
930 ipivot = maction[count];
931 krs = mkrs[isort];
932 jcol = c_ekkidmx(idense, &dluval[krs]) - 1;
933 pivot = dluval[krs + jcol];
934 --idense;
935 mcol[count] = jcol;
936 mjcol[isort] = mcol[count];
937 dluval[krs + jcol] = dluval[krs + idense];
938 if (fabs(pivot) < fact->zeroTolerance) {
939 pivot = 0.;
940 dpivx = 0.;
941 } else {
942 dpivx = 1. / pivot;
943 }
944 dluval[krs + idense] = pivot;
945 dpivxx[isort] = dpivx;
946 for (j = isort - 1; j >= 0; --j) {
947 krxs = mkrs[j];
948 multip = -dluval[krxs + jcol] * dpivx;
949 dluval[krxs + jcol] = dluval[krxs + idense];
950 /* for moment skip if zero */
951 if (fabs(multip) > fact->zeroTolerance) {
952 for (i = 0; i < idense; ++i) {
953 dluval[krxs + i] += multip * dluval[krs + i];
954 }
955 } else {
956 multip = 0.;
957 }
958 dluval[krxs + idense] = multip;
959 }
960 }
961 /* sort all U in rows already done */
962 for (i = 7; i >= 0; --i) {
963 /* **** this is important bit */
964 krs = mkrs[i];
965 for (j = i - 1; j >= 0; --j) {
966 jcol = mjcol[j];
967 dsave = dluval[krs + jcol];
968 dluval[krs + jcol] = dluval[krs + idense + j];
969 dluval[krs + idense + j] = dsave;
970 }
971 }
972 /* leave IDENSE as it is */
973 if (ndense <= 400) {
974 for (jrow = ndense - 8; jrow >= 1; --jrow) {
975 irow = maction[jrow];
976 krxs = mrstrt[irow];
977 for (j = 7; j >= 0; --j) {
978 jcol = mjcol[j];
979 dsave = dluval[krxs + jcol];
980 dluval[krxs + jcol] = dluval[krxs + idense + j];
981 dluval[krxs + idense + j] = dsave;
982 }
983 for (j = 7; j >= 0; --j) {
984 krs = mkrs[j];
985 jdense = idense + j;
986 dpivx = dpivxx[j];
987 multip = -dluval[krxs + jdense] * dpivx;
988 if (fabs(multip) <= fact->zeroTolerance) {
989 multip = 0.;
990 }
991 dpivyy[j] = multip;
992 dluval[krxs + jdense] = multip;
993 for (i = idense; i < jdense; ++i) {
994 dluval[krxs + i] += multip * dluval[krs + i];
995 }
996 }
997 for (i = 0; i < idense; ++i) {
998 dx = dluval[krxs + i];
999 d0 = dpivyy[0] * dluval[mkrs[0] + i];
1000 dx += dpivyy[1] * dluval[mkrs[1] + i];
1001 d0 += dpivyy[2] * dluval[mkrs[2] + i];
1002 dx += dpivyy[3] * dluval[mkrs[3] + i];
1003 d0 += dpivyy[4] * dluval[mkrs[4] + i];
1004 dx += dpivyy[5] * dluval[mkrs[5] + i];
1005 d0 += dpivyy[6] * dluval[mkrs[6] + i];
1006 dx += dpivyy[7] * dluval[mkrs[7] + i];
1007 dluval[krxs + i] = d0 + dx;
1008 }
1009 }
1010 } else {
1011 for (jrow = ndense - 8; jrow >= 1; --jrow) {
1012 irow = maction[jrow];
1013 krxs = mrstrt[irow];
1014 for (j = 7; j >= 0; --j) {
1015 jcol = mjcol[j];
1016 dsave = dluval[krxs + jcol];
1017 dluval[krxs + jcol] = dluval[krxs + idense + j];
1018 dluval[krxs + idense + j] = dsave;
1019 }
1020 for (j = 7; j >= 0; --j) {
1021 krs = mkrs[j];
1022 jdense = idense + j;
1023 dpivx = dpivxx[j];
1024 multip = -dluval[krxs + jdense] * dpivx;
1025 if (fabs(multip) <= fact->zeroTolerance) {
1026 multip = 0.;
1027 }
1028 dluval[krxs + jdense] = multip;
1029 for (i = idense; i < jdense; ++i) {
1030 dluval[krxs + i] += multip * dluval[krs + i];
1031 }
1032 }
1033 }
1034 for (kchunk = 0; kchunk < idense; kchunk += 400) {
1035 kend = CoinMin(idense - 1, kchunk + 399);
1036 for (jrow = ndense - 8; jrow >= 1; --jrow) {
1037 irow = maction[jrow];
1038 krxs = mrstrt[irow];
1039 for (j = 7; j >= 0; --j) {
1040 dpivyy[j] = dluval[krxs + idense + j];
1041 }
1042 for (i = kchunk; i <= kend; ++i) {
1043 dx = dluval[krxs + i];
1044 d0 = dpivyy[0] * dluval[mkrs[0] + i];
1045 dx += dpivyy[1] * dluval[mkrs[1] + i];
1046 d0 += dpivyy[2] * dluval[mkrs[2] + i];
1047 dx += dpivyy[3] * dluval[mkrs[3] + i];
1048 d0 += dpivyy[4] * dluval[mkrs[4] + i];
1049 dx += dpivyy[5] * dluval[mkrs[5] + i];
1050 d0 += dpivyy[6] * dluval[mkrs[6] + i];
1051 dx += dpivyy[7] * dluval[mkrs[7] + i];
1052 dluval[krxs + i] = d0 + dx;
1053 }
1054 }
1055 }
1056 }
1057 /* resort all U in rows already done */
1058 for (i = 7; i >= 0; --i) {
1059 krs = mkrs[i];
1060 for (j = 0; j < i; ++j) {
1061 jcol = mjcol[j];
1062 dsave = dluval[krs + jcol];
1063 dluval[krs + jcol] = dluval[krs + idense + j];
1064 dluval[krs + idense + j] = dsave;
1065 }
1066 }
1067 ndense += -8;
1068 }
1069 idense = ndense;
1070 /* do remainder */
1071 for (count = ndense; count >= 1; --count) {
1072 /* Find a pivot element */
1073 ipivot = maction[count];
1074 krs = mrstrt[ipivot];
1075 jcol = c_ekkidmx(idense, &dluval[krs]) - 1;
1076 pivot = dluval[krs + jcol];
1077 --idense;
1078 mcol[count] = jcol;
1079 dluval[krs + jcol] = dluval[krs + idense];
1080 if (fabs(pivot) < fact->zeroTolerance) {
1081 dluval[krs + idense] = 0.;
1082 } else {
1083 dpivx = 1. / pivot;
1084 dluval[krs + idense] = pivot;
1085 for (jrow = idense; jrow >= 1; --jrow) {
1086 irow = maction[jrow];
1087 krxs = mrstrt[irow];
1088 multip = -dluval[krxs + jcol] * dpivx;
1089 dluval[krxs + jcol] = dluval[krxs + idense];
1090 /* for moment skip if zero */
1091 if (fabs(multip) > fact->zeroTolerance) {
1092 dluval[krxs + idense] = multip;
1093 for (i = 0; i < idense; ++i) {
1094 dluval[krxs + i] += multip * dluval[krs + i];
1095 }
1096 } else {
1097 dluval[krxs + idense] = 0.;
1098 }
1099 }
1100 }
1101 }
1102 /* now create in form for OSL */
1103 ndense = nrow - fact->npivots;
1104 idense = ndense;
1105 for (count = ndense; count >= 1; --count) {
1106 /* Find a pivot element */
1107 ipivot = maction[count];
1108 krs = mrstrt[ipivot];
1109 --idense;
1110 jcol = mcol[count];
1111 jpivot = hcoli[krlast + jcol];
1112 ++fact->npivots;
1113 pivot = dluval[krs + idense];
1114 if (pivot == 0.) {
1115 hinrow[ipivot] = 0;
1116 rlink[ipivot].pre = -nrow - 1;
1117 ++(*nsingp);
1118 irtcod = 10;
1119 } else {
1120 rlink[ipivot].pre = -fact->npivots;
1121 clink[jpivot].pre = -fact->npivots;
1122 hincol[jpivot] = 0;
1123 ++fact->xnetal;
1124 mcstrt[fact->xnetal] = lstart - 1;
1125 hpivco[fact->xnetal] = ipivot;
1126 for (jrow = idense; jrow >= 1; --jrow) {
1127 irow = maction[jrow];
1128 krxs = mrstrt[irow];
1129 multip = dluval[krxs + idense];
1130 /* for moment skip if zero */
1131 if (multip != 0. || storeZero) {
1132 /* Store elementary row transformation */
1133 ++nnentl;
1134 --nnentu;
1135 --lstart;
1136 dluval[lstart] = multip;
1137 hrowi[lstart] = SHIFT_INDEX(irow);
1138 }
1139 }
1140 hcoli[krlast + jcol] = hcoli[krlast + idense];
1141 /* update pivot row and last row HCOLI */
1142 dluval[krs + idense] = dluval[krs];
1143 hcoli[krlast + idense] = hcoli[krlast];
1144 nz = 1;
1145 dluval[krs] = pivot;
1146 hcoli[krs] = jpivot;
1147 if (!storeZero) {
1148 for (i = 1; i <= idense; ++i) {
1149 if (fabs(dluval[krs + i]) > fact->zeroTolerance) {
1150 ++nz;
1151 hcoli[krs + nz - 1] = hcoli[krlast + i];
1152 dluval[krs + nz - 1] = dluval[krs + i];
1153 }
1154 }
1155 hinrow[ipivot] = nz;
1156 } else {
1157 for (i = 1; i <= idense; ++i) {
1158 ++nz;
1159 hcoli[krs + nz - 1] = hcoli[krlast + i];
1160 dluval[krs + nz - 1] = dluval[krs + i];
1161 }
1162 hinrow[ipivot] = nz;
1163 }
1164 }
1165 }
1166 }
1167 }
1168
1169 *nnentlp = nnentl;
1170 *nnentup = nnentu;
1171
1172 return (irtcod);
1173 } /* c_ekkcmfd */
1174 /* ***C_EKKCMFC */
1175
1176 /*
1177 * Generate a variant of c_ekkcmfc that uses an maction array of type
1178 * int rather than short.
1179 */
1180 #undef MACTION_T
1181 #define C_EKKCMFY
1182 #define COIN_OSL_CMFC
1183 #define MACTION_T int
c_ekkcmfy(EKKfactinfo * fact,EKKHlink * rlink,EKKHlink * clink,EKKHlink * mwork,void * maction_void,int nnetas,int * nsingp,int * xrejctp,int * xnewrop,int xnewco,int * ncompactionsp)1184 int c_ekkcmfy(EKKfactinfo *fact,
1185 EKKHlink *rlink, EKKHlink *clink,
1186 EKKHlink *mwork, void *maction_void,
1187 int nnetas,
1188 int *nsingp, int *xrejctp,
1189 int *xnewrop, int xnewco,
1190 int *ncompactionsp)
1191
1192 #include "CoinOslC.h"
1193 #undef COIN_OSL_CMFC
1194 #undef C_EKKCMFY
1195 #undef MACTION_T
1196 int c_ekkford(const EKKfactinfo *fact, const int *hinrow, const int *hincol,
1197 int *hpivro, int *hpivco,
1198 EKKHlink *rlink, EKKHlink *clink)
1199 {
1200 int i, iri, nzi;
1201 const int nrow = fact->nrow;
1202 int nsing = 0;
1203
1204 /* Uwe H. Suhl, August 1986 */
1205 /* Builds linked lists of rows and cols of nucleus for efficient */
1206 /* pivot searching. */
1207
1208 memset(hpivro + 1, 0, nrow * sizeof(int));
1209 memset(hpivco + 1, 0, nrow * sizeof(int));
1210 for (i = 1; i <= nrow; ++i) {
1211 //hpivro[i] = 0;
1212 //hpivco[i] = 0;
1213 assert(rlink[i].suc == 0);
1214 assert(clink[i].suc == 0);
1215 }
1216
1217 /* Generate double linked list of rows having equal numbers of */
1218 /* nonzeros in each row. Skip pivotal rows. */
1219 for (i = 1; i <= nrow; ++i) {
1220 if (!(rlink[i].pre < 0)) {
1221 nzi = hinrow[i];
1222 if (nzi <= 0) {
1223 ++nsing;
1224 rlink[i].pre = -nrow - 1;
1225 } else {
1226 iri = hpivro[nzi];
1227 hpivro[nzi] = i;
1228 rlink[i].suc = iri;
1229 rlink[i].pre = 0;
1230 if (iri != 0) {
1231 rlink[iri].pre = i;
1232 }
1233 }
1234 }
1235 }
1236
1237 /* Generate double linked list of cols having equal numbers of */
1238 /* nonzeros in each col. Skip pivotal cols. */
1239 for (i = 1; i <= nrow; ++i) {
1240 if (!(clink[i].pre < 0)) {
1241 nzi = hincol[i];
1242 if (nzi <= 0) {
1243 ++nsing;
1244 clink[i].pre = -nrow - 1;
1245 } else {
1246 iri = hpivco[nzi];
1247 hpivco[nzi] = i;
1248 clink[i].suc = iri;
1249 clink[i].pre = 0;
1250 if (iri != 0) {
1251 clink[iri].pre = i;
1252 }
1253 }
1254 }
1255 }
1256
1257 return (nsing);
1258 } /* c_ekkford */
1259
1260 /* c version of OSL from 36100 */
1261
1262 /* Assumes that a basis exists in correct form */
1263 /* Calls Uwe's routines (approximately) */
1264 /* Then if OK shuffles U into column order */
1265 /* Return codes: */
1266
1267 /* 0: everything ok */
1268 /* 1: everything ok but performance would be better if more space */
1269 /* would be make available */
1270 /* 4: growth rate of element in U too big */
1271 /* 5: not enough space in row file */
1272 /* 6: not enough space in column file */
1273 /* 7: pivot too small - col sing */
1274 /* 8: pivot too small - row sing */
1275 /* 10: matrix is singular */
1276
1277 /* I suspect c_ekklfct never returns 1 */
1278 /*
1279 * layout of data
1280 *
1281 * dluval/hcoli: (L^-1)B - hole - L factors
1282 *
1283 * The L factors are written from high to low, starting from nnetas.
1284 * There are nnentl factors in L. lstart the next entry to use for the
1285 * L factors. Eventually, (L^-1)B turns into U.
1286
1287 * The ninbas coefficients of matrix B are originally in the start of
1288 * dluval/hcoli. As L transforms it, rows may have to be expanded.
1289 * If there is room, they are copied to the start of the hole,
1290 * otherwise the first part of this area is compacted, and hopefully
1291 * there is then room.
1292 * There are nnentu coefficients in (L^-1)B.
1293 * nnentu + nnentl >= ninbas.
1294 * nnentu + nnentl == ninbas if there has been no fill-in.
1295 * nnentu is decreased when the pivot eliminates elements
1296 * (in which case there is a corresponding increase in nnentl),
1297 * and if pivoting happens to cancel out factors (in which case
1298 * there is no corresponding increase in L).
1299 * nnentu is increased if there is fill-in (no decrease in L).
1300 * If nnentu + nnentl >= nnetas, then we've run out of room.
1301 * It is not the case that the elements of (L^-1)B are all in the
1302 * first nnentu positions of dluval/hcoli, but that is of course
1303 * the lower bound on the number of positions needed to store it.
1304 * nuspik is roughly the sum of the row lengths of the rows that were pivoted
1305 * out. singleton rows in c_ekktria do not change nuspik, but
1306 * c_ekkrsin does increment it for each singleton row.
1307 * That is, there are nuspik elements that in the upper part of (L^-1)B,
1308 * and (nnentu - nuspik) elements left in B.
1309 */
1310 /*
1311 * As part of factorization, we test candidate pivots for numerical
1312 * stability; if the largest element in a row/col is much larger than
1313 * the smallest, this generally causes problems. To easily determine
1314 * what the largest element is, we ensure that it is always in front.
1315 * This establishes this property; later on we take steps to preserve it.
1316 */
c_ekkmltf(const EKKfactinfo * fact,double * dluval,int * hcoli,const int * mrstrt,const int * hinrow,const EKKHlink * rlink)1317 static void c_ekkmltf(const EKKfactinfo *fact, double *dluval, int *hcoli,
1318 const int *mrstrt, const int *hinrow,
1319 const EKKHlink *rlink)
1320 {
1321 #if 0
1322 int *hcoli = fact->xecadr;
1323 double *dluval = fact->xeeadr;
1324 double *dvalpv = fact->kw3adr;
1325 int *mrstrt = fact->xrsadr;
1326 int *hrowi = fact->xeradr;
1327 int *mcstrt = fact->xcsadr;
1328 int *hinrow = fact->xrnadr;
1329 int *hincol = fact->xcnadr;
1330 int *hpivro = fact->krpadr;
1331 int *hpivco = fact->kcpadr;
1332 #endif
1333 int i, j, k;
1334 int koff = -1;
1335 const int nrow = fact->nrow;
1336
1337 for (i = 1; i <= nrow; ++i) {
1338 /* ignore rows that have already been pivoted */
1339 /* if it is a singleton row, the property trivially holds */
1340 if (!(rlink[i].pre < 0 || hinrow[i] <= 1)) {
1341 const int krs = mrstrt[i];
1342 const int kre = krs + hinrow[i] - 1;
1343
1344 double maxaij = 0.f;
1345
1346 /* this assumes that at least one of the dluvals is non-zero. */
1347 for (k = krs; k <= kre; ++k) {
1348 if (!(fabs(dluval[k]) <= maxaij)) {
1349 maxaij = fabs(dluval[k]);
1350 koff = k;
1351 }
1352 }
1353 assert(koff > 0);
1354 maxaij = dluval[koff];
1355 j = hcoli[koff];
1356
1357 dluval[koff] = dluval[krs];
1358 hcoli[koff] = hcoli[krs];
1359
1360 dluval[krs] = maxaij;
1361 hcoli[krs] = j;
1362 }
1363 }
1364 } /* c_ekkmltf */
c_ekklfct(register EKKfactinfo * fact)1365 int c_ekklfct(register EKKfactinfo *fact)
1366 {
1367 const int nrow = fact->nrow;
1368 int ninbas = fact->xcsadr[nrow + 1] - 1;
1369 int ifvsol = fact->ifvsol;
1370 int *hcoli = fact->xecadr;
1371 double *dluval = fact->xeeadr;
1372 int *mrstrt = fact->xrsadr;
1373 int *hrowi = fact->xeradr;
1374 int *mcstrt = fact->xcsadr;
1375 int *hinrow = fact->xrnadr;
1376 int *hincol = fact->xcnadr;
1377 int *hpivro = fact->krpadr;
1378 int *hpivco = fact->kcpadr;
1379
1380 EKKHlink *rlink = fact->kp1adr;
1381 EKKHlink *clink = fact->kp2adr;
1382 EKKHlink *mwork = (reinterpret_cast< EKKHlink * >(fact->kw1adr)) - 1;
1383
1384 int nsing, kdnspt, xnewro, xnewco;
1385 int i;
1386 int xrejct;
1387 int irtcod;
1388 const int nnetas = fact->nnetas;
1389
1390 int ncompactions;
1391 double save_drtpiv = fact->drtpiv;
1392 double save_zpivlu = fact->zpivlu;
1393 if (ifvsol > 0 && fact->invok < 0) {
1394 fact->zpivlu = CoinMin(0.9, fact->zpivlu * 10.);
1395 fact->drtpiv = 1.0e-8;
1396 }
1397
1398 rlink--;
1399 clink--;
1400
1401 /* Function Body */
1402 hcoli[nnetas] = 1;
1403 hrowi[nnetas] = 1;
1404 dluval[nnetas] = 0.0;
1405 /* set amount of work */
1406 xrejct = 0;
1407 nsing = 0;
1408 kdnspt = nnetas + 1;
1409 fact->ndenuc = 0;
1410 /* Triangularize */
1411 irtcod = c_ekktria(fact, rlink, clink,
1412 &nsing,
1413 &xnewco, &xnewro,
1414 &ncompactions, ninbas);
1415 fact->nnentl = ninbas - fact->nnentu;
1416
1417 if (irtcod < 0) {
1418 /* no space or system error */
1419 goto L8000;
1420 }
1421
1422 if (irtcod != 0 && fact->invok >= 0) {
1423 goto L8500; /* 7 or 8 - pivot too small */
1424 }
1425 #if 0
1426 /* is this necessary ? */
1427 lstart = nnetas - fact->nnentl + 1;
1428 for (i = lstart; i <= nnetas; ++i) {
1429 hrowi[i] = (hcoli[i] << 3);
1430 }
1431 #endif
1432
1433 /* See if finished */
1434 if (!(fact->npivots >= nrow)) {
1435 int nsing1;
1436
1437 /* No - do nucleus */
1438
1439 nsing1 = c_ekkford(fact, hinrow, hincol, hpivro, hpivco, rlink, clink);
1440 nsing += nsing1;
1441 if (nsing1 != 0 && fact->invok >= 0) {
1442 irtcod = 7;
1443 goto L8500;
1444 }
1445 c_ekkmltf(fact, dluval, hcoli, mrstrt, hinrow, rlink);
1446
1447 {
1448 bool callcmfy = false;
1449
1450 if (nrow > 32767) {
1451 int count = 0;
1452 for (i = 1; i <= nrow; ++i) {
1453 count = CoinMax(count, hinrow[i]);
1454 }
1455 if (count + nrow - fact->npivots > 32767) {
1456 /* will have to use I*4 version of CMFC */
1457 /* no changes to pointer params */
1458 callcmfy = true;
1459 }
1460 }
1461
1462 irtcod = (callcmfy ? c_ekkcmfy : c_ekkcmfc)(fact,
1463 rlink, clink,
1464 mwork, &mwork[nrow + 1],
1465 nnetas,
1466 &nsing, &xrejct,
1467 &xnewro, xnewco,
1468 &ncompactions);
1469
1470 /* irtcod one of 0,-5,7,10 */
1471 }
1472
1473 if (irtcod < 0) {
1474 goto L8000;
1475 }
1476 kdnspt = nnetas - fact->nnentl;
1477 }
1478
1479 /* return if error */
1480 if (nsing > 0 || irtcod == 10) {
1481 irtcod = 99;
1482 }
1483 /* irtcod one of 0,7,99 */
1484
1485 if (irtcod != 0) {
1486 goto L8500;
1487 }
1488 ++fact->xnetal;
1489 mcstrt[fact->xnetal] = nnetas - fact->nnentl;
1490
1491 /* give message if tight on memory */
1492 if (ncompactions > 2) {
1493 if (1) {
1494 int etasize = CoinMax(4 * fact->nnentu + (nnetas - fact->nnentl) + 1000, fact->eta_size);
1495 fact->eta_size = CoinMin(static_cast< int >(1.2 * fact->eta_size), etasize);
1496 if (fact->maxNNetas > 0 && fact->eta_size > fact->maxNNetas) {
1497 fact->eta_size = fact->maxNNetas;
1498 }
1499 } /* endif */
1500 }
1501 /* Shuffle U and multiply L by 8 (if assembler) */
1502 {
1503 int jrtcod = c_ekkshff(fact, clink, rlink,
1504 xnewro);
1505
1506 /* nR_etas is the number of R transforms;
1507 * it is incremented only in c_ekketsj.
1508 */
1509 fact->nR_etas = 0;
1510 /*fact->R_etas_start = mcstrt+nrow+fact->nnentl+3;*/
1511 fact->R_etas_start[1] = /*kdnspt - 1*/ 0; /* magic */
1512 fact->R_etas_index = &fact->xeradr[kdnspt - 1];
1513 fact->R_etas_element = &fact->xeeadr[kdnspt - 1];
1514
1515 if (jrtcod != 0) {
1516 irtcod = jrtcod;
1517 /* irtcod == 2 */
1518 }
1519 }
1520 goto L8500;
1521
1522 /* Fatal error */
1523 L8000:
1524
1525 if (1) {
1526 if (fact->maxNNetas != fact->eta_size && nnetas) {
1527 /* return and get more space */
1528
1529 /* double eta_size, unless that exceeds max (if there is one) */
1530 fact->eta_size = fact->eta_size << 1;
1531 if (fact->maxNNetas > 0 && fact->eta_size > fact->maxNNetas) {
1532 fact->eta_size = fact->maxNNetas;
1533 }
1534 return (5);
1535 }
1536 }
1537 /*c_ekkmesg_no_i1(121, -irtcod);*/
1538 irtcod = 3;
1539
1540 L8500:
1541 /* restore pivot tolerance */
1542 fact->drtpiv = save_drtpiv;
1543 fact->zpivlu = save_zpivlu;
1544 #ifndef NDEBUG
1545 if (fact->rows_ok) {
1546 int *hinrow = fact->xrnadr;
1547 if (!fact->xe2adr) {
1548 for (int i = 1; i <= fact->nrow; i++) {
1549 assert(hinrow[i] >= 0 && hinrow[i] <= fact->nrow);
1550 }
1551 }
1552 }
1553 #endif
1554 return (irtcod);
1555 } /* c_ekklfct */
1556
1557 /*
1558 summary of return codes
1559
1560 c_ekktria:
1561 7 small pivot
1562 -5 no memory
1563
1564 c_ekkcsin:
1565 returns true if small pivot
1566
1567 c_ekkrsin:
1568 -5 no memory
1569 7 small pivot
1570
1571 c_ekkfpvt:
1572 10: no pivots found (singular)
1573
1574 c_ekkcmfd:
1575 10: zero pivot (not just small)
1576
1577 c_ekkcmfc:
1578 -5: no memory
1579 any non-zero code from c_ekkcsin, c_ekkrsin, c_ekkfpvt, c_ekkprpv, c_ekkcmfd
1580
1581 c_ekkshff:
1582 2: singular
1583
1584 c_ekklfct:
1585 any positive code from c_ekktria, c_ekkcmfc, c_ekkshff (2,7,10)
1586 *except* 10, which is changed to 99.
1587 all negative return codes are changed to 5 or 3
1588 (5 == ran out of memory but could get more,
1589 3 == ran out of memory, no luck)
1590 so: 2,3,5,7,99
1591
1592 c_ekklfct1:
1593 1: c_ekksmem_invert failed
1594 2: c_ekkslcf/c_ekkslct ran out of room
1595 any return code from c_ekklfct, except 2 and 5
1596 */
1597
c_ekkrowq(int * hrow,int * hcol,double * dels,int * mrstrt,const int * hinrow,int nnrow,int ninbas)1598 void c_ekkrowq(int *hrow, int *hcol, double *dels,
1599 int *mrstrt,
1600 const int *hinrow, int nnrow, int ninbas)
1601 {
1602 int i, k, iak, jak;
1603 double daik;
1604 int iloc;
1605 double dsave;
1606 int isave, jsave;
1607
1608 /* Order matrix rowwise using MRSTRT, DELS, HCOL */
1609
1610 k = 1;
1611 /* POSITION AFTER END OF ROW */
1612 for (i = 1; i <= nnrow; ++i) {
1613 k += hinrow[i];
1614 mrstrt[i] = k;
1615 }
1616
1617 for (k = ninbas; k >= 1; --k) {
1618 iak = hrow[k];
1619 if (iak != 0) {
1620 daik = dels[k];
1621 jak = hcol[k];
1622 hrow[k] = 0;
1623 while (1) {
1624 --mrstrt[iak];
1625
1626 iloc = mrstrt[iak];
1627
1628 dsave = dels[iloc];
1629 isave = hrow[iloc];
1630 jsave = hcol[iloc];
1631 dels[iloc] = daik;
1632 hrow[iloc] = 0;
1633 hcol[iloc] = jak;
1634
1635 if (isave == 0)
1636 break;
1637 daik = dsave;
1638 iak = isave;
1639 jak = jsave;
1640 }
1641 }
1642 }
1643 } /* c_ekkrowq */
1644
c_ekkrwco(const EKKfactinfo * fact,double * dluval,int * hcoli,int * mrstrt,int * hinrow,int xnewro)1645 int c_ekkrwco(const EKKfactinfo *fact, double *dluval,
1646 int *hcoli, int *mrstrt, int *hinrow, int xnewro)
1647 {
1648 int i, k, nz, kold;
1649 int kstart;
1650 const int nrow = fact->nrow;
1651
1652 for (i = 1; i <= nrow; ++i) {
1653 nz = hinrow[i];
1654 if (0 < nz) {
1655 /* save the last column entry of row i in hinrow */
1656 /* and replace that entry with -i */
1657 k = mrstrt[i] + nz - 1;
1658 hinrow[i] = hcoli[k];
1659 hcoli[k] = -i;
1660 }
1661 }
1662
1663 kstart = 0;
1664 kold = 0;
1665 for (k = 1; k <= xnewro; ++k) {
1666 if (hcoli[k] != 0) {
1667 ++kstart;
1668
1669 /* if this is the last entry for the row... */
1670 if (hcoli[k] < 0) {
1671 /* restore the entry */
1672 i = -hcoli[k];
1673 hcoli[k] = hinrow[i];
1674
1675 /* update mrstart and hinrow */
1676 /* ACTUALLY, hinrow should already be accurate */
1677 mrstrt[i] = kold + 1;
1678 hinrow[i] = kstart - kold;
1679 kold = kstart;
1680 }
1681
1682 /* move the entry */
1683 dluval[kstart] = dluval[k];
1684 hcoli[kstart] = hcoli[k];
1685 }
1686 }
1687
1688 return (kstart);
1689 } /* c_ekkrwco */
1690
c_ekkrwcs(const EKKfactinfo * fact,double * dluval,int * hcoli,int * mrstrt,const int * hinrow,const EKKHlink * mwork,int nfirst)1691 int c_ekkrwcs(const EKKfactinfo *fact, double *dluval, int *hcoli, int *mrstrt,
1692 const int *hinrow, const EKKHlink *mwork,
1693 int nfirst)
1694 {
1695 #if 0
1696 int *hcoli = fact->xecadr;
1697 double *dluval = fact->xeeadr;
1698 double *dvalpv = fact->kw3adr;
1699 int *mrstrt = fact->xrsadr;
1700 int *hrowi = fact->xeradr;
1701 int *mcstrt = fact->xcsadr;
1702 int *hinrow = fact->xrnadr;
1703 int *hincol = fact->xcnadr;
1704 int *hpivro = fact->krpadr;
1705 int *hpivco = fact->kcpadr;
1706 #endif
1707 int i, k, k1, k2, nz;
1708 int irow, iput;
1709 const int nrow = fact->nrow;
1710
1711 /* Compress row file */
1712
1713 iput = 1;
1714 irow = nfirst;
1715 for (i = 1; i <= nrow; ++i) {
1716 nz = hinrow[irow];
1717 k1 = mrstrt[irow];
1718 if (k1 != iput) {
1719 mrstrt[irow] = iput;
1720 k2 = k1 + nz - 1;
1721 for (k = k1; k <= k2; ++k) {
1722 dluval[iput] = dluval[k];
1723 hcoli[iput] = hcoli[k];
1724 ++iput;
1725 }
1726 } else {
1727 iput += nz;
1728 }
1729 irow = mwork[irow].suc;
1730 }
1731
1732 return (iput);
1733 } /* c_ekkrwcs */
c_ekkrwct(const EKKfactinfo * fact,double * dluval,int * hcoli,int * mrstrt,const int * hinrow,const EKKHlink * mwork,const EKKHlink * rlink,const short * msort,double * dsort,int nlast,int xnewro)1734 void c_ekkrwct(const EKKfactinfo *fact, double *dluval, int *hcoli, int *mrstrt,
1735 const int *hinrow, const EKKHlink *mwork,
1736 const EKKHlink *rlink,
1737 const short *msort, double *dsort,
1738 int nlast, int xnewro)
1739 {
1740 #if 0
1741 int *hcoli = fact->xecadr;
1742 double *dluval = fact->xeeadr;
1743 double *dvalpv = fact->kw3adr;
1744 int *mrstrt = fact->xrsadr;
1745 int *hrowi = fact->xeradr;
1746 int *mcstrt = fact->xcsadr;
1747 int *hinrow = fact->xrnadr;
1748 int *hincol = fact->xcnadr;
1749 int *hpivro = fact->krpadr;
1750 int *hpivco = fact->kcpadr;
1751 #endif
1752 int i, k, k1, nz, icol;
1753 int kmax;
1754 int irow, iput;
1755 int ilook;
1756 const int nrow = fact->nrow;
1757
1758 iput = xnewro;
1759 irow = nlast;
1760 kmax = nrow - fact->npivots;
1761 for (i = 1; i <= nrow; ++i) {
1762 nz = hinrow[irow];
1763 k1 = mrstrt[irow] - 1;
1764 if (rlink[irow].pre < 0) {
1765 /* pivoted on already */
1766 iput -= nz;
1767 if (k1 != iput) {
1768 mrstrt[irow] = iput + 1;
1769 for (k = nz; k >= 1; --k) {
1770 dluval[iput + k] = dluval[k1 + k];
1771 hcoli[iput + k] = hcoli[k1 + k];
1772 }
1773 }
1774 } else {
1775 /* not pivoted - going dense */
1776 iput -= kmax;
1777 mrstrt[irow] = iput + 1;
1778 c_ekkdzero(kmax, &dsort[1]);
1779 for (k = 1; k <= nz; ++k) {
1780 icol = hcoli[k1 + k];
1781 ilook = msort[icol];
1782 dsort[ilook] = dluval[k1 + k];
1783 }
1784 c_ekkdcpy(kmax,
1785 (dsort + 1), (dluval + iput + 1));
1786 }
1787 irow = mwork[irow].pre;
1788 }
1789 } /* c_ekkrwct */
1790 /* takes Uwe's modern structures and puts them back 20 years */
c_ekkshff(EKKfactinfo * fact,EKKHlink * clink,EKKHlink * rlink,int xnewro)1791 int c_ekkshff(EKKfactinfo *fact,
1792 EKKHlink *clink, EKKHlink *rlink,
1793 int xnewro)
1794 {
1795 int *hpivro = fact->krpadr;
1796
1797 int i, j;
1798 int nbas, icol;
1799 int ipiv;
1800 const int nrow = fact->nrow;
1801 int nsing;
1802
1803 for (i = 1; i <= nrow; ++i) {
1804 j = -rlink[i].pre;
1805 rlink[i].pre = j;
1806 if (j > 0 && j <= nrow) {
1807 hpivro[j] = i;
1808 }
1809 j = -clink[i].pre;
1810 clink[i].pre = j;
1811 }
1812 /* hpivro[j] is now (hopefully) the row that was pivoted on step j */
1813 /* rlink[i].pre is the step in which row i was pivoted */
1814
1815 nbas = 0;
1816 nsing = 0;
1817 /* Decide if permutation wanted */
1818 fact->first_dense = nrow - fact->ndenuc + 1 + 1;
1819 fact->last_dense = nrow;
1820
1821 /* rlink[].suc is dead at this point */
1822
1823 /*
1824 * replace the the basis index
1825 * with the pivot (or permuted) index generated by factorization.
1826 * This eventually goes into mpermu.
1827 */
1828 for (icol = 1; icol <= nrow; ++icol) {
1829 int ibasis = icol;
1830 ipiv = clink[ibasis].pre;
1831
1832 if (0 < ipiv && ipiv <= nrow) {
1833 rlink[ibasis].suc = ipiv;
1834 ++nbas;
1835 }
1836 }
1837
1838 nsing = nrow - nbas;
1839 if (nsing > 0) {
1840 abort();
1841 }
1842
1843 /* if we reach here, then rlink[1..nrow].suc == clink[1..nrow].pre */
1844
1845 /* switch off sparse update if any dense section */
1846 {
1847 const int notMuchRoom = (fact->nnentu + xnewro + 10 > fact->nnetas - fact->nnentl);
1848
1849 /* must be same as in c_ekkshfv */
1850 if (fact->ndenuc || notMuchRoom || nrow < C_EKK_GO_SPARSE) {
1851 #if PRINT_DEBUG
1852 if (fact->if_sparse_update) {
1853 printf("**** Switching off sparse update - dense - c_ekkshff\n");
1854 }
1855 #endif
1856 fact->if_sparse_update = 0;
1857 }
1858 }
1859
1860 /* hpivro[1..nrow] is not read by c_ekkshfv */
1861 c_ekkshfv(fact,
1862 rlink, clink,
1863 xnewro);
1864
1865 return (0);
1866 } /* c_ekkshff */
1867 /* sorts on indices dragging elements with */
c_ekk_sort2(int * key,double * array2,int number)1868 static void c_ekk_sort2(int *key, double *array2, int number)
1869 {
1870 int minsize = 10;
1871 int n = number;
1872 int sp;
1873 int *v = key;
1874 int *m, t;
1875 int *ls[32], *rs[32];
1876 int *l, *r, c;
1877 double it;
1878 int j;
1879 /*check already sorted */
1880 int last = INT_MIN;
1881 for (j = 0; j < number; j++) {
1882 if (key[j] >= last) {
1883 last = key[j];
1884 } else {
1885 break;
1886 } /* endif */
1887 } /* endfor */
1888 if (j == number) {
1889 return;
1890 } /* endif */
1891 sp = 0;
1892 ls[sp] = v;
1893 rs[sp] = v + (n - 1);
1894 while (sp >= 0) {
1895 if (rs[sp] - ls[sp] > minsize) {
1896 l = ls[sp];
1897 r = rs[sp];
1898 m = l + (r - l) / 2;
1899 if (*l > *m) {
1900 t = *l;
1901 *l = *m;
1902 *m = t;
1903 it = array2[l - v];
1904 array2[l - v] = array2[m - v];
1905 array2[m - v] = it;
1906 }
1907 if (*m > *r) {
1908 t = *m;
1909 *m = *r;
1910 *r = t;
1911 it = array2[m - v];
1912 array2[m - v] = array2[r - v];
1913 array2[r - v] = it;
1914 if (*l > *m) {
1915 t = *l;
1916 *l = *m;
1917 *m = t;
1918 it = array2[l - v];
1919 array2[l - v] = array2[m - v];
1920 array2[m - v] = it;
1921 }
1922 }
1923 c = *m;
1924 while (r - l > 1) {
1925 while (*(++l) < c)
1926 ;
1927 while (*(--r) > c)
1928 ;
1929 t = *l;
1930 *l = *r;
1931 *r = t;
1932 it = array2[l - v];
1933 array2[l - v] = array2[r - v];
1934 array2[r - v] = it;
1935 }
1936 l = r - 1;
1937 if (l < m) {
1938 ls[sp + 1] = ls[sp];
1939 rs[sp + 1] = l;
1940 ls[sp] = r;
1941 } else {
1942 ls[sp + 1] = r;
1943 rs[sp + 1] = rs[sp];
1944 rs[sp] = l;
1945 }
1946 sp++;
1947 } else
1948 sp--;
1949 }
1950 for (l = v, m = v + (n - 1); l < m; l++) {
1951 if (*l > *(l + 1)) {
1952 c = *(l + 1);
1953 it = array2[(l - v) + 1];
1954 for (r = l; r >= v && *r > c; r--) {
1955 *(r + 1) = *r;
1956 array2[(r - v) + 1] = array2[(r - v)];
1957 }
1958 *(r + 1) = c;
1959 array2[(r - v) + 1] = it;
1960 }
1961 }
1962 }
1963 /* For each row compute reciprocal of pivot element and take out of */
1964 /* Also use HLINK(1 to permute column numbers */
1965 /* and HPIVRO to permute row numbers */
1966 /* Sort into column order as was stored by row */
1967 /* If Assembler then shift row numbers in L by 3 */
1968 /* Put column numbers in U for L-U update */
1969 /* and multiply U elements by - reciprocal of pivot element */
1970 /* and set up backward pointers for pivot rows */
c_ekkshfv(EKKfactinfo * fact,EKKHlink * rlink,EKKHlink * clink,int xnewro)1971 void c_ekkshfv(EKKfactinfo *fact,
1972 EKKHlink *rlink, EKKHlink *clink,
1973 int xnewro)
1974 {
1975 int *hcoli = fact->xecadr;
1976 double *dluval = fact->xeeadr;
1977 double *dvalpv = fact->kw3adr;
1978 int *mrstrt = fact->xrsadr;
1979 int *hrowi = fact->xeradr;
1980 int *mcstrt = fact->xcsadr;
1981 int *hinrow = fact->xrnadr;
1982 int *hincol = fact->xcnadr;
1983 int *hpivro = fact->krpadr;
1984 int *hpivco = fact->kcpadr;
1985 double *dpermu = fact->kadrpm;
1986 double *de2val = fact->xe2adr ? fact->xe2adr - 1 : 0;
1987 int nnentu = fact->nnentu;
1988 int xnetal = fact->xnetal;
1989
1990 int numberSlacks; /* numberSlacks not read */
1991
1992 int i, j, k, kk, nel;
1993 int nroom;
1994 bool need_more_space;
1995 int ndenuc = fact->ndenuc;
1996 int if_sparse_update = fact->if_sparse_update;
1997 int nnentl = fact->nnentl;
1998 int nnetas = fact->nnetas;
1999
2000 int *ihlink = (reinterpret_cast< int * >(clink)) + 1; /* can't use rlink for simple loop below */
2001
2002 const int nrow = fact->nrow;
2003 const int maxinv = fact->maxinv;
2004
2005 /* this is not just a temporary - c_ekkbtrn etc use this */
2006 int *mpermu = (reinterpret_cast< int * >(dpermu + nrow)) + 1;
2007
2008 int *temp = ihlink + nrow;
2009 int *temp2 = temp + nrow;
2010 const int notMuchRoom = (nnentu + xnewro + 10 > nnetas - nnentl);
2011
2012 /* compress hlink and make simpler */
2013 for (i = 1; i <= nrow; ++i) {
2014 mpermu[i] = rlink[i].pre;
2015 ihlink[i] = rlink[i].suc;
2016 }
2017 /* mpermu[i] == the step in which row i was pivoted */
2018 /* ihlink[i] == the step in which col i was pivoted */
2019
2020 /* must be same as in c_ekkshff */
2021 if (fact->ndenuc || notMuchRoom || nrow < C_EKK_GO_SPARSE) {
2022 int ninbas;
2023
2024 /* CHANGE COLUMN NUMBERS AND FILL IN RECIPROCALS */
2025 /* ALSO RECOMPUTE NUMBER IN COLUMN */
2026 /* initialize with a fake pivot in each column */
2027 c_ekkscpy_0_1(nrow, 1, &hincol[1]);
2028
2029 if (notMuchRoom) {
2030 fact->eta_size = static_cast< int >(1.05 * fact->eta_size);
2031
2032 /* eta_size can be no larger than maxNNetas */
2033 if (fact->maxNNetas > 0 && fact->eta_size > fact->maxNNetas) {
2034 fact->eta_size = fact->maxNNetas;
2035 }
2036 } /* endif */
2037
2038 /* For each row compute reciprocal of pivot element and take out of U */
2039 /* Also use ihlink to permute column numbers */
2040 /* the rows are not stored compactly or in order,
2041 * so we have to find out where the last one is stored */
2042 ninbas = 0;
2043 for (i = 1; i <= nrow; ++i) {
2044 int jpiv = mpermu[i];
2045 int nin = hinrow[i];
2046 int krs = mrstrt[i];
2047 int kre = krs + nin;
2048
2049 temp[jpiv] = krs;
2050 temp2[jpiv] = nin;
2051
2052 ninbas = CoinMax(kre, ninbas);
2053
2054 /* c_ekktria etc ensure that the first row entry is the pivot */
2055 dvalpv[jpiv] = 1. / dluval[krs];
2056 hcoli[krs] = 0; /* probably needed for c_ekkrowq */
2057 /* room for the pivot has already been allocated, so hincol ok */
2058
2059 for (kk = krs + 1; kk < kre; ++kk) {
2060 int j = ihlink[hcoli[kk]];
2061 hcoli[kk] = j; /* permute the col index */
2062 hrowi[kk] = jpiv; /* permute the row index */
2063 ++hincol[j];
2064 }
2065 }
2066 /* temp [mpermu[i]] == mrstrt[i] */
2067 /* temp2[mpermu[i]] == hinrow[i] */
2068
2069 ninbas--; /* ???? */
2070 c_ekkscpy(nrow, &temp[1], &mrstrt[1]);
2071 c_ekkscpy(nrow, &temp2[1], &hinrow[1]);
2072
2073 /* now mrstrt, hinrow, hcoli and hrowi have been permuted */
2074
2075 /* Sort into column order as was stored by row */
2076 /* There will be an empty entry in front of each each column,
2077 * because we initialized hincol to 1s, and c_ekkrowq fills in
2078 * entries from the back */
2079 c_ekkrowq(hcoli, hrowi, dluval, mcstrt, hincol, nrow, ninbas);
2080
2081 /* The shuffle zeroed out column pointers */
2082 /* Put them back for L-U update */
2083 /* Also multiply U elements by - reciprocal of pivot element */
2084 /* Also decrement mcstrt/hincol to give "real" sizes */
2085 for (i = 1; i <= nrow; ++i) {
2086 int kx = --mcstrt[i];
2087 nel = --hincol[i];
2088 hrowi[kx] = nel;
2089 dluval[kx] = dvalpv[i];
2090 #ifndef NO_SHIFT
2091 for (int j = kx + 1; j <= kx + nel; j++)
2092 hrowi[j] = SHIFT_INDEX(hrowi[j]);
2093 #endif
2094 }
2095
2096 /* sort dense part */
2097 for (i = nrow - ndenuc + 1; i <= nrow; i++) {
2098 int kx = mcstrt[i] + 1; /* "real" entries start after pivot */
2099 int nel = hincol[i];
2100 c_ekk_sort2(&hrowi[kx], &dluval[kx], nel);
2101 }
2102
2103 /* Recompute number in U */
2104 nnentu = mcstrt[nrow] + hincol[nrow];
2105 mcstrt[nrow + 4] = nnentu + 1; /* magic - AND DEAD */
2106
2107 /* as not much room switch off fast etas */
2108 mrstrt[1] = 0; /* magic */
2109 fact->rows_ok = false;
2110 i = nrow + maxinv + 5; /* DEAD */
2111 } else {
2112 /* *************************************** */
2113 /* enough memory to do a bit faster */
2114 /* For each row compute reciprocal of pivot element and */
2115 /* take out of U */
2116 /* Also use HLINK(1 to permute column numbers */
2117 int ninbas = 0;
2118 int ilast; /* last available entry */
2119 int spareSpace;
2120 double *dluval2;
2121 /*int * hlink2 = ihlink+nrow;
2122 int * mrstrt2 = hlink2+nrow;*/
2123 /* mwork has order of row copy */
2124 EKKHlink *mwork = (reinterpret_cast< EKKHlink * >(fact->kw1adr)) - 1;
2125 fact->rows_ok = true;
2126
2127 if (if_sparse_update) {
2128 ilast = nnetas - nnentl;
2129 } else {
2130 /* missing out nnentl stuff */
2131 ilast = nnetas;
2132 }
2133 spareSpace = ilast - nnentu;
2134 need_more_space = false;
2135 /* save clean row copy if enough room */
2136 nroom = (spareSpace) / nrow;
2137 if (nrow < 10000) {
2138 if (nroom < 10) {
2139 need_more_space = true;
2140 }
2141 } else {
2142 if (nroom < 5 && !if_sparse_update) {
2143 need_more_space = true;
2144 }
2145 }
2146 if (nroom > CoinMin(50, maxinv)) {
2147 need_more_space = false;
2148 }
2149 if (need_more_space) {
2150 if (if_sparse_update) {
2151 int i1 = fact->eta_size + 10 * nrow;
2152 fact->eta_size = static_cast< int >(1.2 * fact->eta_size);
2153 if (i1 > fact->eta_size) {
2154 fact->eta_size = i1;
2155 }
2156 } else {
2157 fact->eta_size = static_cast< int >(1.05 * fact->eta_size);
2158 }
2159 } else {
2160 if (nroom < 11) {
2161 if (if_sparse_update) {
2162 int i1 = fact->eta_size + (11 - nroom) * nrow;
2163 fact->eta_size = static_cast< int >(1.2 * fact->eta_size);
2164 if (i1 > fact->eta_size) {
2165 fact->eta_size = i1;
2166 }
2167 }
2168 }
2169 }
2170 if (fact->maxNNetas > 0 && fact->eta_size > fact->maxNNetas) {
2171 fact->eta_size = fact->maxNNetas;
2172 }
2173 {
2174 /* we can swap de2val and dluval to save copying */
2175 int *eta_last = mpermu + nrow * 2 + 3;
2176 int *eta_next = eta_last + nrow + 2;
2177 int last = 0;
2178 eta_last[0] = -1;
2179 if (nnentl) {
2180 /* went into c_ekkcmfc - if not then in order */
2181 int next;
2182 /*next=mwork[((nrow+1)<<1)+1];*/
2183 next = mwork[nrow + 1].pre;
2184 #ifdef DEBUG
2185 j = mrstrt[next];
2186 #endif
2187 for (i = 1; i <= nrow; ++i) {
2188 int iperm = mpermu[next];
2189 eta_next[last] = iperm;
2190 eta_last[iperm] = last;
2191 temp[iperm] = mrstrt[next];
2192 temp2[iperm] = hinrow[next];
2193 #ifdef DEBUG
2194 if (mrstrt[next] != j)
2195 abort();
2196 j = mrstrt[next] + hinrow[next];
2197 #endif
2198 /*next= mwork[(next<<1)+2];*/
2199 next = mwork[next].suc;
2200 last = iperm;
2201 }
2202 } else {
2203 #ifdef DEBUG
2204 j = 0;
2205 #endif
2206 for (i = 1; i <= nrow; ++i) {
2207 int iperm = mpermu[i];
2208 eta_next[last] = iperm;
2209 eta_last[iperm] = last;
2210 temp[iperm] = mrstrt[i];
2211 temp2[iperm] = hinrow[i];
2212 last = iperm;
2213 #ifdef DEBUG
2214 if (mrstrt[i] <= j)
2215 abort();
2216 if (i > 1 && mrstrt[i] != j + hinrow[i - 1])
2217 abort();
2218 j = mrstrt[i];
2219 #endif
2220 }
2221 }
2222 eta_next[last] = nrow + 1;
2223 eta_last[nrow + 1] = last;
2224 eta_next[nrow + 1] = nrow + 2;
2225 c_ekkscpy(nrow, &temp[1], &mrstrt[1]);
2226 c_ekkscpy(nrow, &temp2[1], &hinrow[1]);
2227 i = eta_last[nrow + 1];
2228 ninbas = mrstrt[i] + hinrow[i] - 1;
2229 #ifdef DEBUG
2230 if (spareSpace < ninbas) {
2231 abort();
2232 }
2233 #endif
2234 c_ekkizero(nrow, &hincol[1]);
2235 #ifdef DEBUG
2236 for (i = nrow; i > 0; i--) {
2237 int krs = mrstrt[i];
2238 int jpiv = hcoli[krs];
2239 if (ihlink[jpiv] != i)
2240 abort();
2241 }
2242 #endif
2243 for (i = 1; i <= ninbas; ++i) {
2244 k = hcoli[i];
2245 k = ihlink[k];
2246 #ifdef DEBUG
2247 if (k <= 0 || k > nrow)
2248 abort();
2249 #endif
2250 hcoli[i] = k;
2251 hincol[k]++;
2252 }
2253 #ifdef DEBUG
2254 for (i = nrow; i > 0; i--) {
2255 int krs = mrstrt[i];
2256 int jpiv = hcoli[krs];
2257 if (jpiv != i)
2258 abort();
2259 if (krs > ninbas)
2260 abort();
2261 }
2262 #endif
2263 /* Sort into column order as was stored by row */
2264 k = 1;
2265 /* Position */
2266 for (kk = 1; kk <= nrow; ++kk) {
2267 nel = hincol[kk];
2268 mcstrt[kk] = k;
2269 hrowi[k] = nel - 1;
2270 k += hincol[kk];
2271 hincol[kk] = 0;
2272 }
2273 if (de2val) {
2274 dluval2 = de2val;
2275 } else {
2276 dluval2 = dluval + ninbas;
2277 }
2278 nnentu = k - 1;
2279 mcstrt[nrow + 4] = nnentu + 1;
2280 /* create column copy */
2281 for (i = nrow; i > 0; i--) {
2282 int krs = mrstrt[i];
2283 int kre = krs + hinrow[i];
2284 hinrow[i]--;
2285 mrstrt[i]++;
2286 {
2287 int kx = mcstrt[i];
2288 /*nel = hincol[i];
2289 if (hrowi[kx]!=nel) abort();
2290 hrowi[kx] = nel-1;*/
2291 dluval2[kx] = 1.0 / dluval[krs];
2292 /*hincol[i]=0;*/
2293 for (kk = krs + 1; kk < kre; ++kk) {
2294 int j = hcoli[kk];
2295 int iput = hincol[j] + 1;
2296 hincol[j] = iput;
2297 iput += mcstrt[j];
2298 hrowi[iput] = SHIFT_INDEX(i);
2299 dluval2[iput] = dluval[kk];
2300 }
2301 }
2302 }
2303 if (de2val) {
2304 double *a = dluval;
2305 double *address;
2306 /* move first down */
2307 i = eta_next[0];
2308 {
2309 int krs = mrstrt[i];
2310 nel = hinrow[i];
2311 for (j = 1; j <= nel; j++) {
2312 hcoli[j] = hcoli[j + krs - 1];
2313 dluval[j] = dluval[j + krs - 1];
2314 }
2315 }
2316 mrstrt[i] = 1;
2317 /****** swap dluval and de2val !!!! ******/
2318 /* should work even for dspace */
2319 /* move L part across */
2320 address = fact->xeeadr + 1;
2321 fact->xeeadr = fact->xe2adr - 1;
2322 fact->xe2adr = address;
2323 if (nnentl) {
2324 int n = xnetal - nrow - maxinv - 5;
2325 int j1, j2;
2326 int *mcstrt2 = mcstrt + nrow + maxinv + 4;
2327 j2 = mcstrt2[1];
2328 j1 = mcstrt2[n + 1] + 1;
2329 #if 0
2330 memcpy(de2val+j1,dluval+j1,(j2-j1+1)*sizeof(double));
2331 #else
2332 c_ekkdcpy(j2 - j1 + 1,
2333 (dluval + j1), (de2val + j1));
2334 #endif
2335 }
2336 dluval = de2val;
2337 de2val = a;
2338 } else {
2339 /* copy down dluval */
2340 #if 0
2341 memcpy(&dluval[1],&dluval2[1],ninbas*sizeof(double));
2342 #else
2343 c_ekkdcpy(ninbas,
2344 (dluval2 + 1), (dluval + 1));
2345 #endif
2346 }
2347 /* sort dense part */
2348 for (i = nrow - ndenuc + 1; i <= nrow; i++) {
2349 int kx = mcstrt[i] + 1;
2350 int nel = hincol[i];
2351 c_ekk_sort2(&hrowi[kx], &dluval[kx], nel);
2352 }
2353 }
2354 mrstrt[nrow + 1] = ilast + 1;
2355 }
2356 /* Find first non slack */
2357 for (i = 1; i <= nrow; ++i) {
2358 int kcs = mcstrt[i];
2359 if (hincol[i] != 0 || dluval[kcs] != SLACK_VALUE) {
2360 break;
2361 }
2362 }
2363 numberSlacks = i - 1;
2364 {
2365 /* set slacks to 1 */
2366 int *array = fact->krpadr + (fact->nrowmx + 2);
2367 int nSet = (numberSlacks) >> 5;
2368 int n2 = (fact->nrowmx + 32) >> 5;
2369 int i;
2370 memset(array, 0xff, nSet * sizeof(int));
2371 memset(array + nSet, 0, (n2 - nSet) * sizeof(int));
2372 for (i = nSet << 5; i <= numberSlacks; i++)
2373 c_ekk_Set(array, i);
2374 c_ekk_Unset(array, fact->nrow + 1); /* make sure off end not slack */
2375 #ifndef NDEBUG
2376 for (i = 1; i <= numberSlacks; i++)
2377 assert(c_ekk_IsSet(array, i));
2378 for (; i <= fact->nrow; i++)
2379 assert(!c_ekk_IsSet(array, i));
2380 #endif
2381 }
2382
2383 /* and set up backward pointers */
2384 /* clean up HPIVCO for fancy assembler stuff */
2385 /* xnetal was initialized to nrow + maxinv + 4 in c_ekktria, and grows */
2386 c_ekkscpy_0_1(maxinv + 1, 1, &hpivco[nrow + 4]); /* magic */
2387
2388 hpivco[xnetal] = 1;
2389 /* shuffle down for gaps so can get rid of hpivco for L */
2390 {
2391 const int lstart = nrow + maxinv + 5;
2392 int n = xnetal - lstart; /* number of L entries */
2393 int add, iel;
2394 int *hpivco_L = &hpivco[lstart];
2395 int *mcstrt_L = &mcstrt[lstart];
2396 if (nnentl) {
2397 /* elements of L were stored in descending order in dluval/hcoli */
2398 int kle = mcstrt_L[0];
2399 int kls = mcstrt_L[n] + 1;
2400
2401 if (if_sparse_update) {
2402 int i2, iel;
2403 int *mrstrt2 = &mrstrt[nrow];
2404
2405 /* need row copy of L */
2406 /* hpivro is spare for counts; just used as a temp buffer */
2407 c_ekkizero(nrow, &hpivro[1]);
2408
2409 /* permute L indices; count L row lengths */
2410 for (iel = kls; iel <= kle; ++iel) {
2411 int jrow = mpermu[UNSHIFT_INDEX(hrowi[iel])];
2412 hpivro[jrow]++;
2413 hrowi[iel] = SHIFT_INDEX(jrow);
2414 }
2415 {
2416 int ibase = nnetas - nnentl + 1;
2417 int firstDoRow = 0;
2418 for (i = 1; i <= nrow; i++) {
2419 mrstrt2[i] = ibase;
2420 if (hpivro[i] && !firstDoRow) {
2421 firstDoRow = i;
2422 }
2423 ibase += hpivro[i];
2424 hpivro[i] = mrstrt2[i];
2425 }
2426 if (!firstDoRow) {
2427 firstDoRow = nrow + 1;
2428 }
2429 mrstrt2[i] = ibase;
2430 fact->firstDoRow = firstDoRow;
2431 }
2432 i2 = mcstrt_L[n];
2433 for (i = n - 1; i >= 0; --i) {
2434 int i1 = mcstrt_L[i];
2435 int ipiv = hpivco_L[i];
2436 ipiv = mpermu[ipiv];
2437 hpivco_L[i] = ipiv;
2438 for (iel = i2; iel < i1; iel++) {
2439 int irow = UNSHIFT_INDEX(hrowi[iel + 1]);
2440 int iput = hpivro[irow];
2441 hpivro[irow] = iput + 1;
2442 hcoli[iput] = ipiv;
2443 de2val[iput] = dluval[iel + 1];
2444 }
2445 i2 = i1;
2446 }
2447 } else {
2448 /* just permute row numbers */
2449
2450 for (j = 0; j < n; ++j) {
2451 hpivco_L[j] = mpermu[hpivco_L[j]];
2452 }
2453 for (iel = kls; iel <= kle; ++iel) {
2454 int jrow = mpermu[UNSHIFT_INDEX(hrowi[iel])];
2455 hrowi[iel] = SHIFT_INDEX(jrow);
2456 }
2457 }
2458
2459 add = hpivco_L[n - 1] - hpivco_L[0] - n + 1;
2460 if (add) {
2461 int i;
2462 int last = hpivco_L[n - 1];
2463 int laststart = mcstrt_L[n];
2464 int base = hpivco_L[0] - 1;
2465 /* adjust so numbers match */
2466 mcstrt_L -= base;
2467 hpivco_L -= base;
2468 mcstrt_L[last] = laststart;
2469 for (i = n - 1; i >= 0; i--) {
2470 int ipiv = hpivco_L[i + base];
2471 while (ipiv < last) {
2472 mcstrt_L[last - 1] = laststart;
2473 hpivco_L[last - 1] = last;
2474 last--;
2475 }
2476 laststart = mcstrt_L[i + base];
2477 mcstrt_L[last - 1] = laststart;
2478 hpivco_L[last - 1] = last;
2479 last--;
2480 }
2481 xnetal += add;
2482 }
2483 }
2484 //int lstart=fact->lstart;
2485 //const int * COIN_RESTRICT hpivco = fact->kcpadr;
2486 fact->firstLRow = hpivco[lstart];
2487 }
2488 fact->nnentu = nnentu;
2489 fact->xnetal = xnetal;
2490 /* now we have xnetal * we can set up pointers */
2491 clp_setup_pointers(fact);
2492
2493 /* this is the array used in c_ekkbtrn; it is passed to c_ekkbtju as hpivco.
2494 * this gets modified by F-T as we pivot columns in and out.
2495 */
2496 {
2497 /* do new hpivco */
2498 int *hpivco_new = fact->kcpadr + 1;
2499 int *back = &fact->kcpadr[2 * nrow + maxinv + 4];
2500 /* set zeroth to stop illegal read */
2501 back[0] = 1;
2502
2503 hpivco_new[nrow + 1] = nrow + 1; /* deliberate loop for dense tests */
2504 hpivco_new[0] = 1;
2505
2506 for (i = 1; i <= nrow; i++) {
2507 hpivco_new[i] = i + 1;
2508 back[i + 1] = i;
2509 }
2510 back[1] = 0;
2511
2512 fact->first_dense = CoinMax(fact->first_dense, 4);
2513 fact->numberSlacks = numberSlacks;
2514 fact->lastSlack = numberSlacks;
2515 fact->firstNonSlack = hpivco_new[numberSlacks];
2516 }
2517
2518 /* also zero out permute region and nonzero */
2519 c_ekkdzero(nrow, (dpermu + 1));
2520
2521 if (if_sparse_update) {
2522 char *nonzero = reinterpret_cast< char * >(&mpermu[nrow + 1]); /* used in c_ekkbtrn */
2523 /*c_ekkizero(nrow,(int *)nonzero);*/
2524 c_ekkczero(nrow, nonzero);
2525 /*memset(nonzero,0,nrow*sizeof(int));*/ /* for faster method */
2526 }
2527 for (i = 1; i <= nrow; ++i) {
2528 hpivro[mpermu[i]] = i;
2529 }
2530
2531 } /* c_ekkshfv */
2532
c_ekkclcp1(const int * hcol,const int * mrstrt,int * hrow,int * mcstrt,int * hincol,int nnrow,int nncol,int ninbas)2533 static void c_ekkclcp1(const int *hcol, const int *mrstrt,
2534 int *hrow, int *mcstrt,
2535 int *hincol, int nnrow, int nncol,
2536 int ninbas)
2537 {
2538 int i, j, kc, kr, kre, krs, icol;
2539 int iput;
2540
2541 /* Create columnwise storage of row indices */
2542
2543 kc = 1;
2544 for (j = 1; j <= nncol; ++j) {
2545 mcstrt[j] = kc;
2546 kc += hincol[j];
2547 hincol[j] = 0;
2548 }
2549 mcstrt[nncol + 1] = ninbas + 1;
2550
2551 for (i = 1; i <= nnrow; ++i) {
2552 krs = mrstrt[i];
2553 kre = mrstrt[i + 1] - 1;
2554 for (kr = krs; kr <= kre; ++kr) {
2555 icol = hcol[kr];
2556 iput = hincol[icol];
2557 hincol[icol] = iput + 1;
2558 iput += mcstrt[icol];
2559 hrow[iput] = i;
2560 }
2561 }
2562 } /* c_ekkclcp */
c_ekkclcp2(const int * hcol,const double * dels,const int * mrstrt,int * hrow,double * dels2,int * mcstrt,int * hincol,int nnrow,int nncol,int ninbas)2563 inline void c_ekkclcp2(const int *hcol, const double *dels, const int *mrstrt,
2564 int *hrow, double *dels2, int *mcstrt,
2565 int *hincol, int nnrow, int nncol,
2566 int ninbas)
2567 {
2568 int i, j, kc, kr, kre, krs, icol;
2569 int iput;
2570
2571 /* Create columnwise storage of row indices */
2572
2573 kc = 1;
2574 for (j = 1; j <= nncol; ++j) {
2575 mcstrt[j] = kc;
2576 kc += hincol[j];
2577 hincol[j] = 0;
2578 }
2579 mcstrt[nncol + 1] = ninbas + 1;
2580
2581 for (i = 1; i <= nnrow; ++i) {
2582 krs = mrstrt[i];
2583 kre = mrstrt[i + 1] - 1;
2584 for (kr = krs; kr <= kre; ++kr) {
2585 icol = hcol[kr];
2586 iput = hincol[icol];
2587 hincol[icol] = iput + 1;
2588 iput += mcstrt[icol];
2589 hrow[iput] = i;
2590 dels2[iput] = dels[kr];
2591 }
2592 }
2593 } /* c_ekkclcp */
c_ekkslcf(register const EKKfactinfo * fact)2594 int c_ekkslcf(register const EKKfactinfo *fact)
2595 {
2596 int *hrow = fact->xeradr;
2597 int *hcol = fact->xecadr;
2598 double *dels = fact->xeeadr;
2599 int *hinrow = fact->xrnadr;
2600 int *hincol = fact->xcnadr;
2601 int *mrstrt = fact->xrsadr;
2602 int *mcstrt = fact->xcsadr;
2603 const int nrow = fact->nrow;
2604 int ninbas;
2605 /* space for etas */
2606 const int nnetas = fact->nnetas;
2607 ninbas = mcstrt[nrow + 1] - 1;
2608
2609 /* Now sort */
2610 if (ninbas << 1 > nnetas) {
2611 /* Put it in row order */
2612 int i, k;
2613 c_ekkrowq(hrow, hcol, dels, mrstrt, hinrow, nrow, ninbas);
2614 k = 1;
2615 for (i = 1; i <= nrow; ++i) {
2616 mrstrt[i] = k;
2617 k += hinrow[i];
2618 }
2619 mrstrt[nrow + 1] = k;
2620
2621 /* make a column copy without the extra values */
2622 c_ekkclcp1(hcol, mrstrt, hrow, mcstrt, hincol, nrow, nrow, ninbas);
2623 } else {
2624 /* Move elements up memory */
2625 c_ekkdcpy(ninbas,
2626 (dels + 1), (dels + ninbas + 1));
2627
2628 /* make a row copy with the extra values */
2629 c_ekkclcp2(hrow, &dels[ninbas], mcstrt, hcol, dels, mrstrt, hinrow, nrow, nrow, ninbas);
2630 }
2631 return (ninbas);
2632 } /* c_ekkslcf */
2633 /* Uwe H. Suhl, September 1986 */
2634 /* Removes lower and upper triangular factors from the matrix. */
2635 /* Code for routine: 102 */
2636 /* Return codes: */
2637 /* 0: ok */
2638 /* -5: not enough space in row file */
2639 /* 7: pivot too small - col sing */
2640 /*
2641 * This selects singleton columns and rows for the LU factorization.
2642 * Singleton columns require no
2643 *
2644 * (1) Note that columns are processed using a queue, not a stack;
2645 * this produces better pivots.
2646 *
2647 * (2) At most nrows elements are ever entered into the queue.
2648 *
2649 * (3) When pivoting singleton columns, every column that is part of
2650 * the pivot row is shortened by one, including the singleton column
2651 * itself; the hincol entries are updated appropriately.
2652 * Thus, pivoting on a singleton column may create other singleton columns
2653 * (but not singleton rows).
2654 * The dual property is true for rows.
2655 *
2656 * (4) Row entries (hrowi) are not changed when pivoting singleton columns.
2657 * Singleton columns that are created as a result of pivoting the
2658 * rows of other singleton columns will therefore have row entries
2659 * corresponding to those pivoted rows. Since we need to find the
2660 * row entry for the row being pivoted, we have to
2661 * search its row entries for the one whose hlink entry indicates
2662 * that it has not yet been pivoted.
2663 *
2664 * (9) As a result of pivoting columns, sections in hrowi corresponding to
2665 * pivoted columns are no longer needed, and entries in sections
2666 * for non-pivoted columns may have entries corresponding to pivoted rows.
2667 * This is why hrowi needs to be compacted.
2668 *
2669 * (5) When the row_pre and col_pre fields of the hlink struct contain
2670 * negative values, they indicate that the row has been pivoted, and
2671 * the negative of that value is the pivot order.
2672 * That is the only use for these fields in this routine.
2673 *
2674 * (6) This routine assumes that hlink is initialized to zeroes.
2675 * Under this assumption, the following is an invariant in this routine:
2676 *
2677 * (clink[i].pre < 0) ==> (hincol[i]==0)
2678 *
2679 * The converse is not true; see (15).
2680 *
2681 * The dual is also true, but only while pivoting singletong rows,
2682 * since we don't update hinrow while pivoting columns;
2683 * THESE VALUES ARE USED LATER, BUT I DON'T UNDERSTAND HOW YET.
2684 *
2685 * (7) hpivco is used for two purposes. The low end is used to implement the
2686 * queue when pivoting columns; the high end is used to hold eta-matrix
2687 * entries.
2688 *
2689 * (8) As a result of pivoting columns, for all i:1<=i<=nrow, either
2690 * hinrow[i] has not changed
2691 * or
2692 * hinrow[i] = 0
2693 * This is another way of saying that pivoting singleton columns cannot
2694 * create singleton rows.
2695 * The dual holds for hincol after pivoting rows.
2696 *
2697 * (10) In constrast to (4), while pivoting rows we
2698 * do not let the hcoli get out-of-date. That is because as part of
2699 * the process of numerical pivoting we have to find the row entries
2700 * for all the rows in the pivot column, so we may as well keep the
2701 * entries up to date. This is done by moving the last column entry
2702 * for each row into the entry that was used for the pivot column.
2703 *
2704 * (11) When pivoting a column, we must find the pivot row entry in
2705 * its row table. Sometimes we search for other things at the same time.
2706 * The same is true for pivoting columns. This search should never
2707 * fail.
2708 *
2709 * (12) Information concerning the eta matrices is stored in the high
2710 * ends of arrays that are also used to store information concerning
2711 * the basis; these arrays are: hpivco, mcstrt, dluval and hcoli.
2712 * Information is only stored in these arrays as a part of pivoting
2713 * singleton rows, since the only thing that needs to be saved as
2714 * a part of pivoting singleton columns is which rows and columns were chosen,
2715 * and this is stored in hlink.
2716 * Since they have to share the same array, the eta information grows
2717 * downward instead of upward. Eventually, eta information may grow
2718 * down to the top of the basis information. As pivoting proceeds,
2719 * more and more of this information is no longer needed, so when this
2720 * happens we can try compacting the arrays to see if we can recover
2721 * enough space. lstart points at the bottom entry in the arrays,
2722 * xnewro/xnewco at the top of the basis information, and each time we
2723 * pivot a singleton row we know that we will need exactly as many new
2724 * entries as there are rows in the pivot column, so we can easily
2725 * determine if we need more room. The variable maxinv may be used
2726 * to reserve extra room when inversion starts.
2727 *
2728 * (13) Eta information is stored in a fashion that is similar to how
2729 * matrices are stored. There is one entry in hpivco and mcstrt for
2730 * each eta (other than the initial ones for singleton columns and
2731 * for singleton rows that turn out to be singleton columns),
2732 * in the order they were chosen. hpivco records the pivot row,
2733 * and mcstrt points at the first entry in the other two arrays
2734 * for this row. dluval contains the actual eta values for the column,
2735 * and hcoli the rows these values were in.
2736 * These entries in mcstrt and hpivco grow upward; they start above
2737 * the entries used to store basis information.
2738 * (Actually, I don't see why they need to start maxinv+4 entries past the top).
2739 *
2740 * (14) c_ekkrwco assumes that invalidated hrowi/hcoli entries contain 0.
2741 *
2742 * (15) When pivoting singleton columns, it may possibly happen
2743 * that a row with all singleton column entries is created.
2744 * In this case, all of the columns will be enqueued, and pivoting
2745 * on any of them eliminates the rest, without their being chosen
2746 * as pivots. The dual holds for singleton rows.
2747 * DOES THIS INDICATE A SINGULARITY?
2748 *
2749 * (15) There are some aspects of the implementation that I find odd.
2750 * hrowi is not set to 0 for pivot rows while pivoting singleton columns,
2751 * which would make sense to me. Things don't work if this isn't done,
2752 * so the information is used somehow later on. Also, the information
2753 * for the pivot column is shifted to the front of the pivot row
2754 * when pivoting singleton columns; this is also necessary for reasons
2755 * I don't understand.
2756 */
c_ekktria(EKKfactinfo * fact,EKKHlink * rlink,EKKHlink * clink,int * nsingp,int * xnewcop,int * xnewrop,int * ncompactionsp,const int ninbas)2757 int c_ekktria(EKKfactinfo *fact,
2758 EKKHlink *rlink,
2759 EKKHlink *clink,
2760 int *nsingp,
2761 int *xnewcop, int *xnewrop,
2762 int *ncompactionsp,
2763 const int ninbas)
2764 {
2765 const int nrow = fact->nrow;
2766 const int maxinv = fact->maxinv;
2767 int *hcoli = fact->xecadr;
2768 double *dluval = fact->xeeadr;
2769 int *mrstrt = fact->xrsadr;
2770 int *hrowi = fact->xeradr;
2771 int *mcstrt = fact->xcsadr;
2772 int *hinrow = fact->xrnadr;
2773 int *hincol = fact->xcnadr;
2774 int *stack = fact->krpadr; /* normally hpivro */
2775 int *hpivco = fact->kcpadr;
2776 const double drtpiv = fact->drtpiv;
2777 CoinZeroN(reinterpret_cast< int * >(rlink + 1), static_cast< int >(nrow * (sizeof(EKKHlink) / sizeof(int))));
2778 CoinZeroN(reinterpret_cast< int * >(clink + 1), static_cast< int >(nrow * (sizeof(EKKHlink) / sizeof(int))));
2779
2780 fact->npivots = 0;
2781 /* Use NUSPIK to keep sum of deactivated row counts */
2782 fact->nuspike = 0;
2783 int xnetal = nrow + maxinv + 4;
2784 int xnewro = mrstrt[nrow] + hinrow[nrow] - 1;
2785 int xnewco = xnewro;
2786 int kmxeta = ninbas;
2787 int ncompactions = 0;
2788
2789 int i, j, k, kc, kce, kcs, npr;
2790 double pivot;
2791 int kipis, kipie, kjpis, kjpie, knprs, knpre;
2792 int ipivot, jpivot, stackc, stackr;
2793 #ifndef NDEBUG
2794 int kpivot = -1;
2795 #else
2796 int kpivot = -1;
2797 #endif
2798 int epivco, kstart, maxstk;
2799 int irtcod = 0;
2800 int lastSlack = 0;
2801
2802 int lstart = fact->nnetas + 1;
2803 /*int nnentu = ninbas; */
2804 int lstart_minus_nnentu = lstart - ninbas;
2805 /* do initial column singletons - as can do faster */
2806 for (jpivot = 1; jpivot <= nrow; ++jpivot) {
2807 if (hincol[jpivot] == 1) {
2808 ipivot = hrowi[mcstrt[jpivot]];
2809 if (ipivot > lastSlack) {
2810 lastSlack = ipivot;
2811 } else {
2812 /* so we can't put a structural over a slack */
2813 break;
2814 }
2815 kipis = mrstrt[ipivot];
2816 #if 1
2817 assert(hcoli[kipis] == jpivot);
2818 #else
2819 if (hcoli[kipis] != jpivot) {
2820 kpivot = kipis + 1;
2821 while (hcoli[kpivot] != jpivot)
2822 kpivot++;
2823 #ifdef DEBUG
2824 kipie = kipis + hinrow[ipivot];
2825 if (kpivot >= kipie) {
2826 abort();
2827 }
2828 #endif
2829 pivot = dluval[kpivot];
2830 dluval[kpivot] = dluval[kipis];
2831 dluval[kipis] = pivot;
2832 hcoli[kpivot] = hcoli[kipis];
2833 hcoli[kipis] = jpivot;
2834 }
2835 #endif
2836 if (dluval[kipis] == SLACK_VALUE) {
2837 /* record the new pivot row and column */
2838 ++fact->npivots;
2839 rlink[ipivot].pre = -fact->npivots;
2840 clink[jpivot].pre = -fact->npivots;
2841 hincol[jpivot] = 0;
2842 fact->nuspike += hinrow[ipivot];
2843 } else {
2844 break;
2845 }
2846 } else {
2847 break;
2848 }
2849 }
2850 /* Fill queue with other column singletons and clean up */
2851 maxstk = 0;
2852 for (j = 1; j <= nrow; ++j) {
2853 if (hincol[j]) {
2854 int n = 0;
2855 kcs = mcstrt[j];
2856 kce = mcstrt[j + 1];
2857 for (k = kcs; k < kce; ++k) {
2858 if (!(rlink[hrowi[k]].pre < 0)) {
2859 n++;
2860 }
2861 }
2862 hincol[j] = n;
2863 if (n == 1) {
2864 /* we just created a new singleton column - enqueue it */
2865 ++maxstk;
2866 stack[maxstk] = j;
2867 }
2868 }
2869 }
2870 stackc = 0; /* (1) */
2871
2872 while (!(stackc >= maxstk)) { /* (1) */
2873 /* dequeue the next entry */
2874 ++stackc;
2875 jpivot = stack[stackc];
2876
2877 /* (15) */
2878 if (hincol[jpivot] != 0) {
2879
2880 for (k = mcstrt[jpivot]; rlink[hrowi[k]].pre < 0; k++) {
2881 /* (4) */
2882 }
2883 ipivot = hrowi[k];
2884
2885 /* All the columns in this row are being shortened. */
2886 kipis = mrstrt[ipivot];
2887 kipie = kipis + hinrow[ipivot];
2888 for (k = kipis; k < kipie; ++k) {
2889 j = hcoli[k];
2890 --hincol[j]; /* (3) (6) */
2891
2892 if (j == jpivot) {
2893 kpivot = k; /* (11) */
2894 } else if (hincol[j] == 1) {
2895 /* we just created a new singleton column - enqueue it */
2896 ++maxstk;
2897 stack[maxstk] = j;
2898 }
2899 }
2900
2901 /* record the new pivot row and column */
2902 ++fact->npivots;
2903 rlink[ipivot].pre = -fact->npivots;
2904 clink[jpivot].pre = -fact->npivots;
2905
2906 fact->nuspike += hinrow[ipivot];
2907
2908 /* check the pivot */
2909 assert(kpivot > 0);
2910 pivot = dluval[kpivot];
2911 if (fabs(pivot) < drtpiv) {
2912 irtcod = 7;
2913 ++(*nsingp);
2914 rlink[ipivot].pre = -nrow - 1;
2915 clink[jpivot].pre = -nrow - 1;
2916 }
2917
2918 /* swap the pivot column entry with the first one. */
2919 /* I don't know why. */
2920 dluval[kpivot] = dluval[kipis];
2921 dluval[kipis] = pivot;
2922 hcoli[kpivot] = hcoli[kipis];
2923 hcoli[kipis] = jpivot;
2924 }
2925 }
2926 /* (8) */
2927
2928 /* The entire basis may already be triangular */
2929 if (fact->npivots < nrow) {
2930
2931 /* (9) */
2932 kstart = 0;
2933 for (j = 1; j <= nrow; ++j) {
2934 if (!(clink[j].pre < 0)) {
2935 kcs = mcstrt[j];
2936 kce = mcstrt[j + 1];
2937
2938 mcstrt[j] = kstart + 1;
2939
2940 for (k = kcs; k < kce; ++k) {
2941 if (!(rlink[hrowi[k]].pre < 0)) {
2942 ++kstart;
2943 hrowi[kstart] = hrowi[k];
2944 }
2945 }
2946 hincol[j] = kstart - mcstrt[j] + 1;
2947 }
2948 }
2949 xnewco = kstart;
2950
2951 /* Fill stack with initial row singletons that haven't been pivoted away */
2952 stackr = 0;
2953 for (i = 1; i <= nrow; ++i) {
2954 if (!(rlink[i].pre < 0) && (hinrow[i] == 1)) {
2955 ++stackr;
2956 stack[stackr] = i;
2957 }
2958 }
2959
2960 while (!(stackr <= 0)) {
2961 ipivot = stack[stackr];
2962 assert(ipivot);
2963 --stackr;
2964
2965 #if 1
2966 assert(rlink[ipivot].pre >= 0);
2967 #else
2968 /* This test is probably unnecessary: rlink[i].pre < 0 ==> hinrow[i]==0 */
2969 if (rlink[ipivot].pre < 0) {
2970 continue;
2971 }
2972 #endif
2973
2974 /* (15) */
2975 if (hinrow[ipivot] != 0) {
2976
2977 /* This is a singleton row, which means it has exactly one column */
2978 jpivot = hcoli[mrstrt[ipivot]];
2979
2980 kjpis = mcstrt[jpivot];
2981 epivco = hincol[jpivot] - 1;
2982 hincol[jpivot] = 0; /* this column is being pivoted away */
2983
2984 /* (11) */
2985 kjpie = kjpis + epivco;
2986 for (k = kjpis; k <= kjpie; ++k) {
2987 if (ipivot == hrowi[k])
2988 break;
2989 }
2990 /* ASSERT (k <= kjpie) */
2991
2992 /* move the last row entry for the pivot column into the pivot row's entry */
2993 /* I don't know why */
2994 hrowi[k] = hrowi[kjpie];
2995
2996 /* invalidate the (old) last row entry of the pivot column */
2997 /* I don't know why */
2998 hrowi[kjpie] = 0;
2999
3000 /* (12) */
3001 if (!(xnewro + epivco < lstart)) {
3002 int kstart;
3003
3004 if (!(epivco < lstart_minus_nnentu)) {
3005 irtcod = -5;
3006 break;
3007 }
3008 kstart = c_ekkrwco(fact, dluval, hcoli, mrstrt, hinrow, xnewro);
3009 ++ncompactions;
3010 kmxeta += (xnewro - kstart) << 1;
3011 xnewro = kstart;
3012 }
3013 if (!(xnewco + epivco < lstart)) {
3014 if (!(epivco < lstart_minus_nnentu)) {
3015 irtcod = -5;
3016 break;
3017 }
3018 xnewco = c_ekkclco(fact, hrowi, mcstrt, hincol, xnewco);
3019 ++ncompactions;
3020
3021 /* HINCOL MAY HAVE CHANGED ??? (JJHF) */
3022 epivco = hincol[jpivot];
3023 }
3024
3025 /* record the new pivot row and column */
3026 ++fact->npivots;
3027 rlink[ipivot].pre = -fact->npivots;
3028 clink[jpivot].pre = -fact->npivots;
3029
3030 /* no update for nuspik */
3031
3032 /* check the pivot */
3033 pivot = dluval[mrstrt[ipivot]];
3034 if (fabs(pivot) < drtpiv) {
3035 /* If the pivot is too small, reject it, but keep going */
3036 irtcod = 7;
3037 rlink[ipivot].pre = -nrow - 1;
3038 clink[jpivot].pre = -nrow - 1;
3039 }
3040
3041 /* Perform numerical part of elimination. */
3042 if (!(epivco <= 0)) {
3043 ++xnetal;
3044 mcstrt[xnetal] = lstart - 1;
3045 hpivco[xnetal] = ipivot;
3046 pivot = -1.f / pivot;
3047
3048 kcs = mcstrt[jpivot];
3049 kce = kcs + epivco - 1;
3050 hincol[jpivot] = 0;
3051
3052 for (kc = kcs; kc <= kce; ++kc) {
3053 npr = hrowi[kc];
3054
3055 /* why bother? */
3056 hrowi[kc] = 0;
3057
3058 --hinrow[npr]; /* (3) */
3059 if (hinrow[npr] == 1) {
3060 /* this may create new singleton rows */
3061 ++stackr;
3062 stack[stackr] = npr;
3063 }
3064
3065 /* (11) */
3066 knprs = mrstrt[npr];
3067 knpre = knprs + hinrow[npr];
3068 for (k = knprs; k <= knpre; ++k) {
3069 if (jpivot == hcoli[k]) {
3070 kpivot = k;
3071 break;
3072 }
3073 }
3074 /* ASSERT (kpivot <= knpre) */
3075
3076 {
3077 /* (10) */
3078 double elemnt = dluval[kpivot];
3079 dluval[kpivot] = dluval[knpre];
3080 hcoli[kpivot] = hcoli[knpre];
3081
3082 hcoli[knpre] = 0; /* (14) */
3083
3084 /* store elementary row transformation */
3085 --lstart;
3086 dluval[lstart] = elemnt * pivot;
3087 hcoli[lstart] = npr;
3088 }
3089 }
3090 }
3091 }
3092 }
3093 }
3094 /* (8) */
3095
3096 *xnewcop = xnewco;
3097 *xnewrop = xnewro;
3098 fact->xnetal = xnetal;
3099 fact->nnentu = lstart - lstart_minus_nnentu;
3100 fact->kmxeta = kmxeta;
3101 *ncompactionsp = ncompactions;
3102
3103 return (irtcod);
3104 } /* c_ekktria */
3105 #endif
3106
3107 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
3108 */
3109