pmeGridDimension;
159 |
160 | const System& system;
161 | };
162 |
163 |
164 | } // namespace OpenMM
165 |
166 | #endif /*MPID_OPENMM_REFERENCE_KERNELS_H*/
167 |
--------------------------------------------------------------------------------
/platforms/reference/src/SimTKReference/jama_cholesky.h:
--------------------------------------------------------------------------------
1 | #ifndef JAMA_CHOLESKY_H
2 | #define JAMA_CHOLESKY_H
3 |
4 | #include "math.h"
5 | /* needed for sqrt() below. */
6 |
7 |
8 | namespace JAMA
9 | {
10 |
11 | using namespace TNT;
12 |
13 | /**
14 |
15 | For a symmetric, positive definite matrix A, this function
16 | computes the Cholesky factorization, i.e. it computes a lower
17 | triangular matrix L such that A = L*L'.
18 | If the matrix is not symmetric or positive definite, the function
19 | computes only a partial decomposition. This can be tested with
20 | the is_spd() flag.
21 |
22 |
Typical usage looks like:
23 |
24 | Array2D A(n,n);
25 | Array2D L;
26 |
27 | ...
28 |
29 | Cholesky chol(A);
30 |
31 | if (chol.is_spd())
32 | L = chol.getL();
33 |
34 | else
35 | cout << "factorization was not complete.\n";
36 |
37 |
38 |
39 |
40 |
41 | (Adapted from JAMA, a Java Matrix Library, developed by jointly
42 | by the Mathworks and NIST; see http://math.nist.gov/javanumerics/jama).
43 |
44 | */
45 |
46 | template
47 | class Cholesky
48 | {
49 | Array2D L_; // lower triangular factor
50 | int isspd; // 1 if matrix to be factored was SPD
51 |
52 | public:
53 |
54 | Cholesky();
55 | Cholesky(const Array2D &A);
56 | Array2D getL() const;
57 | Array1D solve(const Array1D &B);
58 | Array2D solve(const Array2D &B);
59 | int is_spd() const;
60 |
61 | };
62 |
63 | template
64 | Cholesky::Cholesky() : L_(0,0), isspd(0) {}
65 |
66 | /**
67 | @return 1, if original matrix to be factored was symmetric
68 | positive-definite (SPD).
69 | */
70 | template
71 | int Cholesky::is_spd() const
72 | {
73 | return isspd;
74 | }
75 |
76 | /**
77 | @return the lower triangular factor, L, such that L*L'=A.
78 | */
79 | template
80 | Array2D Cholesky::getL() const
81 | {
82 | return L_;
83 | }
84 |
85 | /**
86 | Constructs a lower triangular matrix L, such that L*L'= A.
87 | If A is not symmetric positive-definite (SPD), only a
88 | partial factorization is performed. If is_spd()
89 | evalutate true (1) then the factorizaiton was successful.
90 | */
91 | template
92 | Cholesky::Cholesky(const Array2D &A)
93 | {
94 |
95 |
96 | int m = A.dim1();
97 | int n = A.dim2();
98 |
99 | isspd = (m == n);
100 |
101 | if (m != n)
102 | {
103 | L_ = Array2D(0,0);
104 | return;
105 | }
106 |
107 | L_ = Array2D(n,n);
108 |
109 |
110 | // Main loop.
111 | for (int j = 0; j < n; j++)
112 | {
113 | Real d(0.0);
114 | for (int k = 0; k < j; k++)
115 | {
116 | Real s(0.0);
117 | for (int i = 0; i < k; i++)
118 | {
119 | s += L_[k][i]*L_[j][i];
120 | }
121 | L_[j][k] = s = (A[j][k] - s)/L_[k][k];
122 | d = d + s*s;
123 | isspd = isspd && (A[k][j] == A[j][k]);
124 | }
125 | d = A[j][j] - d;
126 | isspd = isspd && (d > 0.0);
127 | L_[j][j] = sqrt(d > 0.0 ? d : 0.0);
128 | for (int k = j+1; k < n; k++)
129 | {
130 | L_[j][k] = 0.0;
131 | }
132 | }
133 | }
134 |
135 | /**
136 |
137 | Solve a linear system A*x = b, using the previously computed
138 | cholesky factorization of A: L*L'.
139 |
140 | @param B A Matrix with as many rows as A and any number of columns.
141 | @return x so that L*L'*x = b. If b is nonconformat, or if A
142 | was not symmetric posidtive definite, a null (0x0)
143 | array is returned.
144 | */
145 | template
146 | Array1D Cholesky::solve(const Array1D &b)
147 | {
148 | int n = L_.dim1();
149 | if (b.dim1() != n)
150 | return Array1D();
151 |
152 |
153 | Array1D x = b.copy();
154 |
155 |
156 | // Solve L*y = b;
157 | for (int k = 0; k < n; k++)
158 | {
159 | for (int i = 0; i < k; i++)
160 | x[k] -= x[i]*L_[k][i];
161 | x[k] /= L_[k][k];
162 |
163 | }
164 |
165 | // Solve L'*X = Y;
166 | for (int k = n-1; k >= 0; k--)
167 | {
168 | for (int i = k+1; i < n; i++)
169 | x[k] -= x[i]*L_[i][k];
170 | x[k] /= L_[k][k];
171 | }
172 |
173 | return x;
174 | }
175 |
176 |
177 | /**
178 |
179 | Solve a linear system A*X = B, using the previously computed
180 | cholesky factorization of A: L*L'.
181 |
182 | @param B A Matrix with as many rows as A and any number of columns.
183 | @return X so that L*L'*X = B. If B is nonconformat, or if A
184 | was not symmetric posidtive definite, a null (0x0)
185 | array is returned.
186 | */
187 | template
188 | Array2D Cholesky::solve(const Array2D &B)
189 | {
190 | int n = L_.dim1();
191 | if (B.dim1() != n)
192 | return Array2D();
193 |
194 |
195 | Array2D X = B.copy();
196 | int nx = B.dim2();
197 |
198 | // Cleve's original code
199 | #if 0
200 | // Solve L*Y = B;
201 | for (int k = 0; k < n; k++) {
202 | for (int i = k+1; i < n; i++) {
203 | for (int j = 0; j < nx; j++) {
204 | X[i][j] -= X[k][j]*L_[k][i];
205 | }
206 | }
207 | for (int j = 0; j < nx; j++) {
208 | X[k][j] /= L_[k][k];
209 | }
210 | }
211 |
212 | // Solve L'*X = Y;
213 | for (int k = n-1; k >= 0; k--) {
214 | for (int j = 0; j < nx; j++) {
215 | X[k][j] /= L_[k][k];
216 | }
217 | for (int i = 0; i < k; i++) {
218 | for (int j = 0; j < nx; j++) {
219 | X[i][j] -= X[k][j]*L_[k][i];
220 | }
221 | }
222 | }
223 | #endif
224 |
225 |
226 | // Solve L*y = b;
227 | for (int j=0; j< nx; j++)
228 | {
229 | for (int k = 0; k < n; k++)
230 | {
231 | for (int i = 0; i < k; i++)
232 | X[k][j] -= X[i][j]*L_[k][i];
233 | X[k][j] /= L_[k][k];
234 | }
235 | }
236 |
237 | // Solve L'*X = Y;
238 | for (int j=0; j= 0; k--)
241 | {
242 | for (int i = k+1; i < n; i++)
243 | X[k][j] -= X[i][j]*L_[i][k];
244 | X[k][j] /= L_[k][k];
245 | }
246 | }
247 |
248 |
249 |
250 | return X;
251 | }
252 |
253 |
254 | }
255 | // namespace JAMA
256 |
257 | #endif
258 | // JAMA_CHOLESKY_H
259 |
--------------------------------------------------------------------------------
/platforms/reference/src/SimTKReference/jama_lu.h:
--------------------------------------------------------------------------------
1 | #ifndef JAMA_LU_H
2 | #define JAMA_LU_H
3 |
4 | #include "tnt.h"
5 | #include
6 | //for min(), max() below
7 |
8 | using namespace TNT;
9 | using namespace std;
10 |
11 | namespace JAMA
12 | {
13 |
14 | /** LU Decomposition.
15 |
16 | For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
17 | unit lower triangular matrix L, an n-by-n upper triangular matrix U,
18 | and a permutation vector piv of length m so that A(piv,:) = L*U.
19 | If m < n, then L is m-by-m and U is m-by-n.
20 |
21 | The LU decompostion with pivoting always exists, even if the matrix is
22 | singular, so the constructor will never fail. The primary use of the
23 | LU decomposition is in the solution of square systems of simultaneous
24 | linear equations. This will fail if isNonsingular() returns false.
25 | */
26 | template
27 | class LU
28 | {
29 |
30 |
31 |
32 | /* Array for internal storage of decomposition. */
33 | Array2D LU_;
34 | int m, n, pivsign;
35 | Array1D piv;
36 |
37 |
38 | Array2D permute_copy(const Array2D &A,
39 | const Array1D &piv, int j0, int j1)
40 | {
41 | int piv_length = piv.dim();
42 |
43 | Array2D X(piv_length, j1-j0+1);
44 |
45 |
46 | for (int i = 0; i < piv_length; i++)
47 | for (int j = j0; j <= j1; j++)
48 | X[i][j-j0] = A[piv[i]][j];
49 |
50 | return X;
51 | }
52 |
53 | Array1D permute_copy(const Array1D &A,
54 | const Array1D &piv)
55 | {
56 | int piv_length = piv.dim();
57 | if (piv_length != A.dim())
58 | return Array1D();
59 |
60 | Array1D x(piv_length);
61 |
62 |
63 | for (int i = 0; i < piv_length; i++)
64 | x[i] = A[piv[i]];
65 |
66 | return x;
67 | }
68 |
69 |
70 | public :
71 |
72 | /** LU Decomposition
73 | @param A Rectangular matrix
74 | @return LU Decomposition object to access L, U and piv.
75 | */
76 |
77 | LU (const Array2D &A) : LU_(A.copy()), m(A.dim1()), n(A.dim2()),
78 | piv(A.dim1())
79 |
80 | {
81 |
82 | // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
83 |
84 |
85 | for (int i = 0; i < m; i++) {
86 | piv[i] = i;
87 | }
88 | pivsign = 1;
89 | Real *LUrowi = 0;;
90 | Array1D LUcolj(m);
91 |
92 | // Outer loop.
93 |
94 | for (int j = 0; j < n; j++) {
95 |
96 | // Make a copy of the j-th column to localize references.
97 |
98 | for (int i = 0; i < m; i++) {
99 | LUcolj[i] = LU_[i][j];
100 | }
101 |
102 | // Apply previous transformations.
103 |
104 | for (int i = 0; i < m; i++) {
105 | LUrowi = LU_[i];
106 |
107 | // Most of the time is spent in the following dot product.
108 |
109 | int kmax = min(i,j);
110 | double s = 0.0;
111 | for (int k = 0; k < kmax; k++) {
112 | s += LUrowi[k]*LUcolj[k];
113 | }
114 |
115 | LUrowi[j] = LUcolj[i] -= s;
116 | }
117 |
118 | // Find pivot and exchange if necessary.
119 |
120 | int p = j;
121 | for (int i = j+1; i < m; i++) {
122 | if (abs(LUcolj[i]) > abs(LUcolj[p])) {
123 | p = i;
124 | }
125 | }
126 | if (p != j) {
127 | int k=0;
128 | for (k = 0; k < n; k++) {
129 | double t = LU_[p][k];
130 | LU_[p][k] = LU_[j][k];
131 | LU_[j][k] = t;
132 | }
133 | k = piv[p];
134 | piv[p] = piv[j];
135 | piv[j] = k;
136 | pivsign = -pivsign;
137 | }
138 |
139 | // Compute multipliers.
140 |
141 | if ((j < m) && (LU_[j][j] != 0.0)) {
142 | for (int i = j+1; i < m; i++) {
143 | LU_[i][j] /= LU_[j][j];
144 | }
145 | }
146 | }
147 | }
148 |
149 |
150 | /** Is the matrix nonsingular?
151 | @return 1 (true) if upper triangular factor U (and hence A)
152 | is nonsingular, 0 otherwise.
153 | */
154 |
155 | int isNonsingular () {
156 | for (int j = 0; j < n; j++) {
157 | if (LU_[j][j] == 0)
158 | return 0;
159 | }
160 | return 1;
161 | }
162 |
163 | /** Return lower triangular factor
164 | @return L
165 | */
166 |
167 | Array2D getL () {
168 | Array2D L_(m,n);
169 | for (int i = 0; i < m; i++) {
170 | for (int j = 0; j < n; j++) {
171 | if (i > j) {
172 | L_[i][j] = LU_[i][j];
173 | } else if (i == j) {
174 | L_[i][j] = 1.0;
175 | } else {
176 | L_[i][j] = 0.0;
177 | }
178 | }
179 | }
180 | return L_;
181 | }
182 |
183 | /** Return upper triangular factor
184 | @return U portion of LU factorization.
185 | */
186 |
187 | Array2D getU () {
188 | Array2D U_(n,n);
189 | for (int i = 0; i < n; i++) {
190 | for (int j = 0; j < n; j++) {
191 | if (i <= j) {
192 | U_[i][j] = LU_[i][j];
193 | } else {
194 | U_[i][j] = 0.0;
195 | }
196 | }
197 | }
198 | return U_;
199 | }
200 |
201 | /** Return pivot permutation vector
202 | @return piv
203 | */
204 |
205 | Array1D getPivot () {
206 | return piv;
207 | }
208 |
209 |
210 | /** Compute determinant using LU factors.
211 | @return determinant of A, or 0 if A is not square.
212 | */
213 |
214 | Real det () {
215 | if (m != n) {
216 | return Real(0);
217 | }
218 | Real d = Real(pivsign);
219 | for (int j = 0; j < n; j++) {
220 | d *= LU_[j][j];
221 | }
222 | return d;
223 | }
224 |
225 | /** Solve A*X = B
226 | @param B A Matrix with as many rows as A and any number of columns.
227 | @return X so that L*U*X = B(piv,:), if B is nonconformant, returns
228 | 0x0 (null) array.
229 | */
230 |
231 | Array2D solve (const Array2D &B)
232 | {
233 |
234 | /* Dimensions: A is mxn, X is nxk, B is mxk */
235 |
236 | if (B.dim1() != m) {
237 | return Array2D(0,0);
238 | }
239 | if (!isNonsingular()) {
240 | return Array2D(0,0);
241 | }
242 |
243 | // Copy right hand side with pivoting
244 | int nx = B.dim2();
245 |
246 |
247 | Array2D X = permute_copy(B, piv, 0, nx-1);
248 |
249 | // Solve L*Y = B(piv,:)
250 | for (int k = 0; k < n; k++) {
251 | for (int i = k+1; i < n; i++) {
252 | for (int j = 0; j < nx; j++) {
253 | X[i][j] -= X[k][j]*LU_[i][k];
254 | }
255 | }
256 | }
257 | // Solve U*X = Y;
258 | for (int k = n-1; k >= 0; k--) {
259 | for (int j = 0; j < nx; j++) {
260 | X[k][j] /= LU_[k][k];
261 | }
262 | for (int i = 0; i < k; i++) {
263 | for (int j = 0; j < nx; j++) {
264 | X[i][j] -= X[k][j]*LU_[i][k];
265 | }
266 | }
267 | }
268 | return X;
269 | }
270 |
271 |
272 | /** Solve A*x = b, where x and b are vectors of length equal
273 | to the number of rows in A.
274 |
275 | @param b a vector (Array1D> of length equal to the first dimension
276 | of A.
277 | @return x a vector (Array1D> so that L*U*x = b(piv), if B is nonconformant,
278 | returns 0x0 (null) array.
279 | */
280 |
281 | Array1D solve (const Array1D &b)
282 | {
283 |
284 | /* Dimensions: A is mxn, X is nxk, B is mxk */
285 |
286 | if (b.dim1() != m) {
287 | return Array1D();
288 | }
289 | if (!isNonsingular()) {
290 | return Array1D();
291 | }
292 |
293 |
294 | Array1D x = permute_copy(b, piv);
295 |
296 | // Solve L*Y = B(piv)
297 | for (int k = 0; k < n; k++) {
298 | for (int i = k+1; i < n; i++) {
299 | x[i] -= x[k]*LU_[i][k];
300 | }
301 | }
302 |
303 | // Solve U*X = Y;
304 | for (int k = n-1; k >= 0; k--) {
305 | x[k] /= LU_[k][k];
306 | for (int i = 0; i < k; i++)
307 | x[i] -= x[k]*LU_[i][k];
308 | }
309 |
310 |
311 | return x;
312 | }
313 |
314 | }; /* class LU */
315 |
316 | } /* namespace JAMA */
317 |
318 | #endif
319 | /* JAMA_LU_H */
320 |
--------------------------------------------------------------------------------
/platforms/reference/src/SimTKReference/tnt.h:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Template Numerical Toolkit (TNT): Linear Algebra Module
4 | *
5 | * Mathematical and Computational Sciences Division
6 | * National Institute of Technology,
7 | * Gaithersburg, MD USA
8 | *
9 | *
10 | * This software was developed at the National Institute of Standards and
11 | * Technology (NIST) by employees of the Federal Government in the course
12 | * of their official duties. Pursuant to title 17 Section 105 of the
13 | * United States Code, this software is not subject to copyright protection
14 | * and is in the public domain. NIST assumes no responsibility whatsoever for
15 | * its use by other parties, and makes no guarantees, expressed or implied,
16 | * about its quality, reliability, or any other characteristic.
17 | *
18 | */
19 |
20 |
21 | #ifndef TNT_H
22 | #define TNT_H
23 |
24 |
25 |
26 | //---------------------------------------------------------------------
27 | // Define this macro if you want TNT to track some of the out-of-bounds
28 | // indexing. This can encur a small run-time overhead, but is recommended
29 | // while developing code. It can be turned off for production runs.
30 | //
31 | // #define TNT_BOUNDS_CHECK
32 | //---------------------------------------------------------------------
33 | //
34 |
35 | //#define TNT_BOUNDS_CHECK
36 |
37 |
38 |
39 | #include "tnt_version.h"
40 | #include "tnt_math_utils.h"
41 | #include "tnt_array1d.h"
42 | #include "tnt_array2d.h"
43 | #include "tnt_array3d.h"
44 | #include "tnt_array1d_utils.h"
45 | #include "tnt_array2d_utils.h"
46 | #include "tnt_array3d_utils.h"
47 |
48 | #include "tnt_fortran_array1d.h"
49 | #include "tnt_fortran_array2d.h"
50 | #include "tnt_fortran_array3d.h"
51 | #include "tnt_fortran_array1d_utils.h"
52 | #include "tnt_fortran_array2d_utils.h"
53 | #include "tnt_fortran_array3d_utils.h"
54 |
55 | #include "tnt_sparse_matrix_csr.h"
56 |
57 | #include "tnt_stopwatch.h"
58 | #include "tnt_subscript.h"
59 | #include "tnt_vec.h"
60 | #include "tnt_cmat.h"
61 |
62 |
63 | #endif
64 | // TNT_H
65 |
--------------------------------------------------------------------------------
/platforms/reference/src/SimTKReference/tnt_array1d.h:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Template Numerical Toolkit (TNT)
4 | *
5 | * Mathematical and Computational Sciences Division
6 | * National Institute of Technology,
7 | * Gaithersburg, MD USA
8 | *
9 | *
10 | * This software was developed at the National Institute of Standards and
11 | * Technology (NIST) by employees of the Federal Government in the course
12 | * of their official duties. Pursuant to title 17 Section 105 of the
13 | * United States Code, this software is not subject to copyright protection
14 | * and is in the public domain. NIST assumes no responsibility whatsoever for
15 | * its use by other parties, and makes no guarantees, expressed or implied,
16 | * about its quality, reliability, or any other characteristic.
17 | *
18 | */
19 |
20 |
21 |
22 | #ifndef TNT_ARRAY1D_H
23 | #define TNT_ARRAY1D_H
24 |
25 | //#include
26 | #include
27 |
28 | #ifdef TNT_BOUNDS_CHECK
29 | #include
30 | #endif
31 |
32 |
33 | #include "tnt_i_refvec.h"
34 |
35 | namespace TNT
36 | {
37 |
38 | template
39 | class Array1D
40 | {
41 |
42 | private:
43 |
44 | /* ... */
45 | i_refvec v_;
46 | int n_;
47 | T* data_; /* this normally points to v_.begin(), but
48 | * could also point to a portion (subvector)
49 | * of v_.
50 | */
51 |
52 | void copy_(T* p, const T* q, int len) const;
53 | void set_(T* begin, T* end, const T& val);
54 |
55 |
56 | public:
57 |
58 | typedef T value_type;
59 |
60 |
61 | Array1D();
62 | explicit Array1D(int n);
63 | Array1D(int n, const T &a);
64 | Array1D(int n, T *a);
65 | inline Array1D(const Array1D &A);
66 | inline operator T*();
67 | inline operator const T*();
68 | inline Array1D & operator=(const T &a);
69 | inline Array1D & operator=(const Array1D &A);
70 | inline Array1D & ref(const Array1D &A);
71 | Array1D copy() const;
72 | Array1D & inject(const Array1D & A);
73 | inline T& operator[](int i);
74 | inline const T& operator[](int i) const;
75 | inline int dim1() const;
76 | inline int dim() const;
77 | ~Array1D();
78 |
79 |
80 | /* ... extended interface ... */
81 |
82 | inline int ref_count() const;
83 | inline Array1D subarray(int i0, int i1);
84 |
85 | };
86 |
87 |
88 |
89 |
90 | template
91 | Array1D::Array1D() : v_(), n_(0), data_(0) {}
92 |
93 | template
94 | Array1D::Array1D(const Array1D &A) : v_(A.v_), n_(A.n_),
95 | data_(A.data_)
96 | {
97 | #ifdef TNT_DEBUG
98 | std::cout << "Created Array1D(const Array1D &A) \n";
99 | #endif
100 |
101 | }
102 |
103 |
104 | template
105 | Array1D::Array1D(int n) : v_(n), n_(n), data_(v_.begin())
106 | {
107 | #ifdef TNT_DEBUG
108 | std::cout << "Created Array1D(int n) \n";
109 | #endif
110 | }
111 |
112 | template
113 | Array1D::Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin())
114 | {
115 | #ifdef TNT_DEBUG
116 | std::cout << "Created Array1D(int n, const T& val) \n";
117 | #endif
118 | set_(data_, data_+ n, val);
119 |
120 | }
121 |
122 | template
123 | Array1D::Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin())
124 | {
125 | #ifdef TNT_DEBUG
126 | std::cout << "Created Array1D(int n, T* a) \n";
127 | #endif
128 | }
129 |
130 | template
131 | inline Array1D::operator T*()
132 | {
133 | return &(v_[0]);
134 | }
135 |
136 |
137 | template
138 | inline Array1D::operator const T*()
139 | {
140 | return &(v_[0]);
141 | }
142 |
143 |
144 |
145 | template
146 | inline T& Array1D::operator[](int i)
147 | {
148 | #ifdef TNT_BOUNDS_CHECK
149 | assert(i>= 0);
150 | assert(i < n_);
151 | #endif
152 | return data_[i];
153 | }
154 |
155 | template
156 | inline const T& Array1D::operator[](int i) const
157 | {
158 | #ifdef TNT_BOUNDS_CHECK
159 | assert(i>= 0);
160 | assert(i < n_);
161 | #endif
162 | return data_[i];
163 | }
164 |
165 |
166 |
167 |
168 | template
169 | Array1D & Array1D::operator=(const T &a)
170 | {
171 | set_(data_, data_+n_, a);
172 | return *this;
173 | }
174 |
175 | template
176 | Array1D Array1D::copy() const
177 | {
178 | Array1D A( n_);
179 | copy_(A.data_, data_, n_);
180 |
181 | return A;
182 | }
183 |
184 |
185 | template
186 | Array1D & Array1D::inject(const Array1D &A)
187 | {
188 | if (A.n_ == n_)
189 | copy_(data_, A.data_, n_);
190 |
191 | return *this;
192 | }
193 |
194 |
195 |
196 |
197 |
198 | template
199 | Array1D & Array1D::ref(const Array1D &A)
200 | {
201 | if (this != &A)
202 | {
203 | v_ = A.v_; /* operator= handles the reference counting. */
204 | n_ = A.n_;
205 | data_ = A.data_;
206 |
207 | }
208 | return *this;
209 | }
210 |
211 | template
212 | Array1D & Array1D::operator=(const Array1D &A)
213 | {
214 | return ref(A);
215 | }
216 |
217 | template
218 | inline int Array1D::dim1() const { return n_; }
219 |
220 | template
221 | inline int Array1D::dim() const { return n_; }
222 |
223 | template
224 | Array1D::~Array1D() {}
225 |
226 |
227 | /* ............................ exented interface ......................*/
228 |
229 | template
230 | inline int Array1D::ref_count() const
231 | {
232 | return v_.ref_count();
233 | }
234 |
235 | template
236 | inline Array1D Array1D::subarray(int i0, int i1)
237 | {
238 | if ((i0 > 0) && (i1 < n_) || (i0 <= i1))
239 | {
240 | Array1D X(*this); /* create a new instance of this array. */
241 | X.n_ = i1-i0+1;
242 | X.data_ += i0;
243 |
244 | return X;
245 | }
246 | else
247 | {
248 | return Array1D();
249 | }
250 | }
251 |
252 |
253 | /* private internal functions */
254 |
255 |
256 | template
257 | void Array1D::set_(T* begin, T* end, const T& a)
258 | {
259 | for (T* p=begin; p
265 | void Array1D::copy_(T* p, const T* q, int len) const
266 | {
267 | T *end = p + len;
268 | while (p
24 | #include
25 |
26 | namespace TNT
27 | {
28 |
29 |
30 | template
31 | std::ostream& operator<<(std::ostream &s, const Array1D &A)
32 | {
33 | int N=A.dim1();
34 |
35 | #ifdef TNT_DEBUG
36 | s << "addr: " << (void *) &A[0] << "\n";
37 | #endif
38 | s << N << "\n";
39 | for (int j=0; j
49 | std::istream& operator>>(std::istream &s, Array1D &A)
50 | {
51 | int N;
52 | s >> N;
53 |
54 | Array1D B(N);
55 | for (int i=0; i> B[i];
57 | A = B;
58 | return s;
59 | }
60 |
61 |
62 |
63 | template
64 | Array1D operator+(const Array1D &A, const Array1D &B)
65 | {
66 | int n = A.dim1();
67 |
68 | if (B.dim1() != n )
69 | return Array1D();
70 |
71 | else
72 | {
73 | Array1D C(n);
74 |
75 | for (int i=0; i
86 | Array1D operator-(const Array1D &A, const Array1D &B)
87 | {
88 | int n = A.dim1();
89 |
90 | if (B.dim1() != n )
91 | return Array1D();
92 |
93 | else
94 | {
95 | Array1D C(n);
96 |
97 | for (int i=0; i
107 | Array1D operator*(const Array1D &A, const Array1D &B)
108 | {
109 | int n = A.dim1();
110 |
111 | if (B.dim1() != n )
112 | return Array1D();
113 |
114 | else
115 | {
116 | Array1D C(n);
117 |
118 | for (int i=0; i
128 | Array1D operator/(const Array1D &A, const Array1D &B)
129 | {
130 | int n = A.dim1();
131 |
132 | if (B.dim1() != n )
133 | return Array1D();
134 |
135 | else
136 | {
137 | Array1D C(n);
138 |
139 | for (int i=0; i
156 | Array1D& operator+=(Array1D &A, const Array1D &B)
157 | {
158 | int n = A.dim1();
159 |
160 | if (B.dim1() == n)
161 | {
162 | for (int i=0; i
174 | Array1D& operator-=(Array1D &A, const Array1D &B)
175 | {
176 | int n = A.dim1();
177 |
178 | if (B.dim1() == n)
179 | {
180 | for (int i=0; i
191 | Array1D& operator*=(Array1D &A, const Array1D &B)
192 | {
193 | int n = A.dim1();
194 |
195 | if (B.dim1() == n)
196 | {
197 | for (int i=0; i
209 | Array1D& operator/=(Array1D &A, const Array1D &B)
210 | {
211 | int n = A.dim1();
212 |
213 | if (B.dim1() == n)
214 | {
215 | for (int i=0; i
26 | #include
27 | #ifdef TNT_BOUNDS_CHECK
28 | #include
29 | #endif
30 |
31 | #include "tnt_array1d.h"
32 |
33 | namespace TNT
34 | {
35 |
36 | template
37 | class Array2D
38 | {
39 |
40 |
41 | private:
42 |
43 |
44 |
45 | Array1D data_;
46 | Array1D v_;
47 | int m_;
48 | int n_;
49 |
50 | public:
51 |
52 | typedef T value_type;
53 | Array2D();
54 | Array2D(int m, int n);
55 | Array2D(int m, int n, T *a);
56 | Array2D(int m, int n, const T &a);
57 | inline Array2D(const Array2D &A);
58 | inline operator T**();
59 | inline operator const T**();
60 | inline Array2D & operator=(const T &a);
61 | inline Array2D & operator=(const Array2D &A);
62 | inline Array2D & ref(const Array2D &A);
63 | Array2D copy() const;
64 | Array2D & inject(const Array2D & A);
65 | inline T* operator[](int i);
66 | inline const T* operator[](int i) const;
67 | inline int dim1() const;
68 | inline int dim2() const;
69 | ~Array2D();
70 |
71 | /* extended interface (not part of the standard) */
72 |
73 |
74 | inline int ref_count();
75 | inline int ref_count_data();
76 | inline int ref_count_dim1();
77 | Array2D subarray(int i0, int i1, int j0, int j1);
78 |
79 | };
80 |
81 |
82 | template
83 | Array2D::Array2D() : data_(), v_(), m_(0), n_(0) {}
84 |
85 | template
86 | Array2D::Array2D(const Array2D &A) : data_(A.data_), v_(A.v_),
87 | m_(A.m_), n_(A.n_) {}
88 |
89 |
90 |
91 |
92 | template
93 | Array2D::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n)
94 | {
95 | if (m>0 && n>0)
96 | {
97 | T* p = &(data_[0]);
98 | for (int i=0; i
109 | Array2D::Array2D(int m, int n, const T &val) : data_(m*n), v_(m),
110 | m_(m), n_(n)
111 | {
112 | if (m>0 && n>0)
113 | {
114 | data_ = val;
115 | T* p = &(data_[0]);
116 | for (int i=0; i
125 | Array2D::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n)
126 | {
127 | if (m>0 && n>0)
128 | {
129 | T* p = &(data_[0]);
130 |
131 | for (int i=0; i
141 | inline T* Array2D::operator[](int i)
142 | {
143 | #ifdef TNT_BOUNDS_CHECK
144 | assert(i >= 0);
145 | assert(i < m_);
146 | #endif
147 |
148 | return v_[i];
149 |
150 | }
151 |
152 |
153 | template
154 | inline const T* Array2D::operator[](int i) const
155 | {
156 | #ifdef TNT_BOUNDS_CHECK
157 | assert(i >= 0);
158 | assert(i < m_);
159 | #endif
160 |
161 | return v_[i];
162 |
163 | }
164 |
165 | template
166 | Array2D & Array2D::operator=(const T &a)
167 | {
168 | /* non-optimzied, but will work with subarrays in future verions */
169 |
170 | for (int i=0; i
180 | Array2D Array2D::copy() const
181 | {
182 | Array2D A(m_, n_);
183 |
184 | for (int i=0; i
194 | Array2D & Array2D::inject(const Array2D &A)
195 | {
196 | if (A.m_ == m_ && A.n_ == n_)
197 | {
198 | for (int i=0; i
209 | Array2D & Array2D::ref(const Array2D &A)
210 | {
211 | if (this != &A)
212 | {
213 | v_ = A.v_;
214 | data_ = A.data_;
215 | m_ = A.m_;
216 | n_ = A.n_;
217 |
218 | }
219 | return *this;
220 | }
221 |
222 |
223 |
224 | template
225 | Array2D & Array2D::operator=(const Array2D &A)
226 | {
227 | return ref(A);
228 | }
229 |
230 | template
231 | inline int Array2D::dim1() const { return m_; }
232 |
233 | template
234 | inline int Array2D::dim2() const { return n_; }
235 |
236 |
237 | template
238 | Array2D::~Array2D() {}
239 |
240 |
241 |
242 |
243 | template
244 | inline Array2D