doxygen: intern/smoke tagged.
[blender.git] / intern / smoke / intern / tnt / tnt_array2d_utils.h
1 /** \file smoke/intern/tnt/tnt_array2d_utils.h
2  *  \ingroup smoke
3  */
4 /*
5 *
6 * Template Numerical Toolkit (TNT)
7 *
8 * Mathematical and Computational Sciences Division
9 * National Institute of Technology,
10 * Gaithersburg, MD USA
11 *
12 *
13 * This software was developed at the National Institute of Standards and
14 * Technology (NIST) by employees of the Federal Government in the course
15 * of their official duties. Pursuant to title 17 Section 105 of the
16 * United States Code, this software is not subject to copyright protection
17 * and is in the public domain. NIST assumes no responsibility whatsoever for
18 * its use by other parties, and makes no guarantees, expressed or implied,
19 * about its quality, reliability, or any other characteristic.
20 *
21 */
22
23
24 #ifndef TNT_ARRAY2D_UTILS_H
25 #define TNT_ARRAY2D_UTILS_H
26
27 #include <cstdlib>
28 #include <cassert>
29
30 namespace TNT
31 {
32
33
34 template <class T>
35 std::ostream& operator<<(std::ostream &s, const Array2D<T> &A)
36 {
37     int M=A.dim1();
38     int N=A.dim2();
39
40     s << M << " " << N << "\n";
41
42     for (int i=0; i<M; i++)
43     {
44         for (int j=0; j<N; j++)
45         {
46             s << A[i][j] << " ";
47         }
48         s << "\n";
49     }
50
51
52     return s;
53 }
54
55 template <class T>
56 std::istream& operator>>(std::istream &s, Array2D<T> &A)
57 {
58
59     int M, N;
60
61     s >> M >> N;
62
63         Array2D<T> B(M,N);
64
65     for (int i=0; i<M; i++)
66         for (int j=0; j<N; j++)
67         {
68             s >>  B[i][j];
69         }
70
71         A = B;
72     return s;
73 }
74
75
76 template <class T>
77 Array2D<T> operator+(const Array2D<T> &A, const Array2D<T> &B)
78 {
79         int m = A.dim1();
80         int n = A.dim2();
81
82         if (B.dim1() != m ||  B.dim2() != n )
83                 return Array2D<T>();
84
85         else
86         {
87                 Array2D<T> C(m,n);
88
89                 for (int i=0; i<m; i++)
90                 {
91                         for (int j=0; j<n; j++)
92                                 C[i][j] = A[i][j] + B[i][j];
93                 }
94                 return C;
95         }
96 }
97
98 template <class T>
99 Array2D<T> operator-(const Array2D<T> &A, const Array2D<T> &B)
100 {
101         int m = A.dim1();
102         int n = A.dim2();
103
104         if (B.dim1() != m ||  B.dim2() != n )
105                 return Array2D<T>();
106
107         else
108         {
109                 Array2D<T> C(m,n);
110
111                 for (int i=0; i<m; i++)
112                 {
113                         for (int j=0; j<n; j++)
114                                 C[i][j] = A[i][j] - B[i][j];
115                 }
116                 return C;
117         }
118 }
119
120
121 template <class T>
122 Array2D<T> operator*(const Array2D<T> &A, const Array2D<T> &B)
123 {
124         int m = A.dim1();
125         int n = A.dim2();
126
127         if (B.dim1() != m ||  B.dim2() != n )
128                 return Array2D<T>();
129
130         else
131         {
132                 Array2D<T> C(m,n);
133
134                 for (int i=0; i<m; i++)
135                 {
136                         for (int j=0; j<n; j++)
137                                 C[i][j] = A[i][j] * B[i][j];
138                 }
139                 return C;
140         }
141 }
142
143
144
145
146 template <class T>
147 Array2D<T> operator/(const Array2D<T> &A, const Array2D<T> &B)
148 {
149         int m = A.dim1();
150         int n = A.dim2();
151
152         if (B.dim1() != m ||  B.dim2() != n )
153                 return Array2D<T>();
154
155         else
156         {
157                 Array2D<T> C(m,n);
158
159                 for (int i=0; i<m; i++)
160                 {
161                         for (int j=0; j<n; j++)
162                                 C[i][j] = A[i][j] / B[i][j];
163                 }
164                 return C;
165         }
166 }
167
168
169
170
171
172 template <class T>
173 Array2D<T>&  operator+=(Array2D<T> &A, const Array2D<T> &B)
174 {
175         int m = A.dim1();
176         int n = A.dim2();
177
178         if (B.dim1() == m ||  B.dim2() == n )
179         {
180                 for (int i=0; i<m; i++)
181                 {
182                         for (int j=0; j<n; j++)
183                                 A[i][j] += B[i][j];
184                 }
185         }
186         return A;
187 }
188
189
190
191 template <class T>
192 Array2D<T>&  operator-=(Array2D<T> &A, const Array2D<T> &B)
193 {
194         int m = A.dim1();
195         int n = A.dim2();
196
197         if (B.dim1() == m ||  B.dim2() == n )
198         {
199                 for (int i=0; i<m; i++)
200                 {
201                         for (int j=0; j<n; j++)
202                                 A[i][j] -= B[i][j];
203                 }
204         }
205         return A;
206 }
207
208
209
210 template <class T>
211 Array2D<T>&  operator*=(Array2D<T> &A, const Array2D<T> &B)
212 {
213         int m = A.dim1();
214         int n = A.dim2();
215
216         if (B.dim1() == m ||  B.dim2() == n )
217         {
218                 for (int i=0; i<m; i++)
219                 {
220                         for (int j=0; j<n; j++)
221                                 A[i][j] *= B[i][j];
222                 }
223         }
224         return A;
225 }
226
227
228
229
230
231 template <class T>
232 Array2D<T>&  operator/=(Array2D<T> &A, const Array2D<T> &B)
233 {
234         int m = A.dim1();
235         int n = A.dim2();
236
237         if (B.dim1() == m ||  B.dim2() == n )
238         {
239                 for (int i=0; i<m; i++)
240                 {
241                         for (int j=0; j<n; j++)
242                                 A[i][j] /= B[i][j];
243                 }
244         }
245         return A;
246 }
247
248 /**
249     Matrix Multiply:  compute C = A*B, where C[i][j]
250     is the dot-product of row i of A and column j of B.
251
252
253     @param A an (m x n) array
254     @param B an (n x k) array
255     @return the (m x k) array A*B, or a null array (0x0)
256         if the matrices are non-conformant (i.e. the number
257         of columns of A are different than the number of rows of B.)
258
259
260 */
261 template <class T>
262 Array2D<T> matmult(const Array2D<T> &A, const Array2D<T> &B)
263 {
264     if (A.dim2() != B.dim1())
265         return Array2D<T>();
266
267     int M = A.dim1();
268     int N = A.dim2();
269     int K = B.dim2();
270
271     Array2D<T> C(M,K);
272
273     for (int i=0; i<M; i++)
274         for (int j=0; j<K; j++)
275         {
276             T sum = 0;
277
278             for (int k=0; k<N; k++)
279                 sum += A[i][k] * B [k][j];
280
281             C[i][j] = sum;
282         }
283
284     return C;
285
286 }
287
288 } // namespace TNT
289
290 #endif