Macaulay2 Engine
Loading...
Searching...
No Matches
fractionfreeLU.cpp
Go to the documentation of this file.
1// Copyright 2004 Michael E. Stillman
2
3#include "fractionfreeLU.hpp"
4#include "interrupted.hpp"
5
7// Fraction free gaussian elimination //
9
11 : R(M0->get_ring()), M(M0), col_perm(nullptr), need_div(nullptr)
12{
13 int ncols = static_cast<int>(M->n_cols());
14 col_perm = newarray_atomic(int, ncols);
15 need_div = newarray_atomic(bool, ncols);
16 pivot_col = ncols; // Will be decremented before use
17 for (int i = 0; i < ncols; i++)
18 {
19 col_perm[i] = i;
20 need_div[i] = false;
21 }
22
23 pivot = R->from_long(1);
24 lastpivot = R->from_long(1);
25}
26
34
36{
37 int r = -1; // If this remains -1, then no better column was found
38 int c = -1;
39 for (int i = lo; i <= hi; i++)
40 {
41 int r1 = static_cast<int>(M->lead_row(i));
42 if (r1 > r)
43 {
44 r = r1;
45 c = i;
46 }
47 }
48 if (r == -1) return false;
49
50 result = c;
51 return true;
52}
53
54void FF_LUComputation::do_pivots(int lo, int hi, int pivotCol)
55{
56 // Here we clear out row r in columns lo..hi, using the pivot.
57 R->remove(lastpivot);
59 size_t pivot_row = M->lead_row(
60 pivotCol, pivot); // pivot is the element at (pivot_row, pivotCol)
61
62 for (int i = lo; i <= hi; i++)
63 {
64 ring_elem a;
65 size_t r = M->lead_row(i, a);
66 if (r == pivot_row)
67 {
68 // Need to modify column i:
69 // col(i) := pivot*M[i] - M[pivot_row,i] * M[pivotCol]
70 R->negate_to(a);
71 M->scale_column(i, pivot);
72 M->column_op(i, a, pivotCol);
73 }
74
75 if (need_div[i]) M->divide_column(i, lastpivot);
76
77 need_div[i] = (r == pivot_row);
78 }
79}
80
82{
83 int c1;
84 while (choose_pivot_column(0, --pivot_col, c1))
85 {
86 if (system_interrupted()) return false;
87
88 if (pivot_col != c1)
89 {
90 M->interchange_columns(pivot_col, c1);
91
92 // swap need_div[pivot_col], need_div[c1]
93 bool tmp = need_div[pivot_col];
95 need_div[c1] = tmp;
96
97 // swap col_perm
98 int ctmp = col_perm[pivot_col];
100 col_perm[c1] = ctmp;
101 }
102
104 }
105 return true;
106}
107
109{
110 int ncols = static_cast<int>(M->n_cols());
112 for (int i = 0; i < ncols; i++) result->array[i] = col_perm[i];
113 return result;
114}
115
117{
119 if (!F.calc()) return nullptr;
120 M2_arrayint col_permutation = F.get_column_permutation();
121 return col_permutation;
122}
123
124// Local Variables:
125// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
126// indent-tabs-mode: nil
127// End:
bool choose_pivot_column(int lo, int hi, int &result)
M2_arrayint get_column_permutation()
MutableMatrix * M
void do_pivots(int lo, int hi, int pivot_col)
FF_LUComputation(MutableMatrix *M)
static M2_arrayintOrNull DO(MutableMatrix *M)
Abstract base class for mutable matrices over an arbitrary engine Ring, the in-place counterpart of t...
Definition mat.hpp:79
FF_LUComputation — Bareiss-style fraction-free LU over an integral domain.
bool system_interrupted()
system_interrupted() — thread-safe polling predicate for Ctrl+C handling.
void freemem(void *s)
Definition m2-mem.cpp:103
VALGRIND_MAKE_MEM_DEFINED & result(result)
M2_arrayint M2_makearrayint(int n)
Definition m2-types.cpp:6
M2_arrayint M2_arrayintOrNull
Definition m2-types.h:99
#define newarray_atomic(T, len)
Definition newdelete.hpp:91