0307ee02c39acc76cbf0bdfac70b9974fa3362b1
[blender.git] / intern / iksolver / intern / TNT / region1d.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
58
59 #ifndef REGION1D_H
60 #define REGION1D_H
61
62
63 #include "subscript.h"
64 #include "index.h"
65 #include <iostream>
66 #include <cassert>
67
68 namespace TNT
69 {
70
71 template <class Array1D>
72 class const_Region1D;
73
74 template <class Array1D>
75 class Region1D
76 {
77     protected:
78
79         Array1D &  A_;
80         Subscript offset_;          // 0-based
81         Subscript dim_;
82
83         typedef typename Array1D::element_type T;
84
85     public:
86         const Array1D & array()  const { return A_; }
87
88         Subscript offset() const { return offset_;}
89         Subscript dim() const { return dim_; }
90
91         Subscript offset(Subscript i) const
92         {
93 #ifdef TNT_BOUNDS_CHECK
94             assert(i==TNT_BASE_OFFSET);
95 #endif
96             return offset_;
97         }
98
99         Subscript dim(Subscript i) const
100         {
101 #ifdef TNT_BOUNDS_CHECK
102             assert(i== TNT_BASE_OFFSET);
103 #endif
104             return offset_;
105         }
106
107
108         Region1D(Array1D &A, Subscript i1, Subscript i2) : A_(A)
109         {
110 #ifdef TNT_BOUNDS_CHECK
111             assert(TNT_BASE_OFFSET <= i1 );
112             assert(i2 <= A.dim() + (TNT_BASE_OFFSET-1));
113             assert(i1 <= i2);
114 #endif
115             offset_ = i1 - TNT_BASE_OFFSET;
116             dim_ = i2-i1 + 1;
117         }
118
119         Region1D(Array1D &A, const Index1D &I) : A_(A)
120         {
121 #ifdef TNT_BOUNDS_CHECK
122             assert(TNT_BASE_OFFSET <=I.lbound());
123             assert(I.ubound() <= A.dim() + (TNT_BASE_OFFSET-1));
124             assert(I.lbound() <= I.ubound());
125 #endif
126             offset_ = I.lbound() - TNT_BASE_OFFSET;
127             dim_ = I.ubound() - I.lbound() + 1;
128         }
129
130         Region1D(Region1D<Array1D> &A, Subscript i1, Subscript i2) :
131                 A_(A.A_)
132         {
133 #ifdef TNT_BOUNDS_CHECK
134             assert(TNT_BASE_OFFSET <= i1 );
135             assert(i2 <= A.dim() + (TNT_BASE_OFFSET - 1));
136             assert(i1 <= i2);
137 #endif
138                     //     (old-offset)        (new-offset)
139                     //
140             offset_ =  (i1 - TNT_BASE_OFFSET) + A.offset_;
141             dim_ = i2-i1 + 1;
142         }
143
144         Region1D<Array1D> operator()(Subscript i1, Subscript i2)
145         {
146 #ifdef TNT_BOUNDS_CHECK
147             assert(TNT_BASE_OFFSET <= i1);
148             assert(i2 <= dim() + (TNT_BASE_OFFSET -1));
149             assert(i1 <= i2);
150 #endif
151                     // offset_ is 0-based, so no need for
152                     //  ( - TNT_BASE_OFFSET)
153                     //
154             return Region1D<Array1D>(A_, i1+offset_,
155                     offset_ + i2);
156         }
157
158
159         Region1D<Array1D> operator()(const Index1D &I)
160         {
161 #ifdef TNT_BOUNDS_CHECK
162             assert(TNT_BASE_OFFSET<=I.lbound());
163             assert(I.ubound() <= dim() + (TNT_BASE_OFFSET-1));
164             assert(I.lbound() <= I.ubound());
165 #endif
166             return Region1D<Array1D>(A_, I.lbound()+offset_,
167                 offset_ + I.ubound());
168         }
169
170
171
172
173         T & operator()(Subscript i)
174         {
175 #ifdef TNT_BOUNDS_CHECK
176             assert(TNT_BASE_OFFSET <= i);
177             assert(i <=  dim() + (TNT_BASE_OFFSET-1));
178 #endif
179             return A_(i+offset_);
180         }
181
182         const T & operator() (Subscript i) const
183         {
184 #ifdef TNT_BOUNDS_CHECK
185             assert(TNT_BASE_OFFSET <= i);
186             assert(i <= dim() + (TNT_BASE_OFFSET-1));
187 #endif
188             return A_(i+offset_);
189         }
190
191
192         Region1D<Array1D> & operator=(const Region1D<Array1D> &R)
193         {
194             // make sure both sides conform
195             assert(dim() == R.dim());
196
197             Subscript N = dim();
198             Subscript i;
199             Subscript istart = TNT_BASE_OFFSET;
200             Subscript iend = istart + N-1;
201
202             for (i=istart; i<=iend; i++)
203                 (*this)(i) = R(i);
204
205             return *this;
206         }
207
208
209
210         Region1D<Array1D> & operator=(const const_Region1D<Array1D> &R)
211         {
212             // make sure both sides conform
213             assert(dim() == R.dim());
214
215             Subscript N = dim();
216             Subscript i;
217             Subscript istart = TNT_BASE_OFFSET;
218             Subscript iend = istart + N-1;
219
220             for (i=istart; i<=iend; i++)
221                 (*this)(i) = R(i);
222
223             return *this;
224
225         }
226
227
228         Region1D<Array1D> & operator=(const T& t)
229         {
230             Subscript N=dim();
231             Subscript i;
232             Subscript istart = TNT_BASE_OFFSET;
233             Subscript iend = istart + N-1;
234
235             for (i=istart; i<= iend; i++)
236                 (*this)(i) = t;
237
238             return *this;
239
240         }
241
242
243         Region1D<Array1D> & operator=(const Array1D &R)
244         {
245             // make sure both sides conform
246             Subscript N = dim();
247             assert(dim() == R.dim());
248
249             Subscript i;
250             Subscript istart = TNT_BASE_OFFSET;
251             Subscript iend = istart + N-1;
252
253             for (i=istart; i<=iend; i++)
254                 (*this)(i) = R(i);
255
256             return *this;
257
258         }
259
260 };
261
262 template <class Array1D>
263 std::ostream& operator<<(std::ostream &s, Region1D<Array1D> &A)
264 {
265     Subscript N=A.dim();
266     Subscript istart = TNT_BASE_OFFSET;
267     Subscript iend = N - 1 + TNT_BASE_OFFSET;
268
269     for (Subscript i=istart; i<=iend; i++)
270         s << A(i) << endl;
271
272     return s;
273 }
274
275
276 /*  ---------  class const_Region1D ------------ */
277
278 template <class Array1D>
279 class const_Region1D
280 {
281     protected:
282
283         const Array1D &  A_;
284         Subscript offset_;          // 0-based
285         Subscript dim_;
286        typedef typename Array1D::element_type T;
287
288     public:
289         const Array1D & array()  const { return A_; }
290
291         Subscript offset() const { return offset_;}
292         Subscript dim() const { return dim_; }
293
294         Subscript offset(Subscript i) const
295         {
296 #ifdef TNT_BOUNDS_CHECK
297             assert(i==TNT_BASE_OFFSET);
298 #endif
299             return offset_;
300         }
301
302         Subscript dim(Subscript i) const
303         {
304 #ifdef TNT_BOUNDS_CHECK
305             assert(i== TNT_BASE_OFFSET);
306 #endif
307             return offset_;
308         }
309
310
311         const_Region1D(const Array1D &A, Subscript i1, Subscript i2) : A_(A)
312         {
313 #ifdef TNT_BOUNDS_CHECK
314             assert(TNT_BASE_OFFSET <= i1 );
315             assert(i2 <= A.dim() + (TNT_BASE_OFFSET-1));
316             assert(i1 <= i2);
317 #endif
318             offset_ = i1 - TNT_BASE_OFFSET;
319             dim_ = i2-i1 + 1;
320         }
321
322         const_Region1D(const Array1D &A, const Index1D &I) : A_(A)
323         {
324 #ifdef TNT_BOUNDS_CHECK
325             assert(TNT_BASE_OFFSET <=I.lbound());
326             assert(I.ubound() <= A.dim() + (TNT_BASE_OFFSET-1));
327             assert(I.lbound() <= I.ubound());
328 #endif
329             offset_ = I.lbound() - TNT_BASE_OFFSET;
330             dim_ = I.ubound() - I.lbound() + 1;
331         }
332
333         const_Region1D(const_Region1D<Array1D> &A, Subscript i1, Subscript i2) :
334                 A_(A.A_)
335         {
336 #ifdef TNT_BOUNDS_CHECK
337             assert(TNT_BASE_OFFSET <= i1 );
338             assert(i2 <= A.dim() + (TNT_BASE_OFFSET - 1));
339             assert(i1 <= i2);
340 #endif
341                     //     (old-offset)        (new-offset)
342                     //
343             offset_ =  (i1 - TNT_BASE_OFFSET) + A.offset_;
344             dim_ = i2-i1 + 1;
345         }
346
347         const_Region1D<Array1D> operator()(Subscript i1, Subscript i2)
348         {
349 #ifdef TNT_BOUNDS_CHECK
350             assert(TNT_BASE_OFFSET <= i1);
351             assert(i2 <= dim() + (TNT_BASE_OFFSET -1));
352             assert(i1 <= i2);
353 #endif
354                     // offset_ is 0-based, so no need for
355                     //  ( - TNT_BASE_OFFSET)
356                     //
357             return const_Region1D<Array1D>(A_, i1+offset_,
358                     offset_ + i2);
359         }
360
361
362         const_Region1D<Array1D> operator()(const Index1D &I)
363         {
364 #ifdef TNT_BOUNDS_CHECK
365             assert(TNT_BASE_OFFSET<=I.lbound());
366             assert(I.ubound() <= dim() + (TNT_BASE_OFFSET-1));
367             assert(I.lbound() <= I.ubound());
368 #endif
369             return const_Region1D<Array1D>(A_, I.lbound()+offset_,
370                 offset_ + I.ubound());
371         }
372
373
374         const T & operator() (Subscript i) const
375         {
376 #ifdef TNT_BOUNDS_CHECK
377             assert(TNT_BASE_OFFSET <= i);
378             assert(i <= dim() + (TNT_BASE_OFFSET-1));
379 #endif
380             return A_(i+offset_);
381         }
382
383
384
385
386 };
387
388 template <class Array1D>
389 std::ostream& operator<<(std::ostream &s, const_Region1D<Array1D> &A)
390 {
391     Subscript N=A.dim();
392
393     for (Subscript i=1; i<=N; i++)
394         s << A(i) << endl;
395
396     return s;
397 }
398
399
400 } // namespace TNT
401
402 #endif
403 // const_Region1D_H