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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 126 - (hide annotations)
Fri Jul 22 03:53:08 2005 UTC (14 years, 7 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/DataArrayView.h
File MIME type: text/plain
File size: 34591 byte(s)
Merge of development branch back to main trunk on 2005-07-22

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 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     template <class UnaryFunction>
944     inline
945     double
946 jgs 108 DataArrayView::reductionOp(UnaryFunction operation) const
947 jgs 82 {
948 jgs 108 return reductionOp(m_offset,operation);
949 jgs 82 }
950    
951 jgs 108 template <class UnaryFunction>
952 jgs 82 inline
953 jgs 108 double
954     DataArrayView::reductionOp(ValueType::size_type offset,
955     UnaryFunction operation) const
956 jgs 82 {
957 jgs 108 EsysAssert((!isEmpty()&&checkOffset(offset)),
958     "Error - Couldn't perform reductionOp due to insufficient storage.");
959 jgs 113 operation.resetResult();
960 jgs 108 for (ValueType::size_type i=0;i<noValues();i++) {
961     operation((*m_data)[offset+i]);
962 jgs 82 }
963 jgs 108 return operation.getResult();
964 jgs 82 }
965    
966     inline
967 jgs 108 DataArrayView::ValueType::size_type
968     DataArrayView::relIndex() const
969 jgs 82 {
970 jgs 108 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
971     return 0;
972 jgs 82 }
973    
974     inline
975 jgs 108 DataArrayView::ValueType::size_type
976     DataArrayView::index() const
977 jgs 82 {
978 jgs 108 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
979     return (m_offset);
980 jgs 82 }
981    
982     inline
983 jgs 108 DataArrayView::ValueType::size_type
984     DataArrayView::relIndex(ValueType::size_type i) const
985 jgs 82 {
986 jgs 108 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
987     EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
988     return i;
989 jgs 82 }
990    
991     inline
992     DataArrayView::ValueType::size_type
993     DataArrayView::index(ValueType::size_type i) const
994     {
995 jgs 108 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
996     EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
997     return (m_offset+i);
998 jgs 82 }
999    
1000     inline
1001     DataArrayView::ValueType::size_type
1002     DataArrayView::relIndex(ValueType::size_type i,
1003     ValueType::size_type j) const
1004     {
1005 jgs 108 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1006 jgs 82 ValueType::size_type temp=i+j*m_shape[0];
1007 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1008 jgs 82 return temp;
1009     }
1010    
1011     inline
1012     DataArrayView::ValueType::size_type
1013     DataArrayView::index(ValueType::size_type i,
1014     ValueType::size_type j) const
1015     {
1016 jgs 108 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1017 jgs 82 ValueType::size_type temp=i+j*m_shape[0];
1018 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1019     return (m_offset+temp);
1020 jgs 82 }
1021    
1022     inline
1023     DataArrayView::ValueType::size_type
1024     DataArrayView::relIndex(ValueType::size_type i,
1025     ValueType::size_type j,
1026     ValueType::size_type k) const
1027     {
1028 jgs 108 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1029     ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1030     EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1031     return temp;
1032 jgs 82 }
1033    
1034     inline
1035     DataArrayView::ValueType::size_type
1036     DataArrayView::index(ValueType::size_type i,
1037     ValueType::size_type j,
1038     ValueType::size_type k) const
1039     {
1040 jgs 108 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1041     ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1042     EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1043     return (m_offset+temp);
1044 jgs 82 }
1045    
1046     inline
1047     DataArrayView::ValueType::size_type
1048     DataArrayView::relIndex(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 jgs 82 return temp;
1057     }
1058    
1059     inline
1060     DataArrayView::ValueType::size_type
1061     DataArrayView::index(ValueType::size_type i,
1062     ValueType::size_type j,
1063     ValueType::size_type k,
1064     ValueType::size_type m) const
1065     {
1066 jgs 108 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1067 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];
1068 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1069     return (m_offset+temp);
1070 jgs 82 }
1071    
1072     inline
1073     DataArrayView::ValueType::reference
1074 jgs 108 DataArrayView::operator()()
1075 jgs 82 {
1076 jgs 108 return (*m_data)[index()];
1077 jgs 82 }
1078    
1079     inline
1080     DataArrayView::ValueType::const_reference
1081 jgs 108 DataArrayView::operator()() const
1082 jgs 82 {
1083 jgs 108 return (*m_data)[index()];
1084 jgs 82 }
1085    
1086     inline
1087     DataArrayView::ValueType::reference
1088 jgs 108 DataArrayView::operator()(ValueType::size_type i)
1089 jgs 82 {
1090 jgs 108 return (*m_data)[index(i)];
1091 jgs 82 }
1092    
1093     inline
1094     DataArrayView::ValueType::const_reference
1095 jgs 108 DataArrayView::operator()(ValueType::size_type i) const
1096 jgs 82 {
1097 jgs 108 return (*m_data)[index(i)];
1098 jgs 82 }
1099    
1100     inline
1101     DataArrayView::ValueType::reference
1102     DataArrayView::operator()(ValueType::size_type i,
1103     ValueType::size_type j)
1104     {
1105 jgs 108 return (*m_data)[index(i,j)];
1106 jgs 82 }
1107    
1108     inline
1109     DataArrayView::ValueType::const_reference
1110     DataArrayView::operator()(ValueType::size_type i,
1111     ValueType::size_type j) const
1112     {
1113 jgs 108 return (*m_data)[index(i,j)];
1114 jgs 82 }
1115    
1116     inline
1117     DataArrayView::ValueType::reference
1118 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1119     ValueType::size_type j,
1120     ValueType::size_type k)
1121 jgs 82 {
1122 jgs 108 return (*m_data)[index(i,j,k)];
1123 jgs 82 }
1124    
1125     inline
1126     DataArrayView::ValueType::const_reference
1127 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1128     ValueType::size_type j,
1129     ValueType::size_type k) const
1130 jgs 82 {
1131 jgs 108 return (*m_data)[index(i,j,k)];
1132 jgs 82 }
1133    
1134     inline
1135     DataArrayView::ValueType::reference
1136 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1137     ValueType::size_type j,
1138     ValueType::size_type k,
1139     ValueType::size_type m)
1140 jgs 82 {
1141 jgs 108 return (*m_data)[index(i,j,k,m)];
1142 jgs 82 }
1143    
1144     inline
1145     DataArrayView::ValueType::const_reference
1146 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1147     ValueType::size_type j,
1148     ValueType::size_type k,
1149     ValueType::size_type m) const
1150 jgs 82 {
1151 jgs 108 return (*m_data)[index(i,j,k,m)];
1152 jgs 82 }
1153    
1154     } // end of namespace
1155    
1156     #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26