fixed spacing in the headers to get rid of some warnings and some other
[blender.git] / intern / iksolver / intern / TNT / region2d.h
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31
32 /*
33
34 *
35 * Template Numerical Toolkit (TNT): Linear Algebra Module
36 *
37 * Mathematical and Computational Sciences Division
38 * National Institute of Technology,
39 * Gaithersburg, MD USA
40 *
41 *
42 * This software was developed at the National Institute of Standards and
43 * Technology (NIST) by employees of the Federal Government in the course
44 * of their official duties. Pursuant to title 17 Section 105 of the
45 * United States Code, this software is not subject to copyright protection
46 * and is in the public domain.  The Template Numerical Toolkit (TNT) is
47 * an experimental system.  NIST assumes no responsibility whatsoever for
48 * its use by other parties, and makes no guarantees, expressed or implied,
49 * about its quality, reliability, or any other characteristic.
50 *
51 * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
52 * see http://math.nist.gov/tnt for latest updates.
53 *
54 */
55
56
57 // 2D Regions for arrays and matrices
58
59 #ifndef REGION2D_H
60 #define REGION2D_H
61
62 #include "index.h"
63 #include <iostream>
64 #include <cassert>
65
66 namespace TNT
67 {
68
69 template <class Array2D>
70 class const_Region2D;
71
72
73 template <class Array2D>
74 class Region2D
75 {
76     protected:
77
78         Array2D &  A_;
79         Subscript offset_[2];       // 0-offset internally
80         Subscript dim_[2];
81
82     public:
83         typedef typename Array2D::value_type T;
84         typedef Subscript   size_type;
85         typedef         T   value_type;
86         typedef         T   element_type;
87         typedef         T*  pointer;
88         typedef         T*  iterator;
89         typedef         T&  reference;
90         typedef const   T*  const_iterator;
91         typedef const   T&  const_reference;
92
93         Array2D & array() { return A_; }
94         const Array2D & array()  const { return A_; }
95         Subscript lbound() const { return A_.lbound(); }
96         Subscript num_rows() const { return dim_[0]; }
97         Subscript num_cols() const { return dim_[1]; }
98         Subscript offset(Subscript i) const                 // 1-offset
99         {
100 #ifdef TNT_BOUNDS_CHECK
101             assert( A_.lbound() <= i);
102             assert( i<= dim_[0] + A_.lbound()-1);
103 #endif
104             return offset_[i-A_.lbound()];
105         }
106
107         Subscript dim(Subscript i) const
108         {
109 #ifdef TNT_BOUNDS_CHECK
110             assert( A_.lbound() <= i);
111             assert( i<= dim_[0] + A_.lbound()-1);
112 #endif
113             return dim_[i-A_.lbound()];
114         }
115
116
117
118         Region2D(Array2D &A, Subscript i1, Subscript i2, Subscript j1,
119                 Subscript j2) : A_(A)
120         {
121 #ifdef TNT_BOUNDS_CHECK
122             assert( i1 <= i2 );
123             assert( j1 <= j2);
124             assert( A.lbound() <= i1);
125             assert( i2<= A.dim(A.lbound()) + A.lbound()-1);
126             assert( A.lbound() <= j1);
127             assert( j2<= A.dim(A.lbound()+1) + A.lbound()-1 );
128 #endif
129
130
131             offset_[0] = i1-A.lbound();
132             offset_[1] = j1-A.lbound();
133             dim_[0] = i2-i1+1;
134             dim_[1] = j2-j1+1;
135         }
136
137         Region2D(Array2D &A, const Index1D &I, const Index1D &J) : A_(A)
138         {
139 #ifdef TNT_BOUNDS_CHECK
140             assert( I.lbound() <= I.ubound() );
141             assert( J.lbound() <= J.ubound() );
142             assert( A.lbound() <= I.lbound());
143             assert( I.ubound()<= A.dim(A.lbound()) + A.lbound()-1);
144             assert( A.lbound() <= J.lbound());
145             assert( J.ubound() <= A.dim(A.lbound()+1) + A.lbound()-1 );
146 #endif
147
148             offset_[0] = I.lbound()-A.lbound();
149             offset_[1] = J.lbound()-A.lbound();
150             dim_[0] = I.ubound() - I.lbound() + 1;
151             dim_[1] = J.ubound() - J.lbound() + 1;
152         }
153
154         Region2D(Region2D<Array2D> &A, Subscript i1, Subscript i2,
155             Subscript j1, Subscript j2) : A_(A.A_)
156         {
157 #ifdef TNT_BOUNDS_CHECK
158             assert( i1 <= i2 );
159             assert( j1 <= j2);
160             assert( A.lbound() <= i1);
161             assert( i2<= A.dim(A.lbound()) + A.lbound()-1);
162             assert( A.lbound() <= j1);
163             assert( j2<= A.dim(A.lbound()+1) + A.lbound()-1 );
164 #endif
165             offset_[0] = (i1 - A.lbound()) + A.offset_[0];
166             offset_[1] = (j1 - A.lbound()) + A.offset_[1];
167             dim_[0] = i2-i1 + 1;
168             dim_[1] = j2-j1+1;
169         }
170
171         Region2D<Array2D> operator()(Subscript i1, Subscript i2,
172                 Subscript j1, Subscript j2)
173         {
174 #ifdef TNT_BOUNDS_CHECK
175             assert( i1 <= i2 );
176             assert( j1 <= j2);
177             assert( A_.lbound() <= i1);
178             assert( i2<= dim_[0] + A_.lbound()-1);
179             assert( A_.lbound() <= j1);
180             assert( j2<= dim_[1] + A_.lbound()-1 );
181 #endif
182             return Region2D<Array2D>(A_, 
183                     i1+offset_[0], offset_[0] + i2, 
184                     j1+offset_[1], offset_[1] + j2);
185         }
186
187
188         Region2D<Array2D> operator()(const Index1D &I,
189                 const Index1D &J)
190         {
191 #ifdef TNT_BOUNDS_CHECK
192             assert( I.lbound() <= I.ubound() );
193             assert( J.lbound() <= J.ubound() );
194             assert( A_.lbound() <= I.lbound());
195             assert( I.ubound()<= dim_[0] + A_.lbound()-1);
196             assert( A_.lbound() <= J.lbound());
197             assert( J.ubound() <= dim_[1] + A_.lbound()-1 );
198 #endif
199
200             return Region2D<Array2D>(A_, I.lbound()+offset_[0],
201                 offset_[0] + I.ubound(), offset_[1]+J.lbound(),
202                 offset_[1] + J.ubound());
203         }
204
205         inline T & operator()(Subscript i, Subscript j)
206         {
207 #ifdef TNT_BOUNDS_CHECK
208             assert( A_.lbound() <= i);
209             assert( i<= dim_[0] + A_.lbound()-1);
210             assert( A_.lbound() <= j);
211             assert( j<= dim_[1] + A_.lbound()-1 );
212 #endif
213             return A_(i+offset_[0], j+offset_[1]);
214         }
215
216         inline const T & operator() (Subscript i, Subscript j) const
217         {
218 #ifdef TNT_BOUNDS_CHECK
219             assert( A_.lbound() <= i);
220             assert( i<= dim_[0] + A_.lbound()-1);
221             assert( A_.lbound() <= j);
222             assert( j<= dim_[1] + A_.lbound()-1 );
223 #endif
224             return A_(i+offset_[0], j+offset_[1]);
225         }
226
227
228         Region2D<Array2D> & operator=(const Region2D<Array2D> &R)
229         {
230             Subscript M = num_rows(); 
231             Subscript N = num_cols();
232
233             // make sure both sides conform
234             assert(M == R.num_rows());
235             assert(N == R.num_cols());
236
237
238             Subscript start = R.lbound();
239             Subscript Mend =  start + M - 1;
240             Subscript Nend =  start + N - 1;
241             for (Subscript i=start; i<=Mend; i++)
242               for (Subscript j=start; j<=Nend; j++)
243                 (*this)(i,j) = R(i,j);
244
245             return *this;
246         }
247
248         Region2D<Array2D> & operator=(const const_Region2D<Array2D> &R)
249         {
250             Subscript M = num_rows(); 
251             Subscript N = num_cols();
252
253             // make sure both sides conform
254             assert(M == R.num_rows());
255             assert(N == R.num_cols());
256
257
258             Subscript start = R.lbound();
259             Subscript Mend =  start + M - 1;
260             Subscript Nend =  start + N - 1;
261             for (Subscript i=start; i<=Mend; i++)
262               for (Subscript j=start; j<=Nend; j++)
263                 (*this)(i,j) = R(i,j);
264
265             return *this;
266         }
267
268         Region2D<Array2D> & operator=(const Array2D &R)
269         {
270             Subscript M = num_rows(); 
271             Subscript N = num_cols();
272
273             // make sure both sides conform
274             assert(M == R.num_rows());
275             assert(N == R.num_cols());
276
277
278             Subscript start = R.lbound();
279             Subscript Mend =  start + M - 1;
280             Subscript Nend =  start + N - 1;
281             for (Subscript i=start; i<=Mend; i++)
282               for (Subscript j=start; j<=Nend; j++)
283                 (*this)(i,j) = R(i,j);
284
285             return *this;
286         }
287
288         Region2D<Array2D> & operator=(const  T &scalar)
289         {
290             Subscript start = lbound();
291             Subscript Mend = lbound() + num_rows() - 1;
292             Subscript Nend = lbound() + num_cols() - 1;
293
294
295             for (Subscript i=start; i<=Mend; i++)
296               for (Subscript j=start; j<=Nend; j++)
297                 (*this)(i,j) = scalar;
298
299             return *this;
300         }
301
302 };
303
304 //************************
305
306 template <class Array2D>
307 class const_Region2D
308 {
309     protected:
310
311         const Array2D &  A_;
312         Subscript offset_[2];       // 0-offset internally
313         Subscript dim_[2];
314
315     public:
316     typedef typename Array2D::value_type T;
317         typedef         T   value_type;
318         typedef         T   element_type;
319         typedef const   T*  const_iterator;
320         typedef const   T&  const_reference;
321
322         const Array2D & array() const { return A_; }
323         Subscript lbound() const { return A_.lbound(); }
324         Subscript num_rows() const { return dim_[0]; }
325         Subscript num_cols() const { return dim_[1]; }
326         Subscript offset(Subscript i) const                 // 1-offset
327         {
328 #ifdef TNT_BOUNDS_CHECK
329             assert( TNT_BASE_OFFSET <= i);
330             assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
331 #endif
332             return offset_[i-TNT_BASE_OFFSET];
333         }
334
335         Subscript dim(Subscript i) const
336         {
337 #ifdef TNT_BOUNDS_CHECK
338             assert( TNT_BASE_OFFSET <= i);
339             assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
340 #endif
341             return dim_[i-TNT_BASE_OFFSET];
342         }
343
344
345         const_Region2D(const Array2D &A, Subscript i1, Subscript i2, 
346                 Subscript j1, Subscript j2) : A_(A)
347         {
348 #ifdef TNT_BOUNDS_CHECK
349             assert( i1 <= i2 );
350             assert( j1 <= j2);
351             assert( TNT_BASE_OFFSET <= i1);
352             assert( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
353             assert( TNT_BASE_OFFSET <= j1);
354             assert( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
355 #endif
356
357             offset_[0] = i1-TNT_BASE_OFFSET;
358             offset_[1] = j1-TNT_BASE_OFFSET;
359             dim_[0] = i2-i1+1;
360             dim_[1] = j2-j1+1;
361         }
362
363         const_Region2D(const Array2D &A, const Index1D &I, const Index1D &J) 
364                 : A_(A)
365         {
366 #ifdef TNT_BOUNDS_CHECK
367             assert( I.lbound() <= I.ubound() );
368             assert( J.lbound() <= J.ubound() );
369             assert( TNT_BASE_OFFSET <= I.lbound());
370             assert( I.ubound()<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
371             assert( TNT_BASE_OFFSET <= J.lbound());
372             assert( J.ubound() <= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
373 #endif
374
375             offset_[0] = I.lbound()-TNT_BASE_OFFSET;
376             offset_[1] = J.lbound()-TNT_BASE_OFFSET;
377             dim_[0] = I.ubound() - I.lbound() + 1;
378             dim_[1] = J.ubound() - J.lbound() + 1;
379         }
380
381
382         const_Region2D(const_Region2D<Array2D> &A, Subscript i1, 
383                 Subscript i2,
384             Subscript j1, Subscript j2) : A_(A.A_)
385         {
386 #ifdef TNT_BOUNDS_CHECK
387             assert( i1 <= i2 );
388             assert( j1 <= j2);
389             assert( TNT_BASE_OFFSET <= i1);
390             assert( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
391             assert( TNT_BASE_OFFSET <= j1);
392             assert( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
393 #endif
394             offset_[0] = (i1 - TNT_BASE_OFFSET) + A.offset_[0];
395             offset_[1] = (j1 - TNT_BASE_OFFSET) + A.offset_[1];
396             dim_[0] = i2-i1 + 1;
397             dim_[1] = j2-j1+1;
398         }
399
400         const_Region2D<Array2D> operator()(Subscript i1, Subscript i2,
401                 Subscript j1, Subscript j2)
402         {
403 #ifdef TNT_BOUNDS_CHECK
404             assert( i1 <= i2 );
405             assert( j1 <= j2);
406             assert( TNT_BASE_OFFSET <= i1);
407             assert( i2<= dim_[0] + TNT_BASE_OFFSET-1);
408             assert( TNT_BASE_OFFSET <= j1);
409             assert( j2<= dim_[0] + TNT_BASE_OFFSET-1 );
410 #endif
411             return const_Region2D<Array2D>(A_, 
412                     i1+offset_[0], offset_[0] + i2, 
413                     j1+offset_[1], offset_[1] + j2);
414         }
415
416
417         const_Region2D<Array2D> operator()(const Index1D &I,
418                 const Index1D &J)
419         {
420 #ifdef TNT_BOUNDS_CHECK
421             assert( I.lbound() <= I.ubound() );
422             assert( J.lbound() <= J.ubound() );
423             assert( TNT_BASE_OFFSET <= I.lbound());
424             assert( I.ubound()<= dim_[0] + TNT_BASE_OFFSET-1);
425             assert( TNT_BASE_OFFSET <= J.lbound());
426             assert( J.ubound() <= dim_[1] + TNT_BASE_OFFSET-1 );
427 #endif
428
429             return const_Region2D<Array2D>(A_, I.lbound()+offset_[0],
430                 offset_[0] + I.ubound(), offset_[1]+J.lbound(),
431                 offset_[1] + J.ubound());
432         }
433
434
435         inline const T & operator() (Subscript i, Subscript j) const
436         {
437 #ifdef TNT_BOUNDS_CHECK
438             assert( TNT_BASE_OFFSET <= i);
439             assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
440             assert( TNT_BASE_OFFSET <= j);
441             assert( j<= dim_[1] + TNT_BASE_OFFSET-1 );
442 #endif
443             return A_(i+offset_[0], j+offset_[1]);
444         }
445
446 };
447
448
449 //  ************** std::ostream algorithms *******************************
450
451 template <class Array2D>
452 std::ostream& operator<<(std::ostream &s, const const_Region2D<Array2D> &A)
453 {
454     Subscript start = A.lbound();
455     Subscript Mend=A.lbound()+ A.num_rows() - 1;
456     Subscript Nend=A.lbound() + A.num_cols() - 1;
457
458
459     s << A.num_rows() << "  " << A.num_cols() << "\n";
460     for (Subscript i=start; i<=Mend; i++)
461     {
462         for (Subscript j=start; j<=Nend; j++)
463         {
464             s << A(i,j) << " ";
465         }
466         s << "\n";
467     }
468
469
470     return s;
471 }
472
473 template <class Array2D>
474 std::ostream& operator<<(std::ostream &s, const Region2D<Array2D> &A)
475 {
476     Subscript start = A.lbound();
477     Subscript Mend=A.lbound()+ A.num_rows() - 1;
478     Subscript Nend=A.lbound() + A.num_cols() - 1;
479
480
481     s << A.num_rows() << "  " << A.num_cols() << "\n";
482     for (Subscript i=start; i<=Mend; i++)
483     {
484         for (Subscript j=start; j<=Nend; j++)
485         {
486             s << A(i,j) << " ";
487         }
488         s << "\n";
489     }
490
491
492     return s;
493
494 }
495
496 } // namespace TNT
497
498 #endif // REGION2D_H
499