Simbody  3.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Row.h
Go to the documentation of this file.
1 #ifndef SimTK_SIMMATRIX_SMALLMATRIX_ROW_H_
2 #define SimTK_SIMMATRIX_SMALLMATRIX_ROW_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-12 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: Peter Eastman *
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 
32 
33 
34 namespace SimTK {
35 
36 // The following functions are used internally by Row.
37 
38 namespace Impl {
39 
40 // For those wimpy compilers that don't unroll short, constant-limit loops,
41 // Peter Eastman added these recursive template implementations of
42 // elementwise add, subtract, and copy. Sherm added multiply and divide.
43 
44 template <class E1, int S1, class E2, int S2> void
45 conformingAdd(const Row<1,E1,S1>& r1, const Row<1,E2,S2>& r2,
46  Row<1,typename CNT<E1>::template Result<E2>::Add>& result) {
47  result[0] = r1[0] + r2[0];
48 }
49 template <int N, class E1, int S1, class E2, int S2> void
50 conformingAdd(const Row<N,E1,S1>& r1, const Row<N,E2,S2>& r2,
51  Row<N,typename CNT<E1>::template Result<E2>::Add>& result) {
52  conformingAdd(reinterpret_cast<const Row<N-1,E1,S1>&>(r1),
53  reinterpret_cast<const Row<N-1,E2,S2>&>(r2),
54  reinterpret_cast<Row<N-1,typename CNT<E1>::
55  template Result<E2>::Add>&>(result));
56  result[N-1] = r1[N-1] + r2[N-1];
57 }
58 
59 template <class E1, int S1, class E2, int S2> void
61  Row<1,typename CNT<E1>::template Result<E2>::Sub>& result) {
62  result[0] = r1[0] - r2[0];
63 }
64 template <int N, class E1, int S1, class E2, int S2> void
66  Row<N,typename CNT<E1>::template Result<E2>::Sub>& result) {
67  conformingSubtract(reinterpret_cast<const Row<N-1,E1,S1>&>(r1),
68  reinterpret_cast<const Row<N-1,E2,S2>&>(r2),
69  reinterpret_cast<Row<N-1,typename CNT<E1>::
70  template Result<E2>::Sub>&>(result));
71  result[N-1] = r1[N-1] - r2[N-1];
72 }
73 
74 template <class E1, int S1, class E2, int S2> void
76  Row<1,typename CNT<E1>::template Result<E2>::Mul>& result) {
77  result[0] = r1[0] * r2[0];
78 }
79 template <int N, class E1, int S1, class E2, int S2> void
81  Row<N,typename CNT<E1>::template Result<E2>::Mul>& result) {
82  elementwiseMultiply(reinterpret_cast<const Row<N-1,E1,S1>&>(r1),
83  reinterpret_cast<const Row<N-1,E2,S2>&>(r2),
84  reinterpret_cast<Row<N-1,typename CNT<E1>::
85  template Result<E2>::Mul>&>(result));
86  result[N-1] = r1[N-1] * r2[N-1];
87 }
88 
89 template <class E1, int S1, class E2, int S2> void
91  Row<1,typename CNT<E1>::template Result<E2>::Dvd>& result) {
92  result[0] = r1[0] / r2[0];
93 }
94 template <int N, class E1, int S1, class E2, int S2> void
96  Row<N,typename CNT<E1>::template Result<E2>::Dvd>& result) {
97  elementwiseDivide(reinterpret_cast<const Row<N-1,E1,S1>&>(r1),
98  reinterpret_cast<const Row<N-1,E2,S2>&>(r2),
99  reinterpret_cast<Row<N-1,typename CNT<E1>::
100  template Result<E2>::Dvd>&>(result));
101  result[N-1] = r1[N-1] / r2[N-1];
102 }
103 
104 template <class E1, int S1, class E2, int S2> void
105 copy(Row<1,E1,S1>& r1, const Row<1,E2,S2>& r2) {
106  r1[0] = r2[0];
107 }
108 template <int N, class E1, int S1, class E2, int S2> void
109 copy(Row<N,E1,S1>& r1, const Row<N,E2,S2>& r2) {
110  copy(reinterpret_cast<Row<N-1,E1,S1>&>(r1),
111  reinterpret_cast<const Row<N-1,E2,S2>&>(r2));
112  r1[N-1] = r2[N-1];
113 }
114 
115 }
116 
118 template <int N, class ELT, int STRIDE> class Row {
119  typedef ELT E;
120  typedef typename CNT<E>::TNeg ENeg;
121  typedef typename CNT<E>::TWithoutNegator EWithoutNegator;
122  typedef typename CNT<E>::TReal EReal;
123  typedef typename CNT<E>::TImag EImag;
124  typedef typename CNT<E>::TComplex EComplex;
125  typedef typename CNT<E>::THerm EHerm;
126  typedef typename CNT<E>::TPosTrans EPosTrans;
127  typedef typename CNT<E>::TSqHermT ESqHermT;
128  typedef typename CNT<E>::TSqTHerm ESqTHerm;
129 
130  typedef typename CNT<E>::TSqrt ESqrt;
131  typedef typename CNT<E>::TAbs EAbs;
132  typedef typename CNT<E>::TStandard EStandard;
133  typedef typename CNT<E>::TInvert EInvert;
134  typedef typename CNT<E>::TNormalize ENormalize;
135 
136  typedef typename CNT<E>::Scalar EScalar;
137  typedef typename CNT<E>::ULessScalar EULessScalar;
138  typedef typename CNT<E>::Number ENumber;
139  typedef typename CNT<E>::StdNumber EStdNumber;
140  typedef typename CNT<E>::Precision EPrecision;
141  typedef typename CNT<E>::ScalarNormSq EScalarNormSq;
142 
143 public:
144 
145  enum {
146  NRows = 1,
147  NCols = N,
149  NActualElements = N * STRIDE, // includes trailing gap
152  ColSpacing = STRIDE,
154  RealStrideFactor = 1, // composite types don't change size when
155  // cast from complex to real or imaginary
157  ? CNT<E>::ArgDepth + 1
159  IsScalar = 0,
161  IsNumber = 0,
165  };
166 
170 
178  typedef E TElement;
179  typedef Row TRow;
180  typedef E TCol;
181 
182  // These are the results of calculations, so are returned in new, packed
183  // memory. Be sure to refer to element types here which are also packed.
184  typedef Vec<N,ESqrt,1> TSqrt; // Note stride
185  typedef Row<N,EAbs,1> TAbs; // Note stride
187  typedef Vec<N,EInvert,1> TInvert; // packed
189 
190  typedef SymMat<N,ESqHermT> TSqHermT; // result of self outer product
191  typedef EScalarNormSq TSqTHerm; // result of self dot product
192 
193  // These recurse right down to the underlying scalar type no matter how
194  // deep the elements are.
195  typedef EScalar Scalar;
196  typedef EULessScalar ULessScalar;
197  typedef ENumber Number;
198  typedef EStdNumber StdNumber;
199  typedef EPrecision Precision;
200  typedef EScalarNormSq ScalarNormSq;
201 
202  static int size() { return N; }
203  static int nrow() { return 1; }
204  static int ncol() { return N; }
205 
206 
207  // Scalar norm square is sum( conjugate squares of all scalars )
208  ScalarNormSq scalarNormSqr() const {
209  ScalarNormSq sum(0);
210  for(int i=0;i<N;++i) sum += CNT<E>::scalarNormSqr(d[i*STRIDE]);
211  return sum;
212  }
213 
214  // sqrt() is elementwise square root; that is, the return value has the same
215  // dimension as this Vec but with each element replaced by whatever it thinks
216  // its square root is.
217  TSqrt sqrt() const {
218  TSqrt rsqrt;
219  for(int i=0;i<N;++i) rsqrt[i] = CNT<E>::sqrt(d[i*STRIDE]);
220  return rsqrt;
221  }
222 
223  // abs() is elementwise absolute value; that is, the return value has the same
224  // dimension as this Row but with each element replaced by whatever it thinks
225  // its absolute value is.
226  TAbs abs() const {
227  TAbs rabs;
228  for(int i=0;i<N;++i) rabs[i] = CNT<E>::abs(d[i*STRIDE]);
229  return rabs;
230  }
231 
232  TStandard standardize() const {
233  TStandard rstd;
234  for(int i=0;i<N;++i) rstd[i] = CNT<E>::standardize(d[i*STRIDE]);
235  return rstd;
236  }
237 
238  // Sum just adds up all the elements, getting rid of negators and
239  // conjugates in the process.
240  EStandard sum() const {
241  E sum(0);
242  for (int i=0;i<N;++i) sum += d[i*STRIDE];
243  return CNT<E>::standardize(sum);
244  }
245 
246  // This gives the resulting rowvector type when (v[i] op P) is applied to each element of v.
247  // It is a row of length N, stride 1, and element types which are the regular
248  // composite result of E op P. Typically P is a scalar type but it doesn't have to be.
249  template <class P> struct EltResult {
254  };
255 
256  // This is the composite result for v op P where P is some kind of appropriately shaped
257  // non-scalar type.
258  template <class P> struct Result {
259  typedef MulCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
262  typedef typename MulOp::Type Mul;
263 
264  typedef MulCNTsNonConforming<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
267  typedef typename MulOpNonConforming::Type MulNon;
268 
269 
270  typedef DvdCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
273  typedef typename DvdOp::Type Dvd;
274 
275  typedef AddCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
278  typedef typename AddOp::Type Add;
279 
280  typedef SubCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
283  typedef typename SubOp::Type Sub;
284  };
285 
286  // Shape-preserving element substitution (always packed)
287  template <class P> struct Substitute {
288  typedef Row<N,P> Type;
289  };
290 
291  // Default construction initializes to NaN when debugging but
292  // is left uninitialized otherwise.
293  Row(){
294  #ifndef NDEBUG
295  setToNaN();
296  #endif
297  }
298 
299  // It's important not to use the default copy constructor or copy
300  // assignment because the compiler doesn't understand that we may
301  // have noncontiguous storage and will try to copy the whole array.
302  Row(const Row& src) {
303  Impl::copy(*this, src);
304  }
305  Row& operator=(const Row& src) { // no harm if src and 'this' are the same
306  Impl::copy(*this, src);
307  return *this;
308  }
309 
310  // We want an implicit conversion from a Row of the same length
311  // and element type but with a different stride.
312  template <int SS> Row(const Row<N,E,SS>& src) {
313  Impl::copy(*this, src);
314  }
315 
316  // We want an implicit conversion from a Row of the same length
317  // and *negated* element type, possibly with a different stride.
318  template <int SS> Row(const Row<N,ENeg,SS>& src) {
319  Impl::copy(*this, src);
320  }
321 
322  // Construct a Row from a Row of the same length, with any
323  // stride. Works as long as the element types are compatible.
324  template <class EE, int SS> explicit Row(const Row<N,EE,SS>& vv) {
325  Impl::copy(*this, vv);
326  }
327 
328  // Construction using an element assigns to each element.
329  explicit Row(const E& e)
330  { for (int i=0;i<N;++i) d[i*STRIDE]=e; }
331 
332  // Construction using a negated element assigns to each element.
333  explicit Row(const ENeg& ne)
334  { for (int i=0;i<N;++i) d[i*STRIDE]=ne; }
335 
336  // Given an int, turn it into a suitable floating point number
337  // and then feed that to the above single-element constructor.
338  explicit Row(int i)
339  { new (this) Row(E(Precision(i))); }
340 
341  // A bevy of constructors for Rows up to length 6.
342  Row(const E& e0,const E& e1)
343  { assert(N==2);(*this)[0]=e0;(*this)[1]=e1; }
344  Row(const E& e0,const E& e1,const E& e2)
345  { assert(N==3);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; }
346  Row(const E& e0,const E& e1,const E& e2,const E& e3)
347  { assert(N==4);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;(*this)[3]=e3; }
348  Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4)
349  { assert(N==5);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
350  (*this)[3]=e3;(*this)[4]=e4; }
351  Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5)
352  { assert(N==6);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
353  (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5; }
354  Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5,const E& e6)
355  { assert(N==7);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
356  (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6; }
357  Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5,const E& e6,const E& e7)
358  { assert(N==8);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
359  (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7; }
360  Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5,const E& e6,const E& e7,const E& e8)
361  { assert(N==9);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
362  (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7;(*this)[8]=e8; }
363 
364  // Construction from a pointer to anything assumes we're pointing
365  // at an element list of the right length.
366  template <class EE> explicit Row(const EE* p)
367  { assert(p); for(int i=0;i<N;++i) d[i*STRIDE]=p[i]; }
368  template <class EE> Row& operator=(const EE* p)
369  { assert(p); for(int i=0;i<N;++i) d[i*STRIDE]=p[i]; return *this; }
370 
371  // Conforming assignment ops.
372  template <class EE, int SS> Row& operator=(const Row<N,EE,SS>& vv) {
373  Impl::copy(*this, vv);
374  return *this;
375  }
376  template <class EE, int SS> Row& operator+=(const Row<N,EE,SS>& r)
377  { for(int i=0;i<N;++i) d[i*STRIDE] += r[i]; return *this; }
378  template <class EE, int SS> Row& operator+=(const Row<N,negator<EE>,SS>& r)
379  { for(int i=0;i<N;++i) d[i*STRIDE] -= -(r[i]); return *this; }
380  template <class EE, int SS> Row& operator-=(const Row<N,EE,SS>& r)
381  { for(int i=0;i<N;++i) d[i*STRIDE] -= r[i]; return *this; }
382  template <class EE, int SS> Row& operator-=(const Row<N,negator<EE>,SS>& r)
383  { for(int i=0;i<N;++i) d[i*STRIDE] += -(r[i]); return *this; }
384 
385  // Conforming binary ops with 'this' on left, producing new packed result.
386  // Cases: r=r+r, r=r-r, s=r*v r=r*m
387 
389  template <class EE, int SS> Row<N,typename CNT<E>::template Result<EE>::Add>
390  conformingAdd(const Row<N,EE,SS>& r) const {
391  Row<N,typename CNT<E>::template Result<EE>::Add> result;
392  Impl::conformingAdd(*this, r, result);
393  return result;
394  }
395 
397  template <class EE, int SS> Row<N,typename CNT<E>::template Result<EE>::Sub>
399  Row<N,typename CNT<E>::template Result<EE>::Sub> result;
400  Impl::conformingSubtract(*this, r, result);
401  return result;
402  }
403 
405  template <class EE, int SS> typename CNT<E>::template Result<EE>::Mul
407  return (*this)*r;
408  }
409 
411  template <int MatNCol, class EE, int CS, int RS>
414  Row<MatNCol,typename CNT<E>::template Result<EE>::Mul> result;
415  for (int j=0;j<N;++j) result[j] = conformingMultiply(m(j));
416  return result;
417  }
418 
420  template <class EE, int SS> Row<N,typename CNT<E>::template Result<EE>::Mul>
422  Row<N,typename CNT<E>::template Result<EE>::Mul> result;
423  Impl::elementwiseMultiply(*this, r, result);
424  return result;
425  }
426 
428  template <class EE, int SS> Row<N,typename CNT<E>::template Result<EE>::Dvd>
429  elementwiseDivide(const Row<N,EE,SS>& r) const {
430  Row<N,typename CNT<E>::template Result<EE>::Dvd> result;
431  Impl::elementwiseDivide(*this, r, result);
432  return result;
433  }
434 
435  const E& operator[](int i) const { assert(0 <= i && i < N); return d[i*STRIDE]; }
436  E& operator[](int i) { assert(0 <= i && i < N); return d[i*STRIDE]; }
437  const E& operator()(int i) const { return (*this)[i]; }
438  E& operator()(int i) { return (*this)[i]; }
439 
440  ScalarNormSq normSqr() const { return scalarNormSqr(); }
441  typename CNT<ScalarNormSq>::TSqrt
443 
444  // If the elements of this Row are scalars, the result is what you get by
445  // dividing each element by the norm() calculated above. If the elements are
446  // *not* scalars, then the elements are *separately* normalized. That means
447  // you will get a different answer from Row<2,Row3>::normalize() than you
448  // would from a Row<6>::normalize() containing the same scalars.
449  //
450  // Normalize returns a row of the same dimension but in new, packed storage
451  // and with a return type that does not include negator<> even if the original
452  // Row<> does, because we can eliminate the negation here almost for free.
453  // But we can't standardize (change conjugate to complex) for free, so we'll retain
454  // conjugates if there are any.
455  TNormalize normalize() const {
456  if (CNT<E>::IsScalar) {
458  } else {
459  TNormalize elementwiseNormalized;
460  for (int j=0; j<N; ++j)
461  elementwiseNormalized[j] = CNT<E>::normalize((*this)[j]);
462  return elementwiseNormalized;
463  }
464  }
465 
466  TInvert invert() const {assert(false); return TInvert();} // TODO default inversion
467 
468  const Row& operator+() const { return *this; }
469  const TNeg& operator-() const { return negate(); }
470  TNeg& operator-() { return updNegate(); }
471  const THerm& operator~() const { return transpose(); }
472  THerm& operator~() { return updTranspose(); }
473 
474  const TNeg& negate() const { return *reinterpret_cast<const TNeg*>(this); }
475  TNeg& updNegate() { return *reinterpret_cast<TNeg*>(this); }
476 
477  const THerm& transpose() const { return *reinterpret_cast<const THerm*>(this); }
478  THerm& updTranspose() { return *reinterpret_cast<THerm*>(this); }
479 
480  const TPosTrans& positionalTranspose() const
481  { return *reinterpret_cast<const TPosTrans*>(this); }
483  { return *reinterpret_cast<TPosTrans*>(this); }
484 
485  const TReal& real() const { return *reinterpret_cast<const TReal*>(this); }
486  TReal& real() { return *reinterpret_cast< TReal*>(this); }
487 
488  // Had to contort these routines to get them through VC++ 7.net
489  const TImag& imag() const {
490  const int offs = ImagOffset;
491  const EImag* p = reinterpret_cast<const EImag*>(this);
492  return *reinterpret_cast<const TImag*>(p+offs);
493  }
494  TImag& imag() {
495  const int offs = ImagOffset;
496  EImag* p = reinterpret_cast<EImag*>(this);
497  return *reinterpret_cast<TImag*>(p+offs);
498  }
499 
500  const TWithoutNegator& castAwayNegatorIfAny() const {return *reinterpret_cast<const TWithoutNegator*>(this);}
501  TWithoutNegator& updCastAwayNegatorIfAny() {return *reinterpret_cast<TWithoutNegator*>(this);}
502 
503 
504  // These are elementwise binary operators, (this op ee) by default but
505  // (ee op this) if 'FromLeft' appears in the name. The result is a packed
506  // Row<N> but the element type may change. These are mostly used to
507  // implement global operators. We call these "scalar" operators but
508  // actually the "scalar" can be a composite type.
509 
510  //TODO: consider converting 'e' to Standard Numbers as precalculation and
511  // changing return type appropriately.
512  template <class EE> Row<N, typename CNT<E>::template Result<EE>::Mul>
513  scalarMultiply(const EE& e) const {
514  Row<N, typename CNT<E>::template Result<EE>::Mul> result;
515  for (int j=0; j<N; ++j) result[j] = (*this)[j] * e;
516  return result;
517  }
518  template <class EE> Row<N, typename CNT<EE>::template Result<E>::Mul>
519  scalarMultiplyFromLeft(const EE& e) const {
520  Row<N, typename CNT<EE>::template Result<E>::Mul> result;
521  for (int j=0; j<N; ++j) result[j] = e * (*this)[j];
522  return result;
523  }
524 
525  // TODO: should precalculate and store 1/e, while converting to Standard
526  // Numbers. Note that return type should change appropriately.
527  template <class EE> Row<N, typename CNT<E>::template Result<EE>::Dvd>
528  scalarDivide(const EE& e) const {
529  Row<N, typename CNT<E>::template Result<EE>::Dvd> result;
530  for (int j=0; j<N; ++j) result[j] = (*this)[j] / e;
531  return result;
532  }
533  template <class EE> Row<N, typename CNT<EE>::template Result<E>::Dvd>
534  scalarDivideFromLeft(const EE& e) const {
535  Row<N, typename CNT<EE>::template Result<E>::Dvd> result;
536  for (int j=0; j<N; ++j) result[j] = e / (*this)[j];
537  return result;
538  }
539 
540  template <class EE> Row<N, typename CNT<E>::template Result<EE>::Add>
541  scalarAdd(const EE& e) const {
542  Row<N, typename CNT<E>::template Result<EE>::Add> result;
543  for (int j=0; j<N; ++j) result[j] = (*this)[j] + e;
544  return result;
545  }
546  // Add is commutative, so no 'FromLeft'.
547 
548  template <class EE> Row<N, typename CNT<E>::template Result<EE>::Sub>
549  scalarSubtract(const EE& e) const {
550  Row<N, typename CNT<E>::template Result<EE>::Sub> result;
551  for (int j=0; j<N; ++j) result[j] = (*this)[j] - e;
552  return result;
553  }
554  template <class EE> Row<N, typename CNT<EE>::template Result<E>::Sub>
555  scalarSubtractFromLeft(const EE& e) const {
556  Row<N, typename CNT<EE>::template Result<E>::Sub> result;
557  for (int j=0; j<N; ++j) result[j] = e - (*this)[j];
558  return result;
559  }
560 
561  // Generic assignments for any element type not listed explicitly, including scalars.
562  // These are done repeatedly for each element and only work if the operation can
563  // be performed leaving the original element type.
564  template <class EE> Row& operator =(const EE& e) {return scalarEq(e);}
565  template <class EE> Row& operator+=(const EE& e) {return scalarPlusEq(e);}
566  template <class EE> Row& operator-=(const EE& e) {return scalarMinusEq(e);}
567  template <class EE> Row& operator*=(const EE& e) {return scalarTimesEq(e);}
568  template <class EE> Row& operator/=(const EE& e) {return scalarDivideEq(e);}
569 
570  // Generalized scalar assignment & computed assignment methods. These will work
571  // for any assignment-compatible element, not just scalars.
572  template <class EE> Row& scalarEq(const EE& ee)
573  { for(int i=0;i<N;++i) d[i*STRIDE] = ee; return *this; }
574  template <class EE> Row& scalarPlusEq(const EE& ee)
575  { for(int i=0;i<N;++i) d[i*STRIDE] += ee; return *this; }
576  template <class EE> Row& scalarMinusEq(const EE& ee)
577  { for(int i=0;i<N;++i) d[i*STRIDE] -= ee; return *this; }
578  template <class EE> Row& scalarMinusEqFromLeft(const EE& ee)
579  { for(int i=0;i<N;++i) d[i*STRIDE] = ee - d[i*STRIDE]; return *this; }
580  template <class EE> Row& scalarTimesEq(const EE& ee)
581  { for(int i=0;i<N;++i) d[i*STRIDE] *= ee; return *this; }
582  template <class EE> Row& scalarTimesEqFromLeft(const EE& ee)
583  { for(int i=0;i<N;++i) d[i*STRIDE] = ee * d[i*STRIDE]; return *this; }
584  template <class EE> Row& scalarDivideEq(const EE& ee)
585  { for(int i=0;i<N;++i) d[i*STRIDE] /= ee; return *this; }
586  template <class EE> Row& scalarDivideEqFromLeft(const EE& ee)
587  { for(int i=0;i<N;++i) d[i*STRIDE] = ee / d[i*STRIDE]; return *this; }
588 
589 
590  // Specialize for int to avoid warnings and ambiguities.
591  Row& scalarEq(int ee) {return scalarEq(Precision(ee));}
592  Row& scalarPlusEq(int ee) {return scalarPlusEq(Precision(ee));}
593  Row& scalarMinusEq(int ee) {return scalarMinusEq(Precision(ee));}
594  Row& scalarTimesEq(int ee) {return scalarTimesEq(Precision(ee));}
595  Row& scalarDivideEq(int ee) {return scalarDivideEq(Precision(ee));}
599 
602  void setToNaN() {
603  (*this) = CNT<ELT>::getNaN();
604  }
605 
607  void setToZero() {
608  (*this) = ELT(0);
609  }
610 
616  template <int NN>
617  const Row<NN,ELT,STRIDE>& getSubRow(int j) const {
618  assert(0 <= j && j + NN <= N);
619  return Row<NN,ELT,STRIDE>::getAs(&(*this)[j]);
620  }
626  template <int NN>
628  assert(0 <= j && j + NN <= N);
629  return Row<NN,ELT,STRIDE>::updAs(&(*this)[j]);
630  }
631 
635  template <int NN>
636  static const Row& getSubRow(const Row<NN,ELT,STRIDE>& r, int j) {
637  assert(0 <= j && j + N <= NN);
638  return getAs(&r[j]);
639  }
643  template <int NN>
644  static Row& updSubRow(Row<NN,ELT,STRIDE>& r, int j) {
645  assert(0 <= j && j + N <= NN);
646  return updAs(&r[j]);
647  }
648 
652  Row<N-1,ELT,1> drop1(int p) const {
653  assert(0 <= p && p < N);
654  Row<N-1,ELT,1> out;
655  int nxt=0;
656  for (int i=0; i<N-1; ++i, ++nxt) {
657  if (nxt==p) ++nxt; // skip the loser
658  out[i] = (*this)[nxt];
659  }
660  return out;
661  }
662 
666  template <class EE> Row<N+1,ELT,1> append1(const EE& v) const {
667  Row<N+1,ELT,1> out;
668  Row<N,ELT,1>::updAs(&out[0]) = (*this);
669  out[N] = v;
670  return out;
671  }
672 
673 
679  template <class EE> Row<N+1,ELT,1> insert1(int p, const EE& v) const {
680  assert(0 <= p && p <= N);
681  if (p==N) return append1(v);
682  Row<N+1,ELT,1> out;
683  int nxt=0;
684  for (int i=0; i<N; ++i, ++nxt) {
685  if (i==p) out[nxt++] = v;
686  out[nxt] = (*this)[i];
687  }
688  return out;
689  }
690 
693  static const Row& getAs(const ELT* p) {return *reinterpret_cast<const Row*>(p);}
696  static Row& updAs(ELT* p) {return *reinterpret_cast<Row*>(p);}
697 
702 
704  bool isNaN() const {
705  for (int j=0; j<N; ++j)
706  if (CNT<ELT>::isNaN((*this)[j]))
707  return true;
708  return false;
709  }
710 
713  bool isInf() const {
714  bool seenInf = false;
715  for (int j=0; j<N; ++j) {
716  const ELT& e = (*this)[j];
717  if (!CNT<ELT>::isFinite(e)) {
718  if (!CNT<ELT>::isInf(e))
719  return false; // something bad was found
720  seenInf = true;
721  }
722  }
723  return seenInf;
724  }
725 
728  bool isFinite() const {
729  for (int j=0; j<N; ++j)
730  if (!CNT<ELT>::isFinite((*this)[j]))
731  return false;
732  return true;
733  }
734 
738 
741  template <class E2, int CS2>
742  bool isNumericallyEqual(const Row<N,E2,CS2>& r, double tol) const {
743  for (int j=0; j<N; ++j)
744  if (!CNT<ELT>::isNumericallyEqual((*this)(j), r(j), tol))
745  return false;
746  return true;
747  }
748 
752  template <class E2, int CS2>
753  bool isNumericallyEqual(const Row<N,E2,CS2>& r) const {
754  const double tol = std::max(getDefaultTolerance(),r.getDefaultTolerance());
755  return isNumericallyEqual(r, tol);
756  }
757 
762  bool isNumericallyEqual
763  (const ELT& e,
764  double tol = getDefaultTolerance()) const
765  {
766  for (int j=0; j<N; ++j)
767  if (!CNT<ELT>::isNumericallyEqual((*this)(j), e, tol))
768  return false;
769  return true;
770  }
771 private:
772  ELT d[NActualElements]; // data
773 };
774 
776 // Global operators involving two rows. //
777 // v+v, v-v, v==v, v!=v //
779 
780 // v3 = v1 + v2 where all v's have the same length N.
781 template <int N, class E1, int S1, class E2, int S2> inline
782 typename Row<N,E1,S1>::template Result< Row<N,E2,S2> >::Add
783 operator+(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) {
784  return Row<N,E1,S1>::template Result< Row<N,E2,S2> >
785  ::AddOp::perform(l,r);
786 }
787 
788 // v3 = v1 - v2, similar to +
789 template <int N, class E1, int S1, class E2, int S2> inline
790 typename Row<N,E1,S1>::template Result< Row<N,E2,S2> >::Sub
791 operator-(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) {
792  return Row<N,E1,S1>::template Result< Row<N,E2,S2> >
793  ::SubOp::perform(l,r);
794 }
795 
797 template <int N, class E1, int S1, class E2, int S2> inline bool
798 operator==(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) {
799  for (int i=0; i < N; ++i) if (l[i] != r[i]) return false;
800  return true;
801 }
803 template <int N, class E1, int S1, class E2, int S2> inline bool
804 operator!=(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) {return !(l==r);}
805 
807 template <int N, class E1, int S1, class E2, int S2> inline bool
808 operator<(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r)
809 { for (int i=0; i < N; ++i) if (l[i] >= r[i]) return false;
810  return true; }
812 template <int N, class E1, int S1, class E2> inline bool
813 operator<(const Row<N,E1,S1>& v, const E2& e)
814 { for (int i=0; i < N; ++i) if (v[i] >= e) return false;
815  return true; }
816 
818 template <int N, class E1, int S1, class E2, int S2> inline bool
819 operator>(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r)
820 { for (int i=0; i < N; ++i) if (l[i] <= r[i]) return false;
821  return true; }
823 template <int N, class E1, int S1, class E2> inline bool
824 operator>(const Row<N,E1,S1>& v, const E2& e)
825 { for (int i=0; i < N; ++i) if (v[i] <= e) return false;
826  return true; }
827 
830 template <int N, class E1, int S1, class E2, int S2> inline bool
831 operator<=(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r)
832 { for (int i=0; i < N; ++i) if (l[i] > r[i]) return false;
833  return true; }
836 template <int N, class E1, int S1, class E2> inline bool
837 operator<=(const Row<N,E1,S1>& v, const E2& e)
838 { for (int i=0; i < N; ++i) if (v[i] > e) return false;
839  return true; }
840 
843 template <int N, class E1, int S1, class E2, int S2> inline bool
845 { for (int i=0; i < N; ++i) if (l[i] < r[i]) return false;
846  return true; }
849 template <int N, class E1, int S1, class E2> inline bool
850 operator>=(const Row<N,E1,S1>& v, const E2& e)
851 { for (int i=0; i < N; ++i) if (v[i] < e) return false;
852  return true; }
853 
855 // Global operators involving a row and a scalar. //
857 
858 // I haven't been able to figure out a nice way to templatize for the
859 // built-in reals without introducing a lot of unwanted type matches
860 // as well. So we'll just grind them out explicitly here.
861 
862 // SCALAR MULTIPLY
863 
864 // v = v*real, real*v
865 template <int N, class E, int S> inline
866 typename Row<N,E,S>::template Result<float>::Mul
867 operator*(const Row<N,E,S>& l, const float& r)
868  { return Row<N,E,S>::template Result<float>::MulOp::perform(l,r); }
869 template <int N, class E, int S> inline
870 typename Row<N,E,S>::template Result<float>::Mul
871 operator*(const float& l, const Row<N,E,S>& r) {return r*l;}
872 
873 template <int N, class E, int S> inline
874 typename Row<N,E,S>::template Result<double>::Mul
875 operator*(const Row<N,E,S>& l, const double& r)
876  { return Row<N,E,S>::template Result<double>::MulOp::perform(l,r); }
877 template <int N, class E, int S> inline
878 typename Row<N,E,S>::template Result<double>::Mul
879 operator*(const double& l, const Row<N,E,S>& r) {return r*l;}
880 
881 template <int N, class E, int S> inline
882 typename Row<N,E,S>::template Result<long double>::Mul
883 operator*(const Row<N,E,S>& l, const long double& r)
884  { return Row<N,E,S>::template Result<long double>::MulOp::perform(l,r); }
885 template <int N, class E, int S> inline
886 typename Row<N,E,S>::template Result<long double>::Mul
887 operator*(const long double& l, const Row<N,E,S>& r) {return r*l;}
888 
889 // v = v*int, int*v -- just convert int to v's precision float
890 template <int N, class E, int S> inline
891 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Mul
892 operator*(const Row<N,E,S>& l, int r) {return l * (typename CNT<E>::Precision)r;}
893 template <int N, class E, int S> inline
894 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Mul
895 operator*(int l, const Row<N,E,S>& r) {return r * (typename CNT<E>::Precision)l;}
896 
897 // Complex, conjugate, and negator are all easy to templatize.
898 
899 // v = v*complex, complex*v
900 template <int N, class E, int S, class R> inline
901 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
902 operator*(const Row<N,E,S>& l, const std::complex<R>& r)
903  { return Row<N,E,S>::template Result<std::complex<R> >::MulOp::perform(l,r); }
904 template <int N, class E, int S, class R> inline
905 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
906 operator*(const std::complex<R>& l, const Row<N,E,S>& r) {return r*l;}
907 
908 // v = v*conjugate, conjugate*v (convert conjugate->complex)
909 template <int N, class E, int S, class R> inline
910 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
911 operator*(const Row<N,E,S>& l, const conjugate<R>& r) {return l*(std::complex<R>)r;}
912 template <int N, class E, int S, class R> inline
913 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
914 operator*(const conjugate<R>& l, const Row<N,E,S>& r) {return r*(std::complex<R>)l;}
915 
916 // v = v*negator, negator*v: convert negator to standard number
917 template <int N, class E, int S, class R> inline
918 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Mul
919 operator*(const Row<N,E,S>& l, const negator<R>& r) {return l * (typename negator<R>::StdNumber)(R)r;}
920 template <int N, class E, int S, class R> inline
921 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Mul
922 operator*(const negator<R>& l, const Row<N,E,S>& r) {return r * (typename negator<R>::StdNumber)(R)l;}
923 
924 
925 // SCALAR DIVIDE. This is a scalar operation when the scalar is on the right,
926 // but when it is on the left it means scalar * pseudoInverse(row), which is
927 // a vec.
928 
929 // v = v/real, real/v
930 template <int N, class E, int S> inline
931 typename Row<N,E,S>::template Result<float>::Dvd
932 operator/(const Row<N,E,S>& l, const float& r)
933  { return Row<N,E,S>::template Result<float>::DvdOp::perform(l,r); }
934 template <int N, class E, int S> inline
935 typename CNT<float>::template Result<Row<N,E,S> >::Dvd
936 operator/(const float& l, const Row<N,E,S>& r)
937  { return CNT<float>::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
938 
939 template <int N, class E, int S> inline
940 typename Row<N,E,S>::template Result<double>::Dvd
941 operator/(const Row<N,E,S>& l, const double& r)
942  { return Row<N,E,S>::template Result<double>::DvdOp::perform(l,r); }
943 template <int N, class E, int S> inline
944 typename CNT<double>::template Result<Row<N,E,S> >::Dvd
945 operator/(const double& l, const Row<N,E,S>& r)
946  { return CNT<double>::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
947 
948 template <int N, class E, int S> inline
949 typename Row<N,E,S>::template Result<long double>::Dvd
950 operator/(const Row<N,E,S>& l, const long double& r)
951  { return Row<N,E,S>::template Result<long double>::DvdOp::perform(l,r); }
952 template <int N, class E, int S> inline
953 typename CNT<long double>::template Result<Row<N,E,S> >::Dvd
954 operator/(const long double& l, const Row<N,E,S>& r)
955  { return CNT<long double>::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
956 
957 // v = v/int, int/v -- just convert int to v's precision float
958 template <int N, class E, int S> inline
959 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Dvd
960 operator/(const Row<N,E,S>& l, int r) {return l / (typename CNT<E>::Precision)r;}
961 template <int N, class E, int S> inline
962 typename CNT<typename CNT<E>::Precision>::template Result<Row<N,E,S> >::Dvd
963 operator/(int l, const Row<N,E,S>& r) {return (typename CNT<E>::Precision)l / r;}
964 
965 
966 // Complex, conjugate, and negator are all easy to templatize.
967 
968 // v = v/complex, complex/v
969 template <int N, class E, int S, class R> inline
970 typename Row<N,E,S>::template Result<std::complex<R> >::Dvd
971 operator/(const Row<N,E,S>& l, const std::complex<R>& r)
972  { return Row<N,E,S>::template Result<std::complex<R> >::DvdOp::perform(l,r); }
973 template <int N, class E, int S, class R> inline
974 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Dvd
975 operator/(const std::complex<R>& l, const Row<N,E,S>& r)
976  { return CNT<std::complex<R> >::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
977 
978 // v = v/conjugate, conjugate/v (convert conjugate->complex)
979 template <int N, class E, int S, class R> inline
980 typename Row<N,E,S>::template Result<std::complex<R> >::Dvd
981 operator/(const Row<N,E,S>& l, const conjugate<R>& r) {return l/(std::complex<R>)r;}
982 template <int N, class E, int S, class R> inline
983 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Dvd
984 operator/(const conjugate<R>& l, const Row<N,E,S>& r) {return (std::complex<R>)l/r;}
985 
986 // v = v/negator, negator/v: convert negator to number
987 template <int N, class E, int S, class R> inline
988 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Dvd
989 operator/(const Row<N,E,S>& l, const negator<R>& r) {return l/(typename negator<R>::StdNumber)(R)r;}
990 template <int N, class E, int S, class R> inline
991 typename CNT<R>::template Result<Row<N,E,S> >::Dvd
992 operator/(const negator<R>& l, const Row<N,E,S>& r) {return (typename negator<R>::StdNumber)(R)l/r;}
993 
994 
995 // Add and subtract are odd as scalar ops. They behave as though the
996 // scalar stands for a vector each of whose elements is that scalar,
997 // and then a normal vector add or subtract is done.
998 
999 // SCALAR ADD
1000 
1001 // v = v+real, real+v
1002 template <int N, class E, int S> inline
1003 typename Row<N,E,S>::template Result<float>::Add
1004 operator+(const Row<N,E,S>& l, const float& r)
1005  { return Row<N,E,S>::template Result<float>::AddOp::perform(l,r); }
1006 template <int N, class E, int S> inline
1007 typename Row<N,E,S>::template Result<float>::Add
1008 operator+(const float& l, const Row<N,E,S>& r) {return r+l;}
1009 
1010 template <int N, class E, int S> inline
1011 typename Row<N,E,S>::template Result<double>::Add
1012 operator+(const Row<N,E,S>& l, const double& r)
1013  { return Row<N,E,S>::template Result<double>::AddOp::perform(l,r); }
1014 template <int N, class E, int S> inline
1015 typename Row<N,E,S>::template Result<double>::Add
1016 operator+(const double& l, const Row<N,E,S>& r) {return r+l;}
1017 
1018 template <int N, class E, int S> inline
1019 typename Row<N,E,S>::template Result<long double>::Add
1020 operator+(const Row<N,E,S>& l, const long double& r)
1021  { return Row<N,E,S>::template Result<long double>::AddOp::perform(l,r); }
1022 template <int N, class E, int S> inline
1023 typename Row<N,E,S>::template Result<long double>::Add
1024 operator+(const long double& l, const Row<N,E,S>& r) {return r+l;}
1025 
1026 // v = v+int, int+v -- just convert int to v's precision float
1027 template <int N, class E, int S> inline
1028 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Add
1029 operator+(const Row<N,E,S>& l, int r) {return l + (typename CNT<E>::Precision)r;}
1030 template <int N, class E, int S> inline
1031 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Add
1032 operator+(int l, const Row<N,E,S>& r) {return r + (typename CNT<E>::Precision)l;}
1033 
1034 // Complex, conjugate, and negator are all easy to templatize.
1035 
1036 // v = v+complex, complex+v
1037 template <int N, class E, int S, class R> inline
1038 typename Row<N,E,S>::template Result<std::complex<R> >::Add
1039 operator+(const Row<N,E,S>& l, const std::complex<R>& r)
1040  { return Row<N,E,S>::template Result<std::complex<R> >::AddOp::perform(l,r); }
1041 template <int N, class E, int S, class R> inline
1042 typename Row<N,E,S>::template Result<std::complex<R> >::Add
1043 operator+(const std::complex<R>& l, const Row<N,E,S>& r) {return r+l;}
1044 
1045 // v = v+conjugate, conjugate+v (convert conjugate->complex)
1046 template <int N, class E, int S, class R> inline
1047 typename Row<N,E,S>::template Result<std::complex<R> >::Add
1048 operator+(const Row<N,E,S>& l, const conjugate<R>& r) {return l+(std::complex<R>)r;}
1049 template <int N, class E, int S, class R> inline
1050 typename Row<N,E,S>::template Result<std::complex<R> >::Add
1051 operator+(const conjugate<R>& l, const Row<N,E,S>& r) {return r+(std::complex<R>)l;}
1052 
1053 // v = v+negator, negator+v: convert negator to standard number
1054 template <int N, class E, int S, class R> inline
1055 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Add
1056 operator+(const Row<N,E,S>& l, const negator<R>& r) {return l + (typename negator<R>::StdNumber)(R)r;}
1057 template <int N, class E, int S, class R> inline
1058 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Add
1059 operator+(const negator<R>& l, const Row<N,E,S>& r) {return r + (typename negator<R>::StdNumber)(R)l;}
1060 
1061 // SCALAR SUBTRACT -- careful, not commutative.
1062 
1063 // v = v-real, real-v
1064 template <int N, class E, int S> inline
1065 typename Row<N,E,S>::template Result<float>::Sub
1066 operator-(const Row<N,E,S>& l, const float& r)
1067  { return Row<N,E,S>::template Result<float>::SubOp::perform(l,r); }
1068 template <int N, class E, int S> inline
1069 typename CNT<float>::template Result<Row<N,E,S> >::Sub
1070 operator-(const float& l, const Row<N,E,S>& r)
1071  { return CNT<float>::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
1072 
1073 template <int N, class E, int S> inline
1074 typename Row<N,E,S>::template Result<double>::Sub
1075 operator-(const Row<N,E,S>& l, const double& r)
1076  { return Row<N,E,S>::template Result<double>::SubOp::perform(l,r); }
1077 template <int N, class E, int S> inline
1078 typename CNT<double>::template Result<Row<N,E,S> >::Sub
1079 operator-(const double& l, const Row<N,E,S>& r)
1080  { return CNT<double>::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
1081 
1082 template <int N, class E, int S> inline
1083 typename Row<N,E,S>::template Result<long double>::Sub
1084 operator-(const Row<N,E,S>& l, const long double& r)
1085  { return Row<N,E,S>::template Result<long double>::SubOp::perform(l,r); }
1086 template <int N, class E, int S> inline
1087 typename CNT<long double>::template Result<Row<N,E,S> >::Sub
1088 operator-(const long double& l, const Row<N,E,S>& r)
1089  { return CNT<long double>::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
1090 
1091 // v = v-int, int-v // just convert int to v's precision float
1092 template <int N, class E, int S> inline
1093 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Sub
1094 operator-(const Row<N,E,S>& l, int r) {return l - (typename CNT<E>::Precision)r;}
1095 template <int N, class E, int S> inline
1096 typename CNT<typename CNT<E>::Precision>::template Result<Row<N,E,S> >::Sub
1097 operator-(int l, const Row<N,E,S>& r) {return (typename CNT<E>::Precision)l - r;}
1098 
1099 
1100 // Complex, conjugate, and negator are all easy to templatize.
1101 
1102 // v = v-complex, complex-v
1103 template <int N, class E, int S, class R> inline
1104 typename Row<N,E,S>::template Result<std::complex<R> >::Sub
1105 operator-(const Row<N,E,S>& l, const std::complex<R>& r)
1106  { return Row<N,E,S>::template Result<std::complex<R> >::SubOp::perform(l,r); }
1107 template <int N, class E, int S, class R> inline
1108 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Sub
1109 operator-(const std::complex<R>& l, const Row<N,E,S>& r)
1110  { return CNT<std::complex<R> >::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
1111 
1112 // v = v-conjugate, conjugate-v (convert conjugate->complex)
1113 template <int N, class E, int S, class R> inline
1114 typename Row<N,E,S>::template Result<std::complex<R> >::Sub
1115 operator-(const Row<N,E,S>& l, const conjugate<R>& r) {return l-(std::complex<R>)r;}
1116 template <int N, class E, int S, class R> inline
1117 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Sub
1118 operator-(const conjugate<R>& l, const Row<N,E,S>& r) {return (std::complex<R>)l-r;}
1119 
1120 // v = v-negator, negator-v: convert negator to standard number
1121 template <int N, class E, int S, class R> inline
1122 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Sub
1123 operator-(const Row<N,E,S>& l, const negator<R>& r) {return l-(typename negator<R>::StdNumber)(R)r;}
1124 template <int N, class E, int S, class R> inline
1125 typename CNT<R>::template Result<Row<N,E,S> >::Sub
1126 operator-(const negator<R>& l, const Row<N,E,S>& r) {return (typename negator<R>::StdNumber)(R)l-r;}
1127 
1128 
1129 // Row I/O
1130 template <int N, class E, int S, class CHAR, class TRAITS> inline
1131 std::basic_ostream<CHAR,TRAITS>&
1132 operator<<(std::basic_ostream<CHAR,TRAITS>& o, const Row<N,E,S>& v) {
1133  o << "[" << v[0]; for(int i=1;i<N;++i) o<<','<<v[i]; o<<']'; return o;
1134 }
1135 
1138 template <int N, class E, int S, class CHAR, class TRAITS> inline
1139 std::basic_istream<CHAR,TRAITS>&
1140 operator>>(std::basic_istream<CHAR,TRAITS>& is, Row<N,E,S>& v) {
1141  CHAR openBracket, closeBracket;
1142  is >> openBracket; if (is.fail()) return is;
1143  if (openBracket==CHAR('('))
1144  closeBracket = CHAR(')');
1145  else if (openBracket==CHAR('['))
1146  closeBracket = CHAR(']');
1147  else {
1148  closeBracket = CHAR(0);
1149  is.unget(); if (is.fail()) return is;
1150  }
1151 
1152  for (int i=0; i < N; ++i) {
1153  is >> v[i];
1154  if (is.fail()) return is;
1155  if (i != N-1) {
1156  CHAR c; is >> c; if (is.fail()) return is;
1157  if (c != ',') is.unget();
1158  if (is.fail()) return is;
1159  }
1160  }
1161 
1162  // Get the closing bracket if there was an opening one. If we don't
1163  // see the expected character we'll set the fail bit in the istream.
1164  if (closeBracket != CHAR(0)) {
1165  CHAR closer; is >> closer; if (is.fail()) return is;
1166  if (closer != closeBracket) {
1167  is.unget(); if (is.fail()) return is;
1168  is.setstate( std::ios::failbit );
1169  }
1170  }
1171 
1172  return is;
1173 }
1174 
1175 } //namespace SimTK
1176 
1177 
1178 #endif //SimTK_SIMMATRIX_SMALLMATRIX_ROW_H_
AddCNTs< 1, N, ArgDepth, Row, ColSpacing, RowSpacing, CNT< P >::NRows, CNT< P >::NCols, CNT< P >::ArgDepth, P, CNT< P >::ColSpacing, CNT< P >::RowSpacing > AddOp
Definition: Row.h:277
Definition: Row.h:148
AddOp::Type Add
Definition: Row.h:278
Vec< N, EHerm, STRIDE > THerm
Definition: Row.h:176
Matrix_< E > operator/(const MatrixBase< E > &l, const typename CNT< E >::StdNumber &r)
Definition: BigMatrix.h:2693
TNeg & updNegate()
Definition: Row.h:475
Row< N, typename CNT< E >::template Result< EE >::Mul > scalarMultiply(const EE &e) const
Definition: Row.h:513
Row & scalarPlusEq(int ee)
Definition: Row.h:592
Row & scalarMinusEq(int ee)
Definition: Row.h:593
EPrecision Precision
Definition: Row.h:199
Row & scalarTimesEqFromLeft(int ee)
Definition: Row.h:597
K::ScalarNormSq ScalarNormSq
Definition: CompositeNumericalTypes.h:166
Row(const ENeg &ne)
Definition: Row.h:333
Row< N, typename CNT< E >::template Result< EE >::Add > conformingAdd(const Row< N, EE, SS > &r) const
Vector addition – use operator+ instead.
Definition: Row.h:390
K::ULessScalar ULessScalar
Definition: CompositeNumericalTypes.h:161
TImag & imag()
Definition: Row.h:494
Definition: Row.h:156
DvdOp::Type Dvd
Definition: Row.h:273
EULessScalar ULessScalar
Definition: Row.h:196
Row TRow
Definition: Row.h:179
K::TReal TReal
Definition: CompositeNumericalTypes.h:141
Vec< N, EInvert, 1 > TInvert
Definition: Row.h:187
EStandard sum() const
Definition: Row.h:240
Row & scalarDivideEq(const EE &ee)
Definition: Row.h:584
Definition: Row.h:154
Row & scalarEq(const EE &ee)
Definition: Row.h:572
Row< N, typename CNT< EE >::template Result< E >::Sub > scalarSubtractFromLeft(const EE &e) const
Definition: Row.h:555
Row< N, E, STRIDE > T
Definition: Row.h:167
Row(const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5)
Definition: Row.h:351
RS is total spacing between rows in memory (default 1)
Definition: SymMat.h:71
Row & scalarTimesEq(const EE &ee)
Definition: Row.h:580
Row & scalarDivideEqFromLeft(const EE &ee)
Definition: Row.h:586
Row & operator=(const Row< N, EE, SS > &vv)
Definition: Row.h:372
TNeg & operator-()
Definition: Row.h:470
EScalar Scalar
Definition: Row.h:195
Row & scalarPlusEq(const EE &ee)
Definition: Row.h:574
Row & operator+=(const Row< N, EE, SS > &r)
Definition: Row.h:376
Row< N, typename CNT< E >::template Result< EE >::Mul > elementwiseMultiply(const Row< N, EE, SS > &r) const
Elementwise multiply (Matlab .
Definition: Row.h:421
TAbs abs() const
Definition: Row.h:226
MulOpNonConforming::Type MulNon
Definition: Row.h:267
Row & operator-=(const Row< N, negator< EE >, SS > &r)
Definition: Row.h:382
THerm & updTranspose()
Definition: Row.h:478
SimTK::conjugate<R> should be instantiated only for float, double, long double.
Definition: String.h:45
K::TSqrt TSqrt
Definition: CompositeNumericalTypes.h:154
SymMat< N, ESqHermT > TSqHermT
Definition: Row.h:190
static TSqrt sqrt(const K &t)
Definition: CompositeNumericalTypes.h:239
Definition: Row.h:164
Row(const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5, const E &e6, const E &e7, const E &e8)
Definition: Row.h:360
K::Scalar Scalar
Definition: CompositeNumericalTypes.h:160
Row< N, EWithoutNegator, STRIDE > TWithoutNegator
Definition: Row.h:169
Row & operator=(const EE *p)
Definition: Row.h:368
Definition: Row.h:151
K::TNormalize TNormalize
Definition: CompositeNumericalTypes.h:158
ENumber Number
Definition: Row.h:197
Definition: Row.h:162
K::TImag TImag
Definition: CompositeNumericalTypes.h:142
MulCNTsNonConforming< 1, N, ArgDepth, Row, ColSpacing, RowSpacing, CNT< P >::NRows, CNT< P >::NCols, CNT< P >::ArgDepth, P, CNT< P >::ColSpacing, CNT< P >::RowSpacing > MulOpNonConforming
Definition: Row.h:266
Definition: Row.h:160
Row & operator-=(const EE &e)
Definition: Row.h:566
static int size()
Definition: Row.h:202
Row< N, typename CNT< E >::template Result< P >::Add, 1 > Add
Definition: Row.h:252
CNT< ScalarNormSq >::TSqrt norm() const
Definition: Row.h:442
std::basic_istream< CHAR, TRAITS > & operator>>(std::basic_istream< CHAR, TRAITS > &is, conjugate< R > &c)
Definition: conjugate.h:800
Row< N, EReal, STRIDE *CNT< E >::RealStrideFactor > TReal
Definition: Row.h:172
const E & operator()(int i) const
Definition: Row.h:437
MulCNTs< 1, N, ArgDepth, Row, ColSpacing, RowSpacing, CNT< P >::NRows, CNT< P >::NCols, CNT< P >::ArgDepth, P, CNT< P >::ColSpacing, CNT< P >::RowSpacing > MulOp
Definition: Row.h:261
negator<N>, where N is a number type (real, complex, conjugate), is represented in memory identically...
Definition: String.h:44
Definition: CompositeNumericalTypes.h:120
Row & operator/=(const EE &e)
Definition: Row.h:568
static double getDefaultTolerance()
Definition: CompositeNumericalTypes.h:269
Row(const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5, const E &e6)
Definition: Row.h:354
bool isInf() const
Return true if any element of this Row contains a +Infinity or -Infinity somewhere but no element con...
Definition: Row.h:713
TPosTrans & updPositionalTranspose()
Definition: Row.h:482
bool operator==(const PhiMatrix &p1, const PhiMatrix &p2)
Definition: SpatialAlgebra.h:774
ScalarNormSq scalarNormSqr() const
Definition: Row.h:208
Row & operator=(const Row &src)
Definition: Row.h:305
static TStandard standardize(const K &t)
Definition: CompositeNumericalTypes.h:241
Row< N+1, ELT, 1 > insert1(int p, const EE &v) const
Return a row one larger than this one by inserting an element before the indicated one...
Definition: Row.h:679
const THerm & operator~() const
Definition: Row.h:471
Row(int i)
Definition: Row.h:338
static Row & updSubRow(Row< NN, ELT, STRIDE > &r, int j)
Extract a subvector of type Row from a longer one that has the same element type and stride...
Definition: Row.h:644
Row & scalarMinusEqFromLeft(int ee)
Definition: Row.h:596
Row< N, typename CNT< EE >::template Result< E >::Dvd > scalarDivideFromLeft(const EE &e) const
Definition: Row.h:534
Row(const Row< N, EE, SS > &vv)
Definition: Row.h:324
Row< N, P > Type
Definition: Row.h:288
K::TSqTHerm TSqTHerm
Definition: CompositeNumericalTypes.h:147
Row< N, EAbs, 1 > TAbs
Definition: Row.h:185
Row(const E &e0, const E &e1, const E &e2)
Definition: Row.h:344
TNormalize normalize() const
Definition: Row.h:455
THerm & operator~()
Definition: Row.h:472
Row(const EE *p)
Definition: Row.h:366
DvdCNTs< 1, N, ArgDepth, Row, ColSpacing, RowSpacing, CNT< P >::NRows, CNT< P >::NCols, CNT< P >::ArgDepth, P, CNT< P >::ColSpacing, CNT< P >::RowSpacing > DvdOp
Definition: Row.h:272
Definition: Row.h:159
Row< N, typename CNT< E >::template Result< EE >::Sub > conformingSubtract(const Row< N, EE, SS > &r) const
Vector subtraction – use operator- instead.
Definition: Row.h:398
This is a fixed length column vector designed for no-overhead inline computation. ...
Definition: Vec.h:131
Row< N, EComplex, STRIDE > TComplex
Definition: Row.h:175
Row & operator-=(const Row< N, EE, SS > &r)
Definition: Row.h:380
K::Precision Precision
Definition: CompositeNumericalTypes.h:164
static Row & updAs(ELT *p)
Recast a writable ordinary C++ array E[] to a writable Row<N,E,S>; assumes compatible length...
Definition: Row.h:696
Row< N, typename CNT< EE >::template Result< E >::Mul > scalarMultiplyFromLeft(const EE &e) const
Definition: Row.h:519
Definition: Row.h:146
SubOp::Type Sub
Definition: Row.h:283
Definition: Row.h:150
Matrix_< E > operator*(const MatrixBase< E > &l, const typename CNT< E >::StdNumber &r)
Definition: BigMatrix.h:2685
Row & scalarTimesEq(int ee)
Definition: Row.h:594
void elementwiseDivide(const Row< 1, E1, S1 > &r1, const Row< 1, E2, S2 > &r2, Row< 1, typename CNT< E1 >::template Result< E2 >::Dvd > &result)
Definition: Row.h:90
K::TInvert TInvert
Definition: CompositeNumericalTypes.h:157
TStandard standardize() const
Definition: Row.h:232
bool isNaN() const
Return true if any element of this Row contains a NaN anywhere.
Definition: Row.h:704
CNT< E >::template Result< EE >::Mul conformingMultiply(const Vec< N, EE, SS > &r) const
Same as dot product (s = row*col) – use operator* or dot() instead.
Definition: Row.h:406
ELEM max(const VectorBase< ELEM > &v)
Definition: VectorMath.h:251
NTraits< N >::StdNumber StdNumber
Definition: negator.h:107
Row< N, typename CNT< E >::template Result< P >::Sub, 1 > Sub
Definition: Row.h:253
Row & scalarMinusEq(const EE &ee)
Definition: Row.h:576
E & operator()(int i)
Definition: Row.h:438
static double getDefaultTolerance()
For approximate comparisions, the default tolerance to use for a vector is the same as its elements' ...
Definition: Row.h:737
bool operator>=(const Row< N, E1, S1 > &l, const Row< N, E2, S2 > &r)
bool = v1[i] >= v2[i], for all elements i This is not the same as !(v1<v2).
Definition: Row.h:844
Row< MatNCol, typename CNT< E >::template Result< EE >::Mul > conformingMultiply(const Mat< N, MatNCol, EE, CS, RS > &m) const
Row times a conforming matrix, row=row*mat – use operator* instead.
Definition: Row.h:413
EScalarNormSq ScalarNormSq
Definition: Row.h:200
TSqrt sqrt() const
Definition: Row.h:217
MulOp::Type Mul
Definition: Row.h:262
K::TPosTrans TPosTrans
Definition: CompositeNumericalTypes.h:145
void elementwiseMultiply(const Row< 1, E1, S1 > &r1, const Row< 1, E2, S2 > &r2, Row< 1, typename CNT< E1 >::template Result< E2 >::Mul > &result)
Definition: Row.h:75
Row()
Definition: Row.h:293
Row(const Row &src)
Definition: Row.h:302
TWithoutNegator & updCastAwayNegatorIfAny()
Definition: Row.h:501
const Row & operator+() const
Definition: Row.h:468
Definition: Row.h:153
Row< N, typename CNT< E >::template Result< EE >::Dvd > scalarDivide(const EE &e) const
Definition: Row.h:528
K::StdNumber StdNumber
Definition: CompositeNumericalTypes.h:163
Row & scalarEq(int ee)
Definition: Row.h:591
RowVectorBase< typename CNT< ELEM >::TAbs > abs(const RowVectorBase< ELEM > &v)
Definition: VectorMath.h:120
Row< N, typename CNT< E >::template Result< EE >::Dvd > elementwiseDivide(const Row< N, EE, SS > &r) const
Elementwise divide (Matlab .
Definition: Row.h:429
Definition: Row.h:287
bool operator!=(const conjugate< R > &a, const float &b)
Definition: conjugate.h:859
Definition: Row.h:161
Row< N, typename CNT< E >::template Result< EE >::Add > scalarAdd(const EE &e) const
Definition: Row.h:541
Row< N, typename CNT< E >::template Result< P >::Mul, 1 > Mul
Definition: Row.h:250
Specialized information about Composite Numerical Types which allows us to define appropriate templat...
Definition: CompositeNumericalTypes.h:136
Row & scalarMinusEqFromLeft(const EE &ee)
Definition: Row.h:578
bool isFinite() const
Return true if no element of this Row contains an Infinity or a NaN anywhere.
Definition: Row.h:728
TInvert invert() const
Definition: Row.h:466
const TNeg & negate() const
Definition: Row.h:474
Generic Row.
Definition: Row.h:118
Row< N, EStandard, 1 > TStandard
Definition: Row.h:186
Row< N, EImag, STRIDE *CNT< E >::RealStrideFactor > TImag
Definition: Row.h:174
E & operator[](int i)
Definition: Row.h:436
const TWithoutNegator & castAwayNegatorIfAny() const
Definition: Row.h:500
Mandatory first inclusion for any Simbody source or header file.
bool isNumericallyEqual(const Row< N, E2, CS2 > &r) const
Test whether this row vector is numerically equal to some other row with the same shape...
Definition: Row.h:753
Row< N, typename CNT< E >::template Result< P >::Dvd, 1 > Dvd
Definition: Row.h:251
static const Row & getAs(const ELT *p)
Recast an ordinary C++ array E[] to a const Row<N,E,S>; assumes compatible length, stride, and packing.
Definition: Row.h:693
Row & operator+=(const Row< N, negator< EE >, SS > &r)
Definition: Row.h:378
K::TNeg TNeg
Definition: CompositeNumericalTypes.h:139
Row< N-1, ELT, 1 > drop1(int p) const
Return a row one smaller than this one by dropping the element at the indicated position p...
Definition: Row.h:652
Definition: Row.h:152
static Row< N, ELT, 1 > getNaN()
Return a Row of the same length and element type as this one but with all elements set to NaN...
Definition: Row.h:701
K::TStandard TStandard
Definition: CompositeNumericalTypes.h:156
Row(const Row< N, ENeg, SS > &src)
Definition: Row.h:318
Row & operator*=(const EE &e)
Definition: Row.h:567
void copy(Row< 1, E1, S1 > &r1, const Row< 1, E2, S2 > &r2)
Definition: Row.h:105
K::TWithoutNegator TWithoutNegator
Definition: CompositeNumericalTypes.h:140
const Row< NN, ELT, STRIDE > & getSubRow(int j) const
Extract a const reference to a sub-Row with size known at compile time.
Definition: Row.h:617
Row & scalarTimesEqFromLeft(const EE &ee)
Definition: Row.h:582
Row< N, ENormalize, 1 > TNormalize
Definition: Row.h:188
void conformingSubtract(const Row< 1, E1, S1 > &r1, const Row< 1, E2, S2 > &r2, Row< 1, typename CNT< E1 >::template Result< E2 >::Sub > &result)
Definition: Row.h:60
Row< N, ENeg, STRIDE > TNeg
Definition: Row.h:168
Definition: Row.h:149
Row & scalarDivideEq(int ee)
Definition: Row.h:595
Row(const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5, const E &e6, const E &e7)
Definition: Row.h:357
SubCNTs< 1, N, ArgDepth, Row, ColSpacing, RowSpacing, CNT< P >::NRows, CNT< P >::NCols, CNT< P >::ArgDepth, P, CNT< P >::ColSpacing, CNT< P >::RowSpacing > SubOp
Definition: Row.h:282
void setToZero()
Set every scalar in this Row to zero.
Definition: Row.h:607
Row & scalarDivideEqFromLeft(int ee)
Definition: Row.h:598
EStdNumber StdNumber
Definition: Row.h:198
static int nrow()
Definition: Row.h:203
const THerm & transpose() const
Definition: Row.h:477
E TElement
Definition: Row.h:178
This class represents a small matrix whose size is known at compile time, containing elements of any ...
Definition: Mat.h:51
E TCol
Definition: Row.h:180
K::TComplex TComplex
Definition: CompositeNumericalTypes.h:143
bool isNumericallyEqual(const Row< N, E2, CS2 > &r, double tol) const
Test whether this row is numerically equal to some other row with the same shape, using a specified t...
Definition: Row.h:742
TReal & real()
Definition: Row.h:486
K::Number Number
Definition: CompositeNumericalTypes.h:162
Definition: Row.h:249
const TReal & real() const
Definition: Row.h:485
static K getNaN()
Definition: CompositeNumericalTypes.h:246
Definition: Row.h:258
Row(const E &e0, const E &e1)
Definition: Row.h:342
Definition: Row.h:163
Vec< N, ESqrt, 1 > TSqrt
Definition: Row.h:184
Row(const E &e)
Definition: Row.h:329
Definition: Row.h:147
ScalarNormSq normSqr() const
Definition: Row.h:440
K::TSqHermT TSqHermT
Definition: CompositeNumericalTypes.h:146
const E & operator[](int i) const
Definition: Row.h:435
const TImag & imag() const
Definition: Row.h:489
bool operator>(const Row< N, E1, S1 > &l, const Row< N, E2, S2 > &r)
bool = v1[i] > v2[i], for all elements i
Definition: Row.h:819
const TPosTrans & positionalTranspose() const
Definition: Row.h:480
K::THerm THerm
Definition: CompositeNumericalTypes.h:144
const TNeg & operator-() const
Definition: Row.h:469
Row(const E &e0, const E &e1, const E &e2, const E &e3)
Definition: Row.h:346
Definition: negator.h:64
Row & operator+=(const EE &e)
Definition: Row.h:565
static int ncol()
Definition: Row.h:204
Row< NN, ELT, STRIDE > & updSubRow(int j)
Extract a writable reference to a sub-Row with size known at compile time.
Definition: Row.h:627
Row(const E &e0, const E &e1, const E &e2, const E &e3, const E &e4)
Definition: Row.h:348
void setToNaN()
Set every scalar in this Row to NaN; this is the default initial value in Debug builds, but not in Release.
Definition: Row.h:602
void conformingAdd(const Row< 1, E1, S1 > &r1, const Row< 1, E2, S2 > &r2, Row< 1, typename CNT< E1 >::template Result< E2 >::Add > &result)
Definition: Row.h:45
Row(const Row< N, E, SS > &src)
Definition: Row.h:312
Vec< N, E, STRIDE > TPosTrans
Definition: Row.h:177
Row< N, typename CNT< E >::template Result< EE >::Sub > scalarSubtract(const EE &e) const
Definition: Row.h:549
Row< N+1, ELT, 1 > append1(const EE &v) const
Return a row one larger than this one by adding an element to the end.
Definition: Row.h:666
K::TAbs TAbs
Definition: CompositeNumericalTypes.h:155
EScalarNormSq TSqTHerm
Definition: Row.h:191
static const Row & getSubRow(const Row< NN, ELT, STRIDE > &r, int j)
Extract a subvector of type Row from a longer one that has the same element type and stride...
Definition: Row.h:636