1 |
/* $Id$ */ |
2 |
|
3 |
/******************************************************* |
4 |
* |
5 |
* Copyright 2003-2007 by ACceSS MNRF |
6 |
* Copyright 2007 by University of Queensland |
7 |
* |
8 |
* http://esscc.uq.edu.au |
9 |
* Primary Business: Queensland, Australia |
10 |
* Licensed under the Open Software License version 3.0 |
11 |
* http://www.opensource.org/licenses/osl-3.0.php |
12 |
* |
13 |
*******************************************************/ |
14 |
|
15 |
#if !defined escript_DataAbstract_20040315_H |
16 |
#define escript_DataAbstract_20040315_H |
17 |
#include "system_dep.h" |
18 |
|
19 |
#include "DataArrayView.h" |
20 |
#include "DataTypes.h" |
21 |
#include "FunctionSpace.h" |
22 |
|
23 |
#include <boost/scoped_ptr.hpp> |
24 |
#include <boost/python/numeric.hpp> |
25 |
|
26 |
#include <string> |
27 |
#include <fstream> |
28 |
|
29 |
namespace escript { |
30 |
|
31 |
/** |
32 |
\brief |
33 |
DataAbstract provides an abstract interface for the class of containers |
34 |
which hold ESyS data. |
35 |
|
36 |
Description: |
37 |
DataAbstract provides an abstract interface for the class of containers |
38 |
which hold ESyS data. The container may be thought of as a 2 dimensional |
39 |
array of data points where one dimension corresponds to the number of samples |
40 |
and the other to the number of data points per sample as defined by the function |
41 |
space associated with each Data object. The data points themselves are arrays of |
42 |
doubles of rank 0-4. |
43 |
*/ |
44 |
|
45 |
class DataAbstract { |
46 |
|
47 |
public: |
48 |
|
49 |
typedef DataTypes::ValueType ValueType; |
50 |
typedef DataTypes::ShapeType ShapeType; |
51 |
|
52 |
/** |
53 |
\brief |
54 |
Constructor for DataAbstract. |
55 |
|
56 |
Description: |
57 |
Constructor for DataAbstract. |
58 |
|
59 |
\param what - Input - A description of what this data represents. |
60 |
*/ |
61 |
ESCRIPT_DLL_API |
62 |
DataAbstract(const FunctionSpace& what); |
63 |
|
64 |
/** |
65 |
\brief |
66 |
Destructor for DataAbstract. |
67 |
*/ |
68 |
ESCRIPT_DLL_API |
69 |
virtual |
70 |
~DataAbstract(); |
71 |
|
72 |
/** |
73 |
\brief |
74 |
Write the data as a string. |
75 |
*/ |
76 |
ESCRIPT_DLL_API |
77 |
virtual |
78 |
std::string |
79 |
toString() const = 0; |
80 |
|
81 |
/** |
82 |
\brief |
83 |
dumps the object into a netCDF file |
84 |
*/ |
85 |
ESCRIPT_DLL_API |
86 |
virtual |
87 |
void |
88 |
dump(const std::string fileName) const; |
89 |
|
90 |
/** |
91 |
\brief |
92 |
Return the number of data points per sample. |
93 |
*/ |
94 |
ESCRIPT_DLL_API |
95 |
int |
96 |
getNumDPPSample() const; |
97 |
|
98 |
/** |
99 |
\brief |
100 |
Return the number of samples. |
101 |
*/ |
102 |
ESCRIPT_DLL_API |
103 |
int |
104 |
getNumSamples() const; |
105 |
|
106 |
/** |
107 |
\brief |
108 |
Return the DataArrayView of the point data. This essentially contains |
109 |
the shape information for each data point although it also may be used |
110 |
to manipulate the point data. |
111 |
*/ |
112 |
ESCRIPT_DLL_API |
113 |
DataArrayView& |
114 |
getPointDataView(); |
115 |
|
116 |
ESCRIPT_DLL_API |
117 |
const DataArrayView& |
118 |
getPointDataView() const; |
119 |
|
120 |
/** |
121 |
\brief |
122 |
Return the shape information for the point data. |
123 |
|
124 |
The omission of a non-constant form is deliberate. |
125 |
*/ |
126 |
ESCRIPT_DLL_API |
127 |
const DataTypes::ShapeType& |
128 |
getShape() const; |
129 |
|
130 |
/** |
131 |
\brief |
132 |
Return the rank information for the point data. |
133 |
*/ |
134 |
ESCRIPT_DLL_API |
135 |
int |
136 |
getRank() const; |
137 |
|
138 |
|
139 |
|
140 |
/** |
141 |
\brief |
142 |
Return the offset for the given sample. This returns the offset for the given |
143 |
point into the container holding the point data. Only really necessary to |
144 |
avoid creating many DataArrayView objects. |
145 |
|
146 |
\param sampleNo - Input - sample number. |
147 |
\param dataPointNo - Input - data point number. |
148 |
*/ |
149 |
ESCRIPT_DLL_API |
150 |
virtual |
151 |
ValueType::size_type |
152 |
getPointOffset(int sampleNo, |
153 |
int dataPointNo) const = 0; |
154 |
|
155 |
/** |
156 |
\brief |
157 |
Return the sample data for the given sample number. |
158 |
*/ |
159 |
ESCRIPT_DLL_API |
160 |
double* |
161 |
getSampleData(ValueType::size_type sampleNo); |
162 |
|
163 |
/** |
164 |
\brief |
165 |
Return the number of doubles stored for this Data object. |
166 |
*/ |
167 |
ESCRIPT_DLL_API |
168 |
virtual |
169 |
ValueType::size_type |
170 |
getLength() const = 0; |
171 |
|
172 |
/** |
173 |
\brief |
174 |
Return the sample data for the given tag key. |
175 |
NB: If the data isn't tagged an exception will be thrown. |
176 |
*/ |
177 |
ESCRIPT_DLL_API |
178 |
virtual |
179 |
double* |
180 |
getSampleDataByTag(int tag); |
181 |
|
182 |
|
183 |
/** |
184 |
\brief |
185 |
Check this and the given RHS operands are compatible. Throws |
186 |
an exception if they aren't. |
187 |
|
188 |
\param right - Input - The right hand side. |
189 |
*/ |
190 |
ESCRIPT_DLL_API |
191 |
void |
192 |
operandCheck(const DataAbstract& right) const; |
193 |
|
194 |
/** |
195 |
\brief |
196 |
Return true if a valid sample point number. |
197 |
*/ |
198 |
ESCRIPT_DLL_API |
199 |
bool |
200 |
validSamplePointNo(int samplePointNo) const; |
201 |
|
202 |
/** |
203 |
\brief |
204 |
Return true if a valid sample number. |
205 |
*/ |
206 |
ESCRIPT_DLL_API |
207 |
bool |
208 |
validSampleNo(int sampleNo) const; |
209 |
|
210 |
/** |
211 |
\brief |
212 |
Return a view into the data for the data point specified. |
213 |
NOTE: Construction of the DataArrayView is a relatively expensive |
214 |
operation. |
215 |
|
216 |
\param sampleNo - Input - the sample number. |
217 |
\param dataPointNo - Input - the data point number. |
218 |
*/ |
219 |
ESCRIPT_DLL_API |
220 |
virtual |
221 |
DataArrayView |
222 |
getDataPoint(int sampleNo, |
223 |
int dataPointNo) = 0; |
224 |
|
225 |
/** |
226 |
\brief |
227 |
Return the function space associated with this Data object. |
228 |
*/ |
229 |
ESCRIPT_DLL_API |
230 |
const |
231 |
FunctionSpace& |
232 |
getFunctionSpace() const; |
233 |
|
234 |
/** |
235 |
\brief |
236 |
Return the given slice from this object. |
237 |
|
238 |
NB: The caller is responsible for managing the object created. |
239 |
*/ |
240 |
ESCRIPT_DLL_API |
241 |
virtual |
242 |
DataAbstract* |
243 |
getSlice(const DataTypes::RegionType& region) const = 0; |
244 |
|
245 |
/** |
246 |
\brief |
247 |
Copy the specified region from the given object. |
248 |
|
249 |
\param value - Input - Data to copy from |
250 |
\param region - Input - Region to copy. |
251 |
*/ |
252 |
ESCRIPT_DLL_API |
253 |
virtual |
254 |
void |
255 |
setSlice(const DataAbstract* value, |
256 |
const DataTypes::RegionType& region) = 0; |
257 |
|
258 |
|
259 |
/** |
260 |
\brief |
261 |
setTaggedValue |
262 |
|
263 |
Description: |
264 |
Assign the given value to the given tag. |
265 |
|
266 |
NB: If the data isn't tagged an exception will be thrown. |
267 |
|
268 |
\param tagKey - Input - Integer key. |
269 |
\param value - Input - Single DataArrayView value to be assigned to the tag. |
270 |
*/ |
271 |
ESCRIPT_DLL_API |
272 |
virtual |
273 |
void |
274 |
setTaggedValue(int tagKey, |
275 |
const DataArrayView& value); |
276 |
|
277 |
|
278 |
/** |
279 |
\brief |
280 |
setTaggedValue |
281 |
|
282 |
Description: |
283 |
Assign the given value to the given tag. |
284 |
|
285 |
NB: If the data isn't tagged an exception will be thrown. |
286 |
|
287 |
\param tagKey - Input - Integer key. |
288 |
\param pointshape - Input - the shape of the value parameter. |
289 |
\param value - Input - |
290 |
*/ |
291 |
ESCRIPT_DLL_API |
292 |
virtual |
293 |
void |
294 |
setTaggedValue(int tagKey, |
295 |
const DataTypes::ShapeType& pointshape, |
296 |
const DataTypes::ValueType& value, |
297 |
int dataOffset=0); |
298 |
|
299 |
|
300 |
|
301 |
/** |
302 |
\brief |
303 |
Archive the underlying data values to the file referenced |
304 |
by ofstream. A count of the number of values expected to be written |
305 |
is provided as a cross-check. |
306 |
|
307 |
The return value indicates success (0) or otherwise (1). |
308 |
*/ |
309 |
ESCRIPT_DLL_API |
310 |
virtual |
311 |
int |
312 |
archiveData(std::ofstream& archiveFile, |
313 |
const ValueType::size_type noValues) const; |
314 |
|
315 |
/** |
316 |
\brief |
317 |
Extract the number of values specified by noValues from the file |
318 |
referenced by ifstream to the underlying data structure. |
319 |
|
320 |
The return value indicates success (0) or otherwise (1). |
321 |
*/ |
322 |
ESCRIPT_DLL_API |
323 |
virtual |
324 |
int |
325 |
extractData(std::ifstream& archiveFile, |
326 |
const ValueType::size_type noValues); |
327 |
|
328 |
/** |
329 |
\brief |
330 |
Copy the numarray object to the data points in this object. |
331 |
|
332 |
Description: |
333 |
Copy the numarray object to the data points in this object. |
334 |
|
335 |
\param value Input - new values for the data points |
336 |
*/ |
337 |
ESCRIPT_DLL_API |
338 |
virtual void |
339 |
copyAll(const boost::python::numeric::array& value); |
340 |
|
341 |
/** |
342 |
\brief |
343 |
Copy a double value to the data point dataPointNo of sample sampleNo in this object. |
344 |
|
345 |
Description: |
346 |
Copy a double value to the data point dataPointNo of sample sampleNo in this object. |
347 |
|
348 |
\param sampleNo Input - sample number |
349 |
\param dataPointNo Input - data point of the sample |
350 |
\param value Input - new values for the data point |
351 |
*/ |
352 |
ESCRIPT_DLL_API |
353 |
virtual void |
354 |
copyToDataPoint(const int sampleNo, const int dataPointNo, const double value); |
355 |
|
356 |
/** |
357 |
\brief |
358 |
Copy the numarray object to the data point dataPointNo of sample sampleNo in this object. |
359 |
|
360 |
Description: |
361 |
Copy the numarray object to the data point dataPointNo of sample sampleNo in this object. |
362 |
|
363 |
\param sampleNo Input - sample number |
364 |
\param dataPointNo Input - data point of the sample |
365 |
\param value Input - new values for the data point |
366 |
*/ |
367 |
ESCRIPT_DLL_API |
368 |
virtual void |
369 |
copyToDataPoint(const int sampleNo, const int dataPointNo, const boost::python::numeric::array& value); |
370 |
|
371 |
|
372 |
/** |
373 |
\brief |
374 |
Return the tag number associated with the given data-point number. |
375 |
|
376 |
If the object cannot be referenced by tag numbers, an exception |
377 |
will be thrown. |
378 |
*/ |
379 |
ESCRIPT_DLL_API |
380 |
virtual |
381 |
int |
382 |
getTagNumber(int dpno); |
383 |
|
384 |
/** |
385 |
\brief |
386 |
Computes a symmetric matrix (A + AT) / 2 |
387 |
|
388 |
\param ev - Output - a symmetric matrix |
389 |
|
390 |
*/ |
391 |
ESCRIPT_DLL_API |
392 |
virtual void |
393 |
symmetric(DataAbstract* ev); |
394 |
|
395 |
/** |
396 |
\brief |
397 |
Computes a nonsymmetric matrix (A - AT) / 2 |
398 |
|
399 |
\param ev - Output - a nonsymmetric matrix |
400 |
|
401 |
*/ |
402 |
ESCRIPT_DLL_API |
403 |
virtual void |
404 |
nonsymmetric(DataAbstract* ev); |
405 |
|
406 |
/** |
407 |
\brief |
408 |
Computes the trace of a matrix |
409 |
|
410 |
\param ev - Output - the trace of a matrix |
411 |
|
412 |
*/ |
413 |
ESCRIPT_DLL_API |
414 |
virtual void |
415 |
trace(DataAbstract* ev, int axis_offset); |
416 |
|
417 |
/** |
418 |
\brief |
419 |
Transpose each data point of this Data object around the given axis. |
420 |
|
421 |
\param ev - Output - the transpose of a matrix |
422 |
|
423 |
*/ |
424 |
ESCRIPT_DLL_API |
425 |
virtual void |
426 |
transpose(DataAbstract* ev, int axis_offset); |
427 |
|
428 |
/** |
429 |
\brief |
430 |
swaps components axis0 and axis1 |
431 |
|
432 |
\param ev - Output - swapped components |
433 |
|
434 |
*/ |
435 |
ESCRIPT_DLL_API |
436 |
virtual void |
437 |
swapaxes(DataAbstract* ev, int axis0, int axis1); |
438 |
/** |
439 |
\brief |
440 |
solves the eigenvalue problem this*V=ev*V for the eigenvalues ev |
441 |
|
442 |
\param ev - Output - eigenvalues in increasing order at each data point |
443 |
|
444 |
*/ |
445 |
ESCRIPT_DLL_API |
446 |
virtual void |
447 |
eigenvalues(DataAbstract* ev); |
448 |
|
449 |
/** |
450 |
\brief |
451 |
sets values to zero |
452 |
|
453 |
*/ |
454 |
ESCRIPT_DLL_API |
455 |
virtual void |
456 |
setToZero(); |
457 |
|
458 |
/** |
459 |
\brief |
460 |
solves the eigenvalue problem this*V=ev*V for the eigenvalues ev and eigenvectors V |
461 |
|
462 |
\param ev - Output - eigenvalues in increasing order at each data point |
463 |
\param V - Output - corresponding eigenvectors. They are normalized such that their length is one |
464 |
and the first nonzero component is positive. |
465 |
\param tol - Input - eigenvalue with relative distance tol are treated as equal. |
466 |
|
467 |
*/ |
468 |
|
469 |
ESCRIPT_DLL_API |
470 |
virtual void |
471 |
eigenvalues_and_eigenvectors(DataAbstract* ev,DataAbstract* V,const double tol=1.e-13); |
472 |
|
473 |
/** |
474 |
\brief |
475 |
reorders data sample ordered by reference_ids to the ordering of the functions space |
476 |
|
477 |
\param reference_ids - Input - reference_ids used for current ordering |
478 |
*/ |
479 |
ESCRIPT_DLL_API |
480 |
virtual void |
481 |
reorderByReferenceIDs(int *reference_ids); |
482 |
|
483 |
protected: |
484 |
|
485 |
/** |
486 |
\brief |
487 |
Set the pointDataView DataArrayView associated with this object. |
488 |
|
489 |
\param input - Input - The point data view. DataAbstract takes ownership |
490 |
of the DataArrayView provided. It will delete it when it is destructed. |
491 |
*/ |
492 |
ESCRIPT_DLL_API |
493 |
void |
494 |
setPointDataView(const DataArrayView& input); |
495 |
|
496 |
ESCRIPT_DLL_API |
497 |
void |
498 |
resetPointDataView(); |
499 |
|
500 |
|
501 |
|
502 |
/** |
503 |
\brief |
504 |
Set the shape of the object and update related properties. |
505 |
|
506 |
Note: This is only intended as a helper for constructors. |
507 |
Do not call it at any other time. Especially not to change the shape of an |
508 |
existing DataAbstract. |
509 |
The goal is for this method to be removed once DataArrayView is gone. |
510 |
\param s - shape for this data |
511 |
*/ |
512 |
ESCRIPT_DLL_API |
513 |
void |
514 |
setShape(const DataTypes::ShapeType& s); |
515 |
|
516 |
/** |
517 |
\brief |
518 |
Return the number of values in the shape for this object. |
519 |
*/ |
520 |
ESCRIPT_DLL_API |
521 |
int |
522 |
getNoValues() const; |
523 |
|
524 |
|
525 |
|
526 |
private: |
527 |
|
528 |
// |
529 |
// The number of samples in this Data object. |
530 |
// This is derived directly from the FunctionSpace. |
531 |
int m_noSamples; |
532 |
|
533 |
// |
534 |
// The number of data points per sample in this Data object. |
535 |
// This is derived directly from the FunctionSpace. |
536 |
int m_noDataPointsPerSample; |
537 |
|
538 |
// |
539 |
// The DataArrayView of the data array associated with this object. |
540 |
// The data array is defined only in child classes of this class, it |
541 |
// is not defined in this abstract parent class. |
542 |
boost::scoped_ptr<DataArrayView> m_pointDataView; |
543 |
|
544 |
// |
545 |
// A FunctionSpace which provides a description of the data associated |
546 |
// with this Data object. |
547 |
FunctionSpace m_functionSpace; |
548 |
|
549 |
// |
550 |
// The shape of the points stored in this view |
551 |
DataTypes::ShapeType m_shape; |
552 |
|
553 |
// |
554 |
// The number of values in each point |
555 |
int m_novalues; |
556 |
|
557 |
// |
558 |
// The rank of the points stored in this view |
559 |
int m_rank; |
560 |
|
561 |
}; |
562 |
|
563 |
inline |
564 |
bool |
565 |
DataAbstract::validSamplePointNo(int samplePointNo) const |
566 |
{ |
567 |
return ((0 <= samplePointNo) && (samplePointNo < m_noDataPointsPerSample)); |
568 |
} |
569 |
|
570 |
inline |
571 |
bool |
572 |
DataAbstract::validSampleNo(int sampleNo) const |
573 |
{ |
574 |
return ((0 <= sampleNo) && (sampleNo < m_noSamples)); |
575 |
} |
576 |
|
577 |
inline |
578 |
DataAbstract::ValueType::value_type* |
579 |
DataAbstract::getSampleData(ValueType::size_type sampleNo) |
580 |
{ |
581 |
return &(m_pointDataView->getData(getPointOffset(sampleNo,0))); |
582 |
} |
583 |
|
584 |
inline |
585 |
int |
586 |
DataAbstract::getNumDPPSample() const |
587 |
{ |
588 |
return m_noDataPointsPerSample; |
589 |
} |
590 |
|
591 |
inline |
592 |
int |
593 |
DataAbstract::getNumSamples() const |
594 |
{ |
595 |
return m_noSamples; |
596 |
} |
597 |
|
598 |
inline |
599 |
const |
600 |
FunctionSpace& |
601 |
DataAbstract::getFunctionSpace() const |
602 |
{ |
603 |
return m_functionSpace; |
604 |
} |
605 |
|
606 |
inline |
607 |
const |
608 |
DataArrayView& |
609 |
DataAbstract::getPointDataView() const |
610 |
{ |
611 |
return *(m_pointDataView.get()); |
612 |
} |
613 |
|
614 |
inline |
615 |
DataArrayView& |
616 |
DataAbstract::getPointDataView() |
617 |
{ |
618 |
return *(m_pointDataView.get()); |
619 |
} |
620 |
|
621 |
inline |
622 |
const DataTypes::ShapeType& |
623 |
DataAbstract::getShape() const |
624 |
{ |
625 |
return m_shape; |
626 |
} |
627 |
|
628 |
inline |
629 |
int |
630 |
DataAbstract::getRank() const |
631 |
{ |
632 |
return m_rank; |
633 |
} |
634 |
|
635 |
inline |
636 |
int |
637 |
DataAbstract::getNoValues() const |
638 |
{ |
639 |
return m_novalues; |
640 |
} |
641 |
|
642 |
} // end of namespace |
643 |
|
644 |
#endif |