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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 121 - (hide annotations)
Fri May 6 04:26:16 2005 UTC (14 years, 2 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/DataArrayView.h
File MIME type: text/plain
File size: 34413 byte(s)
Merge of development branch back to main trunk on 2005-05-06

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26