quern.h 10.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
* Quern: a sparse QR library.
* This code is in the public domain.
* - Robert Bridson
*/

#ifndef QUERN_H
#define QUERN_H

#ifdef __cplusplus
extern "C" {
#endif

14
15
#include "openmm/internal/windowsExport.h"

16
17
18
19
20
21
22
23
24
25
// Function return values: nonzero indicates an error
#define QUERN_OK 0
#define QUERN_INPUT_ERROR 1
#define QUERN_OUT_OF_MEMORY 2

// Takes a compressed sparse column format matrix and outputs it in compressed
// sparse row format (suitable for the QR factorization routines).
// Requires A1_row_start to have room for num_columns+1 entries,
//          A1_column_index to have room for all nonzeros,
//      and A1_value to have room for all nonzeros.
26
int OPENMM_EXPORT QUERN_convert_column_format_to_row_format(int num_rows,
27
28
29
30
31
32
33
34
35
36
37
38
                                              int num_columns,
                                              const int* A0_column_start,
                                              const int* A0_row_index,
                                              const double* A0_value,
                                              int* A1_row_start,
                                              int* A1_column_index,
                                              double* A1_value);

// Takes a compressed sparse row format m*n matrix and finds a reversed
// breadth-first search column ordering, suitable for incomplete QR
// preconditioning.
// Requires column_order to have room for n entries.
39
int OPENMM_EXPORT QUERN_get_rbfs_column_ordering(int m,
40
41
42
43
44
45
46
                                   int n,
                                   const int* A_row_start,
                                   const int* A_column_index,
                                   int* column_order);

// Takes a length n column ordering and a compressed sparse row format m*n
// matrix, then reorders each row accordingly.
47
int OPENMM_EXPORT QUERN_reorder_columns(int m,
48
49
50
51
52
53
54
55
56
57
58
59
                          int n,
                          const int* column_order,
                          const int* A_row_start,
                          int* A_column_index,
                          double* A_value);

// Takes a compressed sparse row format m*n matrix and finds a row ordering
// which minimizes the lower profile---in particular, if A's rows can be
// permuted to make it upper triangular, row_order will do the trick.
// This is recommended as a cheap pre-process before QR, at least if nothing
// is known about the current structure, to improve performance.
// Requires row_order to have room for m integers.
60
int OPENMM_EXPORT QUERN_get_profile_row_ordering(int m,
61
62
63
64
65
66
                                   int n,
                                   const int* A_row_start,
                                   const int* A_column_index,
                                   int* row_order);

// Reorders a given input vector x into an output vector y of length m.
67
int OPENMM_EXPORT QUERN_reorder_vector(int m,
68
69
70
71
72
73
                         const int* order,
                         const double* x,
                         double* y);

// Applies the inverse order to a given input vector x, saving in an output
// vector y of length m.
74
int OPENMM_EXPORT QUERN_inverse_order_vector(int m,
75
76
77
78
79
80
81
82
83
                               const int* order,
                               const double* x,
                               double* y);

// Takes a compressed sparse row format m*n matrix (m>=n) and outputs the upper
// triangular R factor from QR, also in compressed sparse row format. If
// row_order is non-null, it should contain the order in which rows of A should be
// taken; if it is null, the natural ordering is used. Memory for R is
// allocated internally; use QUERN_free_result to free.
84
int OPENMM_EXPORT QUERN_compute_qr_without_q(int m,
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
                               int n,
                               const int* A_row_start,
                               const int* A_column_index,
                               const double* A_value,
                               const int* row_order,
                               int** ptr_R_row_start,
                               int** ptr_R_column_index,
                               double** ptr_R_value);

// Takes a compressed sparse row format m*n matrix (m>=n) and outputs the QR
// factors. The storage for Q encodes a sequence of Givens rotations and row
// swaps; it is not directly usable as a standard sparse matrix. R, however,
// is stored in standard compressed sparse row format. If row_order is non-null
// it should contain the order in which rows of A should be taken; if it is
// null, the natural ordering is used. Memory for Q and R is allocated
// internally; use QUERN_free_result to free.
101
int OPENMM_EXPORT QUERN_compute_qr(int m,
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
                     int n,
                     const int* A_row_start,
                     const int* A_column_index,
                     const double* A_value,
                     const int* row_order,
                     int** ptr_Q_row_start,
                     int** ptr_Q_column_index,
                     double** ptr_Q_value,
                     int** ptr_R_row_start,
                     int** ptr_R_column_index,
                     double** ptr_R_value);

// Takes a compressed sparse row format m*n matrix (m>=n) and outputs the upper
// triangular R factor from QR, with small entries dropped, also in compressed
// sparse row format. If row_order is non-null, it should contain the order in
// which rows of A should be taken; if it is null, the natural ordering is used.
// Memory for R is allocated internally; use QUERN_free_result to free.
119
int OPENMM_EXPORT QUERN_compute_incomplete_qr_without_q(int m,
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
                                          int n,
                                          const int* A_row_start,
                                          const int* A_column_index,
                                          const double* A_value,
                                          const int* row_order,
                                          double drop_tolerance,
                                          int** ptr_R_row_start,
                                          int** ptr_R_column_index,
                                          double** ptr_R_value);

// Takes a compressed sparse row format m*n matrix (m>=n) and outputs incomplete
// QR factors. The storage for Q encodes a sequence of Givens rotations and row
// swaps; it is not directly usable as a standard sparse matrix. R, however,
// is stored in standard compressed sparse row format. If row_order is non-null
// it should contain the order in which rows of A should be taken; if it is
// null, the natural ordering is used. Memory for Q and R is allocated
// internally; use QUERN_free_result to free.
137
int OPENMM_EXPORT QUERN_compute_incomplete_qr(int m,
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
                                int n,
                                const int* A_row_start,
                                const int* A_column_index,
                                const double* A_value,
                                const int* row_order,
                                double drop_tolerance,
                                int** ptr_Q_row_start,
                                int** ptr_Q_column_index,
                                double** ptr_Q_value,
                                int** ptr_R_row_start,
                                int** ptr_R_column_index,
                                double** ptr_R_value);

// Free the memory allocated during QR factorization (for either Q or R).
// After calling this, do not try to access the factor again!
153
void OPENMM_EXPORT QUERN_free_result(int* row_start,
154
155
156
157
158
                       int* column_index,
                       double* value);

// Compute the product of an m*n CSR matrix with n-vector input in
// m-vector result.
159
int OPENMM_EXPORT QUERN_multiply(int m,
160
161
162
163
164
165
166
167
168
                   int n,
                   const int* row_start,
                   const int* column_index,
                   const double* value,
                   const double* input,
                   double* result);

// Compute the product of an m*n CSR matrix transposes with m-vector input in
// n-vector result.
169
int OPENMM_EXPORT QUERN_multiply_transpose(int m,
170
171
172
173
174
175
176
177
178
179
180
181
                             int n,
                             const int* row_start,
                             const int* column_index,
                             const double* value,
                             const double* input,
                             double* result);

// Compute the product Q*x in-place (Q from QR factorization).
// Note: if the input is naturally a length n vector, you should pad it with
// zeros to make it length m.
// If a row reordering of A was involved, you probably want to
// call QUERN_inverse_order_vector afterwards.
182
int OPENMM_EXPORT QUERN_multiply_with_q(int m,
183
184
185
186
187
188
189
190
                          const int* Q_row_start,
                          const int* Q_column_index,
                          const double* Q_value,
                          double* x);

// Compute the product Q^T*x in-place (Q from QR factorization).
// If a row reordering of A was involved, you probably want to
// call QUERN_reorder_vector first.
191
int OPENMM_EXPORT QUERN_multiply_with_q_transpose(int m,
192
193
194
195
196
197
198
                                    const int* Q_row_start,
                                    const int* Q_column_index,
                                    const double* Q_value,
                                    double* x);

// Compute result=R^{-1}*rhs (R from QR factorization).
// The vector result may actually be aliased to rhs, for an in-place solve.
199
int OPENMM_EXPORT QUERN_solve_with_r(int n,
200
201
202
203
204
205
206
                       const int* R_row_start,
                       const int* R_column_index,
                       const double* R_value,
                       const double* rhs,
                       double* result);

// Compute R^{-T}*x in-place (R from QR factorization).
207
int OPENMM_EXPORT QUERN_solve_with_r_transpose_in_place(int n,
208
209
210
211
212
213
214
                                          const int* R_row_start,
                                          const int* R_column_index,
                                          const double* R_value,
                                          double* x);

// CGNR solver for A^T*A*x=rhs, starting with zero initial guess,
// with R as preconditioner.
215
int OPENMM_EXPORT QUERN_solve_with_CGNR(int m,
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
                          int n,
                          const int* A_row_start,
                          const int* A_column_index,
                          const double* A_value,
                          const double* rhs,
                          const int* R_row_start,
                          const int* R_column_index,
                          const double* R_value,
                          int max_iterations,
                          double absolute_convergence_tolerance,
                          double* x,
                          int* return_solved,
                          int* return_iterations,
                          double* return_residual_norm);

#ifdef __cplusplus
}
#endif

#endif