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