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