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