Scippy

SoPlex

Sequential object-oriented simPlex

clufactor_rational.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2019 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 #include <assert.h>
17 
18 #include "soplex/spxdefines.h"
20 #include "soplex/cring.h"
21 #include "soplex/spxalloc.h"
22 #include "soplex/exceptions.h"
23 #include "soplex/basevectors.h"
24 #include "soplex/rational.h"
25 
26 namespace soplex
27 {
28 /* This number is used to decide wether a value is zero
29  * or was explicitly set to zero.
30  */
31 /*
32 #define MARKER 1e-100
33 */
34 
35 static const Real verySparseFactor = 0.001;
36 static const Real verySparseFactor4right = 0.2;
37 
38 /* generic heap management */
39 static void enQueueMax(int* heap, int* size, int elem)
40 {
41  int i, j;
42 
43  j = (*size)++;
44 
45  while(j > 0)
46  {
47  i = (j - 1) / 2;
48 
49  if(elem > heap[i])
50  {
51  heap[j] = heap[i];
52  j = i;
53  }
54  else
55  break;
56  }
57 
58  heap[j] = elem;
59 
60 #ifdef SOPLEX_DEBUG
61 
62  // no NDEBUG define, since this block is really expensive
63  for(i = 1; i < *size; ++i)
64  for(j = 0; j < i; ++j)
65  assert(heap[i] != heap[j]);
66 
67 #endif /* SOPLEX_DEBUG */
68 }
69 
70 static int deQueueMax(int* heap, int* size)
71 {
72  int e, elem;
73  int i, j, s;
74  int e1, e2;
75 
76  elem = *heap;
77  e = heap[s = --(*size)];
78  --s;
79 
80  for(j = 0, i = 1; i < s; i = 2 * j + 1)
81  {
82  e1 = heap[i];
83  e2 = heap[i + 1];
84 
85  if(e1 > e2)
86  {
87  if(e < e1)
88  {
89  heap[j] = e1;
90  j = i;
91  }
92  else
93  {
94  heap[j] = e;
95  return elem;
96  }
97  }
98  else
99  {
100  if(e < e2)
101  {
102  heap[j] = e2;
103  j = i + 1;
104  }
105  else
106  {
107  heap[j] = e;
108  return elem;
109  }
110  }
111  }
112 
113  if(i < *size && e < heap[i])
114  {
115  heap[j] = heap[i];
116  j = i;
117  }
118 
119  heap[j] = e;
120 
121  return elem;
122 }
123 
124 static void enQueueMin(int* heap, int* size, int elem)
125 {
126  int i, j;
127 
128  j = (*size)++;
129 
130  while(j > 0)
131  {
132  i = (j - 1) / 2;
133 
134  if(elem < heap[i])
135  {
136  heap[j] = heap[i];
137  j = i;
138  }
139  else
140  break;
141  }
142 
143  heap[j] = elem;
144 
145 #ifdef SOPLEX_DEBUG
146 
147  // no NDEBUG define, since this block is really expensive
148  for(i = 1; i < *size; ++i)
149  for(j = 0; j < i; ++j)
150  assert(heap[i] != heap[j]);
151 
152 #endif /* SOPLEX_DEBUG */
153 }
154 
155 static int deQueueMin(int* heap, int* size)
156 {
157  int e, elem;
158  int i, j, s;
159  int e1, e2;
160 
161  elem = *heap;
162  e = heap[s = --(*size)];
163  --s;
164 
165  for(j = 0, i = 1; i < s; i = 2 * j + 1)
166  {
167  e1 = heap[i];
168  e2 = heap[i + 1];
169 
170  if(e1 < e2)
171  {
172  if(e > e1)
173  {
174  heap[j] = e1;
175  j = i;
176  }
177  else
178  {
179  heap[j] = e;
180  return elem;
181  }
182  }
183  else
184  {
185  if(e > e2)
186  {
187  heap[j] = e2;
188  j = i + 1;
189  }
190  else
191  {
192  heap[j] = e;
193  return elem;
194  }
195  }
196  }
197 
198  if(i < *size && e > heap[i])
199  {
200  heap[j] = heap[i];
201  j = i;
202  }
203 
204  heap[j] = e;
205 
206  return elem;
207 }
208 
209 /************************************************************/
211  : s_mark(0)
212  , s_cact(0)
213  , stage(0)
214  , pivot_col(0)
215  , pivot_colNZ(0)
216  , pivot_row(0)
217  , pivot_rowNZ(0)
218 {}
219 
221 {
222  s_max.reDim(p_dim);
223  spx_realloc(s_cact, p_dim);
224  spx_realloc(s_mark, p_dim);
225  stage = 0;
226 }
227 
229 {
230  if(s_mark != 0)
231  spx_free(s_mark);
232 
233  if(s_cact != 0)
234  spx_free(s_cact);
235 
236  s_max.reDim(0);
237 
238  if(pivot_col != 0)
240 
241  if(pivot_colNZ != 0)
243 
244  if(pivot_row != 0)
246 
247  if(pivot_rowNZ != 0)
249 }
250 
252 {
253  clear();
254 }
255 
256 /************************************************************/
258 {
259 
260  for(int i = 0; i < thedim; ++i)
261  row.orig[i] = row.perm[i] = col.orig[i] = col.perm[i] = -1;
262 }
263 
264 /*****************************************************************************/
265 
266 void CLUFactorRational::setPivot(const int p_stage,
267  const int p_col,
268  const int p_row,
269  const Rational& val)
270 {
271  assert(row.perm[p_row] < 0);
272  assert(col.perm[p_col] < 0);
273 
274  row.orig[p_stage] = p_row;
275  col.orig[p_stage] = p_col;
276  row.perm[p_row] = p_stage;
277  col.perm[p_col] = p_stage;
278  diag[p_row] = 1.0 / val;
279 
280  if(spxAbs(diag[p_row]) > maxabs)
281  maxabs = spxAbs(diag[p_row]);
282 }
283 
284 /*****************************************************************************/
285 /*
286  * Perform garbage collection on row file
287  */
289 {
290  int n, i, j, l_row;
291  Dring* ring, *list;
292 
293  int* l_ridx = u.row.idx;
294  DVectorRational& l_rval = u.row.val;
295  int* l_rlen = u.row.len;
296  int* l_rmax = u.row.max;
297  int* l_rbeg = u.row.start;
298 
299  n = 0;
300  list = &(u.row.list);
301 
302  for(ring = list->next; ring != list; ring = ring->next)
303  {
304  l_row = ring->idx;
305 
306  if(l_rbeg[l_row] != n)
307  {
308  do
309  {
310  l_row = ring->idx;
311  i = l_rbeg[l_row];
312  assert(l_rlen[l_row] <= l_rmax[l_row]);
313  l_rbeg[l_row] = n;
314  l_rmax[l_row] = l_rlen[l_row];
315  j = i + l_rlen[l_row];
316 
317  for(; i < j; ++i, ++n)
318  {
319  assert(n <= i);
320  l_ridx[n] = l_ridx[i];
321  l_rval[n] = l_rval[i];
322  }
323 
324  ring = ring->next;
325  }
326  while(ring != list);
327 
328  goto terminatePackRows;
329  }
330 
331  n += l_rlen[l_row];
332 
333  l_rmax[l_row] = l_rlen[l_row];
334  }
335 
336 terminatePackRows:
337 
338  u.row.max[thedim] = 0;
339  u.row.used = n;
340 }
341 
342 /*****************************************************************************/
343 /*
344  * Perform garbage collection on column file
345  */
347 {
348  int n, i, j, colno;
349  Dring* ring, *list;
350 
351  DVectorRational& cval = u.col.val;
352  int* cidx = u.col.idx;
353  int* clen = u.col.len;
354  int* cmax = u.col.max;
355  int* cbeg = u.col.start;
356 
357  n = 0;
358  list = &u.col.list;
359 
360  for(ring = list->next; ring != list; ring = ring->next)
361  {
362  colno = ring->idx;
363 
364  if(cbeg[colno] != n)
365  {
366  do
367  {
368  colno = ring->idx;
369  i = cbeg[colno];
370  cbeg[colno] = n;
371  cmax[colno] = clen[colno];
372  j = i + clen[colno];
373 
374  for(; i < j; ++i)
375  {
376  cval[n] = cval[i];
377  cidx[n++] = cidx[i];
378  }
379 
380  ring = ring->next;
381  }
382  while(ring != list);
383 
384  goto terminatePackColumns;
385  }
386 
387  n += clen[colno];
388 
389  cmax[colno] = clen[colno];
390  }
391 
392 terminatePackColumns :
393 
394  u.col.used = n;
395  u.col.max[thedim] = 0;
396 }
397 
398 /*
399  * Make row of fac large enough to hold len nonzeros.
400  */
401 void CLUFactorRational::remaxRow(int p_row, int len)
402 {
403  assert(u.row.max[p_row] < len);
404 
405  if(u.row.elem[p_row].next == &(u.row.list)) /* last in row file */
406  {
407  int delta = len - u.row.max[p_row];
408 
409  if(delta > u.row.val.dim() - u.row.used)
410  {
411  packRows();
412  delta = len - u.row.max[p_row]; // packRows() changes u.row.max[] !
413 
414  if(u.row.val.dim() < rowMemMult * u.row.used + len)
415  minRowMem(2 * u.row.used + len);
416 
417  /* minRowMem(rowMemMult * u.row.used + len); */
418  }
419 
420  assert(delta <= u.row.val.dim() - u.row.used
421 
422  && "ERROR: could not allocate memory for row file");
423 
424  u.row.used += delta;
425  u.row.max[p_row] = len;
426  }
427  else /* row must be moved to end of row file */
428  {
429  int i, j, k;
430  DVectorRational& val = u.row.val;
431  Dring* ring;
432 
433  if(len > u.row.val.dim() - u.row.used)
434  {
435  packRows();
436 
437  if(u.row.val.dim() < rowMemMult * u.row.used + len)
438  minRowMem(2 * u.row.used + len);
439 
440  /* minRowMem(rowMemMult * u.row.used + len);*/
441  }
442 
443  assert(len <= u.row.val.dim() - u.row.used
444 
445  && "ERROR: could not allocate memory for row file");
446 
447  int* idx = u.row.idx;
448  j = u.row.used;
449  i = u.row.start[p_row];
450  k = u.row.len[p_row] + i;
451  u.row.start[p_row] = j;
452  u.row.used += len;
453 
454  u.row.max[u.row.elem[p_row].prev->idx] += u.row.max[p_row];
455  u.row.max[p_row] = len;
456  removeDR(u.row.elem[p_row]);
457  ring = u.row.list.prev;
458  init2DR(u.row.elem[p_row], *ring);
459 
460  for(; i < k; ++i, ++j)
461  {
462  val[j] = val[i];
463  idx[j] = idx[i];
464  }
465  }
466 
467  assert(u.row.start[u.row.list.prev->idx] + u.row.max[u.row.list.prev->idx]
468 
469  == u.row.used);
470 }
471 
472 /*************************************************************************/
473 /*
474  * Perform garbage collection on column file
475  */
477 {
478  int n, i, j, l_col;
479  Dring* ring, *list;
480 
481  int* l_cidx = u.col.idx;
482  int* l_clen = u.col.len;
483  int* l_cmax = u.col.max;
484  int* l_cbeg = u.col.start;
485 
486  n = 0;
487  list = &(u.col.list);
488 
489  for(ring = list->next; ring != list; ring = ring->next)
490  {
491  l_col = ring->idx;
492 
493  if(l_cbeg[l_col] != n)
494  {
495  do
496  {
497  l_col = ring->idx;
498  i = l_cbeg[l_col];
499  l_cbeg[l_col] = n;
500  l_cmax[l_col] = l_clen[l_col];
501  j = i + l_clen[l_col];
502 
503  for(; i < j; ++i)
504  l_cidx[n++] = l_cidx[i];
505 
506  ring = ring->next;
507  }
508  while(ring != list);
509 
510  goto terminatePackColumns;
511  }
512 
513  n += l_clen[l_col];
514 
515  l_cmax[l_col] = l_clen[l_col];
516  }
517 
518 terminatePackColumns :
519 
520  u.col.used = n;
521  u.col.max[thedim] = 0;
522 }
523 
524 /*
525  * Make column col of fac large enough to hold len nonzeros.
526  */
527 void CLUFactorRational::remaxCol(int p_col, int len)
528 {
529  assert(u.col.max[p_col] < len);
530 
531  if(u.col.elem[p_col].next == &(u.col.list)) /* last in column file */
532  {
533  int delta = len - u.col.max[p_col];
534 
535  if(delta > u.col.size - u.col.used)
536  {
537  packColumns();
538  delta = len - u.col.max[p_col];
539 
540  if(u.col.size < colMemMult * u.col.used + len)
541  minColMem(2 * u.col.used + len);
542 
543  /* minColMem(colMemMult * u.col.used + len); */
544  }
545 
546  assert(delta <= u.col.size - u.col.used
547 
548  && "ERROR: could not allocate memory for column file");
549 
550  u.col.used += delta;
551  u.col.max[p_col] = len;
552  }
553 
554  else /* column must be moved to end of column file */
555  {
556  int i, j, k;
557  int* idx;
558  Dring* ring;
559 
560  if(len > u.col.size - u.col.used)
561  {
562  packColumns();
563 
564  if(u.col.size < colMemMult * u.col.used + len)
565  minColMem(2 * u.col.used + len);
566 
567  /* minColMem(colMemMult * u.col.used + len); */
568  }
569 
570  assert(len <= u.col.size - u.col.used
571 
572  && "ERROR: could not allocate memory for column file");
573 
574  j = u.col.used;
575  i = u.col.start[p_col];
576  k = u.col.len[p_col] + i;
577  u.col.start[p_col] = j;
578  u.col.used += len;
579 
580  u.col.max[u.col.elem[p_col].prev->idx] += u.col.max[p_col];
581  u.col.max[p_col] = len;
582  removeDR(u.col.elem[p_col]);
583  ring = u.col.list.prev;
584  init2DR(u.col.elem[p_col], *ring);
585 
586  idx = u.col.idx;
587 
588  for(; i < k; ++i)
589  idx[j++] = idx[i];
590  }
591 }
592 
593 /*
594  * Make column col of fac large enough to hold len nonzeros.
595  */
596 void CLUFactorRational::forestReMaxCol(int p_col, int len)
597 {
598  assert(u.col.max[p_col] < len);
599 
600  if(u.col.elem[p_col].next == &(u.col.list)) /* last in column file */
601  {
602  int delta = len - u.col.max[p_col];
603 
604  if(delta > u.col.size - u.col.used)
605  {
607  delta = len - u.col.max[p_col];
608 
609  if(u.col.size < colMemMult * u.col.used + len)
610  forestMinColMem(int(colMemMult * u.col.used + len));
611  }
612 
613  assert(delta <= u.col.size - u.col.used
614 
615  && "ERROR: could not allocate memory for column file");
616 
617  u.col.used += delta;
618  u.col.max[p_col] = len;
619  }
620 
621  else /* column must be moved to end of column file */
622  {
623  int i, j, k;
624  int* idx = u.col.idx;
625  DVectorRational& val = u.col.val;
626  Dring* ring;
627 
628  if(len > u.col.size - u.col.used)
629  {
631 
632  if(u.col.size < colMemMult * u.col.used + len)
633  forestMinColMem(int(colMemMult * u.col.used + len));
634  }
635 
636  assert(len <= u.col.size - u.col.used
637 
638  && "ERROR: could not allocate memory for column file");
639 
640  j = u.col.used;
641  i = u.col.start[p_col];
642  k = u.col.len[p_col] + i;
643  u.col.start[p_col] = j;
644  u.col.used += len;
645 
646  u.col.max[u.col.elem[p_col].prev->idx] += u.col.max[p_col];
647  u.col.max[p_col] = len;
648  removeDR(u.col.elem[p_col]);
649  ring = u.col.list.prev;
650  init2DR(u.col.elem[p_col], *ring);
651 
652  for(; i < k; ++i)
653  {
654  val[j] = val[i];
655  idx[j++] = idx[i];
656  }
657  }
658 }
659 
660 /*****************************************************************************/
661 
662 /**
663  * \brief Performs the Forrest-Tomlin update of the LU factorization.
664  *
665  * BH: I suppose this is implemented as described in UH Suhl, LM Suhl: A fast LU
666  * update for linear programming, Annals of OR 43, p. 33-47, 1993.
667  *
668  * @param p_col Index of basis column to replace.
669  * @param p_work Dense vector to substitute in the basis.
670  * @param num Number of nonzeros in vector represented by p_work.
671  * @param nonz Indices of nonzero elements in vector p_work.
672  *
673  * The parameters num and nonz are used for the following optimization: If both
674  * are nonzero, indices of the nonzero elements provided in nonz (num giving
675  * their number) allow to access only those nonzero entries. Otherwise we have
676  * to go through the entire dense vector element by element.
677  *
678  * After copying p_work into U, p_work is used to expand the row r, which is
679  * needed to restore the triangular structure of U.
680  *
681  * Also num and nonz are used to maintain a heap if there are only very few
682  * nonzeros to be eliminated. This is plainly wrong if the method is called with
683  * nonz==0, see todo at the corresponding place below.
684  *
685  * @throw SPxStatusException if the loaded matrix is singular
686  *
687  * @todo Use an extra member variable as a buffer for working with the dense
688  * row instead of misusing p_work. I think that should be as efficient and
689  * much cleaner.
690  */
691 
692 void CLUFactorRational::forestUpdate(int p_col, Rational* p_work, int num, int* nonz)
693 {
694  int i, j, k, h, m, n;
695  int ll, c, r, rowno;
696  Rational x;
697 
698  int* lbeg = l.start;
699 
700  DVectorRational& cval = u.col.val;
701  int* cidx = u.col.idx;
702  int* cmax = u.col.max;
703  int* clen = u.col.len;
704  int* cbeg = u.col.start;
705 
706  DVectorRational& rval = u.row.val;
707  int* ridx = u.row.idx;
708  int* rmax = u.row.max;
709  int* rlen = u.row.len;
710  int* rbeg = u.row.start;
711 
712  int* rperm = row.perm;
713  int* rorig = row.orig;
714  int* cperm = col.perm;
715  int* corig = col.orig;
716 
717  Rational l_maxabs = maxabs;
718  int dim = thedim;
719 
720  /* Remove column p_col from U
721  */
722  j = cbeg[p_col];
723  i = clen[p_col];
724  nzCnt -= i;
725 
726  for(i += j - 1; i >= j; --i)
727  {
728  m = cidx[i]; // remove column p_col from row m
729  k = rbeg[m];
730  h = --(rlen[m]) + k; // decrease length of row m
731 
732  while(ridx[k] != p_col)
733  ++k;
734 
735  assert(k <= h); // k is the position of p_col, h is last position
736 
737  ridx[k] = ridx[h]; // store last index at the position of p_col
738 
739  rval[k] = rval[h];
740  }
741 
742  /* Insert new vector column p_col thereby determining the highest permuted
743  * row index r.
744  *
745  * Distinguish between optimized call (num > 0, nonz != 0) and
746  * non-optimized one.
747  */
748  assert(num); // otherwise the assert( nonz != 0 ) below should fail
749 
750  if(num)
751  {
752  // Optimized call.
753  assert(nonz != 0);
754 
755  clen[p_col] = 0;
756 
757  if(num > cmax[p_col])
758  forestReMaxCol(p_col, num);
759 
760  cidx = u.col.idx;
761 
762  cval = u.col.val;
763 
764  k = cbeg[p_col];
765 
766  r = 0;
767 
768  for(j = 0; j < num; ++j)
769  {
770  i = nonz[j];
771  x = p_work[i];
772  p_work[i] = 0;
773 
774  if(x != 0)
775  {
776  if(spxAbs(x) > l_maxabs)
777  l_maxabs = spxAbs(x);
778 
779  /* insert to column file */
780  assert(k - cbeg[p_col] < cmax[p_col]);
781 
782  cval[k] = x;
783 
784  cidx[k++] = i;
785 
786  /* insert to row file */
787  if(rmax[i] <= rlen[i])
788  {
789  remaxRow(i, rlen[i] + 1);
790  rval = u.row.val;
791  ridx = u.row.idx;
792  }
793 
794  h = rbeg[i] + (rlen[i])++;
795 
796  rval[h] = x;
797  ridx[h] = p_col;
798 
799  /* check permuted row index */
800 
801  if(rperm[i] > r)
802  r = rperm[i];
803  }
804  }
805 
806  nzCnt += (clen[p_col] = k - cbeg[p_col]);
807  }
808  else
809  {
810  // Non-optimized call: We have to access all elements of p_work.
811  assert(nonz == 0);
812 
813  /*
814  * clen[col] = 0;
815  * reMaxCol(fac, col, dim);
816  */
817  cidx = u.col.idx;
818  cval = u.col.val;
819  k = cbeg[p_col];
820  j = k + cmax[p_col];
821  r = 0;
822 
823  for(i = 0; i < dim; ++i)
824  {
825  x = p_work[i];
826  p_work[i] = 0;
827 
828  if(x != 0)
829  {
830  if(spxAbs(x) > l_maxabs)
831  l_maxabs = spxAbs(x);
832 
833  /* insert to column file */
834  if(k >= j)
835  {
836  clen[p_col] = k - cbeg[p_col];
837  forestReMaxCol(p_col, dim - i);
838  cidx = u.col.idx;
839  cval = u.col.val;
840  k = cbeg[p_col];
841  j = k + cmax[p_col];
842  k += clen[p_col];
843  }
844 
845  assert(k - cbeg[p_col] < cmax[p_col]);
846 
847  cval[k] = x;
848  cidx[k++] = i;
849 
850  /* insert to row file */
851 
852  if(rmax[i] <= rlen[i])
853  {
854  remaxRow(i, rlen[i] + 1);
855  rval = u.row.val;
856  ridx = u.row.idx;
857  }
858 
859  h = rbeg[i] + (rlen[i])++;
860 
861  rval[h] = x;
862  ridx[h] = p_col;
863 
864  /* check permuted row index */
865 
866  if(rperm[i] > r)
867  r = rperm[i];
868  }
869  }
870 
871  nzCnt += (clen[p_col] = k - cbeg[p_col]);
872 
873  if(cbeg[p_col] + cmax[p_col] == u.col.used)
874  {
875  u.col.used -= cmax[p_col];
876  cmax[p_col] = clen[p_col];
877  u.col.used += cmax[p_col];
878  }
879  }
880 
881  c = cperm[p_col];
882 
883  if(r > c) /* Forest Tomlin update */
884  {
885  /* update permutations
886  */
887  j = rorig[c];
888 
889  // memmove is more efficient than a for loop
890  // for ( i = c; i < r; ++i )
891  // rorig[i] = rorig[i + 1];
892  memmove(&rorig[c], &rorig[c + 1], (unsigned int)(r - c) * sizeof(int));
893 
894  rorig[r] = j;
895 
896  for(i = c; i <= r; ++i)
897  rperm[rorig[i]] = i;
898 
899  j = corig[c];
900 
901  // memmove is more efficient than a for loop
902  // for ( i = c; i < r; ++i )
903  // corig[i] = corig[i + 1];
904  memmove(&corig[c], &corig[c + 1], (unsigned int)(r - c) * sizeof(int));
905 
906  corig[r] = j;
907 
908  for(i = c; i <= r; ++i)
909  cperm[corig[i]] = i;
910 
911 
912  rowno = rorig[r];
913 
914  j = rbeg[rowno];
915 
916  i = rlen[rowno];
917 
918  nzCnt -= i;
919 
920  if(i < verySparseFactor * (dim - c)) // few nonzeros to be eliminated
921  {
922  /**
923  * The following assert is obviously violated if this method is called
924  * with nonzero==0.
925  *
926  * @todo Use an extra member variable as a buffer for the heap instead of
927  * misusing nonz and num. The method enQueueMin() seems to
928  * sort the nonzeros or something, for which it only needs
929  * some empty vector of size num.
930  */
931  assert(nonz != 0);
932 
933  /* move row r from U to p_work
934  */
935  num = 0;
936 
937  for(i += j - 1; i >= j; --i)
938  {
939  k = ridx[i];
940  p_work[k] = rval[i];
941  enQueueMin(nonz, &num, cperm[k]);
942  m = --(clen[k]) + cbeg[k];
943 
944  for(h = m; cidx[h] != rowno; --h)
945  ;
946 
947  cidx[h] = cidx[m];
948 
949  cval[h] = cval[m];
950  }
951 
952 
953  /* Eliminate row r from U to L file
954  */
955  ll = makeLvec(r - c, rowno);
956 
957  DVectorRational& lval = l.val;
958  int* lidx = l.idx;
959 
960  assert((num == 0) || (nonz != 0));
961 
962  /* for(i = c; i < r; ++i) */
963  while(num)
964  {
965 #ifndef NDEBUG
966  // The numbers seem to be often 1e-100, is this ok ?
967 
968  for(i = 0; i < num; ++i)
969  assert(p_work[corig[nonz[i]]] != 0);
970 
971 #endif // NDEBUG
972  i = deQueueMin(nonz, &num);
973 
974  if(i == r)
975  break;
976 
977  k = corig[i];
978 
979  assert(p_work[k] != 0);
980 
981  n = rorig[i];
982 
983  x = p_work[k] * diag[n];
984 
985  lidx[ll] = n;
986 
987  lval[ll] = x;
988 
989  p_work[k] = 0;
990 
991  ll++;
992 
993  if(spxAbs(x) > l_maxabs)
994  l_maxabs = spxAbs(x);
995 
996  j = rbeg[n];
997 
998  m = rlen[n] + j;
999 
1000  for(; j < m; ++j)
1001  {
1002  int jj = ridx[j];
1003  Rational y = p_work[jj];
1004 
1005  if(y == 0)
1006  enQueueMin(nonz, &num, cperm[jj]);
1007 
1008  y -= x * rval[j];
1009 
1010  //p_work[jj] = y + (( y == 0 ) ? MARKER : 0 );
1011  p_work[jj] = y;
1012  }
1013  }
1014 
1015  if(lbeg[l.firstUnused - 1] == ll)
1016  (l.firstUnused)--;
1017  else
1018  lbeg[l.firstUnused] = ll;
1019 
1020 
1021  /* Set diagonal value
1022  */
1023  if(i != r)
1024  {
1026  throw SPxStatusException("XFORE01 The loaded matrix is singular");
1027  }
1028 
1029  k = corig[r];
1030 
1031  x = p_work[k];
1032  diag[rowno] = 1 / x;
1033  p_work[k] = 0;
1034 
1035 
1036  /* make row large enough to fit all nonzeros.
1037  */
1038 
1039  if(rmax[rowno] < num)
1040  {
1041  rlen[rowno] = 0;
1042  remaxRow(rowno, num);
1043  rval = u.row.val;
1044  ridx = u.row.idx;
1045  }
1046 
1047  nzCnt += num;
1048 
1049  /* Insert work to updated row thereby clearing work;
1050  */
1051  n = rbeg[rowno];
1052 
1053  for(i = 0; i < num; ++i)
1054  {
1055  j = corig[nonz[i]];
1056  x = p_work[j];
1057 
1058  // BH 2005-08-24: This if is very important. It may well happen that
1059  // during the elimination of row r a nonzero elements cancels out
1060  // and becomes zero. This would lead to an infinite loop in the
1061  // above elimination code, since the corresponding column index would
1062  // be enqueued for further elimination again and agian.
1063 
1064  if(x != 0)
1065  {
1066  if(spxAbs(x) > l_maxabs)
1067  l_maxabs = spxAbs(x);
1068 
1069  ridx[n] = j;
1070 
1071  rval[n] = x;
1072 
1073  p_work[j] = 0;
1074 
1075  ++n;
1076 
1077  if(clen[j] >= cmax[j])
1078  {
1079  forestReMaxCol(j, clen[j] + 1);
1080  cidx = u.col.idx;
1081  cval = u.col.val;
1082  }
1083 
1084  cval[cbeg[j] + clen[j]] = x;
1085 
1086  cidx[cbeg[j] + clen[j]++] = rowno;
1087  }
1088  }
1089 
1090  rlen[rowno] = n - rbeg[rowno];
1091  }
1092  else /* few nonzeros to be eliminated */
1093  {
1094  /* move row r from U to p_work
1095  */
1096  for(i += j - 1; i >= j; --i)
1097  {
1098  k = ridx[i];
1099  p_work[k] = rval[i];
1100  m = --(clen[k]) + cbeg[k];
1101 
1102  for(h = m; cidx[h] != rowno; --h)
1103  ;
1104 
1105  cidx[h] = cidx[m];
1106 
1107  cval[h] = cval[m];
1108  }
1109 
1110 
1111  /* Eliminate row r from U to L file
1112  */
1113  ll = makeLvec(r - c, rowno);
1114 
1115  DVectorRational& lval = l.val;
1116  int* lidx = l.idx;
1117 
1118  for(i = c; i < r; ++i)
1119  {
1120  k = corig[i];
1121 
1122  if(p_work[k] != 0)
1123  {
1124  n = rorig[i];
1125  x = p_work[k] * diag[n];
1126  lidx[ll] = n;
1127  lval[ll] = x;
1128  p_work[k] = 0;
1129  ll++;
1130 
1131  if(spxAbs(x) > l_maxabs)
1132  l_maxabs = spxAbs(x);
1133 
1134  j = rbeg[n];
1135 
1136  m = rlen[n] + j;
1137 
1138  for(; j < m; ++j)
1139  p_work[ridx[j]] -= x * rval[j];
1140  }
1141  }
1142 
1143  if(lbeg[l.firstUnused - 1] == ll)
1144  (l.firstUnused)--;
1145  else
1146  lbeg[l.firstUnused] = ll;
1147 
1148 
1149  /* Set diagonal value
1150  */
1151  k = corig[r];
1152 
1153  x = p_work[k];
1154 
1155  if(x == 0)
1156  {
1158  throw SPxStatusException("XFORE02 The loaded matrix is singular");
1159  // return;
1160  }
1161 
1162  diag[rowno] = 1 / x;
1163 
1164  p_work[k] = 0;
1165 
1166 
1167  /* count remaining nonzeros in work and make row large enough
1168  * to fit them all.
1169  */
1170  n = 0;
1171 
1172  for(i = r + 1; i < dim; ++i)
1173  if(p_work[corig[i]] != 0)
1174  n++;
1175 
1176  if(rmax[rowno] < n)
1177  {
1178  rlen[rowno] = 0;
1179  remaxRow(rowno, n);
1180  rval = u.row.val;
1181  ridx = u.row.idx;
1182  }
1183 
1184  nzCnt += n;
1185 
1186  /* Insert p_work to updated row thereby clearing p_work;
1187  */
1188  n = rbeg[rowno];
1189 
1190  for(i = r + 1; i < dim; ++i)
1191  {
1192  j = corig[i];
1193  x = p_work[j];
1194 
1195  if(x != 0)
1196  {
1197  if(spxAbs(x) > l_maxabs)
1198  l_maxabs = spxAbs(x);
1199 
1200  ridx[n] = j;
1201 
1202  rval[n] = x;
1203 
1204  p_work[j] = 0;
1205 
1206  ++n;
1207 
1208  if(clen[j] >= cmax[j])
1209  {
1210  forestReMaxCol(j, clen[j] + 1);
1211  cidx = u.col.idx;
1212  cval = u.col.val;
1213  }
1214 
1215  cval[cbeg[j] + clen[j]] = x;
1216 
1217  cidx[cbeg[j] + clen[j]++] = rowno;
1218  }
1219  }
1220 
1221  rlen[rowno] = n - rbeg[rowno];
1222  }
1223  }
1224 
1225  else if(r == c)
1226  {
1227  /* Move diagonal element to diag. Note, that it must be the last
1228  * element, since it has just been inserted above.
1229  */
1230  rowno = rorig[r];
1231  i = rbeg[rowno] + --(rlen[rowno]);
1232  diag[rowno] = 1 / rval[i];
1233 
1234  for(j = i = --(clen[p_col]) + cbeg[p_col]; cidx[i] != rowno; --i)
1235  ;
1236 
1237  cidx[i] = cidx[j];
1238 
1239  cval[i] = cval[j];
1240  }
1241  else /* r < c */
1242  {
1244  throw SPxStatusException("XFORE03 The loaded matrix is singular");
1245  // return;
1246  }
1247 
1248  maxabs = l_maxabs;
1249 
1250  assert(isConsistent());
1252 }
1253 
1254 void CLUFactorRational::update(int p_col, Rational* p_work, const int* p_idx, int num)
1255 {
1256  int ll, i, j;
1257  Rational x, rezi;
1258 
1259  assert(p_work[p_col] != 0);
1260  rezi = 1 / p_work[p_col];
1261  p_work[p_col] = 0;
1262 
1263  ll = makeLvec(num, p_col);
1264  // ll = fac->makeLvec(num, col);
1265  DVectorRational& lval = l.val;
1266  int* lidx = l.idx;
1267 
1268  for(i = num - 1; (j = p_idx[i]) != p_col; --i)
1269  {
1270  lidx[ll] = j;
1271  lval[ll] = rezi * p_work[j];
1272  p_work[j] = 0;
1273  ++ll;
1274  }
1275 
1276  lidx[ll] = p_col;
1277 
1278  lval[ll] = 1 - rezi;
1279  ++ll;
1280 
1281  for(--i; i >= 0; --i)
1282  {
1283  j = p_idx[i];
1284  lidx[ll] = j;
1285  lval[ll] = x = rezi * p_work[j];
1286  p_work[j] = 0;
1287  ++ll;
1288 
1289  if(spxAbs(x) > maxabs)
1290  maxabs = spxAbs(x);
1291  }
1292 
1294 }
1295 
1297  int p_col,
1298  const Rational* p_work,
1299  const int* p_idx,
1300  int num)
1301 {
1302  int ll, i, j;
1303  Rational x, rezi;
1304 
1305  assert(p_work[p_col] != 0);
1306  rezi = 1 / p_work[p_col];
1307  ll = makeLvec(num, p_col);
1308  //ll = fac->makeLvec(num, col);
1309  DVectorRational& lval = l.val;
1310  int* lidx = l.idx;
1311 
1312  for(i = num - 1; (j = p_idx[i]) != p_col; --i)
1313  {
1314  lidx[ll] = j;
1315  lval[ll] = rezi * p_work[j];
1316  ++ll;
1317  }
1318 
1319  lidx[ll] = p_col;
1320 
1321  lval[ll] = 1 - rezi;
1322  ++ll;
1323 
1324  for(--i; i >= 0; --i)
1325  {
1326  j = p_idx[i];
1327  lidx[ll] = j;
1328  lval[ll] = x = rezi * p_work[j];
1329  ++ll;
1330 
1331  if(spxAbs(x) > maxabs)
1332  maxabs = spxAbs(x);
1333  }
1334 
1336 }
1337 
1338 /*****************************************************************************/
1339 /*
1340  * Temporary data structures.
1341  */
1342 
1343 /*
1344  * For the i=th column the situation might look like this:
1345  *
1346  * \begin{verbatim}
1347  * idx = ....................iiiIIIIII-----..............
1348  * cbeg[i] = ^
1349  * cact[i] = +----+
1350  * clen[i] = +-------+
1351  * cmax[i] = +------------+
1352  *
1353  * Indices clen[i]-cbeg[i]: ^^^
1354  * \end{verbatim}
1355  * belong to column i, but have already been pivotal and don't belong to
1356  * the active submatrix.
1357  */
1358 
1359 /****************************************************************************/
1360 /*
1361  * Initialize row and column file of working matrix and
1362  * mark column singletons.
1363  */
1365 {
1366 
1367  Rational x;
1368  int m;
1369  int tot;
1370  Dring* rring, *lastrring;
1371  Dring* cring, *lastcring;
1372  const SVectorRational* psv;
1373  int* sing = temp.s_mark;
1374 
1375  /* Initialize:
1376  * - column file thereby remembering column singletons in |sing|.
1377  * - nonzeros counts per row
1378  * - total number of nonzeros
1379  */
1380 
1381  for(int i = 0; i < thedim; i++)
1382  u.row.max[i] = u.row.len[i] = 0;
1383 
1384  tot = 0;
1385 
1386  for(int i = 0; i < thedim; i++)
1387  {
1388  int k;
1389 
1390  psv = vec[i];
1391  k = psv->size();
1392 
1393  if(k > 1)
1394  {
1395  tot += k;
1396 
1397  for(int j = 0; j < k; ++j)
1398  u.row.max[psv->index(j)]++;
1399  }
1400  else if(k == 0)
1401  {
1403  return;
1404  }
1405  }
1406 
1407  /* Resize nonzero memory if necessary
1408  */
1409  minRowMem(int(rowMemMult * tot));
1410 
1411  minColMem(int(colMemMult * tot));
1412 
1413  minLMem(int(lMemMult * tot));
1414 
1415 
1416  /* Initialize:
1417  * - row ring lists
1418  * - row vectors in file
1419  * - column ring lists
1420  */
1421  u.row.start[0] = 0;
1422 
1423  rring = u.row.elem;
1424 
1425  lastrring = &(u.row.list);
1426 
1427  lastrring->idx = thedim;
1428 
1429  lastrring->next = rring;
1430 
1431  cring = u.col.elem;
1432 
1433  lastcring = &(u.col.list);
1434 
1435  lastcring->idx = thedim;
1436 
1437  lastcring->next = cring;
1438 
1439  m = 0;
1440 
1441  for(int i = 0; i < thedim; i++)
1442  {
1443  u.row.start[i] = m;
1444  m += u.row.max[i];
1445 
1446  rring->idx = i;
1447  rring->prev = lastrring;
1448  lastrring->next = rring;
1449  lastrring = rring;
1450  ++rring;
1451 
1452  cring->idx = i;
1453  cring->prev = lastcring;
1454  lastcring->next = cring;
1455  lastcring = cring;
1456  ++cring;
1457  }
1458 
1459  u.row.start[thedim] = 0;
1460 
1461  u.row.max[thedim] = 0;
1462  u.row.used = m;
1463 
1464  lastrring->next = &(u.row.list);
1465  lastrring->next->prev = lastrring;
1466 
1467  lastcring->next = &(u.col.list);
1468  lastcring->next->prev = lastcring;
1469 
1470  /* Copy matrix to row and column file
1471  * excluding and marking column singletons!
1472  */
1473  m = 0;
1474  temp.stage = 0;
1475 
1476  initMaxabs = 0;
1477 
1478  for(int i = 0; i < thedim; i++)
1479  {
1480  int nnonzeros;
1481 
1482  psv = vec[i];
1483  u.col.start[i] = m;
1484 
1485  /* check whether number of nonzeros above tolerance is 0, 1 or >= 2 */
1486  nnonzeros = 0;
1487 
1488  for(int j = 0; j < psv->size() && nnonzeros <= 1; j++)
1489  {
1490  if(psv->value(j) != 0)
1491  nnonzeros++;
1492  }
1493 
1494  /* basis is singular due to empty column */
1495  if(nnonzeros == 0)
1496  {
1498  return;
1499  }
1500 
1501  /* exclude column singletons */
1502  else if(nnonzeros == 1)
1503  {
1504  int j;
1505 
1506  /* find nonzero */
1507 
1508  for(j = 0; psv->value(j) == 0; j++)
1509  ;
1510 
1511  assert(j < psv->size());
1512 
1513  /* basis is singular due to two linearly dependent column singletons */
1514  if(row.perm[psv->index(j)] >= 0)
1515  {
1517  return;
1518  }
1519 
1520  /* update maximum absolute nonzero value */
1521  x = psv->value(j);
1522 
1523  if(spxAbs(x) > initMaxabs)
1524  initMaxabs = spxAbs(x);
1525 
1526  /* permute to front and mark as singleton */
1527  setPivot(temp.stage, i, psv->index(j), x);
1528 
1529  sing[temp.stage] = i;
1530 
1531  temp.stage++;
1532 
1533  /* set column length to zero */
1534  temp.s_cact[i] = u.col.len[i] = u.col.max[i] = 0;
1535  }
1536 
1537  /* add to active matrix if not a column singleton */
1538  else
1539  {
1540  int end;
1541  int k;
1542 
1543  /* go through all nonzeros in column */
1544  assert(nnonzeros >= 2);
1545  nnonzeros = 0;
1546 
1547  for(int j = 0; j < psv->size(); j++)
1548  {
1549  x = psv->value(j);
1550 
1551  if(x != 0)
1552  {
1553  /* add to column array */
1554  k = psv->index(j);
1555  u.col.idx[m] = k;
1556  m++;
1557 
1558  /* add to row array */
1559  end = u.row.start[k] + u.row.len[k];
1560  u.row.idx[end] = i;
1561  u.row.val[end] = x;
1562  u.row.len[k]++;
1563 
1564  /* update maximum absolute nonzero value */
1565 
1566  if(spxAbs(x) > initMaxabs)
1567  initMaxabs = spxAbs(x);
1568 
1569  nnonzeros++;
1570  }
1571  }
1572 
1573  assert(nnonzeros >= 2);
1574 
1575  /* set column length */
1576  temp.s_cact[i] = u.col.len[i] = u.col.max[i] = nnonzeros;
1577  }
1578  }
1579 
1580  u.col.used = m;
1581 }
1582 
1583 
1584 
1585 /*****************************************************************************/
1586 /*
1587  * Remove column singletons
1588  */
1589 
1591 {
1592  int i, j, k, n;
1593  int len;
1594  int p_col, p_row, newrow;
1595  int* idx;
1596  int* rorig = row.orig;
1597  int* rperm = row.perm;
1598  int* sing = temp.s_mark;
1599 
1600 
1601  /* Iteratively update column counts due to removed column singletons
1602  * thereby removing new arising columns singletons
1603  * and computing the index of the first row singleton (-1)
1604  * until no more can be found.
1605  */
1606 
1607  for(i = 0; i < temp.stage; ++i)
1608  {
1609  p_row = rorig[i];
1610  assert(p_row >= 0);
1611  idx = &(u.row.idx[u.row.start[p_row]]);
1612  len = u.row.len[p_row];
1613 
1614  for(j = 0; j < len; ++j)
1615  {
1616  /* Move pivotal nonzeros to front of column.
1617  */
1618  p_col = idx[j];
1619  assert(temp.s_cact[p_col] > 0);
1620 
1621  n = u.col.start[p_col] + u.col.len[p_col] - temp.s_cact[p_col];
1622 
1623  for(k = n; u.col.idx[k] != p_row; ++k)
1624  ;
1625 
1626  assert(k < u.col.start[p_col] + u.col.len[p_col]);
1627 
1628  u.col.idx[k] = u.col.idx[n];
1629 
1630  u.col.idx[n] = p_row;
1631 
1632  n = --(temp.s_cact[p_col]); /* column nonzeros of ACTIVE matrix */
1633 
1634  if(n == 1) /* Here is another singleton */
1635  {
1636  newrow = u.col.idx[--u.col.len[p_col] + u.col.start[p_col]];
1637 
1638  /* Ensure, matrix not singular
1639  */
1640 
1641  if(rperm[newrow] >= 0)
1642  {
1644  return;
1645  }
1646 
1647  /* Find singleton in row.
1648  */
1649  n = u.row.start[newrow] + (--(u.row.len[newrow]));
1650 
1651  for(k = n; u.row.idx[k] != p_col; --k)
1652  ;
1653 
1654  /* Remove singleton from column.
1655  */
1656  setPivot(temp.stage, p_col, newrow, u.row.val[k]);
1657 
1658  sing[temp.stage++] = p_col;
1659 
1660  /* Move pivot element to diag.
1661  */
1662  u.row.val[k] = u.row.val[n];
1663 
1664  u.row.idx[k] = u.row.idx[n];
1665  }
1666  else if(n == 0)
1667  {
1669  return;
1670  }
1671  }
1672  }
1673 
1674  assert(temp.stage <= thedim);
1675 }
1676 
1677 
1678 /*****************************************************************************/
1679 /*
1680  * Remove row singletons
1681  */
1683 {
1684  Rational pval;
1685  int i, j, k, ll, r;
1686  int p_row, p_col, len, rs, lk;
1687  int* idx;
1688  int* rperm = row.perm;
1689  int* sing = temp.s_mark;
1690 
1691  /* Mark row singletons
1692  */
1693  rs = temp.stage;
1694 
1695  for(i = 0; i < thedim; ++i)
1696  {
1697  if(rperm[i] < 0 && u.row.len[i] == 1)
1698  sing[temp.stage++] = i;
1699  }
1700 
1701  /* Eliminate row singletons
1702  * thereby marking newly arising ones
1703  * until no more can be found.
1704  */
1705  for(; rs < temp.stage; ++rs)
1706  {
1707  /* Move pivot element from row file to diag
1708  */
1709  p_row = sing[rs];
1710  j = u.row.start[p_row];
1711  p_col = u.row.idx[j];
1712  pval = u.row.val[j];
1713  setPivot(rs, p_col, p_row, pval);
1714  u.row.len[p_row] = 0;
1715 
1716  /* Remove pivot column form workingmatrix
1717  * thereby building up L vector.
1718  */
1719  idx = &(u.col.idx[u.col.start[p_col]]);
1720  i = temp.s_cact[p_col]; /* nr. nonzeros of new L vector */
1721  lk = makeLvec(i - 1, p_row);
1722  len = u.col.len[p_col];
1723  i = (u.col.len[p_col] -= i); /* remove pivot column from U */
1724 
1725  for(; i < len; ++i)
1726  {
1727  r = idx[i];
1728 
1729  if(r != p_row)
1730  {
1731  /* Find pivot column in row.
1732  */
1733  ll = --(u.row.len[r]);
1734  k = u.row.start[r] + ll;
1735 
1736  for(j = k; u.row.idx[j] != p_col; --j)
1737  ;
1738 
1739  assert(k >= u.row.start[r]);
1740 
1741  /* Initialize L vector
1742  */
1743  l.idx[lk] = r;
1744 
1745  l.val[lk] = u.row.val[j] / pval;
1746 
1747  ++lk;
1748 
1749  /* Remove pivot column from row.
1750  */
1751  u.row.idx[j] = u.row.idx[k];
1752 
1753  u.row.val[j] = u.row.val[k];
1754 
1755  /* Check new row length.
1756  */
1757  if(ll == 1)
1758  sing[temp.stage++] = r;
1759  else if(ll == 0)
1760  {
1762  return;
1763  }
1764  }
1765  }
1766  }
1767 }
1768 
1769 
1770 /*****************************************************************************/
1771 /*
1772  * Init nonzero number Ring lists
1773  * and required entries of arrays max and mark
1774  */
1775 
1777 {
1778  int i;
1779  int* rperm = row.perm;
1780  int* cperm = col.perm;
1782 
1783  assert(thedim >= 0);
1788 
1789  for(i = thedim - temp.stage; i >= 0; --i)
1790  {
1791  initDR(temp.pivot_colNZ[i]);
1792  initDR(temp.pivot_rowNZ[i]);
1793  }
1794 
1795  for(i = 0; i < thedim; ++i)
1796  {
1797  if(rperm[i] < 0)
1798  {
1799  if(u.row.len[i] <= 0)
1800  {
1802  return;
1803  }
1804 
1805  ring = &(temp.pivot_rowNZ[u.row.len[i]]);
1806 
1807  init2DR(temp.pivot_row[i], *ring);
1808  temp.pivot_row[i].idx = i;
1809  temp.s_max[i] = -1;
1810  }
1811 
1812  if(cperm[i] < 0)
1813  {
1814  if(temp.s_cact[i] <= 0)
1815  {
1817  return;
1818  }
1819 
1820  ring = &(temp.pivot_colNZ[temp.s_cact[i]]);
1821 
1822  init2DR(temp.pivot_col[i], *ring);
1823  temp.pivot_col[i].idx = i;
1824  temp.s_mark[i] = 0;
1825  }
1826  }
1827 }
1828 
1830 {
1831 
1832  if(temp.pivot_col)
1834 
1835  if(temp.pivot_colNZ)
1837 
1838  if(temp.pivot_row)
1840 
1841  if(temp.pivot_rowNZ)
1843 }
1844 
1845 
1846 /*
1847  * Eliminate all row singletons from nucleus.
1848  * A row singleton may well be column singleton at the same time!
1849  */
1851 {
1852  int i, j, k, ll, r;
1853  int len, lk;
1854  int pcol, prow;
1855  Rational pval;
1856  int* idx;
1858 
1859  for(sing = temp.pivot_rowNZ[1].prev; sing != &(temp.pivot_rowNZ[1]); sing = sing->prev)
1860  {
1861  prow = sing->idx;
1862  i = u.row.start[prow];
1863  pcol = u.row.idx[i];
1864  pval = u.row.val[i];
1865  setPivot(temp.stage++, pcol, prow, pval);
1866  u.row.len[prow] = 0;
1867  removeDR(temp.pivot_col[pcol]);
1868 
1869  /* Eliminate pivot column and build L vector.
1870  */
1871  i = temp.s_cact[pcol];
1872 
1873  if(i > 1)
1874  {
1875  idx = &(u.col.idx[u.col.start[pcol]]);
1876  len = u.col.len[pcol];
1877  lk = makeLvec(i - 1, prow);
1878  i = u.col.len[pcol] -= i;
1879 
1880  for(; (r = idx[i]) != prow; ++i)
1881  {
1882  /* Find pivot column in row.
1883  */
1884  ll = --(u.row.len[r]);
1885  k = u.row.start[r] + ll;
1886 
1887  for(j = k; u.row.idx[j] != pcol; --j)
1888  ;
1889 
1890  assert(j >= u.row.start[r]);
1891 
1892  /* Initialize L vector
1893  */
1894  l.idx[lk] = r;
1895 
1896  l.val[lk] = u.row.val[j] / pval;
1897 
1898  ++lk;
1899 
1900  /* Remove pivot column from row.
1901  */
1902  u.row.idx[j] = u.row.idx[k];
1903 
1904  u.row.val[j] = u.row.val[k];
1905 
1906  /* Move column to appropriate nonzero ring.
1907  */
1908  removeDR(temp.pivot_row[r]);
1909 
1911 
1912  assert(row.perm[r] < 0);
1913 
1914  temp.s_max[r] = -1;
1915  }
1916 
1917  /* skip pivot element */
1918  assert(i < len && "ERROR: pivot column does not contain pivot row");
1919 
1920  for(++i; i < len; ++i)
1921  {
1922  /* Find pivot column in row.
1923  */
1924  r = idx[i];
1925  ll = --(u.row.len[r]);
1926  k = u.row.start[r] + ll;
1927 
1928  for(j = k; u.row.idx[j] != pcol; --j)
1929  ;
1930 
1931  assert(j >= u.row.start[r]);
1932 
1933  /* Initialize L vector
1934  */
1935  l.idx[lk] = r;
1936 
1937  l.val[lk] = u.row.val[j] / pval;
1938 
1939  ++lk;
1940 
1941  /* Remove pivot column from row.
1942  */
1943  u.row.idx[j] = u.row.idx[k];
1944 
1945  u.row.val[j] = u.row.val[k];
1946 
1947  /* Move column to appropriate nonzero ring.
1948  */
1949  removeDR(temp.pivot_row[r]);
1950 
1952 
1953  assert(row.perm[r] < 0);
1954 
1955  temp.s_max[r] = -1;
1956  }
1957  }
1958  else
1959  u.col.len[pcol] -= i;
1960  }
1961 
1962  initDR(temp.pivot_rowNZ[1]); /* Remove all row singletons from list */
1963 }
1964 
1965 
1966 
1967 /*
1968  * Eliminate all column singletons from nucleus.
1969  * A column singleton must not be row singleton at the same time!
1970  */
1972 {
1973  int i, j, k, m, c;
1974  int pcol, prow;
1976 
1977  for(sing = temp.pivot_colNZ[1].prev;
1978  sing != &(temp.pivot_colNZ[1]);
1979  sing = sing->prev)
1980  {
1981  /* Find pivot value
1982  */
1983  pcol = sing->idx;
1984  j = --(u.col.len[pcol]) + u.col.start[pcol]; /* remove pivot column */
1985  prow = u.col.idx[j];
1986  removeDR(temp.pivot_row[prow]);
1987 
1988  j = --(u.row.len[prow]) + u.row.start[prow];
1989 
1990  for(i = j; (c = u.row.idx[i]) != pcol; --i)
1991  {
1992  m = u.col.len[c] + u.col.start[c] - (temp.s_cact[c])--;
1993 
1994  for(k = m; u.col.idx[k] != prow; ++k)
1995  ;
1996 
1997  u.col.idx[k] = u.col.idx[m];
1998 
1999  u.col.idx[m] = prow;
2000 
2001  m = temp.s_cact[c];
2002 
2003  removeDR(temp.pivot_col[c]);
2004 
2006 
2007  assert(col.perm[c] < 0);
2008  }
2009 
2010  /* remove pivot element from pivot row
2011  */
2012  setPivot(temp.stage++, pcol, prow, u.row.val[i]);
2013 
2014  u.row.idx[i] = u.row.idx[j];
2015 
2016  u.row.val[i] = u.row.val[j];
2017 
2018  j = u.row.start[prow];
2019 
2020  for(--i; i >= j; --i)
2021  {
2022  c = u.row.idx[i];
2023  m = u.col.len[c] + u.col.start[c] - (temp.s_cact[c])--;
2024 
2025  for(k = m; u.col.idx[k] != prow; ++k)
2026  ;
2027 
2028  u.col.idx[k] = u.col.idx[m];
2029 
2030  u.col.idx[m] = prow;
2031 
2032  m = temp.s_cact[c];
2033 
2034  removeDR(temp.pivot_col[c]);
2035 
2037 
2038  assert(col.perm[c] < 0);
2039  }
2040  }
2041 
2042  initDR(temp.pivot_colNZ[1]); /* Remove all column singletons from list */
2043 }
2044 
2045 /*
2046  * No singletons available: Select pivot elements.
2047  */
2049 {
2050  int ii;
2051  int i;
2052  int j;
2053  int k;
2054  int ll = -1; // This value should never be used.
2055  int kk;
2056  int m;
2057  int count;
2058  int num;
2059  int rw = -1; // This value should never be used.
2060  int cl = -1; // This value should never be used.
2061  int len;
2062  int beg;
2063  Rational l_maxabs;
2064  Rational x = 0; // This value should never be used.
2065  int mkwtz;
2066  int candidates;
2067 
2068  candidates = thedim - temp.stage - 1;
2069 
2070  if(candidates > 4)
2071  candidates = 4;
2072 
2073  num = 0;
2074 
2075  count = 2;
2076 
2077  for(;;)
2078  {
2079  ii = -1;
2080 
2081  if(temp.pivot_rowNZ[count].next != &(temp.pivot_rowNZ[count]))
2082  {
2083  rw = temp.pivot_rowNZ[count].next->idx;
2084  beg = u.row.start[rw];
2085  len = u.row.len[rw] + beg - 1;
2086 
2087  /* set l_maxabs to maximum absolute value in row
2088  * (compute it if necessary).
2089  */
2090 
2091  if(temp.s_max[rw] < 0)
2092  {
2093  l_maxabs = spxAbs(u.row.val[len]);
2094 
2095  for(i = len - 1; i >= beg; --i)
2096  if(l_maxabs < spxAbs(u.row.val[i]))
2097  l_maxabs = spxAbs(u.row.val[i]);
2098 
2099  temp.s_max[rw] = l_maxabs; /* ##### */
2100  }
2101  else
2102  l_maxabs = temp.s_max[rw];
2103 
2104  l_maxabs *= threshold;
2105 
2106  /* select pivot element with lowest markowitz number in row
2107  */
2108  mkwtz = thedim + 1;
2109 
2110  for(i = len; i >= beg; --i)
2111  {
2112  k = u.row.idx[i];
2113  j = temp.s_cact[k];
2114  x = u.row.val[i];
2115 
2116  if(j < mkwtz && spxAbs(x) > l_maxabs)
2117  {
2118  mkwtz = j;
2119  cl = k;
2120  ii = i;
2121 
2122  if(j <= count) /* ##### */
2123  break;
2124  }
2125  }
2126  }
2127  else if(temp.pivot_colNZ[count].next != &(temp.pivot_colNZ[count]))
2128  {
2129  cl = temp.pivot_colNZ[count].next->idx;
2130  beg = u.col.start[cl];
2131  len = u.col.len[cl] + beg - 1;
2132  beg = len - temp.s_cact[cl] + 1;
2133  assert(count == temp.s_cact[cl]);
2134 
2135  /* select pivot element with lowest markowitz number in column
2136  */
2137  mkwtz = thedim + 1;
2138 
2139  for(i = len; i >= beg; --i)
2140  {
2141  k = u.col.idx[i];
2142  j = u.row.len[k];
2143 
2144  if(j < mkwtz)
2145  {
2146  /* ensure that element (cl,k) is stable.
2147  */
2148  if(temp.s_max[k] > 0)
2149  {
2150  /* case 1: l_maxabs is known
2151  */
2152  for(m = u.row.start[k], kk = m + u.row.len[k] - 1;
2153  kk >= m; --kk)
2154  {
2155  if(u.row.idx[kk] == cl)
2156  {
2157  x = u.row.val[kk];
2158  ll = kk;
2159  break;
2160  }
2161  }
2162 
2163  l_maxabs = temp.s_max[k];
2164  }
2165  else
2166  {
2167  /* case 2: l_maxabs needs to be computed
2168  */
2169  m = u.row.start[k];
2170  l_maxabs = spxAbs(u.row.val[m]);
2171 
2172  for(kk = m + u.row.len[k] - 1; kk >= m; --kk)
2173  {
2174  if(l_maxabs < spxAbs(u.row.val[kk]))
2175  l_maxabs = spxAbs(u.row.val[kk]);
2176 
2177  if(u.row.idx[kk] == cl)
2178  {
2179  x = u.row.val[kk];
2180  ll = kk;
2181  break;
2182  }
2183  }
2184 
2185  for(--kk; kk > m; --kk)
2186  {
2187  if(l_maxabs < spxAbs(u.row.val[kk]))
2188  l_maxabs = spxAbs(u.row.val[kk]);
2189  }
2190 
2191  temp.s_max[k] = l_maxabs;
2192  }
2193 
2194  l_maxabs *= threshold;
2195 
2196  if(spxAbs(x) > l_maxabs)
2197  {
2198  mkwtz = j;
2199  rw = k;
2200  ii = ll;
2201 
2202  if(j <= count + 1)
2203  break;
2204  }
2205  }
2206  }
2207  }
2208  else
2209  {
2210  ++count;
2211  continue;
2212  }
2213 
2214  assert(cl >= 0);
2215 
2216  removeDR(temp.pivot_col[cl]);
2217  initDR(temp.pivot_col[cl]);
2218 
2219  if(ii >= 0)
2220  {
2221  /* Initialize selected pivot element
2222  */
2224  temp.pivot_row[rw].pos = ii - u.row.start[rw];
2225  temp.pivot_row[rw].mkwtz = mkwtz = (mkwtz - 1) * (count - 1);
2226  // ??? mkwtz originally was long,
2227  // maybe to avoid an overflow in this instruction?
2228 
2229  for(pr = temp.pivots.next; pr->idx >= 0; pr = pr->next)
2230  {
2231  if(pr->idx == rw || pr->mkwtz >= mkwtz)
2232  break;
2233  }
2234 
2235  pr = pr->prev;
2236 
2237  if(pr->idx != rw)
2238  {
2239  removeDR(temp.pivot_row[rw]);
2240  init2DR(temp.pivot_row[rw], *pr);
2241  }
2242 
2243  num++;
2244 
2245  if(num >= candidates)
2246  break;
2247  }
2248  }
2249 
2250  /*
2251  * while(temp.temp.next->mkwtz < temp.temp.prev->mkwtz)
2252  * {
2253  * Pring *pr;
2254  * pr = temp.temp.prev;
2255  * removeDR(*pr);
2256  * init2DR (*pr, rowNZ[u.row.len[pr->idx]]);
2257  }
2258  */
2259 
2260  assert(row.perm[rw] < 0);
2261 
2262  assert(col.perm[cl] < 0);
2263 }
2264 
2265 
2266 /*
2267  * Perform L and update loop for row r
2268  */
2270  int lv,
2271  int prow,
2272  int pcol,
2273  const Rational& pval)
2274 {
2275  int fill;
2276  Rational x, lx;
2277  int c, i, j, k, ll, m, n;
2278 
2279  n = u.row.start[r];
2280  m = --(u.row.len[r]) + n;
2281 
2282  /* compute L vector entry and
2283  * and remove pivot column form row file
2284  */
2285 
2286  for(j = m; u.row.idx[j] != pcol; --j)
2287  ;
2288 
2289  lx = u.row.val[j] / pval;
2290 
2291  l.val[lv] = lx;
2292 
2293  l.idx[lv] = r;
2294 
2295  ++lv;
2296 
2297  u.row.idx[j] = u.row.idx[m];
2298 
2299  u.row.val[j] = u.row.val[m];
2300 
2301 
2302  /* update loop (I) and
2303  * computing expected fill
2304  */
2305  fill = u.row.len[prow];
2306 
2307  for(j = m - 1; j >= n; --j)
2308  {
2309  c = u.row.idx[j];
2310 
2311  if(temp.s_mark[c])
2312  {
2313  /* count fill elements.
2314  */
2315  temp.s_mark[c] = 0;
2316  --fill;
2317 
2318  /* update row values
2319  */
2320  x = u.row.val[j] -= work[c] * lx;
2321 
2322  if(x == 0)
2323  {
2324  /* Eliminate zero from row r
2325  */
2326  --u.row.len[r];
2327  --m;
2328  u.row.val[j] = u.row.val[m];
2329  u.row.idx[j] = u.row.idx[m];
2330 
2331  /* Eliminate zero from column c
2332  */
2333  --(temp.s_cact[c]);
2334  k = --(u.col.len[c]) + u.col.start[c];
2335 
2336  for(i = k; u.col.idx[i] != r; --i)
2337  ;
2338 
2339  u.col.idx[i] = u.col.idx[k];
2340  }
2341  }
2342  }
2343 
2344 
2345  /* create space for fill in row file
2346  */
2347  ll = u.row.len[r];
2348 
2349  if(ll + fill > u.row.max[r])
2350  remaxRow(r, ll + fill);
2351 
2352  ll += u.row.start[r];
2353 
2354  /* fill creating update loop (II)
2355  */
2356  for(j = u.row.start[prow], m = j + u.row.len[prow]; j < m; ++j)
2357  {
2358  c = u.row.idx[j];
2359 
2360  if(temp.s_mark[c])
2361  {
2362  x = - work[c] * lx;
2363 
2364  if(x != 0)
2365  {
2366  /* produce fill element in row r
2367  */
2368  u.row.val[ll] = x;
2369  u.row.idx[ll] = c;
2370  ll++;
2371  u.row.len[r]++;
2372 
2373  /* produce fill element in column c
2374  */
2375 
2376  if(u.col.len[c] >= u.col.max[c])
2377  remaxCol(c, u.col.len[c] + 1);
2378 
2379  u.col.idx[u.col.start[c] + (u.col.len[c])++] = r;
2380 
2381  temp.s_cact[c]++;
2382  }
2383  }
2384  else
2385  temp.s_mark[c] = 1;
2386  }
2387 
2388  /* move row to appropriate list.
2389  */
2390  removeDR(temp.pivot_row[r]);
2391 
2393 
2394  assert(row.perm[r] < 0);
2395 
2396  temp.s_max[r] = -1;
2397 
2398  return lv;
2399 }
2400 
2401 /*
2402  * Eliminate pivot element
2403  */
2404 void CLUFactorRational::eliminatePivot(int prow, int pos)
2405 {
2406  int i, j, k, m = -1;
2407  int lv = -1; // This value should never be used.
2408  int pcol;
2409  Rational pval;
2410  int pbeg = u.row.start[prow];
2411  int plen = --(u.row.len[prow]);
2412  int pend = pbeg + plen;
2413 
2414 
2415  /* extract pivot element */
2416  i = pbeg + pos;
2417  pcol = u.row.idx[i];
2418  pval = u.row.val[i];
2419  removeDR(temp.pivot_col[pcol]);
2420  initDR(temp.pivot_col[pcol]);
2421 
2422  /* remove pivot from pivot row */
2423  u.row.idx[i] = u.row.idx[pend];
2424  u.row.val[i] = u.row.val[pend];
2425 
2426  /* set pivot element and construct L vector */
2427  setPivot(temp.stage++, pcol, prow, pval);
2428 
2429  /**@todo If this test failes, lv has no value. I suppose that in this
2430  * case none of the loops below that uses lv is executed.
2431  * But this is unproven.
2432  */
2433 
2434  if(temp.s_cact[pcol] - 1 > 0)
2435  lv = makeLvec(temp.s_cact[pcol] - 1, prow);
2436 
2437  /* init working vector,
2438  * remove pivot row from working matrix
2439  * and remove columns from list.
2440  */
2441  for(i = pbeg; i < pend; ++i)
2442  {
2443  j = u.row.idx[i];
2444  temp.s_mark[j] = 1;
2445  work[j] = u.row.val[i];
2446  removeDR(temp.pivot_col[j]);
2447  m = u.col.start[j] + u.col.len[j] - temp.s_cact[j];
2448 
2449  for(k = m; u.col.idx[k] != prow; ++k)
2450  ;
2451 
2452  u.col.idx[k] = u.col.idx[m];
2453 
2454  u.col.idx[m] = prow;
2455 
2456  temp.s_cact[j]--;
2457  }
2458 
2459  /* perform L and update loop
2460  */
2461  for(i = u.col.len[pcol] - temp.s_cact[pcol];
2462  (m = u.col.idx[u.col.start[pcol] + i]) != prow;
2463  ++i)
2464  {
2465  assert(row.perm[m] < 0);
2466  assert(lv >= 0);
2467  updateRow(m, lv++, prow, pcol, pval);
2468  }
2469 
2470  /* skip pivot row */
2471 
2472  m = u.col.len[pcol];
2473 
2474  for(++i; i < m; ++i)
2475  {
2476  assert(lv >= 0);
2477  updateRow(u.col.idx[u.col.start[pcol] + i], lv++, prow, pcol, pval);
2478  }
2479 
2480  /* remove pivot column from column file.
2481  */
2482  u.col.len[pcol] -= temp.s_cact[pcol];
2483 
2484  /* clear working vector and reinsert columns to lists
2485  */
2486  for(i = u.row.start[prow], pend = i + plen; i < pend; ++i)
2487  {
2488  j = u.row.idx[i];
2489  work[j] = 0;
2490  temp.s_mark[j] = 0;
2492  assert(col.perm[j] < 0);
2493  }
2494 }
2495 
2496 
2497 /*
2498  * Factorize nucleus.
2499  */
2501 {
2502  int r, c;
2503  CLUFactorRational::Pring* pivot;
2504 
2506  return;
2507 
2508  temp.pivots.mkwtz = -1;
2509 
2510  temp.pivots.idx = -1;
2511 
2512  temp.pivots.pos = -1;
2513 
2514  while(temp.stage < thedim - 1)
2515  {
2516 #ifndef NDEBUG
2517  int i;
2518  // CLUFactorRationalIsConsistent(fac);
2519 
2520  for(i = 0; i < thedim; ++i)
2521  if(col.perm[i] < 0)
2522  assert(temp.s_mark[i] == 0);
2523 
2524 #endif
2525 
2526  if(temp.pivot_rowNZ[1].next != &(temp.pivot_rowNZ[1]))
2527  {
2528  if(timeLimitReached())
2529  return;
2530 
2531  /* row singleton available */
2533  }
2534  else if(temp.pivot_colNZ[1].next != &(temp.pivot_colNZ[1]))
2535  {
2536  if(timeLimitReached())
2537  return;
2538 
2539  /* column singleton available */
2541  }
2542  else
2543  {
2544  initDR(temp.pivots);
2545  selectPivots(threshold);
2546 
2547  assert(temp.pivots.next != &temp.pivots &&
2548  "ERROR: no pivot element selected");
2549 
2550  for(pivot = temp.pivots.next; pivot != &temp.pivots;
2551  pivot = pivot->next)
2552  {
2553  if(timeLimitReached())
2554  return;
2555 
2556  eliminatePivot(pivot->idx, pivot->pos);
2557  }
2558  }
2559 
2562  {
2564  return;
2565  }
2566  }
2567 
2568  if(temp.stage < thedim)
2569  {
2570  /* Eliminate remaining element.
2571  * Note, that this must be both, column and row singleton.
2572  */
2573  assert(temp.pivot_rowNZ[1].next != &(temp.pivot_rowNZ[1]) &&
2574  "ERROR: one row must be left");
2575  assert(temp.pivot_colNZ[1].next != &(temp.pivot_colNZ[1]) &&
2576  "ERROR: one col must be left");
2577  r = temp.pivot_rowNZ[1].next->idx;
2578  c = temp.pivot_colNZ[1].next->idx;
2579  u.row.len[r] = 0;
2580  u.col.len[c]--;
2581  setPivot(temp.stage, c, r, u.row.val[u.row.start[r]]);
2582  }
2583 }
2584 
2585 /*****************************************************************************/
2586 
2588 {
2589  int i;
2590  int n = thedim;
2591 
2592  u.col.val.reDim(u.col.size);
2593 
2594  for(i = 0; i < thedim; i++)
2595  u.col.len[i] = 0;
2596 
2597  maxabs = 0;
2598 
2599  for(i = 0; i < thedim; i++)
2600  {
2601  int k = u.row.start[i];
2602  int* idx = &u.row.idx[k];
2603  Rational* val = &u.row.val[k];
2604  int len = u.row.len[i];
2605 
2606  n += len;
2607 
2608  while(len-- > 0)
2609  {
2610  assert((*idx >= 0) && (*idx < thedim));
2611 
2612  k = u.col.start[*idx] + u.col.len[*idx];
2613 
2614  assert((k >= 0) && (k < u.col.size));
2615 
2616  u.col.len[*idx]++;
2617 
2618  assert(u.col.len[*idx] <= u.col.max[*idx]);
2619 
2620  u.col.idx[k] = i;
2621  u.col.val[k] = *val;
2622 
2623  if(spxAbs(*val) > maxabs)
2624  maxabs = spxAbs(*val);
2625 
2626  idx++;
2627 
2628  val++;
2629  }
2630  }
2631 
2632  return n;
2633 }
2634 
2635 /*****************************************************************************/
2636 
2637 #ifdef WITH_L_ROWS
2639 {
2640  int i, j, k, m;
2641  int vecs, mem;
2642  int* l_row;
2643  int* idx;
2644  int* beg;
2645  int* l_ridx;
2646  int* l_rbeg;
2647  int* rorig;
2648  int* rrorig;
2649  int* rperm;
2650  int* rrperm;
2651 
2652  vecs = l.firstUpdate;
2653  l_row = l.row;
2654  idx = l.idx;
2655  DVectorRational& val = l.val;
2656  int validx = 0;
2657  beg = l.start;
2658  mem = beg[vecs];
2659 
2660  if(l.ridx)
2661  spx_free(l.ridx);
2662 
2663  if(l.rbeg)
2664  spx_free(l.rbeg);
2665 
2666  if(l.rorig)
2667  spx_free(l.rorig);
2668 
2669  if(l.rperm)
2670  spx_free(l.rperm);
2671 
2672  l.rval.reDim(mem);
2673 
2674  spx_alloc(l.ridx, mem);
2675 
2676  spx_alloc(l.rbeg, thedim + 1);
2677 
2678  spx_alloc(l.rorig, thedim);
2679 
2680  spx_alloc(l.rperm, thedim);
2681 
2682  l_ridx = l.ridx;
2683 
2684  DVectorRational& l_rval = l.rval;
2685 
2686  l_rbeg = l.rbeg;
2687 
2688  rorig = l.rorig;
2689 
2690  rrorig = row.orig;
2691 
2692  rperm = l.rperm;
2693 
2694  rrperm = row.perm;
2695 
2696  for(i = thedim; i--; *l_rbeg++ = 0)
2697  {
2698  *rorig++ = *rrorig++;
2699  *rperm++ = *rrperm++;
2700  }
2701 
2702  *l_rbeg = 0;
2703 
2704  l_rbeg = l.rbeg + 1;
2705 
2706  for(i = mem; i--;)
2707  l_rbeg[*idx++]++;
2708 
2709  idx = l.idx;
2710 
2711  for(m = 0, i = thedim; i--; l_rbeg++)
2712  {
2713  j = *l_rbeg;
2714  *l_rbeg = m;
2715  m += j;
2716  }
2717 
2718  assert(m == mem);
2719 
2720  l_rbeg = l.rbeg + 1;
2721 
2722  for(i = j = 0; i < vecs; ++i)
2723  {
2724  m = l_row[i];
2725  assert(idx == &l.idx[l.start[i]]);
2726 
2727  for(; j < beg[i + 1]; j++)
2728  {
2729  k = l_rbeg[*idx++]++;
2730  assert(k < mem);
2731  l_ridx[k] = m;
2732  l_rval[k] = val[validx];
2733  validx++; // was l_rval[k] = *val++; with Rational* val
2734  }
2735  }
2736 
2737  assert(l.rbeg[thedim] == mem);
2738 
2739  assert(l.rbeg[0] == 0);
2740 }
2741 
2742 #endif
2743 
2744 /*****************************************************************************/
2745 
2747  const SVectorRational** vec, ///< Array of column vector pointers
2748  const Rational& threshold ///< pivoting threshold
2749 )
2750 {
2751  MSG_DEBUG(std::cout << "CLUFactorRational::factor()\n");
2752 
2753  factorTime->start();
2754 
2756 
2757  l.start[0] = 0;
2758  l.firstUpdate = 0;
2759  l.firstUnused = 0;
2760 
2761  temp.init(thedim);
2762  initPerm();
2763 
2764  initFactorMatrix(vec);
2765 
2766  if(stat)
2767  goto TERMINATE;
2768 
2769  if(timeLimitReached())
2770  goto TERMINATE;
2771 
2772  // initMaxabs = initMaxabs;
2773 
2774  colSingletons();
2775 
2777  goto TERMINATE;
2778 
2779  if(timeLimitReached())
2780  goto TERMINATE;
2781 
2782  rowSingletons();
2783 
2785  goto TERMINATE;
2786 
2787  if(temp.stage < thedim)
2788  {
2789  if(timeLimitReached())
2790  goto TERMINATE;
2791 
2792  initFactorRings();
2793  eliminateNucleus(threshold);
2794  freeFactorRings();
2795  }
2796 
2797 TERMINATE:
2798 
2800 
2802  {
2803 #ifdef WITH_L_ROWS
2804  setupRowVals();
2805 #endif
2806  nzCnt = setupColVals();
2807  }
2808 
2809  factorTime->stop();
2810 
2811  factorCount++;
2812 }
2813 
2815 {
2816  int i, j, k;
2817 
2818  // Dump regardless of the verbosity level if this method is called;
2819 
2820  /* Dump U:
2821  */
2822 
2823  for(i = 0; i < thedim; ++i)
2824  {
2825  if(row.perm[i] >= 0)
2826  std::cout << "DCLUFA01 diag[" << i << "]: [" << col.orig[row.perm[i]]
2827  << "] = " << diag[i] << std::endl;
2828 
2829  for(j = 0; j < u.row.len[i]; ++j)
2830  std::cout << "DCLUFA02 u[" << i << "]: ["
2831  << u.row.idx[u.row.start[i] + j] << "] = "
2832  << u.row.val[u.row.start[i] + j] << std::endl;
2833  }
2834 
2835  /* Dump L:
2836  */
2837  for(i = 0; i < thedim; ++i)
2838  {
2839  for(j = 0; j < l.firstUnused; ++j)
2840  if(col.orig[row.perm[l.row[j]]] == i)
2841  {
2842  std::cout << "DCLUFA03 l[" << i << "]" << std::endl;
2843 
2844  for(k = l.start[j]; k < l.start[j + 1]; ++k)
2845  std::cout << "DCLUFA04 l[" << k - l.start[j]
2846  << "]: [" << l.idx[k]
2847  << "] = " << l.val[k] << std::endl;
2848 
2849  break;
2850  }
2851  }
2852 
2853  return;
2854 }
2855 
2856 /*****************************************************************************/
2857 /*
2858  * Ensure that row memory is at least size.
2859  */
2861 {
2862  if(u.row.val.dim() < size)
2863  {
2864  u.row.val.reDim(size);
2865  spx_realloc(u.row.idx, size);
2866  }
2867 
2868  assert(u.row.val.dim() >= size);
2869 }
2870 
2871 /*****************************************************************************/
2872 /*
2873  * Ensure that column memory is at least size.
2874  */
2876 {
2877 
2878  if(u.col.size < size)
2879  {
2880  u.col.size = size;
2881  spx_realloc(u.col.idx, size);
2882  }
2883 }
2884 
2886 {
2887 
2888  if(u.col.size < size)
2889  {
2890  u.col.size = size;
2891  spx_realloc(u.col.idx, size);
2892  u.col.val.reDim(size);
2893  }
2894 }
2895 
2897 {
2898 
2899  if(size > l.val.dim())
2900  {
2901  int newsize = int(0.2 * l.val.dim() + size);
2902  l.val.reDim(newsize);
2903  spx_realloc(l.idx, l.val.dim());
2904  }
2905 }
2906 
2907 
2908 int CLUFactorRational::makeLvec(int p_len, int p_row)
2909 {
2910 
2911  if(l.firstUnused >= l.startSize)
2912  {
2913  l.startSize += 100;
2915  }
2916 
2917  int* p_lrow = l.row;
2918 
2919  int* p_lbeg = l.start;
2920  int first = p_lbeg[l.firstUnused];
2921 
2922  assert(p_len > 0 && "ERROR: no empty columns allowed in L vectors");
2923 
2924  minLMem(first + p_len);
2925  p_lrow[l.firstUnused] = p_row;
2926  l.start[++(l.firstUnused)] = first + p_len;
2927 
2928  assert(l.start[l.firstUnused] <= l.val.dim());
2929  assert(l.firstUnused <= l.startSize);
2930  return first;
2931 }
2932 
2933 
2934 /*****************************************************************************/
2935 
2937 {
2938 #ifdef ENABLE_CONSISTENCY_CHECKS
2939  int i, j, k, ll;
2940  Dring* ring;
2941  CLUFactorRational::Pring* pring;
2942 
2943  /* Consistency only relevant for real factorizations
2944  */
2945 
2946  if(stat)
2947  return true;
2948 
2949  /* Test column ring list consistency.
2950  */
2951  i = 0;
2952 
2953  for(ring = u.col.list.next; ring != &(u.col.list); ring = ring->next)
2954  {
2955  assert(ring->idx >= 0);
2956  assert(ring->idx < thedim);
2957  assert(ring->prev->next == ring);
2958 
2959  if(ring != u.col.list.next)
2960  {
2961  assert(u.col.start[ring->prev->idx] + u.col.max[ring->prev->idx]
2962  == u.col.start[ring->idx]);
2963  }
2964 
2965  ++i;
2966  }
2967 
2968  assert(i == thedim);
2969 
2970  assert(u.col.start[ring->prev->idx] + u.col.max[ring->prev->idx]
2971  == u.col.used);
2972 
2973 
2974  /* Test row ring list consistency.
2975  */
2976  i = 0;
2977 
2978  for(ring = u.row.list.next; ring != &(u.row.list); ring = ring->next)
2979  {
2980  assert(ring->idx >= 0);
2981  assert(ring->idx < thedim);
2982  assert(ring->prev->next == ring);
2983  assert(u.row.start[ring->prev->idx] + u.row.max[ring->prev->idx]
2984  == u.row.start[ring->idx]);
2985  ++i;
2986  }
2987 
2988  assert(i == thedim);
2989 
2990  assert(u.row.start[ring->prev->idx] + u.row.max[ring->prev->idx]
2991  == u.row.used);
2992 
2993 
2994  /* Test consistency of individual svectors.
2995  */
2996 
2997  for(i = 0; i < thedim; ++i)
2998  {
2999  assert(u.row.max[i] >= u.row.len[i]);
3000  assert(u.col.max[i] >= u.col.len[i]);
3001  }
3002 
3003 
3004  /* Test consistency of column file to row file of U
3005  */
3006  for(i = 0; i < thedim; ++i)
3007  {
3008  for(j = u.row.start[i] + u.row.len[i] - 1; j >= u.row.start[i]; j--)
3009  {
3010  k = u.row.idx[j];
3011 
3012  for(ll = u.col.start[k] + u.col.len[k] - 1; ll >= u.col.start[k]; ll--)
3013  {
3014  if(u.col.idx[ll] == i)
3015  break;
3016  }
3017 
3018  assert(u.col.idx[ll] == i);
3019 
3020  if(row.perm[i] < 0)
3021  {
3022  assert(col.perm[k] < 0);
3023  }
3024  else
3025  {
3026  assert(col.perm[k] < 0 || col.perm[k] > row.perm[i]);
3027  }
3028  }
3029  }
3030 
3031  /* Test consistency of row file to column file of U
3032  */
3033  for(i = 0; i < thedim; ++i)
3034  {
3035  for(j = u.col.start[i] + u.col.len[i] - 1; j >= u.col.start[i]; j--)
3036  {
3037  k = u.col.idx[j];
3038 
3039  for(ll = u.row.start[k] + u.row.len[k] - 1; ll >= u.row.start[k]; ll--)
3040  {
3041  if(u.row.idx[ll] == i)
3042  break;
3043  }
3044 
3045  assert(u.row.idx[ll] == i);
3046 
3047  assert(col.perm[i] < 0 || row.perm[k] < col.perm[i]);
3048  }
3049  }
3050 
3051  /* Test consistency of nonzero count lists
3052  */
3054  {
3055  for(i = 0; i < thedim - temp.stage; ++i)
3056  {
3057  for(pring = temp.pivot_rowNZ[i].next; pring != &(temp.pivot_rowNZ[i]); pring = pring->next)
3058  {
3059  assert(row.perm[pring->idx] < 0);
3060  }
3061 
3062  for(pring = temp.pivot_colNZ[i].next; pring != &(temp.pivot_colNZ[i]); pring = pring->next)
3063  {
3064  assert(col.perm[pring->idx] < 0);
3065  }
3066  }
3067  }
3068 
3069 #endif // CONSISTENCY_CHECKS
3070 
3071  return true;
3072 }
3073 
3075 {
3076 
3077  for(int i = thedim - 1; i >= 0; i--)
3078  {
3079  int r = row.orig[i];
3080  int c = col.orig[i];
3081  Rational x = wrk[c] = diag[r] * vec[r];
3082 
3083  vec[r] = 0;
3084 
3085  if(x != 0)
3086  //if (isNotZero(x))
3087  {
3088  if(timeLimitReached())
3089  return;
3090 
3091  for(int j = u.col.start[c]; j < u.col.start[c] + u.col.len[c]; j++)
3092  vec[u.col.idx[j]] -= x * u.col.val[j];
3093  }
3094  }
3095 }
3096 
3098 {
3099  int i, j, r, c, n;
3100  int* rorig, *corig;
3101  int* cidx, *clen, *cbeg;
3102  Rational x;
3103 
3104  int* idx;
3105  Rational* val;
3106 
3107  rorig = row.orig;
3108  corig = col.orig;
3109 
3110  cidx = u.col.idx;
3111  DVectorRational& cval = u.col.val;
3112  clen = u.col.len;
3113  cbeg = u.col.start;
3114 
3115  n = 0;
3116 
3117  for(i = thedim - 1; i >= 0; --i)
3118  {
3119  r = rorig[i];
3120  x = diag[r] * rhs[r];
3121 
3122  if(x != 0)
3123  {
3124  c = corig[i];
3125  vec[c] = x;
3126  nonz[n++] = c;
3127  val = &cval[cbeg[c]];
3128  idx = &cidx[cbeg[c]];
3129  j = clen[c];
3130 
3131  while(j-- > 0)
3132  rhs[*idx++] -= x * (*val++);
3133  }
3134  }
3135 
3136  return n;
3137 }
3138 
3140  Rational* vec2)
3141 {
3142  int i, j, r, c;
3143  int* rorig, *corig;
3144  int* cidx, *clen, *cbeg;
3145  Rational x1, x2;
3146 
3147  int* idx;
3148  Rational* val;
3149 
3150  rorig = row.orig;
3151  corig = col.orig;
3152 
3153  cidx = u.col.idx;
3154  DVectorRational& cval = u.col.val;
3155  clen = u.col.len;
3156  cbeg = u.col.start;
3157 
3158  for(i = thedim - 1; i >= 0; --i)
3159  {
3160  r = rorig[i];
3161  c = corig[i];
3162  p_work1[c] = x1 = diag[r] * vec1[r];
3163  p_work2[c] = x2 = diag[r] * vec2[r];
3164  vec1[r] = vec2[r] = 0;
3165 
3166  if(x1 != 0 && x2 != 0)
3167  {
3168  val = &cval[cbeg[c]];
3169  idx = &cidx[cbeg[c]];
3170  j = clen[c];
3171 
3172  while(j-- > 0)
3173  {
3174  vec1[*idx] -= x1 * (*val);
3175  vec2[*idx++] -= x2 * (*val++);
3176  }
3177  }
3178  else if(x1 != 0)
3179  {
3180  val = &cval[cbeg[c]];
3181  idx = &cidx[cbeg[c]];
3182  j = clen[c];
3183 
3184  while(j-- > 0)
3185  vec1[*idx++] -= x1 * (*val++);
3186  }
3187  else if(x2 != 0)
3188  {
3189  val = &cval[cbeg[c]];
3190  idx = &cidx[cbeg[c]];
3191  j = clen[c];
3192 
3193  while(j-- > 0)
3194  vec2[*idx++] -= x2 * (*val++);
3195  }
3196  }
3197 }
3198 
3200  Rational* vec2, int* nonz)
3201 {
3202  int i, j, r, c, n;
3203  int* rorig, *corig;
3204  int* cidx, *clen, *cbeg;
3205  bool notzero1, notzero2;
3206  Rational x1, x2;
3207 
3208  int* idx;
3209  Rational* val;
3210 
3211  rorig = row.orig;
3212  corig = col.orig;
3213 
3214  cidx = u.col.idx;
3215  DVectorRational& cval = u.col.val;
3216  clen = u.col.len;
3217  cbeg = u.col.start;
3218 
3219  n = 0;
3220 
3221  for(i = thedim - 1; i >= 0; --i)
3222  {
3223  c = corig[i];
3224  r = rorig[i];
3225  p_work1[c] = x1 = diag[r] * vec1[r];
3226  p_work2[c] = x2 = diag[r] * vec2[r];
3227  vec1[r] = vec2[r] = 0;
3228  notzero1 = x1 != 0 ? 1 : 0;
3229  notzero2 = x2 != 0 ? 1 : 0;
3230 
3231  if(notzero1 && notzero2)
3232  {
3233  *nonz++ = c;
3234  n++;
3235  val = &cval[cbeg[c]];
3236  idx = &cidx[cbeg[c]];
3237  j = clen[c];
3238 
3239  while(j-- > 0)
3240  {
3241  vec1[*idx] -= x1 * (*val);
3242  vec2[*idx++] -= x2 * (*val++);
3243  }
3244  }
3245  else if(notzero1)
3246  {
3247  p_work2[c] = 0;
3248  *nonz++ = c;
3249  n++;
3250  val = &cval[cbeg[c]];
3251  idx = &cidx[cbeg[c]];
3252  j = clen[c];
3253 
3254  while(j-- > 0)
3255  vec1[*idx++] -= x1 * (*val++);
3256  }
3257  else if(notzero2)
3258  {
3259  p_work1[c] = 0;
3260  val = &cval[cbeg[c]];
3261  idx = &cidx[cbeg[c]];
3262  j = clen[c];
3263 
3264  while(j-- > 0)
3265  vec2[*idx++] -= x2 * (*val++);
3266  }
3267  else
3268  {
3269  p_work1[c] = 0;
3270  p_work2[c] = 0;
3271  }
3272  }
3273 
3274  return n;
3275 }
3276 
3278 {
3279  int i, j, k;
3280  int end;
3281  Rational x;
3282  Rational* val;
3283  int* lrow, *lidx, *idx;
3284  int* lbeg;
3285 
3286  DVectorRational& lval = l.val;
3287  lidx = l.idx;
3288  lrow = l.row;
3289  lbeg = l.start;
3290 
3291  end = l.firstUpdate;
3292 
3293  for(i = 0; i < end; ++i)
3294  {
3295  if((x = vec[lrow[i]]) != 0)
3296  {
3297  if(timeLimitReached())
3298  return;
3299 
3300  MSG_DEBUG(std::cout << "y" << lrow[i] << "=" << vec[lrow[i]] << std::endl;)
3301 
3302  k = lbeg[i];
3303  idx = &(lidx[k]);
3304  val = &(lval[k]);
3305 
3306  for(j = lbeg[i + 1]; j > k; --j)
3307  {
3308  MSG_DEBUG(std::cout << " -> y" << *idx << " -= " << x << " * " << *val <<
3309  " = " << x * (*val) << " -> " << vec[*idx] - x * (*val) << std::endl;)
3310  vec[*idx++] -= x * (*val++);
3311  }
3312  }
3313  }
3314 
3315  if(l.updateType) /* Forest-Tomlin Updates */
3316  {
3317  MSG_DEBUG(std::cout << "performing FT updates..." << std::endl;)
3318 
3319  end = l.firstUnused;
3320 
3321  for(; i < end; ++i)
3322  {
3323  x = 0;
3324  k = lbeg[i];
3325  idx = &(lidx[k]);
3326  val = &(lval[k]);
3327 
3328  for(j = lbeg[i + 1]; j > k; --j)
3329  x += vec[*idx++] * (*val++);
3330 
3331  vec[lrow[i]] -= x;
3332 
3333  MSG_DEBUG(std::cout << "y" << lrow[i] << "=" << vec[lrow[i]] << std::endl;)
3334  }
3335 
3336  MSG_DEBUG(std::cout << "finished FT updates." << std::endl;)
3337  }
3338 }
3339 
3341 {
3342  int i, j, k;
3343  int end;
3344  Rational x2;
3345  Rational x1;
3346  Rational* val;
3347  int* lrow, *lidx, *idx;
3348  int* lbeg;
3349 
3350  DVectorRational& lval = l.val;
3351  lidx = l.idx;
3352  lrow = l.row;
3353  lbeg = l.start;
3354 
3355  end = l.firstUpdate;
3356 
3357  for(i = 0; i < end; ++i)
3358  {
3359  x1 = vec1[lrow[i]];
3360  x2 = vec2[lrow[i]];
3361 
3362  if(x1 != 0 && x2 != 0)
3363  {
3364  k = lbeg[i];
3365  idx = &(lidx[k]);
3366  val = &(lval[k]);
3367 
3368  for(j = lbeg[i + 1]; j > k; --j)
3369  {
3370  vec1[*idx] -= x1 * (*val);
3371  vec2[*idx++] -= x2 * (*val++);
3372  }
3373  }
3374  else if(x1 != 0)
3375  {
3376  k = lbeg[i];
3377  idx = &(lidx[k]);
3378  val = &(lval[k]);
3379 
3380  for(j = lbeg[i + 1]; j > k; --j)
3381  vec1[*idx++] -= x1 * (*val++);
3382  }
3383  else if(x2 != 0)
3384  {
3385  k = lbeg[i];
3386  idx = &(lidx[k]);
3387  val = &(lval[k]);
3388 
3389  for(j = lbeg[i + 1]; j > k; --j)
3390  vec2[*idx++] -= x2 * (*val++);
3391  }
3392  }
3393 
3394  if(l.updateType) /* Forest-Tomlin Updates */
3395  {
3396  end = l.firstUnused;
3397 
3398  for(; i < end; ++i)
3399  {
3400  x1 = 0;
3401  x2 = 0;
3402  k = lbeg[i];
3403  idx = &(lidx[k]);
3404  val = &(lval[k]);
3405 
3406  for(j = lbeg[i + 1]; j > k; --j)
3407  {
3408  x1 += vec1[*idx] * (*val);
3409  x2 += vec2[*idx++] * (*val++);
3410  }
3411 
3412  vec1[lrow[i]] -= x1;
3413 
3414  vec2[lrow[i]] -= x2;
3415  }
3416  }
3417 }
3418 
3420 {
3421  int i, j, k;
3422  int end;
3423  Rational x;
3424  Rational* val;
3425  int* lrow, *lidx, *idx;
3426  int* lbeg;
3427 
3428  assert(!l.updateType); /* no Forest-Tomlin Updates */
3429 
3430  DVectorRational& lval = l.val;
3431  lidx = l.idx;
3432  lrow = l.row;
3433  lbeg = l.start;
3434 
3435  end = l.firstUnused;
3436 
3437  for(i = l.firstUpdate; i < end; ++i)
3438  {
3439  if((x = vec[lrow[i]]) != 0)
3440  {
3441  k = lbeg[i];
3442  idx = &(lidx[k]);
3443  val = &(lval[k]);
3444 
3445  for(j = lbeg[i + 1]; j > k; --j)
3446  vec[*idx++] -= x * (*val++);
3447  }
3448  }
3449 }
3450 
3452 {
3453  int i, j, k;
3454  int end;
3455  Rational x1, x2;
3456  int* lrow, *lidx;
3457  int* lbeg;
3458 
3459  int* idx;
3460  Rational* val;
3461 
3462  assert(!l.updateType); /* no Forest-Tomlin Updates */
3463 
3464  DVectorRational& lval = l.val;
3465  lidx = l.idx;
3466  lrow = l.row;
3467  lbeg = l.start;
3468 
3469  end = l.firstUnused;
3470 
3471  for(i = l.firstUpdate; i < end; ++i)
3472  {
3473  x1 = vec1[lrow[i]];
3474  x2 = vec2[lrow[i]];
3475 
3476  if(x1 != 0 && x2 != 0)
3477  {
3478  k = lbeg[i];
3479  idx = &(lidx[k]);
3480  val = &(lval[k]);
3481 
3482  for(j = lbeg[i + 1]; j > k; --j)
3483  {
3484  vec1[*idx] -= x1 * (*val);
3485  vec2[*idx++] -= x2 * (*val++);
3486  }
3487  }
3488  else if(x1 != 0)
3489  {
3490  k = lbeg[i];
3491  idx = &(lidx[k]);
3492  val = &(lval[k]);
3493 
3494  for(j = lbeg[i + 1]; j > k; --j)
3495  vec1[*idx++] -= x1 * (*val++);
3496  }
3497  else if(x2 != 0)
3498  {
3499  k = lbeg[i];
3500  idx = &(lidx[k]);
3501  val = &(lval[k]);
3502 
3503  for(j = lbeg[i + 1]; j > k; --j)
3504  vec2[*idx++] -= x2 * (*val++);
3505  }
3506  }
3507 }
3508 
3510  Rational* rhs, Rational* forest, int* forestNum, int* forestIdx)
3511 {
3512  solveLright(rhs);
3513 
3514  if(forest)
3515  {
3516  int n = 0;
3517 
3518  for(int i = 0; i < thedim; i++)
3519  {
3520  forestIdx[n] = i;
3521  forest[i] = rhs[i];
3522  n += rhs[i] != 0 ? 1 : 0;
3523  }
3524 
3525  *forestNum = n;
3526  }
3527 
3528  if(!l.updateType) /* no Forest-Tomlin Updates */
3529  {
3530  solveUright(vec, rhs);
3531  solveUpdateRight(vec);
3532  return 0;
3533  }
3534  else
3535  return solveUrightEps(vec, nonz, rhs);
3536 }
3537 
3539 {
3540  solveLright(rhs);
3541  solveUright(vec, rhs);
3542 
3543  if(!l.updateType) /* no Forest-Tomlin Updates */
3544  solveUpdateRight(vec);
3545 }
3546 
3548  Rational* vec2,
3549  Rational* rhs1,
3550  Rational* rhs2,
3551  int* nonz,
3552  Rational* forest,
3553  int* forestNum,
3554  int* forestIdx)
3555 {
3556  solveLright2(rhs1, rhs2);
3557 
3558  if(forest)
3559  {
3560  int n = 0;
3561 
3562  for(int i = 0; i < thedim; i++)
3563  {
3564  forestIdx[n] = i;
3565  forest[i] = rhs1[i];
3566  n += rhs1[i] != 0 ? 1 : 0;
3567  }
3568 
3569  *forestNum = n;
3570  }
3571 
3572  if(!l.updateType) /* no Forest-Tomlin Updates */
3573  {
3574  solveUright2(vec1, rhs1, vec2, rhs2);
3575  solveUpdateRight2(vec1, vec2);
3576  return 0;
3577  }
3578  else
3579  return solveUright2eps(vec1, rhs1, vec2, rhs2, nonz);
3580 }
3581 
3583  Rational* vec1,
3584  Rational* vec2,
3585  Rational* rhs1,
3586  Rational* rhs2)
3587 {
3588  solveLright2(rhs1, rhs2);
3589 
3590  if(l.updateType) /* Forest-Tomlin Updates */
3591  solveUright2(vec1, rhs1, vec2, rhs2);
3592  else
3593  {
3594  solveUright2(vec1, rhs1, vec2, rhs2);
3595  solveUpdateRight2(vec1, vec2);
3596  }
3597 }
3598 
3599 /*****************************************************************************/
3601 {
3602  for(int i = 0; i < thedim; ++i)
3603  {
3604  int c = col.orig[i];
3605  int r = row.orig[i];
3606 
3607  assert(c >= 0); // Inna/Tobi: otherwise, vec[c] would be strange...
3608  assert(r >= 0); // Inna/Tobi: otherwise, diag[r] would be strange...
3609 
3610  Rational x = vec[c];
3611 
3612  // ASSERT_WARN( "WSOLVE01", spxAbs( x ) < 1e40 );
3613  // ASSERT_WARN( "WSOLVE02", spxAbs( vec[c] ) < 1e40 );
3614 
3615  vec[c] = 0;
3616 
3617  if(x != 0)
3618  {
3619  if(timeLimitReached())
3620  return;
3621 
3622  // ASSERT_WARN( "WSOLVE03", spxAbs( diag[r] ) < 1e40 );
3623 
3624  x *= diag[r];
3625  p_work[r] = x;
3626 
3627  // ASSERT_WARN( "WSOLVE04", spxAbs( x ) < 1e40 );
3628 
3629  int end = u.row.start[r] + u.row.len[r];
3630 
3631  for(int m = u.row.start[r]; m < end; m++)
3632  {
3633  // ASSERT_WARN( "WSOLVE05", spxAbs( u.row.val[m] ) < 1e40 );
3634  // ASSERT_WARN( "WSOLVE06", spxAbs( vec[u.row.idx[m]] ) < infinity );
3635  vec[u.row.idx[m]] -= x * u.row.val[m];
3636  // ASSERT_WARN( "WSOLVE07", spxAbs( vec[u.row.idx[m]] ) < 1e40 );
3637  }
3638  }
3639 
3640  // ASSERT_WARN( "WSOLVE08", spxAbs( y ) < 1e40 );
3641  }
3642 }
3643 
3644 
3645 
3647  Rational* vec2)
3648 {
3649  Rational x1;
3650  Rational x2;
3651  int i, k, r, c;
3652  int* rorig, *corig;
3653  int* ridx, *rlen, *rbeg, *idx;
3654  Rational* val;
3655 
3656  rorig = row.orig;
3657  corig = col.orig;
3658 
3659  ridx = u.row.idx;
3660  DVectorRational& rval = u.row.val;
3661  rlen = u.row.len;
3662  rbeg = u.row.start;
3663 
3664  for(i = 0; i < thedim; ++i)
3665  {
3666  c = corig[i];
3667  r = rorig[i];
3668  x1 = vec1[c];
3669  x2 = vec2[c];
3670 
3671  if((x1 != 0) && (x2 != 0))
3672  {
3673  x1 *= diag[r];
3674  x2 *= diag[r];
3675  p_work1[r] = x1;
3676  p_work2[r] = x2;
3677  k = rbeg[r];
3678  idx = &ridx[k];
3679  val = &rval[k];
3680 
3681  for(int m = rlen[r]; m != 0; --m)
3682  {
3683  vec1[*idx] -= x1 * (*val);
3684  vec2[*idx] -= x2 * (*val++);
3685  idx++;
3686  }
3687  }
3688  else if(x1 != 0)
3689  {
3690  x1 *= diag[r];
3691  p_work1[r] = x1;
3692  k = rbeg[r];
3693  idx = &ridx[k];
3694  val = &rval[k];
3695 
3696  for(int m = rlen[r]; m != 0; --m)
3697  vec1[*idx++] -= x1 * (*val++);
3698  }
3699  else if(x2 != 0)
3700  {
3701  x2 *= diag[r];
3702  p_work2[r] = x2;
3703  k = rbeg[r];
3704  idx = &ridx[k];
3705  val = &rval[k];
3706 
3707  for(int m = rlen[r]; m != 0; --m)
3708  vec2[*idx++] -= x2 * (*val++);
3709  }
3710  }
3711 }
3712 
3713 int CLUFactorRational::solveLleft2forest(Rational* vec1, int* /* nonz */, Rational* vec2)
3714 {
3715  int i;
3716  int j;
3717  int k;
3718  int end;
3719  Rational x1, x2;
3720  Rational* val;
3721  int* lidx, *idx, *lrow;
3722  int* lbeg;
3723 
3724  DVectorRational& lval = l.val;
3725  lidx = l.idx;
3726  lrow = l.row;
3727  lbeg = l.start;
3728 
3729  end = l.firstUpdate;
3730 
3731  for(i = l.firstUnused - 1; i >= end; --i)
3732  {
3733  j = lrow[i];
3734  x1 = vec1[j];
3735  x2 = vec2[j];
3736 
3737  if(x1 != 0)
3738  {
3739  if(x2 != 0)
3740  {
3741  k = lbeg[i];
3742  val = &lval[k];
3743  idx = &lidx[k];
3744 
3745  for(j = lbeg[i + 1]; j > k; --j)
3746  {
3747  vec1[*idx] -= x1 * (*val);
3748  vec2[*idx++] -= x2 * (*val++);
3749  }
3750  }
3751  else
3752  {
3753  k = lbeg[i];
3754  val = &lval[k];
3755  idx = &lidx[k];
3756 
3757  for(j = lbeg[i + 1]; j > k; --j)
3758  vec1[*idx++] -= x1 * (*val++);
3759  }
3760  }
3761  else if(x2 != 0)
3762  {
3763  k = lbeg[i];
3764  val = &lval[k];
3765  idx = &lidx[k];
3766 
3767  for(j = lbeg[i + 1]; j > k; --j)
3768  vec2[*idx++] -= x2 * (*val++);
3769  }
3770  }
3771 
3772  return 0;
3773 }
3774 
3775 void CLUFactorRational::solveLleft2(Rational* vec1, int* /* nonz */, Rational* vec2)
3776 {
3777  int i, j, k, r;
3778  int x1not0, x2not0;
3779  Rational x1, x2;
3780 
3781  Rational* val;
3782  int* ridx, *idx;
3783  int* rbeg;
3784  int* rorig;
3785 
3786  ridx = l.ridx;
3787  DVectorRational& rval = l.rval;
3788  rbeg = l.rbeg;
3789  rorig = l.rorig;
3790 
3791 #ifndef WITH_L_ROWS
3792  DVectorRational& lval = l.val;
3793  int* lidx = l.idx;
3794  int* lrow = l.row;
3795  int* lbeg = l.start;
3796 
3797  i = l.firstUpdate - 1;
3798 
3799  for(; i >= 0; --i)
3800  {
3801  k = lbeg[i];
3802  val = &lval[k];
3803  idx = &lidx[k];
3804  x1 = 0;
3805  x2 = 0;
3806 
3807  for(j = lbeg[i + 1]; j > k; --j)
3808  {
3809  x1 += vec1[*idx] * (*val);
3810  x2 += vec2[*idx++] * (*val++);
3811  }
3812 
3813  vec1[lrow[i]] -= x1;
3814 
3815  vec2[lrow[i]] -= x2;
3816  }
3817 
3818 #else
3819 
3820  for(i = thedim; i--;)
3821  {
3822  r = rorig[i];
3823  x1 = vec1[r];
3824  x2 = vec2[r];
3825  x1not0 = (x1 != 0);
3826  x2not0 = (x2 != 0);
3827 
3828  if(x1not0 && x2not0)
3829  {
3830  k = rbeg[r];
3831  j = rbeg[r + 1] - k;
3832  val = &rval[k];
3833  idx = &ridx[k];
3834 
3835  while(j-- > 0)
3836  {
3837  assert(row.perm[*idx] < i);
3838  vec1[*idx] -= x1 * *val;
3839  vec2[*idx++] -= x2 * *val++;
3840  }
3841  }
3842  else if(x1not0)
3843  {
3844  k = rbeg[r];
3845  j = rbeg[r + 1] - k;
3846  val = &rval[k];
3847  idx = &ridx[k];
3848 
3849  while(j-- > 0)
3850  {
3851  assert(row.perm[*idx] < i);
3852  vec1[*idx++] -= x1 * *val++;
3853  }
3854  }
3855  else if(x2not0)
3856  {
3857  k = rbeg[r];
3858  j = rbeg[r + 1] - k;
3859  val = &rval[k];
3860  idx = &ridx[k];
3861 
3862  while(j-- > 0)
3863  {
3864  assert(row.perm[*idx] < i);
3865  vec2[*idx++] -= x2 * *val++;
3866  }
3867  }
3868  }
3869 
3870 #endif
3871 }
3872 
3874 {
3875  int i, j, k, end;
3876  Rational x;
3877  Rational* val;
3878  int* idx, *lidx, *lrow, *lbeg;
3879 
3880  DVectorRational& lval = l.val;
3881  lidx = l.idx;
3882  lrow = l.row;
3883  lbeg = l.start;
3884 
3885  end = l.firstUpdate;
3886 
3887  for(i = l.firstUnused - 1; i >= end; --i)
3888  {
3889  if((x = vec[lrow[i]]) != 0)
3890  {
3891  if(timeLimitReached())
3892  return 0;
3893 
3894  k = lbeg[i];
3895  val = &lval[k];
3896  idx = &lidx[k];
3897 
3898  for(j = lbeg[i + 1]; j > k; --j)
3899  vec[*idx++] -= x * (*val++);
3900  }
3901  }
3902 
3903  return 0;
3904 }
3905 
3907 {
3908 
3909 #ifndef WITH_L_ROWS
3910  int* idx;
3911  Rational* val;
3912  DVectorRational& lval = l.val;
3913  int* lidx = l.idx;
3914  int* lrow = l.row;
3915  int* lbeg = l.start;
3916 
3917  for(int i = l.firstUpdate - 1; i >= 0; --i)
3918  {
3919  if(timeLimitReached())
3920  return;
3921 
3922  int k = lbeg[i];
3923  val = &lval[k];
3924  idx = &lidx[k];
3925  x = 0;
3926 
3927  for(int j = lbeg[i + 1]; j > k; --j)
3928  x += vec[*idx++] * (*val++);
3929 
3930  vec[lrow[i]] -= x;
3931  }
3932 
3933 #else
3934 
3935  for(int i = thedim - 1; i >= 0; --i)
3936  {
3937  int r = l.rorig[i];
3938  Rational x = vec[r];
3939 
3940  if(x != 0)
3941  {
3942  if(timeLimitReached())
3943  return;
3944 
3945  for(int k = l.rbeg[r]; k < l.rbeg[r + 1]; k++)
3946  {
3947  int j = l.ridx[k];
3948 
3949  assert(l.rperm[j] < i);
3950 
3951  vec[j] -= x * l.rval[k];
3952  }
3953  }
3954  }
3955 
3956 #endif // WITH_L_ROWS
3957 }
3958 
3960 {
3961  int i, j, k, n;
3962  int r;
3963  Rational x;
3964  Rational* val;
3965  int* ridx, *idx;
3966  int* rbeg;
3967  int* rorig;
3968 
3969  ridx = l.ridx;
3970  DVectorRational& rval = l.rval;
3971  rbeg = l.rbeg;
3972  rorig = l.rorig;
3973  n = 0;
3974 #ifndef WITH_L_ROWS
3975  DVectorRational& lval = l.val;
3976  int* lidx = l.idx;
3977  int* lrow = l.row;
3978  int* lbeg = l.start;
3979 
3980  for(i = l.firstUpdate - 1; i >= 0; --i)
3981  {
3982  k = lbeg[i];
3983  val = &lval[k];
3984  idx = &lidx[k];
3985  x = 0;
3986 
3987  for(j = lbeg[i + 1]; j > k; --j)
3988  x += vec[*idx++] * (*val++);
3989 
3990  vec[lrow[i]] -= x;
3991  }
3992 
3993 #else
3994 
3995  for(i = thedim; i--;)
3996  {
3997  r = rorig[i];
3998  x = vec[r];
3999 
4000  if(x != 0)
4001  {
4002  *nonz++ = r;
4003  n++;
4004  k = rbeg[r];
4005  j = rbeg[r + 1] - k;
4006  val = &rval[k];
4007  idx = &ridx[k];
4008 
4009  while(j-- > 0)
4010  {
4011  assert(row.perm[*idx] < i);
4012  vec[*idx++] -= x * *val++;
4013  }
4014  }
4015  else
4016  vec[r] = 0;
4017  }
4018 
4019 #endif
4020 
4021  return n;
4022 }
4023 
4025 {
4026  int i, j, k, end;
4027  Rational x;
4028  Rational* val;
4029  int* lrow, *lidx, *idx;
4030  int* lbeg;
4031 
4032  DVectorRational& lval = l.val;
4033  lidx = l.idx;
4034  lrow = l.row;
4035  lbeg = l.start;
4036 
4037  assert(!l.updateType); /* Forest-Tomlin Updates */
4038 
4039  end = l.firstUpdate;
4040 
4041  for(i = l.firstUnused - 1; i >= end; --i)
4042  {
4043  k = lbeg[i];
4044  val = &lval[k];
4045  idx = &lidx[k];
4046  x = 0;
4047 
4048  for(j = lbeg[i + 1]; j > k; --j)
4049  x += vec[*idx++] * (*val++);
4050 
4051  vec[lrow[i]] -= x;
4052  }
4053 }
4054 
4056 {
4057  int i, j, k, end;
4058  Rational x1, x2;
4059  Rational* val;
4060  int* lrow, *lidx, *idx;
4061  int* lbeg;
4062 
4063  DVectorRational& lval = l.val;
4064  lidx = l.idx;
4065  lrow = l.row;
4066  lbeg = l.start;
4067 
4068  assert(!l.updateType); /* Forest-Tomlin Updates */
4069 
4070  end = l.firstUpdate;
4071 
4072  for(i = l.firstUnused - 1; i >= end; --i)
4073  {
4074  k = lbeg[i];
4075  val = &lval[k];
4076  idx = &lidx[k];
4077  x1 = 0;
4078  x2 = 0;
4079 
4080  for(j = lbeg[i + 1]; j > k; --j)
4081  {
4082  x1 += vec1[*idx] * (*val);
4083  x2 += vec2[*idx++] * (*val++);
4084  }
4085 
4086  vec1[lrow[i]] -= x1;
4087 
4088  vec2[lrow[i]] -= x2;
4089  }
4090 }
4091 
4093 {
4094  int i, j, k, end;
4095  Rational x, y;
4096  Rational* val;
4097  int* lrow, *lidx, *idx;
4098  int* lbeg;
4099 
4100  assert(!l.updateType); /* no Forest-Tomlin Updates! */
4101 
4102  DVectorRational& lval = l.val;
4103  lidx = l.idx;
4104  lrow = l.row;
4105  lbeg = l.start;
4106 
4107  end = l.firstUpdate;
4108 
4109  for(i = l.firstUnused - 1; i >= end; --i)
4110  {
4111  k = lbeg[i];
4112  assert(k >= 0 && k < l.val.dim());
4113  val = &lval[k];
4114  idx = &lidx[k];
4115  x = 0;
4116 
4117  for(j = lbeg[i + 1]; j > k; --j)
4118  {
4119  assert(*idx >= 0 && *idx < thedim);
4120  x += vec[*idx++] * (*val++);
4121  }
4122 
4123  k = lrow[i];
4124 
4125  y = vec[k];
4126 
4127  if(y == 0)
4128  {
4129  y = -x;
4130 
4131  if(y != 0)
4132  {
4133  nonz[n++] = k;
4134  vec[k] = y;
4135  }
4136  }
4137  else
4138  {
4139  y -= x;
4140  //vec[k] = ( y != 0 ) ? y : MARKER;
4141  vec[k] = y;
4142  }
4143  }
4144 
4145  return n;
4146 }
4147 
4149 {
4150 
4151  if(!l.updateType) /* no Forest-Tomlin Updates */
4152  {
4153  solveUpdateLeft(rhs);
4154  solveUleft(vec, rhs);
4155  solveLleft(vec);
4156  }
4157  else
4158  {
4159  solveUleft(vec, rhs);
4160  solveLleftForest(vec, 0);
4161  solveLleft(vec);
4162  }
4163 }
4164 
4166 {
4167 
4168  if(!l.updateType) /* no Forest-Tomlin Updates */
4169  {
4170  solveUpdateLeft(rhs);
4171  solveUleft(vec, rhs);
4172  return solveLleftEps(vec, nonz);
4173  }
4174  else
4175  {
4176  solveUleft(vec, rhs);
4177  solveLleftForest(vec, nonz);
4178  return solveLleftEps(vec, nonz);
4179  }
4180 }
4181 
4183  Rational* vec1,
4184  int* nonz,
4185  Rational* vec2,
4186  Rational* rhs1,
4187  Rational* rhs2)
4188 {
4189 
4190  if(!l.updateType) /* no Forest-Tomlin Updates */
4191  {
4192  solveUpdateLeft2(rhs1, rhs2);
4193  solveUleft2(vec1, rhs1, vec2, rhs2);
4194  solveLleft2(vec1, nonz, vec2);
4195  return 0;
4196  }
4197  else
4198  {
4199  solveUleft2(vec1, rhs1, vec2, rhs2);
4200  solveLleft2forest(vec1, nonz, vec2);
4201  solveLleft2(vec1, nonz, vec2);
4202  return 0;
4203  }
4204 }
4205 
4207  Rational* rhs, int* rhsidx, int rhsn)
4208 {
4209  Rational x, y;
4210  int i, j, k, n, r, c;
4211  int* rorig, *corig, *cperm;
4212  int* ridx, *rlen, *rbeg, *idx;
4213  Rational* val;
4214 
4215  rorig = row.orig;
4216  corig = col.orig;
4217  cperm = col.perm;
4218 
4219  /* move rhsidx to a heap
4220  */
4221 
4222  for(i = 0; i < rhsn;)
4223  enQueueMin(rhsidx, &i, cperm[rhsidx[i]]);
4224 
4225  ridx = u.row.idx;
4226 
4227  DVectorRational& rval = u.row.val;
4228 
4229  rlen = u.row.len;
4230 
4231  rbeg = u.row.start;
4232 
4233  n = 0;
4234 
4235  while(rhsn > 0)
4236  {
4237  i = deQueueMin(rhsidx, &rhsn);
4238  assert(i >= 0 && i < thedim);
4239  c = corig[i];
4240  assert(c >= 0 && c < thedim);
4241  x = rhs[c];
4242  rhs[c] = 0;
4243 
4244  if(x != 0)
4245  {
4246  r = rorig[i];
4247  assert(r >= 0 && r < thedim);
4248  vecidx[n++] = r;
4249  x *= diag[r];
4250  vec[r] = x;
4251  k = rbeg[r];
4252  assert(k >= 0 && k < u.row.val.dim());
4253  idx = &ridx[k];
4254  val = &rval[k];
4255 
4256  for(int m = rlen[r]; m; --m)
4257  {
4258  j = *idx++;
4259  assert(j >= 0 && j < thedim);
4260  y = rhs[j];
4261 
4262  if(y == 0)
4263  {
4264  y = -x * (*val++);
4265 
4266  if(y != 0)
4267  {
4268  rhs[j] = y;
4269  enQueueMin(rhsidx, &rhsn, cperm[j]);
4270  }
4271  }
4272  else
4273  {
4274  y -= x * (*val++);
4275  // rhs[j] = ( y != 0 ) ? y : MARKER;
4276  rhs[j] = y;
4277  }
4278  }
4279  }
4280  }
4281 
4282  return n;
4283 }
4284 
4285 
4286 void CLUFactorRational::solveUleftNoNZ(Rational* vec, Rational* rhs, int* rhsidx, int rhsn)
4287 {
4288  Rational x, y;
4289  int i, j, k, r, c;
4290  int* rorig, *corig, *cperm;
4291  int* ridx, *rlen, *rbeg, *idx;
4292  Rational* val;
4293 
4294  rorig = row.orig;
4295  corig = col.orig;
4296  cperm = col.perm;
4297 
4298  /* move rhsidx to a heap
4299  */
4300 
4301  for(i = 0; i < rhsn;)
4302  enQueueMin(rhsidx, &i, cperm[rhsidx[i]]);
4303 
4304  ridx = u.row.idx;
4305 
4306  DVectorRational& rval = u.row.val;
4307 
4308  rlen = u.row.len;
4309 
4310  rbeg = u.row.start;
4311 
4312  while(rhsn > 0)
4313  {
4314  i = deQueueMin(rhsidx, &rhsn);
4315  assert(i >= 0 && i < thedim);
4316  c = corig[i];
4317  assert(c >= 0 && c < thedim);
4318  x = rhs[c];
4319  rhs[c] = 0;
4320 
4321  if(x != 0)
4322  {
4323  r = rorig[i];
4324  assert(r >= 0 && r < thedim);
4325  x *= diag[r];
4326  vec[r] = x;
4327  k = rbeg[r];
4328  assert(k >= 0 && k < u.row.val.dim());
4329  idx = &ridx[k];
4330  val = &rval[k];
4331 
4332  for(int m = rlen[r]; m; --m)
4333  {
4334  j = *idx++;
4335  assert(j >= 0 && j < thedim);
4336  y = rhs[j];
4337 
4338  if(y == 0)
4339  {
4340  y = -x * (*val++);
4341 
4342  if(y != 0)
4343  {
4344  rhs[j] = y;
4345  enQueueMin(rhsidx, &rhsn, cperm[j]);
4346  }
4347  }
4348  else
4349  {
4350  y -= x * (*val++);
4351  // rhs[j] = ( y != 0 ) ? y : MARKER;
4352  rhs[j] = y;
4353  }
4354  }
4355  }
4356  }
4357 }
4358 
4359 
4361 {
4362  int i, j, k, end;
4363  Rational x, y;
4364  Rational* val;
4365  int* idx, *lidx, *lrow, *lbeg;
4366 
4367  DVectorRational& lval = l.val;
4368  lidx = l.idx;
4369  lrow = l.row;
4370  lbeg = l.start;
4371  end = l.firstUpdate;
4372 
4373  for(i = l.firstUnused - 1; i >= end; --i)
4374  {
4375  assert(i >= 0 && i < l.val.dim());
4376 
4377  if((x = vec[lrow[i]]) != 0)
4378  {
4379  k = lbeg[i];
4380  assert(k >= 0 && k < l.val.dim());
4381  val = &lval[k];
4382  idx = &lidx[k];
4383 
4384  for(j = lbeg[i + 1]; j > k; --j)
4385  {
4386  int m = *idx++;
4387  assert(m >= 0 && m < thedim);
4388  y = vec[m];
4389 
4390  if(y == 0)
4391  {
4392  y = -x * (*val++);
4393 
4394  if(y != 0)
4395  {
4396  vec[m] = y;
4397  nonz[n++] = m;
4398  }
4399  }
4400  else
4401  {
4402  y -= x * (*val++);
4403 
4404  }
4405  }
4406  }
4407  }
4408 
4409  return n;
4410 }
4411 
4412 
4414 {
4415  int i, j, k, end;
4416  Rational x;
4417  Rational* val;
4418  int* idx, *lidx, *lrow, *lbeg;
4419 
4420  DVectorRational& lval = l.val;
4421  lidx = l.idx;
4422  lrow = l.row;
4423  lbeg = l.start;
4424  end = l.firstUpdate;
4425 
4426  for(i = l.firstUnused - 1; i >= end; --i)
4427  {
4428  if((x = vec[lrow[i]]) != 0)
4429  {
4430  assert(i >= 0 && i < l.val.dim());
4431  k = lbeg[i];
4432  assert(k >= 0 && k < l.val.dim());
4433  val = &lval[k];
4434  idx = &lidx[k];
4435 
4436  for(j = lbeg[i + 1]; j > k; --j)
4437  {
4438  assert(*idx >= 0 && *idx < thedim);
4439  vec[*idx++] -= x * (*val++);
4440  }
4441  }
4442  }
4443 }
4444 
4445 
4446 int CLUFactorRational::solveLleft(Rational* vec, int* nonz, int rn)
4447 {
4448  int i, j, k, n;
4449  int r;
4450  Rational x, y;
4451  Rational* val;
4452  int* ridx, *idx;
4453  int* rbeg;
4454  int* rorig, *rperm;
4455  int* last;
4456 
4457  ridx = l.ridx;
4458  DVectorRational& rval = l.rval;
4459  rbeg = l.rbeg;
4460  rorig = l.rorig;
4461  rperm = l.rperm;
4462  n = 0;
4463 
4464  i = l.firstUpdate - 1;
4465 #ifndef WITH_L_ROWS
4466 #pragma warn "Not yet implemented, define WITH_L_ROWS"
4467  DVectorRational& lval = l.val;
4468  int* lidx = l.idx;
4469  int* lrow = l.row;
4470  int* lbeg = l.start;
4471 
4472  for(; i >= 0; --i)
4473  {
4474  k = lbeg[i];
4475  val = &lval[k];
4476  idx = &lidx[k];
4477  x = 0;
4478 
4479  for(j = lbeg[i + 1]; j > k; --j)
4480  x += vec[*idx++] * (*val++);
4481 
4482  vec[lrow[i]] -= x;
4483  }
4484 
4485 #else
4486 
4487  /* move rhsidx to a heap
4488  */
4489  for(i = 0; i < rn;)
4490  enQueueMax(nonz, &i, rperm[nonz[i]]);
4491 
4492  last = nonz + thedim;
4493 
4494  while(rn > 0)
4495  {
4496  i = deQueueMax(nonz, &rn);
4497  r = rorig[i];
4498  x = vec[r];
4499 
4500  if(x != 0)
4501  {
4502  *(--last) = r;
4503  n++;
4504  k = rbeg[r];
4505  j = rbeg[r + 1] - k;
4506  val = &rval[k];
4507  idx = &ridx[k];
4508 
4509  while(j-- > 0)
4510  {
4511  assert(l.rperm[*idx] < i);
4512  int m = *idx++;
4513  y = vec[m];
4514 
4515  if(y == 0)
4516  {
4517  y = -x * *val++;
4518 
4519  if(y != 0)
4520  {
4521  vec[m] = y;
4522  enQueueMax(nonz, &rn, rperm[m]);
4523  }
4524  }
4525  else
4526  {
4527  y -= x * *val++;
4528  // vec[m] = ( y != 0 ) ? y : MARKER;
4529  vec[m] = y;
4530  }
4531  }
4532  }
4533  else
4534  vec[r] = 0;
4535  }
4536 
4537  for(i = 0; i < n; ++i)
4538  *nonz++ = *last++;
4539 
4540 #endif
4541 
4542  return n;
4543 }
4544 
4545 
4547 {
4548  int i, j, k;
4549  int r;
4550  Rational x;
4551  Rational* val;
4552  int* ridx, *idx;
4553  int* rbeg;
4554  int* rorig;
4555 
4556  ridx = l.ridx;
4557  DVectorRational& rval = l.rval;
4558  rbeg = l.rbeg;
4559  rorig = l.rorig;
4560 
4561 #ifndef WITH_L_ROWS
4562  DVectorRational& lval = l.val;
4563  int* lidx = l.idx;
4564  int* lrow = l.row;
4565  int* lbeg = l.start;
4566 
4567  i = l.firstUpdate - 1;
4568  assert(i < thedim);
4569 
4570  for(; i >= 0; --i)
4571  {
4572  k = lbeg[i];
4573  assert(k >= 0 && k < l.val.dim());
4574  val = &lval[k];
4575  idx = &lidx[k];
4576  x = 0;
4577 
4578  for(j = lbeg[i + 1]; j > k; --j)
4579  {
4580  assert(*idx >= 0 && *idx < thedim);
4581  x += vec[*idx++] * (*val++);
4582  }
4583 
4584  vec[lrow[i]] -= x;
4585  }
4586 
4587 #else
4588 
4589  for(i = thedim; i--;)
4590  {
4591  r = rorig[i];
4592  x = vec[r];
4593 
4594  if(x != 0)
4595  {
4596  k = rbeg[r];
4597  j = rbeg[r + 1] - k;
4598  val = &rval[k];
4599  idx = &ridx[k];
4600 
4601  while(j-- > 0)
4602  {
4603  assert(l.rperm[*idx] < i);
4604  vec[*idx++] -= x * *val++;
4605  }
4606  }
4607  }
4608 
4609 #endif
4610 }
4611 
4612 int CLUFactorRational::vSolveLright(Rational* vec, int* ridx, int rn)
4613 {
4614  int i, j, k, n;
4615  int end;
4616  Rational x;
4617  Rational* val;
4618  int* lrow, *lidx, *idx;
4619  int* lbeg;
4620 
4621  DVectorRational& lval = l.val;
4622  lidx = l.idx;
4623  lrow = l.row;
4624  lbeg = l.start;
4625 
4626  end = l.firstUpdate;
4627 
4628  for(i = 0; i < end; ++i)
4629  {
4630  x = vec[lrow[i]];
4631 
4632  if(x != 0)
4633  {
4634  k = lbeg[i];
4635  idx = &(lidx[k]);
4636  val = &(lval[k]);
4637 
4638  for(j = lbeg[i + 1]; j > k; --j)
4639  {
4640  assert(*idx >= 0 && *idx < thedim);
4641  ridx[rn] = n = *idx++;
4642  rn += (vec[n] == 0) ? 1 : 0;
4643  vec[n] -= x * (*val++);
4644  // vec[n] += ( vec[n] == 0 ) ? MARKER : 0;
4645  }
4646  }
4647  }
4648 
4649  if(l.updateType) /* Forest-Tomlin Updates */
4650  {
4651  end = l.firstUnused;
4652 
4653  for(; i < end; ++i)
4654  {
4655  x = 0;
4656  k = lbeg[i];
4657  idx = &(lidx[k]);
4658  val = &(lval[k]);
4659 
4660  for(j = lbeg[i + 1]; j > k; --j)
4661  {
4662  assert(*idx >= 0 && *idx < thedim);
4663  x += vec[*idx++] * (*val++);
4664  }
4665 
4666  ridx[rn] = j = lrow[i];
4667 
4668  rn += (vec[j] == 0) ? 1 : 0;
4669  vec[j] -= x;
4670  // vec[j] += ( vec[j] == 0 ) ? MARKER : 0;
4671  }
4672  }
4673 
4674  return rn;
4675 }
4676 
4677 void CLUFactorRational::vSolveLright2(Rational* vec, int* ridx, int* rnptr,
4678  Rational* vec2, int* ridx2, int* rn2ptr)
4679 {
4680  int i, j, k, n;
4681  int end;
4682  Rational x, y;
4683  Rational x2, y2;
4684  Rational* val;
4685  int* lrow, *lidx, *idx;
4686  int* lbeg;
4687 
4688  int rn = *rnptr;
4689  int rn2 = *rn2ptr;
4690 
4691  DVectorRational& lval = l.val;
4692  lidx = l.idx;
4693  lrow = l.row;
4694  lbeg = l.start;
4695 
4696  end = l.firstUpdate;
4697 
4698  for(i = 0; i < end; ++i)
4699  {
4700  j = lrow[i];
4701  x2 = vec2[j];
4702  x = vec[j];
4703 
4704  if(x != 0)
4705  {
4706  k = lbeg[i];
4707  idx = &(lidx[k]);
4708  val = &(lval[k]);
4709 
4710  if(x2 != 0)
4711  {
4712  for(j = lbeg[i + 1]; j > k; --j)
4713  {
4714  assert(*idx >= 0 && *idx < thedim);
4715  ridx[rn] = ridx2[rn2] = n = *idx++;
4716  y = vec[n];
4717  y2 = vec2[n];
4718  rn += (y == 0) ? 1 : 0;
4719  rn2 += (y2 == 0) ? 1 : 0;
4720  y -= x * (*val);
4721  y2 -= x2 * (*val++);
4722  // vec[n] = y + ( y == 0 ? MARKER : 0 );
4723  // vec2[n] = y2 + ( y2 == 0 ? MARKER : 0 );
4724  vec[n] = y;
4725  vec2[n] = y2;
4726  }
4727  }
4728  else
4729  {
4730  for(j = lbeg[i + 1]; j > k; --j)
4731  {
4732  assert(*idx >= 0 && *idx < thedim);
4733  ridx[rn] = n = *idx++;
4734  y = vec[n];
4735  rn += (y == 0) ? 1 : 0;
4736  y -= x * (*val++);
4737  // vec[n] = y + ( y == 0 ? MARKER : 0 );
4738  vec[n] = y;
4739  }
4740  }
4741  }
4742  else if(x2 != 0)
4743  {
4744  k = lbeg[i];
4745  idx = &(lidx[k]);
4746  val = &(lval[k]);
4747 
4748  for(j = lbeg[i + 1]; j > k; --j)
4749  {
4750  assert(*idx >= 0 && *idx < thedim);
4751  ridx2[rn2] = n = *idx++;
4752  y2 = vec2[n];
4753  rn2 += (y2 == 0) ? 1 : 0;
4754  y2 -= x2 * (*val++);
4755  // vec2[n] = y2 + ( y2 == 0 ? MARKER : 0 );
4756  vec2[n] = y2;
4757  }
4758  }
4759  }
4760 
4761  if(l.updateType) /* Forest-Tomlin Updates */
4762  {
4763  end = l.firstUnused;
4764 
4765  for(; i < end; ++i)
4766  {
4767  x = x2 = 0;
4768  k = lbeg[i];
4769  idx = &(lidx[k]);
4770  val = &(lval[k]);
4771 
4772  for(j = lbeg[i + 1]; j > k; --j)
4773  {
4774  assert(*idx >= 0 && *idx < thedim);
4775  x += vec[*idx] * (*val);
4776  x2 += vec2[*idx++] * (*val++);
4777  }
4778 
4779  ridx[rn] = ridx2[rn2] = j = lrow[i];
4780 
4781  rn += (vec[j] == 0) ? 1 : 0;
4782  rn2 += (vec2[j] == 0) ? 1 : 0;
4783  vec[j] -= x;
4784  vec2[j] -= x2;
4785  // vec[j] += ( vec[j] == 0 ) ? MARKER : 0;
4786  // vec2[j] += ( vec2[j] == 0 ) ? MARKER : 0;
4787  }
4788  }
4789 
4790  *rnptr = rn;
4791 
4792  *rn2ptr = rn2;
4793 }
4794 
4795 void CLUFactorRational::vSolveLright3(Rational* vec, int* ridx, int* rnptr,
4796  Rational* vec2, int* ridx2, int* rn2ptr,
4797  Rational* vec3, int* ridx3, int* rn3ptr)
4798 {
4799  int i, j, k, n;
4800  int end;
4801  Rational x, y;
4802  Rational x2, y2;
4803  Rational x3, y3;
4804  Rational* val;
4805  int* lrow, *lidx, *idx;
4806  int* lbeg;
4807 
4808  int rn = *rnptr;
4809  int rn2 = *rn2ptr;
4810  int rn3 = *rn3ptr;
4811 
4812  DVectorRational& lval = l.val;
4813  lidx = l.idx;
4814  lrow = l.row;
4815  lbeg = l.start;
4816 
4817  end = l.firstUpdate;
4818 
4819  for(i = 0; i < end; ++i)
4820  {
4821  j = lrow[i];
4822  x3 = vec3[j];
4823  x2 = vec2[j];
4824  x = vec[j];
4825 
4826  if(x != 0)
4827  {
4828  k = lbeg[i];
4829  idx = &(lidx[k]);
4830  val = &(lval[k]);
4831 
4832  if(x2 != 0)
4833  {
4834  if(x3 != 0)
4835  {
4836  // case 1: all three vectors are nonzero at j
4837  for(j = lbeg[i + 1]; j > k; --j)
4838  {
4839  assert(*idx >= 0 && *idx < thedim);
4840  ridx[rn] = ridx2[rn2] = ridx3[rn3] = n = *idx++;
4841  y = vec[n];
4842  y2 = vec2[n];
4843  y3 = vec3[n];
4844  rn += (y == 0) ? 1 : 0;
4845  rn2 += (y2 == 0) ? 1 : 0;
4846  rn3 += (y3 == 0) ? 1 : 0;
4847  y -= x * (*val);
4848  y2 -= x2 * (*val);
4849  y3 -= x3 * (*val++);
4850  // vec[n] = y + ( y == 0 ? MARKER : 0 );
4851  // vec2[n] = y2 + ( y2 == 0 ? MARKER : 0 );
4852  // vec3[n] = y3 + ( y3 == 0 ? MARKER : 0 );
4853  vec[n] = y;
4854  vec2[n] = y2;
4855  vec3[n] = y3;
4856  }
4857  }
4858  else
4859  {
4860  // case 2: 1 and 2 are nonzero at j
4861  for(j = lbeg[i + 1]; j > k; --j)
4862  {
4863  assert(*idx >= 0 && *idx < thedim);
4864  ridx[rn] = ridx2[rn2] = n = *idx++;
4865  y = vec[n];
4866  y2 = vec2[n];
4867  rn += (y == 0) ? 1 : 0;
4868  rn2 += (y2 == 0) ? 1 : 0;
4869  y -= x * (*val);
4870  y2 -= x2 * (*val++);
4871  // vec[n] = y + ( y == 0 ? MARKER : 0 );
4872  //vec2[n] = y2 + ( y2 == 0 ? MARKER : 0 );
4873  vec[n] = y;
4874  vec2[n] = y2;
4875  }
4876  }
4877  }
4878  else if(x3 != 0)
4879  {
4880  // case 3: 1 and 3 are nonzero at j
4881  for(j = lbeg[i + 1]; j > k; --j)
4882  {
4883  assert(*idx >= 0 && *idx < thedim);
4884  ridx[rn] = ridx3[rn3] = n = *idx++;
4885  y = vec[n];
4886  y3 = vec3[n];
4887  rn += (y == 0) ? 1 : 0;
4888  rn3 += (y3 == 0) ? 1 : 0;
4889  y -= x * (*val);
4890  y3 -= x3 * (*val++);
4891  // vec[n] = y + ( y == 0 ? MARKER : 0 );
4892  // vec3[n] = y3 + ( y3 == 0 ? MARKER : 0 );
4893  vec[n] = y;
4894  vec3[n] = y3;
4895  }
4896  }
4897  else
4898  {
4899  // case 4: only 1 is nonzero at j
4900  for(j = lbeg[i + 1]; j > k; --j)
4901  {
4902  assert(*idx >= 0 && *idx < thedim);
4903  ridx[rn] = n = *idx++;
4904  y = vec[n];
4905  rn += (y == 0) ? 1 : 0;
4906  y -= x * (*val++);
4907  // vec[n] = y + ( y == 0 ? MARKER : 0 );
4908  vec[n] = y;
4909  }
4910  }
4911  }
4912  else if(x2 != 0)
4913  {
4914  k = lbeg[i];
4915  idx = &(lidx[k]);
4916  val = &(lval[k]);
4917 
4918  if(x3 != 0)
4919  {
4920  // case 5: 2 and 3 are nonzero at j
4921  for(j = lbeg[i + 1]; j > k; --j)
4922  {
4923  assert(*idx >= 0 && *idx < thedim);
4924  ridx2[rn2] = ridx3[rn3] = n = *idx++;
4925  y2 = vec2[n];
4926  y3 = vec3[n];
4927  rn2 += (y2 == 0) ? 1 : 0;
4928  rn3 += (y3 == 0) ? 1 : 0;
4929  y2 -= x2 * (*val);
4930  y3 -= x3 * (*val++);
4931  // vec2[n] = y2 + ( y2 == 0 ? MARKER : 0 );
4932  // vec3[n] = y3 + ( y3 == 0 ? MARKER : 0 );
4933  vec2[n] = y2;
4934  vec3[n] = y3;
4935  }
4936  }
4937  else
4938  {
4939  // case 6: only 2 is nonzero at j
4940  for(j = lbeg[i + 1]; j > k; --j)
4941  {
4942  assert(*idx >= 0 && *idx < thedim);
4943  ridx2[rn2] = n = *idx++;
4944  y2 = vec2[n];
4945  rn2 += (y2 == 0) ? 1 : 0;
4946  y2 -= x2 * (*val++);
4947  // vec2[n] = y2 + ( y2 == 0 ? MARKER : 0 );
4948  vec2[n] = y2;
4949  }
4950  }
4951  }
4952  else if(x3 != 0)
4953  {
4954  // case 7: only 3 is nonzero at j
4955  k = lbeg[i];
4956  idx = &(lidx[k]);
4957  val = &(lval[k]);
4958 
4959  for(j = lbeg[i + 1]; j > k; --j)
4960  {
4961  assert(*idx >= 0 && *idx < thedim);
4962  ridx3[rn3] = n = *idx++;
4963  y3 = vec3[n];
4964  rn3 += (y3 == 0) ? 1 : 0;
4965  y3 -= x3 * (*val++);
4966  // vec3[n] = y3 + ( y3 == 0 ? MARKER : 0 );
4967  vec3[n] = y3;
4968  }
4969  }
4970  }
4971 
4972  if(l.updateType) /* Forest-Tomlin Updates */
4973  {
4974  end = l.firstUnused;
4975 
4976  for(; i < end; ++i)
4977  {
4978  x = x2 = x3 = 0;
4979  k = lbeg[i];
4980  idx = &(lidx[k]);
4981  val = &(lval[k]);
4982 
4983  for(j = lbeg[i + 1]; j > k; --j)
4984  {
4985  assert(*idx >= 0 && *idx < thedim);
4986  x += vec[*idx] * (*val);
4987  x2 += vec2[*idx] * (*val);
4988  x3 += vec3[*idx++] * (*val++);
4989  }
4990 
4991  ridx[rn] = ridx2[rn2] = ridx3[rn3] = j = lrow[i];
4992 
4993  rn += (vec[j] == 0) ? 1 : 0;
4994  rn2 += (vec2[j] == 0) ? 1 : 0;
4995  rn3 += (vec3[j] == 0) ? 1 : 0;
4996  vec[j] -= x;
4997  vec2[j] -= x2;
4998  vec3[j] -= x3;
4999  // vec[j] += ( vec[j] == 0 ) ? MARKER : 0;
5000  // vec2[j] += ( vec2[j] == 0 ) ? MARKER : 0;
5001  // vec3[j] += ( vec3[j] == 0 ) ? MARKER : 0;
5002  }
5003  }
5004 
5005  *rnptr = rn;
5006 
5007  *rn2ptr = rn2;
5008  *rn3ptr = rn3;
5009 }
5010 
5012  Rational* rhs, int* ridx, int rn)
5013 {
5014  int i, j, k, r, c, n;
5015  int* rorig, *corig;
5016  int* rperm;
5017  int* cidx, *clen, *cbeg;
5018  Rational x, y;
5019 
5020  int* idx;
5021  Rational* val;
5022 
5023  rorig = row.orig;
5024  corig = col.orig;
5025  rperm = row.perm;
5026 
5027  cidx = u.col.idx;
5028  DVectorRational& cval = u.col.val;
5029  clen = u.col.len;
5030  cbeg = u.col.start;
5031 
5032  n = 0;
5033 
5034  while(rn > 0)
5035  {
5036  /* Find nonzero with highest permuted row index and setup i and r
5037  */
5038  i = deQueueMax(ridx, &rn);
5039  assert(i >= 0 && i < thedim);
5040  r = rorig[i];
5041  assert(r >= 0 && r < thedim);
5042 
5043  x = diag[r] * rhs[r];
5044  rhs[r] = 0;
5045 
5046  if(x != 0)
5047  {
5048  c = corig[i];
5049  assert(c >= 0 && c < thedim);
5050  vidx[n++] = c;
5051  vec[c] = x;
5052  val = &cval[cbeg[c]];
5053  idx = &cidx[cbeg[c]];
5054  j = clen[c];
5055 
5056  while(j-- > 0)
5057  {
5058  assert(*idx >= 0 && *idx < thedim);
5059  k = *idx++;
5060  assert(k >= 0 && k < thedim);
5061  y = rhs[k];
5062 
5063  if(y == 0)
5064  {
5065  y = -x * (*val++);
5066 
5067  if(y != 0)
5068  {
5069  rhs[k] = y;
5070  enQueueMax(ridx, &rn, rperm[k]);
5071  }
5072  }
5073  else
5074  {
5075  y -= x * (*val++);
5076  // y += ( y == 0 ) ? MARKER : 0;
5077  rhs[k] = y;
5078  }
5079  }
5080 
5081  if(rn > i * verySparseFactor4right)
5082  {
5083  /* continue with dense case */
5084  for(i = *ridx; i >= 0; --i)
5085  {
5086  r = rorig[i];
5087  assert(r >= 0 && r < thedim);
5088  x = diag[r] * rhs[r];
5089  rhs[r] = 0;
5090 
5091  if(x != 0)
5092  {
5093  c = corig[i];
5094  assert(c >= 0 && c < thedim);
5095  vidx[n++] = c;
5096  vec[c] = x;
5097  val = &cval[cbeg[c]];
5098  idx = &cidx[cbeg[c]];
5099  j = clen[c];
5100 
5101  while(j-- > 0)
5102  {
5103  assert(*idx >= 0 && *idx < thedim);
5104  rhs[*idx++] -= x * (*val++);
5105  }
5106  }
5107  }
5108 
5109  break;
5110  }
5111  }
5112  }
5113 
5114  return n;
5115 }
5116 
5117 
5118 void CLUFactorRational::vSolveUrightNoNZ(Rational* vec, Rational* rhs, int* ridx, int rn)
5119 {
5120  int i, j, k, r, c;
5121  int* rorig, *corig;
5122  int* rperm;
5123  int* cidx, *clen, *cbeg;
5124  Rational x, y;
5125 
5126  int* idx;
5127  Rational* val;
5128 
5129  rorig = row.orig;
5130  corig = col.orig;
5131  rperm = row.perm;
5132 
5133  cidx = u.col.idx;
5134  DVectorRational& cval = u.col.val;
5135  clen = u.col.len;
5136  cbeg = u.col.start;
5137 
5138  while(rn > 0)
5139  {
5140  if(rn > *ridx * verySparseFactor4right)
5141  {
5142  /* continue with dense case */
5143  for(i = *ridx; i >= 0; --i)
5144  {
5145  assert(i >= 0 && i < thedim);
5146  r = rorig[i];
5147  assert(r >= 0 && r < thedim);
5148  x = diag[r] * rhs[r];
5149  rhs[r] = 0;
5150 
5151  if(x != 0)
5152  {
5153  c = corig[i];
5154  vec[c] = x;
5155  val = &cval[cbeg[c]];
5156  idx = &cidx[cbeg[c]];
5157  j = clen[c];
5158 
5159  while(j-- > 0)
5160  {
5161  assert(*idx >= 0 && *idx < thedim);
5162  rhs[*idx++] -= x * (*val++);
5163  }
5164  }
5165  }
5166 
5167  break;
5168  }
5169 
5170  /* Find nonzero with highest permuted row index and setup i and r
5171  */
5172  i = deQueueMax(ridx, &rn);
5173 
5174  assert(i >= 0 && i < thedim);
5175 
5176  r = rorig[i];
5177 
5178  assert(r >= 0 && r < thedim);
5179 
5180  x = diag[r] * rhs[r];
5181 
5182  rhs[r] = 0;
5183 
5184  if(x != 0)
5185  {
5186  c = corig[i];
5187  vec[c] = x;
5188  val = &cval[cbeg[c]];
5189  idx = &cidx[cbeg[c]];
5190  j = clen[c];
5191 
5192  while(j-- > 0)
5193  {
5194  k = *idx++;
5195  assert(k >= 0 && k < thedim);
5196  y = rhs[k];
5197 
5198  if(y == 0)
5199  {
5200  y = -x * (*val++);
5201 
5202  if(y != 0)
5203  {
5204  rhs[k] = y;
5205  enQueueMax(ridx, &rn, rperm[k]);
5206  }
5207  }
5208  else
5209  {
5210  y -= x * (*val++);
5211  // y += ( y == 0 ) ? MARKER : 0;
5212  rhs[k] = y;
5213  }
5214  }
5215  }
5216  }
5217 }
5218 
5219 
5220 int CLUFactorRational::vSolveUright2(Rational* vec, int* vidx, Rational* rhs, int* ridx, int rn,
5221  Rational* vec2, Rational* rhs2, int* ridx2, int rn2)
5222 {
5223  int i, j, k, r, c, n;
5224  int* rorig, *corig;
5225  int* rperm;
5226  int* cidx, *clen, *cbeg;
5227  Rational x, y;
5228  Rational x2, y2;
5229 
5230  int* idx;
5231  Rational* val;
5232 
5233  rorig = row.orig;
5234  corig = col.orig;
5235  rperm = row.perm;
5236 
5237  cidx = u.col.idx;
5238  DVectorRational& cval = u.col.val;
5239  clen = u.col.len;
5240  cbeg = u.col.start;
5241 
5242  n = 0;
5243 
5244  while(rn + rn2 > 0)
5245  {
5246  /* Find nonzero with highest permuted row index and setup i and r
5247  */
5248  if(rn <= 0)
5249  i = deQueueMax(ridx2, &rn2);
5250  else if(rn2 <= 0)
5251  i = deQueueMax(ridx, &rn);
5252  else if(*ridx2 > *ridx)
5253  i = deQueueMax(ridx2, &rn2);
5254  else if(*ridx2 < *ridx)
5255  i = deQueueMax(ridx, &rn);
5256  else
5257  {
5258  (void) deQueueMax(ridx, &rn);
5259  i = deQueueMax(ridx2, &rn2);
5260  }
5261 
5262  assert(i >= 0 && i < thedim);
5263 
5264  r = rorig[i];
5265  assert(r >= 0 && r < thedim);
5266 
5267  x = diag[r] * rhs[r];
5268  x2 = diag[r] * rhs2[r];
5269  rhs[r] = 0;
5270  rhs2[r] = 0;
5271 
5272  if(x != 0)
5273  {
5274  c = corig[i];
5275  vidx[n++] = c;
5276  vec[c] = x;
5277  vec2[c] = x2;
5278  val = &cval[cbeg[c]];
5279  idx = &cidx[cbeg[c]];
5280  j = clen[c];
5281 
5282  if(x2 != 0)
5283  {
5284  while(j-- > 0)
5285  {
5286  k = *idx++;
5287  assert(k >= 0 && k < thedim);
5288  y2 = rhs2[k];
5289 
5290  if(y2 == 0)
5291  {
5292  y2 = -x2 * (*val);
5293 
5294  if(y2 != 0)
5295  {
5296  rhs2[k] = y2;
5297  enQueueMax(ridx2, &rn2, rperm[k]);
5298  }
5299  }
5300  else
5301  {
5302  y2 -= x2 * (*val);
5303  // rhs2[k] = ( y2 != 0 ) ? y2 : MARKER;
5304  rhs2[k] = y2;
5305  }
5306 
5307  y = rhs[k];
5308 
5309  if(y == 0)
5310  {
5311  y = -x * (*val++);
5312 
5313  if(y != 0)
5314  {
5315  rhs[k] = y;
5316  enQueueMax(ridx, &rn, rperm[k]);
5317  }
5318  }
5319  else
5320  {
5321  y -= x * (*val++);
5322  // y += ( y == 0 ) ? MARKER : 0;
5323  rhs[k] = y;
5324  }
5325  }
5326  }
5327  else
5328  {
5329  while(j-- > 0)
5330  {
5331  k = *idx++;
5332  assert(k >= 0 && k < thedim);
5333  y = rhs[k];
5334 
5335  if(y == 0)
5336  {
5337  y = -x * (*val++);
5338 
5339  if(y != 0)
5340  {
5341  rhs[k] = y;
5342  enQueueMax(ridx, &rn, rperm[k]);
5343  }
5344  }
5345  else
5346  {
5347  y -= x * (*val++);
5348  // y += ( y == 0 ) ? MARKER : 0;
5349  rhs[k] = y;
5350  }
5351  }
5352  }
5353  }
5354  else if(x2 != 0)
5355  {
5356  c = corig[i];
5357  assert(c >= 0 && c < thedim);
5358  vec2[c] = x2;
5359  val = &cval[cbeg[c]];
5360  idx = &cidx[cbeg[c]];
5361  j = clen[c];
5362 
5363  while(j-- > 0)
5364  {
5365  k = *idx++;
5366  assert(k >= 0 && k < thedim);
5367  y2 = rhs2[k];
5368 
5369  if(y2 == 0)
5370  {
5371  y2 = -x2 * (*val++);
5372 
5373  if(y2 != 0)
5374  {
5375  rhs2[k] = y2;
5376  enQueueMax(ridx2, &rn2, rperm[k]);
5377  }
5378  }
5379  else
5380  {
5381  y2 -= x2 * (*val++);
5382  // rhs2[k] = ( y2 != 0 ) ? y2 : MARKER;
5383  rhs2[k] = y2;
5384  }
5385  }
5386  }
5387 
5388  if(rn + rn2 > i * verySparseFactor4right)
5389  {
5390  /* continue with dense case */
5391  if(*ridx > *ridx2)
5392  i = *ridx;
5393  else
5394  i = *ridx2;
5395 
5396  for(; i >= 0; --i)
5397  {
5398  assert(i < thedim);
5399  r = rorig[i];
5400  assert(r >= 0 && r < thedim);
5401  x = diag[r] * rhs[r];
5402  x2 = diag[r] * rhs2[r];
5403  rhs[r] = 0;
5404  rhs2[r] = 0;
5405 
5406  if(x2 != 0)
5407  {
5408  c = corig[i];
5409  assert(c >= 0 && c < thedim);
5410  vec2[c] = x2;
5411  val = &cval[cbeg[c]];
5412  idx = &cidx[cbeg[c]];
5413  j = clen[c];
5414 
5415  if(x != 0)
5416  {
5417  vidx[n++] = c;
5418  vec[c] = x;
5419 
5420  while(j-- > 0)
5421  {
5422  assert(*idx >= 0 && *idx < thedim);
5423  rhs[*idx] -= x * (*val);
5424  rhs2[*idx++] -= x2 * (*val++);
5425  }
5426  }
5427  else
5428  {
5429  while(j-- > 0)
5430  {
5431  assert(*idx >= 0 && *idx < thedim);
5432  rhs2[*idx++] -= x2 * (*val++);
5433  }
5434  }
5435  }
5436  else if(x != 0)
5437  {
5438  c = corig[i];
5439  assert(c >= 0 && c < thedim);
5440  vidx[n++] = c;
5441  vec[c] = x;
5442  val = &cval[cbeg[c]];
5443  idx = &cidx[cbeg[c]];
5444  j = clen[c];
5445 
5446  while(j-- > 0)
5447  {
5448  assert(*idx >= 0 && *idx < thedim);
5449  rhs[*idx++] -= x * (*val++);
5450  }
5451  }
5452  }
5453 
5454  break;
5455  }
5456  }
5457 
5458  return n;
5459 }
5460 
5462 {
5463  int i, j, k;
5464  int end;
5465  Rational x, y;
5466  Rational* val;
5467  int* lrow, *lidx, *idx;
5468  int* lbeg;
5469 
5470  assert(!l.updateType); /* no Forest-Tomlin Updates */
5471 
5472  DVectorRational& lval = l.val;
5473  lidx = l.idx;
5474  lrow = l.row;
5475  lbeg = l.start;
5476  end = l.firstUnused;
5477 
5478  for(i = l.firstUpdate; i < end; ++i)
5479  {
5480  assert(i >= 0 && i < thedim);
5481  x = vec[lrow[i]];
5482 
5483  if(x != 0)
5484  {
5485  k = lbeg[i];
5486  assert(k >= 0 && k < l.val.dim());
5487  idx = &(lidx[k]);
5488  val = &(lval[k]);
5489 
5490  for(j = lbeg[i + 1]; j > k; --j)
5491  {
5492  int m = ridx[n] = *idx++;
5493  assert(m >= 0 && m < thedim);
5494  y = vec[m];
5495  n += (y == 0) ? 1 : 0;
5496  y = y - x * (*val++);
5497  // vec[m] = ( y != 0 ) ? y : MARKER;
5498  vec[m] = y;
5499  }
5500  }
5501  }
5502 
5503  return n;
5504 }
5505 
5507 {
5508  int i, j, k;
5509  int end;
5510  Rational x;
5511  Rational* val;
5512  int* lrow, *lidx, *idx;
5513  int* lbeg;
5514 
5515  assert(!l.updateType); /* no Forest-Tomlin Updates */
5516 
5517  DVectorRational& lval = l.val;
5518  lidx = l.idx;
5519  lrow = l.row;
5520  lbeg = l.start;
5521  end = l.firstUnused;
5522 
5523  for(i = l.firstUpdate; i < end; ++i)
5524  {
5525  assert(i >= 0 && i < thedim);
5526 
5527  if((x = vec[lrow[i]]) != 0)
5528  {
5529  k = lbeg[i];
5530  assert(k >= 0 && k < l.val.dim());
5531  idx = &(lidx[k]);
5532  val = &(lval[k]);
5533 
5534  for(j = lbeg[i + 1]; j > k; --j)
5535  {
5536  assert(*idx >= 0 && *idx < thedim);
5537  vec[*idx++] -= x * (*val++);
5538  }
5539  }
5540  }
5541 }
5542 
5543 
5545  int* idx, /* result */
5546  Rational* rhs, int* ridx, int rn, /* rhs */
5547  Rational* forest, int* forestNum, int* forestIdx)
5548 {
5549  rn = vSolveLright(rhs, ridx, rn);
5550 
5551  /* turn index list into a heap
5552  */
5553 
5554  if(forest)
5555  {
5556  Rational x;
5557  int i, j, k;
5558  int* rperm;
5559  int* it = forestIdx;
5560 
5561  rperm = row.perm;
5562 
5563  for(i = j = 0; i < rn; ++i)
5564  {
5565  k = ridx[i];
5566  assert(k >= 0 && k < thedim);
5567  x = rhs[k];
5568 
5569  if(x != 0)
5570  {
5571  enQueueMax(ridx, &j, rperm[*it++ = k]);
5572  forest[k] = x;
5573  }
5574  else
5575  rhs[k] = 0;
5576  }
5577 
5578  *forestNum = rn = j;
5579  }
5580  else
5581  {
5582  Rational x;
5583  int i, j, k;
5584  int* rperm;
5585 
5586  rperm = row.perm;
5587 
5588  for(i = j = 0; i < rn; ++i)
5589  {
5590  k = ridx[i];
5591  assert(k >= 0 && k < thedim);
5592  x = rhs[k];
5593 
5594  if(x != 0)
5595  enQueueMax(ridx, &j, rperm[k]);
5596  else
5597  rhs[k] = 0;
5598  }
5599 
5600  rn = j;
5601  }
5602 
5603  rn = vSolveUright(vec, idx, rhs, ridx, rn);
5604 
5605  if(!l.updateType) /* no Forest-Tomlin Updates */
5606  rn = vSolveUpdateRight(vec, idx, rn);
5607 
5608  return rn;
5609 }
5610 
5612  int* idx, /* result1 */
5613  Rational* rhs, int* ridx, int rn, /* rhs1 */
5614  Rational* vec2, /* result2 */
5615  Rational* rhs2, int* ridx2, int rn2, /* rhs2 */
5616  Rational* forest, int* forestNum, int* forestIdx)
5617 {
5618  vSolveLright2(rhs, ridx, &rn, rhs2, ridx2, &rn2);
5619 
5620  /* turn index list into a heap
5621  */
5622 
5623  if(forest)
5624  {
5625  Rational x;
5626  int i, j, k;
5627  int* rperm;
5628  int* it = forestIdx;
5629 
5630  rperm = row.perm;
5631 
5632  for(i = j = 0; i < rn; ++i)
5633  {
5634  k = ridx[i];
5635  assert(k >= 0 && k < thedim);
5636  x = rhs[k];
5637 
5638  if(x != 0)
5639  {
5640  enQueueMax(ridx, &j, rperm[*it++ = k]);
5641  forest[k] = x;
5642  }
5643  else
5644  rhs[k] = 0;
5645  }
5646 
5647  *forestNum = rn = j;
5648  }
5649  else
5650  {
5651  Rational x;
5652  int i, j, k;
5653  int* rperm;
5654 
5655  rperm = row.perm;
5656 
5657  for(i = j = 0; i < rn; ++i)
5658  {
5659  k = ridx[i];
5660  assert(k >= 0 && k < thedim);
5661  x = rhs[k];
5662 
5663  if(x != 0)
5664  enQueueMax(ridx, &j, rperm[k]);
5665  else
5666  rhs[k] = 0;
5667  }
5668 
5669  rn = j;
5670  }
5671 
5672  if(rn2 > thedim * verySparseFactor4right)
5673  {
5674  ridx2[0] = thedim - 1;
5675  /* ridx2[1] = thedim - 2; */
5676  }
5677  else
5678  {
5679  Rational x;
5680  /* Rational maxabs; */
5681  int i, j, k;
5682  int* rperm;
5683 
5684  /* maxabs = 1; */
5685  rperm = row.perm;
5686 
5687  for(i = j = 0; i < rn2; ++i)
5688  {
5689  k = ridx2[i];
5690  assert(k >= 0 && k < thedim);
5691  x = rhs2[k];
5692 
5693  if(x == 0)
5694  {
5695  /* maxabs = (maxabs < -x) ? -x : maxabs; */
5696  enQueueMax(ridx2, &j, rperm[k]);
5697  }
5698  else
5699  rhs2[k] = 0;
5700  }
5701 
5702  rn2 = j;
5703 
5704  }
5705 
5706  rn = vSolveUright(vec, idx, rhs, ridx, rn);
5707 
5708  vSolveUrightNoNZ(vec2, rhs2, ridx2, rn2);
5709 
5710  /*
5711  * rn = vSolveUright2(vec, idx, rhs, ridx, rn, vec2, rhs2, ridx2, rn2 );
5712  */
5713 
5714  if(!l.updateType) /* no Forest-Tomlin Updates */
5715  {
5716  rn = vSolveUpdateRight(vec, idx, rn);
5717  vSolveUpdateRightNoNZ(vec2);
5718  }
5719 
5720  return rn;
5721 }
5722 
5724  int* idx, /* result1 */
5725  Rational* rhs, int* ridx, int rn, /* rhs1 */
5726  Rational* vec2, /* result2 */
5727  Rational* rhs2, int* ridx2, int rn2, /* rhs2 */
5728  Rational* vec3, /* result3 */
5729  Rational* rhs3, int* ridx3, int rn3, /* rhs3 */
5730  Rational* forest, int* forestNum, int* forestIdx)
5731 {
5732 
5733  vSolveLright3(rhs, ridx, &rn, rhs2, ridx2, &rn2, rhs3, ridx3, &rn3);
5734  assert(rn >= 0 && rn <= thedim);
5735  assert(rn2 >= 0 && rn2 <= thedim);
5736  assert(rn3 >= 0 && rn3 <= thedim);
5737 
5738  /* turn index list into a heap
5739  */
5740 
5741  if(forest)
5742  {
5743  Rational x;
5744  int i, j, k;
5745  int* rperm;
5746  int* it = forestIdx;
5747 
5748  rperm = row.perm;
5749 
5750  for(i = j = 0; i < rn; ++i)
5751  {
5752  k = ridx[i];
5753  assert(k >= 0 && k < thedim);
5754  x = rhs[k];
5755 
5756  if(x != 0)
5757  {
5758  enQueueMax(ridx, &j, rperm[*it++ = k]);
5759  forest[k] = x;
5760  }
5761  else
5762  rhs[k] = 0;
5763  }
5764 
5765  *forestNum = rn = j;
5766  }
5767  else
5768  {
5769  Rational x;
5770  int i, j, k;
5771  int* rperm;
5772 
5773  rperm = row.perm;
5774 
5775  for(i = j = 0; i < rn; ++i)
5776  {
5777  k = ridx[i];
5778  assert(k >= 0 && k < thedim);
5779  x = rhs[k];
5780 
5781  if(x != 0)
5782  enQueueMax(ridx, &j, rperm[k]);
5783  else
5784  rhs[k] = 0;
5785  }
5786 
5787  rn = j;
5788  }
5789 
5790  if(rn2 > thedim * verySparseFactor4right)
5791  {
5792  ridx2[0] = thedim - 1;
5793  }
5794  else
5795  {
5796  Rational x;
5797  int i, j, k;
5798  int* rperm;
5799 
5800  rperm = row.perm;
5801 
5802  for(i = j = 0; i < rn2; ++i)
5803  {
5804  k = ridx2[i];
5805  assert(k >= 0 && k < thedim);
5806  x = rhs2[k];
5807 
5808  if(x == 0)
5809  {
5810  enQueueMax(ridx2, &j, rperm[k]);
5811  }
5812  else
5813  rhs2[k] = 0;
5814  }
5815 
5816  rn2 = j;
5817  }
5818 
5819  if(rn3 > thedim * verySparseFactor4right)
5820  {
5821  ridx3[0] = thedim - 1;
5822  }
5823  else
5824  {
5825  Rational x;
5826  int i, j, k;
5827  int* rperm;
5828 
5829  rperm = row.perm;
5830 
5831  for(i = j = 0; i < rn3; ++i)
5832  {
5833  k = ridx3[i];
5834  assert(k >= 0 && k < thedim);
5835  x = rhs3[k];
5836 
5837  if(x == 0)
5838  {
5839  enQueueMax(ridx3, &j, rperm[k]);
5840  }
5841  else
5842  rhs3[k] = 0;
5843  }
5844 
5845  rn3 = j;
5846  }
5847 
5848  rn = vSolveUright(vec, idx, rhs, ridx, rn);
5849 
5850  vSolveUrightNoNZ(vec2, rhs2, ridx2, rn2);
5851  vSolveUrightNoNZ(vec3, rhs3, ridx3, rn3);
5852 
5853  if(!l.updateType) /* no Forest-Tomlin Updates */
5854  {
5855  rn = vSolveUpdateRight(vec, idx, rn);
5856  vSolveUpdateRightNoNZ(vec2);
5857  vSolveUpdateRightNoNZ(vec3);
5858  }
5859 
5860  return rn;
5861 }
5862 
5864  Rational* rhs2, int* ridx2, int rn2) /* rhs2 */
5865 {
5866  rn2 = vSolveLright(rhs2, ridx2, rn2);
5867  assert(rn2 >= 0 && rn2 <= thedim);
5868 
5869  if(rn2 > thedim * verySparseFactor4right)
5870  {
5871  *ridx2 = thedim - 1;
5872  }
5873  else
5874  {
5875  Rational x;
5876  /* Rational maxabs; */
5877  int i, j, k;
5878  int* rperm;
5879 
5880  /* maxabs = 1; */
5881  rperm = row.perm;
5882 
5883  for(i = j = 0; i < rn2; ++i)
5884  {
5885  k = ridx2[i];
5886  assert(k >= 0 && k < thedim);
5887  x = rhs2[k];
5888 
5889  if(x == 0)
5890  {
5891  /* maxabs = (maxabs < -x) ? -x : maxabs; */
5892  enQueueMax(ridx2, &j, rperm[k]);
5893  }
5894  else
5895  rhs2[k] = 0;
5896  }
5897 
5898  rn2 = j;
5899  }
5900 
5901  vSolveUrightNoNZ(vec2, rhs2, ridx2, rn2);
5902 
5903  if(!l.updateType) /* no Forest-Tomlin Updates */
5904  vSolveUpdateRightNoNZ(vec2);
5905 }
5906 
5907 int CLUFactorRational::vSolveLeft(Rational* vec, int* idx, /* result */
5908  Rational* rhs, int* ridx, int rn) /* rhs */
5909 {
5910 
5911  if(!l.updateType) /* no Forest-Tomlin Updates */
5912  {
5913  rn = solveUpdateLeft(rhs, ridx, rn);
5914  rn = solveUleft(vec, idx, rhs, ridx, rn);
5915  }
5916  else
5917  {
5918  rn = solveUleft(vec, idx, rhs, ridx, rn);
5919  rn = solveLleftForest(vec, idx, rn);
5920  }
5921 
5922  return solveLleft(vec, idx, rn);
5923 }
5924 
5925 int CLUFactorRational::vSolveLeft2(Rational* vec, int* idx, /* result */
5926  Rational* rhs, int* ridx, int rn, /* rhs */
5927  Rational* vec2, /* result2 */
5928  Rational* rhs2, int* ridx2, int rn2) /* rhs2 */
5929 {
5930 
5931  if(!l.updateType) /* no Forest-Tomlin Updates */
5932  {
5933  rn = solveUpdateLeft(rhs, ridx, rn);
5934  rn = solveUleft(vec, idx, rhs, ridx, rn);
5935  rn2 = solveUpdateLeft(rhs2, ridx2, rn2);
5936  solveUleftNoNZ(vec2, rhs2, ridx2, rn2);
5937  }
5938  else
5939  {
5940  rn = solveUleft(vec, idx, rhs, ridx, rn);
5941  rn = solveLleftForest(vec, idx, rn);
5942  solveUleftNoNZ(vec2, rhs2, ridx2, rn2);
5943  solveLleftForestNoNZ(vec2);
5944  }
5945 
5946  rn = solveLleft(vec, idx, rn);
5947 
5948  solveLleftNoNZ(vec2);
5949 
5950  return rn;
5951 }
5952 
5953 int CLUFactorRational::vSolveLeft3(Rational* vec, int* idx, /* result */
5954  Rational* rhs, int* ridx, int rn, /* rhs */
5955  Rational* vec2, /* result2 */
5956  Rational* rhs2, int* ridx2, int rn2, /* rhs2 */
5957  Rational* vec3, /* result3 */
5958  Rational* rhs3, int* ridx3, int rn3) /* rhs3 */
5959 {
5960 
5961  if(!l.updateType) /* no Forest-Tomlin Updates */
5962  {
5963  rn = solveUpdateLeft(rhs, ridx, rn);
5964  rn = solveUleft(vec, idx, rhs, ridx, rn);
5965  rn2 = solveUpdateLeft(rhs2, ridx2, rn2);
5966  solveUleftNoNZ(vec2, rhs2, ridx2, rn2);
5967  rn3 = solveUpdateLeft(rhs3, ridx3, rn3);
5968  solveUleftNoNZ(vec3, rhs3, ridx3, rn3);
5969  }
5970  else
5971  {
5972  rn = solveUleft(vec, idx, rhs, ridx, rn);
5973  rn = solveLleftForest(vec, idx, rn);
5974  solveUleftNoNZ(vec2, rhs2, ridx2, rn2);
5975  solveLleftForestNoNZ(vec2);
5976  solveUleftNoNZ(vec3, rhs3, ridx3, rn3);
5977  solveLleftForestNoNZ(vec3);
5978  }
5979 
5980  rn = solveLleft(vec, idx, rn);
5981 
5982  solveLleftNoNZ(vec2);
5983  solveLleftNoNZ(vec3);
5984 
5985  return rn;
5986 }
5987 
5989  Rational* rhs2, int* ridx2, int rn2) /* rhs2 */
5990 {
5991 
5992  if(!l.updateType) /* no Forest-Tomlin Updates */
5993  {
5994  rn2 = solveUpdateLeft(rhs2, ridx2, rn2);
5995  solveUleftNoNZ(vec2, rhs2, ridx2, rn2);
5996  }
5997  else
5998  {
5999  solveUleftNoNZ(vec2, rhs2, ridx2, rn2);
6000  solveLleftForestNoNZ(vec2);
6001  }
6002 
6003  solveLleftNoNZ(vec2);
6004 }
6005 } // namespace soplex
int mkwtz
markowitz number of pivot
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:4102
void remaxCol(int p_col, int len)
Real lMemMult
factor of minimum Memory * number of nonzeros
int * start
starting positions in val and idx
int firstUpdate
number of first update L vector
int * ridx
indices of rows of L
int solveRight2update(Rational *vec1, Rational *vec2, Rational *rhs1, Rational *rhs2, int *nonz, Rational *forest, int *forestNum, int *forestIdx)
int used
used entries of array idx
int * max
maximum available nonzeros per colunn: start[i] + max[i] == start[elem[i].next->idx] len[i] <= max[i]...
void reDim(int newdim, const bool setZero=true)
Resets DVectorBase&#39;s dimension to newdim.
Definition: dvectorbase.h:253
Rational * work
Working array: must always be left as 0!
int solveRight4update(Rational *vec, int *nonz, Rational *rhs, Rational *forest, int *forestNum, int *forestIdx)
Pring pivots
ring of selected pivot rows
Memory allocation routines.
int * max
maximum available nonzeros per row: start[i] + max[i] == start[elem[i].next->idx] len[i] <= max[i]...
Dring list
Double linked ringlist of vector indices in the order they appear in the column file.
Real colMemMult
factor of minimum Memory * number of nonzeros
int firstUnused
number of first unused L vector
struct soplex::CLUFactorRational::U::Col col
void solveUleft(Rational *work, Rational *vec)
int size() const
Number of used indices.
Definition: svectorbase.h:153
Implementation of sparse LU factorization with Rational precision.
Exception classes for SoPlex.
int thedim
dimension of factorized matrix
#define init2DR(elem, ring)
Definition: cring.h:25
int * row
column indices of L vectors
void forestReMaxCol(int col, int len)
int solveLleft2forest(Rational *vec1, int *, Rational *vec2)
The loaded matrix is singular.
DVectorRational diag
Array of pivot elements.
void solveUpdateLeft(Rational *vec)
#define removeDR(ring)
Definition: cring.h:33
Temp temp
Temporary storage.
void update(int p_col, Rational *p_work, const int *p_idx, int num)
int used
used entries of arrays idx and val
static void enQueueMin(int *heap, int *size, int elem)
Definition: clufactor.cpp:123
void factor(const SVectorRational **vec, const Rational &threshold)
pivoting threshold
int vSolveUright2(Rational *vec, int *vidx, Rational *rhs, int *ridx, int rn, Rational *vec2, Rational *rhs2, int *ridx2, int rn2)
R & value(int n)
Reference to value of n &#39;th nonzero.
Definition: svectorbase.h:253
void solveUpdateRight2(Rational *vec1, Rational *vec2)
Wrapper for GMP type mpq_class.We wrap mpq_class so that we can replace it by a double type if GMP is...
Definition: rational.h:44
int solveUright2eps(Rational *work1, Rational *vec1, Rational *work2, Rational *vec2, int *nonz)
int updateType
type of updates to be used.
void initFactorMatrix(const SVectorRational **vec)
void eliminatePivot(int prow, int pos)
int solveUrightEps(Rational *vec, int *nonz, Rational *rhs)
int vSolveLeft(Rational *vec, int *idx, Rational *rhs, int *ridx, int rn)
DVectorRational val
hold nonzero values: this is only initialized in the end of the factorization with DEFAULT updates...
int solveLleftEps(Rational *vec, int *nonz)
Rational initMaxabs
maximum abs number in initail Matrix
void solveRight(Rational *vec, Rational *rhs)
virtual void start()=0
start timer, resume accounting user, system and real time.
virtual Real stop()=0
stop timer, return accounted user time.
void spx_alloc(T &p, int n=1)
Allocate memory.
Definition: spxalloc.h:48
void clear()
clears the structure
int vSolveUright(Rational *vec, int *vidx, Rational *rhs, int *ridx, int rn)
DVectorRational s_max
maximum absolute value per row (or -1)
static const Real verySparseFactor4right
Definition: clufactor.cpp:34
int * start
starting positions in val and idx
int vSolveRight4update(Rational *vec, int *idx, Rational *rhs, int *ridx, int rn, Rational *forest, int *forestNum, int *forestIdx)
int solveLeftEps(Rational *vec, Rational *rhs, int *nonz)
void solveLleftNoNZ(Rational *vec)
double Real
Definition: spxdefines.h:218
void solveLright2(Rational *vec1, Rational *vec2)
int pos
position of pivot column in row
#define MSG_DEBUG(x)
Definition: spxdefines.h:132
void solveUright2(Rational *work1, Rational *vec1, Rational *work2, Rational *vec2)
void solveUleft2(Rational *work1, Rational *vec1, Rational *work2, Rational *vec2)
int vSolveLeft2(Rational *vec, int *idx, Rational *rhs, int *ridx, int rn, Rational *vec2, Rational *rhs2, int *ridx2, int rn2)
int solveLeft2(Rational *vec1, int *nonz, Rational *vec2, Rational *rhs1, Rational *rhs2)
void solveUright(Rational *wrk, Rational *vec)
void setPivot(const int p_stage, const int p_col, const int p_row, const Rational &val)
int & index(int n)
Reference to index of n &#39;th nonzero.
Definition: svectorbase.h:235
Real rowMemMult
factor of minimum Memory * number of nonzeros
void solveLeft(Rational *vec, Rational *rhs)
Pring * pivot_rowNZ
lists for rows to number of nonzeros
void vSolveLeftNoNZ(Rational *vec, Rational *rhs, int *ridx, int rn)
int * s_cact
lengths of columns of active submatrix
int vSolveLright(Rational *vec, int *ridx, int rn)
Wrapper for GMP types.
DVectorRational val
values of L vectors
void vSolveUrightNoNZ(Rational *vec, Rational *rhs, int *ridx, int rn)
Dring list
Double linked ringlist of vector indices in the order they appear in the row file.
Perm row
row permutation matrices
int * rorig
original row permutation
void selectPivots(const Rational &threshold)
void vSolveRightNoNZ(Rational *vec2, Rational *rhs2, int *ridx2, int rn2)
DVectorRational rval
values of rows of L
Timer * factorTime
Time spent in factorizations.
int stage
stage of the structure
Debugging, floating point type and parameter definitions.
int * idx
array of size val.dim() storing indices of L vectors
void spx_realloc(T &p, int n)
Change amount of allocated memory.
Definition: spxalloc.h:79
void solveRight2(Rational *vec1, Rational *vec2, Rational *rhs1, Rational *rhs2)
void vSolveLright3(Rational *vec, int *ridx, int *rnptr, Rational *vec2, int *ridx2, int *rn2ptr, Rational *vec3, int *ridx3, int *rn3ptr)
int makeLvec(int p_len, int p_row)
Collection of dense, sparse, and semi-sparse vectors.
int dim() const
Dimension of vector.
Definition: vectorbase.h:217
Everything should be within this namespace.
void solveLleft2(Rational *vec1, int *, Rational *vec2)
struct soplex::CLUFactorRational::U::Row row
int * perm
perm[i] permuted index from i
void remaxRow(int p_row, int len)
int * len
used nonzeros per column vector
int * len
used nonzeros per row vectors
DVectorRational val
hold nonzero values
int * idx
hold row indices of nonzeros
int updateRow(int r, int lv, int prow, int pcol, const Rational &pval)
int vSolveUpdateRight(Rational *vec, int *ridx, int n)
int * start
starting positions in val and idx
Dring * elem
Array of ring elements.
int vSolveLeft3(Rational *vec, int *idx, Rational *rhs, int *ridx, int rn, Rational *vec2, Rational *rhs2, int *ridx2, int rn2, Rational *vec3, Rational *rhs3, int *ridx3, int rn3)
int factorCount
Number of factorizations.
static int deQueueMax(int *heap, int *size)
Definition: clufactor.cpp:69
int startSize
size of array start
void vSolveUpdateRightNoNZ(Rational *vec)
void forestUpdate(int col, Rational *work, int num, int *nonz)
Performs the Forrest-Tomlin update of the LU factorization.
void eliminateNucleus(const Rational &threshold)
#define initDR(ring)
Definition: cring.h:23
int vSolveRight4update2(Rational *vec, int *idx, Rational *rhs, int *ridx, int rn, Rational *vec2, Rational *rhs2, int *ridx2, int rn2, Rational *forest, int *forestNum, int *forestIdx)
static const Real verySparseFactor
Definition: clufactor.cpp:33
int solveLleftForest(Rational *vec, int *)
Rational maxabs
maximum abs number in L and U
Perm col
column permutation matrices
Pring * pivot_colNZ
lists for columns to number of nonzeros
static void enQueueMax(int *heap, int *size, int elem)
Definition: clufactor.cpp:38
Exception class for status exceptions during the computationsThis class is derived from the SoPlex ex...
Definition: exceptions.h:89
int * rperm
original row permutation
void solveUpdateLeft2(Rational *vec1, Rational *vec2)
Pring * pivot_row
row index handlers for Real linked list
void vSolveLright2(Rational *vec, int *ridx, int *rnptr, Rational *vec2, int *ridx2, int *rn2ptr)
void updateNoClear(int p_col, const Rational *p_work, const int *p_idx, int num)
int * rbeg
start of rows in rval and ridx
void solveUpdateRight(Rational *vec)
Dring * elem
Array of ring elements.
int * idx
array of length val.dim() to hold column indices of nonzeros in val
Pring * pivot_col
column index handlers for Real linked list
void solveLleftForestNoNZ(Rational *vec)
int * orig
orig[p] original index from p
void solveUleftNoNZ(Rational *vec, Rational *rhs, int *rhsidx, int rhsn)
int vSolveRight4update3(Rational *vec, int *idx, Rational *rhs, int *ridx, int rn, Rational *vec2, Rational *rhs2, int *ridx2, int rn2, Rational *vec3, Rational *rhs3, int *ridx3, int rn3, Rational *forest, int *forestNum, int *forestIdx)
int nzCnt
number of nonzeros in U
void spx_free(T &p)
Release memory.
Definition: spxalloc.h:110
void init(int p_dim)
initialization
static int deQueueMin(int *heap, int *size)
Definition: clufactor.cpp:154
SLinSolverRational::Status stat
Status indicator.