00001 // SuperMix version 1.0 C++ source file
00002 //
00003 // Copyright (c) 1999 California Institute of Technology.
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms for noncommercial
00007 // purposes are permitted provided that the above copyright notice and
00008 // this paragraph are duplicated in all such forms and that any
00009 // documentation and other materials related to such distribution and
00010 // use acknowledge that the software was developed by California
00011 // Institute of Technology. Redistribution and/or use in source or
00012 // binary forms is not permitted for any commercial purpose. Use of
00013 // this software does not include a permitted use of the Institute's
00014 // name or trademark for any purpose.
00015 //
00016 // DISCLAIMER:
00017 // THIS SOFTWARE AND/OR RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT
00018 // WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR
00019 // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE (AS SET
00020 // FORTH IN UCC 23212-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
00021 // LICENSED PRODUCT, HOWEVER USED. IN NO EVENT SHALL CALTECH/JPL BE
00022 // LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING BUT NOT LIMITED TO
00023 // INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING ECONOMIC
00024 // DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF
00025 // WHETHER CALTECH/JPL SHALL BE ADVISED, HAVE REASON TO KNOW, OR IN
00026 // FACT SHALL KNOW OF THE POSSIBILITY. THE USER BEARS ALL RISK
00027 // RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND/OR RELATED
00028 // MATERIALS.
00029 //
00030 // ************************************************************************
00031 // table.h
00032 // numeric matrix classes
00033 //
00034 // Needs:
00035 // table.cc for function definitions
00036 // a #defined constant macro DEFAULT_MATRIX_SIZE
00037 // (creates its own otherwise)
00038 //
00039 // Includes: SIScmplx.h
00040 //
00041 // F. Rice 9/24/97
00042 //
00043 // 4/26/00: added is_empty(), make_empty().
00044 // 7/6/99: changed "table" to "matrix". Included typedefs for compatibility
00045 // 11/11/98: enhanced access operators; removed public "data"
00046 // 7/31/98: added out_separator() static member functions
00047 // 7/30/98: Enhanced show(), added <<
00048 // 7/7/98: Made certain constructors explicit
00049 // 7/6/98: Added reindex()
00050 // 2/5/98: Added new constructor and operator = with datafile argument
00051 // to real_table class
00052 // 12/18/97: Special version with show() member function
00053 // 12/12/97: "fully" tested with calc
00054 // 11/24/97: improved real_table resize(), added real() and imaginary(),
00055 // fillrow() and fillcol(), and constructors using vectors.
00056 // 11/17/97: add(), sub()
00057 // 11/14/97: additional math functions
00058 // 11/12/97: changed void functions to return Lvalue *this
00059 // 11/11/97: Converting functions for compatibility with 11/11 vector.h
00060 // and matmath.h -- NOT FINISHED
00061 // 11/8/97: CHANGED DEFAULT MODE TO Index_1 instead of Index_C.
00062 // added resize().
00063 // 11/7/97: added checks for A = A and A.copy(A), so these constructs
00064 // behave properly (oops!). Also fixed copy constructor.
00065 // 11/3/97: New operator =, with an Rvalue RHS. Not fully tested yet.
00066 // 10/26/97: added additional functionality
00067 // 10/17/97: took out the ugly workaround; still bombs Sun CC.
00068 // 10/15/97: fixed some minor syntax bugs; added an ugly workaround in
00069 // construct() to get it to compile with Sun CC.
00070 // 9/30/97: first version fully functional and tested.
00071 //
00072 // ************************************************************************
00073 //
00074 // The real_matrix and complex_matrix Classes
00075 //
00076 // General:
00077 // -------
00078 // The *_matrix classes provide for manipulation of 2-dimensional array
00079 // data. A matrix object's data is allocated and referenced as a set of 1-D
00080 // data "rows", each in its own contiguous chunk of memory. A 1-D array
00081 // contains pointers to each of the rows, providing for the row indexing.
00082 // Each row is in effect a numeric vector "record", whose location is
00083 // maintained in the pointer array. The real_matrix can store type double
00084 // data elements, the complex_matrix can store type Complex data elements.
00085 //
00086 // Even though implemented as a list of rows, the matrix classes require
00087 // that all rows have the same data capacity and indexing mode. When
00088 // created, a matrix allocates a single, contiguous block of memory for the
00089 // data elements, which it divides up into the individual row arrays. Upon
00090 // destruction, the entire block of memory is deleted.
00091 //
00092 //
00093 // Indexing and Capacity:
00094 // ---------------------
00095 // Indexing of the data elements in a matrix is accomplished using a pair of
00096 // int indexes. There are three different indexing modes available, and
00097 // the row indexing and column indexing modes may differ in a given matrix
00098 // object. The three indexing modes available are called Index_C, Index_1,
00099 // and Index_S, and are identical to the modes used for *_vector indexing,
00100 // described in vectors.h.
00101 //
00102 // Both controlled and uncontrolled (direct) indexed access to the data
00103 // elements are provided. If "A" is a matrix object, then:
00104 //
00105 //
00106 // A.get(i,j); Provides controlled, safe read and write access to
00107 // the data elements. The indexes i and j may have any
00108 // integer values; i selects the row, and j selects the
00109 // element within the row (column). If (i,j) selects an
00110 // "element" beyond the limits of A's memory capacity,
00111 // A.get(i,j) returns a modifiable Lvalue containing 0.
00112 // The program can select a subset of the physically
00113 // allocated memory for controlled access -- see "Data
00114 // subset control" below. The default is for all
00115 // allocated memory to be accessible. get returns an
00116 // Lvalue, so it can be used to modify a data element,
00117 // e.g.: A.get(2,3) = 5.0;
00118 // If the matrix is declared const, returns a const
00119 // (read-only) Lvalue.
00120 //
00121 // A.read(i,j); Like A.get(i,j), except returns an Rvalue, so it is
00122 // only useful for reading data values, not writing to
00123 // them.
00124 //
00125 // A[i][j]; Provides uncontrolled, direct Lvalue access to the data
00126 // elements. [i] selects a row pointer, [j] selects an
00127 // offset from element 0 within the row. If [i][j] addresses
00128 // a nonexistant element of A, a program crash is likely. If
00129 // a is declared const, then the Lvalue will be const.
00130 //
00131 // A[i]; Returns a const Lvalue pointer to the data in row i of matrix
00132 // A. Actually points to A[i][0], which is not necessarily
00133 // the first (lowest address) data element in row i. In
00134 // fact, if the right index mode is Index_1, then A[i]
00135 // does not directly point to any valid data element in
00136 // row i. See the section "Manipulating Matrix Rows as
00137 // Vector Objects" for a quite useful application of this
00138 // construct. If A is declared const, then the pointer
00139 // returned will be to const data.
00140 //
00141 // The controlled access modes simulate an "infinite" matrix, whose
00142 // elements become identically zero if an index gets close enough to +/-
00143 // infinity. How close is "close" depends on A's data capacity and the
00144 // indexing modes it uses for row and column indexing.
00145 //
00146 // Referring to the following indexing modes and limits matrix:
00147 //
00148 // Indexing Modes, Index Limits, and Capacities
00149 //
00150 // n : size of an index (a nonnegative integer)
00151 //
00152 // Index Mode Index Range Data Capacity
00153 // ---------- ----------- -------------
00154 // Index_C { 0 .. n-1 } n
00155 //
00156 // Index_1 { 1 .. n } n
00157 //
00158 // Index_S {-n .. 0 .. n } 2*n + 1
00159 //
00160 // If, for example, the left index (row) mode is Index_1 and its size is n,
00161 // while the right index (within a row) mode is Index_S, size m, then the
00162 // total data capacity of the matrix is (referring to the matrix above)
00163 // n * (2*m + 1). The sizes for the left and right indexes are specified at
00164 // construction or reallocation and are kept as read-only member variables.
00165 // For matrix object A:
00166 //
00167 //
00168 // A.Lsize; Current value of the size of the left index range
00169 //
00170 // A.Rsize; Current value of the size of the right index range
00171 //
00172 //
00173 // To easily determine the valid index range for a given matrix object A,
00174 // the following member functions are provided:
00175 //
00176 //
00177 // A.Lmaxindex(); Returns the int value of the max valid left index
00178 //
00179 // A.Rmaxindex(); Returns the int value of the max valid right index
00180 //
00181 // A.Lminindex(); Returns the int value of the min valid left index
00182 //
00183 // A.Rminindex(); Returns the int value of the min valid right index
00184 //
00185 //
00186 // The left index picks the row, the right index picks the element in the
00187 // row (or column).
00188 //
00189 // Many times a square matrix using the same addressing mode for each index
00190 // is required. the following member functions are particularly useful in
00191 // this case, though they may be called regardless of the matrix topology:
00192 //
00193 //
00194 // A.maxindex(); Returns the minimum of A.Lmaxindex() and A.Rmaxindex()
00195 //
00196 // A.minindex(); Returns the maximum of A.Lminindex() and A.Rminindex()
00197 //
00198 //
00199 // For a square matrix, these functions return the proper limits for both
00200 // row and column indexing. For other matrices, they would identify a valid
00201 // subset of the full matrix indexing range.
00202 //
00203 // As for the vector classes, a maxindex is guaranteed to be smaller than
00204 // its corresponding minindex if the data capacity of the matrix is 0.
00205 // Therefore, loop constructs such as:
00206 //
00207 // for (int i = A.Lminindex(); i <= A.Lmaxindex(); ++i)
00208 // for (int j = A.Rminindex(); j <= A.Rmaxindex(); ++j)
00209 // A[i][j];
00210 //
00211 // will properly loop over the valid index values of the matrix A,
00212 // regardless of its index modes or data capacity.
00213 //
00214 // The following function will quickly tell you if a matrix has no valid
00215 // data elements:
00216 //
00217 // A.is_empty(); Returns 1 if there are no valid elements of A,
00218 // otherwise returns 0.
00219 //
00220 //
00221 // Specifying the Index Modes:
00222 // --------------------------
00223 // The default index mode for both the left and right indexes is Index_1.
00224 // This may be overridden by including one or two index mode values at the
00225 // end of a constructor's argument list, or at the end of the reallocate
00226 // member function's argument list. If only one index mode value is
00227 // supplied, it will be used for both indexes. If two values are supplied,
00228 // the first will be used for the left index, the other for the right
00229 // index. The index mode names are enumerations specified in an enumerated
00230 // type defined in this header file, called "v_index_mode".
00231 //
00232 // The index mode values for the left and right indexes for a matrix object
00233 // are maintained in read-only member variables. For matrix object A:
00234 //
00235 //
00236 // A.Lmode; current indexing mode value for the left index
00237 //
00238 // A.Rmode; current indexing mode value for the right index
00239 //
00240 // The indexing mode may also be changed:
00241 //
00242 //
00243 // A.reindex(Lmode, Rmode); change the index modes for this matrix
00244 // without moving data or reallocating memeory (mostly). Turns
00245 // off any data subset control, then changes internal pointers
00246 // so that the allocated memory for the matrix is now indexed
00247 // using the specified v_index_modes. The memory contents are
00248 // not moved, so: A[A.Lminindex()][A.Rminindex()]
00249 // addresses the same data element before and after the mode
00250 // change (assuming no data subset control before reindex() is
00251 // executed). Note that changing to Index_S requires an odd
00252 // number of allocated elements along that index direction;
00253 // if the number is even, the matrix is first resized, adding
00254 // an additional element.
00255 //
00256 //
00257 // Data Subset Control:
00258 // -------------------
00259 // At creation (L/R)minindex() and (L/R)maxindex() are set so that all
00260 // physically allocated matrix elements are available using controlled
00261 // access (except for the copy constructor, in which case they match the
00262 // values in the source matrix). The default behavior is therefore to allow
00263 // controlled access to all data elements. If only a subset of the matrix
00264 // near data[0][0] contains useful values, however, it may be wise to
00265 // temporarily limit access, so that looping over the relevant data will
00266 // not also include memory locations not currently needed, speeding up loop
00267 // execution. To implement this capability, both Lmaxindex() and
00268 // Rmaxindex() may be adjusted under program control; Lminindex() and
00269 // Rminindex() are determined by the index modes and the value of the
00270 // respective maxindex().
00271 //
00272 // Note that all data elements are always accessible using A[i][j]. For
00273 // any matrix object A:
00274 //
00275 //
00276 // A.Lmaxindex(i); Set the maximum valid left index to i if possible. If
00277 // the result would be less than the resulting
00278 // Lminindex(), then set Lmaxindex such that Lmaxindex()
00279 // == Lminindex() (0 for Index_C and Index_S, 1 for
00280 // Index_1). If the result would exceed the allocated
00281 // memory, set Lmaxindex so that all allocated memory is
00282 // available (A.Lsize for Index_1 and Index_S, A.Lsize-1
00283 // for Index_C). If the size of the left index (A.Lsize)
00284 // is zero, A.Lmaxindex(i) will have no effect, regardless
00285 // of the value of i. Returns the resulting Lmaxindex()
00286 // value. To maximize Lmaxindex(), use:
00287 // A.Lmaxindex(A.Lsize);
00288 //
00289 //
00290 // A.Rmaxindex(i); Set the maximum valid right index to i if possible.
00291 // Same notes as for Lmaxindex(i). To maximize
00292 // Rmaxindex(), use: A.Rmaxindex(A.Rsize);
00293 //
00294 //
00295 // A.maxindex(i); Set the maximum vaild index for both the left and right
00296 // indexes to i if possible. Individually limit the
00297 // indexes to valid ranges as described for Lmaxindex(i)
00298 // and Rmaxindex(i); this may result in a nonsquare index
00299 // range if A.Lsize != A.Rsize or A.Lmode != A.Rmode.
00300 // Returns the resulting A.maxindex(). To simultaneously
00301 // maximize both index ranges, use:
00302 //
00303 // A.maximize(); Set Lmaxindex() and Rmaxindex() to the largest values
00304 // allowed by physically allocated memory and their modes.
00305 // Equivalent to: A.maxindex(A.Lsize + A.Rsize);
00306 //
00307 // A.make_empty(); Set Lmaxindex() and Rmaxindex() and Lminindex() and
00308 // Rminindex() to the values they would have were there to
00309 // be no memory allocated for A, so that each maxindex()
00310 // will be less than its corresponding minindex().
00311 //
00312 //
00313 // Construction, Memory Allocation and Reallocation:
00314 // ------------------------------------------------
00315 // Upon creation a matrix object's data memory will be allocated from the
00316 // heap. The sizes of each dimension (left index and right index) for the
00317 // matrix object are specifiable as constructor parameters. If no values for
00318 // the sizes are given, a square matrix is constructed using the value
00319 // defined by the macro DEFAULT_MATRIX_SIZE for both dimensions. This macro
00320 // will be defined by this header file if it is not already defined. The
00321 // constant member variables Lsize and Rsize are set to the matrix's sizes;
00322 // both will equal 0 if memory allocation fails.
00323 //
00324 // If required, the memory allocation and/or indexing modes for an
00325 // individual matrix object may be adjusted following creation, so a matrix
00326 // object may be created with initial sizes of 0, and then later
00327 // reallocated once the required sizes are known.
00328 //
00329 // Upon destruction, a matrix object will return its memory to the heap.
00330 //
00331 // Note for mode Index_S and (L/R)size: size == 0 should mean that one
00332 // valid index value is available in mode Index_S, namely 0. However, in
00333 // the event of a memory allocation failure, this one index value will
00334 // actually access the same location as that used for index out of range
00335 // operations, and so will not be very useful. Note that in this case the
00336 // maxindex() value will be -1, and the minindex() value will be +1, so a
00337 // looping construct as described previously will access no values, which
00338 // is the correct action.
00339 //
00340 // A list of the basic constructor forms follows. In this list, *_ means a
00341 // prefix of real_ or complex_. Additionally: n and m are nonnegative int
00342 // sizes for the left and right indexes; t, tl, and tr are index mode
00343 // values of enumerated type v_index_mode and specify the index modes for
00344 // both indexes, the left index, and the right index respectively.
00345 //
00346 //
00347 // *_matrix A; Construct a square matrix with size given by the
00348 // value of DEFAULT_MATRIX_SIZE and index mode Index_1
00349 // in each index. Initialize all data elements to 0.
00350 //
00351 // *_matrix A(n); Construct a matrix with left and right index sizes
00352 // both equal n, and use Index_1 mode for both
00353 // indexes. Initialize all data elements to 0.
00354 //
00355 // *_matrix A(n,t); Construct a matrix with left and right index sizes
00356 // both equal n, and use index mode t for both
00357 // indexes. Initialize all data elements to 0.
00358 //
00359 // *_matrix A(n,m); Construct a matrix with left and right index sizes
00360 // of n and m, respectively. Use Index_1 for both
00361 // indexes. Initialize all data elements to 0.
00362 //
00363 // *_matrix A(n,m,t); Construct a matrix with left and right index sizes
00364 // of n and m, respectively. Use index mode t for
00365 // both indexes. Initialize all data elements to 0.
00366 //
00367 // *_matrix A(n,m,tl,tr); Construct a matrix with left and right index sizes
00368 // of n and m, respectively. Use index mode tl for
00369 // the left index, tr for the right index. Initialize
00370 // all data elements to 0.
00371 //
00372 // For all of the above constructors, the valid index range is initialized
00373 // to include all allocated data elements.
00374 //
00375 //
00376 // *_matrix A(B); Construct a copy of the matrix B, with the same
00377 // sizes and index modes as B, and with the same
00378 // valid index ranges (maxindex and minindex). Copy
00379 // all data from B, even any elements beyond the
00380 // valid index ranges. If A is a complex_matrix, then
00381 // B may be either a complex_matrix or a real_matrix
00382 // object. If A is a real_matrix, then B must also be
00383 // a real_matrix.
00384 //
00385 // *_matrix A(v); Construct a matrix which is a copy of the vector v.
00386 // The matrix will have one column, ie: Rsize == 1,
00387 // and will have Rmode == Index_1. The Left indexing
00388 // will match the indexing of the vector v, and all
00389 // physical elements of v will be copied. Finally,
00390 // set Lmaxindex() == v.maxindex(). If A is complex,
00391 // v may be either a complex_vector or a real_vector
00392 // object. If A is a real_matrix, then v must be a
00393 // real_vector.
00394 //
00395 // real_matrix A(D); Construct a real_matrix which is a copy of the
00396 // data matrix in the datafile class object D.
00397 //
00398 // To reallocate the memory or change the indexing modes of an existing
00399 // matrix object, the resize and reallocate member functions are
00400 // provided. When a matrix is reallocated, it copies the maximum amount of
00401 // data from the old A into the new A, given the new index sizes and modes
00402 // of A, and such that each data element keeps its same index locations. If
00403 // data subset control is being used, then the new valid index range will
00404 // match as closely as possible the old valid index range, but all physical
00405 // data will be copied, not just the data in the valid index range. If data
00406 // subset control is not being used (the maxindex and minindex values
00407 // include all allocated memory), then the new maxindex and minindex values
00408 // will include all of the newly allocated memory. The resize() member
00409 // function is useful if you know the resulting index range you want. The
00410 // reallocate() function is a more primitive construct which is called by
00411 // resize(). If A is a matrix object, then:
00412 //
00413 // A.resize(n,m); Reallocate the memory for A so that its size will
00414 // just fit left and right maximum index values of n
00415 // and m, respectively. Keep the current indexing
00416 // modes.
00417 //
00418 // A.resize(n); Reallocate the memory for A so that its size will
00419 // just fit left and right maximum index values of n.
00420 // Keep the current indexing modes.
00421 //
00422 // A.resize(B); Reallocate the memory for A so that its index
00423 // modes match those of matrix B, and its size will
00424 // just fit the valid index ranges of B, as
00425 // determined by B's data subset control.
00426 //
00427 // A.reallocate(n); Reallocate the memory for A to change it into a
00428 // matrix with size n for each index. Keep the
00429 // current indexing modes.
00430 //
00431 // A.reallocate(n,m); Reallocate the memory for A to change it into a
00432 // matrix with left and right index sizes n and m,
00433 // respectively. Keep the current indexing modes.
00434 //
00435 // A.reallocate(n,m,tl,tr); Reallocate the memory for A to change its
00436 // left index size and mode to n and tl, and the
00437 // right index size and mode to m and tr.
00438 //
00439 // In addition to the reallocate member function, the assignment operator
00440 // '=' may result in memory reallocation. This behavior is described in
00441 // the next section.
00442 //
00443 //
00444 // Assignment and Copying Data:
00445 // ---------------------------
00446 // The following member functions are provided for bulk data transfer from
00447 // one matrix object into another existing object: = and copy. Both
00448 // functions attempt to preserve the source matrix's data subset control,
00449 // and both set unused elements in the destination matrix to 0. There is a
00450 // major difference, however, between the two operations: = may reallocate
00451 // memory for the receiving matrix, while copy leaves the sizes and modes of
00452 // the receiving matrix unchanged. Note that self assignment ( A = A ) and
00453 // self copy ( A.copy(A) ) are not "do nothing" operations.
00454 //
00455 //
00456 // A = B; If A has insufficient memory to hold all of B's valid
00457 // (data subset control) data, or if the index modes of A
00458 // differ from those of B, reallocate the memory for A so
00459 // that it has the same index modes as B, with sizes just
00460 // sufficient to hold all of the valid data elements of B.
00461 // Copy all of B's valid data elements into A, and set any
00462 // remaining elements of A to 0. Set the data subset control
00463 // for A so that its valid index ranges match the valid
00464 // index ranges for B. When finished, A will be a (possibly
00465 // larger) copy of the valid data elements of B, with the
00466 // same valid index ranges and index modes. Note that = only
00467 // copies data within B's currently valid index range, so
00468 // data subset control on B will reduce the number of
00469 // elements copied. If A and B are the SAME matrix, just
00470 // perform A.clean().
00471 //
00472 // A = D; Perform the above operator = using the real_matrix data
00473 // in datafile object D. A must be a real_matrix.
00474 //
00475 // A.copy(B); Copy as many of the valid data elements of B into the
00476 // corresponding elements of A as the memory allocation and
00477 // indexing modes of A will allow. In other words, copy
00478 // the data elements with indexes in the intersection of
00479 // the indexing ranges of A and B. Only copies data within
00480 // B's currently valid index range, so data subset control
00481 // on B will reduce the number of elements copied. Ignores
00482 // any data subset control previously set for A. Sets the
00483 // remaining elements of A to 0, and sets A data subset
00484 // control to match as closely as possible B's valid index
00485 // range. If A and B are the SAME matrix, just perform
00486 // A.clean().
00487 //
00488 // As with the copy constructor, B may be either a real_matrix or a
00489 // complex_matrix if A is of type complex_matrix; B must be of type
00490 // real_matrix if A is of type real_matrix. D is of type datafile (defined in
00491 // datafile.h); for A = D, A must be of type real_matrix.
00492 //
00493 //
00494 // Other Member Functions:
00495 // ----------------------
00496 // The remaining member functions defined for matrix objects are:
00497 //
00498 //
00499 // A.fill(s); Fill all elements in the valid index range of A with the
00500 // scalar value s. The fill is subject to data subset
00501 // control.
00502 //
00503 // A = s; For scalar s, the same as A.fill(s). s may not be
00504 // Complex if A is of type real_matrix.
00505 //
00506 // A.fillall(s); Fill all physically allocated elements of A with the
00507 // scalar value s. Ignores data subset control.
00508 //
00509 // A.fillrow(n,v); Fill row n of A using the contents of vector v. Only
00510 // copies data into the valid index range of A from the
00511 // corresponding elements in the valid index range of v;
00512 // any valid elements of A without a corresponding valid
00513 // element in v are set to 0. If A is real, so must be v.
00514 //
00515 // A.fillcol(n,v); Fill column n of A using the contents of vector v. Only
00516 // copies data into the valid index range of A from the
00517 // corresponding elements in the valid index range of v;
00518 // any valid elements of A without a corresponding valid
00519 // element in v are set to 0. If A is real, so must be v.
00520 //
00521 // A.clean(); Reset to 0 all elements of A beyond the valid index
00522 // range as determined by data subset control.
00523 //
00524 // A.diagonal(s); Set A.get(i,i) = s; for all valid diagonal elements of A.
00525 // Sets all other elements of A to 0. Uses data subset
00526 // control to determine the valid diagonal elements of A.
00527 //
00528 // A.rowswap(n,m); Swap rows n and m of A. Actually performs the swap by
00529 // exchanging the values of the pointers stored in A[n]
00530 // and A[m], so the execution is very fast. If either
00531 // index is outside the valid left index range, then fills
00532 // the other row with zeroes. If both are outside the
00533 // valid left index range, then has no effect.
00534 //
00535 // A.apply(f); Apply the scalar function f to each valid element of
00536 // A. f() will be called once for each valid element of A.
00537 // f must be a function taking either:
00538 // (1) a single numeric argument of the same type as the
00539 // data elements of A: f(double x) or f(Complex x).
00540 // (2) a numeric argument and and two int arguments:
00541 // f(double x,int i,int j) or f(Complex x,int i,int j)
00542 // f() must return a single numeric value of the same type
00543 // as the data elements of A. As apply() iterates through
00544 // the vector elements, it calls f() with the value of each
00545 // element and, if f() is of type (2) above, the value of
00546 // the left index and the right index of the element.
00547 // Equivalent to:
00548 //
00549 // for (int i = A.Lminindex(); i <= A.Lmaxindex(); ++i)
00550 // for (int j = A.Rminindex(); j <= A.Rmaxindex(); ++j)
00551 // A[i][j] = f(A[i][j]);
00552 // /* OR */
00553 // A[i][j] = f(A[i][j], i, j);
00554 //
00555 //
00556 // Matrix Arithmetic Member Functions:
00557 // ----------------------------------
00558 //
00559 //
00560 // A += s; A -= s; A *= s; A /= s;
00561 // Perform the indicated assignment operator operation to
00562 // each element of A within its valid index range, using
00563 // data subset control. The scalar s may not be Complex if
00564 // A is a real_matrix.
00565 //
00566 // A += B; A -= B; First perform A.clean(), then perform the indicated
00567 // assignment operation as a vector addition or subtraction
00568 // using only valid elements of B (data subset control on
00569 // B). Increases the data subset range of A if necessary
00570 // so that its valid index range includes the valid index
00571 // range of B as a subset, unless limited by the physical
00572 // capacity of A. Does not reallocate any memory for A or
00573 // change A's index modes. B must be a real_matrix if A is
00574 // a real_matrix.
00575 //
00576 // A.add(B,C); sets A = B + C (matrix sum), where zeroes are padded to
00577 // rows and or columns of B and C to make them have equal
00578 // index ranges for the purposes of the sum (B and C are
00579 // not actually modified). Only includes elements in the
00580 // valid index ranges of B and C. If A is not originally
00581 // large enough to hold all elements of the result, it is
00582 // reallocated. B and C must both be real_matrix if A is a
00583 // real_matrix.
00584 //
00585 // A.sub(B,C); sets A = B - C (matrix), otherwise like A.add(B,C).
00586 //
00587 //
00588 // A.real(B); sets each element of A equal to the real part of the
00589 // corresponding element of complex_matrix B. Performs
00590 // A.resize(B) first, so that it is just big enough to
00591 // hold the valid elements of B. A may be either a
00592 // real_matrix or a complex_matrix; B must be a complex_
00593 // matrix. (The resize is not performed if B is the same
00594 // matrix as A)
00595 //
00596 // A.imaginary(B); sets each element of A equal to the imaginary part of
00597 // the corresponding element of complex_matrix B. Performs
00598 // A.resize(B) first, so that it is just big enough to
00599 // hold the valid elements of B. A may be either a
00600 // real_matrix or a complex_matrix; B must be a complex_
00601 // matrix. (The resize is not performed if B is the same
00602 // matrix as A)
00603 //
00604 //
00605 // Manipulating Matrix Rows as Vector Objects
00606 // -----------------------------------------
00607 // Because the *_vector classes include an alias constructor, and because
00608 // each row of a matrix object is stored as a contiguous block of memory, it
00609 // is easy to manipulate any row of a matrix as a true vector object. Some
00610 // examples follow (you must use the same data type for both the matrix and
00611 // vector objects, ie: both of type real or type complex):
00612 //
00613 //
00614 // complex_matrix A(10,7,Index_S,Index_1);
00615 // // each row of A is like a complex_vector(7,Index_1)
00616 //
00617 // complex_vector y(complex_vector(A[3], A.Rsize, A.Rmode));
00618 // // y is an independent copy of the data in row 3 of A
00619 //
00620 // complex_vector x(A[3], A.Rsize, A.Rmode);
00621 // // x aliases row 3 of A, with the same size and index mode.
00622 // // any changes to elements of x will result in changes to
00623 // // A, such as:
00624 //
00625 // x.copy(v); // copy elements of v into x (and row 3 of A)
00626 //
00627 // x.copy(y); // restores x (and row 3 of A) to its original values
00628 //
00629 //
00630 //
00631 // Matrix Output/Display Functions:
00632 // ------------------------------
00633 //
00634 // ostream << A; send the contents of matrix A to the output stream ostream,
00635 // using "ostream << v" to output each row in the valid
00636 // index range of A as a vector v. Multiple valid rows of
00637 // A are separated by the C++ string whose value is controlled
00638 // by the static member function out_separator(); the default
00639 // value is a single newline character '\n'. The value of
00640 // ostream.width() is used to set the field width for each
00641 // row output; it is not used for the field width of the row
00642 // separator string. Note that << is not a member function of
00643 // any class. See vector.h for details on how each row of
00644 // output is formatted.
00645 //
00646 // A.show(ostream); output equivalent to: ostream << endl << A << endl;
00647 //
00648 // A.show(); equivalent to A.show(cout);
00649 //
00650 // real_matrix::out_separator(s); or: complex_matrix::out_separator(s);
00651 // either function sets the output separator string for
00652 // both real_matrix and complex_matrix output. s may be a
00653 // C++ string, a C-style string, or a single char. The
00654 // function returns the previous value of the separator as
00655 // a C++ string. If no argument is specified, then the
00656 // function simply returns the current separator value. The
00657 // default value is a single newline. If no output separator
00658 // character is desired, use a null string "" for s.
00659 //
00660 // ************************************************************************
00661
00662 #ifndef MATRIX_H
00663 #define MATRIX_H
00664
00665 #ifndef DEFAULT_MATRIX_SIZE
00666 #define DEFAULT_MATRIX_SIZE 16 /* a default matrix size */
00667 #endif /* DEFAULT_MATRIX_SIZE */
00668
00669 #ifndef V_INDEX_MODE_DEFINED
00670 #define V_INDEX_MODE_DEFINED
00671 enum v_index_mode { Index_C, Index_1, Index_S }; // same as in vectors.h
00672 #endif /* V_INDEX_MODE_DEFINED */
00673
00674 #include "SIScmplx.h"
00675 #include <string>
00676
00677 class real_vector;
00678 class complex_vector;
00679 class complex_matrix;
00680 class datafile;
00681 class ostream;
00682
00683 //-------------------------------------------------------------------------
00684 class real_matrix {
00685
00686 public:
00687
00688 // data (all are read-only aliases of private data members):
00689
00690 const int &Lsize; // the size of the left index
00691 const int &Rsize; // the size of the right index
00692 const v_index_mode &Lmode; // the indexing mode for the left index
00693 const v_index_mode &Rmode; // the indexing mode for the right index
00694
00695
00696 // constructors:
00697
00698 explicit real_matrix(const int n = DEFAULT_MATRIX_SIZE)
00699 : Lsize(internal_Lsize), Rsize(internal_Rsize),
00700 Lmode(internal_Lmode), Rmode(internal_Rmode)
00701 { construct(n, n, Index_1, Index_1); constfill(0.0); }
00702
00703 real_matrix(const int n, const v_index_mode t)
00704 : Lsize(internal_Lsize), Rsize(internal_Rsize),
00705 Lmode(internal_Lmode), Rmode(internal_Rmode)
00706 { construct(n, n, t, t); constfill(0.0); }
00707
00708 real_matrix(const int n, const int m)
00709 : Lsize(internal_Lsize), Rsize(internal_Rsize),
00710 Lmode(internal_Lmode), Rmode(internal_Rmode)
00711 { construct(n, m, Index_1, Index_1); constfill(0.0); }
00712
00713 real_matrix(const int n, const int m, const v_index_mode t)
00714 : Lsize(internal_Lsize), Rsize(internal_Rsize),
00715 Lmode(internal_Lmode), Rmode(internal_Rmode)
00716 { construct(n, m, t, t); constfill(0.0); }
00717
00718 real_matrix(const int n, const int m,
00719 const v_index_mode tl, const v_index_mode tr)
00720 : Lsize(internal_Lsize), Rsize(internal_Rsize),
00721 Lmode(internal_Lmode), Rmode(internal_Rmode)
00722 { construct(n, m, tl, tr); constfill(0.0); }
00723
00724 real_matrix(const real_matrix & B);
00725 real_matrix(const real_vector & v);
00726 real_matrix(const datafile & D);
00727
00728
00729 // destructor:
00730
00731 ~real_matrix(void)
00732 { delete [] delete_pointer_data; delete [] delete_pointer_rows; }
00733
00734
00735 // data subset contol:
00736
00737 inline int Lminindex(void) const { return Lminindexvalue; }
00738 inline int Lmaxindex(void) const { return Lmaxindexvalue; }
00739 int Lmaxindex(const int n);
00740 inline int Rminindex(void) const { return Rminindexvalue; }
00741 inline int Rmaxindex(void) const { return Rmaxindexvalue; }
00742 int Rmaxindex(const int n);
00743 inline int minindex(void) const
00744 {
00745 return (Lminindexvalue > Rminindexvalue) ?
00746 Lminindexvalue : Rminindexvalue;
00747 }
00748 inline int maxindex(void) const
00749 {
00750 return (Lmaxindexvalue < Rmaxindexvalue) ?
00751 Lmaxindexvalue : Rmaxindexvalue;
00752 }
00753 inline int maxindex(int n)
00754 { Lmaxindex(n); Rmaxindex(n); return maxindex(); }
00755 inline int maximize(void)
00756 { return maxindex(Lsize+Rsize); }
00757 inline int is_empty() const
00758 { return (Lmaxindex() < Lminindex())||(Rmaxindex() < Rminindex());}
00759 real_matrix & make_empty();
00760
00761
00762 // data access:
00763
00764 inline double read(const int i, const int j) const
00765 {
00766 if((i > Lmaxindex())||(j > Rmaxindex())||
00767 (i < Lminindex())||(j < Rminindex()) )
00768 return 0.0;
00769 else
00770 return data[i][j];
00771 }
00772
00773 inline double & get(const int i, const int j)
00774 {
00775 if((i > Lmaxindex())||(j > Rmaxindex())||
00776 (i < Lminindex())||(j < Rminindex()) )
00777 return (trash = 0.0);
00778 else
00779 return data[i][j];
00780 }
00781
00782 inline const double & get(const int i, const int j) const
00783 {
00784 if((i > Lmaxindex())||(j > Rmaxindex())||
00785 (i < Lminindex())||(j < Rminindex()) )
00786 return (trash = 0.0);
00787 else
00788 return data[i][j];
00789 }
00790
00791 inline double *const & operator [] (const int i)
00792 { return data[i]; }
00793
00794 inline const double *const & operator [] (const int i) const
00795 {
00796 // These extra steps are necessary to work around a compiler bug
00797 // in gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-81)
00798 // return data[i];
00799 double const * const * p = data + i;
00800 return *p;
00801 }
00802
00803
00804 // change the index modes:
00805
00806 real_matrix & reindex(const v_index_mode, const v_index_mode);
00807
00808
00809 // reallocation:
00810
00811 real_matrix & reallocate(const int n, const int m,
00812 const v_index_mode tl, const v_index_mode tr);
00813 inline real_matrix & reallocate(const int n)
00814 { return reallocate(n, n, Lmode, Rmode); }
00815 inline real_matrix & reallocate(const int n, const int m)
00816 { return reallocate(n, m, Lmode, Rmode); }
00817 inline real_matrix & resize(const int Lmax, const int Rmax)
00818 {
00819 int Lsize = (Lmode == Index_C) ? Lmax+1: Lmax;
00820 int Rsize = (Rmode == Index_C) ? Rmax+1: Rmax;
00821 return reallocate(Lsize, Rsize);
00822 }
00823 inline real_matrix & resize(const int Max) { return resize(Max, Max); }
00824 inline real_matrix & resize(const real_matrix & B)
00825 {
00826 int Lsize = (B.Lmode == Index_C) ? B.Lmaxindex()+1: B.Lmaxindex();
00827 int Rsize = (B.Rmode == Index_C) ? B.Rmaxindex()+1: B.Rmaxindex();
00828 return reallocate(Lsize, Rsize, B.Lmode, B.Rmode);
00829 }
00830 real_matrix & resize(const complex_matrix & B);
00831
00832
00833 // copy and assignment:
00834
00835 real_matrix & copy(const real_matrix & B);
00836 real_matrix & operator = (const real_matrix & B);
00837 real_matrix & operator = (const datafile & D);
00838
00839
00840 // other member functions:
00841
00842 real_matrix & clean(void);
00843 inline real_matrix & fill(const double s) { constfill(s); return *this; }
00844 inline real_matrix & operator = (const double s) { return fill(s); }
00845 real_matrix & fillall(const double s);
00846 real_matrix & fillrow(const int n, const real_vector & v);
00847 real_matrix & fillcol(const int n, const real_vector & v);
00848 real_matrix & diagonal(const double s);
00849 real_matrix & rowswap(const int n, const int m);
00850 real_matrix & apply(double (*f)(double));
00851 real_matrix & apply(double (*f)(const double &));
00852 real_matrix & apply(double (*f)(double, int, int));
00853 real_matrix & apply(double (*f)(const double &, int, int));
00854
00855 // matrix arithmetic member functions:
00856
00857 real_matrix & operator += (const double s);
00858 real_matrix & operator -= (const double s);
00859 real_matrix & operator *= (const double s);
00860 real_matrix & operator /= (const double s);
00861 real_matrix & operator += (const real_matrix & B);
00862 real_matrix & operator -= (const real_matrix & B);
00863
00864 real_matrix & add(const real_matrix & B, const real_matrix & C);
00865 real_matrix & sub(const real_matrix & B, const real_matrix & C);
00866 real_matrix & real(const complex_matrix & B);
00867 real_matrix & imaginary(const complex_matrix & B);
00868
00869 // matrix output member functions:
00870
00871 real_matrix & show(ostream &);
00872 real_matrix & show(void);
00873 const real_matrix & show(ostream &) const;
00874 const real_matrix & show(void) const;
00875 static string out_separator(); // return the current output separator
00876 static string out_separator(const string &);
00877 static string out_separator(const char * const);
00878 static string out_separator(const char);
00879
00880
00881 private:
00882
00883 int internal_Lsize; // aliased by Lsize
00884 int internal_Rsize; // aliased by Rsize
00885 v_index_mode internal_Lmode; // aliased by Lmode
00886 v_index_mode internal_Rmode; // aliased by Rmode
00887 int Lmaxindexvalue; // the left index upper limit
00888 int Lminindexvalue; // the left index lower limit
00889 int Rmaxindexvalue; // the right index upper limit
00890 int Rminindexvalue; // the right index lower limit
00891 double * * data; // points to pointer to [0][0]
00892 double * * delete_pointer_data; // used by destructor to delete memory
00893 double * delete_pointer_rows; // used by destructor to delete memory
00894 mutable double trash; // Where index-out-of-bounds wind up
00895 double * trashptr; // Will point to trash ico alloc failure
00896
00897 // these functions are called by other member functions:
00898 void construct(const int n, const int m,
00899 const v_index_mode tl,
00900 const v_index_mode tr); //allocate memory
00901 void constfill(const double f); // fill with a constant value
00902
00903 }; // class real_matrix
00904
00905 ostream & operator << (ostream &, const real_matrix &);
00906
00907 //-------------------------------------------------------------------------
00908
00909 class complex_matrix {
00910
00911 public:
00912
00913 // data (all are read-only aliases of private data members):
00914
00915 const int &Lsize; // the size of the left index
00916 const int &Rsize; // the size of the right index
00917 const v_index_mode &Lmode; // the indexing mode for the left index
00918 const v_index_mode &Rmode; // the indexing mode for the right index
00919
00920
00921 // constructors:
00922
00923 explicit complex_matrix(const int n = DEFAULT_MATRIX_SIZE)
00924 : Lsize(internal_Lsize), Rsize(internal_Rsize),
00925 Lmode(internal_Lmode), Rmode(internal_Rmode)
00926 { construct(n, n, Index_1, Index_1); constfill(0.0); }
00927
00928 complex_matrix(const int n, const v_index_mode t)
00929 : Lsize(internal_Lsize), Rsize(internal_Rsize),
00930 Lmode(internal_Lmode), Rmode(internal_Rmode)
00931 { construct(n, n, t, t); constfill(0.0); }
00932
00933 complex_matrix(const int n, const int m)
00934 : Lsize(internal_Lsize), Rsize(internal_Rsize),
00935 Lmode(internal_Lmode), Rmode(internal_Rmode)
00936 { construct(n, m, Index_1, Index_1); constfill(0.0); }
00937
00938 complex_matrix(const int n, const int m, const v_index_mode t)
00939 : Lsize(internal_Lsize), Rsize(internal_Rsize),
00940 Lmode(internal_Lmode), Rmode(internal_Rmode)
00941 { construct(n, m, t, t); constfill(0.0); }
00942
00943 complex_matrix(const int n, const int m,
00944 const v_index_mode tl, const v_index_mode tr)
00945 : Lsize(internal_Lsize), Rsize(internal_Rsize),
00946 Lmode(internal_Lmode), Rmode(internal_Rmode)
00947 { construct(n, m, tl, tr); constfill(0.0); }
00948
00949 complex_matrix(const complex_matrix & B);
00950 complex_matrix(const real_matrix & B);
00951 complex_matrix(const real_vector & v);
00952 complex_matrix(const complex_vector & v);
00953
00954 // destructor:
00955
00956 ~complex_matrix(void)
00957 { delete [] delete_pointer_data; delete [] delete_pointer_rows; }
00958
00959
00960 // data subset contol:
00961
00962 inline int Lminindex(void) const { return Lminindexvalue; }
00963 inline int Lmaxindex(void) const { return Lmaxindexvalue; }
00964 int Lmaxindex(const int n);
00965 inline int Rminindex(void) const { return Rminindexvalue; }
00966 inline int Rmaxindex(void) const { return Rmaxindexvalue; }
00967 int Rmaxindex(const int n);
00968 inline int minindex(void) const
00969 {
00970 return (Lminindexvalue > Rminindexvalue) ?
00971 Lminindexvalue : Rminindexvalue;
00972 }
00973 inline int maxindex(void) const
00974 {
00975 return (Lmaxindexvalue < Rmaxindexvalue) ?
00976 Lmaxindexvalue : Rmaxindexvalue;
00977 }
00978 inline int maxindex(int n)
00979 { Lmaxindex(n); Rmaxindex(n); return maxindex(); }
00980 inline int maximize(void)
00981 { return maxindex(Lsize+Rsize); }
00982 inline int is_empty() const
00983 { return (Lmaxindex() < Lminindex())||(Rmaxindex() < Rminindex());}
00984 complex_matrix & make_empty();
00985
00986
00987 // data access:
00988
00989 inline Complex read(const int i, const int j) const
00990 {
00991 if((i > Lmaxindex())||(j > Rmaxindex())||
00992 (i < Lminindex())||(j < Rminindex()) )
00993 return 0.0;
00994 else
00995 return data[i][j];
00996 }
00997
00998 inline Complex & get(const int i, const int j)
00999 {
01000 if((i > Lmaxindex())||(j > Rmaxindex())||
01001 (i < Lminindex())||(j < Rminindex()) )
01002 return (trash = 0.0);
01003 else
01004 return data[i][j];
01005 }
01006
01007 inline const Complex & get(const int i, const int j) const
01008 {
01009 if((i > Lmaxindex())||(j > Rmaxindex())||
01010 (i < Lminindex())||(j < Rminindex()) )
01011 return (trash = 0.0);
01012 else
01013 return data[i][j];
01014 }
01015
01016 inline Complex *const & operator [] (const int i)
01017 { return data[i]; }
01018
01019 inline const Complex *const & operator [] (const int i) const
01020 {
01021 // These extra steps are necessary to work around a compiler bug
01022 // in gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-81)
01023 // return data[i];
01024 Complex const * const * p = data + i;
01025 return *p;
01026 }
01027
01028
01029 // change the index modes:
01030
01031 complex_matrix & reindex(const v_index_mode, const v_index_mode);
01032
01033
01034 // reallocation:
01035
01036 complex_matrix & reallocate(const int n, const int m,
01037 const v_index_mode tl, const v_index_mode tr);
01038 inline complex_matrix & reallocate(const int n)
01039 { return reallocate(n, n, Lmode, Rmode); }
01040 inline complex_matrix & reallocate(const int n, const int m)
01041 { return reallocate(n, m, Lmode, Rmode); }
01042 inline complex_matrix & resize(const int Lmax, const int Rmax)
01043 {
01044 int Lsize = (Lmode == Index_C) ? Lmax+1: Lmax;
01045 int Rsize = (Rmode == Index_C) ? Rmax+1: Rmax;
01046 return reallocate(Lsize, Rsize);
01047 }
01048 inline complex_matrix & resize(const int Max)
01049 { return resize(Max, Max); }
01050 inline complex_matrix & resize(const complex_matrix & B)
01051 {
01052 int Lsize = (B.Lmode == Index_C) ? B.Lmaxindex()+1: B.Lmaxindex();
01053 int Rsize = (B.Rmode == Index_C) ? B.Rmaxindex()+1: B.Rmaxindex();
01054 return reallocate(Lsize, Rsize, B.Lmode, B.Rmode);
01055 }
01056 inline complex_matrix & resize(const real_matrix & B)
01057 {
01058 int Lsize = (B.Lmode == Index_C) ? B.Lmaxindex()+1: B.Lmaxindex();
01059 int Rsize = (B.Rmode == Index_C) ? B.Rmaxindex()+1: B.Rmaxindex();
01060 return reallocate(Lsize, Rsize, B.Lmode, B.Rmode);
01061 }
01062
01063 // copy and assignment:
01064
01065 complex_matrix & copy(const complex_matrix & B);
01066 complex_matrix & copy(const real_matrix & B);
01067 complex_matrix & operator = (const complex_matrix & B);
01068 complex_matrix & operator = (const real_matrix & B);
01069
01070
01071 // other member functions:
01072
01073 complex_matrix & clean(void);
01074 inline complex_matrix & fill(const Complex s) { constfill(s); return *this; }
01075 inline complex_matrix & operator = (const Complex s) { return fill(s); }
01076 inline complex_matrix & operator = (const double s)
01077 { return fill(Complex(s)); }
01078 complex_matrix & fillall(const Complex s);
01079 complex_matrix & fillrow(const int n, const real_vector & v);
01080 complex_matrix & fillrow(const int n, const complex_vector & v);
01081 complex_matrix & fillcol(const int n, const real_vector & v);
01082 complex_matrix & fillcol(const int n, const complex_vector & v);
01083 complex_matrix & diagonal(const Complex s);
01084 complex_matrix & rowswap(const int n, const int m);
01085 complex_matrix & apply(Complex (*f)(Complex));
01086 complex_matrix & apply(Complex (*f)(const Complex &));
01087 complex_matrix & apply(Complex (*f)(Complex, int, int));
01088 complex_matrix & apply(Complex (*f)(const Complex &, int, int));
01089
01090 // matrix arithmetic member functions:
01091
01092 complex_matrix & operator += (const Complex s);
01093 complex_matrix & operator -= (const Complex s);
01094 complex_matrix & operator *= (const Complex s);
01095 complex_matrix & operator /= (const Complex s);
01096 complex_matrix & operator += (const complex_matrix & B);
01097 complex_matrix & operator -= (const complex_matrix & B);
01098 complex_matrix & operator += (const real_matrix & B);
01099 complex_matrix & operator -= (const real_matrix & B);
01100
01101 complex_matrix & add(const complex_matrix & B, const complex_matrix & C);
01102 complex_matrix & add(const complex_matrix & B, const real_matrix & C);
01103 inline complex_matrix & add(const real_matrix & B, const complex_matrix & C)
01104 { return add(C,B); }
01105 complex_matrix & add(const real_matrix & B, const real_matrix & C);
01106 complex_matrix & sub(const complex_matrix & B, const complex_matrix & C);
01107 complex_matrix & sub(const complex_matrix & B, const real_matrix & C);
01108 complex_matrix & sub(const real_matrix & B, const complex_matrix & C);
01109 complex_matrix & sub(const real_matrix & B, const real_matrix & C);
01110 complex_matrix & real(const complex_matrix & B);
01111 complex_matrix & imaginary(const complex_matrix & B);
01112
01113 // matrix output member functions:
01114
01115 complex_matrix & show(ostream &);
01116 complex_matrix & show(void);
01117 const complex_matrix & show(ostream &) const;
01118 const complex_matrix & show(void) const;
01119 static string out_separator(); // return the current output separator
01120 static string out_separator(const string &);
01121 static string out_separator(const char * const);
01122 static string out_separator(const char);
01123
01124
01125 private:
01126
01127 int internal_Lsize; // aliased by Lsize
01128 int internal_Rsize; // aliased by Rsize
01129 v_index_mode internal_Lmode; // aliased by Lmode
01130 v_index_mode internal_Rmode; // aliased by Rmode
01131 int Lmaxindexvalue; // the left index upper limit
01132 int Lminindexvalue; // the left index lower limit
01133 int Rmaxindexvalue; // the right index upper limit
01134 int Rminindexvalue; // the right index lower limit
01135 Complex * * data; // points to pointer to [0][0]
01136 Complex * * delete_pointer_data; // used by destructor to delete memory
01137 Complex * delete_pointer_rows; // used by destructor to delete memory
01138 mutable Complex trash; // Where index-out-of-bounds wind up
01139 Complex * trashptr; // Will point to trash ico alloc failure
01140
01141 // these functions are called by other member functions:
01142 void construct(const int n, const int m,
01143 const v_index_mode tl,
01144 const v_index_mode tr); //allocate memory
01145 void constfill(const Complex f); // fill with a constant value
01146
01147 }; // class complex_matrix
01148
01149 ostream & operator << (ostream &, const complex_matrix &);
01150
01151 //-------------------------------------------------------------------------
01152
01153 typedef real_matrix real_table;
01154 typedef complex_matrix complex_table;
01155
01156 #endif /* MATRIX_H */
Please direct comments and corrections to
supermix@submm.caltech.edu
Go to the supermix home page
Generated by
1.2.7