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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 113 - (hide annotations)
Mon Feb 28 07:06:33 2005 UTC (14 years, 11 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/DataArrayView.h
File MIME type: text/plain
File size: 34363 byte(s)
*** empty log message ***

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26