1 #ifndef SimTK_SIMMATRIX_BIGMATRIX_H_
2 #define SimTK_SIMMATRIX_BIGMATRIX_H_
3 
4 /* -------------------------------------------------------------------------- *
5  *                       Simbody(tm): SimTKcommon                             *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from           *
8  * Simbios, the NIH National Center for Physics-Based Simulation of           *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody.  *
11  *                                                                            *
12  * Portions Copyright (c) 2005-2017 Stanford University and the Authors.      *
13  * Authors: Michael Sherman                                                   *
14  * Contributors:                                                              *
15  *                                                                            *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
17  * not use this file except in compliance with the License. You may obtain a  *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
19  *                                                                            *
20  * Unless required by applicable law or agreed to in writing, software        *
21  * distributed under the License is distributed on an "AS IS" BASIS,          *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
23  * See the License for the specific language governing permissions and        *
24  * limitations under the License.                                             *
25  * -------------------------------------------------------------------------- */
26 
27 /** @file
28  * This file defines the client side of the SimTK::Matrix classes, which
29  * hold medium to large, variable-sized matrices whose elements are packed
30  * SimTK "Composite Numerical Types" (CNTs). Unlike CNTs, the implemention here
31  * is opaque, and almost all properties are captured in the implementation at
32  * run time rather than in the type at compile time.
33  *
34  * Every Matrix consists logically of three pieces:
35  *  - the matrix handle
36  *  - the matrix helper
37  *  - and the matrix data.
38  *
39  * They are organized like this:
40  * <pre>
41  *      ------------            ------------
42  *     |  Handle<E> | -------> |            |
43  *      ------------  <------- | Helper<S>  |
44  *                             |            |
45  *                             |            |          --------~ ~--
46  *                             |            | ------> | Data<S> ... |
47  *                              ------------           --------~ ~--
48  * </pre>
49  * The handle is the object actually appearing in SimTK API user programs.
50  * It always consists of just a single pointer, pointing to a library-side
51  * "helper" object whose implementation is opaque. The handle is templatized
52  * by the user's element type, which may be any packed composite numerical
53  * type, including scalar types like \c float and \c complex<double>, but also
54  * composite types such as \c Vec3 or \c Mat<2,2,Mat<3,3>>. A Matrix handle
55  * owns the helper to which it points and must destruct the helper when
56  * the handle's destructor is called.
57  *
58  * The helper, on the other hand, is parameterized only by the underlying scalar
59  * type. There are exactly 12 SimTK scalar types, so all can be instantiated on
60  * the library side leaving the implementation opaque and thus flexible from
61  * release to release without compromising binary compatibility. (The scalar
62  * types are: the four C++ standard types float and double,
63  * complex<float>, and complex<double>; the SimTK numbers conjugate<float> and
64  * conjugate<double>; and negator<> types templatized by any of the six
65  * numeric types.) The helper contains several kinds of information:
66  *  - the underlying scalar type S (as its template parameter)
67  *  - the number of scalars in the handle's logical element type E
68  *  - whether this is an owner matrix, or just a view
69  *  - the handle "commitment"; defining the range of matrix characteristics
70  *      to which that handle may refer
71  *  - the actual characteristics of the matrix currently represented by
72  *      the helper
73  *  - a virtual function table full of methods which are aware of the
74  *      logical structure of the Matrix and the physical structure of
75  *      the data to support operations such as element indexing
76  *  - a pointer to the underlying data, which may be shared with other
77  *      helpers
78  *
79  * The data itself consists only of scalars
80  * S of the same type as the helper's template argument, but different
81  * helpers can look at the same data differently. For examples, when the
82  * elements are composite consisting of k scalars, the helper will provide a
83  * view of the data in which its scalars are interpreted in groups of k.
84  * Many other reinterpretations of the data are possible and useful, such
85  * as a real-valued helper viewing only the real or imaginary part of
86  * complex data, or a helper which views the data order as though it were
87  * transposed.
88  *
89  * At most \e one matrix helper owns the matrix data and is responsible
90  * for deleting that data when no longer needed. That is called an "owner"
91  * helper and its associated handle is an owner handle. Normally the owner
92  * is the handle (and helper) that allocated the data, and
93  * in most cases an owner can resize the data at will. Many other handles
94  * may reference the same data; those non-owner handles are called "views".
95  * Every view may present a different picture of the underlying data. The
96  * default view is "whole" meaning that all the elements of the data are
97  * visible, and appear in their normal order. A "transpose" view also shows
98  * all the elements but the matrix dimensions and indices are reversed.
99  * Other common views are "block" to select a sub-block of a matrix, and
100  * "diagonal" which shows only the diagonal of a matrix (as a vector).
101  *
102  * NOTE: Destruction of an owner destructs the data it owns
103  * *regardless* of the presence of other views into that data! I.e., these
104  * are not reference counted. TODO: should we change that?
105  *
106  * In some cases there may be no owner helper for a particular piece of
107  * matrix data. That occurs when pre-existing memory, such as a Fortran
108  * array, is used to construct a Matrix. In that case all the helpers are
109  * views and the data will persist after the destruction of the last
110  * referencing helper.
111  *
112  * A Matrix that is the owner of its data will be resized whenever
113  * necessary, unless you take active steps to prevent that. For example, if
114  * you declare a Vector, the number of rows can resize but the number of
115  * columns will be locked at 1. A RowVector does the reverse. You can also
116  * explicitly lock the number of rows and/or columns of a matrix to prevent
117  * unwanted resizes.
118  *
119  * Here are the classes and short descriptions:
120  * <pre>
121  *   MatrixHelper<S>  interface to the opaque implementation, templatized
122  *                      by scalar type only
123  *   MatrixBase<CNT>  fully templatized client, contains a MatrixHelper
124  * </pre>
125  *
126  * The rest are dataless classes all of which can be interconverted just
127  * by recasting. Every one of these classes has a default conversion to
128  * type Matrix_<same element type>, so users can write functions that expect
129  * a Matrix argument and pass it a Vector, RowVectorView, or whatever.
130  *
131  * <pre>
132  *   VectorBase<CNT>    these are derived from MatrixBase and add no new data,
133  *   RowVectorBase<CNT> but change some of the operators and other methods to
134  *                        be appropriate for 1d data.
135  *
136  *   Matrix_<CNT>      2d owner class     (a MatrixBase<CNT>)
137  *   Vector_<CNT>      column owner class (a VectorBase<CNT>)
138  *   RowVector_<CNT>   row owner class    (a RowVectorBase<CNT>)
139  * </pre>
140  *
141  * Views are exactly the same as the corresponding owner class, but with
142  * shallow construction and assignment semantics.
143  *
144  * <pre>
145  *   MatrixView_<CNT>, VectorView_<CNT>, RowVectorView_<CNT>
146  * </pre>
147  *
148  * Dead matrices are owners that are about to be destructed. Anything
149  * they own may be taken from them, including the helper and/or
150  * the data. This is a very effective performance trick for sequences
151  * of operations since it eliminates most of the need for allocating and
152  * deallocating temporaries.
153  *
154  * <pre>
155  *   DeadMatrix_<CNT>, DeadVector_<CNT>, DeadRowVector_<CNT>
156  * </pre>
157  *
158  */
159 // TODO: matrix expression templates for delaying operator execution.
160 
161 #include "SimTKcommon/Scalar.h"
162 #include "SimTKcommon/SmallMatrix.h"
163 
164 #include "SimTKcommon/internal/MatrixHelper.h"
165 #include "SimTKcommon/internal/MatrixCharacteristics.h"
166 
167 #include <iostream>
168 #include <cassert>
169 #include <complex>
170 #include <cstddef>
171 #include <limits>
172 
173 namespace SimTK {
174 
175 #ifndef SWIG
176 template <class ELT>    class MatrixBase;
177 template <class ELT>    class VectorBase;
178 template <class ELT>    class RowVectorBase;
179 
180 template <class T=Real> class MatrixView_;
181 template <class T=Real> class DeadMatrixView_;
182 template <class T=Real> class Matrix_;
183 template <class T=Real> class DeadMatrix_;
184 
185 template <class T=Real> class VectorView_;
186 template <class T=Real> class DeadVectorView_;
187 template <class T=Real> class Vector_;
188 template <class T=Real> class DeadVector_;
189 
190 template <class T=Real> class RowVectorView_;
191 template <class T=Real> class DeadRowVectorView_;
192 template <class T=Real> class RowVector_;
193 template <class T=Real> class DeadRowVector_;
194 
195 template <class ELT, class VECTOR_CLASS> class VectorIterator;
196 
197 //  -------------------------------- MatrixBase --------------------------------
198 /// Variable-size 2d matrix of Composite Numerical Type (ELT) elements. This is
199 /// a container of such elements, it is NOT a Composite Numerical Type itself.
200 /// MatrixBase<ELT> uses MatrixHelper<S> for implementation, where S is
201 /// ELT::Scalar, that is, the underlying float, double, long double,
202 /// complex<float>, negator<conjugate<double>>,
203 /// etc. from which ELT is constructed. This is a finite set of which all
204 /// members are explicitly instantiated in the implementation code, so
205 /// clients don't have to know how anything is implemented.
206 ///
207 /// MatrixBase is the only class in the Matrix/Vector family which has any
208 /// data members (it has exactly one MatrixHelper, which itself consists only
209 /// of a single pointer to an opaque class). Thus all other objects
210 /// in this family (that is, derived from MatrixBase) are exactly the same
211 /// size in memory and may be "reinterpreted" as appropriate. For example,
212 /// a Vector may be reinterpreted as a Matrix or vice versa, provided runtime
213 /// requirements are met (e.g., exactly 1 column).
214 ///
215 /// Unlike the small matrix classes, very little is encoded in the type.
216 /// Only the element type, and matrix vs. vector vs. row are in the type;
217 /// everything else like shape, storage layout, and writability are handled
218 /// at run time.
219 //  ----------------------------------------------------------------------------
220 #endif
221 template <class ELT=double> class MatrixBase {
222 public:
223     // These typedefs are handy, but despite appearances you cannot
224     // treat a MatrixBase as a composite numerical type. That is,
225     // CNT<MatrixBase> will not compile, or if it does it won't be
226     // meaningful.
227 #ifndef SWIG
228     typedef ELT                                 E;
229     typedef typename CNT<E>::TNeg               ENeg;
230     typedef typename CNT<E>::TWithoutNegator    EWithoutNegator;
231     typedef typename CNT<E>::TReal              EReal;
232     typedef typename CNT<E>::TImag              EImag;
233     typedef typename CNT<E>::TComplex           EComplex;
234     typedef typename CNT<E>::THerm              EHerm;
235     typedef typename CNT<E>::TPosTrans          EPosTrans;
236 
237     typedef typename CNT<E>::TAbs               EAbs;
238     typedef typename CNT<E>::TStandard          EStandard;
239     typedef typename CNT<E>::TInvert            EInvert;
240     typedef typename CNT<E>::TNormalize         ENormalize;
241     typedef typename CNT<E>::TSqHermT           ESqHermT;
242     typedef typename CNT<E>::TSqTHerm           ESqTHerm;
243 
244     typedef typename CNT<E>::Scalar             EScalar;
245     typedef typename CNT<E>::Number             ENumber;
246     typedef typename CNT<E>::StdNumber          EStdNumber;
247     typedef typename CNT<E>::Precision          EPrecision;
248     typedef typename CNT<E>::ScalarNormSq       EScalarNormSq;
249 
250     typedef EScalar    Scalar;        // the underlying Scalar type
251     typedef ENumber    Number;        // negator removed from Scalar
252     typedef EStdNumber StdNumber;     // conjugate goes to complex
253     typedef EPrecision Precision;     // complex removed from StdNumber
254     typedef EScalarNormSq  ScalarNormSq;      // type of scalar^2
255 
256     typedef MatrixBase<E>                T;
257     typedef MatrixBase<ENeg>             TNeg;
258     typedef MatrixBase<EWithoutNegator>  TWithoutNegator;
259     typedef MatrixBase<EReal>            TReal;
260     typedef MatrixBase<EImag>            TImag;
261     typedef MatrixBase<EComplex>         TComplex;
262     typedef MatrixBase<EHerm>            THerm;
263     typedef MatrixBase<E>                TPosTrans;
264 
265     typedef MatrixBase<EAbs>             TAbs;
266     typedef MatrixBase<EStandard>        TStandard;
267     typedef MatrixBase<EInvert>          TInvert;
268     typedef MatrixBase<ENormalize>       TNormalize;
269     typedef MatrixBase<ESqHermT>         TSqHermT;  // ~Mat*Mat
270     typedef MatrixBase<ESqTHerm>         TSqTHerm;  // Mat*~Mat
271 
getCharacterCommitment()272     const MatrixCommitment& getCharacterCommitment() const {return helper.getCharacterCommitment();}
getMatrixCharacter()273     const MatrixCharacter& getMatrixCharacter()     const {return helper.getMatrixCharacter();}
274 
275     /// Change the handle commitment for this matrix handle; only allowed if the
276     /// handle is currently clear.
commitTo(const MatrixCommitment & mc)277     void commitTo(const MatrixCommitment& mc)
278     {   helper.commitTo(mc); }
279 
280     // This gives the resulting matrix type when (m(i,j) op P) is applied to each element.
281     // It will have element types which are the regular composite result of E op P.
282     template <class P> struct EltResult {
283         typedef MatrixBase<typename CNT<E>::template Result<P>::Mul> Mul;
284         typedef MatrixBase<typename CNT<E>::template Result<P>::Dvd> Dvd;
285         typedef MatrixBase<typename CNT<E>::template Result<P>::Add> Add;
286         typedef MatrixBase<typename CNT<E>::template Result<P>::Sub> Sub;
287     };
288 #endif
289     /// Return the number of rows m in the logical shape of this matrix.
nrow()290     int  nrow() const {return helper.nrow();}
291     /// Return the number of columns n in the logical shape of this matrix.
ncol()292     int  ncol() const {return helper.ncol();}
293 #ifndef SWIG
294     /// Return the number of elements in the \e logical shape of this matrix.
295     /// This has nothing to do with how many elements are actually stored;
296     /// it is simply the product of the logical number of rows and columns,
297     /// that is, nrow()*ncol(). Note that although each dimension is limited
298     /// to a 32 bit size, the product of those dimensions may be > 32 bits
299     /// on a 64 bit machine so the return type may be larger than that of
300     /// nrow() and ncol().
nelt()301     ptrdiff_t nelt() const {return helper.nelt();}
302 #endif
303     /// Return true if either dimension of this Matrix is resizable.
isResizeable()304     bool isResizeable() const {return getCharacterCommitment().isResizeable();}
305 
306     enum {
307         NScalarsPerElement    = CNT<E>::NActualScalars,
308         CppNScalarsPerElement = sizeof(E) / sizeof(Scalar)
309     };
310 
311     /// The default constructor builds a 0x0 matrix managed by a helper that
312     /// understands how many scalars there are in one of our elements but is
313     /// otherwise uncommitted.
MatrixBase()314     MatrixBase() : helper(NScalarsPerElement,CppNScalarsPerElement) {}
315 
316     /// This constructor allocates the default matrix a completely uncommitted
317     /// matrix commitment, given particular initial dimensions.
MatrixBase(int m,int n)318     MatrixBase(int m, int n)
319     :   helper(NScalarsPerElement,CppNScalarsPerElement,MatrixCommitment(),m,n) {}
320 #ifndef SWIG
321     /// This constructor takes a handle commitment and allocates the default
322     /// matrix for that kind of commitment. If a dimension is set to a
323     /// particular (unchangeable) value in the commitment then the initial
324     /// allocation will use that value. Unlocked dimensions are given the
325     /// smallest value consistent with other committed attributes, typically 0.
MatrixBase(const MatrixCommitment & commitment)326     explicit MatrixBase(const MatrixCommitment& commitment)
327     :   helper(NScalarsPerElement,CppNScalarsPerElement,commitment) {}
328 
329 
330     /// This constructor takes a handle commitment and allocates the default
331     /// matrix for that kind of commitment given particular initial minimum
332     /// dimensions, which cannot be larger than those permitted by the
333     /// commitment.
MatrixBase(const MatrixCommitment & commitment,int m,int n)334     MatrixBase(const MatrixCommitment& commitment, int m, int n)
335     :   helper(NScalarsPerElement,CppNScalarsPerElement,commitment,m,n) {}
336 
337     /// Copy constructor is a deep copy (not appropriate for views!).
MatrixBase(const MatrixBase & b)338     MatrixBase(const MatrixBase& b)
339       : helper(b.helper.getCharacterCommitment(),
340                b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
341 
342     /// Implicit conversion from matrix with negated elements (otherwise this
343     /// is just like the copy constructor.
MatrixBase(const TNeg & b)344     MatrixBase(const TNeg& b)
345       : helper(b.helper.getCharacterCommitment(),
346                b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
347 
348     /// Copy assignment is a deep copy but behavior depends on type of lhs: if
349     /// view, rhs must match. If owner, we reallocate and copy rhs.
copyAssign(const MatrixBase & b)350     MatrixBase& copyAssign(const MatrixBase& b) {
351         helper.copyAssign(b.helper);
352         return *this;
353     }
354     MatrixBase& operator=(const MatrixBase& b) { return copyAssign(b); }
355 
356 
357     /// View assignment is a shallow copy, meaning that we disconnect the MatrixBase
358     /// from whatever it used to refer to (destructing as necessary), then make it a new view
359     /// for the data descriptor referenced by the source.
360     /// CAUTION: we always take the source as const, but that is ignored in
361     /// determining whether the resulting view is writable. Instead, that is
362     /// inherited from the writability status of the source. We have to do this
363     /// in order to allow temporary view objects to be writable -- the compiler
364     /// creates temporaries like m(i,j,m,n) as const.
viewAssign(const MatrixBase & src)365     MatrixBase& viewAssign(const MatrixBase& src) {
366         helper.writableViewAssign(const_cast<MatrixHelper<Scalar>&>(src.helper));
367         return *this;
368     }
369 
370     // default destructor
371 
372     /// Initializing constructor with all of the initially-allocated elements
373     /// initialized to the same value. The given dimensions are treated as
374     /// minimum dimensions in case the commitment requires more. So it is
375     /// always permissible to set them both to 0 in which case you'll get
376     /// the smallest matrix that satisfies the commitment, with each of its
377     /// elements (if any) set to the given initial value.
MatrixBase(const MatrixCommitment & commitment,int m,int n,const ELT & initialValue)378     MatrixBase(const MatrixCommitment& commitment, int m, int n, const ELT& initialValue)
379     :   helper(NScalarsPerElement, CppNScalarsPerElement, commitment, m, n)
380     {   helper.fillWith(reinterpret_cast<const Scalar*>(&initialValue)); }
381 
382     /// Initializing constructor with the initially-allocated elements
383     /// initialized from a C++ array of elements, which is provided in
384     /// <i>row major</i> order. The given dimensions are treated as
385     /// minimum dimensions in case the commitment requires more. The
386     /// array is presumed to be long enough to supply a value for each
387     /// element. Note that C++ packing for elements may be different than
388     /// Simmatrix packing of the same elements (Simmatrix packs them
389     /// more tightly in some cases). So you should not use this constructor
390     /// to copy elements from one Simmatrix matrix to another; this is
391     /// exclusively for initializing a Simmatrix from a C++ array.
MatrixBase(const MatrixCommitment & commitment,int m,int n,const ELT * cppInitialValuesByRow)392     MatrixBase(const MatrixCommitment& commitment, int m, int n,
393                const ELT* cppInitialValuesByRow)
394     :   helper(NScalarsPerElement, CppNScalarsPerElement, commitment, m, n)
395     {   helper.copyInByRowsFromCpp(reinterpret_cast<const Scalar*>(cppInitialValuesByRow)); }
396 
397     /// @name           Matrix view of pre-exising data
398     ///
399     /// Non-resizeable view of someone else's already-allocated
400     /// memory of a size and storage type indicated by the supplied
401     /// MatrixCharacter. The \a spacing argument has different interpretations
402     /// depending on the storage format. Typically it is the leading
403     /// dimension for Lapack-style full storage or stride for a vector.
404     /// Spacing is in units like "number of scalars between elements" or
405     /// "number of scalars between columns" so it can be used to deal
406     /// with C++ packing vs. Simmatrix packing if necessary.
407     /// @{
408 
409     /// Construct a read-only view of pre-existing data.
MatrixBase(const MatrixCommitment & commitment,const MatrixCharacter & character,int spacing,const Scalar * data)410     MatrixBase(const MatrixCommitment& commitment,
411                const MatrixCharacter&  character,
412                int spacing, const Scalar* data) // read only data
413     :   helper(NScalarsPerElement, CppNScalarsPerElement,
414                commitment, character, spacing, data) {}
415 
416     /// Construct a writable view of pre-existing data.
MatrixBase(const MatrixCommitment & commitment,const MatrixCharacter & character,int spacing,Scalar * data)417     MatrixBase(const MatrixCommitment& commitment,
418                const MatrixCharacter&  character,
419                int spacing, Scalar* data) // writable data
420     :   helper(NScalarsPerElement, CppNScalarsPerElement,
421                commitment, character, spacing, data) {}
422     /// @}
423 
424     // Create a new MatrixBase from an existing helper. Both shallow and deep copies are possible.
MatrixBase(const MatrixCommitment & commitment,MatrixHelper<Scalar> & source,const typename MatrixHelper<Scalar>::ShallowCopy & shallow)425     MatrixBase(const MatrixCommitment& commitment,
426                MatrixHelper<Scalar>&   source,
427                const typename MatrixHelper<Scalar>::ShallowCopy& shallow)
428     :   helper(commitment, source, shallow) {}
MatrixBase(const MatrixCommitment & commitment,const MatrixHelper<Scalar> & source,const typename MatrixHelper<Scalar>::ShallowCopy & shallow)429     MatrixBase(const MatrixCommitment&      commitment,
430                const MatrixHelper<Scalar>&  source,
431                const typename MatrixHelper<Scalar>::ShallowCopy& shallow)
432     :   helper(commitment, source, shallow) {}
MatrixBase(const MatrixCommitment & commitment,const MatrixHelper<Scalar> & source,const typename MatrixHelper<Scalar>::DeepCopy & deep)433     MatrixBase(const MatrixCommitment&      commitment,
434                const MatrixHelper<Scalar>&  source,
435                const typename MatrixHelper<Scalar>::DeepCopy& deep)
436     :   helper(commitment, source, deep) {}
437 #endif
438     /// This restores the MatrixBase to the state it would be in had it
439     /// been constructed specifying only its handle commitment. The size will
440     /// have been reduced to the smallest size consistent with the commitment.
clear()441     void clear() {helper.clear();}
442 #ifndef SWIG
443     MatrixBase& operator*=(const StdNumber& t)  { helper.scaleBy(t);              return *this; }
444     MatrixBase& operator/=(const StdNumber& t)  { helper.scaleBy(StdNumber(1)/t); return *this; }
445     MatrixBase& operator+=(const MatrixBase& r) { helper.addIn(r.helper);         return *this; }
446     MatrixBase& operator-=(const MatrixBase& r) { helper.subIn(r.helper);         return *this; }
447 
MatrixBase(const MatrixBase<EE> & b)448     template <class EE> MatrixBase(const MatrixBase<EE>& b)
449       : helper(MatrixCommitment(),b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
450 
451     template <class EE> MatrixBase& operator=(const MatrixBase<EE>& b)
452       { helper = b.helper; return *this; }
453     template <class EE> MatrixBase& operator+=(const MatrixBase<EE>& b)
454       { helper.addIn(b.helper); return *this; }
455     template <class EE> MatrixBase& operator-=(const MatrixBase<EE>& b)
456       { helper.subIn(b.helper); return *this; }
457 
458     /// Matrix assignment to an element sets only the *diagonal* elements to
459     /// the indicated value; everything else is set to zero. This is particularly
460     /// useful for setting a Matrix to zero or to the identity; for other values
461     /// it creates a Matrix which acts like the scalar. That is, if the scalar
462     /// is s and we do M=s, then multiplying another Matrix B by the resulting
463     /// diagonal matrix M gives the same result as multiplying B by s. That is
464     /// (M=s)*B == s*B.
465     ///
466     /// NOTE: this must be overridden for Vector and RowVector since then scalar
467     /// assignment is defined to copy the scalar to every element.
468     MatrixBase& operator=(const ELT& t) {
469         setToZero(); updDiag().setTo(t);
470         return *this;
471     }
472 
473     /// Set M's diagonal elements to a "scalar" value S, and all off-diagonal
474     /// elements to zero. S can be any type which is assignable to an element
475     /// of type E. This is the same as the Matrix assignment operator M=S for
476     /// a scalar type S. It is overriden for Vector and Row types to behave
477     /// as elementwiseScalarAssign.
478     template <class S> inline MatrixBase&
scalarAssign(const S & s)479     scalarAssign(const S& s) {
480         setToZero(); updDiag().setTo(s);
481         return *this;
482     }
483 
484     /// Add a scalar to M's diagonal. This is the same as the Matrix +=
485     /// operator. This is overridden for Vector and Row types to behave
486     /// as elementwiseAddScalarInPlace.
487     template <class S> inline MatrixBase&
scalarAddInPlace(const S & s)488     scalarAddInPlace(const S& s) {
489         updDiag().elementwiseAddScalarInPlace(s);
490     }
491 
492 
493     /// Subtract a scalar from M's diagonal. This is the same as the Matrix -=
494     /// operator. This is overridden for Vector and Row types to behave
495     /// as elementwiseSubtractScalarInPlace.
496     template <class S> inline MatrixBase&
scalarSubtractInPlace(const S & s)497     scalarSubtractInPlace(const S& s) {
498         updDiag().elementwiseSubtractScalarInPlace(s);
499     }
500 
501     /// Set M(i,i) = S - M(i,i), M(i,j) = -M(i,j) for i!=j. This is overridden
502     /// for Vector and Row types to behave as elementwiseSubtractFromScalarInPlace.
503     template <class S> inline MatrixBase&
scalarSubtractFromLeftInPlace(const S & s)504     scalarSubtractFromLeftInPlace(const S& s) {
505         negateInPlace();
506         updDiag().elementwiseAddScalarInPlace(s); // yes, add
507     }
508 
509     /// Set M(i,j) = M(i,j)*S for some "scalar" S. Actually S can be any
510     /// type for which E = E*S makes sense. That is, S must be conformant
511     /// with E and it must be possible to store the result back in an E.
512     /// This is the *= operator for M *= S and behaves the same way for
513     /// Matrix, Vector, and RowVector: every element gets multiplied in
514     /// place on the right by S.
515     template <class S> inline MatrixBase&
516     scalarMultiplyInPlace(const S&);
517 
518     /// Set M(i,j) = S * M(i,j) for some "scalar" S. This is the same
519     /// as the above routine if S really is a scalar, but for S a more
520     /// complicated CNT it will be different.
521     template <class S> inline MatrixBase&
522     scalarMultiplyFromLeftInPlace(const S&);
523 
524     /// Set M(i,j) = M(i,j)/S for some "scalar" S. Actually S can be any
525     /// type for which E = E/S makes sense. That is, S^-1 must be conformant
526     /// with E and it must be possible to store the result back in an E.
527     /// This is the /= operator for M /= S and behaves the same way for
528     /// Matrix, Vector, and RowVector: every element gets divided in
529     /// place on the right by S.
530     template <class S> inline MatrixBase&
531     scalarDivideInPlace(const S&);
532 
533     /// Set M(i,j) = S/M(i,j) for some "scalar" S. Actually S can be any
534     /// type for which E = S/E makes sense. That is, S must be conformant
535     /// with E^-1 and it must be possible to store the result back in an E.
536     template <class S> inline MatrixBase&
537     scalarDivideFromLeftInPlace(const S&);
538 
539 
540     /// M = diag(r) * M; r must have nrow() elements.
541     /// That is, M[i] *= r[i].
542     template <class EE> inline MatrixBase&
543     rowScaleInPlace(const VectorBase<EE>&);
544 
545     /// Return type is a new matrix which will have the same dimensions as 'this' but
546     /// will have element types appropriate for the elementwise multiply being performed.
547     template <class EE> inline void
548     rowScale(const VectorBase<EE>& r, typename EltResult<EE>::Mul& out) const;
549 
550     template <class EE> inline typename EltResult<EE>::Mul
rowScale(const VectorBase<EE> & r)551     rowScale(const VectorBase<EE>& r) const {
552         typename EltResult<EE>::Mul out(nrow(), ncol()); rowScale(r,out); return out;
553     }
554 
555     /// M = M * diag(c); c must have ncol() elements.
556     /// That is, M(j) *= c[j].
557     template <class EE> inline MatrixBase&
558     colScaleInPlace(const VectorBase<EE>&);
559 
560     template <class EE> inline void
561     colScale(const VectorBase<EE>& c, typename EltResult<EE>::Mul& out) const;
562 
563     template <class EE> inline typename EltResult<EE>::Mul
colScale(const VectorBase<EE> & c)564     colScale(const VectorBase<EE>& c) const {
565         typename EltResult<EE>::Mul out(nrow(), ncol()); colScale(c,out); return out;
566     }
567 
568 
569     /// M = diag(r) * M * diag(c); r must have nrow() elements;  must have ncol() elements.
570     /// That is, M(i,j) *= r[i]*c[j].
571     /// Having a combined row & column scaling operator means we can go through the matrix
572     /// memory once instead of twice.
573     template <class ER, class EC> inline MatrixBase&
574     rowAndColScaleInPlace(const VectorBase<ER>& r, const VectorBase<EC>& c);
575 
576     template <class ER, class EC> inline void
577     rowAndColScale(const VectorBase<ER>& r, const VectorBase<EC>& c,
578                    typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul& out) const;
579 
580     template <class ER, class EC> inline typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul
rowAndColScale(const VectorBase<ER> & r,const VectorBase<EC> & c)581     rowAndColScale(const VectorBase<ER>& r, const VectorBase<EC>& c) const {
582         typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul
583             out(nrow(), ncol());
584         rowAndColScale(r,c,out); return out;
585     }
586 
587     /// Set M(i,j)=s for every element of M and some value s. This requires only
588     /// that s be assignment compatible with M's elements; s doesn't
589     /// actually have to be a scalar. Note that for Matrix types this behavior
590     /// is different than scalar assignment, which puts the scalar only on M's
591     /// diagonal and sets the rest of M to zero. For Vector and RowVector types,
592     /// this operator is identical to the normal assignment operator and
593     /// scalarAssignInPlace() method which also assign the scalar to every element.
594     template <class S> inline MatrixBase&
595     elementwiseAssign(const S& s);
596 
597     /// Overloaded to allow an integer argument, which is converted to Real.
elementwiseAssign(int s)598     MatrixBase& elementwiseAssign(int s)
599     {   return elementwiseAssign<Real>(Real(s)); }
600 
601     /// Set M(i,j) = M(i,j)^-1.
602     MatrixBase& elementwiseInvertInPlace();
603 
604     void elementwiseInvert(MatrixBase<typename CNT<E>::TInvert>& out) const;
605 
elementwiseInvert()606     MatrixBase<typename CNT<E>::TInvert> elementwiseInvert() const {
607         MatrixBase<typename CNT<E>::TInvert> out(nrow(), ncol());
608         elementwiseInvert(out);
609         return out;
610     }
611 
612     /// Set M(i,j)+=s for every element of M and some value s. This requires that s be
613     /// conformant with M's elements (of type E) and that the result can
614     /// be stored in an E. For Matrix types this behavior is different than
615     /// the normal += or scalarAddInPlace() operators, which add the scalar
616     /// only to the Matrix diagonal. For Vector and RowVector, this operator
617     /// is identical to += and scalarAddInPlace() which also add the scalar
618     /// to every element.
619     template <class S> inline MatrixBase&
620     elementwiseAddScalarInPlace(const S& s);
621 
622     template <class S> inline void
623     elementwiseAddScalar(const S& s, typename EltResult<S>::Add&) const;
624 
625     template <class S> inline typename EltResult<S>::Add
elementwiseAddScalar(const S & s)626     elementwiseAddScalar(const S& s) const {
627         typename EltResult<S>::Add out(nrow(), ncol());
628         elementwiseAddScalar(s,out);
629         return out;
630     }
631 
632     /// Set M(i,j)-=s for every element of M and some value s. This requires that s be
633     /// conformant with M's elements (of type E) and that the result can
634     /// be stored in an E. For Matrix types this behavior is different than
635     /// the normal -= or scalarSubtractInPlace() operators, which subtract the scalar
636     /// only from the Matrix diagonal. For Vector and RowVector, this operator
637     /// is identical to -= and scalarSubtractInPlace() which also subtract the scalar
638     /// from every element.
639     template <class S> inline MatrixBase&
640     elementwiseSubtractScalarInPlace(const S& s);
641 
642     template <class S> inline void
643     elementwiseSubtractScalar(const S& s, typename EltResult<S>::Sub&) const;
644 
645     template <class S> inline typename EltResult<S>::Sub
elementwiseSubtractScalar(const S & s)646     elementwiseSubtractScalar(const S& s) const {
647         typename EltResult<S>::Sub out(nrow(), ncol());
648         elementwiseSubtractScalar(s,out);
649         return out;
650     }
651 
652     /// Set M(i,j) = s - M(i,j) for every element of M and some value s. This requires that s be
653     /// conformant with M's elements (of type E) and that the result can
654     /// be stored in an E. For Matrix types this behavior is different than
655     /// the scalarSubtractFromLeftInPlace() operator, which subtracts only the diagonal
656     /// elements of M from s, while simply negating the off diagonal elements.
657     /// For Vector and RowVector, this operator
658     /// is identical to scalarSubtractFromLeftInPlace() which also subtracts every
659     /// element of M from the scalar.
660     template <class S> inline MatrixBase&
661     elementwiseSubtractFromScalarInPlace(const S& s);
662 
663     template <class S> inline void
664     elementwiseSubtractFromScalar(
665         const S&,
666         typename MatrixBase<S>::template EltResult<E>::Sub&) const;
667 
668     template <class S> inline typename MatrixBase<S>::template EltResult<E>::Sub
elementwiseSubtractFromScalar(const S & s)669     elementwiseSubtractFromScalar(const S& s) const {
670         typename MatrixBase<S>::template EltResult<E>::Sub out(nrow(), ncol());
671         elementwiseSubtractFromScalar<S>(s,out);
672         return out;
673     }
674 
675     /// M(i,j) *= R(i,j); R must have same dimensions as this.
676     template <class EE> inline MatrixBase&
677     elementwiseMultiplyInPlace(const MatrixBase<EE>&);
678 
679     template <class EE> inline void
680     elementwiseMultiply(const MatrixBase<EE>&, typename EltResult<EE>::Mul&) const;
681 
682     template <class EE> inline typename EltResult<EE>::Mul
elementwiseMultiply(const MatrixBase<EE> & m)683     elementwiseMultiply(const MatrixBase<EE>& m) const {
684         typename EltResult<EE>::Mul out(nrow(), ncol());
685         elementwiseMultiply<EE>(m,out);
686         return out;
687     }
688 
689     /// M(i,j) = R(i,j) * M(i,j); R must have same dimensions as this.
690     template <class EE> inline MatrixBase&
691     elementwiseMultiplyFromLeftInPlace(const MatrixBase<EE>&);
692 
693     template <class EE> inline void
694     elementwiseMultiplyFromLeft(
695         const MatrixBase<EE>&,
696         typename MatrixBase<EE>::template EltResult<E>::Mul&) const;
697 
698     template <class EE> inline typename MatrixBase<EE>::template EltResult<E>::Mul
elementwiseMultiplyFromLeft(const MatrixBase<EE> & m)699     elementwiseMultiplyFromLeft(const MatrixBase<EE>& m) const {
700         typename EltResult<EE>::Mul out(nrow(), ncol());
701         elementwiseMultiplyFromLeft<EE>(m,out);
702         return out;
703     }
704 
705     /// M(i,j) /= R(i,j); R must have same dimensions as this.
706     template <class EE> inline MatrixBase&
707     elementwiseDivideInPlace(const MatrixBase<EE>&);
708 
709     template <class EE> inline void
710     elementwiseDivide(const MatrixBase<EE>&, typename EltResult<EE>::Dvd&) const;
711 
712     template <class EE> inline typename EltResult<EE>::Dvd
elementwiseDivide(const MatrixBase<EE> & m)713     elementwiseDivide(const MatrixBase<EE>& m) const {
714         typename EltResult<EE>::Dvd out(nrow(), ncol());
715         elementwiseDivide<EE>(m,out);
716         return out;
717     }
718 
719     /// M(i,j) = R(i,j) / M(i,j); R must have same dimensions as this.
720     template <class EE> inline MatrixBase&
721     elementwiseDivideFromLeftInPlace(const MatrixBase<EE>&);
722 
723     template <class EE> inline void
724     elementwiseDivideFromLeft(
725         const MatrixBase<EE>&,
726         typename MatrixBase<EE>::template EltResult<E>::Dvd&) const;
727 
728     template <class EE> inline typename MatrixBase<EE>::template EltResult<EE>::Dvd
elementwiseDivideFromLeft(const MatrixBase<EE> & m)729     elementwiseDivideFromLeft(const MatrixBase<EE>& m) const {
730         typename MatrixBase<EE>::template EltResult<E>::Dvd out(nrow(), ncol());
731         elementwiseDivideFromLeft<EE>(m,out);
732         return out;
733     }
734 #endif
735     /// Fill every element in current allocation with given element (or NaN or 0).
setTo(const ELT & t)736     MatrixBase& setTo(const ELT& t) {helper.fillWith(reinterpret_cast<const Scalar*>(&t)); return *this;}
setToNaN()737     MatrixBase& setToNaN() {helper.fillWithScalar(CNT<StdNumber>::getNaN()); return *this;}
setToZero()738     MatrixBase& setToZero() {helper.fillWithScalar(StdNumber(0)); return *this;}
739  #ifndef SWIG
740     // View creating operators. TODO: these should be DeadMatrixViews
741     inline RowVectorView_<ELT> row(int i) const;   // select a row
742     inline RowVectorView_<ELT> updRow(int i);
743     inline VectorView_<ELT>    col(int j) const;   // select a column
744     inline VectorView_<ELT>    updCol(int j);
745 
746     RowVectorView_<ELT> operator[](int i) const {return row(i);}
747     RowVectorView_<ELT> operator[](int i)       {return updRow(i);}
operator()748     VectorView_<ELT>    operator()(int j) const {return col(j);}
operator()749     VectorView_<ELT>    operator()(int j)       {return updCol(j);}
750 
751     // Select a block.
752     inline MatrixView_<ELT> block(int i, int j, int m, int n) const;
753     inline MatrixView_<ELT> updBlock(int i, int j, int m, int n);
754 
operator()755     MatrixView_<ELT> operator()(int i, int j, int m, int n) const
756       { return block(i,j,m,n); }
operator()757     MatrixView_<ELT> operator()(int i, int j, int m, int n)
758       { return updBlock(i,j,m,n); }
759 
760     // Hermitian transpose.
761     inline MatrixView_<EHerm> transpose() const;
762     inline MatrixView_<EHerm> updTranspose();
763 
764     MatrixView_<EHerm> operator~() const {return transpose();}
765     MatrixView_<EHerm> operator~()       {return updTranspose();}
766 
767     /// Select main diagonal (of largest leading square if rectangular) and
768     /// return it as a read-only view of the diagonal elements of this Matrix.
769     inline VectorView_<ELT> diag() const;
770     /// Select main diagonal (of largest leading square if rectangular) and
771     /// return it as a writable view of the diagonal elements of this Matrix.
772     inline VectorView_<ELT> updDiag();
773     /// This non-const version of diag() is an alternate name for updDiag()
774     /// available for historical reasons.
diag()775     VectorView_<ELT> diag() {return updDiag();}
776 
777     // Create a view of the real or imaginary elements. TODO
778     //inline MatrixView_<EReal> real() const;
779     //inline MatrixView_<EReal> updReal();
780     //inline MatrixView_<EImag> imag() const;
781     //inline MatrixView_<EImag> updImag();
782 
783     // Overload "real" and "imag" for both read and write as a nod to convention. TODO
784     //MatrixView_<EReal> real() {return updReal();}
785     //MatrixView_<EReal> imag() {return updImag();}
786 
787     // TODO: this routine seems ill-advised but I need it for the IVM port at the moment
invert()788     TInvert invert() const {  // return a newly-allocated inverse; dump negator
789         TInvert m(*this);
790         m.helper.invertInPlace();
791         return m;   // TODO - bad: makes an extra copy
792     }
793 
invertInPlace()794     void invertInPlace() {helper.invertInPlace();}
795 
796     /// Matlab-compatible debug output.
797     void dump(const char* msg=0) const {
798         helper.dump(msg);
799     }
800 
801 
802     // This routine is useful for implementing friendlier Matrix expressions and operators.
803     // It maps closely to the Level-3 BLAS family of pxxmm() routines like sgemm(). The
804     // operation performed assumes that "this" is the result, and that "this" has
805     // already been sized correctly to receive the result. We'll compute
806     //     this = beta*this + alpha*A*B
807     // If beta is 0 then "this" can be uninitialized. If alpha is 0 we promise not
808     // to look at A or B. The routine can work efficiently even if A and/or B are transposed
809     // by their views, so an expression like
810     //        C += s * ~A * ~B
811     // can be performed with the single equivalent call
812     //        C.matmul(1., s, Tr(A), Tr(B))
813     // where Tr(A) indicates a transposed view of the original A.
814     // The ultimate efficiency of this call depends on the data layout and views which
815     // are used for the three matrices.
816     // NOTE: neither A nor B can be the same matrix as 'this', nor views of the same data
817     // which would expose elements of 'this' that will be modified by this operation.
818     template <class ELT_A, class ELT_B>
matmul(const StdNumber & beta,const StdNumber & alpha,const MatrixBase<ELT_A> & A,const MatrixBase<ELT_B> & B)819     MatrixBase& matmul(const StdNumber& beta,   // applied to 'this'
820                        const StdNumber& alpha, const MatrixBase<ELT_A>& A, const MatrixBase<ELT_B>& B)
821     {
822         helper.matmul(beta,alpha,A.helper,B.helper);
823         return *this;
824     }
825 #endif
826     /// Element selection for stored elements. These are the fastest element access
827     /// methods but may not be able to access all elements of the logical matrix when
828     /// some of its elements are not stored in memory. For example, a Hermitian matrix
829     /// stores only half its elements and other ones have to be calculated by conjugation
830     /// if they are to be returned as type ELT. (You can get them for free by recasting
831     /// the matrix so that the elements are reinterpreted as conjugates.) If you want
832     /// to guarantee that you can access the value of every element of a matrix, stored or not,
833     /// use getAnyElt() instead.
getElt(int i,int j)834     const ELT& getElt(int i, int j) const { return *reinterpret_cast<const ELT*>(helper.getElt(i,j)); }
835 #ifndef SWIG
updElt(int i,int j)836     ELT&       updElt(int i, int j)       { return *reinterpret_cast<      ELT*>(helper.updElt(i,j)); }
837 
operator()838     const ELT& operator()(int i, int j) const {return getElt(i,j);}
operator()839     ELT&       operator()(int i, int j)       {return updElt(i,j);}
840 
841     /// This returns a copy of the element value for any position in the logical matrix,
842     /// regardless of whether it is stored in memory. If necessary the element's value
843     /// is calculated. This is much slower than getElt() but less restrictive.
844     /// @see getElt()
getAnyElt(int i,int j,ELT & value)845     void getAnyElt(int i, int j, ELT& value) const
846     {   helper.getAnyElt(i,j,reinterpret_cast<Scalar*>(&value)); }
getAnyElt(int i,int j)847     ELT getAnyElt(int i, int j) const {ELT e; getAnyElt(i,j,e); return e;}
848 
849     /// Scalar norm square is sum( squares of all scalars ). Note that this
850     /// is not very useful unless the elements are themselves scalars.
851     // TODO: very slow! Should be optimized at least for the case
852     //       where ELT is a Scalar.
scalarNormSqr()853     ScalarNormSq scalarNormSqr() const {
854         const int nr=nrow(), nc=ncol();
855         ScalarNormSq sum(0);
856         for(int j=0;j<nc;++j)
857             for (int i=0; i<nr; ++i)
858                 sum += CNT<E>::scalarNormSqr((*this)(i,j));
859         return sum;
860     }
861 
862     /// abs() is elementwise absolute value; that is, the return value has the same
863     /// dimension as this Matrix but with each element replaced by whatever it thinks
864     /// its absolute value is.
865     // TODO: very slow! Should be optimized at least for the case
866     //       where ELT is a Scalar.
abs(TAbs & mabs)867     void abs(TAbs& mabs) const {
868         const int nr=nrow(), nc=ncol();
869         mabs.resize(nr,nc);
870         for(int j=0;j<nc;++j)
871             for (int i=0; i<nr; ++i)
872                 mabs(i,j) = CNT<E>::abs((*this)(i,j));
873     }
874 
875     /// abs() with the result as a function return. More convenient than the
876     /// other abs() member function, but may involve an additional copy of the
877     /// matrix.
abs()878     TAbs abs() const { TAbs mabs; abs(mabs); return mabs; }
879 
880     /// Return a Matrix of the same shape and contents as this one but
881     /// with the element type converted to one based on the standard
882     /// C++ scalar types: float, double, complex<float>,
883     /// complex<double>. That is, negator<>
884     /// and conjugate<> are eliminated from the element type by
885     /// performing any needed negations computationally.
886     /// Note that this is actually producing a new matrix with new data;
887     /// you can also do this for free by reinterpreting the current
888     /// matrix as a different type, if you don't mind looking at
889     /// shared data.
standardize()890     TStandard standardize() const {
891         const int nr=nrow(), nc=ncol();
892         TStandard mstd(nr, nc);
893         for(int j=0;j<nc;++j)
894             for (int i=0; i<nr; ++i)
895                 mstd(i,j) = CNT<E>::standardize((*this)(i,j));
896         return mstd;
897     }
898 
899     /// This is the scalar Frobenius norm, and its square. Note: if this is a
900     /// Matrix then the Frobenius norm is NOT the same as the 2-norm, although
901     /// they are equivalent for Vectors.
normSqr()902     ScalarNormSq normSqr() const { return scalarNormSqr(); }
903     // TODO -- not good; unnecessary overflow
904     typename CNT<ScalarNormSq>::TSqrt
norm()905         norm() const { return CNT<ScalarNormSq>::sqrt(scalarNormSqr()); }
906 
907     /// We only allow RMS norm if the elements are scalars. If there are no
908     /// elements in this Matrix, we'll define its RMS norm to be 0, although
909     /// NaN might be a better choice.
910     typename CNT<ScalarNormSq>::TSqrt
normRMS()911     normRMS() const {
912         if (!CNT<ELT>::IsScalar)
913             SimTK_THROW1(Exception::Cant, "normRMS() only defined for scalar elements");
914         if (nelt() == 0)
915             return typename CNT<ScalarNormSq>::TSqrt(0);
916         return CNT<ScalarNormSq>::sqrt(scalarNormSqr()/nelt());
917     }
918 
919     /// Form the column sums of this matrix, returned as a RowVector.
colSum()920     RowVector_<ELT> colSum() const {
921         const int cols = ncol();
922         RowVector_<ELT> row(cols);
923         for (int j = 0; j < cols; ++j)
924             helper.colSum(j, reinterpret_cast<Scalar*>(&row[j]));
925         return row;
926     }
927     /// Alternate name for colSum(); behaves like the Matlab function sum().
sum()928     RowVector_<ELT> sum() const {return colSum();}
929 
930     /// Form the row sums of this matrix, returned as a Vector.
rowSum()931     Vector_<ELT> rowSum() const {
932         const int rows = nrow();
933         Vector_<ELT> col(rows);
934         for (int i = 0; i < rows; ++i)
935             helper.rowSum(i, reinterpret_cast<Scalar*>(&col[i]));
936         return col;
937     }
938 
939     //TODO: make unary +/- return a self-view so they won't reallocate?
940     const MatrixBase& operator+() const {return *this; }
negate()941     const TNeg&       negate()    const {return *reinterpret_cast<const TNeg*>(this); }
updNegate()942     TNeg&             updNegate()       {return *reinterpret_cast<TNeg*>(this); }
943 
944     const TNeg&       operator-() const {return negate();}
945     TNeg&             operator-()       {return updNegate();}
946 #endif
negateInPlace()947     MatrixBase& negateInPlace() {(*this) *= EPrecision(-1); return *this;}
948 
949     /// Change the size of this matrix. This is only allowed for owner matrices. The
950     /// current storage format is retained, but all the data is lost. If you want
951     /// to keep the old data, use resizeKeep().
952     /// @see resizeKeep()
resize(int m,int n)953     MatrixBase& resize(int m, int n)     { helper.resize(m,n); return *this; }
954     /// Change the size of this matrix, retaining as much of the old data as will
955     /// fit. This is only allowed for owner matrices. The
956     /// current storage format is retained, and the existing data is copied
957     /// into the new memory to the extent that it will fit.
958     /// @see resize()
resizeKeep(int m,int n)959     MatrixBase& resizeKeep(int m, int n) { helper.resizeKeep(m,n); return *this; }
960 
961     // This prevents shape changes in a Matrix that would otherwise allow it. No harm if is
962     // are called on a Matrix that is locked already; it always succeeds.
lockShape()963     void lockShape() {helper.lockShape();}
964 
965     // This allows shape changes again for a Matrix which was constructed to allow them
966     // but had them locked with the above routine. No harm if this is called on a Matrix
967     // that is already unlocked, but it is not allowed to call this on a Matrix which
968     // *never* allowed resizing. An exception will be thrown in that case.
unlockShape()969     void unlockShape() {helper.unlockShape();}
970  #ifndef SWIG
971     // An assortment of handy conversions
getAsMatrixView()972     const MatrixView_<ELT>& getAsMatrixView() const { return *reinterpret_cast<const MatrixView_<ELT>*>(this); }
updAsMatrixView()973     MatrixView_<ELT>&       updAsMatrixView()       { return *reinterpret_cast<      MatrixView_<ELT>*>(this); }
getAsMatrix()974     const Matrix_<ELT>&     getAsMatrix()     const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
updAsMatrix()975     Matrix_<ELT>&           updAsMatrix()           { return *reinterpret_cast<      Matrix_<ELT>*>(this); }
976 
getAsVectorView()977     const VectorView_<ELT>& getAsVectorView() const
978       { assert(ncol()==1); return *reinterpret_cast<const VectorView_<ELT>*>(this); }
updAsVectorView()979     VectorView_<ELT>&       updAsVectorView()
980       { assert(ncol()==1); return *reinterpret_cast<      VectorView_<ELT>*>(this); }
getAsVector()981     const Vector_<ELT>&     getAsVector()     const
982       { assert(ncol()==1); return *reinterpret_cast<const Vector_<ELT>*>(this); }
updAsVector()983     Vector_<ELT>&           updAsVector()
984       { assert(ncol()==1); return *reinterpret_cast<      Vector_<ELT>*>(this); }
getAsVectorBase()985     const VectorBase<ELT>& getAsVectorBase() const
986       { assert(ncol()==1); return *reinterpret_cast<const VectorBase<ELT>*>(this); }
updAsVectorBase()987     VectorBase<ELT>&       updAsVectorBase()
988       { assert(ncol()==1); return *reinterpret_cast<      VectorBase<ELT>*>(this); }
989 
getAsRowVectorView()990     const RowVectorView_<ELT>& getAsRowVectorView() const
991       { assert(nrow()==1); return *reinterpret_cast<const RowVectorView_<ELT>*>(this); }
updAsRowVectorView()992     RowVectorView_<ELT>&       updAsRowVectorView()
993       { assert(nrow()==1); return *reinterpret_cast<      RowVectorView_<ELT>*>(this); }
getAsRowVector()994     const RowVector_<ELT>&     getAsRowVector()     const
995       { assert(nrow()==1); return *reinterpret_cast<const RowVector_<ELT>*>(this); }
updAsRowVector()996     RowVector_<ELT>&           updAsRowVector()
997       { assert(nrow()==1); return *reinterpret_cast<      RowVector_<ELT>*>(this); }
getAsRowVectorBase()998     const RowVectorBase<ELT>& getAsRowVectorBase() const
999       { assert(nrow()==1); return *reinterpret_cast<const RowVectorBase<ELT>*>(this); }
updAsRowVectorBase()1000     RowVectorBase<ELT>&       updAsRowVectorBase()
1001       { assert(nrow()==1); return *reinterpret_cast<      RowVectorBase<ELT>*>(this); }
1002 
1003     // Access to raw data. We have to return the raw data
1004     // pointer as pointer-to-scalar because we may pack the elements tighter
1005     // than a C++ array would.
1006 
1007     /// This is the number of consecutive scalars used to represent one
1008     /// element of type ELT. This may be fewer than C++ would use for the
1009     /// element, since it may introduce some padding.
getNScalarsPerElement()1010     int getNScalarsPerElement()  const {return NScalarsPerElement;}
1011 
1012     /// This is like sizeof(ELT), but returning the number of bytes \e we use
1013     /// to store the element which may be fewer than what C++ would use. We store
1014     /// these packed elements adjacent to one another in memory.
getPackedSizeofElement()1015     int getPackedSizeofElement() const {return NScalarsPerElement*sizeof(Scalar);}
1016 
hasContiguousData()1017     bool hasContiguousData() const {return helper.hasContiguousData();}
getContiguousScalarDataLength()1018     ptrdiff_t getContiguousScalarDataLength() const {
1019         return helper.getContiguousDataLength();
1020     }
getContiguousScalarData()1021     const Scalar* getContiguousScalarData() const {
1022         return helper.getContiguousData();
1023     }
updContiguousScalarData()1024     Scalar* updContiguousScalarData() {
1025         return helper.updContiguousData();
1026     }
replaceContiguousScalarData(Scalar * newData,ptrdiff_t length,bool takeOwnership)1027     void replaceContiguousScalarData(Scalar* newData, ptrdiff_t length, bool takeOwnership) {
1028         helper.replaceContiguousData(newData,length,takeOwnership);
1029     }
replaceContiguousScalarData(const Scalar * newData,ptrdiff_t length)1030     void replaceContiguousScalarData(const Scalar* newData, ptrdiff_t length) {
1031         helper.replaceContiguousData(newData,length);
1032     }
swapOwnedContiguousScalarData(Scalar * newData,ptrdiff_t length,Scalar * & oldData)1033     void swapOwnedContiguousScalarData(Scalar* newData, ptrdiff_t length, Scalar*& oldData) {
1034         helper.swapOwnedContiguousData(newData,length,oldData);
1035     }
1036 
1037     /// Helper rep-stealing constructor. We take over ownership of this rep here. Note
1038     /// that this \e defines the handle commitment for this handle. This is intended
1039     /// for internal use only -- don't call this constructor unless you really
1040     /// know what you're doing.
MatrixBase(MatrixHelperRep<Scalar> * hrep)1041     explicit MatrixBase(MatrixHelperRep<Scalar>* hrep) : helper(hrep) {}
1042 
1043 protected:
getHelper()1044     const MatrixHelper<Scalar>& getHelper() const {return helper;}
updHelper()1045     MatrixHelper<Scalar>&       updHelper()       {return helper;}
1046 
1047 private:
1048     MatrixHelper<Scalar> helper; // this is just one pointer
1049 
1050     template <class EE> friend class MatrixBase;
1051 #endif
1052 };
1053 
1054 
1055 
1056 //  -------------------------------- VectorBase --------------------------------
1057 /// This is a dataless rehash of the MatrixBase class to specialize it for Vectors.
1058 /// This mostly entails overriding a few of the methods. Note that all the MatrixBase
1059 /// operations remain available if you static_cast<> this up to a MatrixBase.
1060 //  ----------------------------------------------------------------------------
1061 template <class ELT=double> class VectorBase : public MatrixBase<ELT> {
1062 #ifndef SWIG
1063     typedef MatrixBase<ELT>                             Base;
1064     typedef typename Base::ScalarNormSq                 ScalarNormSq;
1065     typedef typename Base::EAbs                         EAbs;
1066     typedef typename CNT<ELT>::Scalar                   Scalar;
1067     typedef typename CNT<ELT>::Number                   Number;
1068     typedef typename CNT<ELT>::StdNumber                StdNumber;
1069     typedef VectorBase<ELT>                             T;
1070     typedef VectorBase<typename CNT<ELT>::TAbs>         TAbs;
1071     typedef VectorBase<typename CNT<ELT>::TNeg>         TNeg;
1072     typedef RowVectorView_<typename CNT<ELT>::THerm>    THerm;
1073 #endif
1074 public:
1075     //  ------------------------------------------------------------------------
1076     /// @name       VectorBase "owner" construction
1077     ///
1078     /// These constructors create new VectorBase objects which own their
1079     /// own data and are (at least by default) resizable. The resulting matrices
1080     /// are m X 1 with the number of columns locked at 1. If there is any data
1081     /// allocated but not explicitly initialized, that data will be uninitialized
1082     /// garbage in Release builds but will be initialized to NaN (at a performance
1083     /// cost) in Debug builds.
1084     /// @{
1085 
1086     /// Default constructor makes a 0x1 matrix locked at 1 column; you can
1087     /// provide an initial allocation if you want.
1088     explicit VectorBase(int m=0) : Base(MatrixCommitment::Vector(), m, 1) {}
1089 
1090     /// Copy constructor is a deep copy (not appropriate for views!). That
1091     /// means it creates a new, densely packed vector whose elements are
1092     /// initialized from the source object.
VectorBase(const VectorBase & source)1093     VectorBase(const VectorBase& source) : Base(source) {}
1094 
1095  #ifndef SWIG
1096     /// Implicit conversion from compatible vector with negated elements.
VectorBase(const TNeg & source)1097     VectorBase(const TNeg& source) : Base(source) {}
1098 
1099     /// Construct an owner vector of length m, with each element initialized to
1100     /// the given value.
VectorBase(int m,const ELT & initialValue)1101     VectorBase(int m, const ELT& initialValue)
1102     :   Base(MatrixCommitment::Vector(),m,1,initialValue) {}
1103 
1104     /// Construct an owner vector of length m, with the elements initialized sequentially
1105     /// from a C++ array of elements which is assumed to be of length m. Note that we
1106     /// are expecting C++ packing; don't use this to initialize one Simmatrix vector
1107     /// from another because Simmatrix may pack its elements more densely than C++.
VectorBase(int m,const ELT * cppInitialValues)1108     VectorBase(int m, const ELT* cppInitialValues)
1109     :   Base(MatrixCommitment::Vector(),m,1,cppInitialValues) {}
1110     /// @}
1111 
1112     //  ------------------------------------------------------------------------
1113     /// @name       VectorBase construction from pre-existing data
1114     ///
1115     /// Construct a non-resizeable, VectorBase view of externally supplied data. Note that
1116     /// stride should be interpreted as "the number of scalars between elements" and
1117     /// for composite elements may have a different value if the source is a C++ array
1118     /// of elements vs. a Simmatrix packed data array. We provide constructors for
1119     /// both read-only and writable external data.
1120     /// @{
1121 
1122     /// Construct a read-only view of existing data.
VectorBase(int m,int stride,const Scalar * s)1123     VectorBase(int m, int stride, const Scalar* s)
1124     :   Base(MatrixCommitment::Vector(m), MatrixCharacter::Vector(m),stride,s) { }
1125     /// Construct a writable view into existing data.
VectorBase(int m,int stride,Scalar * s)1126     VectorBase(int m, int stride, Scalar* s)
1127     :   Base(MatrixCommitment::Vector(m), MatrixCharacter::Vector(m),stride,s) { }
1128     /// @}
1129 
1130     //  ------------------------------------------------------------------------
1131     /// @name       VectorBase construction from an existing Helper.
1132     ///
1133     /// Create a new VectorBase from an existing helper. Both shallow (view) and deep
1134     /// copies are possible. For shallow copies, there is a constructor providing a read-only
1135     /// view of the original data and one providing a writable view into the original data.
1136     /// @{
1137 
1138     /// Construct a writable view into the source data.
VectorBase(MatrixHelper<Scalar> & h,const typename MatrixHelper<Scalar>::ShallowCopy & s)1139     VectorBase(MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s)
1140     :   Base(MatrixCommitment::Vector(), h,s) { }
1141     /// Construct a read-only view of the source data.
VectorBase(const MatrixHelper<Scalar> & h,const typename MatrixHelper<Scalar>::ShallowCopy & s)1142     VectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s)
1143     :   Base(MatrixCommitment::Vector(), h,s) { }
1144     /// Construct a new owner vector initialized with the data from the source.
VectorBase(const MatrixHelper<Scalar> & h,const typename MatrixHelper<Scalar>::DeepCopy & d)1145     VectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::DeepCopy& d)
1146     :   Base(MatrixCommitment::Vector(), h,d) { }
1147     /// @}
1148 
1149     // This gives the resulting vector type when (v[i] op P) is applied to each element.
1150     // It will have element types which are the regular composite result of ELT op P.
1151     template <class P> struct EltResult {
1152         typedef VectorBase<typename CNT<ELT>::template Result<P>::Mul> Mul;
1153         typedef VectorBase<typename CNT<ELT>::template Result<P>::Dvd> Dvd;
1154         typedef VectorBase<typename CNT<ELT>::template Result<P>::Add> Add;
1155         typedef VectorBase<typename CNT<ELT>::template Result<P>::Sub> Sub;
1156     };
1157 
1158     /// Copy assignment is deep copy but behavior depends on type of lhs: if view, rhs
1159     /// must match. If owner, we reallocate and copy rhs.
1160     VectorBase& operator=(const VectorBase& b) {
1161         Base::operator=(b); return *this;
1162     }
1163 
1164     // default destructor
1165 
1166 
1167     VectorBase& operator*=(const StdNumber& t)  { Base::operator*=(t); return *this; }
1168     VectorBase& operator/=(const StdNumber& t)  { Base::operator/=(t); return *this; }
1169     VectorBase& operator+=(const VectorBase& r) { Base::operator+=(r); return *this; }
1170     VectorBase& operator-=(const VectorBase& r) { Base::operator-=(r); return *this; }
1171 
1172 
1173     template <class EE> VectorBase& operator=(const VectorBase<EE>& b)
1174       { Base::operator=(b);  return *this; }
1175     template <class EE> VectorBase& operator+=(const VectorBase<EE>& b)
1176       { Base::operator+=(b); return *this; }
1177     template <class EE> VectorBase& operator-=(const VectorBase<EE>& b)
1178       { Base::operator-=(b); return *this; }
1179 
1180 
1181     /// Fill current allocation with copies of element. Note that this is not the
1182     /// same behavior as assignment for Matrices, where only the diagonal is set (and
1183     /// everything else is set to zero.)
1184     VectorBase& operator=(const ELT& t) { Base::setTo(t); return *this; }
1185 
1186     /// There's only one column here so it's a bit weird to use rowScale rather than
1187     /// elementwiseMultiply, but there's nothing really wrong with it. Using colScale
1188     /// would be really wacky since it is the same as a scalar multiply. We won't support
1189     /// colScale here except through inheritance where it will not be much use.
rowScaleInPlace(const VectorBase<EE> & v)1190     template <class EE> VectorBase& rowScaleInPlace(const VectorBase<EE>& v)
1191     { Base::template rowScaleInPlace<EE>(v); return *this; }
rowScale(const VectorBase<EE> & v,typename EltResult<EE>::Mul & out)1192     template <class EE> inline void rowScale(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
1193     { Base::rowScale(v,out); }
rowScale(const VectorBase<EE> & v)1194     template <class EE> inline typename EltResult<EE>::Mul rowScale(const VectorBase<EE>& v) const
1195     { typename EltResult<EE>::Mul out(nrow()); Base::rowScale(v,out); return out; }
1196 
1197     /** Return the root-mean-square (RMS) norm of a Vector of scalars, with
1198     optional return of the index of the element of largest absolute value.
1199     The RMS norm of a Vector v of length n is rms=sqrt(~v*v/n). If n==0 we
1200     define the RMS norm to be zero but return the element index as -1. **/
1201     typename CNT<ScalarNormSq>::TSqrt
1202     normRMS(int* worstOne=0) const {
1203         if (!CNT<ELT>::IsScalar)
1204             SimTK_THROW1(Exception::Cant,
1205                 "Vector::normRMS() only defined for scalar elements.");
1206         const int n = nelt();
1207         if (n == 0) {
1208             if (worstOne) *worstOne = -1;
1209             return typename CNT<ScalarNormSq>::TSqrt(0);
1210         }
1211 
1212         ScalarNormSq sumsq = 0;
1213         if (worstOne) {
1214             *worstOne = 0;
1215             ScalarNormSq maxsq = 0;
1216             for (int i=0; i<n; ++i) {
1217                 const ScalarNormSq v2 = square((*this)[i]);
1218                 if (v2 > maxsq) maxsq=v2, *worstOne=i;
1219                 sumsq += v2;
1220             }
1221         } else { // don't track the worst element
1222             for (int i=0; i<n; ++i) {
1223                 const ScalarNormSq v2 = square((*this)[i]);
1224                 sumsq += v2;
1225             }
1226         }
1227 
1228         return CNT<ScalarNormSq>::sqrt(sumsq/n);
1229     }
1230 
1231     /** Return the weighted root-mean-square (WRMS) norm of a Vector of
1232     scalars, with optional return of the index of the weighted element of
1233     largest absolute value. The WRMS norm of a Vector v of length n with
1234     weights w is wrms=sqrt(sum_i((w_i*v_i)^2))/n). If n==0 we
1235     define the WRMS norm to be zero but return the element index as -1. **/
1236     template <class EE>
1237     typename CNT<ScalarNormSq>::TSqrt
1238     weightedNormRMS(const VectorBase<EE>& w, int* worstOne=0) const {
1239         if (!CNT<ELT>::IsScalar || !CNT<EE>::IsScalar)
1240             SimTK_THROW1(Exception::Cant,
1241             "Vector::weightedNormRMS() only defined for scalar elements"
1242             " and weights.");
1243         const int n = nelt();
1244         assert(w.nelt()==n);
1245         if (n == 0) {
1246             if (worstOne) *worstOne = -1;
1247             return typename CNT<ScalarNormSq>::TSqrt(0);
1248         }
1249 
1250         ScalarNormSq sumsq = 0;
1251         if (worstOne) {
1252             *worstOne = 0;
1253             ScalarNormSq maxsq = 0;
1254             for (int i=0; i<n; ++i) {
1255                 const ScalarNormSq wv2 = square(w[i]*(*this)[i]);
1256                 if (wv2 > maxsq) maxsq=wv2, *worstOne=i;
1257                 sumsq += wv2;
1258             }
1259         } else { // don't track the worst element
1260             for (int i=0; i<n; ++i) {
1261                 const ScalarNormSq wv2 = square(w[i]*(*this)[i]);
1262                 sumsq += wv2;
1263             }
1264         }
1265 
1266         return CNT<ScalarNormSq>::sqrt(sumsq/n);
1267     }
1268 
1269     /** Return the infinity norm (max absolute value) of a Vector of scalars,
1270     with optional return of the index of the element of largest absolute value.
1271     The Inf norm of a Vector v is inf=max_i(|v_i|). If n==0 we
1272     define the Inf norm to be zero but return the element index as -1. **/
1273     EAbs normInf(int* worstOne=0) const {
1274         if (!CNT<ELT>::IsScalar)
1275             SimTK_THROW1(Exception::Cant,
1276                 "Vector::normInf() only defined for scalar elements.");
1277         const int n = nelt();
1278         if (n == 0) {
1279             if (worstOne) *worstOne = -1;
1280             return EAbs(0);
1281         }
1282 
1283         EAbs maxabs = 0;
1284         if (worstOne) {
1285             *worstOne = 0;
1286             for (int i=0; i<n; ++i) {
1287                 const EAbs a = std::abs((*this)[i]);
1288                 if (a > maxabs) maxabs=a, *worstOne=i;
1289             }
1290         } else { // don't track the worst element
1291             for (int i=0; i<n; ++i) {
1292                 const EAbs a = std::abs((*this)[i]);
1293                 if (a > maxabs) maxabs=a;
1294             }
1295         }
1296 
1297         return maxabs;
1298     }
1299 
1300     /** Return the weighted infinity norm (max absolute value) WInf of a Vector
1301     of scalars, with optional return of the index of the weighted element of
1302     largest absolute value. The WInf norm of a Vector v of length n with
1303     weights w is winf=max_i(|w_i*v_i|). If n==0 we
1304     define the WInf norm to be zero but return the element index as -1. **/
1305     template <class EE>
1306     EAbs weightedNormInf(const VectorBase<EE>& w, int* worstOne=0) const {
1307         if (!CNT<ELT>::IsScalar || !CNT<EE>::IsScalar)
1308             SimTK_THROW1(Exception::Cant,
1309             "Vector::weightedNormInf() only defined for scalar elements"
1310             " and weights.");
1311         const int n = nelt();
1312         assert(w.nelt()==n);
1313         if (n == 0) {
1314             if (worstOne) *worstOne = -1;
1315             return EAbs(0);
1316         }
1317 
1318         EAbs maxabs = 0;
1319         if (worstOne) {
1320             *worstOne = 0;
1321             for (int i=0; i<n; ++i) {
1322                 const EAbs wv = std::abs(w[i]*(*this)[i]);
1323                 if (wv > maxabs) maxabs=wv, *worstOne=i;
1324             }
1325         } else { // don't track the worst element
1326             for (int i=0; i<n; ++i) {
1327                 const EAbs wv = std::abs(w[i]*(*this)[i]);
1328                 if (wv > maxabs) maxabs=wv;
1329             }
1330         }
1331 
1332         return maxabs;
1333     }
1334 
1335     /// Set this[i] = this[i]^-1.
elementwiseInvertInPlace()1336     VectorBase& elementwiseInvertInPlace() {
1337         Base::elementwiseInvertInPlace();
1338         return *this;
1339     }
1340 
1341     /// Set supplied out[i] = this[i]^-1
elementwiseInvert(VectorBase<typename CNT<ELT>::TInvert> & out)1342     void elementwiseInvert(VectorBase<typename CNT<ELT>::TInvert>& out) const {
1343         Base::elementwiseInvert(out);
1344     }
1345 
1346     /// Return out[i]=this[i]^-1 as function return.
elementwiseInvert()1347     VectorBase<typename CNT<ELT>::TInvert> elementwiseInvert() const {
1348         VectorBase<typename CNT<ELT>::TInvert> out(nrow());
1349         Base::elementwiseInvert(out);
1350         return out;
1351     }
1352 
1353     // elementwise multiply
elementwiseMultiplyInPlace(const VectorBase<EE> & r)1354     template <class EE> VectorBase& elementwiseMultiplyInPlace(const VectorBase<EE>& r)
1355     { Base::template elementwiseMultiplyInPlace<EE>(r); return *this; }
elementwiseMultiply(const VectorBase<EE> & v,typename EltResult<EE>::Mul & out)1356     template <class EE> inline void elementwiseMultiply(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
1357     { Base::template elementwiseMultiply<EE>(v,out); }
elementwiseMultiply(const VectorBase<EE> & v)1358     template <class EE> inline typename EltResult<EE>::Mul elementwiseMultiply(const VectorBase<EE>& v) const
1359     { typename EltResult<EE>::Mul out(nrow()); Base::template elementwiseMultiply<EE>(v,out); return out; }
1360 
1361     // elementwise multiply from left
elementwiseMultiplyFromLeftInPlace(const VectorBase<EE> & r)1362     template <class EE> VectorBase& elementwiseMultiplyFromLeftInPlace(const VectorBase<EE>& r)
1363     { Base::template elementwiseMultiplyFromLeftInPlace<EE>(r); return *this; }
1364     template <class EE> inline void
elementwiseMultiplyFromLeft(const VectorBase<EE> & v,typename VectorBase<EE>::template EltResult<ELT>::Mul & out)1365     elementwiseMultiplyFromLeft(
1366         const VectorBase<EE>& v,
1367         typename VectorBase<EE>::template EltResult<ELT>::Mul& out) const
1368     {
1369         Base::template elementwiseMultiplyFromLeft<EE>(v,out);
1370     }
1371     template <class EE> inline typename VectorBase<EE>::template EltResult<ELT>::Mul
elementwiseMultiplyFromLeft(const VectorBase<EE> & v)1372     elementwiseMultiplyFromLeft(const VectorBase<EE>& v) const
1373     {
1374         typename VectorBase<EE>::template EltResult<ELT>::Mul out(nrow());
1375         Base::template elementwiseMultiplyFromLeft<EE>(v,out);
1376         return out;
1377     }
1378 
1379     // elementwise divide
elementwiseDivideInPlace(const VectorBase<EE> & r)1380     template <class EE> VectorBase& elementwiseDivideInPlace(const VectorBase<EE>& r)
1381     { Base::template elementwiseDivideInPlace<EE>(r); return *this; }
elementwiseDivide(const VectorBase<EE> & v,typename EltResult<EE>::Dvd & out)1382     template <class EE> inline void elementwiseDivide(const VectorBase<EE>& v, typename EltResult<EE>::Dvd& out) const
1383     { Base::template elementwiseDivide<EE>(v,out); }
elementwiseDivide(const VectorBase<EE> & v)1384     template <class EE> inline typename EltResult<EE>::Dvd elementwiseDivide(const VectorBase<EE>& v) const
1385     { typename EltResult<EE>::Dvd out(nrow()); Base::template elementwiseDivide<EE>(v,out); return out; }
1386 
1387     // elementwise divide from left
elementwiseDivideFromLeftInPlace(const VectorBase<EE> & r)1388     template <class EE> VectorBase& elementwiseDivideFromLeftInPlace(const VectorBase<EE>& r)
1389     { Base::template elementwiseDivideFromLeftInPlace<EE>(r); return *this; }
1390     template <class EE> inline void
elementwiseDivideFromLeft(const VectorBase<EE> & v,typename VectorBase<EE>::template EltResult<ELT>::Dvd & out)1391     elementwiseDivideFromLeft(
1392         const VectorBase<EE>& v,
1393         typename VectorBase<EE>::template EltResult<ELT>::Dvd& out) const
1394     {
1395         Base::template elementwiseDivideFromLeft<EE>(v,out);
1396     }
1397     template <class EE> inline typename VectorBase<EE>::template EltResult<ELT>::Dvd
elementwiseDivideFromLeft(const VectorBase<EE> & v)1398     elementwiseDivideFromLeft(const VectorBase<EE>& v) const
1399     {
1400         typename VectorBase<EE>::template EltResult<ELT>::Dvd out(nrow());
1401         Base::template elementwiseDivideFromLeft<EE>(v,out);
1402         return out;
1403     }
1404 
1405     // Implicit conversions are allowed to Vector or Matrix, but not to RowVector.
1406     operator const Vector_<ELT>&()     const { return *reinterpret_cast<const Vector_<ELT>*>(this); }
1407     operator       Vector_<ELT>&()           { return *reinterpret_cast<      Vector_<ELT>*>(this); }
1408     operator const VectorView_<ELT>&() const { return *reinterpret_cast<const VectorView_<ELT>*>(this); }
1409     operator       VectorView_<ELT>&()       { return *reinterpret_cast<      VectorView_<ELT>*>(this); }
1410 
1411     operator const Matrix_<ELT>&()     const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
1412     operator       Matrix_<ELT>&()           { return *reinterpret_cast<      Matrix_<ELT>*>(this); }
1413     operator const MatrixView_<ELT>&() const { return *reinterpret_cast<const MatrixView_<ELT>*>(this); }
1414     operator       MatrixView_<ELT>&()       { return *reinterpret_cast<      MatrixView_<ELT>*>(this); }
1415 
1416 #endif
1417     // size() for Vectors is Base::nelt() but returns int instead of ptrdiff_t.
size()1418     int size() const {
1419     assert(Base::nelt() <= (ptrdiff_t)std::numeric_limits<int>::max());
1420     assert(Base::ncol()==1);
1421     return (int)Base::nelt();
1422     }
nrow()1423     int       nrow() const {assert(Base::ncol()==1); return Base::nrow();}
ncol()1424     int       ncol() const {assert(Base::ncol()==1); return Base::ncol();}
1425  #ifndef SWIG
nelt()1426     ptrdiff_t nelt() const {assert(Base::ncol()==1); return Base::nelt();}
1427 
1428     // Override MatrixBase operators to return the right shape
abs()1429     TAbs abs() const {TAbs result; Base::abs(result); return result;}
1430 
1431     // Override MatrixBase indexing operators
1432     const ELT& operator[](int i) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(i));}
1433     ELT&       operator[](int i)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(i));}
operator()1434     const ELT& operator()(int i) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(i));}
operator()1435     ELT&       operator()(int i)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(i));}
1436 
1437     // Block (contiguous subvector) view creation
operator()1438     VectorView_<ELT> operator()(int i, int m) const {return Base::operator()(i,0,m,1).getAsVectorView();}
operator()1439     VectorView_<ELT> operator()(int i, int m)       {return Base::operator()(i,0,m,1).updAsVectorView();}
1440 
1441     // Indexed view creation (arbitrary subvector). Indices must be
1442     // monotonically increasing.
index(const Array_<int> & indices)1443     VectorView_<ELT> index(const Array_<int>& indices) const {
1444         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(),
1445                                Base::getHelper(), indices);
1446         return VectorView_<ELT>(h);
1447     }
updIndex(const Array_<int> & indices)1448     VectorView_<ELT> updIndex(const Array_<int>& indices) {
1449         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(),
1450                                Base::updHelper(), indices);
1451         return VectorView_<ELT>(h);
1452     }
1453 
operator()1454     VectorView_<ELT> operator()(const Array_<int>& indices) const {return index(indices);}
operator()1455     VectorView_<ELT> operator()(const Array_<int>& indices)       {return updIndex(indices);}
1456 
1457     // Hermitian transpose.
transpose()1458     THerm transpose() const {return Base::transpose().getAsRowVectorView();}
updTranspose()1459     THerm updTranspose()    {return Base::updTranspose().updAsRowVectorView();}
1460 
1461     THerm operator~() const {return transpose();}
1462     THerm operator~()       {return updTranspose();}
1463 
1464     const VectorBase& operator+() const {return *this; }
1465 
1466     // Negation
1467 
negate()1468     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
updNegate()1469     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
1470 
1471     const TNeg& operator-() const {return negate();}
1472     TNeg&       operator-()       {return updNegate();}
1473 #endif
resize(int m)1474     VectorBase& resize(int m)     {Base::resize(m,1); return *this;}
resizeKeep(int m)1475     VectorBase& resizeKeep(int m) {Base::resizeKeep(m,1); return *this;}
1476 
1477     //TODO: this is not re-locking the number of columns at 1.
clear()1478     void clear() {Base::clear(); Base::resize(0,1);}
1479 
sum()1480     ELT sum() const {ELT s; Base::getHelper().sum(reinterpret_cast<Scalar*>(&s)); return s; } // add all the elements
1481 #ifndef SWIG
begin()1482     VectorIterator<ELT, VectorBase<ELT> > begin() {
1483         return VectorIterator<ELT, VectorBase<ELT> >(*this, 0);
1484     }
end()1485     VectorIterator<ELT, VectorBase<ELT> > end() {
1486         return VectorIterator<ELT, VectorBase<ELT> >(*this, size());
1487     }
1488 
1489 protected:
1490     // Create a VectorBase handle using a given helper rep.
VectorBase(MatrixHelperRep<Scalar> * hrep)1491     explicit VectorBase(MatrixHelperRep<Scalar>* hrep) : Base(hrep) {}
1492 
1493 private:
1494     // NO DATA MEMBERS ALLOWED
1495 #endif
1496 };
1497 
1498 //  ------------------------------- RowVectorBase ------------------------------
1499 /// This is a dataless rehash of the MatrixBase class to specialize it for RowVectors.
1500 /// This mostly entails overriding a few of the methods. Note that all the MatrixBase
1501 /// operations remain available if you static_cast<> this up to a MatrixBase.
1502 //  ----------------------------------------------------------------------------
1503 template <class ELT> class RowVectorBase : public MatrixBase<ELT> {
1504 #ifndef SWIG
1505     typedef MatrixBase<ELT>                             Base;
1506     typedef typename CNT<ELT>::Scalar                   Scalar;
1507     typedef typename CNT<ELT>::Number                   Number;
1508     typedef typename CNT<ELT>::StdNumber                StdNumber;
1509     typedef RowVectorBase<ELT>                          T;
1510     typedef RowVectorBase<typename CNT<ELT>::TAbs>      TAbs;
1511     typedef RowVectorBase<typename CNT<ELT>::TNeg>      TNeg;
1512     typedef VectorView_<typename CNT<ELT>::THerm>       THerm;
1513 #endif
1514 public:
1515     //  ------------------------------------------------------------------------
1516     /// @name       RowVectorBase "owner" construction
1517     ///
1518     /// These constructors create new RowVectorBase objects which own their
1519     /// own data and are (at least by default) resizable. The resulting matrices
1520     /// are 1 x n with the number of rows locked at 1. If there is any data
1521     /// allocated but not explicitly initialized, that data will be uninitialized
1522     /// garbage in Release builds but will be initialized to NaN (at a performance
1523     /// cost) in Debug builds.
1524     /// @{
1525 
1526     /// Default constructor makes a 1x0 matrix locked at 1 row; you can
1527     /// provide an initial allocation if you want.
1528     explicit RowVectorBase(int n=0) : Base(MatrixCommitment::RowVector(), 1, n) {}
1529 
1530     /// Copy constructor is a deep copy (not appropriate for views!). That
1531     /// means it creates a new, densely packed vector whose elements are
1532     /// initialized from the source object.
RowVectorBase(const RowVectorBase & source)1533     RowVectorBase(const RowVectorBase& source) : Base(source) {}
1534 
1535 #ifndef SWIG
1536     /// Implicit conversion from compatible row vector with negated elements.
RowVectorBase(const TNeg & source)1537     RowVectorBase(const TNeg& source) : Base(source) {}
1538 #endif
1539 
1540     /// Construct an owner row vector of length n, with each element initialized to
1541     /// the given value.
RowVectorBase(int n,const ELT & initialValue)1542     RowVectorBase(int n, const ELT& initialValue)
1543     :   Base(MatrixCommitment::RowVector(),1,n,initialValue) {}
1544 
1545     /// Construct an owner vector of length n, with the elements initialized sequentially
1546     /// from a C++ array of elements which is assumed to be of length n. Note that we
1547     /// are expecting C++ packing; don't use this to initialize one Simmatrix vector
1548     /// from another because Simmatrix may pack its elements more densely than C++.
RowVectorBase(int n,const ELT * cppInitialValues)1549     RowVectorBase(int n, const ELT* cppInitialValues)
1550     :   Base(MatrixCommitment::RowVector(),1,n,cppInitialValues) {}
1551     /// @}
1552 
1553     //  ------------------------------------------------------------------------
1554     /// @name       RowVectorBase construction from pre-existing data
1555     ///
1556     /// Construct a non-resizeable, RowVectorBase view of externally supplied data. Note that
1557     /// stride should be interpreted as "the number of scalars between elements" and
1558     /// for composite elements may have a different value if the source is a C++ array
1559     /// of elements vs. a Simmatrix packed data array. We provide constructors for
1560     /// both read-only and writable external data.
1561     /// @{
1562 
1563 #ifndef SWIG
1564     /// Construct a read-only view of existing data.
RowVectorBase(int n,int stride,const Scalar * s)1565     RowVectorBase(int n, int stride, const Scalar* s)
1566     :   Base(MatrixCommitment::RowVector(n), MatrixCharacter::RowVector(n),stride,s) { }
1567     /// Construct a writable view into existing data.
RowVectorBase(int n,int stride,Scalar * s)1568     RowVectorBase(int n, int stride, Scalar* s)
1569     :   Base(MatrixCommitment::RowVector(n), MatrixCharacter::RowVector(n),stride,s) { }
1570     /// @}
1571 #endif
1572 
1573     //  ------------------------------------------------------------------------
1574     /// @name       RowVectorBase construction from an existing Helper.
1575     ///
1576     /// Create a new RowVectorBase from an existing helper. Both shallow (view) and deep
1577     /// copies are possible. For shallow copies, there is a constructor providing a read-only
1578     /// view of the original data and one providing a writable view into the original data.
1579     /// @{
1580 
1581 #ifndef SWIG
1582     /// Construct a writable view into the source data.
RowVectorBase(MatrixHelper<Scalar> & h,const typename MatrixHelper<Scalar>::ShallowCopy & s)1583     RowVectorBase(MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s)
1584     :   Base(MatrixCommitment::RowVector(), h,s) { }
1585     /// Construct a read-only view of the source data.
RowVectorBase(const MatrixHelper<Scalar> & h,const typename MatrixHelper<Scalar>::ShallowCopy & s)1586     RowVectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s)
1587     :   Base(MatrixCommitment::RowVector(), h,s) { }
1588     /// Construct a new owner vector initialized with the data from the source.
RowVectorBase(const MatrixHelper<Scalar> & h,const typename MatrixHelper<Scalar>::DeepCopy & d)1589     RowVectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::DeepCopy& d)
1590     :   Base(MatrixCommitment::RowVector(), h,d) { }
1591     /// @}
1592 
1593     // This gives the resulting rowvector type when (r(i) op P) is applied to each element.
1594     // It will have element types which are the regular composite result of ELT op P.
1595     template <class P> struct EltResult {
1596         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Mul> Mul;
1597         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Dvd> Dvd;
1598         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Add> Add;
1599         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Sub> Sub;
1600     };
1601 #endif
1602 
1603     /// Copy assignment is deep copy but behavior depends on type of lhs: if view, rhs
1604     /// must match. If owner, we reallocate and copy rhs.
1605     RowVectorBase& operator=(const RowVectorBase& b) {
1606         Base::operator=(b); return *this;
1607     }
1608 
1609     // default destructor
1610 #ifndef SWIG
1611     RowVectorBase& operator*=(const StdNumber& t)     {Base::operator*=(t); return *this;}
1612     RowVectorBase& operator/=(const StdNumber& t)     {Base::operator/=(t); return *this;}
1613     RowVectorBase& operator+=(const RowVectorBase& r) {Base::operator+=(r); return *this;}
1614     RowVectorBase& operator-=(const RowVectorBase& r) {Base::operator-=(r); return *this;}
1615 #endif
1616 
1617     template <class EE> RowVectorBase& operator=(const RowVectorBase<EE>& b)
1618       { Base::operator=(b);  return *this; }
1619     template <class EE> RowVectorBase& operator+=(const RowVectorBase<EE>& b)
1620       { Base::operator+=(b); return *this; }
1621     template <class EE> RowVectorBase& operator-=(const RowVectorBase<EE>& b)
1622       { Base::operator-=(b); return *this; }
1623 
1624     // default destructor
1625 
1626     /// Fill current allocation with copies of element. Note that this is not the
1627     /// same behavior as assignment for Matrices, where only the diagonal is set (and
1628     /// everything else is set to zero.)
1629     RowVectorBase& operator=(const ELT& t) { Base::setTo(t); return *this; }
1630 
1631     /// There's only one row here so it's a bit wierd to use colScale rather than
1632     /// elementwiseMultiply, but there's nothing really wrong with it. Using rowScale
1633     /// would be really wacky since it is the same as a scalar multiply. We won't support
1634     /// rowScale here except through inheritance where it will not be much use.
colScaleInPlace(const VectorBase<EE> & v)1635     template <class EE> RowVectorBase& colScaleInPlace(const VectorBase<EE>& v)
1636     { Base::template colScaleInPlace<EE>(v); return *this; }
colScale(const VectorBase<EE> & v,typename EltResult<EE>::Mul & out)1637     template <class EE> inline void colScale(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
1638     { return Base::template colScale<EE>(v,out); }
colScale(const VectorBase<EE> & v)1639     template <class EE> inline typename EltResult<EE>::Mul colScale(const VectorBase<EE>& v) const
1640     { typename EltResult<EE>::Mul out(ncol()); Base::template colScale<EE>(v,out); return out; }
1641 
1642 
1643     // elementwise multiply
elementwiseMultiplyInPlace(const RowVectorBase<EE> & r)1644     template <class EE> RowVectorBase& elementwiseMultiplyInPlace(const RowVectorBase<EE>& r)
1645     { Base::template elementwiseMultiplyInPlace<EE>(r); return *this; }
elementwiseMultiply(const RowVectorBase<EE> & v,typename EltResult<EE>::Mul & out)1646     template <class EE> inline void elementwiseMultiply(const RowVectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
1647     { Base::template elementwiseMultiply<EE>(v,out); }
elementwiseMultiply(const RowVectorBase<EE> & v)1648     template <class EE> inline typename EltResult<EE>::Mul elementwiseMultiply(const RowVectorBase<EE>& v) const
1649     { typename EltResult<EE>::Mul out(nrow()); Base::template elementwiseMultiply<EE>(v,out); return out; }
1650 
1651     // elementwise multiply from left
elementwiseMultiplyFromLeftInPlace(const RowVectorBase<EE> & r)1652     template <class EE> RowVectorBase& elementwiseMultiplyFromLeftInPlace(const RowVectorBase<EE>& r)
1653     { Base::template elementwiseMultiplyFromLeftInPlace<EE>(r); return *this; }
1654 
1655 #ifndef SWIG
1656     template <class EE> inline void
elementwiseMultiplyFromLeft(const RowVectorBase<EE> & v,typename RowVectorBase<EE>::template EltResult<ELT>::Mul & out)1657     elementwiseMultiplyFromLeft(
1658         const RowVectorBase<EE>& v,
1659         typename RowVectorBase<EE>::template EltResult<ELT>::Mul& out) const
1660     {
1661         Base::template elementwiseMultiplyFromLeft<EE>(v,out);
1662     }
1663 
1664     template <class EE> inline
1665     typename RowVectorBase<EE>::template EltResult<ELT>::Mul
elementwiseMultiplyFromLeft(const RowVectorBase<EE> & v)1666     elementwiseMultiplyFromLeft(const RowVectorBase<EE>& v) const {
1667         typename RowVectorBase<EE>::template EltResult<ELT>::Mul out(nrow());
1668         Base::template elementwiseMultiplyFromLeft<EE>(v,out);
1669         return out;
1670     }
1671 #endif
1672 
1673     // elementwise divide
elementwiseDivideInPlace(const RowVectorBase<EE> & r)1674     template <class EE> RowVectorBase& elementwiseDivideInPlace(const RowVectorBase<EE>& r)
1675     { Base::template elementwiseDivideInPlace<EE>(r); return *this; }
elementwiseDivide(const RowVectorBase<EE> & v,typename EltResult<EE>::Dvd & out)1676     template <class EE> inline void elementwiseDivide(const RowVectorBase<EE>& v, typename EltResult<EE>::Dvd& out) const
1677     { Base::template elementwiseDivide<EE>(v,out); }
elementwiseDivide(const RowVectorBase<EE> & v)1678     template <class EE> inline typename EltResult<EE>::Dvd elementwiseDivide(const RowVectorBase<EE>& v) const
1679     { typename EltResult<EE>::Dvd out(nrow()); Base::template elementwiseDivide<EE>(v,out); return out; }
1680 
1681     // elementwise divide from left
elementwiseDivideFromLeftInPlace(const RowVectorBase<EE> & r)1682     template <class EE> RowVectorBase& elementwiseDivideFromLeftInPlace(const RowVectorBase<EE>& r)
1683     { Base::template elementwiseDivideFromLeftInPlace<EE>(r); return *this; }
1684 
1685 #ifndef SWIG
1686     template <class EE> inline void
elementwiseDivideFromLeft(const RowVectorBase<EE> & v,typename RowVectorBase<EE>::template EltResult<ELT>::Dvd & out)1687     elementwiseDivideFromLeft
1688        (const RowVectorBase<EE>& v,
1689         typename RowVectorBase<EE>::template EltResult<ELT>::Dvd& out) const {
1690         Base::template elementwiseDivideFromLeft<EE>(v,out);
1691     }
1692     template <class EE> inline
1693     typename RowVectorBase<EE>::template EltResult<ELT>::Dvd
elementwiseDivideFromLeft(const RowVectorBase<EE> & v)1694     elementwiseDivideFromLeft(const RowVectorBase<EE>& v) const {
1695         typename RowVectorBase<EE>::template EltResult<ELT>::Dvd out(nrow());
1696         Base::template elementwiseDivideFromLeft<EE>(v,out);
1697         return out;
1698     }
1699 #endif
1700 
1701     // Implicit conversions are allowed to RowVector or Matrix, but not to Vector.
1702     operator const RowVector_<ELT>&()     const {return *reinterpret_cast<const RowVector_<ELT>*>(this);}
1703     operator       RowVector_<ELT>&()           {return *reinterpret_cast<      RowVector_<ELT>*>(this);}
1704     operator const RowVectorView_<ELT>&() const {return *reinterpret_cast<const RowVectorView_<ELT>*>(this);}
1705     operator       RowVectorView_<ELT>&()       {return *reinterpret_cast<      RowVectorView_<ELT>*>(this);}
1706 
1707     operator const Matrix_<ELT>&()     const {return *reinterpret_cast<const Matrix_<ELT>*>(this);}
1708     operator       Matrix_<ELT>&()           {return *reinterpret_cast<      Matrix_<ELT>*>(this);}
1709     operator const MatrixView_<ELT>&() const {return *reinterpret_cast<const MatrixView_<ELT>*>(this);}
1710     operator       MatrixView_<ELT>&()       {return *reinterpret_cast<      MatrixView_<ELT>*>(this);}
1711 
1712 
1713     // size() for RowVectors is Base::nelt() but returns int instead of ptrdiff_t.
size()1714     int size() const {
1715         assert(Base::nelt() <= (ptrdiff_t)std::numeric_limits<int>::max());
1716         assert(Base::nrow()==1);
1717         return (int)Base::nelt();
1718     }
nrow()1719     int       nrow() const {assert(Base::nrow()==1); return Base::nrow();}
ncol()1720     int       ncol() const {assert(Base::nrow()==1); return Base::ncol();}
nelt()1721     ptrdiff_t nelt() const {assert(Base::nrow()==1); return Base::nelt();}
1722 
1723 #ifndef SWIG
1724     // Override MatrixBase operators to return the right shape
abs()1725     TAbs abs() const {
1726         TAbs result; Base::abs(result); return result;
1727     }
1728 #endif
1729 
1730     // Override MatrixBase indexing operators
1731     const ELT& operator[](int j) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(j));}
1732     ELT&       operator[](int j)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(j));}
operator()1733     const ELT& operator()(int j) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(j));}
operator()1734     ELT&       operator()(int j)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(j));}
1735 
1736     // Block (contiguous subvector) creation
operator()1737     RowVectorView_<ELT> operator()(int j, int n) const {return Base::operator()(0,j,1,n).getAsRowVectorView();}
operator()1738     RowVectorView_<ELT> operator()(int j, int n)       {return Base::operator()(0,j,1,n).updAsRowVectorView();}
1739 
1740     // Indexed view creation (arbitrary subvector). Indices must be monotonically increasing.
index(const Array_<int> & indices)1741     RowVectorView_<ELT> index(const Array_<int>& indices) const {
1742         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(), Base::getHelper(), indices);
1743         return RowVectorView_<ELT>(h);
1744     }
updIndex(const Array_<int> & indices)1745     RowVectorView_<ELT> updIndex(const Array_<int>& indices) {
1746         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(), Base::updHelper(), indices);
1747         return RowVectorView_<ELT>(h);
1748     }
1749 
operator()1750     RowVectorView_<ELT> operator()(const Array_<int>& indices) const {return index(indices);}
operator()1751     RowVectorView_<ELT> operator()(const Array_<int>& indices)       {return updIndex(indices);}
1752 
1753 #ifndef SWIG
1754     // Hermitian transpose.
transpose()1755     THerm transpose() const {return Base::transpose().getAsVectorView();}
updTranspose()1756     THerm updTranspose()    {return Base::updTranspose().updAsVectorView();}
1757 
1758     THerm operator~() const {return transpose();}
1759     THerm operator~()       {return updTranspose();}
1760 #endif
1761 
1762     const RowVectorBase& operator+() const {return *this; }
1763 
1764 #ifndef SWIG
1765     // Negation
negate()1766     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
updNegate()1767     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
1768 
1769     const TNeg& operator-() const {return negate();}
1770     TNeg&       operator-()       {return updNegate();}
1771 #endif
1772 
resize(int n)1773     RowVectorBase& resize(int n)     {Base::resize(1,n); return *this;}
resizeKeep(int n)1774     RowVectorBase& resizeKeep(int n) {Base::resizeKeep(1,n); return *this;}
1775 
1776     //TODO: this is not re-locking the number of rows at 1.
clear()1777     void clear() {Base::clear(); Base::resize(1,0);}
1778 
sum()1779     ELT sum() const {ELT s; Base::getHelper().sum(reinterpret_cast<Scalar*>(&s)); return s; } // add all the elements
begin()1780     VectorIterator<ELT, RowVectorBase<ELT> > begin() {
1781         return VectorIterator<ELT, RowVectorBase<ELT> >(*this, 0);
1782     }
end()1783     VectorIterator<ELT, RowVectorBase<ELT> > end() {
1784         return VectorIterator<ELT, RowVectorBase<ELT> >(*this, size());
1785     }
1786 
1787 protected:
1788     // Create a RowVectorBase handle using a given helper rep.
RowVectorBase(MatrixHelperRep<Scalar> * hrep)1789     explicit RowVectorBase(MatrixHelperRep<Scalar>* hrep) : Base(hrep) {}
1790 
1791 private:
1792     // NO DATA MEMBERS ALLOWED
1793 };
1794 
1795 
1796 //  ------------------------------- MatrixView_ --------------------------------
1797 /// This class is identical to a Matrix_; it is used only to manage the C++ rules
1798 /// for when copy constructors are called by introducing a separate type to
1799 /// prevent certain allowed optimizations from occuring when we don't want them.
1800 /// Despite the name, this may be an owner if a Matrix_ is recast to a MatrixView_.
1801 /// However, there are no owner constructors for MatrixView_.
1802 //  ----------------------------------------------------------------------------
1803 template <class ELT> class MatrixView_ : public MatrixBase<ELT> {
1804     typedef MatrixBase<ELT>                 Base;
1805     typedef typename CNT<ELT>::Scalar       S;
1806     typedef typename CNT<ELT>::StdNumber    StdNumber;
1807 public:
1808     // Default construction is suppressed.
1809     // Uses default destructor.
1810 
1811 #ifndef SWIG
1812     // Create a MatrixView_ handle using a given helper rep.
MatrixView_(MatrixHelperRep<S> * hrep)1813     explicit MatrixView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
1814 #endif
1815 
1816     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
1817     // if it was present in the source. This is necessary to allow temporary views to be
1818     // created and used as lvalues.
MatrixView_(const MatrixView_ & m)1819     MatrixView_(const MatrixView_& m)
1820       : Base(MatrixCommitment(),
1821              const_cast<MatrixHelper<S>&>(m.getHelper()),
1822              typename MatrixHelper<S>::ShallowCopy()) {}
1823 
1824     // Copy assignment is deep but not reallocating.
1825     MatrixView_& operator=(const MatrixView_& m) {
1826         Base::operator=(m); return *this;
1827     }
1828 
1829 #ifndef SWIG
1830     // Copy construction and copy assignment from a DeadMatrixView steals the helper.
1831     MatrixView_(DeadMatrixView_<ELT>&);
1832     MatrixView_& operator=(DeadMatrixView_<ELT>&);
1833 
1834     // Ask for shallow copy
MatrixView_(const MatrixHelper<S> & h)1835     MatrixView_(const MatrixHelper<S>& h) : Base(MatrixCommitment(), h, typename MatrixHelper<S>::ShallowCopy()) { }
MatrixView_(MatrixHelper<S> & h)1836     MatrixView_(MatrixHelper<S>&       h) : Base(MatrixCommitment(), h, typename MatrixHelper<S>::ShallowCopy()) { }
1837 #endif
1838 
1839     MatrixView_& operator=(const Matrix_<ELT>& v)     { Base::operator=(v); return *this; }
1840     MatrixView_& operator=(const ELT& e)              { Base::operator=(e); return *this; }
1841 
1842     template <class EE> MatrixView_& operator=(const MatrixBase<EE>& m)
1843       { Base::operator=(m); return *this; }
1844     template <class EE> MatrixView_& operator+=(const MatrixBase<EE>& m)
1845       { Base::operator+=(m); return *this; }
1846     template <class EE> MatrixView_& operator-=(const MatrixBase<EE>& m)
1847       { Base::operator-=(m); return *this; }
1848 
1849 #ifndef SWIG
1850     MatrixView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
1851     MatrixView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
1852 #endif
1853 
1854     MatrixView_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
1855     MatrixView_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }
1856 
1857     operator const Matrix_<ELT>&() const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
1858     operator Matrix_<ELT>&()             { return *reinterpret_cast<Matrix_<ELT>*>(this); }
1859 
1860 private:
1861     // NO DATA MEMBERS ALLOWED
1862     MatrixView_(); // default constructor suppressed (what's it a view of?)
1863 };
1864 
1865 #ifndef SWIG
1866 
1867 //  ----------------------------- DeadMatrixView_ ------------------------------
1868 /// This is a MatrixView_ with the additional property that we are about to delete it.
1869 /// If this is the source for an assignment or copy construction, the destination is
1870 /// free to steal the helper and/or the underlying data.
1871 //  ----------------------------------------------------------------------------
1872 template <class ELT> class DeadMatrixView_ : public MatrixView_<ELT> {
1873     typedef MatrixView_<ELT>                Base;
1874     typedef typename CNT<ELT>::Scalar       S;
1875     typedef typename CNT<ELT>::StdNumber    StdNumber;
1876 public:
1877     // Default construction is suppressed.
1878     // Uses default destructor.
1879 
1880     // All functionality is passed through to MatrixView_.
DeadMatrixView_(MatrixHelperRep<S> * hrep)1881     explicit DeadMatrixView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
DeadMatrixView_(const Base & m)1882     DeadMatrixView_(const Base& m) : Base(m) {}
1883     DeadMatrixView_& operator=(const Base& m) {
1884         Base::operator=(m); return *this;
1885     }
1886 
1887     // Ask for shallow copy
DeadMatrixView_(const MatrixHelper<S> & h)1888     DeadMatrixView_(const MatrixHelper<S>& h) : Base(h) {}
DeadMatrixView_(MatrixHelper<S> & h)1889     DeadMatrixView_(MatrixHelper<S>&       h) : Base(h) {}
1890 
1891     DeadMatrixView_& operator=(const Matrix_<ELT>& v)     { Base::operator=(v); return *this; }
1892     DeadMatrixView_& operator=(const ELT& e)              { Base::operator=(e); return *this; }
1893 
1894     template <class EE> DeadMatrixView_& operator=(const MatrixBase<EE>& m)
1895       { Base::operator=(m); return *this; }
1896     template <class EE> DeadMatrixView_& operator+=(const MatrixBase<EE>& m)
1897       { Base::operator+=(m); return *this; }
1898     template <class EE> DeadMatrixView_& operator-=(const MatrixBase<EE>& m)
1899       { Base::operator-=(m); return *this; }
1900 
1901     DeadMatrixView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
1902     DeadMatrixView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
1903     DeadMatrixView_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
1904     DeadMatrixView_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }
1905 
1906 private:
1907     // NO DATA MEMBERS ALLOWED
1908     DeadMatrixView_(); // default constructor suppressed (what's it a view of?)
1909 };
1910 
1911 template <class ELT> inline
MatrixView_(DeadMatrixView_<ELT> & dead)1912 MatrixView_<ELT>::MatrixView_(DeadMatrixView_<ELT>& dead)
1913 :   Base(dead.updHelper().stealRep()) {}
1914 
1915 template <class ELT> inline MatrixView_<ELT>&
1916 MatrixView_<ELT>::operator=(DeadMatrixView_<ELT>& dead) {
1917     if (Base::getHelper().getCharacterCommitment().isSatisfiedBy(dead.getMatrixCharacter()))
1918         Base::updHelper().replaceRep(dead.updHelper().stealRep());
1919     else
1920         Base::operator=(dead);
1921     return *this;
1922 }
1923 
1924 #endif
1925 //  ---------------------------------- Matrix_ ---------------------------------
1926 /// This is the Matrix class intended to appear in user code. It can be a
1927 /// fixed-size view of someone else's data, or can be a resizable data owner itself.
1928 //  ----------------------------------------------------------------------------
1929 template <class ELT> class Matrix_ : public MatrixBase<ELT> {
1930 #ifndef SWIG
1931     typedef typename CNT<ELT>::Scalar       S;
1932     typedef typename CNT<ELT>::Number       Number;
1933     typedef typename CNT<ELT>::StdNumber    StdNumber;
1934 
1935     typedef typename CNT<ELT>::TNeg         ENeg;
1936     typedef typename CNT<ELT>::THerm        EHerm;
1937 
1938     typedef MatrixBase<ELT>     Base;
1939     typedef MatrixBase<ENeg>    BaseNeg;
1940     typedef MatrixBase<EHerm>   BaseHerm;
1941 
1942     typedef Matrix_<ELT>        T;
1943     typedef MatrixView_<ELT>    TView;
1944     typedef Matrix_<ENeg>       TNeg;
1945 #endif
1946 public:
Matrix_()1947     Matrix_() : Base() { }
1948 #ifndef SWIG
Matrix_(const MatrixCommitment & mc)1949     Matrix_(const MatrixCommitment& mc) : Base(mc) {}
1950 #endif
1951     // Copy constructor is deep.
Matrix_(const Matrix_ & src)1952     Matrix_(const Matrix_& src) : Base(src) { }
1953 #ifndef SWIG
1954     // Assignment is a deep copy and will also allow reallocation if this Matrix
1955     // doesn't have a view.
1956     Matrix_& operator=(const Matrix_& src) {
1957         Base::operator=(src); return *this;
1958     }
1959 
1960     // Force a deep copy of the view or whatever this is.
1961     // Note that this is an implicit conversion.
Matrix_(const Base & v)1962     Matrix_(const Base& v) : Base(v) {}   // e.g., MatrixView
1963 
1964     // Allow implicit conversion from a source matrix that
1965     // has a negated version of ELT.
Matrix_(const BaseNeg & v)1966     Matrix_(const BaseNeg& v) : Base(v) {}
1967 #endif
1968     // TODO: implicit conversion from conjugate. This is trickier
1969     // since real elements are their own conjugate so you'll get
1970     // duplicate methods defined from Matrix_(BaseHerm) and Matrix_(Base).
1971 
Matrix_(int m,int n)1972     Matrix_(int m, int n) : Base(MatrixCommitment(), m, n) {}
1973 #ifndef SWIG
Matrix_(int m,int n,const ELT * cppInitialValuesByRow)1974     Matrix_(int m, int n, const ELT* cppInitialValuesByRow)
1975     :   Base(MatrixCommitment(), m, n, cppInitialValuesByRow) {}
1976 #endif
Matrix_(int m,int n,const ELT & initialValue)1977     Matrix_(int m, int n, const ELT& initialValue)
1978     :   Base(MatrixCommitment(), m, n, initialValue) {}
1979 #ifndef SWIG
Matrix_(int m,int n,int leadingDim,const S * data)1980     Matrix_(int m, int n, int leadingDim, const S* data) // read only
1981     :   Base(MatrixCommitment(), MatrixCharacter::LapackFull(m,n),
1982              leadingDim, data) {}
Matrix_(int m,int n,int leadingDim,S * data)1983     Matrix_(int m, int n, int leadingDim, S* data) // writable
1984     :   Base(MatrixCommitment(), MatrixCharacter::LapackFull(m,n),
1985              leadingDim, data) {}
1986 
1987     /// Convert a Mat to a Matrix_.
1988     template <int M, int N, int CS, int RS>
Matrix_(const Mat<M,N,ELT,CS,RS> & mat)1989     explicit Matrix_(const Mat<M,N,ELT,CS,RS>& mat)
1990     :   Base(MatrixCommitment(), M, N)
1991     {   for (int i = 0; i < M; ++i)
1992             for (int j = 0; j < N; ++j)
1993                 this->updElt(i, j) = mat(i, j); }
1994 
1995     Matrix_& operator=(const ELT& v) { Base::operator=(v); return *this; }
1996 
1997     template <class EE> Matrix_& operator=(const MatrixBase<EE>& m)
1998       { Base::operator=(m); return*this; }
1999     template <class EE> Matrix_& operator+=(const MatrixBase<EE>& m)
2000       { Base::operator+=(m); return*this; }
2001     template <class EE> Matrix_& operator-=(const MatrixBase<EE>& m)
2002       { Base::operator-=(m); return*this; }
2003 
2004     Matrix_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
2005     Matrix_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
2006     Matrix_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
2007     Matrix_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }
2008 
negate()2009     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
updNegate()2010     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
2011 
2012     const TNeg& operator-() const {return negate();}
2013     TNeg&       operator-()       {return updNegate();}
2014 #endif
2015     // Functions to be used for Scripting in MATLAB and languages that do not support operator overloading
2016     // toString() returns a string representation of the Matrix_. Please refer to operator<< for details.
toString()2017     std::string toString() const {
2018         std::stringstream stream;
2019         stream <<  (*this) ;
2020         return stream.str();
2021     }
2022     /** Variant of indexing operator that's scripting friendly to get entry (i, j) **/
get(int i,int j)2023     const ELT& get(int i,int j) const { return getElt(i,j); }
2024     /** Variant of indexing operator that's scripting friendly to set entry (i, j) **/
set(int i,int j,const ELT & value)2025     void       set(int i,int j, const ELT& value)       { updElt(i,j)=value; }
2026 
2027 private:
2028     // NO DATA MEMBERS ALLOWED
2029 };
2030 
2031 //  -------------------------------- VectorView_ -------------------------------
2032 /// This class is identical to a Vector_; it is used only to manage the C++ rules
2033 /// for when copy constructors are called by introducing a separate type to
2034 /// prevent certain allowed optimizations from occuring when we don't want them.
2035 /// Despite the name, this may be an owner if a Vector_ is recast to a VectorView_.
2036 /// However, there are no owner constructors for VectorView_.
2037 //  ----------------------------------------------------------------------------
2038 template <class ELT> class VectorView_ : public VectorBase<ELT> {
2039 #ifndef SWIG
2040     typedef VectorBase<ELT>                             Base;
2041     typedef typename CNT<ELT>::Scalar                   S;
2042     typedef typename CNT<ELT>::Number                   Number;
2043     typedef typename CNT<ELT>::StdNumber                StdNumber;
2044     typedef VectorView_<ELT>                            T;
2045     typedef VectorView_< typename CNT<ELT>::TNeg >      TNeg;
2046     typedef RowVectorView_< typename CNT<ELT>::THerm >  THerm;
2047 #endif
2048 public:
2049     // Default construction is suppressed.
2050     // Uses default destructor.
2051 
2052 #ifndef SWIG
2053     // Create a VectorView_ handle using a given helper rep.
VectorView_(MatrixHelperRep<S> * hrep)2054     explicit VectorView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
2055 #endif
2056 
2057     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
2058     // if it was present in the source. This is necessary to allow temporary views to be
2059     // created and used as lvalues.
VectorView_(const VectorView_ & v)2060     VectorView_(const VectorView_& v)
2061       : Base(const_cast<MatrixHelper<S>&>(v.getHelper()), typename MatrixHelper<S>::ShallowCopy()) { }
2062 
2063     // Copy assignment is deep but not reallocating.
2064     VectorView_& operator=(const VectorView_& v) {
2065         Base::operator=(v); return *this;
2066     }
2067 
2068 #ifndef SWIG
2069     // Ask for shallow copy
VectorView_(const MatrixHelper<S> & h)2070     explicit VectorView_(const MatrixHelper<S>& h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
VectorView_(MatrixHelper<S> & h)2071     explicit VectorView_(MatrixHelper<S>&       h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
2072 #endif
2073 
2074     VectorView_& operator=(const Base& b) { Base::operator=(b); return *this; }
2075 
2076     VectorView_& operator=(const ELT& v) { Base::operator=(v); return *this; }
2077 
2078     template <class EE> VectorView_& operator=(const VectorBase<EE>& m)
2079       { Base::operator=(m); return*this; }
2080     template <class EE> VectorView_& operator+=(const VectorBase<EE>& m)
2081       { Base::operator+=(m); return*this; }
2082     template <class EE> VectorView_& operator-=(const VectorBase<EE>& m)
2083       { Base::operator-=(m); return*this; }
2084 
2085 #ifndef SWIG
2086     VectorView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
2087     VectorView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
2088     VectorView_& operator+=(const ELT& b) { this->elementwiseAddScalarInPlace(b); return *this; }
2089     VectorView_& operator-=(const ELT& b) { this->elementwiseSubtractScalarInPlace(b); return *this; }
2090 #endif
2091 
2092 private:
2093     // NO DATA MEMBERS ALLOWED
2094     VectorView_(); // default construction suppressed (what's it a View of?)
2095 };
2096 
2097 
2098 //  ---------------------------------- Vector_ ---------------------------------
2099 /// This is the Vector class intended to appear in user code. It can be a
2100 /// fixed-size view of someone else's data, or can be a resizable data owner
2101 /// itself, although of course it will always have just one column.
2102 //  ----------------------------------------------------------------------------
2103 #ifndef SWIG
2104 template <class ELT> class Vector_ : public VectorBase<ELT> {
2105 #else
2106 template <class ELT=double> class Vector_ : public VectorBase<ELT> {
2107 #endif
2108 #ifndef SWIG
2109     typedef typename CNT<ELT>::Scalar       S;
2110     typedef typename CNT<ELT>::Number       Number;
2111     typedef typename CNT<ELT>::StdNumber    StdNumber;
2112     typedef typename CNT<ELT>::TNeg         ENeg;
2113     typedef VectorBase<ELT>                 Base;
2114     typedef VectorBase<ENeg>                BaseNeg;
2115 #endif
2116 public:
Vector_()2117     Vector_() : Base() {}  // 0x1 reallocatable
2118     // Uses default destructor.
2119     // Copy constructor is deep.
Vector_(const Vector_ & src)2120     Vector_(const Vector_& src) : Base(src) {}
2121 
2122 #ifndef SWIG
2123     // Implicit conversions.
Vector_(const Base & src)2124     Vector_(const Base& src) : Base(src) {}    // e.g., VectorView
Vector_(const BaseNeg & src)2125     Vector_(const BaseNeg& src) : Base(src) {}
2126 
2127     // Copy assignment is deep and can be reallocating if this Vector
2128     // has no View.
2129 
2130     Vector_& operator=(const Vector_& src) {
2131         Base::operator=(src); return*this;
2132     }
2133 
2134 
Vector_(int m)2135     explicit Vector_(int m) : Base(m) { }
2136 
Vector_(int m,const ELT * cppInitialValues)2137     Vector_(int m, const ELT* cppInitialValues) : Base(m, cppInitialValues) {}
2138 #endif
Vector_(int m,const ELT & initialValue)2139     Vector_(int m, const ELT& initialValue)     : Base(m, initialValue) {}
2140 #ifndef SWIG
2141     /// Construct a Vector which uses borrowed space with assumed
2142     /// element-to-element stride equal to the C++ element spacing.
2143     /// Last parameter is a dummy to avoid overload conflicts when ELT=S;
2144     /// pass it as "true".
Vector_(int m,const S * cppData,bool)2145     Vector_(int m, const S* cppData, bool): Base(m, Base::CppNScalarsPerElement, cppData) {}
Vector_(int m,S * cppData,bool)2146     Vector_(int m,       S* cppData, bool): Base(m, Base::CppNScalarsPerElement, cppData) {}
2147 
2148     /// Borrowed-space construction with explicit stride supplied as
2149     /// "number of scalars between elements". Last parameter is a
2150     /// dummy to avoid overload conflicts; pass it as "true".
Vector_(int m,int stride,const S * data,bool)2151     Vector_(int m, int stride, const S* data, bool) : Base(m, stride, data) {}
Vector_(int m,int stride,S * data,bool)2152     Vector_(int m, int stride,       S* data, bool) : Base(m, stride, data) {}
2153 
2154     /// Convert a Vec to a Vector_.
2155     template <int M>
Vector_(const Vec<M,ELT> & v)2156     explicit Vector_(const Vec<M,ELT>& v) : Base(M) {
2157         for (int i = 0; i < M; ++i)
2158             this->updElt(i, 0) = v(i);
2159     }
2160 
2161     Vector_& operator=(const ELT& v) { Base::operator=(v); return *this; }
2162 
2163     template <class EE> Vector_& operator=(const VectorBase<EE>& m)
2164       { Base::operator=(m); return*this; }
2165     template <class EE> Vector_& operator+=(const VectorBase<EE>& m)
2166       { Base::operator+=(m); return*this; }
2167     template <class EE> Vector_& operator-=(const VectorBase<EE>& m)
2168       { Base::operator-=(m); return*this; }
2169 
2170     Vector_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
2171     Vector_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
2172     Vector_& operator+=(const ELT& b) { this->elementwiseAddScalarInPlace(b); return *this; }
2173     Vector_& operator-=(const ELT& b) { this->elementwiseSubtractScalarInPlace(b); return *this; }
2174 #endif
2175    // Functions to be used for Scripting in MATLAB and languages that do not support operator overloading
2176     // toString() returns a string representation of the Vector_. Please refer to operator<< for details.
toString()2177     std::string toString() const {
2178         std::stringstream stream;
2179         stream <<  (*this) ;
2180         return stream.str();
2181     }
2182     /** Variant of operator[] that's scripting friendly to get ith entry **/
get(int i)2183     const ELT& get(int i) const { return (*this)[i]; }
2184     /** Variant of operator[] that's scripting friendly to set ith entry **/
set(int i,const ELT & value)2185     void  set (int i, const ELT& value)  { (*this)[i]=value; }
2186 
2187 private:
2188     // NO DATA MEMBERS ALLOWED
2189 
2190 };
2191 
2192 
2193 //  ------------------------------ RowVectorView_ ------------------------------
2194 /// This class is identical to a RowVector_; it is used only to manage the C++
2195 /// rules for when copy constructors are called by introducing a separate type to
2196 /// prevent certain allowed optimizations from occuring when we don't want them.
2197 /// Despite the name, this may be an owner if a RowVector_ is recast to a
2198 /// RowVectorView_. However, there are no owner constructors for RowVectorView_.
2199 //  ----------------------------------------------------------------------------
2200 template <class ELT> class RowVectorView_ : public RowVectorBase<ELT> {
2201 #ifndef SWIG
2202     typedef RowVectorBase<ELT>                              Base;
2203     typedef typename CNT<ELT>::Scalar                       S;
2204     typedef typename CNT<ELT>::Number                       Number;
2205     typedef typename CNT<ELT>::StdNumber                    StdNumber;
2206     typedef RowVectorView_<ELT>                             T;
2207     typedef RowVectorView_< typename CNT<ELT>::TNeg >       TNeg;
2208     typedef VectorView_< typename CNT<ELT>::THerm >         THerm;
2209 #endif
2210 public:
2211     // Default construction is suppressed.
2212     // Uses default destructor.
2213 
2214 #ifndef SWIG
2215     // Create a RowVectorView_ handle using a given helper rep.
RowVectorView_(MatrixHelperRep<S> * hrep)2216     explicit RowVectorView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
2217 #endif
2218 
2219     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
2220     // if it was present in the source. This is necessary to allow temporary views to be
2221     // created and used as lvalues.
RowVectorView_(const RowVectorView_ & r)2222     RowVectorView_(const RowVectorView_& r)
2223       : Base(const_cast<MatrixHelper<S>&>(r.getHelper()), typename MatrixHelper<S>::ShallowCopy()) { }
2224 
2225     // Copy assignment is deep but not reallocating.
2226     RowVectorView_& operator=(const RowVectorView_& r) {
2227         Base::operator=(r); return *this;
2228     }
2229 
2230 #ifndef SWIG
2231     // Ask for shallow copy
RowVectorView_(const MatrixHelper<S> & h)2232     explicit RowVectorView_(const MatrixHelper<S>& h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
RowVectorView_(MatrixHelper<S> & h)2233     explicit RowVectorView_(MatrixHelper<S>&       h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
2234 #endif
2235 
2236     RowVectorView_& operator=(const Base& b) { Base::operator=(b); return *this; }
2237 
2238     RowVectorView_& operator=(const ELT& v) { Base::operator=(v); return *this; }
2239 
2240     template <class EE> RowVectorView_& operator=(const RowVectorBase<EE>& m)
2241       { Base::operator=(m); return*this; }
2242     template <class EE> RowVectorView_& operator+=(const RowVectorBase<EE>& m)
2243       { Base::operator+=(m); return*this; }
2244     template <class EE> RowVectorView_& operator-=(const RowVectorBase<EE>& m)
2245       { Base::operator-=(m); return*this; }
2246 
2247 #ifndef SWIG
2248     RowVectorView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
2249     RowVectorView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
2250     RowVectorView_& operator+=(const ELT& b) { this->elementwiseAddScalarInPlace(b); return *this; }
2251     RowVectorView_& operator-=(const ELT& b) { this->elementwiseSubtractScalarInPlace(b); return *this; }
2252 #endif
2253 
2254 private:
2255     // NO DATA MEMBERS ALLOWED
2256     RowVectorView_(); // default construction suppressed (what is it a view of?)
2257 };
2258 
2259 
2260 
2261 //  -------------------------------- RowVector_ --------------------------------
2262 /// RowVectors are much less common than Vectors. However, if a Simmatrix user
2263 /// wants one, this is the class intended to appear in user code. It can be a
2264 /// fixed-size view of someone else's data, or can be a resizable data owner
2265 /// itself, although of course it will always have just one row.
2266 //  ----------------------------------------------------------------------------
2267 template <class ELT> class RowVector_ : public RowVectorBase<ELT> {
2268 #ifndef SWIG
2269     typedef typename CNT<ELT>::Scalar       S;
2270     typedef typename CNT<ELT>::Number       Number;
2271     typedef typename CNT<ELT>::StdNumber    StdNumber;
2272     typedef typename CNT<ELT>::TNeg         ENeg;
2273 
2274     typedef RowVectorBase<ELT>              Base;
2275     typedef RowVectorBase<ENeg>             BaseNeg;
2276 #endif
2277 public:
RowVector_()2278     RowVector_() : Base() {}   // 1x0 reallocatable
2279     // Uses default destructor.
2280 
2281     // Copy constructor is deep.
RowVector_(const RowVector_ & src)2282     RowVector_(const RowVector_& src) : Base(src) {}
2283 
2284 #ifndef SWIG
2285     // Implicit conversions.
RowVector_(const Base & src)2286     RowVector_(const Base& src) : Base(src) {}    // e.g., RowVectorView
RowVector_(const BaseNeg & src)2287     RowVector_(const BaseNeg& src) : Base(src) {}
2288 #endif
2289 
2290     // Copy assignment is deep and can be reallocating if this RowVector
2291     // has no View.
2292     RowVector_& operator=(const RowVector_& src) {
2293         Base::operator=(src); return*this;
2294     }
2295 
2296 
RowVector_(int n)2297     explicit RowVector_(int n) : Base(n) { }
RowVector_(int n,const ELT * cppInitialValues)2298     RowVector_(int n, const ELT* cppInitialValues) : Base(n, cppInitialValues) {}
RowVector_(int n,const ELT & initialValue)2299     RowVector_(int n, const ELT& initialValue)     : Base(n, initialValue) {}
2300 
2301 #ifndef SWIG
2302     /// Construct a Vector which uses borrowed space with assumed
2303     /// element-to-element stride equal to the C++ element spacing.
2304     /// Last parameter is a dummy to avoid overload conflicts when ELT=S;
2305     /// pass it as "true".
RowVector_(int n,const S * cppData,bool)2306     RowVector_(int n, const S* cppData, bool): Base(n, Base::CppNScalarsPerElement, cppData) {}
RowVector_(int n,S * cppData,bool)2307     RowVector_(int n,       S* cppData, bool): Base(n, Base::CppNScalarsPerElement, cppData) {}
2308 
2309     /// Borrowed-space construction with explicit stride supplied as
2310     /// "number of scalars between elements". Last parameter is a
2311     /// dummy to avoid overload conflicts; pass it as "true".
RowVector_(int n,int stride,const S * data,bool)2312     RowVector_(int n, int stride, const S* data, bool) : Base(n, stride, data) {}
RowVector_(int n,int stride,S * data,bool)2313     RowVector_(int n, int stride,       S* data, bool) : Base(n, stride, data) {}
2314 #endif
2315 
2316     /// Convert a Row to a RowVector_.
2317     template <int M>
RowVector_(const Row<M,ELT> & v)2318     explicit RowVector_(const Row<M,ELT>& v) : Base(M) {
2319         for (int i = 0; i < M; ++i)
2320             this->updElt(0, i) = v(i);
2321     }
2322 
2323     RowVector_& operator=(const ELT& v) { Base::operator=(v); return *this; }
2324 
2325     template <class EE> RowVector_& operator=(const RowVectorBase<EE>& b)
2326       { Base::operator=(b); return*this; }
2327     template <class EE> RowVector_& operator+=(const RowVectorBase<EE>& b)
2328       { Base::operator+=(b); return*this; }
2329     template <class EE> RowVector_& operator-=(const RowVectorBase<EE>& b)
2330       { Base::operator-=(b); return*this; }
2331 
2332 #ifndef SWIG
2333     RowVector_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
2334     RowVector_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
2335     RowVector_& operator+=(const ELT& b) { this->elementwiseAddScalarInPlace(b); return *this; }
2336     RowVector_& operator-=(const ELT& b) { this->elementwiseSubtractScalarInPlace(b); return *this; }
2337 #endif
2338 
2339 private:
2340     // NO DATA MEMBERS ALLOWED
2341 };
2342 
2343 #ifndef SWIG
2344 
2345 
2346 //  ------------------------ MatrixBase definitions ----------------------------
2347 
2348 template <class ELT> inline MatrixView_<ELT>
block(int i,int j,int m,int n)2349 MatrixBase<ELT>::block(int i, int j, int m, int n) const {
2350     SimTK_INDEXCHECK(i,nrow()+1,"MatrixBase::block()");
2351     SimTK_INDEXCHECK(j,ncol()+1,"MatrixBase::block()");
2352     SimTK_SIZECHECK(i+m,nrow(),"MatrixBase::block()");
2353     SimTK_SIZECHECK(j+n,ncol(),"MatrixBase::block()");
2354 
2355     MatrixHelper<Scalar> h(MatrixCommitment(),helper,i,j,m,n);
2356     return MatrixView_<ELT>(h.stealRep());
2357 }
2358 
2359 template <class ELT> inline MatrixView_<ELT>
updBlock(int i,int j,int m,int n)2360 MatrixBase<ELT>::updBlock(int i, int j, int m, int n) {
2361     SimTK_INDEXCHECK(i,nrow()+1,"MatrixBase::updBlock()");
2362     SimTK_INDEXCHECK(j,ncol()+1,"MatrixBase::updBlock()");
2363     SimTK_SIZECHECK(i+m,nrow(),"MatrixBase::updBlock()");
2364     SimTK_SIZECHECK(j+n,ncol(),"MatrixBase::updBlock()");
2365 
2366     MatrixHelper<Scalar> h(MatrixCommitment(),helper,i,j,m,n);
2367     return MatrixView_<ELT>(h.stealRep());
2368 }
2369 
2370 template <class E> inline MatrixView_<typename CNT<E>::THerm>
transpose()2371 MatrixBase<E>::transpose() const {
2372     MatrixHelper<typename CNT<Scalar>::THerm>
2373         h(MatrixCommitment(),
2374           helper, typename MatrixHelper<typename CNT<Scalar>::THerm>::TransposeView());
2375     return MatrixView_<typename CNT<E>::THerm>(h.stealRep());
2376 }
2377 
2378 template <class E> inline MatrixView_<typename CNT<E>::THerm>
updTranspose()2379 MatrixBase<E>::updTranspose() {
2380     MatrixHelper<typename CNT<Scalar>::THerm>
2381         h(MatrixCommitment(),
2382           helper, typename MatrixHelper<typename CNT<Scalar>::THerm>::TransposeView());
2383     return MatrixView_<typename CNT<E>::THerm>(h.stealRep());
2384 }
2385 
2386 template <class E> inline VectorView_<E>
diag()2387 MatrixBase<E>::diag() const {
2388     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
2389                            helper, typename MatrixHelper<Scalar>::DiagonalView());
2390     return VectorView_<E>(h.stealRep());
2391 }
2392 
2393 template <class E> inline VectorView_<E>
updDiag()2394 MatrixBase<E>::updDiag() {
2395     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
2396                            helper, typename MatrixHelper<Scalar>::DiagonalView());
2397     return VectorView_<E>(h.stealRep());
2398 }
2399 
2400 template <class ELT> inline VectorView_<ELT>
col(int j)2401 MatrixBase<ELT>::col(int j) const {
2402     SimTK_INDEXCHECK(j,ncol(),"MatrixBase::col()");
2403 
2404     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
2405                            helper,0,j,nrow(),1);
2406     return VectorView_<ELT>(h.stealRep());
2407 }
2408 
2409 template <class ELT> inline VectorView_<ELT>
updCol(int j)2410 MatrixBase<ELT>::updCol(int j) {
2411     SimTK_INDEXCHECK(j,ncol(),"MatrixBase::updCol()");
2412 
2413     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
2414                            helper,0,j,nrow(),1);
2415     return VectorView_<ELT>(h.stealRep());
2416 }
2417 
2418 template <class ELT> inline RowVectorView_<ELT>
row(int i)2419 MatrixBase<ELT>::row(int i) const {
2420     SimTK_INDEXCHECK(i,nrow(),"MatrixBase::row()");
2421 
2422     MatrixHelper<Scalar> h(MatrixCommitment::RowVector(),
2423                            helper,i,0,1,ncol());
2424     return RowVectorView_<ELT>(h.stealRep());
2425 }
2426 
2427 template <class ELT> inline RowVectorView_<ELT>
updRow(int i)2428 MatrixBase<ELT>::updRow(int i) {
2429     SimTK_INDEXCHECK(i,nrow(),"MatrixBase::updRow()");
2430 
2431     MatrixHelper<Scalar> h(MatrixCommitment::RowVector(),
2432                            helper,i,0,1,ncol());
2433     return RowVectorView_<ELT>(h.stealRep());
2434 }
2435 
2436 // M = diag(v) * M; v must have nrow() elements.
2437 // That is, M[i] *= v[i].
2438 template <class ELT> template <class EE> inline MatrixBase<ELT>&
rowScaleInPlace(const VectorBase<EE> & v)2439 MatrixBase<ELT>::rowScaleInPlace(const VectorBase<EE>& v) {
2440     assert(v.nrow() == nrow());
2441     for (int i=0; i < nrow(); ++i)
2442         (*this)[i] *= v[i];
2443     return *this;
2444 }
2445 
2446 template <class ELT> template <class EE> inline void
rowScale(const VectorBase<EE> & v,typename MatrixBase<ELT>::template EltResult<EE>::Mul & out)2447 MatrixBase<ELT>::rowScale(const VectorBase<EE>& v, typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const {
2448     assert(v.nrow() == nrow());
2449     out.resize(nrow(), ncol());
2450     for (int j=0; j<ncol(); ++j)
2451         for (int i=0; i<nrow(); ++i)
2452            out(i,j) = (*this)(i,j) * v[i];
2453 }
2454 
2455 // M = M * diag(v); v must have ncol() elements
2456 // That is, M(i) *= v[i]
2457 template <class ELT> template <class EE>  inline MatrixBase<ELT>&
colScaleInPlace(const VectorBase<EE> & v)2458 MatrixBase<ELT>::colScaleInPlace(const VectorBase<EE>& v) {
2459     assert(v.nrow() == ncol());
2460     for (int j=0; j < ncol(); ++j)
2461         (*this)(j) *= v[j];
2462     return *this;
2463 }
2464 
2465 template <class ELT> template <class EE> inline void
colScale(const VectorBase<EE> & v,typename MatrixBase<ELT>::template EltResult<EE>::Mul & out)2466 MatrixBase<ELT>::colScale(const VectorBase<EE>& v, typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const {
2467     assert(v.nrow() == ncol());
2468     out.resize(nrow(), ncol());
2469     for (int j=0; j<ncol(); ++j)
2470         for (int i=0; i<nrow(); ++i)
2471            out(i,j) = (*this)(i,j) * v[j];
2472 }
2473 
2474 
2475 // M(i,j) *= r[i]*c[j]; r must have nrow() elements; c must have ncol() elements
2476 template <class ELT> template <class ER, class EC> inline MatrixBase<ELT>&
rowAndColScaleInPlace(const VectorBase<ER> & r,const VectorBase<EC> & c)2477 MatrixBase<ELT>::rowAndColScaleInPlace(const VectorBase<ER>& r, const VectorBase<EC>& c) {
2478     assert(r.nrow()==nrow() && c.nrow()==ncol());
2479     for (int j=0; j<ncol(); ++j)
2480         for (int i=0; i<nrow(); ++i)
2481             (*this)(i,j) *= (r[i]*c[j]);
2482     return *this;
2483 }
2484 
2485 template <class ELT> template <class ER, class EC> inline void
rowAndColScale(const VectorBase<ER> & r,const VectorBase<EC> & c,typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul & out)2486 MatrixBase<ELT>::rowAndColScale(
2487     const VectorBase<ER>& r,
2488     const VectorBase<EC>& c,
2489     typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul&
2490                           out) const
2491 {
2492     assert(r.nrow()==nrow() && c.nrow()==ncol());
2493     out.resize(nrow(), ncol());
2494     for (int j=0; j<ncol(); ++j)
2495         for (int i=0; i<nrow(); ++i)
2496             out(i,j) = (*this)(i,j) * (r[i]*c[j]);
2497 }
2498 
2499 // M(i,j) = s
2500 template <class ELT> template <class S> inline MatrixBase<ELT>&
elementwiseAssign(const S & s)2501 MatrixBase<ELT>::elementwiseAssign(const S& s) {
2502     for (int j=0; j<ncol(); ++j)
2503     for (int i=0; i<nrow(); ++i)
2504         (*this)(i,j) = s;
2505     return *this;
2506 }
2507 
2508 // Set M(i,j) = M(i,j)^-1.
2509 template <class ELT> inline MatrixBase<ELT>&
elementwiseInvertInPlace()2510 MatrixBase<ELT>::elementwiseInvertInPlace() {
2511     const int nr=nrow(), nc=ncol();
2512     for (int j=0; j<nc; ++j)
2513         for (int i=0; i<nr; ++i) {
2514             ELT& e = updElt(i,j);
2515             e = CNT<ELT>::invert(e);
2516         }
2517     return *this;
2518 }
2519 
2520 template <class ELT> inline void
elementwiseInvert(MatrixBase<typename CNT<E>::TInvert> & out)2521 MatrixBase<ELT>::elementwiseInvert(MatrixBase<typename CNT<E>::TInvert>& out) const {
2522     const int nr=nrow(), nc=ncol();
2523     out.resize(nr,nc);
2524     for (int j=0; j<nc; ++j)
2525         for (int i=0; i<nr; ++i)
2526             out(i,j) = CNT<ELT>::invert((*this)(i,j));
2527 }
2528 
2529 // M(i,j) += s
2530 template <class ELT> template <class S> inline MatrixBase<ELT>&
elementwiseAddScalarInPlace(const S & s)2531 MatrixBase<ELT>::elementwiseAddScalarInPlace(const S& s) {
2532     for (int j=0; j<ncol(); ++j)
2533         for (int i=0; i<nrow(); ++i)
2534             (*this)(i,j) += s;
2535     return *this;
2536 }
2537 
2538 template <class ELT> template <class S> inline void
elementwiseAddScalar(const S & s,typename MatrixBase<ELT>::template EltResult<S>::Add & out)2539 MatrixBase<ELT>::elementwiseAddScalar(
2540     const S& s,
2541     typename MatrixBase<ELT>::template EltResult<S>::Add& out) const
2542 {
2543     const int nr=nrow(), nc=ncol();
2544     out.resize(nr,nc);
2545     for (int j=0; j<nc; ++j)
2546         for (int i=0; i<nr; ++i)
2547             out(i,j) = (*this)(i,j) + s;
2548 }
2549 
2550 // M(i,j) -= s
2551 template <class ELT> template <class S> inline MatrixBase<ELT>&
elementwiseSubtractScalarInPlace(const S & s)2552 MatrixBase<ELT>::elementwiseSubtractScalarInPlace(const S& s) {
2553     for (int j=0; j<ncol(); ++j)
2554         for (int i=0; i<nrow(); ++i)
2555             (*this)(i,j) -= s;
2556     return *this;
2557 }
2558 
2559 template <class ELT> template <class S> inline void
elementwiseSubtractScalar(const S & s,typename MatrixBase<ELT>::template EltResult<S>::Sub & out)2560 MatrixBase<ELT>::elementwiseSubtractScalar(
2561     const S& s,
2562     typename MatrixBase<ELT>::template EltResult<S>::Sub& out) const
2563 {
2564     const int nr=nrow(), nc=ncol();
2565     out.resize(nr,nc);
2566     for (int j=0; j<nc; ++j)
2567         for (int i=0; i<nr; ++i)
2568             out(i,j) = (*this)(i,j) - s;
2569 }
2570 
2571 // M(i,j) = s - M(i,j)
2572 template <class ELT> template <class S> inline MatrixBase<ELT>&
elementwiseSubtractFromScalarInPlace(const S & s)2573 MatrixBase<ELT>::elementwiseSubtractFromScalarInPlace(const S& s) {
2574     const int nr=nrow(), nc=ncol();
2575     for (int j=0; j<nc; ++j)
2576         for (int i=0; i<nr; ++i) {
2577             ELT& e = updElt(i,j);
2578             e = s - e;
2579         }
2580     return *this;
2581 }
2582 
2583 template <class ELT> template <class S> inline void
elementwiseSubtractFromScalar(const S & s,typename MatrixBase<S>::template EltResult<ELT>::Sub & out)2584 MatrixBase<ELT>::elementwiseSubtractFromScalar(
2585     const S& s,
2586     typename MatrixBase<S>::template EltResult<ELT>::Sub& out) const
2587 {
2588     const int nr=nrow(), nc=ncol();
2589     out.resize(nr,nc);
2590     for (int j=0; j<nc; ++j)
2591         for (int i=0; i<nr; ++i)
2592             out(i,j) = s - (*this)(i,j);
2593 }
2594 
2595 // M(i,j) *= R(i,j); R must have same dimensions as this
2596 template <class ELT> template <class EE> inline MatrixBase<ELT>&
elementwiseMultiplyInPlace(const MatrixBase<EE> & r)2597 MatrixBase<ELT>::elementwiseMultiplyInPlace(const MatrixBase<EE>& r) {
2598     const int nr=nrow(), nc=ncol();
2599     assert(r.nrow()==nr && r.ncol()==nc);
2600     for (int j=0; j<nc; ++j)
2601         for (int i=0; i<nr; ++i)
2602             (*this)(i,j) *= r(i,j);
2603     return *this;
2604 }
2605 
2606 template <class ELT> template <class EE> inline void
elementwiseMultiply(const MatrixBase<EE> & r,typename MatrixBase<ELT>::template EltResult<EE>::Mul & out)2607 MatrixBase<ELT>::elementwiseMultiply(
2608     const MatrixBase<EE>& r,
2609     typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const
2610 {
2611     const int nr=nrow(), nc=ncol();
2612     assert(r.nrow()==nr && r.ncol()==nc);
2613     out.resize(nr,nc);
2614     for (int j=0; j<nc; ++j)
2615         for (int i=0; i<nr; ++i)
2616             out(i,j) = (*this)(i,j) * r(i,j);
2617 }
2618 
2619 // M(i,j) = R(i,j) * M(i,j); R must have same dimensions as this
2620 template <class ELT> template <class EE> inline MatrixBase<ELT>&
elementwiseMultiplyFromLeftInPlace(const MatrixBase<EE> & r)2621 MatrixBase<ELT>::elementwiseMultiplyFromLeftInPlace(const MatrixBase<EE>& r) {
2622     const int nr=nrow(), nc=ncol();
2623     assert(r.nrow()==nr && r.ncol()==nc);
2624     for (int j=0; j<nc; ++j)
2625         for (int i=0; i<nr; ++i) {
2626             ELT& e = updElt(i,j);
2627             e = r(i,j) * e;
2628         }
2629     return *this;
2630 }
2631 
2632 template <class ELT> template <class EE> inline void
elementwiseMultiplyFromLeft(const MatrixBase<EE> & r,typename MatrixBase<EE>::template EltResult<ELT>::Mul & out)2633 MatrixBase<ELT>::elementwiseMultiplyFromLeft(
2634     const MatrixBase<EE>& r,
2635     typename MatrixBase<EE>::template EltResult<ELT>::Mul& out) const
2636 {
2637     const int nr=nrow(), nc=ncol();
2638     assert(r.nrow()==nr && r.ncol()==nc);
2639     out.resize(nr,nc);
2640     for (int j=0; j<nc; ++j)
2641         for (int i=0; i<nr; ++i)
2642             out(i,j) =  r(i,j) * (*this)(i,j);
2643 }
2644 
2645 // M(i,j) /= R(i,j); R must have same dimensions as this
2646 template <class ELT> template <class EE> inline MatrixBase<ELT>&
elementwiseDivideInPlace(const MatrixBase<EE> & r)2647 MatrixBase<ELT>::elementwiseDivideInPlace(const MatrixBase<EE>& r) {
2648     const int nr=nrow(), nc=ncol();
2649     assert(r.nrow()==nr && r.ncol()==nc);
2650     for (int j=0; j<nc; ++j)
2651         for (int i=0; i<nr; ++i)
2652             (*this)(i,j) /= r(i,j);
2653     return *this;
2654 }
2655 
2656 template <class ELT> template <class EE> inline void
elementwiseDivide(const MatrixBase<EE> & r,typename MatrixBase<ELT>::template EltResult<EE>::Dvd & out)2657 MatrixBase<ELT>::elementwiseDivide(
2658     const MatrixBase<EE>& r,
2659     typename MatrixBase<ELT>::template EltResult<EE>::Dvd& out) const
2660 {
2661     const int nr=nrow(), nc=ncol();
2662     assert(r.nrow()==nr && r.ncol()==nc);
2663     out.resize(nr,nc);
2664     for (int j=0; j<nc; ++j)
2665         for (int i=0; i<nr; ++i)
2666             out(i,j) = (*this)(i,j) / r(i,j);
2667 }
2668 // M(i,j) = R(i,j) / M(i,j); R must have same dimensions as this
2669 template <class ELT> template <class EE> inline MatrixBase<ELT>&
elementwiseDivideFromLeftInPlace(const MatrixBase<EE> & r)2670 MatrixBase<ELT>::elementwiseDivideFromLeftInPlace(const MatrixBase<EE>& r) {
2671     const int nr=nrow(), nc=ncol();
2672     assert(r.nrow()==nr && r.ncol()==nc);
2673     for (int j=0; j<nc; ++j)
2674         for (int i=0; i<nr; ++i) {
2675             ELT& e = updElt(i,j);
2676             e = r(i,j) / e;
2677         }
2678     return *this;
2679 }
2680 
2681 template <class ELT> template <class EE> inline void
elementwiseDivideFromLeft(const MatrixBase<EE> & r,typename MatrixBase<EE>::template EltResult<ELT>::Dvd & out)2682 MatrixBase<ELT>::elementwiseDivideFromLeft(
2683     const MatrixBase<EE>& r,
2684     typename MatrixBase<EE>::template EltResult<ELT>::Dvd& out) const
2685 {
2686     const int nr=nrow(), nc=ncol();
2687     assert(r.nrow()==nr && r.ncol()==nc);
2688     out.resize(nr,nc);
2689     for (int j=0; j<nc; ++j)
2690         for (int i=0; i<nr; ++i)
2691             out(i,j) = r(i,j) / (*this)(i,j);
2692 }
2693 
2694 /*
2695 template <class ELT> inline MatrixView_< typename CNT<ELT>::TReal >
2696 MatrixBase<ELT>::real() const {
2697     if (!CNT<ELT>::IsComplex) { // known at compile time
2698         return MatrixView_< typename CNT<ELT>::TReal >( // this is just ELT
2699             MatrixHelper(helper,0,0,nrow(),ncol()));    // a view of the whole matrix
2700     }
2701     // Elements are complex -- helper uses underlying precision (real) type.
2702     MatrixHelper<Precision> h(helper,typename MatrixHelper<Precision>::RealView);
2703     return MatrixView_< typename CNT<ELT>::TReal >(h);
2704 }
2705 */
2706 
2707 
2708 //  ----------------------------------------------------------------------------
2709 /// @name Global operators involving Matrix objects
2710 /// These operators take MatrixBase arguments and produce Matrix_ results.
2711 /// @{
2712 
2713 // + and - allow mixed element types, but will fail to compile if the elements aren't
2714 // compatible. At run time these will fail if the dimensions are incompatible.
2715 template <class E1, class E2>
2716 Matrix_<typename CNT<E1>::template Result<E2>::Add>
2717 operator+(const MatrixBase<E1>& l, const MatrixBase<E2>& r) {
2718     return Matrix_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
2719 }
2720 
2721 template <class E>
2722 Matrix_<E> operator+(const MatrixBase<E>& l, const typename CNT<E>::T& r) {
2723     return Matrix_<E>(l) += r;
2724 }
2725 
2726 template <class E>
2727 Matrix_<E> operator+(const typename CNT<E>::T& l, const MatrixBase<E>& r) {
2728     return Matrix_<E>(r) += l;
2729 }
2730 
2731 template <class E1, class E2>
2732 Matrix_<typename CNT<E1>::template Result<E2>::Sub>
2733 operator-(const MatrixBase<E1>& l, const MatrixBase<E2>& r) {
2734     return Matrix_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
2735 }
2736 
2737 template <class E>
2738 Matrix_<E> operator-(const MatrixBase<E>& l, const typename CNT<E>::T& r) {
2739     return Matrix_<E>(l) -= r;
2740 }
2741 
2742 template <class E>
2743 Matrix_<E> operator-(const typename CNT<E>::T& l, const MatrixBase<E>& r) {
2744     Matrix_<E> temp(r.nrow(), r.ncol());
2745     temp = l;
2746     return (temp -= r);
2747 }
2748 
2749 // Scalar multiply and divide. You might wish the scalar could be
2750 // a templatized type "E2", but that would create horrible ambiguities since
2751 // E2 would match not only scalar types but everything else including
2752 // matrices.
2753 template <class E> Matrix_<E>
2754 operator*(const MatrixBase<E>& l, const typename CNT<E>::StdNumber& r)
2755   { return Matrix_<E>(l)*=r; }
2756 
2757 template <class E> Matrix_<E>
2758 operator*(const typename CNT<E>::StdNumber& l, const MatrixBase<E>& r)
2759   { return Matrix_<E>(r)*=l; }
2760 
2761 template <class E> Matrix_<E>
2762 operator/(const MatrixBase<E>& l, const typename CNT<E>::StdNumber& r)
2763   { return Matrix_<E>(l)/=r; }
2764 
2765 // Handle ints explicitly.
2766 template <class E> Matrix_<E>
2767 operator*(const MatrixBase<E>& l, int r)
2768   { return Matrix_<E>(l)*= typename CNT<E>::StdNumber(r); }
2769 
2770 template <class E> Matrix_<E>
2771 operator*(int l, const MatrixBase<E>& r)
2772   { return Matrix_<E>(r)*= typename CNT<E>::StdNumber(l); }
2773 
2774 template <class E> Matrix_<E>
2775 operator/(const MatrixBase<E>& l, int r)
2776   { return Matrix_<E>(l)/= typename CNT<E>::StdNumber(r); }
2777 
2778 /// @}
2779 
2780 /// @name Global operators involving Vector objects
2781 /// These operators take VectorBase arguments and produce Vector_ results.
2782 /// @{
2783 
2784 template <class E1, class E2>
2785 Vector_<typename CNT<E1>::template Result<E2>::Add>
2786 operator+(const VectorBase<E1>& l, const VectorBase<E2>& r) {
2787     return Vector_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
2788 }
2789 template <class E>
2790 Vector_<E> operator+(const VectorBase<E>& l, const typename CNT<E>::T& r) {
2791     return Vector_<E>(l) += r;
2792 }
2793 template <class E>
2794 Vector_<E> operator+(const typename CNT<E>::T& l, const VectorBase<E>& r) {
2795     return Vector_<E>(r) += l;
2796 }
2797 template <class E1, class E2>
2798 Vector_<typename CNT<E1>::template Result<E2>::Sub>
2799 operator-(const VectorBase<E1>& l, const VectorBase<E2>& r) {
2800     return Vector_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
2801 }
2802 template <class E>
2803 Vector_<E> operator-(const VectorBase<E>& l, const typename CNT<E>::T& r) {
2804     return Vector_<E>(l) -= r;
2805 }
2806 template <class E>
2807 Vector_<E> operator-(const typename CNT<E>::T& l, const VectorBase<E>& r) {
2808     Vector_<E> temp(r.size());
2809     temp = l;
2810     return (temp -= r);
2811 }
2812 
2813 // Scalar multiply and divide.
2814 
2815 template <class E> Vector_<E>
2816 operator*(const VectorBase<E>& l, const typename CNT<E>::StdNumber& r)
2817   { return Vector_<E>(l)*=r; }
2818 
2819 template <class E> Vector_<E>
2820 operator*(const typename CNT<E>::StdNumber& l, const VectorBase<E>& r)
2821   { return Vector_<E>(r)*=l; }
2822 
2823 template <class E> Vector_<E>
2824 operator/(const VectorBase<E>& l, const typename CNT<E>::StdNumber& r)
2825   { return Vector_<E>(l)/=r; }
2826 
2827 // Handle ints explicitly
2828 template <class E> Vector_<E>
2829 operator*(const VectorBase<E>& l, int r)
2830   { return Vector_<E>(l)*= typename CNT<E>::StdNumber(r); }
2831 
2832 template <class E> Vector_<E>
2833 operator*(int l, const VectorBase<E>& r)
2834   { return Vector_<E>(r)*= typename CNT<E>::StdNumber(l); }
2835 
2836 template <class E> Vector_<E>
2837 operator/(const VectorBase<E>& l, int r)
2838   { return Vector_<E>(l)/= typename CNT<E>::StdNumber(r); }
2839 
2840 // These are fancier "scalars"; whether they are allowed depends on
2841 // whether the element type and the CNT are compatible.
2842 
2843 // Vector * Vec
2844 template <class E1, int M, class E2, int S>
2845 Vector_<typename CNT<E1>::template Result< Vec<M,E2,S> >::Mul>
2846 operator*(const VectorBase<E1>& v, const Vec<M,E2,S>& s) {
2847     Vector_<typename CNT<E1>::template Result< Vec<M,E2,S> >::Mul> res(v.nrow());
2848     for (int i=0; i < v.nrow(); ++i)
2849         res[i] = v[i]*s;
2850     return res;
2851 }
2852 
2853 // Vec * Vector
2854 template <class E1, int M, class E2, int S>
2855 Vector_<typename Vec<M,E2,S>::template Result<E1>::Mul>
2856 operator*(const Vec<M,E2,S>& s, const VectorBase<E1>& v) {
2857     Vector_<typename Vec<M,E2,S>::template Result<E1>::Mul> res(v.nrow());
2858     for (int i=0; i < v.nrow(); ++i)
2859         res[i] = s*v[i];
2860     return res;
2861 }
2862 
2863 // Vector * Row
2864 template <class E1, int N, class E2, int S>
2865 Vector_<typename CNT<E1>::template Result< Row<N,E2,S> >::Mul>
2866 operator*(const VectorBase<E1>& v, const Row<N,E2,S>& s) {
2867     Vector_<typename CNT<E1>::template Result< Row<N,E2,S> >::Mul> res(v.nrow());
2868     for (int i=0; i < v.nrow(); ++i)
2869         res[i] = v[i]*s;
2870     return res;
2871 }
2872 
2873 // Row * Vector
2874 template <class E1, int N, class E2, int S>
2875 Vector_<typename Row<N,E2,S>::template Result<E1>::Mul>
2876 operator*(const Row<N,E2,S>& s, const VectorBase<E1>& v) {
2877     Vector_<typename Row<N,E2,S>::template Result<E1>::Mul> res(v.nrow());
2878     for (int i=0; i < v.nrow(); ++i)
2879         res[i] = s*v[i];
2880     return res;
2881 }
2882 
2883 // Vector * Mat
2884 template <class E1, int M, int N, class E2, int S1, int S2>
2885 Vector_<typename CNT<E1>::template Result< Mat<M,N,E2,S1,S2> >::Mul>
2886 operator*(const VectorBase<E1>& v, const Mat<M,N,E2,S1,S2>& s) {
2887     Vector_<typename CNT<E1>::template Result< Mat<M,N,E2,S1,S2> >::Mul> res(v.nrow());
2888     for (int i=0; i < v.nrow(); ++i)
2889         res[i] = v[i]*s;
2890     return res;
2891 }
2892 
2893 // Mat * Vector
2894 template <class E1, int M, int N, class E2, int S1, int S2>
2895 Vector_<typename Mat<M,N,E2,S1,S2>::template Result<E1>::Mul>
2896 operator*(const Mat<M,N,E2,S1,S2>& s, const VectorBase<E1>& v) {
2897     Vector_<typename Mat<M,N,E2,S1,S2>::template Result<E1>::Mul> res(v.nrow());
2898     for (int i=0; i < v.nrow(); ++i)
2899         res[i] = s*v[i];
2900     return res;
2901 }
2902 
2903 // Vector * SymMat
2904 template <class E1, int M, class E2, int S>
2905 Vector_<typename CNT<E1>::template Result< SymMat<M,E2,S> >::Mul>
2906 operator*(const VectorBase<E1>& v, const SymMat<M,E2,S>& s) {
2907     Vector_<typename CNT<E1>::template Result< SymMat<M,E2,S> >::Mul> res(v.nrow());
2908     for (int i=0; i < v.nrow(); ++i)
2909         res[i] = v[i]*s;
2910     return res;
2911 }
2912 
2913 // SymMat * Vector
2914 template <class E1, int M, class E2, int S>
2915 Vector_<typename SymMat<M,E2,S>::template Result<E1>::Mul>
2916 operator*(const SymMat<M,E2,S>& s, const VectorBase<E1>& v) {
2917     Vector_<typename SymMat<M,E2,S>::template Result<E1>::Mul> res(v.nrow());
2918     for (int i=0; i < v.nrow(); ++i)
2919         res[i] = s*v[i];
2920     return res;
2921 }
2922 
2923 /// @}
2924 
2925 /// @name Global operators involving RowVector objects
2926 /// These operators take RowVectorBase arguments and produce RowVector_ results.
2927 /// @{
2928 
2929 template <class E1, class E2>
2930 RowVector_<typename CNT<E1>::template Result<E2>::Add>
2931 operator+(const RowVectorBase<E1>& l, const RowVectorBase<E2>& r) {
2932     return RowVector_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
2933 }
2934 template <class E>
2935 RowVector_<E> operator+(const RowVectorBase<E>& l, const typename CNT<E>::T& r) {
2936     return RowVector_<E>(l) += r;
2937 }
2938 template <class E>
2939 RowVector_<E> operator+(const typename CNT<E>::T& l, const RowVectorBase<E>& r) {
2940     return RowVector_<E>(r) += l;
2941 }
2942 template <class E1, class E2>
2943 RowVector_<typename CNT<E1>::template Result<E2>::Sub>
2944 operator-(const RowVectorBase<E1>& l, const RowVectorBase<E2>& r) {
2945     return RowVector_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
2946 }
2947 template <class E>
2948 RowVector_<E> operator-(const RowVectorBase<E>& l, const typename CNT<E>::T& r) {
2949     return RowVector_<E>(l) -= r;
2950 }
2951 template <class E>
2952 RowVector_<E> operator-(const typename CNT<E>::T& l, const RowVectorBase<E>& r) {
2953     RowVector_<E> temp(r.size());
2954     temp = l;
2955     return (temp -= r);
2956 }
2957 
2958 // Scalar multiply and divide
2959 
2960 template <class E> RowVector_<E>
2961 operator*(const RowVectorBase<E>& l, const typename CNT<E>::StdNumber& r)
2962   { return RowVector_<E>(l)*=r; }
2963 
2964 template <class E> RowVector_<E>
2965 operator*(const typename CNT<E>::StdNumber& l, const RowVectorBase<E>& r)
2966   { return RowVector_<E>(r)*=l; }
2967 
2968 template <class E> RowVector_<E>
2969 operator/(const RowVectorBase<E>& l, const typename CNT<E>::StdNumber& r)
2970   { return RowVector_<E>(l)/=r; }
2971 
2972 // Handle ints explicitly.
2973 template <class E> RowVector_<E>
2974 operator*(const RowVectorBase<E>& l, int r)
2975   { return RowVector_<E>(l)*= typename CNT<E>::StdNumber(r); }
2976 
2977 template <class E> RowVector_<E>
2978 operator*(int l, const RowVectorBase<E>& r)
2979   { return RowVector_<E>(r)*= typename CNT<E>::StdNumber(l); }
2980 
2981 template <class E> RowVector_<E>
2982 operator/(const RowVectorBase<E>& l, int r)
2983   { return RowVector_<E>(l)/= typename CNT<E>::StdNumber(r); }
2984 
2985 
2986 // These are fancier "scalars"; whether they are allowed depends on
2987 // whether the element type and the CNT are compatible.
2988 
2989 // RowVector * Vec
2990 template <class E1, int M, class E2, int S>
2991 RowVector_<typename CNT<E1>::template Result< Vec<M,E2,S> >::Mul>
2992 operator*(const RowVectorBase<E1>& v, const Vec<M,E2,S>& s) {
2993     RowVector_<typename CNT<E1>::template Result< Vec<M,E2,S> >::Mul> res(v.ncol());
2994     for (int i=0; i < v.ncol(); ++i)
2995         res[i] = v[i]*s;
2996     return res;
2997 }
2998 
2999 // Vec * RowVector
3000 template <class E1, int M, class E2, int S>
3001 RowVector_<typename Vec<M,E2,S>::template Result<E1>::Mul>
3002 operator*(const Vec<M,E2,S>& s, const RowVectorBase<E1>& v) {
3003     RowVector_<typename Vec<M,E2,S>::template Result<E1>::Mul> res(v.ncol());
3004     for (int i=0; i < v.ncol(); ++i)
3005         res[i] = s*v[i];
3006     return res;
3007 }
3008 
3009 // RowVector * Row
3010 template <class E1, int N, class E2, int S>
3011 RowVector_<typename CNT<E1>::template Result< Row<N,E2,S> >::Mul>
3012 operator*(const RowVectorBase<E1>& v, const Row<N,E2,S>& s) {
3013     RowVector_<typename CNT<E1>::template Result< Row<N,E2,S> >::Mul> res(v.ncol());
3014     for (int i=0; i < v.ncol(); ++i)
3015         res[i] = v[i]*s;
3016     return res;
3017 }
3018 
3019 // Row * RowVector
3020 template <class E1, int N, class E2, int S>
3021 RowVector_<typename Row<N,E2,S>::template Result<E1>::Mul>
3022 operator*(const Row<N,E2,S>& s, const RowVectorBase<E1>& v) {
3023     RowVector_<typename Row<N,E2,S>::template Result<E1>::Mul> res(v.ncol());
3024     for (int i=0; i < v.ncol(); ++i)
3025         res[i] = s*v[i];
3026     return res;
3027 }
3028 
3029 // RowVector * Mat
3030 template <class E1, int M, int N, class E2, int S1, int S2>
3031 RowVector_<typename CNT<E1>::template Result< Mat<M,N,E2,S1,S2> >::Mul>
3032 operator*(const RowVectorBase<E1>& v, const Mat<M,N,E2,S1,S2>& s) {
3033     RowVector_<typename CNT<E1>::template Result< Mat<M,N,E2,S1,S2> >::Mul> res(v.ncol());
3034     for (int i=0; i < v.ncol(); ++i)
3035         res[i] = v[i]*s;
3036     return res;
3037 }
3038 
3039 // Mat * RowVector
3040 template <class E1, int M, int N, class E2, int S1, int S2>
3041 RowVector_<typename Mat<M,N,E2,S1,S2>::template Result<E1>::Mul>
3042 operator*(const Mat<M,N,E2,S1,S2>& s, const RowVectorBase<E1>& v) {
3043     RowVector_<typename Mat<M,N,E2,S1,S2>::template Result<E1>::Mul> res(v.ncol());
3044     for (int i=0; i < v.ncol(); ++i)
3045         res[i] = s*v[i];
3046     return res;
3047 }
3048 
3049 // RowVector * SymMat
3050 template <class E1, int M, class E2, int S>
3051 RowVector_<typename CNT<E1>::template Result< SymMat<M,E2,S> >::Mul>
3052 operator*(const RowVectorBase<E1>& v, const SymMat<M,E2,S>& s) {
3053     RowVector_<typename CNT<E1>::template Result< SymMat<M,E2,S> >::Mul> res(v.ncol());
3054     for (int i=0; i < v.ncol(); ++i)
3055         res[i] = v[i]*s;
3056     return res;
3057 }
3058 
3059 // SymMat * RowVector
3060 template <class E1, int M, class E2, int S>
3061 RowVector_<typename SymMat<M,E2,S>::template Result<E1>::Mul>
3062 operator*(const SymMat<M,E2,S>& s, const RowVectorBase<E1>& v) {
3063     RowVector_<typename SymMat<M,E2,S>::template Result<E1>::Mul> res(v.ncol());
3064     for (int i=0; i < v.ncol(); ++i)
3065         res[i] = s*v[i];
3066     return res;
3067 }
3068 
3069 /// @}
3070 
3071 
3072 /// @name Global operators involving mixed matrix, vector, and row vector objects
3073 /// These operators take MatrixBase, VectorBase, and RowVectorBase arguments
3074 /// and produce Matrix_, Vector_, and RowVector_ results.
3075 /// @{
3076 
3077     // TODO: these should use LAPACK!
3078 
3079 // Dot product
3080 template <class E1, class E2>
3081 typename CNT<E1>::template Result<E2>::Mul
3082 operator*(const RowVectorBase<E1>& r, const VectorBase<E2>& v) {
3083     assert(r.ncol() == v.nrow());
3084     typename CNT<E1>::template Result<E2>::Mul sum(0);
3085     for (int j=0; j < r.ncol(); ++j)
3086         sum += r(j) * v[j];
3087     return sum;
3088 }
3089 
3090 template <class E1, class E2>
3091 
3092 Vector_<typename CNT<E1>::template Result<E2>::Mul>
3093 operator*(const MatrixBase<E1>& m, const VectorBase<E2>& v) {
3094     assert(m.ncol() == v.nrow());
3095     Vector_<typename CNT<E1>::template Result<E2>::Mul> res(m.nrow());
3096     for (int i=0; i< m.nrow(); ++i)
3097         res[i] = m[i]*v;
3098     return res;
3099 }
3100 
3101 template <class E1, class E2>
3102 Matrix_<typename CNT<E1>::template Result<E2>::Mul>
3103 operator*(const MatrixBase<E1>& m1, const MatrixBase<E2>& m2) {
3104     assert(m1.ncol() == m2.nrow());
3105     Matrix_<typename CNT<E1>::template Result<E2>::Mul>
3106         res(m1.nrow(),m2.ncol());
3107 
3108     for (int j=0; j < res.ncol(); ++j)
3109         for (int i=0; i < res.nrow(); ++i)
3110             res(i,j) = m1[i] * m2(j);
3111 
3112     return res;
3113 }
3114 
3115 /// @}
3116 
3117 // This "private" static method is used to implement VectorView's
3118 // fillVectorViewFromStream() and Vector's readVectorFromStream()
3119 // namespace-scope static methods, which are in turn used to implement
3120 // VectorView's and
3121 // Vector's stream extraction operators ">>". This method has to be in the
3122 // header file so that we don't need to pass streams through the API, but it
3123 // is not intended for use by users and has no Doxygen presence, unlike
3124 // fillArrayFromStream() and readArrayFromStream() and (more commonly)
3125 // the extraction operators.
3126 template <class T> static inline
readVectorFromStreamHelper(std::istream & in,bool isFixedSize,Vector_<T> & out)3127 std::istream& readVectorFromStreamHelper
3128    (std::istream& in, bool isFixedSize, Vector_<T>& out)
3129 {
3130     // If already failed, bad, or eof, set failed bit and return without
3131     // touching the Vector.
3132     if (!in.good()) {in.setstate(std::ios::failbit); return in;}
3133 
3134     // If the passed-in Vector isn't resizeable, then we have to treat it as
3135     // a fixed size VectorView regardless of the setting of the isFixedSize
3136     // argument.
3137     if (!out.isResizeable())
3138         isFixedSize = true; // might be overriding the argument here
3139 
3140     // numRequired will be ignored unless isFixedSize==true.
3141     const int numRequired = isFixedSize ? out.size() : 0;
3142 
3143     if (!isFixedSize)
3144         out.clear(); // We're going to replace the entire contents of the Array.
3145 
3146     // Skip initial whitespace. If that results in eof this may be a successful
3147     // read of a 0-length, unbracketed Vector. That is OK for either a
3148     // variable-length Vector or a fixed-length VectorView of length zero.
3149     std::ws(in); if (in.fail()) return in;
3150     if (in.eof()) {
3151         if (isFixedSize && numRequired != 0)
3152             in.setstate(std::ios_base::failbit); // zero elements not OK
3153         return in;
3154     }
3155 
3156     // Here the stream is good and the next character is non-white.
3157     assert(in.good());
3158 
3159     // Use this for raw i/o (peeks and gets).
3160     typename       std::iostream::int_type ch;
3161     const typename std::iostream::int_type EOFch =
3162         std::iostream::traits_type::eof();
3163 
3164     // First we'll look for the optional "~". If found, the brackets become
3165     // required.
3166     bool tildeFound = false;
3167     ch = in.peek(); if (in.fail()) return in;
3168     assert(ch != EOFch); // we already checked above
3169     if ((char)ch == '~') {
3170         tildeFound = true;
3171         in.get(); // absorb the tilde
3172         // Eat whitespace after the tilde to see what's next.
3173         if (in.good()) std::ws(in);
3174         // If we hit eof after the tilde we don't like the formatting.
3175         if (!in.good()) {in.setstate(std::ios_base::failbit); return in;}
3176     }
3177 
3178     // Here the stream is good, the next character is non-white, and we
3179     // might have seen a tilde.
3180     assert(in.good());
3181 
3182     // Now see if the sequence is bare or surrounded by (), or [].
3183     bool lookForCloser = true;
3184     char openBracket, closeBracket;
3185     ch = in.peek(); if (in.fail()) return in;
3186     assert(ch != EOFch); // we already checked above
3187 
3188     openBracket = (char)ch;
3189     if      (openBracket=='(') {in.get(); closeBracket = ')';}
3190     else if (openBracket=='[') {in.get(); closeBracket = ']';}
3191     else lookForCloser = false;
3192 
3193     // If we found a tilde, the opening bracket was mandatory. If we didn't
3194     // find one then we reject the formatting.
3195     if (tildeFound && !lookForCloser)
3196     {   in.setstate(std::ios_base::failbit); return in;}
3197 
3198     // If lookForCloser is true, then closeBracket contains the terminating
3199     // delimiter, otherwise we're not going to quit until eof.
3200 
3201     // Eat whitespace after the opening bracket to see what's next.
3202     if (in.good()) std::ws(in);
3203 
3204     // If we're at eof now it must be because the open bracket was the
3205     // last non-white character in the stream, which is an error.
3206     if (!in.good()) {
3207         if (in.eof()) {
3208             assert(lookForCloser); // or we haven't read anything that could eof
3209             in.setstate(std::ios::failbit);
3210         }
3211         return in;
3212     }
3213 
3214     // istream is good and next character is non-white; ready to read first
3215     // value or terminator.
3216 
3217     // We need to figure out whether the elements are space- or comma-
3218     // separated and then insist on consistency.
3219     bool commaOK = true, commaRequired = false;
3220     bool terminatorSeen = false;
3221     int nextIndex = 0;
3222     while (true) {
3223         char c;
3224 
3225         // Here at the top of this loop, we have already successfully read
3226         // n=nextIndex values of type T. For fixed-size reads, it might be
3227         // the case that n==numRequired already, but we still may need to
3228         // look for a closing bracket before we can declare victory.
3229         // The stream is good() (not at eof) but it might be the case that
3230         // there is nothing but white space left; we don't know yet because
3231         // if we have satisfied the fixed-size count and are not expecting
3232         // a terminator then we should quit without absorbing the trailing
3233         // white space.
3234         assert(in.good());
3235 
3236         // Look for closing bracket before trying to read value.
3237         if (lookForCloser) {
3238             // Eat white space to find the closing bracket.
3239             std::ws(in); if (!in.good()) break; // eof?
3240             ch = in.peek(); assert(ch != EOFch);
3241             if (!in.good()) break;
3242             c = (char)ch;
3243             if (c == closeBracket) {
3244                 in.get(); // absorb the closing bracket
3245                 terminatorSeen = true;
3246                 break;
3247             }
3248             // next char not a closing bracket; fall through
3249         }
3250 
3251         // We didn't look or didn't find a closing bracket. The istream is good
3252         // but we might be looking at white space.
3253 
3254         // If we already got all the elements we want, break for final checks.
3255         if (isFixedSize && (nextIndex == numRequired))
3256             break; // that's a full count.
3257 
3258         // Look for comma before value, except the first time.
3259         if (commaOK && nextIndex != 0) {
3260             // Eat white space to find the comma.
3261             std::ws(in); if (!in.good()) break; // eof?
3262             ch = in.peek(); assert(ch != EOFch);
3263             if (!in.good()) break;
3264             c = (char)ch;
3265             if (c == ',') {
3266                 in.get(); // absorb comma
3267                 commaRequired = true; // all commas from now on
3268             } else { // next char not a comma
3269                 if (commaRequired) // bad, e.g.: v1, v2, v3 v4
3270                 {   in.setstate(std::ios::failbit); break; }
3271                 else commaOK = false; // saw: v1 v2 (no commas now)
3272             }
3273             if (!in.good()) break; // might be eof
3274         }
3275 
3276         // No closing bracket yet; don't have enough elements; skipped comma
3277         // if any; istream is good; might be looking at white space.
3278         assert(in.good());
3279 
3280         // Now read in an element of type T.
3281         // The extractor T::operator>>() will ignore leading white space.
3282         if (!isFixedSize)
3283             out.resizeKeep(out.size()+1); // grow by one (default consructed)
3284         in >> out[nextIndex]; if (in.fail()) break;
3285         ++nextIndex;
3286 
3287         if (!in.good()) break; // might be eof
3288     }
3289 
3290     // We will get here under a number of circumstances:
3291     //  - the fail bit is set in the istream, or
3292     //  - we reached eof
3293     //  - we saw a closing brace
3294     //  - we got all the elements we wanted (for a fixed-size read)
3295     // Note that it is possible that we consumed everything except some
3296     // trailing white space (meaning we're not technically at eof), but
3297     // for consistency with built-in operator>>()'s we won't try to absorb
3298     // that trailing white space.
3299 
3300     if (!in.fail()) {
3301         if (lookForCloser && !terminatorSeen)
3302             in.setstate(std::ios::failbit); // missing terminator
3303 
3304         if (isFixedSize && nextIndex != numRequired)
3305             in.setstate(std::ios::failbit); // wrong number of values
3306     }
3307 
3308     return in;
3309 }
3310 
3311 
3312 
3313 //------------------------------------------------------------------------------
3314 //                          RELATED GLOBAL OPERATORS
3315 //------------------------------------------------------------------------------
3316 // These are logically part of the Matrix_<T> class but are not actually
3317 // class members; that is, they are in the SimTK namespace.
3318 
3319 /**@name             Matrix_<T> serialization and I/O
3320 These methods are at namespace scope but are logically part of the Vector
3321 classes. These deal with reading and writing Vectors from and to streams,
3322 which places an additional requirement on the element type T: the element
3323 must support the same operation you are trying to do on the Vector as a
3324 whole. **/
3325 /*@{*/
3326 
3327 /** Specialize for VectorBase<E> to delegate to element type E, with spaces
3328 separating the elements.
3329 @relates SimTK::VectorBase **/
3330 template <class E> inline void
writeUnformatted(std::ostream & o,const VectorBase<E> & v)3331 writeUnformatted(std::ostream& o, const VectorBase<E>& v) {
3332     const int sz = v.size();
3333     for (int i=0; i < sz; ++i) {
3334         if (i != 0) o << " ";
3335         writeUnformatted(o, v[i]);
3336     }
3337 }
3338 /** Raw serialization of VectorView_<E>; same as VectorBase<E>.
3339 @relates SimTK::VectorView_ **/
3340 template <class E> inline void
writeUnformatted(std::ostream & o,const VectorView_<E> & v)3341 writeUnformatted(std::ostream& o, const VectorView_<E>& v)
3342 {   writeUnformatted(o, static_cast< const VectorBase<E> >(v)); }
3343 
3344 /** Raw serialization of Vector_<E>; same as VectorBase<E>.
3345 @relates SimTK::Vector_ **/
3346 template <class E> inline void
writeUnformatted(std::ostream & o,const Vector_<E> & v)3347 writeUnformatted(std::ostream& o, const Vector_<E>& v)
3348 {   writeUnformatted(o, static_cast< const VectorBase<E> >(v)); }
3349 
3350 /** Specialize for RowVectorBase<E> to delegate to element type E, with spaces
3351 separating the elements; raw output is same as VectorBase.
3352 @relates SimTK::RowVectorBase **/
3353 template <class E> inline void
writeUnformatted(std::ostream & o,const RowVectorBase<E> & v)3354 writeUnformatted(std::ostream& o, const RowVectorBase<E>& v)
3355 {   writeUnformatted(o, ~v); }
3356 
3357 /** Raw serialization of RowVectorView_<E>; same as VectorView_<E>.
3358 @relates SimTK::RowVectorView_ **/
3359 template <class E> inline void
writeUnformatted(std::ostream & o,const RowVectorView_<E> & v)3360 writeUnformatted(std::ostream& o, const RowVectorView_<E>& v)
3361 {   writeUnformatted(o, static_cast< const RowVectorBase<E> >(v)); }
3362 
3363 /** Raw serialization of RowVector_<E>; same as Vector_<E>.
3364 @relates SimTK::RowVector_ **/
3365 template <class E> inline void
writeUnformatted(std::ostream & o,const RowVector_<E> & v)3366 writeUnformatted(std::ostream& o, const RowVector_<E>& v)
3367 {   writeUnformatted(o, static_cast< const RowVectorBase<E> >(v)); }
3368 
3369 /** Specialize for MatrixBase<E> delegating to RowVectorBase<E> with newlines
3370 separating the rows, but no final newline.
3371 @relates SimTK::MatrixBase **/
3372 template <class E> inline void
writeUnformatted(std::ostream & o,const MatrixBase<E> & v)3373 writeUnformatted(std::ostream& o, const MatrixBase<E>& v) {
3374     const int nr = v.nrow();
3375     for (int i=0; i < nr; ++i) {
3376         if (i != 0) o << std::endl;
3377         writeUnformatted(o, v[i]);
3378     }
3379 }
3380 /** Raw serialization of MatrixView_<E>; same as MatrixBase<E>.
3381 @relates SimTK::MatrixView_ **/
3382 template <class E> inline void
writeUnformatted(std::ostream & o,const MatrixView_<E> & v)3383 writeUnformatted(std::ostream& o, const MatrixView_<E>& v)
3384 {   writeUnformatted(o, static_cast< const MatrixBase<E> >(v)); }
3385 
3386 /** Raw serialization of Vector_<E>; same as VectorBase<E>.
3387 @relates SimTK::Matrix_ **/
3388 template <class E> inline void
writeUnformatted(std::ostream & o,const Matrix_<E> & v)3389 writeUnformatted(std::ostream& o, const Matrix_<E>& v)
3390 {   writeUnformatted(o, static_cast< const MatrixBase<E> >(v)); }
3391 
3392 /** Read fixed-size VectorView from input stream. It is an error if there
3393 aren't enough elements. **/
3394 template <class E> inline bool
readUnformatted(std::istream & in,VectorView_<E> & v)3395 readUnformatted(std::istream& in, VectorView_<E>& v) {
3396     for (int i=0; i < v.size(); ++i)
3397         if (!readUnformatted(in, v[i])) return false;
3398     return true;
3399 }
3400 
3401 /** Read variable-size Vector from input stream. Reads until error or eof. **/
3402 template <class E> inline bool
readUnformatted(std::istream & in,Vector_<E> & v)3403 readUnformatted(std::istream& in, Vector_<E>& v) {
3404     if (!v.isResizeable())
3405         return readUnformatted(in, v.updAsVectorView());
3406 
3407     Array_<E,int> a;
3408     if (!readUnformatted(in,a)) return false;
3409     v.resize(a.size());
3410     for (int i=0; i<a.size(); ++i)
3411         v[i] = a[i];
3412     return true;
3413 }
3414 
3415 /** Read fixed-size RowVectorView from input stream. It is an error if there
3416 aren't enough elements. **/
3417 template <class E> inline bool
readUnformatted(std::istream & in,RowVectorView_<E> & v)3418 readUnformatted(std::istream& in, RowVectorView_<E>& v)
3419 {   VectorView_<E> vt(~v);
3420     return readUnformatted<E>(in, vt); }
3421 
3422 /** Read variable-size RowVector from unformatted (whitespace-separated)
3423 input stream. Reads until error or eof. **/
3424 template <class E> inline bool
readUnformatted(std::istream & in,RowVector_<E> & v)3425 readUnformatted(std::istream& in, RowVector_<E>& v)
3426 {   Vector_<E> vt(~v);
3427     return readUnformatted<E>(in, vt); }
3428 
3429 /** Read fixed-size MatrixView in row order from unformatted (whitespace-
3430 separated) input stream. Newlines in the input have no special meaning --
3431 we'll read them as whitespace. It is an error if there aren't enough
3432 elements. **/
3433 template <class E> inline bool
readUnformatted(std::istream & in,MatrixView_<E> & v)3434 readUnformatted(std::istream& in, MatrixView_<E>& v) {
3435     for (int row=0; row < v.nrow(); ++row) {
3436         RowVectorView_<E> oneRow(v[row]);
3437         if (!readUnformatted<E>(in, oneRow)) return false;
3438     }
3439     return true;
3440 }
3441 
3442 /** Read in new values for a Matrix without changing its size, from a stream
3443 of whitespace-separated tokens with no other formatting recognized. Newlines in
3444 the input have no special meaning -- we'll read them as whitespace. It is an
3445 error if there aren't enough elements. **/
3446 template <class E> inline bool
fillUnformatted(std::istream & in,Matrix_<E> & v)3447 fillUnformatted(std::istream& in, Matrix_<E>& v) {
3448     return readUnformatted<E>(in, v.updAsMatrixView());
3449 }
3450 
3451 /** NOT IMPLEMENTED: read variable-size Matrix recognizing newlines as end
3452 of row; use fillUnformatted() instead. **/
3453 template <class E> inline bool
readUnformatted(std::istream & in,Matrix_<E> & v)3454 readUnformatted(std::istream& in, Matrix_<E>& v) {
3455     SimTK_ASSERT_ALWAYS(!"implemented",
3456         "SimTK::readUnformatted(istream, Matrix) is not implemented; try"
3457         " SimTK::fillUnformatted(istream, Matrix) instead.");
3458     return false;
3459 }
3460 
3461 /** Output a human readable representation of a Vector to an std::ostream
3462 (like std::cout). The format is ~[ \e elements ] where \e elements is a
3463 space-separated list of the Vector's contents output by invoking the "<<"
3464 operator on the elements. This function will not compile if the element type
3465 does not support the "<<" operator. No newline is issued before
3466 or after the output. @relates Vector_ **/
3467 template <class T> inline std::ostream&
3468 operator<<(std::ostream& o, const VectorBase<T>& v)
3469 {   o << "~[";
3470     if (v.size()) {
3471         o << v[0];
3472         for (int i=1; i < v.size(); ++i) o << " " << v[i];
3473     }
3474     return o << "]";
3475 }
3476 
3477 /** Output a human readable representation of a RowVector to an std::ostream
3478 (like std::cout). The format is [ \e elements ] where \e elements is a
3479 space-separated list of the RowVector's contents output by invoking the "<<"
3480 operator on the elements. This function will not compile if the element type
3481 does not support the "<<" operator. No newline is issued before
3482 or after the output. @relates RowVector_ **/
3483 template <class T> inline std::ostream&
3484 operator<<(std::ostream& o, const RowVectorBase<T>& v)
3485 {   o << "[";
3486     if (v.size()) {
3487         o << v[0];
3488         for (int i=1; i < v.size(); ++i) o << " " << v[i];
3489     }
3490     return o << "]";
3491 }
3492 
3493 /** Output a human readable representation of a Matrix to an std::ostream
3494 (like std::cout). The format is one row per line, with each row output as
3495 [ \e elements ] where \e elements is a
3496 space-separated list of the row's contents output by invoking the "<<"
3497 operator on the elements. This function will not compile if the element type
3498 does not support the "<<" operator. A newline is issued before each row and
3499 at the end. @relates Matrix_ **/
3500 template <class T> inline std::ostream&
3501 operator<<(std::ostream& o, const MatrixBase<T>& m) {
3502     for (int i=0;i<m.nrow();++i)
3503         o << std::endl << m[i];
3504     if (m.nrow()) o << std::endl;
3505     return o;
3506 }
3507 
3508 
3509 /** Read in a Vector_<T> from a stream, as a sequence of space-separated or
3510 comma-separated values optionally surrounded by parentheses (), or square
3511 brackets [], or the "transposed" ~() or ~[]. In the case that the transpose
3512 operator is present, the parentheses or brackets are required, otherwise they
3513 are optional. We will continue to read elements of
3514 type T from the stream until we find a reason to stop, using type T's stream
3515 extraction operator>>() to read in each element and resizing the Vector as
3516 necessary. If the data is bracketed, we'll read until we hit the closing
3517 bracket. If it is not bracketed, we'll read until we hit eof() or get an error
3518 such as the element extractor setting the stream's fail bit due to bad
3519 formatting. On successful return, the stream will be positioned right after
3520 the final read-in element or terminating bracket, and the stream's status will
3521 be good() or eof(). We will not consume trailing whitespace after bracketed
3522 elements; that means the stream might actually be empty even if we don't
3523 return eof(). If you want to know whether there is anything else in the
3524 stream, follow this call with the STL whitespace skipper std::ws() like this:
3525 @code
3526     if (readVectorFromStream(in,vec) && !in.eof())
3527         std::ws(in); // might take us to eof
3528     if (in.fail()) {...} // probably a formatting error
3529     else {
3530         // Here if the stream is good() then there is more to read; if the
3531         // stream got used up the status is guaranteed to be eof().
3532     }
3533 @endcode
3534 A compilation error will occur if you try to use this method on an Vector_<T>
3535 for a type T for which there is no stream extraction operator>>().
3536 @note If you want to fill a resizeable Vector_<T> with a fixed amount of data
3537 from the stream, resize() the Vector to the appropriate length and then use
3538 fillVectorFromStream() instead. @see fillVectorFromStream()
3539 @relates Vector_ **/
3540 template <class T> static inline
readVectorFromStream(std::istream & in,Vector_<T> & out)3541 std::istream& readVectorFromStream(std::istream& in, Vector_<T>& out)
3542 {   return readVectorFromStreamHelper<T>(in, false /*variable sizez*/, out); }
3543 
3544 
3545 
3546 /** Read in a fixed number of elements from a stream into a Vector. We expect
3547 to read in exactly size() elements of type T, using type T's stream extraction
3548 operator>>(). This will stop reading when we've read size() elements, or set
3549 the fail bit in the stream if we run out of elements or if any element's
3550 extract operator sets the fail bit. On successful return, all size() elements
3551 will have been set, the stream will be positioned right after the final
3552 read-in element or terminating bracket, and the stream's status will be good()
3553 or eof(). We will not consume trailing whitespace after reading all the
3554 elements; that means the stream might actually be empty even if we don't
3555 return eof(). If you want to know whether there is anything else in the
3556 stream, follow this call with std::ws() like this:
3557 @code
3558     if (fillVectorFromStream(in,vec))
3559         if (!in.eof()) std::ws(in); // might take us to eof
3560     if (in.fail()) {...} // deal with I/O or formatting error
3561     // Here if the stream is good() then there is more to read; if the
3562     // stream got used up the status is guaranteed to be eof().
3563 @endcode
3564 A compilation error will occur if you try to use this method on a Vector_<T>
3565 for a type T for which there is no stream extraction operator>>().
3566 @note If you want to read in a variable number of elements and have the
3567 Vector_<T> resized as needed, use readVectorFromStream() instead.
3568 @see readVectorFromStream()
3569 @relates Vector_ **/
3570 template <class T> static inline
fillVectorFromStream(std::istream & in,Vector_<T> & out)3571 std::istream& fillVectorFromStream(std::istream& in, Vector_<T>& out)
3572 {   return readVectorFromStreamHelper<T>(in, true /*fixed size*/, out); }
3573 
3574 /** Read in a fixed number of elements from a stream into an VectorView. See
3575 fillVectorFromStream() for more information; this works the same way.
3576 @see fillVectorFromStream()
3577 @relates VectorView_ **/
3578 template <class T> static inline
fillVectorViewFromStream(std::istream & in,VectorView_<T> & out)3579 std::istream& fillVectorViewFromStream(std::istream& in, VectorView_<T>& out)
3580 {   return readVectorFromStreamHelper<T>(in, true /*fixed size*/, out); }
3581 
3582 
3583 /** Read Vector_<T> from a stream as a sequence of space- or comma-separated
3584 values of type T, optionally delimited by parentheses, or brackets, and
3585 preceded by "~". The Vector_<T> may be an owner (variable size) or a view
3586 (fixed size n). In the case of an owner, we'll read all the elements in
3587 brackets or until eof if there are no brackets. In the case of a view, there
3588 must be exactly n elements in brackets, or if there are no brackets we'll
3589 consume exactly n elements and then stop. Each element is read in with its
3590 own operator ">>" so this won't work if no such operator is defined for
3591 type T. @relates Vector_ **/
3592 template <class T> inline
3593 std::istream& operator>>(std::istream& in, Vector_<T>& out)
3594 {   return readVectorFromStream<T>(in, out); }
3595 
3596 /** Read a (fixed size n) VectorView_<T> from a stream as a sequence of space-
3597 or comma-separated values of type T, optionally delimited by parentheses or
3598 square brackets, and preceded by "~". If there are no delimiters then we will
3599 read size() values and then stop. Otherwise, there must be exactly size()
3600 values within the brackets. Each element is read in with its own
3601 operator ">>" so  this won't work if no such operator is defined for type T.
3602 @relates VectorView_ **/
3603 template <class T> inline
3604 std::istream& operator>>(std::istream& in, VectorView_<T>& out)
3605 {   return fillVectorViewFromStream<T>(in, out); }
3606 
3607 /*@}                     End of Matrix serialization. **/
3608 
3609 // Friendly abbreviations for vectors and matrices with scalar elements.
3610 
3611 typedef Vector_<Real>           Vector;
3612 typedef Vector_<float>          fVector;
3613 typedef Vector_<double>         dVector;
3614 typedef Vector_<Complex>        ComplexVector;
3615 typedef Vector_<fComplex>       fComplexVector;
3616 typedef Vector_<dComplex>       dComplexVector;
3617 
3618 typedef VectorView_<Real>       VectorView;
3619 typedef VectorView_<float>      fVectorView;
3620 typedef VectorView_<double>     dVectorView;
3621 typedef VectorView_<Complex>    ComplexVectorView;
3622 typedef VectorView_<fComplex>   fComplexVectorView;
3623 typedef VectorView_<dComplex>   dComplexVectorView;
3624 
3625 typedef RowVector_<Real>        RowVector;
3626 typedef RowVector_<float>       fRowVector;
3627 typedef RowVector_<double>      dRowVector;
3628 typedef RowVector_<Complex>     ComplexRowVector;
3629 typedef RowVector_<fComplex>    fComplexRowVector;
3630 typedef RowVector_<dComplex>    dComplexRowVector;
3631 
3632 typedef RowVectorView_<Real>    RowVectorView;
3633 typedef RowVectorView_<float>   fRowVectorView;
3634 typedef RowVectorView_<double>  dRowVectorView;
3635 typedef RowVectorView_<Complex> ComplexRowVectorView;
3636 typedef RowVectorView_<fComplex> fComplexRowVectorView;
3637 typedef RowVectorView_<dComplex> dComplexRowVectorView;
3638 
3639 typedef Matrix_<Real>           Matrix;
3640 typedef Matrix_<float>          fMatrix;
3641 typedef Matrix_<double>         dMatrix;
3642 typedef Matrix_<Complex>        ComplexMatrix;
3643 typedef Matrix_<fComplex>       fComplexMatrix;
3644 typedef Matrix_<dComplex>       dComplexMatrix;
3645 
3646 typedef MatrixView_<Real>       MatrixView;
3647 typedef MatrixView_<float>      fMatrixView;
3648 typedef MatrixView_<double>     dMatrixView;
3649 typedef MatrixView_<Complex>    ComplexMatrixView;
3650 typedef MatrixView_<fComplex>   fComplexMatrixView;
3651 typedef MatrixView_<dComplex>   dComplexMatrixView;
3652 
3653 
3654 /**
3655  * This is an iterator for iterating over the elements of a Vector.
3656  */
3657 
3658 template <class ELT, class VECTOR_CLASS>
3659 class VectorIterator {
3660 public:
3661     typedef ELT value_type;
3662     typedef int difference_type;
3663     typedef ELT& reference;
3664     typedef ELT* pointer;
3665     typedef std::random_access_iterator_tag iterator_category;
VectorIterator(VECTOR_CLASS & vector,int index)3666     VectorIterator(VECTOR_CLASS& vector, int index) : vector(vector), index(index) {
3667     }
VectorIterator(const VectorIterator & iter)3668     VectorIterator(const VectorIterator& iter) : vector(iter.vector), index(iter.index) {
3669     }
3670     VectorIterator& operator=(const VectorIterator& iter) {
3671         vector = iter.vector;
3672         index = iter.index;
3673         return *this;
3674     }
3675     ELT& operator*() {
3676         assert (index >= 0 && index < vector.size());
3677         return vector[index];
3678     }
3679     ELT& operator[](int i) {
3680         assert (i >= 0 && i < vector.size());
3681         return vector[i];
3682     }
3683     VectorIterator operator++() {
3684         assert (index < vector.size());
3685         ++index;
3686         return *this;
3687     }
3688     VectorIterator operator++(int) {
3689         assert (index < vector.size());
3690         VectorIterator current = *this;
3691         ++index;
3692         return current;
3693     }
3694     VectorIterator operator--() {
3695         assert (index > 0);
3696         --index;
3697         return *this;
3698     }
3699     VectorIterator operator--(int) {
3700         assert (index > 0);
3701         VectorIterator current = *this;
3702         --index;
3703         return current;
3704     }
3705     bool operator<(VectorIterator iter) const {
3706         return (index < iter.index);
3707     }
3708     bool operator>(VectorIterator iter) const {
3709         return (index > iter.index);
3710     }
3711     bool operator<=(VectorIterator iter) const {
3712         return (index <= iter.index);
3713     }
3714     bool operator>=(VectorIterator iter) const {
3715         return (index >= iter.index);
3716     }
3717     int operator-(VectorIterator iter) const {
3718         return (index - iter.index);
3719     }
3720     VectorIterator operator-(int n) const {
3721         return VectorIterator(vector, index-n);
3722     }
3723     VectorIterator operator+(int n) const {
3724         return VectorIterator(vector, index+n);
3725     }
3726     bool operator==(VectorIterator iter) const {
3727         return (index == iter.index);
3728     }
3729     bool operator!=(VectorIterator iter) const {
3730         return (index != iter.index);
3731     }
3732 private:
3733     VECTOR_CLASS& vector;
3734     int index;
3735 };
3736 #else
3737 typedef Vector_<double> Vector;
3738 typedef Matrix_<double> Matrix;
3739 #endif
3740 } //namespace SimTK
3741 
3742 #endif //SimTK_SIMMATRIX_BIGMATRIX_H_
3743