Macaulay2 Engine
Loading...
Searching...
No Matches
matrix-sort.cpp
Go to the documentation of this file.
1
32
33#include "matrix.hpp"
34
49{
50 const Ring *R;
57
58 int sort_compare(int i, int j)
59 {
60 if (i == j) return 0;
61 vec v1 = sort_vecs[i];
62 vec v2 = sort_vecs[j];
63 if (v1 == nullptr) return 1;
64 if (v2 == nullptr) return -1;
65 if (deg_ascending != 0)
66 {
67 int d1 = sort_degs[i];
68 int d2 = sort_degs[j];
69 if (d1 > d2) return -deg_ascending;
70 if (d1 < d2) return deg_ascending;
71 }
72 int cmp = R->compare_vecs(v1, v2);
73 if (cmp > 0) return -ringorder_ascending;
74 if (cmp < 0) return ringorder_ascending;
75 return 0;
76 }
77
78 int sort_partition(int lo, int hi)
79 {
80 int pivot = sort_vals[lo];
81 int i = lo - 1;
82 int j = hi + 1;
83 for (;;)
84 {
85 do
86 {
87 j--;
88 }
89 while (sort_compare(sort_vals[j], pivot) < 0);
90 do
91 {
92 i++;
93 }
94 while (sort_compare(sort_vals[i], pivot) > 0);
95
96 if (i < j)
97 {
98 int tmp = sort_vals[j];
99 sort_vals[j] = sort_vals[i];
100 sort_vals[i] = tmp;
101 }
102 else
103 return j;
104 }
105 }
106
107 void sort_range(int lo, int hi)
108 {
109 if (lo < hi)
110 {
111 int q = sort_partition(lo, hi);
112 sort_range(lo, q);
113 sort_range(q + 1, hi);
114 }
115 }
116
117 public:
118 MatrixSorter(const Matrix *m, int degorder, int ringorder);
119
121};
122
123MatrixSorter::MatrixSorter(const Matrix *m, int degorder, int ringorder)
124 : deg_ascending(degorder), ringorder_ascending(ringorder)
125{
126 R = m->get_ring();
127
128 int nelems = m->n_cols();
129
130 if (degorder != 0)
131 {
132 sort_degs = newarray_atomic(int, nelems);
133 for (int i = 0; i < nelems; i++)
134 sort_degs[i] = m->cols()->primary_degree(i);
135 }
136
137 result = M2_makearrayint(nelems);
138
139 sort_vals = result->array;
140 for (int i = 0; i < nelems; i++) sort_vals[i] = i;
141
142 sort_vecs = newarray(vec, nelems);
143 for (int i = 0; i < nelems; i++) sort_vecs[i] = m->elem(i);
144}
145
147{
148 sort_range(0, result->len - 1);
149 return result;
150}
151
152M2_arrayint Matrix::sort(int degorder, int ringorder) const
153// Sort the columns of 'this': Place the column indices into 'result'.
154// If degorder < 0, sort in descending degree order, if >0 ascending degree
155// If ==0, or in the event that two columns have the same (simple) degree,
156// use the ring order: ringorder > 0 means ascending, <0 means descending.
157{
158 MatrixSorter sorter(this, degorder, ringorder);
159 return sorter.value();
160}
161
162// Local Variables:
163// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
164// indent-tabs-mode: nil
165// End:
int primary_degree(int i) const
Definition freemod.cpp:440
const Ring * get_ring() const
Definition matrix.hpp:134
ring_elem elem(int i, int j) const
Definition matrix.cpp:307
int n_cols() const
Definition matrix.hpp:147
M2_arrayint sort(int degorder, int monorder) const
const FreeModule * cols() const
Definition matrix.hpp:145
int sort_compare(int i, int j)
int sort_partition(int lo, int hi)
const Ring * R
int ringorder_ascending
M2_arrayintOrNull value()
M2_arrayint result
MatrixSorter(const Matrix *m, int degorder, int ringorder)
void sort_range(int lo, int hi)
Helper that computes a column permutation for an engine Matrix by degree-then-monomial-order sort.
xxx xxx xxx
Definition ring.hpp:102
#define Matrix
Definition factory.cpp:14
M2_arrayint M2_makearrayint(int n)
Definition m2-types.cpp:6
M2_arrayint M2_arrayintOrNull
Definition m2-types.h:99
Matrix — the engine's immutable homomorphism F -> G between free modules.
#define newarray(T, len)
Definition newdelete.hpp:82
#define newarray_atomic(T, len)
Definition newdelete.hpp:91