thomas.forbriger committed Dec 20, 2002 1 /*! \file libaff/README  thomas.forbriger committed Dec 06, 2002 2  * \brief C++ containers for numbers (libaff)  thomas.forbriger committed Dec 06, 2002 3 4 5  * * ---------------------------------------------------------------------------- *  thomas.forbriger committed Jan 02, 2003 6  * $Id: README,v 1.18 2003-01-02 11:50:54 forbrig Exp$  thomas.forbriger committed Dec 06, 2002 7 8 9  * * Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt) *  thomas.forbriger committed Dec 06, 2002 10  * C++ containers for numbers (libaff)  thomas.forbriger committed Dec 06, 2002 11 12  * * This file contains:  thomas.forbriger committed Dec 06, 2002 13  * - documentation of namespace aff  thomas.forbriger committed Dec 06, 2002 14 15  * - mainpage text * - documentation for pages:  thomas.forbriger committed Dec 08, 2002 16  * - \ref page_design  thomas.forbriger committed Dec 06, 2002 17 18  * - \ref page_using * - \ref page_notes  thomas.forbriger committed Dec 08, 2002 19  * - \ref page_naming  thomas.forbriger committed Dec 06, 2002 20 21  * * REVISIONS and CHANGES  thomas.forbriger committed Dec 06, 2002 22  * - 06/12/2002 V1.0 Thomas Forbriger (copied from libcontxx)  thomas.forbriger committed Dec 20, 2002 23 24 25 26 27  * - 20/12/2002 V1.1 (thof) * - complete revision of this file * - there are major gaps in * -# \ref sec_design_multidimensional * -# \ref page_using  thomas.forbriger committed Dec 29, 2002 28 29 30 31 32  * - 28/12/2002 V1.2 (thof) * - new term for containers of const elements * - added documentation regarding the concept of * const correctness * - added documentation regarding member typedefs  thomas.forbriger committed Dec 29, 2002 33 34 35 36 37 38 39  * - 29/12/2002 V1.3 (thof) * - added section about replicated shared heap base * class (\ref sec_design_replicated) * - added section about sparse interface * (\ref sec_design_interface_sparse) * - added section about accessing internals * (\ref sec_design_interface_internals)  thomas.forbriger committed Dec 29, 2002 40 41 42  * - reflect changes to Subarray and Slice * - tell about class hierarchies and member data vs. * inheritance  thomas.forbriger committed Dec 06, 2002 43 44 45 46 47 48 49  * * ============================================================================ */ /*! \brief Root namespace of library This namespace contains all modules of the library  thomas.forbriger committed Dec 20, 2002 50 51 52  (see \ref sec_main_modules). Here you should find all components, the user needs to work with this library.  thomas.forbriger committed Dec 06, 2002 53  When working with the binary version of the library, you have to use  thomas.forbriger committed Dec 20, 2002 54  aff::prebuilt in place of aff (see \ref sec_design_binary).  thomas.forbriger committed Dec 06, 2002 55  */  thomas.forbriger committed Dec 08, 2002 56 57 namespace aff { } // namespace aff  thomas.forbriger committed Dec 06, 2002 58 59 60 61 62 63  /*======================================================================*/ /*! \mainpage \author Thomas Forbriger  thomas.forbriger committed Dec 06, 2002 64 65 66 \author Wolfgang Friederich \since December 2002 \date December 2002  thomas.forbriger committed Dec 06, 2002 67 \version V1.0  thomas.forbriger committed Jan 02, 2003 68 $Id: README,v 1.18 2003-01-02 11:50:54 forbrig Exp$  thomas.forbriger committed Dec 06, 2002 69 70  Contents of this page:  thomas.forbriger committed Dec 08, 2002 71  - \ref sec_main_aims  thomas.forbriger committed Dec 06, 2002 72  - \ref sec_main_modules  thomas.forbriger committed Dec 20, 2002 73 74  - \ref sec_main_modules_basic - \ref sec_main_modules_extended  thomas.forbriger committed Dec 20, 2002 75  - \ref sec_main_peculiar  thomas.forbriger committed Dec 06, 2002 76 77  Additional information:  thomas.forbriger committed Dec 08, 2002 78 79 80 81  - \ref page_design - \ref page_using - \ref page_notes - \ref page_naming  thomas.forbriger committed Dec 06, 2002 82  - \ref page_representation  thomas.forbriger committed Dec 23, 2002 83  - \ref page_fortran  thomas.forbriger committed Dec 17, 2002 84  - \ref page_changelog  thomas.forbriger committed Dec 19, 2002 85  - \ref page_project_status  thomas.forbriger committed Dec 08, 2002 86 87 88 89 90 91 92  \section sec_main_aims Aims of the library The AFF (Array of Friederich and Forbriger) is a lightweight class library. It offers a simple and easy to use container for numbers as is necessary in numerical code. The offered array always has a rectangular strided layout, reference semantics (through counted references) and a Fortran layout in  thomas.forbriger committed Dec 20, 2002 93  memory. The interface is intentionally kept sparse to keep compilation times  thomas.forbriger committed Dec 08, 2002 94 95 96 97 98 99 100  small. The array itself is meant to be used to pass numbers from one program module to the other. If you want to exploit the power of expression templates, pass the array contents to something like Blitz++. \sa \ref sec_notes_need /*----------------------------------------------------------------------*/  thomas.forbriger committed Dec 06, 2002 101 102 103  \section sec_main_modules Modules of the library  thomas.forbriger committed Dec 08, 2002 104 105  The main module is the array class aff::Array. It provides basic functionality through its interface. See the explanation there.  thomas.forbriger committed Dec 20, 2002 106 107  It is presented in aff/array.h and aff/binarray.h (see also \ref sec_design_binary).  thomas.forbriger committed Dec 29, 2002 108  The object code is placed in libaff.a.  thomas.forbriger committed Dec 20, 2002 109 110 111 112 113  \subsection sec_main_modules_basic Basic array modules By including aff/array.h you will get access to the following modules:  thomas.forbriger committed Dec 29, 2002 114  -# aff::Array is the main array interface (see example tests/arraytest.cc).  thomas.forbriger committed Dec 20, 2002 115  -# aff::Strided is the shape of a strided Fortran array and defines the  thomas.forbriger committed Dec 29, 2002 116 117  memory layout of aff::Array objects (see example tests/shapetest.cc).  thomas.forbriger committed Dec 20, 2002 118 119 120  -# aff::SharedHeap is the representation used by aff::Array. It holds the data in memory and provides an interface to it. This interface may be passed separately from the array object (see also  thomas.forbriger committed Dec 29, 2002 121  "\ref page_representation" and example tests/reprtest.cc).  thomas.forbriger committed Dec 20, 2002 122 123  -# aff::SimpleRigidArray is a linear array with size fixed at compile-time. There are several inline functions defined for operations with  thomas.forbriger committed Dec 29, 2002 124 125  this array class (see example tests/simplearraytest.cc). -# aff::Exception is the exception base class used in the library.  thomas.forbriger committed Dec 20, 2002 126  -# aff::AllocException is the exception that indicated a failed memory  thomas.forbriger committed Dec 20, 2002 127  allocation(see also "\ref group_error").  thomas.forbriger committed Dec 20, 2002 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142  It additionally offers the following type definitions: -# aff::Tsubscript is the type of subscripts to arrays (positive and negative). -# aff::Tsize is the type of size values (non-negative). -# aff::Tdim is the type of the dimension index (small, non-negative). \subsection sec_main_modules_extended Extensions The library provides some additional modules. You need only include the header file of those modules that you really want to use in addition to the basic aff::Array functionality. These additional modules are:  thomas.forbriger committed Dec 23, 2002 143  -# aff::Shaper presented in aff/shaper.h and used to pass Fortran layouts  thomas.forbriger committed Dec 29, 2002 144  to array constructors (see example tests/shapetest.cc).  thomas.forbriger committed Dec 20, 2002 145 146 147  -# aff::Series presented in aff/series.h which is used to interface linear sequences of data (like time series or Fourier spectra). -# aff::Iterator presented in aff/iterator.h which is an iterator interface  thomas.forbriger committed Dec 29, 2002 148 149  to containers like aff::Array or aff::Series (see example tests/helpertest.cc).  thomas.forbriger committed Dec 20, 2002 150 151 152  -# aff::Range presented in aff/lib/range.h which is usefull where ever you need to deal with numerical ranges (calculate with them, find the smallest in a set, etc.).  thomas.forbriger committed Dec 29, 2002 153  -# aff::subarray presented in aff/subarray.h to conveniently create  thomas.forbriger committed Dec 29, 2002 154 155  subarrays from aff::Array objects (see example tests/helpertest.cc).  thomas.forbriger committed Dec 29, 2002 156  -# aff::slice presented in aff/slice.h to conveniently create  thomas.forbriger committed Dec 29, 2002 157 158  slices from aff::Array objects (see example tests/helpertest.cc).  thomas.forbriger committed Dec 23, 2002 159 160  -# aff::FortranArray and its associate aff::util::FortranShape are presented in aff/fortranshape.h. They calculate a Fortran 77 array  thomas.forbriger committed Dec 29, 2002 161 162  layout (leading dimensions) from a given AFF array (see example tests/f77test.cc).  thomas.forbriger committed Dec 20, 2002 163 164  -# aff::dump and its associates, presented in aff/dump.h. They are used to dump shape or contents of containers and are thus useful when  thomas.forbriger committed Dec 20, 2002 165  debugging your code. See also "\ref group_helpers".  thomas.forbriger committed Dec 20, 2002 166   thomas.forbriger committed Dec 08, 2002 167   thomas.forbriger committed Dec 20, 2002 168 169  In the \ref sec_design_binary "binary version" some of the modules (aff::Array and aff::SharedHeap) are presented in namespace aff::prebuilt.  thomas.forbriger committed Dec 06, 2002 170   thomas.forbriger committed Dec 08, 2002 171  \sa \ref sec_design_namespaces  thomas.forbriger committed Dec 29, 2002 172  \sa \ref sec_naming_files  thomas.forbriger committed Dec 06, 2002 173 174 175  /*----------------------------------------------------------------------*/  thomas.forbriger committed Dec 20, 2002 176 \section sec_main_peculiar Peculiarities  thomas.forbriger committed Dec 06, 2002 177   thomas.forbriger committed Dec 29, 2002 178 179 180 181 182 183 \par Containers use counted references All containers (e.g. aff::Array, aff::Series) use counted references to access global memory. Assigning one container object to another just assigns the reference. Both will use the same data in memory afterwards. See also "\ref page_representation".  thomas.forbriger committed Dec 20, 2002 184 185 186 187 \par Const-correctness for array elements In this library we follow provide functionality to write const-correct code with regard to the array container and with regard to its element values. See also "\ref sec_design_const".  thomas.forbriger committed Dec 06, 2002 188   thomas.forbriger committed Dec 20, 2002 189 190 191 192 193 194 \par Multidimensional arrays Every aff::Array of this class has aff::Strided::Mmax_dimen dimensions. Construction and access for lower dimensionality is provided. In the case of using less dimensions, the size of the unused dimensions is 1 by default and its index is inherently set to the first index. See also "\ref sec_design_multidimensional".  thomas.forbriger committed Dec 06, 2002 195   thomas.forbriger committed Dec 08, 2002 196 */  thomas.forbriger committed Dec 06, 2002 197   thomas.forbriger committed Dec 08, 2002 198 /*======================================================================*/  thomas.forbriger committed Dec 06, 2002 199   thomas.forbriger committed Dec 08, 2002 200 /*! \page page_design Design decisions  thomas.forbriger committed Dec 06, 2002 201   thomas.forbriger committed Dec 08, 2002 202  Contents of this page:  thomas.forbriger committed Dec 29, 2002 203  - \ref sec_design_interface  thomas.forbriger committed Dec 29, 2002 204 205 206 207  - \ref sec_design_interface_sparse - \ref sec_design_interface_typedef - \ref sec_design_interface_internals - \ref sec_design_hierarchy  thomas.forbriger committed Dec 29, 2002 208  - \ref sec_design_replicated  thomas.forbriger committed Dec 29, 2002 209 210 211  - \ref sec_design_replicated_fact - \ref sec_design_replicated_problem - \ref sec_design_replicated_solution  thomas.forbriger committed Dec 08, 2002 212 213 214 215 216  - \ref sec_design_copy - \ref sec_design_namespaces - \ref sec_design_binary - \ref sec_design_multidimensional - \ref sec_design_const  thomas.forbriger committed Dec 29, 2002 217 218 219 220  - \ref sec_design_const_problem - \ref sec_design_const_approach - \ref sec_design_const_alternatives - \ref sec_design_const_general  thomas.forbriger committed Dec 06, 2002 221   thomas.forbriger committed Dec 29, 2002 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 \section sec_design_interface Common interface concepts \subsection sec_design_interface_sparse Sparse interfaces The class library is intended to be a light-weight library. This means it should offer basic functionality in terms of multidimensional containers with counted references (and not more in first place). We do not like to include a tremendous amount of code for specialized concepts (like subranges or expression templates in Blitz++) each time we just need a small array. Thus the header files providing array declarations (aff/array.h and the files included therein) should be as sparse as possible. All extra functionality like iterators (aff::Iterator presented in aff/iterator.h) or slices (aff::Slice presented in aff/slice.h) should be external to the aff::Array class. This allows us to load their definitions only where needed. However, this approach requires that the internals of aff::Array are exposed to the outside through appropriate functions (see "\ref sec_design_interface_internals").  thomas.forbriger committed Dec 29, 2002 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294  \subsection sec_design_interface_typedef Member typedefs Class templates like aff::Iterator may be used with any container class, that provides an appropriate interface. This interface convention concerns the access to the type of related objects. I will explain by example: We use an iterator \c i which was declared \code aff::Iterator i \endcode for a container of type \c Cont, it expects to find a corresponding container class that promises constness of the elements through \code Cont::Tcontainer_of_const \endcode or short \code Cont::Tcoc \endcode For aff::ConstArray the type aff::ConstArray::Tcoc is just the class itself. However aff::Array::Tcoc gives an aff::ConstArray. \sa aff::SharedHeap::Tcontainer_of_const \sa aff::ConstSharedHeap::Tcontainer_of_const \sa aff::Array::Tcontainer_of_const \sa aff::ConstArray::Tcontainer_of_const \sa aff::Series::Tcontainer_of_const \sa aff::ConstSeries::Tcontainer_of_const In the same way we may access the appropriate element type through \code Cont::Tvalue \endcode which is \c T for aff::Array and \c const \T for aff::ConstArray. However a \code Cont::Tconst_value \endcode will always provide a type with const qualifier. \sa aff::Array::Tvalue \sa aff::Array::Tconst_value \sa aff::ConstArray::Tvalue \sa aff::ConstArray::Tconst_value \sa aff::Series::Tvalue \sa aff::Series::Tconst_value \sa aff::ConstSeries::Tvalue \sa aff::ConstSeries::Tconst_value In the same way we may access the type of the appropriate representation (although the base class of any container is always an aff::SharedHeap) by \code Cont::Trepresentation \endcode \sa aff::Array::Trepresentation \sa aff::ConstArray::Trepresentation \sa aff::Series::Trepresentation \sa aff::ConstSeries::Trepresentation \b Notice: Using these typedefs (and also the typedefs for the shape class, etc.) improves the maintainability of your code. Think of using the \$HOME variable in shell scripts. Once the name of your home directory changes, you need not modify all your shell scripts. Now consider one day your shape class might be renamed...  thomas.forbriger committed Dec 29, 2002 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 \subsection sec_design_interface_internals Accessing internals Providing extended functionality outside of aff::Array (see "\ref sec_design_interface_sparse") requires, that aff::Array, aff::ConstArray, aff::Series, and aff::ConstSeries expose some of their internals. This concerns the underlying shape as well as the represented data. aff::ConstArray and aff::ConstSeries provide a read-only reference to the data (i.e. an aff::ConstSharedHeap object) through their member-functions aff::ConstArray::representation and aff::ConstSeries::representation, respectively. In the same way aff::Array and aff::Series return an aff::SharedHeap through their representation member function. All of them return a copy of their shape through the member functions aff::Array::shape, aff::ConstArray::shape, aff::Series::shape, and aff::ConstSeries::shape, respectively. The type of the appropriate shape is available through a member typedef ( see "\ref sec_design_interface_typedef"). In return all containers provide a constructor that takes a representation and a shape object and checks for their consistency. /*----------------------------------------------------------------------*/
 thomas.forbriger committed Dec 29, 2002 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 \section sec_design_hierarchy Class hierarchy: member data vs. inheritance Containers like aff::Array rely on functionality provided by other classes. They are shapes like aff::Strided and memory representations like aff::SharedHeap (see "\ref page_representation"). \par An array isn't a shape. Thus it would look like better design to use shapes as member data. We prefer, \b however, to derive privately from the shape classes. This hides them from the outside (apart from explicit access - see "\ref sec_design_interface_internals"). At the same time we make use of using declarations to provide access to member functions like aff::Strided::size() that make also sense as a member of aff::Array. \par An array is some kind of memory representation. Thus it would look like proper design to derive an array from a representation class. We prefer, \b however, to use the memory representation as a private member. We think of the representation as an individual and independent object that can be passed (e.g.) from an aff::Array to and aff::Series. Also due to the replication of the representation in aff::Array (see "\ref sec_design_replicated") and the distinction between containers that allow data modification and containers that allow only read access this leads to a clearer design. This is reflected by the conciseness of the array constructors. Use the representation class as member data should introduce no runtime overhead. The full class specification including member data is available at compile-time. This should enable compilers to do excessive inlining. /*----------------------------------------------------------------------*/
