/[escript]/trunk/escript/src/DataArrayView.h
ViewVC logotype

Annotation of /trunk/escript/src/DataArrayView.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 478 - (hide annotations)
Tue Jan 31 02:21:49 2006 UTC (14 years, 1 month ago) by jgs
File MIME type: text/plain
File size: 34664 byte(s)
rationalise #includes

1 jgs 102 // $Id$
2 jgs 108
3 jgs 82 /*
4     ******************************************************************************
5     * *
6     * COPYRIGHT ACcESS 2004 - All Rights Reserved *
7     * *
8     * This software is the property of ACcESS. No part of this code *
9     * may be copied in any form or by any means without the expressed written *
10     * consent of ACcESS. Copying, use or modification of this software *
11     * by any unauthorised person is illegal unless that person has a software *
12     * license agreement with ACcESS. *
13     * *
14     ******************************************************************************
15     */
16 jgs 474
17 jgs 82 #if !defined escript_DataArrayView_20040323_H
18     #define escript_DataArrayView_20040323_H
19    
20 jgs 468 #include "EsysAssert.h"
21 jgs 82
22 jgs 474 #include "DataVector.h"
23    
24 jgs 82 #include <boost/python/numeric.hpp>
25     #include <boost/python/object.hpp>
26    
27 jgs 108 #include <vector>
28 jgs 102
29 jgs 82 namespace escript {
30    
31     /**
32     \brief
33 jgs 108 DataArrayView provides a view of external data, configured according
34     to the given shape information and offset.
35 jgs 82
36     Description:
37     DataArrayView provides a view of data allocated externally. The
38     external data should provide sufficient values so that the dimensions
39 jgs 108 specified for the view shape will be satisfied. The viewer can update
40 jgs 82 values within the external data but cannot resize the external data.
41 jgs 108
42     The view provided represents a single n-dimensional data-point
43     comprised of values taken from the given data array, starting at the
44     specified offset and extending for as many values as are necessary to
45 jgs 117 satisfy the given shape. The default offset can be changed, or different
46     offsets specified, in order to provide views of other data-points in
47     the underlying data array.
48 jgs 82 */
49    
50     class DataArrayView {
51    
52     friend bool operator==(const DataArrayView& left, const DataArrayView& right);
53     friend bool operator!=(const DataArrayView& left, const DataArrayView& right);
54    
55     public:
56    
57 jgs 117 //
58     // Some basic types which define the data values and view shapes.
59     typedef DataVector ValueType;
60     //typedef std::vector<double> ValueType;
61 jgs 108 typedef std::vector<int> ShapeType;
62 jgs 82 typedef std::vector<std::pair<int, int> > RegionType;
63 jgs 108 typedef std::vector<std::pair<int, int> > RegionLoopRangeType;
64 jgs 82
65     /**
66     \brief
67     Default constructor for DataArrayView.
68    
69     Description:
70 jgs 108 Default constructor for DataArrayView.
71     Creates an empty view with no associated data array.
72    
73     This is essentially useless but here for completeness.
74 jgs 82 */
75     DataArrayView();
76    
77     /**
78     \brief
79     Constructor for DataArrayView.
80    
81     Description:
82     Constructor for DataArrayView.
83    
84 jgs 108 \param data - Input -
85     Array holding data to be viewed. This must be large enough
86     to supply sufficient values for the specified shape starting at
87     the given offset.
88     \param viewShape - Input -
89     The shape of the view to create.
90     \param offset - Input -
91     Offset into the data at which view should start.
92 jgs 82 */
93     DataArrayView(ValueType& data,
94     const ShapeType& viewShape,
95     int offset=0);
96    
97     /**
98     \brief
99     Copy constructor for DataArrayView.
100    
101     Description:
102     Copy constructor for DataArrayView.
103    
104 jgs 108 \param other - Input -
105     DataArrayView to copy.
106 jgs 82
107 jgs 108 NOTE: The copy references the same data array.
108 jgs 82 */
109     DataArrayView(const DataArrayView& other);
110    
111     /**
112     \brief
113 jgs 108 Copy from a numarray into the data array viewed by this.
114     This must have same shape as the given value - will throw if not.
115 jgs 82 */
116     void
117     copy(const boost::python::numeric::array& value);
118    
119     /**
120     \brief
121 jgs 108 Copy data from another DataArrayView into the data array viewed by this
122     starting at the default offset in both views.
123     The shapes of both views must be the same - will throw if not.
124     NB: views may or may not reference same underlying data array!
125 jgs 82 */
126     void
127     copy(const DataArrayView& other);
128    
129     /**
130     \brief
131 jgs 108 Copy data from another DataArrayView into this view starting at the
132     given offset in this view and the default offset in the other view.
133     The shapes of both views must be the same - will throw if not.
134     NB: views may or may not reference same underlying data array!
135 jgs 82 */
136     void
137     copy(ValueType::size_type offset,
138     const DataArrayView& other);
139    
140     /**
141     \brief
142 jgs 108 Copy data from another DataArrayView into this view starting at the
143     given offsets in each view.
144     The shapes of both views must be compatible - will throw if not.
145     NB: views may or may not reference same underlying data array!
146 jgs 82
147 jgs 108 \param thisOffset - Input -
148     Offset into this view's data array to copy to.
149     \param other - Input -
150     View to copy data from.
151     \param otherOffset - Input -
152     Offset into the other view's data array to copy from.
153 jgs 82 */
154     void
155     copy(ValueType::size_type thisOffset,
156     const DataArrayView& other,
157     ValueType::size_type otherOffset);
158    
159     /**
160     \brief
161 jgs 108 Copy the given single value over the entire view starting at the given
162     offset in the view's data array.
163 jgs 82
164 jgs 108 \param offset - Input -
165     Offset into this view's data array to copy to.
166     \param value - Input -
167     Value to copy.
168 jgs 82 */
169     void
170     copy(ValueType::size_type offset,
171     ValueType::value_type value);
172    
173     /**
174 jgs 108 \brief
175     Check if view is empty. ie: does not point to any actual data.
176     */
177     bool
178     isEmpty() const;
179    
180     /**
181 jgs 82 \brief
182 jgs 108 Return this view's offset into the viewed data array.
183 jgs 82 */
184     ValueType::size_type
185     getOffset() const;
186    
187     /**
188 jgs 108 \brief
189     Set the offset into the data array at which this view is to start.
190     This could be used to step through the underlying data array by incrementing
191     the offset by noValues successively. Thus this view would provide a moving
192     window on the underlying data with the given shape.
193 jgs 82 */
194 jgs 108 void
195     setOffset(ValueType::size_type offset);
196 jgs 82
197     /**
198     \brief
199 jgs 108 Increment the offset by the number of values in the shape, if possible. Thus
200     moving the view onto the next data point of the given shape in the underlying
201     data array.
202 jgs 82 */
203 jgs 108 void
204     incrOffset();
205 jgs 82
206     /**
207     \brief
208 jgs 108 Check the (given) offset will not result in two few values being available in
209     the underlying data array for this view's shape.
210 jgs 82 */
211 jgs 108 bool
212     checkOffset() const;
213 jgs 117
214 jgs 108 bool
215     checkOffset(ValueType::size_type offset) const;
216 jgs 82
217     /**
218 jgs 108 \brief
219     Return the rank of the shape of this view.
220     */
221     int
222     getRank() const;
223    
224     /**
225 jgs 82 \brief
226 jgs 108 Return the number of values for the shape of this view.
227 jgs 82 */
228     int
229     noValues() const;
230    
231     /**
232     \brief
233 jgs 108 Calculate the number of values for the given shape or region.
234     This is purely a utility method and has no bearing on this view.
235 jgs 82 */
236 jgs 117 static
237     int
238 jgs 108 noValues(const ShapeType& shape);
239 jgs 117
240     static
241     int
242 jgs 108 noValues(const RegionLoopRangeType& region);
243 jgs 82
244     /**
245     \brief
246 jgs 108 Return a reference to the underlying data array.
247 jgs 82 */
248     ValueType&
249     getData() const;
250    
251     /**
252     \brief
253 jgs 108 Return a reference to the data value with the given
254     index in this view. This takes into account the offset.
255 jgs 82 */
256     ValueType::reference
257     getData(ValueType::size_type i) const;
258    
259     /**
260     \brief
261 jgs 108 Return the shape of this view.
262 jgs 82 */
263 jgs 117 const
264     ShapeType&
265 jgs 108 getShape() const;
266 jgs 82
267     /**
268     \brief
269 jgs 108 Return true if the given shape is the same as this view's shape.
270 jgs 82 */
271 jgs 108 bool
272 jgs 117 checkShape(const ShapeType& other) const;
273 jgs 82
274     /**
275     \brief
276 jgs 108 Create a shape error message. Normally used when there is a shape
277 jgs 117 mismatch between this shape and the other shape.
278 jgs 82
279 jgs 108 \param messagePrefix - Input -
280     First part of the error message.
281     \param other - Input -
282     The other shape.
283 jgs 82 */
284 jgs 108 std::string
285     createShapeErrorMessage(const std::string& messagePrefix,
286 jgs 117 const ShapeType& other) const;
287 jgs 82
288     /**
289     \brief
290 jgs 108 Return the viewed data as a formatted string.
291     Not recommended for very large objects!
292 jgs 82
293 jgs 108 \param suffix - Input -
294     Suffix appended to index display.
295 jgs 82 */
296 jgs 108 std::string
297     toString(const std::string& suffix=std::string("")) const;
298 jgs 82
299     /**
300     \brief
301 jgs 108 Return the given shape as a string.
302     This is purely a utility method and has no bearing on this view.
303 jgs 82
304 jgs 108 \param shape - Input.
305 jgs 82 */
306 jgs 117 static
307     std::string
308     shapeToString(const ShapeType& shape);
309 jgs 82
310 jgs 108 /**
311     \brief
312     Return the 1 dimensional index into the data array of the only element
313     in the view, *ignoring the offset*.
314     Assumes a rank 0 view.
315 jgs 82 */
316 jgs 108 ValueType::size_type
317     relIndex() const;
318 jgs 82
319     /**
320 jgs 108 \brief
321     Return the 1 dimensional index into the data array of the element at
322     position i in the view, *ignoring the offset*.
323     Assumes a rank 1 view.
324 jgs 82 */
325 jgs 108 ValueType::size_type
326     relIndex(ValueType::size_type i) const;
327 jgs 82
328     /**
329 jgs 108 \brief
330     Return the 1 dimensional index into the data array of the element at
331     position i,j in the view, *ignoring the offset*.
332     Assumes a rank 2 view.
333 jgs 82 */
334 jgs 108 ValueType::size_type
335     relIndex(ValueType::size_type i,
336     ValueType::size_type j) const;
337 jgs 82
338     /**
339 jgs 108 \brief
340     Return the 1 dimensional index into the data array of the element at
341     position i,j,k in the view, *ignoring the offset*.
342     Assumes a rank 3 view.
343 jgs 82 */
344 jgs 108 ValueType::size_type
345     relIndex(ValueType::size_type i,
346     ValueType::size_type j,
347     ValueType::size_type k) const;
348 jgs 82
349     /**
350     \brief
351 jgs 108 Return the 1 dimensional index into the data array of the element at
352     position i,j,k,m in the view, *ignoring the offset*.
353     Assumes a rank 4 view.
354 jgs 82 */
355     ValueType::size_type
356     relIndex(ValueType::size_type i,
357     ValueType::size_type j,
358     ValueType::size_type k,
359     ValueType::size_type m) const;
360    
361     /**
362     \brief
363 jgs 108 Return the 1 dimensional index into the data array of the only element
364     in the view.
365     Assumes a rank 0 view.
366 jgs 82 */
367     ValueType::size_type
368 jgs 108 index() const;
369 jgs 82
370     /**
371     \brief
372 jgs 108 Return the 1 dimensional index into the data array of the element at
373     position i in the view.
374     Assumes a rank 1 view.
375 jgs 82 */
376     ValueType::size_type
377 jgs 108 index(ValueType::size_type i) const;
378 jgs 82
379     /**
380     \brief
381 jgs 108 Return the 1 dimensional index into the data array of the element at
382     position i,j in the view.
383     Assumes a rank 2 view.
384 jgs 82 */
385     ValueType::size_type
386     index(ValueType::size_type i,
387 jgs 108 ValueType::size_type j) const;
388 jgs 82
389     /**
390     \brief
391 jgs 108 Return the 1 dimensional index into the data array of the element at
392     position i,j,k in the view.
393     Assumes a rank 3 view.
394 jgs 82 */
395     ValueType::size_type
396     index(ValueType::size_type i,
397     ValueType::size_type j,
398     ValueType::size_type k) const;
399    
400     /**
401     \brief
402 jgs 108 Return the 1 dimensional index into the data array of the element at
403     position i,j,k,m in the view.
404     Assumes a rank 4 view.
405 jgs 82 */
406     ValueType::size_type
407     index(ValueType::size_type i,
408 jgs 108 ValueType::size_type j,
409     ValueType::size_type k,
410     ValueType::size_type m) const;
411 jgs 82
412     /**
413     \brief
414 jgs 108 Return a reference for the only element in the view.
415     Assumes a rank 0 view.
416 jgs 82 */
417 jgs 108 ValueType::reference
418     operator()();
419 jgs 82
420 jgs 108 ValueType::const_reference
421     operator()() const;
422    
423 jgs 82 /**
424     \brief
425 jgs 108 Return a reference to the element at position i in the view.
426     Assumes a rank 1 view.
427 jgs 82 */
428     ValueType::reference
429     operator()(ValueType::size_type i);
430    
431     ValueType::const_reference
432     operator()(ValueType::size_type i) const;
433    
434     /**
435     \brief
436 jgs 108 Return a reference to the element at position i,j in the view.
437     Assumes a rank 2 view.
438 jgs 82 */
439     ValueType::reference
440     operator()(ValueType::size_type i,
441     ValueType::size_type j);
442    
443     ValueType::const_reference
444     operator()(ValueType::size_type i,
445     ValueType::size_type j) const;
446    
447     /**
448     \brief
449 jgs 108 Return a reference to the element at position i,j,k in the view.
450     Assumes a rank 3 view.
451 jgs 82 */
452     ValueType::reference
453     operator()(ValueType::size_type i,
454     ValueType::size_type j,
455     ValueType::size_type k);
456    
457     ValueType::const_reference
458     operator()(ValueType::size_type i,
459     ValueType::size_type j,
460     ValueType::size_type k) const;
461    
462     /**
463     \brief
464 jgs 108 Return a reference to the element at position i,j,k,m in the view.
465     Assumes a rank 4 view.
466 jgs 82 */
467     ValueType::reference
468     operator()(ValueType::size_type i,
469     ValueType::size_type j,
470     ValueType::size_type k,
471     ValueType::size_type m);
472    
473     ValueType::const_reference
474     operator()(ValueType::size_type i,
475     ValueType::size_type j,
476     ValueType::size_type k,
477     ValueType::size_type m) const;
478    
479     /**
480 jgs 108 \brief
481     Determine the shape of the specified slice region.
482     This is purely a utility method and has no bearing on this view.
483    
484     \param region - Input -
485     Slice region.
486 jgs 82 */
487 jgs 117 static
488     ShapeType
489 jgs 108 getResultSliceShape(const RegionType& region);
490 jgs 82
491 jgs 108 /**
492     \brief
493     Determine the region specified by the given python slice object.
494 jgs 82
495 jgs 108 \param key - Input -
496     python slice object specifying region to be returned.
497    
498     The slice object is a tuple of n python slice specifiers, where
499     n <= the rank of this Data object. Each slice specifier specifies the
500     range of indexes to be sliced from the corresponding dimension. The
501     first specifier corresponds to the first dimension, the second to the
502     second and so on. Where n < the rank, the remaining dimensions are
503     sliced across the full range of their indicies.
504    
505     Each slice specifier is of the form "a:b", which specifies a slice
506     from index a, up to but not including index b. Where index a is ommitted
507     a is assumed to be 0. Where index b is ommitted, b is assumed to be the
508     length of this dimension. Where both are ommitted (eg: ":") the slice is
509     assumed to encompass that entire dimension.
510    
511     Where one of the slice specifiers is a single integer, eg: [1], we
512     want to generate a rank-1 dimension object, as opposed to eg: [1,2]
513     which implies we want to take a rank dimensional object with one
514     dimension of size 1.
515    
516     The return value is a vector of pairs with length equal to the rank of
517     this object. Each pair corresponds to the range of indicies from the
518     corresponding dimension to be sliced from, as specified in the input
519     slice object.
520    
521     Examples:
522    
523     For a rank 1 object of shape(5):
524    
525     getSliceRegion(:) => < <0,5> >
526     getSliceRegion(2:3) => < <2,3> >
527     getSliceRegion(:3) => < <0,3> >
528     getSliceRegion(2:) => < <2,5> >
529    
530     For a rank 2 object of shape(4,5):
531    
532     getSliceRegion(2:3) => < <2,3> <0,5> >
533     getSliceRegion(2) => < <2,3> <0,5> >
534     NB: but return object requested will have rank 1, shape(5), with
535     values taken from index 2 of this object's first dimension.
536    
537     For a rank 3 object of shape (2,4,6):
538    
539     getSliceRegion(0:2,0:4,0:6) => < <0,2> <0,4> <0,6> >
540     getSliceRegion(:,:,:) => < <0,2> <0,4> <0,6> >
541     getSliceRegion(0:1) => < <0,1> <0,4> <0,6> >
542     getSliceRegion(:1,0:2) => < <0,1> <0,2> <0,6> >
543    
544     */
545 jgs 117 RegionType
546 jgs 108 getSliceRegion(const boost::python::object& key) const;
547    
548 jgs 82 /**
549     \brief
550 jgs 108 Copy a data slice specified by the given region from the given view
551     into this view, using the default offsets in both views.
552    
553     \param other - Input -
554     View to copy data from.
555     \param region - Input -
556     Region in other view to copy data from.
557 jgs 82 */
558     void
559 jgs 108 copySlice(const DataArrayView& other,
560     const RegionLoopRangeType& region);
561 jgs 82
562     /**
563     \brief
564 jgs 108 Copy a data slice specified by the given region and offset from the
565     given view into this view at the given offset.
566    
567     \param thisOffset - Input -
568     Copy the slice to this offset in this view.
569     \param other - Input -
570     View to copy data from.
571     \param otherOffset - Input -
572     Copy the slice from this offset in the given view.
573     \param region - Input -
574     Region in other view to copy data from.
575 jgs 82 */
576     void
577 jgs 108 copySlice(ValueType::size_type thisOffset,
578     const DataArrayView& other,
579     ValueType::size_type otherOffset,
580     const RegionLoopRangeType& region);
581 jgs 82
582     /**
583     \brief
584 jgs 108 Copy data into a slice specified by the given region in this view from
585     the given view, using the default offsets in both views.
586 jgs 102
587 jgs 108 \param other - Input -
588     View to copy data from.
589     \param region - Input -
590     Region in this view to copy data to.
591 jgs 102 */
592 jgs 108 void
593     copySliceFrom(const DataArrayView& other,
594     const RegionLoopRangeType& region);
595 jgs 102
596     /**
597     \brief
598 jgs 108 Copy data into a slice specified by the given region and offset in
599     this view from the given view at the given offset.
600 jgs 102
601 jgs 108 \param thisOffset - Input -
602     Copy the slice to this offset in this view.
603     \param other - Input -
604     View to copy data from.
605     \param otherOffset - Input -
606     Copy the slice from this offset in the given view.
607     \param region - Input -
608     Region in this view to copy data to.
609 jgs 102 */
610 jgs 108 void
611     copySliceFrom(ValueType::size_type thisOffset,
612     const DataArrayView& other,
613     ValueType::size_type otherOffset,
614     const RegionLoopRangeType& region);
615 jgs 102
616     /**
617     \brief
618 jgs 108 Perform the unary operation on the data point specified by the view's
619     default offset. Applies the specified operation to each value in the data
620     point.
621    
622     Called by escript::unaryOp.
623    
624     \param operation - Input -
625     Operation to apply. Operation must be a pointer to a function.
626 jgs 82 */
627     template <class UnaryFunction>
628 jgs 108 void
629     unaryOp(UnaryFunction operation);
630 jgs 82
631     /**
632     \brief
633 jgs 108 Perform the unary operation on the data point specified by the given
634     offset. Applies the specified operation to each value in the data
635     point. Operation must be a pointer to a function.
636    
637     Called by escript::unaryOp.
638    
639     \param offset - Input -
640     Apply the operation to data starting at this offset in this view.
641     \param operation - Input -
642     Operation to apply. Must be a pointer to a function.
643 jgs 82 */
644     template <class UnaryFunction>
645 jgs 108 void
646     unaryOp(ValueType::size_type offset,
647     UnaryFunction operation);
648 jgs 82
649     /**
650     \brief
651 jgs 108 Perform the binary operation on the data points specified by the default
652     offsets in this view and in view "right". Applies the specified operation
653     to corresponding values in both data points. Operation must be a pointer
654     to a function.
655    
656     Called by escript::binaryOp.
657    
658     \param right - Input -
659     View to act as RHS in given binary operation.
660     \param operation - Input -
661     Operation to apply. Must be a pointer to a function.
662 jgs 82 */
663     template <class BinaryFunction>
664     void
665 jgs 108 binaryOp(const DataArrayView& right,
666 jgs 82 BinaryFunction operation);
667    
668     /**
669     \brief
670 jgs 108 Perform the binary operation on the data points specified by the given
671     offsets in this view and in view "right". Applies the specified operation
672     to corresponding values in both data points. Operation must be a pointer
673     to a function.
674    
675     Called by escript::binaryOp.
676    
677     \param leftOffset - Input -
678     Apply the operation to data starting at this offset in this view.
679     \param right - Input -
680     View to act as RHS in given binary operation.
681     \param rightOffset - Input -
682     Apply the operation to data starting at this offset in right.
683     \param operation - Input -
684     Operation to apply. Must be a pointer to a function.
685 jgs 82 */
686     template <class BinaryFunction>
687     void
688 jgs 108 binaryOp(ValueType::size_type leftOffset,
689     const DataArrayView& right,
690     ValueType::size_type rightOffset,
691 jgs 82 BinaryFunction operation);
692    
693     /**
694     \brief
695 jgs 108 Perform the binary operation on the data point specified by the default
696     offset in this view using the scalar value "right". Applies the specified
697     operation to values in the data point. Operation must be a pointer to
698     a function.
699    
700     Called by escript::binaryOp.
701    
702     \param right - Input -
703     Value to act as RHS in given binary operation.
704     \param operation - Input -
705     Operation to apply. Must be a pointer to a function.
706 jgs 82 */
707     template <class BinaryFunction>
708     void
709 jgs 108 binaryOp(double right,
710 jgs 82 BinaryFunction operation);
711    
712     /**
713     \brief
714 jgs 108 Perform the binary operation on the data point specified by the given
715     offset in this view using the scalar value "right". Applies the specified
716     operation to values in the data point. Operation must be a pointer
717     to a function.
718    
719     Called by escript::binaryOp.
720    
721     \param offset - Input -
722     Apply the operation to data starting at this offset in this view.
723     \param right - Input -
724     Value to act as RHS in given binary operation.
725     \param operation - Input -
726     Operation to apply. Must be a pointer to a function.
727 jgs 82 */
728     template <class BinaryFunction>
729     void
730 jgs 108 binaryOp(ValueType::size_type offset,
731     double right,
732 jgs 82 BinaryFunction operation);
733    
734     /**
735     \brief
736 jgs 108 Perform the given data point reduction operation on the data point
737     specified by the default offset into the view. Reduces all elements of
738     the data point using the given operation, returning the result as a
739     scalar. Operation must be a pointer to a function.
740    
741     Called by escript::algorithm.
742    
743     \param operation - Input -
744     Operation to apply. Must be a pointer to a function.
745     */
746 jgs 147 template <class BinaryFunction>
747 jgs 108 double
748 jgs 147 reductionOp(BinaryFunction operation,
749     double initial_value) const;
750 jgs 108
751     /**
752     \brief
753 jgs 113 Perform the given data point reduction operation on the data point
754 jgs 108 specified by the given offset into the view. Reduces all elements of
755     the data point using the given operation, returning the result as a
756     scalar. Operation must be a pointer to a function.
757    
758     Called by escript::algorithm.
759    
760     \param offset - Input -
761     Apply the operation to data starting at this offset in this view.
762     \param operation - Input -
763     Operation to apply. Must be a pointer to a function.
764     */
765 jgs 147 template <class BinaryFunction>
766 jgs 108 double
767     reductionOp(ValueType::size_type offset,
768 jgs 147 BinaryFunction operation,
769     double initial_value) const;
770 jgs 108
771     /**
772     \brief
773 jgs 113 Perform a matrix multiply of the given views.
774     This is purely a utility method and has no bearing on this view.
775 jgs 82
776 jgs 126 NB: Only multiplies together the two given views, ie: two data-points,
777     would need to call this over all data-points to multiply the entire
778     Data objects involved.
779    
780 jgs 82 \param left - Input - The left hand side.
781     \param right - Input - The right hand side.
782     \param result - Output - The result of the operation.
783     */
784 jgs 117 static
785     void
786 jgs 82 matMult(const DataArrayView& left,
787     const DataArrayView& right,
788     DataArrayView& result);
789    
790 jgs 108 /**
791     \brief
792     Determine the shape of the result array for a matrix multiplication
793     of the given views.
794     This is purely a utility method and has no bearing on this view.
795     */
796 jgs 117 static
797     ShapeType
798 jgs 108 determineResultShape(const DataArrayView& left,
799     const DataArrayView& right);
800    
801 jgs 82 protected:
802    
803     private:
804    
805     //
806 jgs 108 // The maximum rank allowed for the shape of any view.
807 jgs 82 static const int m_maxRank=4;
808    
809     //
810 jgs 108 // The data values for the view.
811     // NOTE: This points to data external to the view.
812 jgs 117 // This is just a pointer to an array of ValueType.
813 jgs 82 ValueType* m_data;
814    
815     //
816     // The offset into the data array used by different views.
817 jgs 108 // This is simply an integer specifying a position in the data array
818     // pointed to by m_data.
819 jgs 82 ValueType::size_type m_offset;
820    
821     //
822     // The shape of the data.
823 jgs 108 // This is simply an STL vector specifying the lengths of each dimension
824     // of the shape as ints.
825 jgs 82 ShapeType m_shape;
826    
827     //
828     // The number of values needed for the array.
829 jgs 108 // This can be derived from m_shape by multiplying the size of each dimension, but
830     // is stored here for convenience.
831 jgs 82 int m_noValues;
832    
833     };
834    
835 jgs 108 bool operator==(const DataArrayView& left, const DataArrayView& right);
836     bool operator!=(const DataArrayView& left, const DataArrayView& right);
837    
838 jgs 102 /**
839     \brief
840 jgs 108 Modify region to copy from in order to
841     deal with the case where one range in the region contains identical indexes,
842     eg: <<1,1><0,3><0,3>>
843     This situation implies we want to copy from an object with rank greater than that of this
844     object. eg: we want to copy the values from a two dimensional slice out of a three
845     dimensional object into a two dimensional object.
846     We do this by taking a slice from the other object where one dimension of
847     the slice region is of size 1. So in the above example, we modify the above
848     region like so: <<1,2><0,3><0,3>> and take this slice.
849     */
850     DataArrayView::RegionLoopRangeType
851     getSliceRegionLoopRange(const DataArrayView::RegionType& region);
852    
853     /**
854     \brief
855 jgs 102 Calculate the slice range from the given python key object
856     Used by DataArrayView::getSliceRegion.
857     Returns the python slice object key as a pair of ints where the first
858     member is the start and the second member is the end. the presence of a possible
859     step attribute with value different from one will throw an exception
860    
861     /param key - Input - key object specifying slice range.
862     */
863     std::pair<int,int>
864     getSliceRange(const boost::python::object& key,
865     const int shape);
866    
867 jgs 108 /**
868     Inline function definitions.
869     */
870    
871     template <class UnaryFunction>
872 jgs 82 inline
873 jgs 108 void
874     DataArrayView::unaryOp(UnaryFunction operation)
875 jgs 82 {
876 jgs 108 unaryOp(m_offset,operation);
877 jgs 82 }
878    
879 jgs 108 template <class UnaryFunction>
880 jgs 82 inline
881 jgs 108 void
882     DataArrayView::unaryOp(ValueType::size_type offset,
883     UnaryFunction operation)
884 jgs 82 {
885 jgs 108 EsysAssert((!isEmpty()&&checkOffset(offset)),
886     "Error - Couldn't perform unaryOp due to insufficient storage.");
887     for (ValueType::size_type i=0;i<noValues();i++) {
888     (*m_data)[offset+i]=operation((*m_data)[offset+i]);
889     }
890 jgs 82 }
891    
892 jgs 108 template <class BinaryFunction>
893 jgs 82 inline
894 jgs 108 void
895     DataArrayView::binaryOp(const DataArrayView& right,
896     BinaryFunction operation)
897 jgs 82 {
898 jgs 108 binaryOp(m_offset,right,right.getOffset(),operation);
899 jgs 82 }
900    
901 jgs 108 template <class BinaryFunction>
902 jgs 82 inline
903     void
904 jgs 108 DataArrayView::binaryOp(ValueType::size_type leftOffset,
905     const DataArrayView& right,
906     ValueType::size_type rightOffset,
907     BinaryFunction operation)
908 jgs 82 {
909 jgs 108 EsysAssert(getShape()==right.getShape(),
910     "Error - Couldn't perform binaryOp due to shape mismatch,");
911     EsysAssert((!isEmpty()&&checkOffset(leftOffset)),
912     "Error - Couldn't perform binaryOp due to insufficient storage in left object.");
913     EsysAssert((!right.isEmpty()&&right.checkOffset(rightOffset)),
914     "Error - Couldn't perform binaryOp due to insufficient storage in right object.");
915     for (ValueType::size_type i=0;i<noValues();i++) {
916     (*m_data)[leftOffset+i]=operation((*m_data)[leftOffset+i],(*right.m_data)[rightOffset+i]);
917 jgs 82 }
918     }
919    
920 jgs 108 template <class BinaryFunction>
921 jgs 82 inline
922     void
923 jgs 108 DataArrayView::binaryOp(double right,
924     BinaryFunction operation)
925 jgs 82 {
926 jgs 108 binaryOp(m_offset,right,operation);
927 jgs 82 }
928    
929 jgs 108 template <class BinaryFunction>
930 jgs 82 inline
931 jgs 108 void
932     DataArrayView::binaryOp(ValueType::size_type offset,
933     double right,
934     BinaryFunction operation)
935 jgs 102 {
936 jgs 108 EsysAssert((!isEmpty()&&checkOffset(offset)),
937 jgs 113 "Error - Couldn't perform binaryOp due to insufficient storage in left object.");
938 jgs 108 for (ValueType::size_type i=0;i<noValues();i++) {
939     (*m_data)[offset+i]=operation((*m_data)[offset+i],right);
940 jgs 102 }
941     }
942    
943 jgs 147 template <class BinaryFunction>
944 jgs 102 inline
945     double
946 jgs 147 DataArrayView::reductionOp(BinaryFunction operation,
947     double initial_value) const
948 jgs 82 {
949 jgs 147 return reductionOp(m_offset,operation,initial_value);
950 jgs 82 }
951    
952 jgs 147 template <class BinaryFunction>
953 jgs 82 inline
954 jgs 108 double
955     DataArrayView::reductionOp(ValueType::size_type offset,
956 jgs 147 BinaryFunction operation,
957     double initial_value) const
958 jgs 82 {
959 jgs 108 EsysAssert((!isEmpty()&&checkOffset(offset)),
960     "Error - Couldn't perform reductionOp due to insufficient storage.");
961 jgs 147 double current_value=initial_value;
962 jgs 108 for (ValueType::size_type i=0;i<noValues();i++) {
963 jgs 147 current_value=operation(current_value,(*m_data)[offset+i]);
964 jgs 82 }
965 jgs 147 return current_value;
966 jgs 82 }
967    
968     inline
969 jgs 108 DataArrayView::ValueType::size_type
970     DataArrayView::relIndex() const
971 jgs 82 {
972 jgs 108 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
973     return 0;
974 jgs 82 }
975    
976     inline
977 jgs 108 DataArrayView::ValueType::size_type
978     DataArrayView::index() const
979 jgs 82 {
980 jgs 108 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
981     return (m_offset);
982 jgs 82 }
983    
984     inline
985 jgs 108 DataArrayView::ValueType::size_type
986     DataArrayView::relIndex(ValueType::size_type i) const
987 jgs 82 {
988 jgs 108 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
989     EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
990     return i;
991 jgs 82 }
992    
993     inline
994     DataArrayView::ValueType::size_type
995     DataArrayView::index(ValueType::size_type i) const
996     {
997 jgs 108 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
998     EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
999     return (m_offset+i);
1000 jgs 82 }
1001    
1002     inline
1003     DataArrayView::ValueType::size_type
1004     DataArrayView::relIndex(ValueType::size_type i,
1005     ValueType::size_type j) const
1006     {
1007 jgs 108 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1008 jgs 82 ValueType::size_type temp=i+j*m_shape[0];
1009 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1010 jgs 82 return temp;
1011     }
1012    
1013     inline
1014     DataArrayView::ValueType::size_type
1015     DataArrayView::index(ValueType::size_type i,
1016     ValueType::size_type j) const
1017     {
1018 jgs 108 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1019 jgs 82 ValueType::size_type temp=i+j*m_shape[0];
1020 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1021     return (m_offset+temp);
1022 jgs 82 }
1023    
1024     inline
1025     DataArrayView::ValueType::size_type
1026     DataArrayView::relIndex(ValueType::size_type i,
1027     ValueType::size_type j,
1028     ValueType::size_type k) const
1029     {
1030 jgs 108 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1031     ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1032     EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1033     return temp;
1034 jgs 82 }
1035    
1036     inline
1037     DataArrayView::ValueType::size_type
1038     DataArrayView::index(ValueType::size_type i,
1039     ValueType::size_type j,
1040     ValueType::size_type k) const
1041     {
1042 jgs 108 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1043     ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1044     EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1045     return (m_offset+temp);
1046 jgs 82 }
1047    
1048     inline
1049     DataArrayView::ValueType::size_type
1050     DataArrayView::relIndex(ValueType::size_type i,
1051     ValueType::size_type j,
1052     ValueType::size_type k,
1053     ValueType::size_type m) const
1054     {
1055 jgs 108 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1056 jgs 82 ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0]+m*m_shape[2]*m_shape[1]*m_shape[0];
1057 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1058 jgs 82 return temp;
1059     }
1060    
1061     inline
1062     DataArrayView::ValueType::size_type
1063     DataArrayView::index(ValueType::size_type i,
1064     ValueType::size_type j,
1065     ValueType::size_type k,
1066     ValueType::size_type m) const
1067     {
1068 jgs 108 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1069 jgs 82 ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0]+m*m_shape[2]*m_shape[1]*m_shape[0];
1070 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1071     return (m_offset+temp);
1072 jgs 82 }
1073    
1074     inline
1075     DataArrayView::ValueType::reference
1076 jgs 108 DataArrayView::operator()()
1077 jgs 82 {
1078 jgs 108 return (*m_data)[index()];
1079 jgs 82 }
1080    
1081     inline
1082     DataArrayView::ValueType::const_reference
1083 jgs 108 DataArrayView::operator()() const
1084 jgs 82 {
1085 jgs 108 return (*m_data)[index()];
1086 jgs 82 }
1087    
1088     inline
1089     DataArrayView::ValueType::reference
1090 jgs 108 DataArrayView::operator()(ValueType::size_type i)
1091 jgs 82 {
1092 jgs 108 return (*m_data)[index(i)];
1093 jgs 82 }
1094    
1095     inline
1096     DataArrayView::ValueType::const_reference
1097 jgs 108 DataArrayView::operator()(ValueType::size_type i) const
1098 jgs 82 {
1099 jgs 108 return (*m_data)[index(i)];
1100 jgs 82 }
1101    
1102     inline
1103     DataArrayView::ValueType::reference
1104     DataArrayView::operator()(ValueType::size_type i,
1105     ValueType::size_type j)
1106     {
1107 jgs 108 return (*m_data)[index(i,j)];
1108 jgs 82 }
1109    
1110     inline
1111     DataArrayView::ValueType::const_reference
1112     DataArrayView::operator()(ValueType::size_type i,
1113     ValueType::size_type j) const
1114     {
1115 jgs 108 return (*m_data)[index(i,j)];
1116 jgs 82 }
1117    
1118     inline
1119     DataArrayView::ValueType::reference
1120 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1121     ValueType::size_type j,
1122     ValueType::size_type k)
1123 jgs 82 {
1124 jgs 108 return (*m_data)[index(i,j,k)];
1125 jgs 82 }
1126    
1127     inline
1128     DataArrayView::ValueType::const_reference
1129 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1130     ValueType::size_type j,
1131     ValueType::size_type k) const
1132 jgs 82 {
1133 jgs 108 return (*m_data)[index(i,j,k)];
1134 jgs 82 }
1135    
1136     inline
1137     DataArrayView::ValueType::reference
1138 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1139     ValueType::size_type j,
1140     ValueType::size_type k,
1141     ValueType::size_type m)
1142 jgs 82 {
1143 jgs 108 return (*m_data)[index(i,j,k,m)];
1144 jgs 82 }
1145    
1146     inline
1147     DataArrayView::ValueType::const_reference
1148 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1149     ValueType::size_type j,
1150     ValueType::size_type k,
1151     ValueType::size_type m) const
1152 jgs 82 {
1153 jgs 108 return (*m_data)[index(i,j,k,m)];
1154 jgs 82 }
1155    
1156     } // end of namespace
1157    
1158     #endif

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26