\section sec_design_replicated Replicated ConstSharedHeap  thomas.forbriger committed Dec 29, 2002 359 360  \subsection sec_design_replicated_fact Design decision  thomas.forbriger committed Dec 29, 2002 361 362 363 364 365 366 367 368 369  aff::Array has a member of type aff::SharedHeap (which is exposed to the outside through aff::Array::representation), which itself inherits from aff::ConstSharedHeap. At the same time aff::ConstArray has a member of type aff::Array and inherits itself from aff::ConstSharedHeap (which is exposed to the outside through aff::ConstArray::representation). Thus the class aff::ConstSharedHeap is replicated in aff::Array and it is not replicated by deriving from virtual base classes a virtual base class.  thomas.forbriger committed Dec 29, 2002 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425  The same applies to aff::Series and aff::ConstSeries. \subsection sec_design_replicated_problem Where is the problem? Having an array object \c a declared \code aff::Array a; \endcode where \c T is any type, we want to pass this object to a function that promises constness of the elements (see "\ref sec_design_const"). The function is thus declared \code void func(const aff::ConstArray&); \endcode and we want to use it like \code func(a) \endcode Consequently we must offer a way to convert an \code aff::Array& \endcode to an \code aff::ConstArray& \endcode implicitely. This is done by deriving aff::Array publicly from aff::ConstArray. The memory representation is needed by both, aff::Array and its base class. Hence aff::ConstArray has to inherit from the representation. It would be natural for aff::ConstArray to inherit from aff::ConstSharedHeap only. However, since the derived aff::Array needs full access to an aff::SharedHeap (to expose the representation to the outside), we might tend to derive aff::ConstArray from aff::SharedHeap privately, allowing only read access and conversion to aff::ConstSharedHeap. Why is this a problem? Consider the inside of the above function. We might know, that the columns of the passed array contain seismogram waveforms. And we might like to access them in an appropriate way (i.e. through an interface that provides waveform operations), though just reading - not modifying - the data. Then we would like to code something like \code template void func(const aff::ConstArray& a) { // cycle all seismograms for (Tsubscript iseis=a.f(1); iseis<=a.l(1); iseis++) { // extract shape aff::Strided shape(a.shape()); // collapse to waveform iseis shape.collapse(1,iseis); // create a time series aff::ConstSeries waveform(a.representation(), shape.size(), shape.first_offset()); // operate on time series (e.g. recursive filter) some_waveform_operation(waveform); } } \endcode The above example requires that we can construct an aff::ConstSeries from an aff::ConstSharedHeap (which is returned by aff::ConstArray::representation). The same problem appears together with aff::ConstArray, when creating a subarray or slice from an aff::ConstArray  thomas.forbriger committed Jan 02, 2003 426  with aff::subarray or aff::slice and aff::ConstArray itself knowing nothing  thomas.forbriger committed Dec 29, 2002 427 428 429 430 431  about slices, etc. Constructing aff::ConstArray from an aff::ConstSharedHeap sounds a natural operation. However, aff::ConstArray will ask for an aff::SharedHeap, if we derive from aff::SharedHeap (as sketched above). Conclusion: aff::ConstArray  thomas.forbriger committed Dec 29, 2002 432 433  must use an aff::ConstSharedHeap only. At the same time we must hold the full aff::SharedHeap together with the aff::Array object, since this must  thomas.forbriger committed Dec 29, 2002 434 435 436 437 438  return an aff::SharedHeap through aff::Array::representation to allow the above operation (accessing data through aff::Series or constructing a slice - see "\ref sec_design_interface_sparse"). \subsection sec_design_replicated_solution Solution  thomas.forbriger committed Dec 29, 2002 439 440 441 442  The most convincing solution (IMHO) to this problem is to use an (additional) member of type aff::SharedHeap in aff::Array which derives aff::ConstArray. In consequence aff::ConstSharedHeap is then a replicated within  thomas.forbriger committed Dec 29, 2002 443 444 445 446 447 448 449 450 451 452 453 454 455  aff::Array. For a proper design we might consider to make aff::ConstSharedHeap a virtual base, thus avoiding member data duplication. This would, however, introduce an extra level of indirection (additional to the indirection when accessing the heap data through the pointer to the aff::util::SHeap struct in aff::ConstSharedHeap). On the other hand, fully replicating the base aff::ConstSharedHeap just adds one member data pointer (the pointer to the aff::util::SHeap struct) to the data block in aff::Array (which already contains many bytes from the aff::Strided base). This overhead is not considered significant. \b But \b notice: We now must take care to synchronize the aff::SharedHeap base of aff::Array and the aff::ConstSharedHeap base of aff::ConstArray during construction. This is no major concern, but it is error-prone to some  thomas.forbriger committed Dec 29, 2002 456 457  degree. It is, however, much easier to keep them synchronous when using member data instead if inheritance.  thomas.forbriger committed Dec 29, 2002 458   thomas.forbriger committed Dec 29, 2002 459 460 /*----------------------------------------------------------------------*/  thomas.forbriger committed Dec 29, 2002 461 
 thomas.forbriger committed Dec 08, 2002 462 463 464 465 466 467 468 469 470 \section sec_design_copy Copy constructor and copy operator Usually we would expect the copy operator and the copy constructor to have the same semantics. Here the copy constructor of aff::Array must have reference semantics (it does a shallow copy). This is necessary to allow arrays as return values from functions. In this case the copy constructor is automatically invoked. Reference semantics ensure a minimal overhead. in terms of memory usage and execution time.  thomas.forbriger committed Dec 20, 2002 471 472  In the case of the copy (assignment) operator things are less clear: If we define the  thomas.forbriger committed Dec 08, 2002 473  copy operator to have reference semantics, it has the same behaviour as the  thomas.forbriger committed Dec 20, 2002 474  copy constructor. That is what we usually would expect. An expression like  thomas.forbriger committed Dec 06, 2002 475  \code  thomas.forbriger committed Dec 08, 2002 476  A=B;  thomas.forbriger committed Dec 06, 2002 477  \endcode  thomas.forbriger committed Dec 08, 2002 478 479 480 481  means that array \c A drops its reference to the memory location it was pointing to and forgets its previous shape. Following this statement array \c A will refer to the same memory location as array \c B and will have the same shape. Both are indistinguishable.  thomas.forbriger committed Dec 06, 2002 482   thomas.forbriger committed Dec 20, 2002 483 484 485  However, in many cases (most cases?) we will use the copy (assignment) operator in the sense of a mathematical equation. This may read like  thomas.forbriger committed Dec 06, 2002 486  \code  thomas.forbriger committed Dec 08, 2002 487  A=B+C;  thomas.forbriger committed Dec 06, 2002 488  \endcode  thomas.forbriger committed Dec 08, 2002 489  although expressions like this are not yet supported by the library  thomas.forbriger committed Dec 20, 2002 490  features. In this case we do not mean that \c A should drop it reference.  thomas.forbriger committed Dec 08, 2002 491 492 493  \c A may refer to an array in memory which is also referred by other array instances. And we want these values to be set to the result of the operation \c B + \c C. In that case the copy operator should have deep copy semantics.  thomas.forbriger committed Dec 06, 2002 494   thomas.forbriger committed Dec 20, 2002 495 496 497  \par Design decision The classes aff::Array and aff::Series provide copy (assignment) operators with shallow copy semantics.  thomas.forbriger committed Dec 29, 2002 498 499  The automatically created copy constructor and copy operator do just right for this.  thomas.forbriger committed Dec 20, 2002 500 501 502 503  This is sensible, because we are not offering mathematical array operations. This operations may be delegated to a wrapper class in the future, which then also may provide expression templates and an appropriate assignment operator.  thomas.forbriger committed Dec 06, 2002 504 505 506  /*----------------------------------------------------------------------*/  thomas.forbriger committed Dec 29, 2002 507 
 thomas.forbriger committed Dec 08, 2002 508 \section sec_design_namespaces Namespaces  thomas.forbriger committed Dec 06, 2002 509   thomas.forbriger committed Dec 08, 2002 510  We group all code in two namespaces. Major modules which will be accessed by  thomas.forbriger committed Dec 20, 2002 511 512 513 514 515 516 517 518 519 520 521  the user are placed in namepsace aff. Modules meant to be used internally are placed in aff::util. Use directives like \code using namespace aff; \endcode or \code using aff::Array; \endcode for convenient access.  thomas.forbriger committed Dec 06, 2002 522 523 524  /*----------------------------------------------------------------------*/  thomas.forbriger committed Dec 29, 2002 525 
 thomas.forbriger committed Dec 08, 2002 526 \section sec_design_binary Binary library  thomas.forbriger committed Dec 06, 2002 527 528 529  We provide a binary version of the library. It contains a set of prebuilt class objects. Using this version and linking against the binary library  thomas.forbriger committed Dec 08, 2002 530  libaff.a should reduce compilation times in comparison to complete  thomas.forbriger committed Dec 06, 2002 531 532 533 534 535 536 537  template evaluation. This will become more significant the more code is factored out to separate definition headers. This approach offers no improvement with inlined code (which we use extensively in array access functions). To use the binary version you should include binarry.h in place of array.h  thomas.forbriger committed Dec 20, 2002 538 539  You will find modules aff::Array and aff::SharedHeap in aff::prebuilt that are in aff in the full-template version.  thomas.forbriger committed Dec 06, 2002 540 541 542 543  \sa tests/binarraytest.cc \sa binarray.h  thomas.forbriger committed Dec 08, 2002 544 545  The inclusion of header files is controlled by a set of preprocessor macros. \sa AFF_PREBUILT  thomas.forbriger committed Dec 10, 2002 546  \sa AFF_INDEXCHECK  thomas.forbriger committed Dec 08, 2002 547 548 549  \sa AFF_NO_DEFINITIONS \sa AFF_COMPILING_LIBRARY \sa DOXYGEN_MUST_SKIP_THIS  thomas.forbriger committed Dec 06, 2002 550   thomas.forbriger committed Dec 20, 2002 551 552 553 554 555 556 557 \note Since we reduced to number of template parameters significantly in this approach, many parts of code have already been factored out to separate files that are compiled into the binary libaff.a. The approach of explicitly instantiated class templates is not supported so far. It is, however, prepared in the structure of header files and may be activated in the future. \date 20/12/2002  thomas.forbriger committed Dec 06, 2002 558   thomas.forbriger committed Dec 08, 2002 559 /*----------------------------------------------------------------------*/  thomas.forbriger committed Dec 06, 2002 560   thomas.forbriger committed Dec 29, 2002 561 
 thomas.forbriger committed Dec 08, 2002 562 \section sec_design_multidimensional Multidimensional arrays  thomas.forbriger committed Dec 06, 2002 563   thomas.forbriger committed Dec 08, 2002 564 565  \todo Explain Wolfgangs idea of multidimensional arrays.  thomas.forbriger committed Dec 06, 2002 566   thomas.forbriger committed Dec 08, 2002 567 /*----------------------------------------------------------------------*/  thomas.forbriger committed Dec 06, 2002 568   thomas.forbriger committed Dec 29, 2002 569 
 thomas.forbriger committed Dec 08, 2002 570 571 \section sec_design_const Notes on the const-correctness of arrays  thomas.forbriger committed Dec 29, 2002 572 573 574 575 576 \subsection sec_design_const_problem Where is the problem? When passing a container (i.e. an array) to a function, we would like to promise that the values in the container are not modified, in case the function uses only read-access. Consider a declaration \code void func(const int& v) \endcode  thomas.forbriger committed Jan 02, 2003 577  of a function that takes and argument of type \c int an promises that this  thomas.forbriger committed Dec 29, 2002 578 579  will not be modified. Passing by reference is used, because this is more efficient than passing by value (in particular for large objects - which is  thomas.forbriger committed Jan 02, 2003 580 581  not the case for \c int, but for an array). And qualifying the type \c const promises that the  thomas.forbriger committed Dec 29, 2002 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598  value passed by reference will not be changed. A declaration \code void func(const Array& v) \endcode does not what we want (see "\ref sec_design_const_general"). It just promises the constness of the container, not of the data. Within the function the passed reference may be assigned to a non-const \c Array, which allows modification of the data (see "\ref page_representation"). Thus we must use something like \code void func(const ConstArray& v) \endcode where \c ConstArray does not allow modification of the data (be no means - copying and conversions included) and may be derived from an \c Array by a trivial conversion (like a conversion to a public base class). \subsection sec_design_const_approach The approach used in this library  thomas.forbriger committed Dec 20, 2002 599 600 601 602 603 604 605 606 607 608 609 610 611 612  We distinguish between the constness of the array and the constness of the elements. A definition \code aff::Array A(12,12); const aff::Array B(A); \endcode means that array \c B is a constant array initialized to array \c A. This means, that the container is constant. Its shape and reference may not be changed. If you want to define constness of the contained values (e.g. when passing an array to a function), you have to use \code  thomas.forbriger committed Dec 29, 2002 613  aff::ConstArray C(A);  thomas.forbriger committed Dec 20, 2002 614 615 616 617 618 619 620 621 622 623  \endcode which defines that the contents of \c C may not be changed (i.e. they are of type \c const \c int. They are still refering to the same data in memory. If you modify data elements through \c A, this will be visible through \c C. An array for elements of type \c T is derived from an array for elements of type \c const \c T. Functions that only need read access to arrays should be declared like \code  thomas.forbriger committed Dec 29, 2002 624  void func(const aff::ConstArray& array);  thomas.forbriger committed Dec 20, 2002 625 626 627 628 629 630  \endcode and may be called like \code aff::Array A(12,12); func(A); \endcode  thomas.forbriger committed Dec 29, 2002 631 632  The type conversion from \code aff::Array \endcode to \code const aff::ConstArray& \endcode is trivial and has no runtime  thomas.forbriger committed Dec 20, 2002 633 634  overhead.  thomas.forbriger committed Dec 29, 2002 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649  Each container class must deal with this issue on its own. Sorry... \sa aff::ConstSharedHeap \sa aff::ConstArray \sa aff::ConstSeries \par Restrictions for containers with const qualifier Strictly distinguishing between constness of the container and constness of the contained data would allow to modify data through an object \c c that was declared \code const Array c; \endcode The containers in this library (aff::Array, etc.), however, provide only a reduced set of access operators, when declared with \c const qualifier. They do not allow direct modification of the data (only through assignment to a non-const container instance).  thomas.forbriger committed Dec 20, 2002 650 651 652  Although the constness of the container object generally does not imply constness of the contained data, we think that every user will expect the classes to behave like this.  thomas.forbriger committed Dec 29, 2002 653 654 655 656 657 658  To ensure true constness of the data, you have to assign to the base class of the container. Any container class (e.g. \c Cont) provides the type of container for const elements through a typedef Tcontainer_of_const (i.e. \c Cont::Tcontainer_of_const) or short Tcoc. Remember that a \c const \c aff::Array always  thomas.forbriger committed Dec 20, 2002 659 660 661  may be assigned to a mutable aff::Array, which in turn allows modification of the data!  thomas.forbriger committed Dec 29, 2002 662 663 664 665 666 667 668 669 \subsection sec_design_const_alternatives Alternatives Three alternatives to this concept have been discussed (and discarded). Both have the appealing property of needing only one class definition for each container (in contrast to a class and a base class in our case). Additionally both would offer name commonality for containers of non-const elements and containers of const elements.  thomas.forbriger committed Dec 29, 2002 670 \par Using arrays with element type const T  thomas.forbriger committed Dec 29, 2002 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700  A rather straight approach is to use the element type \c const \c T where an array of elements of type \c T should be used, that we do not allow to be changed. This design concept can be accomplished with a special traits class that is specialized for \c const \c T and allows to derive a mutable or const version of any type. Be further providing appropriate conversion operators, an \code Array \endcode could be converted to an \code Array, \endcode both sharing the same elements in memory. In this approach, however, both container classes are completely independent (although having the same name) due to their different template arguments. The conversion to the container for const elements is not a trivial conversion (like for a reference to a reference of a public base class) and must be done explicitely. That's inconvenient for the most common use (i.e. passing a container to a function). \par Deriving from a template specialization The name commonality could still be achieved by deriving the Array from template specialization Array. In this case the specialization must be used as a base class before it is actually defined. That's impropoer design. \par Ensuring constness of elements through const qualifier of functions We could strictly follow the concept (as we do anyway to some extent) to couple the constness of the container to the constness of the contained data. This is done by const qualifiers to member functions that allow modification of the data. Avoid pitfalls, we have to consider copy operators and copy constructors then too. Both must not promise const-ness to their arguments. While this works in principle, we would end up with a container class which doesn't allow copies of const instances. Hence we could not return a container from a function, that ensures that the accessed data cannot be modified.  thomas.forbriger committed Dec 20, 2002 701 702 703  \subsection sec_design_const_general General considerations  thomas.forbriger committed Dec 08, 2002 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726  Arrays using the shared heap representation have reference semantics. Different instances will access the same data in memory. Copying an array instance just copies a reference to the data. This mechanism is not obvious to the compiler. The array instances are values in the sense of C++ types and not references. Passing an \c const \c aff::Array to a function does not prohibit the function from assigning this instance to a non-const \c aff::Array, which then references the same memory area and allows the modification of the values contained in the array. Generally it has to be defined, what is meant by declaring an array instance to be \c const. In the first place this means constness of the container to the compiler. The compiler will ensure, that the container (array class) is not changed, thus no data member of the array is changed. This means that the array will keep the reference to the same data and that the index-mapping defined by the array shape may not be changed. However, the compiler will not prevent to change any data, the array refers to. We may define access operators that have a non-const version that returns a reference to the data, allowing to change the data values together with a const version that returns a value of const reference, thus preventing the data from being changed through an instance that is declared const. However, the compiler will always allow to create a non-const copy of a const array instance. In the sense of const-ness of C++ data, this does not violate the  thomas.forbriger committed Dec 20, 2002 727  const-ness of the source of the copy. The shape of the original array may  thomas.forbriger committed Dec 08, 2002 728 729 730 731 732 733 734 735 736  not be changed. Only the shape of the copy may be changed. But the data of the original array may now be changed through the copied instance, since our array classes implicitly have reference semantic. Thus we have to distinguish between const-ness of the container (array class instance) and the contained data (values in memory the arrays refers to). In this library we will not provide a const and a non-const version of the array classes. With templated code it is more convenient to use an array with element type \c const \c T as the const version of an array with  thomas.forbriger committed Dec 20, 2002 737 738 739  element type \c T. To allow conversion of an instance with element type \c T to an instance of type \c const \c T, we use the version for elements of type \c const \c T as a base classe.  thomas.forbriger committed Dec 08, 2002 740 741 742 743 744 745 746 747 748 749 750 751  - The need of const-correctness is discussed in "Chapter 1 Introduction, C++ Conventions, Implementation of Vector and Matrix Classes" of "Numerical Recipes in C++". A link to a PDF file of this chapter is provided at "http://www.nr.com/cpp-blurb.html". - The "C++ FAQ Lite" discusses many aspects of const-correctness in Chapter 18, which you find at "http://www.inf.uni-konstanz.de/~kuehl/cpp/cppfaq.htm/const-correctness.html". - You may find my thoughts about const-correctness with containers that have reference semantics at "http://www.geophysik.uni-frankfurt.de/~forbrig/txt/cxx/tutorial/consthandle.doc/doc/html/index.html".  thomas.forbriger committed Dec 06, 2002 752 753 754 755 */ /*======================================================================*/  thomas.forbriger committed Dec 08, 2002 756 /*! \page page_using HOWTO use this library  thomas.forbriger committed Dec 06, 2002 757   thomas.forbriger committed Dec 08, 2002 758 759  Contents of this page: - \ref sec_using_constructor  thomas.forbriger committed Dec 20, 2002 760  - \ref sec_using_examples  thomas.forbriger committed Dec 06, 2002 761 762  \section sec_using_constructor Constructing arrays  thomas.forbriger committed Dec 20, 2002 763 764 765 766  Arrays are most easy constructed by means of the aff::Shaper. If you want e.g. define an array \c A of element type int with Fortran layout, three dimensions and the index ranges [-2:2], [1:4], and [6:10] you have to code  thomas.forbriger committed Dec 06, 2002 767  \code  thomas.forbriger committed Dec 20, 2002 768 769  using namespace aff; Array A(Shaper(-2,2)(4)(6,10));  thomas.forbriger committed Dec 06, 2002 770  \endcode  thomas.forbriger committed Dec 20, 2002 771  The shaper is presented in aff/shaper.h.  thomas.forbriger committed Dec 06, 2002 772   thomas.forbriger committed Dec 20, 2002 773 774 775 776 777 778 \section sec_using_examples Example code The test programs may serve as examples for using this library: - tests/arraytest.cc - tests/shapetest.cc - tests/reprtest.cc - tests/simplearraytest.cc  thomas.forbriger committed Dec 08, 2002 779 780  \todo  thomas.forbriger committed Dec 20, 2002 781 782 We need more text and examples.  thomas.forbriger committed Dec 08, 2002 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 */ /*======================================================================*/ /*! \page page_notes General notes Contents of this page: - \ref sec_notes_need \section sec_notes_need The need of an array library One major reason for replacing Fortran77 by C++ in numerical code is the convenience in expressing logistics. Data of different type and size may be packed into classes and encapsulated from the outside world. Most numerical results are to be stored in arrays, multi-dimensional arrays in particular. This library provides the basic functionality for storing many data of the same type in memory, passing them around between subroutines in an efficient way and accessing them through convenient interfaces. The main purpose of this library is not calculation but managing (passing between program modules, selection of subsets of the data) large amounts of numbers. In the future it might provide interfaces to libraries like blitz++ for finite difference calculations, MTL for linear algebra calculations, and POOMA for parallel computations.  thomas.forbriger committed Dec 06, 2002 808 809 810 811 */ /*======================================================================*/  thomas.forbriger committed Dec 08, 2002 812 813 814 /*! \page page_naming Naming conventions Contents of this page:  thomas.forbriger committed Dec 29, 2002 815 816 817  - \ref sec_naming_identifiers - \ref sec_naming_macros - \ref sec_naming_files  thomas.forbriger committed Dec 08, 2002 818   thomas.forbriger committed Dec 29, 2002 819 \section sec_naming_identifiers Classes, Typedefs, etc.  thomas.forbriger committed Dec 08, 2002 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837  During coding it is sometimes helpfull to recognize the meaning of an identifier due to some signals in irs name. Therefor the following guidelines are used. The nameing of template parameters is left free for convenience. \par Classes Class names always start with a capital letter. \par Typedefs Typedefs always start with a capital \c T. \par Member data Member data identifiers always start with a capital \c M.  thomas.forbriger committed Dec 29, 2002 838 \section sec_naming_macros Preprocessor macros  thomas.forbriger committed Dec 08, 2002 839 840  Preprocessor macros like include-guards should have the prefix "AFF_".  thomas.forbriger committed Dec 19, 2002 841  The macros in the \ref group_helpers are an exception to this rule.  thomas.forbriger committed Dec 08, 2002 842   thomas.forbriger committed Dec 29, 2002 843 \section sec_naming_files Filenames  thomas.forbriger committed Dec 08, 2002 844 845 846 847 848 849 850  Files with the extension \c .cc contain only non-template definitions. Files with the extension \c .h may contain prototypes, class declarations or template code. Files ending on \c def.h contain template code definitions that is factored out to be compilable into a binary library for explicit instantiation.  thomas.forbriger committed Dec 20, 2002 851 852  The main directory %aff contains headers that are usually included by the user. A subdirectory %aff/lib contains additional headers that are mostly  thomas.forbriger committed Dec 08, 2002 853 854  used internally.  thomas.forbriger committed Dec 06, 2002 855 856 857 */ // ----- END OF README -----