Simbody 3.7
Loading...
Searching...
No Matches
Vec.h
Go to the documentation of this file.
1#ifndef SimTK_SIMMATRIX_SMALLMATRIX_VEC_H_
2#define SimTK_SIMMATRIX_SMALLMATRIX_VEC_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
33namespace SimTK {
34
35
36// The following functions are used internally by Vec.
37
38// Hide from Doxygen.
40namespace Impl {
41
42// For those wimpy compilers that don't unroll short, constant-limit loops,
43// Peter Eastman added these recursive template implementations of
44// elementwise add, subtract, and copy. Sherm added multiply and divide.
45
46template <class E1, int S1, class E2, int S2> void
47conformingAdd(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2,
48 Vec<1,typename CNT<E1>::template Result<E2>::Add>& result) {
49 result[0] = r1[0] + r2[0];
50}
51template <int N, class E1, int S1, class E2, int S2> void
52conformingAdd(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2,
53 Vec<N,typename CNT<E1>::template Result<E2>::Add>& result) {
54 conformingAdd(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1),
55 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2),
56 reinterpret_cast<Vec<N-1,typename CNT<E1>::
57 template Result<E2>::Add>&>(result));
58 result[N-1] = r1[N-1] + r2[N-1];
59}
60
61template <class E1, int S1, class E2, int S2> void
62conformingSubtract(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2,
63 Vec<1,typename CNT<E1>::template Result<E2>::Sub>& result) {
64 result[0] = r1[0] - r2[0];
65}
66template <int N, class E1, int S1, class E2, int S2> void
67conformingSubtract(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2,
68 Vec<N,typename CNT<E1>::template Result<E2>::Sub>& result) {
69 conformingSubtract(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1),
70 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2),
71 reinterpret_cast<Vec<N-1,typename CNT<E1>::
72 template Result<E2>::Sub>&>(result));
73 result[N-1] = r1[N-1] - r2[N-1];
74}
75
76template <class E1, int S1, class E2, int S2> void
77elementwiseMultiply(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2,
78 Vec<1,typename CNT<E1>::template Result<E2>::Mul>& result) {
79 result[0] = r1[0] * r2[0];
80}
81template <int N, class E1, int S1, class E2, int S2> void
82elementwiseMultiply(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2,
83 Vec<N,typename CNT<E1>::template Result<E2>::Mul>& result) {
84 elementwiseMultiply(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1),
85 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2),
86 reinterpret_cast<Vec<N-1,typename CNT<E1>::
87 template Result<E2>::Mul>&>(result));
88 result[N-1] = r1[N-1] * r2[N-1];
89}
90
91template <class E1, int S1, class E2, int S2> void
92elementwiseDivide(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2,
93 Vec<1,typename CNT<E1>::template Result<E2>::Dvd>& result) {
94 result[0] = r1[0] / r2[0];
95}
96template <int N, class E1, int S1, class E2, int S2> void
97elementwiseDivide(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2,
98 Vec<N,typename CNT<E1>::template Result<E2>::Dvd>& result) {
99 elementwiseDivide(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1),
100 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2),
101 reinterpret_cast<Vec<N-1,typename CNT<E1>::
102 template Result<E2>::Dvd>&>(result));
103 result[N-1] = r1[N-1] / r2[N-1];
104}
105
106template <class E1, int S1, class E2, int S2> void
107copy(Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2) {
108 r1[0] = r2[0];
109}
110template <int N, class E1, int S1, class E2, int S2> void
111copy(Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2) {
112 copy(reinterpret_cast<Vec<N-1,E1,S1>&>(r1),
113 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2));
114 r1[N-1] = r2[N-1];
115}
116
117}
183template <int M, class ELT, int STRIDE>
184class Vec {
185public:
191 typedef ELT E;
193 typedef typename CNT<E>::TNeg ENeg;
198 typedef typename CNT<E>::TReal EReal;
202 typedef typename CNT<E>::TImag EImag;
205 typedef typename CNT<E>::TComplex EComplex;
207 typedef typename CNT<E>::THerm EHerm;
209 typedef typename CNT<E>::TPosTrans EPosTrans;
212 typedef typename CNT<E>::TSqHermT ESqHermT;
214 typedef typename CNT<E>::TSqTHerm ESqTHerm;
216 typedef typename CNT<E>::TSqrt ESqrt;
218 typedef typename CNT<E>::TAbs EAbs;
221 typedef typename CNT<E>::TStandard EStandard;
224 typedef typename CNT<E>::TInvert EInvert;
227
228 typedef typename CNT<E>::Scalar EScalar;
230 typedef typename CNT<E>::Number ENumber;
234
237 #ifndef SWIG
238 enum {
239 NRows = M,
240 NCols = 1,
242 NActualElements = M * STRIDE, // includes trailing gap
247 RealStrideFactor = 1, // composite types don't change size when
248 // cast from complex to real or imaginary
250 ? CNT<E>::ArgDepth + 1
258 };
259 #endif
260
261 // These are reinterpretations of the current data, so have the
262 // same packing (stride).
263
289 typedef E TElement;
291 typedef E TRow;
293 typedef Vec TCol;
294
295 // These are the results of calculations, so are returned in new, packed
296 // memory. Be sure to refer to element types here which are also packed.
297 typedef Vec<M,ESqrt,1> TSqrt; // Note stride
298 typedef Vec<M,EAbs,1> TAbs; // Note stride
302
303 typedef ESqHermT TSqHermT; // result of self dot product
304 typedef SymMat<M,ESqTHerm> TSqTHerm; // result of self outer product
305
306 // These recurse right down to the underlying scalar type no matter how
307 // deep the elements are.
318 static int size() { return M; }
320 static int nrow() { return M; }
322 static int ncol() { return 1; }
323
324
328 ScalarNormSq sum(0);
330 return sum;
331 }
332
337 TSqrt sqrt() const {
338 TSqrt vsqrt;
340 return vsqrt;
341 }
342
347 TAbs abs() const {
348 TAbs vabs;
350 return vabs;
351 }
352
360 return vstd;
361 }
362
366 EStandard sum() const {
367 E sum(0);
368 for (int i=0;i<M;++i) sum += d[i*STRIDE];
369 return CNT<E>::standardize(sum);
370 }
371
372
373 // This gives the resulting vector type when (v[i] op P) is applied to
374 // each element of v. It is a vector of length M, stride 1, and element
375 // types which are the regular composite result of E op P. Typically P is
376 // a scalar type but it doesn't have to be.
383
384 // This is the composite result for v op P where P is some kind of
385 // appropriately shaped non-scalar type.
412
418 template <class P> struct Substitute {
419 typedef Vec<M,P> Type;
420 };
421
425 Vec(){
426 #ifndef NDEBUG
427 setToNaN();
428 #endif
429 }
430
431 // It's important not to use the default copy constructor or copy
432 // assignment because the compiler doesn't understand that we may
433 // have noncontiguous storage and will try to copy the whole array.
434
438 Vec(const Vec& src) {
439 Impl::copy(*this, src);
440 }
445 Vec& operator=(const Vec& src) {
446 Impl::copy(*this, src);
447 return *this;
448 }
449
452 template <int SS> Vec(const Vec<M,E,SS>& src) {
453 Impl::copy(*this, src);
454 }
455
458 template <int SS> Vec(const Vec<M,ENeg,SS>& src) {
459 Impl::copy(*this, src);
460 }
461
464 template <class EE, int SS> explicit Vec(const Vec<M,EE,SS>& src) {
465 Impl::copy(*this, src);
466 }
467
470 explicit Vec(const E& e) {for (int i=0;i<M;++i) d[i*STRIDE]=e;}
471
476 explicit Vec(const ENeg& ne) {
477 const E e = ne; // requires floating point negation
478 for (int i=0;i<M;++i) d[i*STRIDE]=e;
479 }
480
485 explicit Vec(int i) {new (this) Vec(E(Precision(i)));}
486
487 // A bevy of constructors for Vecs up to length 9.
488
490 Vec(const E& e0,const E& e1)
491 { assert(M==2);(*this)[0]=e0;(*this)[1]=e1; }
492 Vec(const E& e0,const E& e1,const E& e2)
493 { assert(M==3);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; }
494 Vec(const E& e0,const E& e1,const E& e2,const E& e3)
495 { assert(M==4);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;(*this)[3]=e3; }
496 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4)
497 { assert(M==5);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
498 (*this)[3]=e3;(*this)[4]=e4; }
499 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5)
500 { assert(M==6);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
501 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5; }
502 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5, const E& e6)
503 { assert(M==7);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
504 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6; }
505 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5, const E& e6, const E& e7)
506 { assert(M==8);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
507 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7; }
508 Vec(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)
509 { assert(M==9);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
510 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7;(*this)[8]=e8; }
511
516 template <class EE> explicit Vec(const EE* p)
517 { assert(p); for(int i=0;i<M;++i) d[i*STRIDE]=p[i]; }
518
523 template <class EE> Vec& operator=(const EE* p)
524 { assert(p); for(int i=0;i<M;++i) d[i*STRIDE]=p[i]; return *this; }
525
528 template <class EE, int SS> Vec& operator=(const Vec<M,EE,SS>& vv)
529 { Impl::copy(*this, vv); return *this; }
530
533 template <class EE, int SS> Vec& operator+=(const Vec<M,EE,SS>& r)
534 { for(int i=0;i<M;++i) d[i*STRIDE] += r[i]; return *this; }
538 template <class EE, int SS> Vec& operator+=(const Vec<M,negator<EE>,SS>& r)
539 { for(int i=0;i<M;++i) d[i*STRIDE] -= -(r[i]); return *this; }
540
543 template <class EE, int SS> Vec& operator-=(const Vec<M,EE,SS>& r)
544 { for(int i=0;i<M;++i) d[i*STRIDE] -= r[i]; return *this; }
548 template <class EE, int SS> Vec& operator-=(const Vec<M,negator<EE>,SS>& r)
549 { for(int i=0;i<M;++i) d[i*STRIDE] += -(r[i]); return *this; }
550
551 // Conforming binary ops with 'this' on left, producing new packed result.
552 // Cases: v=v+v, v=v-v, m=v*r
553
555 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Add>
558 Impl::conformingAdd(*this, r, result);
559 return result;
560 }
562 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Sub>
565 Impl::conformingSubtract(*this, r, result);
566 return result;
567 }
568
571 template <class EE, int SS> Mat<M,M,typename CNT<E>::template Result<EE>::Mul>
574 for (int j=0;j<M;++j) result(j) = scalarMultiply(r(j));
575 return result;
576 }
577
579 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Mul>
582 Impl::elementwiseMultiply(*this, r, result);
583 return result;
584 }
586 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Dvd>
589 Impl::elementwiseDivide(*this, r, result);
590 return result;
591 }
592
596 const E& operator[](int i) const
597 { assert(0 <= i && i < M); return d[i*STRIDE]; }
599 const E& operator()(int i) const {return (*this)[i];}
600
604 E& operator[](int i) {assert(0 <= i && i < M); return d[i*STRIDE];}
606 E& operator()(int i) {return (*this)[i];}
607
608 ScalarNormSq normSqr() const { return scalarNormSqr(); }
611
624 if (CNT<E>::IsScalar) {
626 } else {
628 for (int i=0; i<M; ++i)
631 }
632 }
633
635 TInvert invert() const {assert(false); return TInvert();} // TODO default inversion
636
638 const Vec& operator+() const { return *this; }
642 const TNeg& operator-() const { return negate(); }
645 TNeg& operator-() { return updNegate(); }
649 const THerm& operator~() const { return transpose(); }
653 THerm& operator~() { return updTranspose(); }
654
656 const TNeg& negate() const { return *reinterpret_cast<const TNeg*>(this); }
659 TNeg& updNegate() { return *reinterpret_cast< TNeg*>(this); }
660
662 const THerm& transpose() const { return *reinterpret_cast<const THerm*>(this); }
665 THerm& updTranspose() { return *reinterpret_cast< THerm*>(this); }
666
672 { return *reinterpret_cast<const TPosTrans*>(this); }
675 { return *reinterpret_cast<TPosTrans*>(this); }
676
681 const TReal& real() const { return *reinterpret_cast<const TReal*>(this); }
684 TReal& real() { return *reinterpret_cast< TReal*>(this); }
685
686 // Had to contort these next two routines to get them through VC++ 7.net
687
692 const TImag& imag() const {
693 const int offs = ImagOffset;
694 const EImag* p = reinterpret_cast<const EImag*>(this);
695 return *reinterpret_cast<const TImag*>(p+offs);
696 }
700 const int offs = ImagOffset;
701 EImag* p = reinterpret_cast<EImag*>(this);
702 return *reinterpret_cast<TImag*>(p+offs);
703 }
704
709 { return *reinterpret_cast<const TWithoutNegator*>(this); }
713 { return *reinterpret_cast<TWithoutNegator*>(this); }
714
715 // These are elementwise binary operators, (this op ee) by default but
716 // (ee op this) if 'FromLeft' appears in the name. The result is a packed
717 // Vec<M> but the element type may change. These are mostly used to
718 // implement global operators. We call these "scalar" operators but
719 // actually the "scalar" can be a composite type.
720
721 //TODO: consider converting 'e' to Standard Numbers as precalculation and
722 // changing return type appropriately.
724 scalarMultiply(const EE& e) const {
726 for (int i=0; i<M; ++i) result[i] = (*this)[i] * e;
727 return result;
728 }
730 scalarMultiplyFromLeft(const EE& e) const {
732 for (int i=0; i<M; ++i) result[i] = e * (*this)[i];
733 return result;
734 }
735
736 // TODO: should precalculate and store 1/e, while converting to Standard
737 // Numbers. Note that return type should change appropriately.
739 scalarDivide(const EE& e) const {
741 for (int i=0; i<M; ++i) result[i] = (*this)[i] / e;
742 return result;
743 }
745 scalarDivideFromLeft(const EE& e) const {
747 for (int i=0; i<M; ++i) result[i] = e / (*this)[i];
748 return result;
749 }
750
752 scalarAdd(const EE& e) const {
754 for (int i=0; i<M; ++i) result[i] = (*this)[i] + e;
755 return result;
756 }
757 // Add is commutative, so no 'FromLeft'.
758
760 scalarSubtract(const EE& e) const {
762 for (int i=0; i<M; ++i) result[i] = (*this)[i] - e;
763 return result;
764 }
766 scalarSubtractFromLeft(const EE& e) const {
768 for (int i=0; i<M; ++i) result[i] = e - (*this)[i];
769 return result;
770 }
771
772 // Generic assignments for any element type not listed explicitly, including scalars.
773 // These are done repeatedly for each element and only work if the operation can
774 // be performed leaving the original element type.
775 template <class EE> Vec& operator =(const EE& e) {return scalarEq(e);}
776 template <class EE> Vec& operator+=(const EE& e) {return scalarPlusEq(e);}
777 template <class EE> Vec& operator-=(const EE& e) {return scalarMinusEq(e);}
778 template <class EE> Vec& operator*=(const EE& e) {return scalarTimesEq(e);}
779 template <class EE> Vec& operator/=(const EE& e) {return scalarDivideEq(e);}
780
781 // Generalized element assignment & computed assignment methods. These will work
782 // for any assignment-compatible element, not just scalars.
783 template <class EE> Vec& scalarEq(const EE& ee)
784 { for(int i=0;i<M;++i) d[i*STRIDE] = ee; return *this; }
785 template <class EE> Vec& scalarPlusEq(const EE& ee)
786 { for(int i=0;i<M;++i) d[i*STRIDE] += ee; return *this; }
787 template <class EE> Vec& scalarMinusEq(const EE& ee)
788 { for(int i=0;i<M;++i) d[i*STRIDE] -= ee; return *this; }
789 template <class EE> Vec& scalarMinusEqFromLeft(const EE& ee)
790 { for(int i=0;i<M;++i) d[i*STRIDE] = ee - d[i*STRIDE]; return *this; }
791 template <class EE> Vec& scalarTimesEq(const EE& ee)
792 { for(int i=0;i<M;++i) d[i*STRIDE] *= ee; return *this; }
793 template <class EE> Vec& scalarTimesEqFromLeft(const EE& ee)
794 { for(int i=0;i<M;++i) d[i*STRIDE] = ee * d[i*STRIDE]; return *this; }
795 template <class EE> Vec& scalarDivideEq(const EE& ee)
796 { for(int i=0;i<M;++i) d[i*STRIDE] /= ee; return *this; }
797 template <class EE> Vec& scalarDivideEqFromLeft(const EE& ee)
798 { for(int i=0;i<M;++i) d[i*STRIDE] = ee / d[i*STRIDE]; return *this; }
799
800 // Specialize for int to avoid warnings and ambiguities.
801 Vec& scalarEq(int ee) {return scalarEq(Precision(ee));}
809
812 void setToNaN() {
813 (*this) = CNT<ELT>::getNaN();
814 }
815
817 void setToZero() {
818 (*this) = ELT(0);
819 }
820
826 template <int MM>
827 const Vec<MM,ELT,STRIDE>& getSubVec(int i) const {
828 assert(0 <= i && i + MM <= M);
829 return Vec<MM,ELT,STRIDE>::getAs(&(*this)[i]);
830 }
836 template <int MM>
838 assert(0 <= i && i + MM <= M);
839 return Vec<MM,ELT,STRIDE>::updAs(&(*this)[i]);
840 }
841
842
846 template <int MM>
847 static const Vec& getSubVec(const Vec<MM,ELT,STRIDE>& v, int i) {
848 assert(0 <= i && i + M <= MM);
849 return getAs(&v[i]);
850 }
854 template <int MM>
856 assert(0 <= i && i + M <= MM);
857 return updAs(&v[i]);
858 }
859
863 Vec<M-1,ELT,1> drop1(int p) const {
864 assert(0 <= p && p < M);
865 Vec<M-1,ELT,1> out;
866 int nxt=0;
867 for (int i=0; i<M-1; ++i, ++nxt) {
868 if (nxt==p) ++nxt; // skip the loser
869 out[i] = (*this)[nxt];
870 }
871 return out;
872 }
873
877 template <class EE> Vec<M+1,ELT,1> append1(const EE& v) const {
879 Vec<M,ELT,1>::updAs(&out[0]) = (*this);
880 out[M] = v;
881 return out;
882 }
883
884
890 template <class EE> Vec<M+1,ELT,1> insert1(int p, const EE& v) const {
891 assert(0 <= p && p <= M);
892 if (p==M) return append1(v);
894 int nxt=0;
895 for (int i=0; i<M; ++i, ++nxt) {
896 if (i==p) out[nxt++] = v;
897 out[nxt] = (*this)[i];
898 }
899 return out;
900 }
901
904 static const Vec& getAs(const ELT* p)
905 { return *reinterpret_cast<const Vec*>(p); }
908 static Vec& updAs(ELT* p)
909 { return *reinterpret_cast<Vec*>(p); }
910
911
916
918 bool isNaN() const {
919 for (int i=0; i<M; ++i)
920 if (CNT<ELT>::isNaN((*this)[i]))
921 return true;
922 return false;
923 }
924
927 bool isInf() const {
928 bool seenInf = false;
929 for (int i=0; i<M; ++i) {
930 const ELT& e = (*this)[i];
931 if (!CNT<ELT>::isFinite(e)) {
932 if (!CNT<ELT>::isInf(e))
933 return false; // something bad was found
934 seenInf = true;
935 }
936 }
937 return seenInf;
938 }
939
942 bool isFinite() const {
943 for (int i=0; i<M; ++i)
944 if (!CNT<ELT>::isFinite((*this)[i]))
945 return false;
946 return true;
947 }
948
952
955 template <class E2, int RS2>
956 bool isNumericallyEqual(const Vec<M,E2,RS2>& v, double tol) const {
957 for (int i=0; i<M; ++i)
958 if (!CNT<ELT>::isNumericallyEqual((*this)[i], v[i], tol))
959 return false;
960 return true;
961 }
962
966 template <class E2, int RS2>
967 bool isNumericallyEqual(const Vec<M,E2,RS2>& v) const {
968 const double tol = std::max(getDefaultTolerance(),v.getDefaultTolerance());
969 return isNumericallyEqual(v, tol);
970 }
971
977 (const ELT& e,
978 double tol = getDefaultTolerance()) const
979 {
980 for (int i=0; i<M; ++i)
981 if (!CNT<ELT>::isNumericallyEqual((*this)[i], e, tol))
982 return false;
983 return true;
984 }
985
986 // Functions to be used for Scripting in MATLAB and languages that do not support operator overloading
988 std::string toString() const {
989 std::stringstream stream;
990 stream << (*this);
991 return stream.str();
992 }
993
995 void set(int i, const E& value)
996 { (*this)[i] = value; }
997
999 const E& get(int i) const
1000 { return operator[](i); }
1001
1002private:
1003 // TODO: should be an array of scalars rather than elements to control
1004 // packing more carefully.
1005 ELT d[NActualElements]; // data
1006};
1007
1009// Global operators involving two vectors. //
1010// v+v, v-v, v==v, v!=v //
1012
1013// v3 = v1 + v2 where all v's have the same length M.
1014template <int M, class E1, int S1, class E2, int S2> inline
1015typename Vec<M,E1,S1>::template Result< Vec<M,E2,S2> >::Add
1017 return Vec<M,E1,S1>::template Result< Vec<M,E2,S2> >
1018 ::AddOp::perform(l,r);
1019}
1020
1021// v3 = v1 - v2, similar to +
1022template <int M, class E1, int S1, class E2, int S2> inline
1023typename Vec<M,E1,S1>::template Result< Vec<M,E2,S2> >::Sub
1025 return Vec<M,E1,S1>::template Result< Vec<M,E2,S2> >
1026 ::SubOp::perform(l,r);
1027}
1028
1030template <int M, class E1, int S1, class E2, int S2> inline bool
1032{ for (int i=0; i < M; ++i) if (l[i] != r[i]) return false;
1033 return true; }
1035template <int M, class E1, int S1, class E2, int S2> inline bool
1036operator!=(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) {return !(l==r);}
1037
1039template <int M, class E1, int S1, class E2> inline bool
1040operator==(const Vec<M,E1,S1>& v, const E2& e)
1041{ for (int i=0; i < M; ++i) if (v[i] != e) return false;
1042 return true; }
1044template <int M, class E1, int S1, class E2> inline bool
1045operator!=(const Vec<M,E1,S1>& v, const E2& e) {return !(v==e);}
1046
1048template <int M, class E1, int S1, class E2, int S2> inline bool
1049operator<(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r)
1050{ for (int i=0; i < M; ++i) if (l[i] >= r[i]) return false;
1051 return true; }
1053template <int M, class E1, int S1, class E2> inline bool
1054operator<(const Vec<M,E1,S1>& v, const E2& e)
1055{ for (int i=0; i < M; ++i) if (v[i] >= e) return false;
1056 return true; }
1057
1059template <int M, class E1, int S1, class E2, int S2> inline bool
1061{ for (int i=0; i < M; ++i) if (l[i] <= r[i]) return false;
1062 return true; }
1064template <int M, class E1, int S1, class E2> inline bool
1065operator>(const Vec<M,E1,S1>& v, const E2& e)
1066{ for (int i=0; i < M; ++i) if (v[i] <= e) return false;
1067 return true; }
1068
1071template <int M, class E1, int S1, class E2, int S2> inline bool
1072operator<=(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r)
1073{ for (int i=0; i < M; ++i) if (l[i] > r[i]) return false;
1074 return true; }
1077template <int M, class E1, int S1, class E2> inline bool
1078operator<=(const Vec<M,E1,S1>& v, const E2& e)
1079{ for (int i=0; i < M; ++i) if (v[i] > e) return false;
1080 return true; }
1081
1084template <int M, class E1, int S1, class E2, int S2> inline bool
1086{ for (int i=0; i < M; ++i) if (l[i] < r[i]) return false;
1087 return true; }
1090template <int M, class E1, int S1, class E2> inline bool
1091operator>=(const Vec<M,E1,S1>& v, const E2& e)
1092{ for (int i=0; i < M; ++i) if (v[i] < e) return false;
1093 return true; }
1094
1096// Global operators involving a vector and a scalar. //
1098
1099// I haven't been able to figure out a nice way to templatize for the
1100// built-in reals without introducing a lot of unwanted type matches
1101// as well. So we'll just grind them out explicitly here.
1102
1103// SCALAR MULTIPLY
1104
1105// v = v*real, real*v
1106template <int M, class E, int S> inline
1107typename Vec<M,E,S>::template Result<float>::Mul
1108operator*(const Vec<M,E,S>& l, const float& r)
1109 { return Vec<M,E,S>::template Result<float>::MulOp::perform(l,r); }
1110template <int M, class E, int S> inline
1111typename Vec<M,E,S>::template Result<float>::Mul
1112operator*(const float& l, const Vec<M,E,S>& r) {return r*l;}
1113
1114template <int M, class E, int S> inline
1115typename Vec<M,E,S>::template Result<double>::Mul
1116operator*(const Vec<M,E,S>& l, const double& r)
1117 { return Vec<M,E,S>::template Result<double>::MulOp::perform(l,r); }
1118template <int M, class E, int S> inline
1119typename Vec<M,E,S>::template Result<double>::Mul
1120operator*(const double& l, const Vec<M,E,S>& r) {return r*l;}
1121
1122// v = v*int, int*v -- just convert int to v's precision float
1123template <int M, class E, int S> inline
1124typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Mul
1125operator*(const Vec<M,E,S>& l, int r) {return l * (typename CNT<E>::Precision)r;}
1126template <int M, class E, int S> inline
1127typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Mul
1128operator*(int l, const Vec<M,E,S>& r) {return r * (typename CNT<E>::Precision)l;}
1129
1130// Complex, conjugate, and negator are all easy to templatize.
1131
1132// v = v*complex, complex*v
1133template <int M, class E, int S, class R> inline
1134typename Vec<M,E,S>::template Result<std::complex<R> >::Mul
1135operator*(const Vec<M,E,S>& l, const std::complex<R>& r)
1136 { return Vec<M,E,S>::template Result<std::complex<R> >::MulOp::perform(l,r); }
1137template <int M, class E, int S, class R> inline
1138typename Vec<M,E,S>::template Result<std::complex<R> >::Mul
1139operator*(const std::complex<R>& l, const Vec<M,E,S>& r) {return r*l;}
1140
1141// v = v*conjugate, conjugate*v (convert conjugate->complex)
1142template <int M, class E, int S, class R> inline
1143typename Vec<M,E,S>::template Result<std::complex<R> >::Mul
1144operator*(const Vec<M,E,S>& l, const conjugate<R>& r) {return l*(std::complex<R>)r;}
1145template <int M, class E, int S, class R> inline
1146typename Vec<M,E,S>::template Result<std::complex<R> >::Mul
1147operator*(const conjugate<R>& l, const Vec<M,E,S>& r) {return r*(std::complex<R>)l;}
1148
1149// v = v*negator, negator*v: convert negator to standard number
1150template <int M, class E, int S, class R> inline
1151typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Mul
1152operator*(const Vec<M,E,S>& l, const negator<R>& r) {return l * (typename negator<R>::StdNumber)(R)r;}
1153template <int M, class E, int S, class R> inline
1154typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Mul
1155operator*(const negator<R>& l, const Vec<M,E,S>& r) {return r * (typename negator<R>::StdNumber)(R)l;}
1156
1157
1158// SCALAR DIVIDE. This is a scalar operation when the scalar is on the right,
1159// but when it is on the left it means scalar * pseudoInverse(vec), which is
1160// a row.
1161
1162// v = v/real, real/v
1163template <int M, class E, int S> inline
1164typename Vec<M,E,S>::template Result<float>::Dvd
1165operator/(const Vec<M,E,S>& l, const float& r)
1166 { return Vec<M,E,S>::template Result<float>::DvdOp::perform(l,r); }
1167template <int M, class E, int S> inline
1168typename CNT<float>::template Result<Vec<M,E,S> >::Dvd
1169operator/(const float& l, const Vec<M,E,S>& r)
1170 { return CNT<float>::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); }
1171
1172template <int M, class E, int S> inline
1173typename Vec<M,E,S>::template Result<double>::Dvd
1174operator/(const Vec<M,E,S>& l, const double& r)
1175 { return Vec<M,E,S>::template Result<double>::DvdOp::perform(l,r); }
1176template <int M, class E, int S> inline
1177typename CNT<double>::template Result<Vec<M,E,S> >::Dvd
1178operator/(const double& l, const Vec<M,E,S>& r)
1179 { return CNT<double>::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); }
1180
1181// v = v/int, int/v -- just convert int to v's precision float
1182template <int M, class E, int S> inline
1183typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Dvd
1184operator/(const Vec<M,E,S>& l, int r) {return l / (typename CNT<E>::Precision)r;}
1185template <int M, class E, int S> inline
1186typename CNT<typename CNT<E>::Precision>::template Result<Vec<M,E,S> >::Dvd
1187operator/(int l, const Vec<M,E,S>& r) {return (typename CNT<E>::Precision)l / r;}
1188
1189
1190// Complex, conjugate, and negator are all easy to templatize.
1191
1192// v = v/complex, complex/v
1193template <int M, class E, int S, class R> inline
1194typename Vec<M,E,S>::template Result<std::complex<R> >::Dvd
1195operator/(const Vec<M,E,S>& l, const std::complex<R>& r)
1196 { return Vec<M,E,S>::template Result<std::complex<R> >::DvdOp::perform(l,r); }
1197template <int M, class E, int S, class R> inline
1198typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Dvd
1199operator/(const std::complex<R>& l, const Vec<M,E,S>& r)
1200 { return CNT<std::complex<R> >::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); }
1201
1202// v = v/conjugate, conjugate/v (convert conjugate->complex)
1203template <int M, class E, int S, class R> inline
1204typename Vec<M,E,S>::template Result<std::complex<R> >::Dvd
1205operator/(const Vec<M,E,S>& l, const conjugate<R>& r) {return l/(std::complex<R>)r;}
1206template <int M, class E, int S, class R> inline
1207typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Dvd
1208operator/(const conjugate<R>& l, const Vec<M,E,S>& r) {return (std::complex<R>)l/r;}
1209
1210// v = v/negator, negator/v: convert negator to number
1211template <int M, class E, int S, class R> inline
1212typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Dvd
1213operator/(const Vec<M,E,S>& l, const negator<R>& r) {return l/(typename negator<R>::StdNumber)(R)r;}
1214template <int M, class E, int S, class R> inline
1215typename CNT<R>::template Result<Vec<M,E,S> >::Dvd
1216operator/(const negator<R>& l, const Vec<M,E,S>& r) {return (typename negator<R>::StdNumber)(R)l/r;}
1217
1218
1219// Add and subtract are odd as scalar ops. They behave as though the
1220// scalar stands for a vector each of whose elements is that scalar,
1221// and then a normal vector add or subtract is done.
1222
1223// SCALAR ADD
1224
1225// v = v+real, real+v
1226template <int M, class E, int S> inline
1227typename Vec<M,E,S>::template Result<float>::Add
1228operator+(const Vec<M,E,S>& l, const float& r)
1229 { return Vec<M,E,S>::template Result<float>::AddOp::perform(l,r); }
1230template <int M, class E, int S> inline
1231typename Vec<M,E,S>::template Result<float>::Add
1232operator+(const float& l, const Vec<M,E,S>& r) {return r+l;}
1233
1234template <int M, class E, int S> inline
1235typename Vec<M,E,S>::template Result<double>::Add
1236operator+(const Vec<M,E,S>& l, const double& r)
1237 { return Vec<M,E,S>::template Result<double>::AddOp::perform(l,r); }
1238template <int M, class E, int S> inline
1239typename Vec<M,E,S>::template Result<double>::Add
1240operator+(const double& l, const Vec<M,E,S>& r) {return r+l;}
1241
1242// v = v+int, int+v -- just convert int to v's precision float
1243template <int M, class E, int S> inline
1244typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Add
1245operator+(const Vec<M,E,S>& l, int r) {return l + (typename CNT<E>::Precision)r;}
1246template <int M, class E, int S> inline
1247typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Add
1248operator+(int l, const Vec<M,E,S>& r) {return r + (typename CNT<E>::Precision)l;}
1249
1250// Complex, conjugate, and negator are all easy to templatize.
1251
1252// v = v+complex, complex+v
1253template <int M, class E, int S, class R> inline
1254typename Vec<M,E,S>::template Result<std::complex<R> >::Add
1255operator+(const Vec<M,E,S>& l, const std::complex<R>& r)
1256 { return Vec<M,E,S>::template Result<std::complex<R> >::AddOp::perform(l,r); }
1257template <int M, class E, int S, class R> inline
1258typename Vec<M,E,S>::template Result<std::complex<R> >::Add
1259operator+(const std::complex<R>& l, const Vec<M,E,S>& r) {return r+l;}
1260
1261// v = v+conjugate, conjugate+v (convert conjugate->complex)
1262template <int M, class E, int S, class R> inline
1263typename Vec<M,E,S>::template Result<std::complex<R> >::Add
1264operator+(const Vec<M,E,S>& l, const conjugate<R>& r) {return l+(std::complex<R>)r;}
1265template <int M, class E, int S, class R> inline
1266typename Vec<M,E,S>::template Result<std::complex<R> >::Add
1267operator+(const conjugate<R>& l, const Vec<M,E,S>& r) {return r+(std::complex<R>)l;}
1268
1269// v = v+negator, negator+v: convert negator to standard number
1270template <int M, class E, int S, class R> inline
1271typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Add
1272operator+(const Vec<M,E,S>& l, const negator<R>& r) {return l + (typename negator<R>::StdNumber)(R)r;}
1273template <int M, class E, int S, class R> inline
1274typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Add
1275operator+(const negator<R>& l, const Vec<M,E,S>& r) {return r + (typename negator<R>::StdNumber)(R)l;}
1276
1277// SCALAR SUBTRACT -- careful, not commutative.
1278
1279// v = v-real, real-v
1280template <int M, class E, int S> inline
1281typename Vec<M,E,S>::template Result<float>::Sub
1282operator-(const Vec<M,E,S>& l, const float& r)
1283 { return Vec<M,E,S>::template Result<float>::SubOp::perform(l,r); }
1284template <int M, class E, int S> inline
1285typename CNT<float>::template Result<Vec<M,E,S> >::Sub
1286operator-(const float& l, const Vec<M,E,S>& r)
1287 { return CNT<float>::template Result<Vec<M,E,S> >::SubOp::perform(l,r); }
1288
1289template <int M, class E, int S> inline
1290typename Vec<M,E,S>::template Result<double>::Sub
1291operator-(const Vec<M,E,S>& l, const double& r)
1292 { return Vec<M,E,S>::template Result<double>::SubOp::perform(l,r); }
1293template <int M, class E, int S> inline
1294typename CNT<double>::template Result<Vec<M,E,S> >::Sub
1295operator-(const double& l, const Vec<M,E,S>& r)
1296 { return CNT<double>::template Result<Vec<M,E,S> >::SubOp::perform(l,r); }
1297
1298// v = v-int, int-v // just convert int to v's precision float
1299template <int M, class E, int S> inline
1300typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Sub
1301operator-(const Vec<M,E,S>& l, int r) {return l - (typename CNT<E>::Precision)r;}
1302template <int M, class E, int S> inline
1303typename CNT<typename CNT<E>::Precision>::template Result<Vec<M,E,S> >::Sub
1304operator-(int l, const Vec<M,E,S>& r) {return (typename CNT<E>::Precision)l - r;}
1305
1306
1307// Complex, conjugate, and negator are all easy to templatize.
1308
1309// v = v-complex, complex-v
1310template <int M, class E, int S, class R> inline
1311typename Vec<M,E,S>::template Result<std::complex<R> >::Sub
1312operator-(const Vec<M,E,S>& l, const std::complex<R>& r)
1313 { return Vec<M,E,S>::template Result<std::complex<R> >::SubOp::perform(l,r); }
1314template <int M, class E, int S, class R> inline
1315typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Sub
1316operator-(const std::complex<R>& l, const Vec<M,E,S>& r)
1317 { return CNT<std::complex<R> >::template Result<Vec<M,E,S> >::SubOp::perform(l,r); }
1318
1319// v = v-conjugate, conjugate-v (convert conjugate->complex)
1320template <int M, class E, int S, class R> inline
1321typename Vec<M,E,S>::template Result<std::complex<R> >::Sub
1322operator-(const Vec<M,E,S>& l, const conjugate<R>& r) {return l-(std::complex<R>)r;}
1323template <int M, class E, int S, class R> inline
1324typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Sub
1325operator-(const conjugate<R>& l, const Vec<M,E,S>& r) {return (std::complex<R>)l-r;}
1326
1327// v = v-negator, negator-v: convert negator to standard number
1328template <int M, class E, int S, class R> inline
1329typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Sub
1330operator-(const Vec<M,E,S>& l, const negator<R>& r) {return l-(typename negator<R>::StdNumber)(R)r;}
1331template <int M, class E, int S, class R> inline
1332typename CNT<R>::template Result<Vec<M,E,S> >::Sub
1333operator-(const negator<R>& l, const Vec<M,E,S>& r) {return (typename negator<R>::StdNumber)(R)l-r;}
1334
1335// Vec I/O
1336template <int M, class E, int S, class CHAR, class TRAITS> inline
1337std::basic_ostream<CHAR,TRAITS>&
1338operator<<(std::basic_ostream<CHAR,TRAITS>& o, const Vec<M,E,S>& v) {
1339 o << "~[" << v[0]; for(int i=1;i<M;++i) o<<','<<v[i]; o<<']'; return o;
1340}
1341
1344template <int M, class E, int S, class CHAR, class TRAITS> inline
1345std::basic_istream<CHAR,TRAITS>&
1346operator>>(std::basic_istream<CHAR,TRAITS>& is, Vec<M,E,S>& v) {
1347 CHAR tilde;
1348 is >> tilde; if (is.fail()) return is;
1349 if (tilde != CHAR('~')) {
1350 tilde = CHAR(0);
1351 is.unget(); if (is.fail()) return is;
1352 }
1353
1354 CHAR openBracket, closeBracket;
1355 is >> openBracket; if (is.fail()) return is;
1356 if (openBracket==CHAR('('))
1357 closeBracket = CHAR(')');
1358 else if (openBracket==CHAR('['))
1359 closeBracket = CHAR(']');
1360 else {
1361 closeBracket = CHAR(0);
1362 is.unget(); if (is.fail()) return is;
1363 }
1364
1365 // If we saw a "~" but then we didn't see any brackets, that's an
1366 // error. Set the fail bit and return.
1367 if (tilde != CHAR(0) && closeBracket == CHAR(0)) {
1368 is.setstate( std::ios::failbit );
1369 return is;
1370 }
1371
1372 for (int i=0; i < M; ++i) {
1373 is >> v[i];
1374 if (is.fail()) return is;
1375 if (i != M-1) {
1376 CHAR c; is >> c; if (is.fail()) return is;
1377 if (c != ',') is.unget();
1378 if (is.fail()) return is;
1379 }
1380 }
1381
1382 // Get the closing bracket if there was an opening one. If we don't
1383 // see the expected character we'll set the fail bit in the istream.
1384 if (closeBracket != CHAR(0)) {
1385 CHAR closer; is >> closer; if (is.fail()) return is;
1386 if (closer != closeBracket) {
1387 is.unget(); if (is.fail()) return is;
1388 is.setstate( std::ios::failbit );
1389 }
1390 }
1391
1392 return is;
1393}
1394
1395} //namespace SimTK
1396
1397
1398#endif //SimTK_SIMMATRIX_SMALLMATRIX_VEC_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
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
static const Vec & getAs(const ELT *p)
Recast an ordinary C++ array E[] to a const Vec<M,E,S>; assumes compatible length,...
Definition Vec.h:904
Vec & scalarMinusEq(const EE &ee)
Definition Vec.h:787
TSqrt sqrt() const
Elementwise square root; that is, the return value has the same length as this Vec but with each elem...
Definition Vec.h:337
bool isNumericallyEqual(const ELT &e, double tol=getDefaultTolerance()) const
Test whether every element of this vector is numerically equal to the given element,...
Definition Vec.h:977
void setToNaN()
Set every scalar in this Vec to NaN; this is the default initial value in Debug builds,...
Definition Vec.h:812
static Vec & updAs(ELT *p)
Recast a writable ordinary C++ array E[] to a writable Vec<M,E,S>; assumes compatible length,...
Definition Vec.h:908
CNT< E >::TStandard EStandard
Return type of standardize(E) method; a packed type that can hold the value of an element after elimi...
Definition Vec.h:221
Vec(const ENeg &ne)
Construction from a single value of this Vec's negated element type assigns that value to each elemen...
Definition Vec.h:476
TPosTrans & updPositionalTranspose()
Positional transpose returning a writable reference.
Definition Vec.h:674
Row< M, EHerm, STRIDE > THerm
Type of this Vec after casting to its Hermitian transpose; that is, the Vec turns into a Row and each...
Definition Vec.h:284
CNT< E >::TWithoutNegator EWithoutNegator
Element type, stripped of negator<> if it has one.
Definition Vec.h:195
CNT< E >::Number ENumber
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:230
CNT< E >::TNeg ENeg
Negated version of this Vec's element type; ENeg==negator< E >.
Definition Vec.h:193
bool isInf() const
Return true if any element of this Vec contains a +Infinity or -Infinity somewhere but no element con...
Definition Vec.h:927
Vec< M+1, ELT, 1 > append1(const EE &v) const
Return a vector one larger than this one by adding an element to the end.
Definition Vec.h:877
ELT E
Element type of this Vec.
Definition Vec.h:191
Row< M, E, STRIDE > TPosTrans
Type of this Vec after casting to its positional transpose; that is, the Vec turns into a Row but the...
Definition Vec.h:287
Vec< M, E, STRIDE > T
The type of this Vec.
Definition Vec.h:265
void setToZero()
Set every scalar in this Vec to zero.
Definition Vec.h:817
Vec & operator=(const Vec &src)
Copy assignment operator copies the logically-included elements from the source Vec; gaps due to stri...
Definition Vec.h:445
EScalar Scalar
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:308
bool isNaN() const
Return true if any element of this Vec contains a NaN anywhere.
Definition Vec.h:918
Mat< M, M, typename CNT< E >::template Result< EE >::Mul > conformingMultiply(const Row< M, EE, SS > &r) const
Same as outer product (m = col*row) – use operator* or outer() instead.
Definition Vec.h:572
std::string toString() const
Print Vec into a string and return it.
Definition Vec.h:988
Vec & operator-=(const EE &e)
Definition Vec.h:777
CNT< E >::StdNumber EStdNumber
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:231
E TElement
Element type of this Vec.
Definition Vec.h:289
Vec & scalarPlusEq(const EE &ee)
Definition Vec.h:785
TInvert invert() const
This method is not supported for Vec objects.
Definition Vec.h:635
E & operator()(int i)
Same as non-const operator[] above.
Definition Vec.h:606
CNT< ScalarNormSq >::TSqrt norm() const
Definition Vec.h:610
Vec< M, typename CNT< E >::template Result< EE >::Dvd > scalarDivide(const EE &e) const
Definition Vec.h:739
Vec< M, EComplex, STRIDE > TComplex
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:280
Vec TCol
Type of a column of this CNT object (for a Vec, the whole thing).
Definition Vec.h:293
Vec< M, typename CNT< E >::template Result< EE >::Mul > elementwiseMultiply(const Vec< M, EE, SS > &r) const
Elementwise multiply (Matlab " .* " operator).
Definition Vec.h:580
Vec & scalarMinusEqFromLeft(int ee)
Definition Vec.h:806
const E & get(int i) const
Variant of operator[] that's scripting friendly to get const reference to ith entry.
Definition Vec.h:999
Vec< M, typename CNT< E >::template Result< EE >::Add > scalarAdd(const EE &e) const
Definition Vec.h:752
Vec< M, EAbs, 1 > TAbs
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:298
const TReal & real() const
Return a reference to the real portion of this Vec if it has complex elements; otherwise the type doe...
Definition Vec.h:681
Vec< M, typename CNT< EE >::template Result< E >::Sub > scalarSubtractFromLeft(const EE &e) const
Definition Vec.h:766
CNT< E >::ULessScalar EULessScalar
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:229
bool isFinite() const
Return true if no element of this Vec contains an Infinity or a NaN anywhere.
Definition Vec.h:942
Vec(const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5)
Definition Vec.h:499
Vec & operator=(const EE *p)
Assignment to a pointer to elements of any type EE assumes we're pointing at a C++ array of EE's of t...
Definition Vec.h:523
CNT< E >::TNormalize ENormalize
Packed type that can hold the value returned from normalize(E).
Definition Vec.h:226
static int ncol()
The number of columns in a Vec is always 1.
Definition Vec.h:322
TNeg & updNegate()
Non-operator version of unary negation; recasts and returns a writable reference.
Definition Vec.h:659
Vec & operator=(const Vec< M, EE, SS > &vv)
Assignment to a conforming Vec, of any element type and stride, provided that the element types are a...
Definition Vec.h:528
Vec(const Vec< M, ENeg, SS > &src)
This is an implicit conversion from a Vec of the same length and negated element type (possibly with ...
Definition Vec.h:458
Vec< M-1, ELT, 1 > drop1(int p) const
Return a vector one smaller than this one by dropping the element at the indicated position p.
Definition Vec.h:863
Vec(int i)
Given an int value, turn it into a suitable floating point number, convert that to element type E and...
Definition Vec.h:485
Vec(const E &e0, const E &e1)
Construct a Vec<2,E> from two elements of type E, etc.
Definition Vec.h:490
Vec(const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5, const E &e6)
Definition Vec.h:502
Vec< M, EWithoutNegator, STRIDE > TWithoutNegator
Type of this Vec with negator removed from its element type, if the element is negated.
Definition Vec.h:271
Vec< M, ENormalize, 1 > TNormalize
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:301
Vec< M, typename CNT< EE >::template Result< E >::Mul > scalarMultiplyFromLeft(const EE &e) const
Definition Vec.h:730
TImag & imag()
Recast to show only the imaginary portion of this Vec and return a writable reference.
Definition Vec.h:699
Vec & scalarTimesEqFromLeft(int ee)
Definition Vec.h:807
Vec< M, typename CNT< E >::template Result< EE >::Sub > conformingSubtract(const Vec< M, EE, SS > &r) const
Vector subtraction – use operator- instead.
Definition Vec.h:563
TWithoutNegator & updCastAwayNegatorIfAny()
Recast to remove negators from this Vec's type if present and return a writable reference.
Definition Vec.h:712
static const Vec & getSubVec(const Vec< MM, ELT, STRIDE > &v, int i)
Extract a subvector of type Vec from a longer one that has the same element type and stride,...
Definition Vec.h:847
Vec & operator+=(const EE &e)
Definition Vec.h:776
Vec< M, ESqrt, 1 > TSqrt
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:297
Vec(const E &e0, const E &e1, const E &e2)
Definition Vec.h:492
THerm & operator~()
Recast to Hermitian transposed type and return a writable reference; the effect is that writing to el...
Definition Vec.h:653
Vec(const E &e0, const E &e1, const E &e2, const E &e3)
Definition Vec.h:494
Vec & operator-=(const Vec< M, negator< EE >, SS > &r)
Subtract off a conforming Vec, of any negated element type and stride, provided that the element type...
Definition Vec.h:548
ScalarNormSq scalarNormSqr() const
Scalar norm square is sum( conjugate squares of all underlying scalars ), where conjugate square of s...
Definition Vec.h:327
Vec & scalarMinusEq(int ee)
Definition Vec.h:803
Vec< M, typename CNT< E >::template Result< EE >::Dvd > elementwiseDivide(const Vec< M, EE, SS > &r) const
Elementwise divide (Matlab " ./ " operator).
Definition Vec.h:587
Vec(const E &e0, const E &e1, const E &e2, const E &e3, const E &e4)
Definition Vec.h:496
static double getDefaultTolerance()
For approximate comparisons, the default tolerance to use for a vector is the same as its elements' d...
Definition Vec.h:951
TNormalize normalize() const
If the elements of this Vec are scalars, the result is what you get by dividing each element by the n...
Definition Vec.h:623
Vec()
Default construction initializes Vec's elements to NaN when debugging but leaves them uninitialized g...
Definition Vec.h:425
const TWithoutNegator & castAwayNegatorIfAny() const
Recast to remove negators from this Vec's type if present; this is handy for simplifying operations w...
Definition Vec.h:708
static Vec< M, ELT, 1 > getNaN()
Return a Vec of the same length and element type as this one but with all elements set to NaN.
Definition Vec.h:915
Vec< M, typename CNT< E >::template Result< EE >::Add > conformingAdd(const Vec< M, EE, SS > &r) const
Vector addition – use operator+ instead.
Definition Vec.h:556
Vec & scalarEq(const EE &ee)
Definition Vec.h:783
bool isNumericallyEqual(const Vec< M, E2, RS2 > &v, double tol) const
Test whether this vector is numerically equal to some other vector with the same shape,...
Definition Vec.h:956
Vec< M, typename CNT< E >::template Result< EE >::Sub > scalarSubtract(const EE &e) const
Definition Vec.h:760
ScalarNormSq normSqr() const
Definition Vec.h:608
EStandard sum() const
Sum just adds up all the elements into a single return element that is the same type as this Vec's el...
Definition Vec.h:366
TStandard standardize() const
Return a copy of this Vec but with the underlying scalar type converted (if necessary) to one of the ...
Definition Vec.h:357
Vec< M, typename CNT< EE >::template Result< E >::Dvd > scalarDivideFromLeft(const EE &e) const
Definition Vec.h:745
Vec & scalarMinusEqFromLeft(const EE &ee)
Definition Vec.h:789
const TNeg & negate() const
Non-operator version of unary negation; just a recast.
Definition Vec.h:656
void set(int i, const E &value)
Variant of operator[] that's scripting friendly to set ith entry.
Definition Vec.h:995
CNT< E >::TAbs EAbs
Type required to hold the result of abs(E).
Definition Vec.h:218
Vec & scalarDivideEqFromLeft(int ee)
Definition Vec.h:808
const TNeg & operator-() const
Unary minus recasts this Vec to a type that has the opposite interpretation of the sign but is otherw...
Definition Vec.h:642
Vec & scalarDivideEq(const EE &ee)
Definition Vec.h:795
Vec & operator+=(const Vec< M, EE, SS > &r)
Add in a conforming Vec, of any element type and stride, provided that the element types are addition...
Definition Vec.h:533
static int nrow()
The number of rows in a Vec is the number of elements.
Definition Vec.h:320
Vec & scalarTimesEq(int ee)
Definition Vec.h:804
Vec(const EE *p)
Construction from a pointer to elements of any type EE assumes we're pointing at a C++ array of EE's ...
Definition Vec.h:516
CNT< E >::TSqHermT ESqHermT
Type of the expression ~E*E (default vector and matrix square; symmetric).
Definition Vec.h:212
CNT< E >::TReal EReal
Type showing just the real part of an element of this Vec if elements are complex; otherwise just the...
Definition Vec.h:198
THerm & updTranspose()
Non-operator version of Hermitian transpose; recasts and returns a writable reference.
Definition Vec.h:665
CNT< E >::TComplex EComplex
Type that elements would have if complex, if E is currently real; otherwise just the element type E.
Definition Vec.h:205
CNT< E >::TPosTrans EPosTrans
Type of a positional transpose of an element of this Vec.
Definition Vec.h:209
Vec & operator+=(const Vec< M, negator< EE >, SS > &r)
Add in a conforming Vec, of any negated element type and stride, provided that the element types are ...
Definition Vec.h:538
static Vec & updSubVec(Vec< MM, ELT, STRIDE > &v, int i)
Extract a subvector of type Vec from a longer one that has the same element type and stride,...
Definition Vec.h:855
TReal & real()
Recast to show only the real portion of this Vec and return a writable reference.
Definition Vec.h:684
CNT< E >::Precision EPrecision
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:232
ESqHermT TSqHermT
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:303
CNT< E >::ScalarNormSq EScalarNormSq
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:233
Vec(const E &e)
Construction from a single value of this Vec's element type assigns that value to each element.
Definition Vec.h:470
const TImag & imag() const
Return a reference to the imaginary portion of this Vec if it has complex elements; otherwise the typ...
Definition Vec.h:692
Vec & scalarDivideEqFromLeft(const EE &ee)
Definition Vec.h:797
Vec & operator*=(const EE &e)
Definition Vec.h:778
Vec< M, typename CNT< E >::template Result< EE >::Mul > scalarMultiply(const EE &e) const
Definition Vec.h:724
EScalarNormSq ScalarNormSq
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:313
@ SignInterpretation
Definition Vec.h:257
@ IsStdNumber
Definition Vec.h:255
@ IsULessScalar
Definition Vec.h:253
@ NRows
Definition Vec.h:239
@ ArgDepth
Definition Vec.h:249
@ RealStrideFactor
Definition Vec.h:247
@ ColSpacing
Definition Vec.h:245
@ NPackedElements
Definition Vec.h:241
@ IsNumber
Definition Vec.h:254
@ IsPrecision
Definition Vec.h:256
@ RowSpacing
Definition Vec.h:244
@ NActualElements
Definition Vec.h:242
@ NCols
Definition Vec.h:240
@ ImagOffset
Definition Vec.h:246
@ IsScalar
Definition Vec.h:252
@ NActualScalars
Definition Vec.h:243
CNT< E >::TImag EImag
Type showing the imaginary part of an element of this Vec as real, if elements are complex; otherwise...
Definition Vec.h:202
const TPosTrans & positionalTranspose() const
Positional transpose turns this Vec into a Row but does not transpose the individual elements.
Definition Vec.h:671
TNeg & operator-()
Recast to negated type and return a writable reference; writing to this will cause the negated result...
Definition Vec.h:645
EULessScalar ULessScalar
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:309
const E & operator[](int i) const
Select an element of this Vec and return a const reference to it.
Definition Vec.h:596
Vec< M, EImag, STRIDE *CNT< E >::RealStrideFactor > TImag
Type of this Vec cast to show only the imaginary part of its element; this might affect the stride.
Definition Vec.h:279
Vec & scalarDivideEq(int ee)
Definition Vec.h:805
Vec< M, EStandard, 1 > TStandard
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:299
ENumber Number
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:310
Vec(const Vec &src)
Copy constructor copies the logically-included elements from the source Vec; gaps due to stride are n...
Definition Vec.h:438
Vec< MM, ELT, STRIDE > & updSubVec(int i)
Extract a writable reference to a sub-Vec with size known at compile time.
Definition Vec.h:837
Vec(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 Vec.h:508
Vec(const Vec< M, E, SS > &src)
This is an implicit conversion from a Vec of the same length and element type but with a different st...
Definition Vec.h:452
Vec< M+1, ELT, 1 > insert1(int p, const EE &v) const
Return a vector one larger than this one by inserting an element before the indicated one.
Definition Vec.h:890
CNT< E >::TSqrt ESqrt
Type required to hold the result of sqrt(E).
Definition Vec.h:216
const THerm & operator~() const
The Hermitian transpose operator recasts this Vec to a type that specifies the opposite storage order...
Definition Vec.h:649
Vec< M, ENeg, STRIDE > TNeg
Type this Vec would have if its elements were interpreted as negated.
Definition Vec.h:268
Vec(const Vec< M, EE, SS > &src)
Construct a Vec from a Vec of the same length, with any stride.
Definition Vec.h:464
TAbs abs() const
Elementwise absolute value; that is, the return value has the same dimension as this Vec but with eac...
Definition Vec.h:347
bool isNumericallyEqual(const Vec< M, E2, RS2 > &v) const
Test whether this vector is numerically equal to some other vector with the same shape,...
Definition Vec.h:967
static int size()
The number of elements in this Vec (note that stride does not affect this number.)
Definition Vec.h:318
Row< M, EInvert, 1 > TInvert
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:300
E TRow
Type of a row of this CNT object (for a Vec, just its element type).
Definition Vec.h:291
const Vec & operator+() const
Unary plus does nothing.
Definition Vec.h:638
const E & operator()(int i) const
Same as const operator[] above.
Definition Vec.h:599
Vec(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 Vec.h:505
Vec & scalarTimesEqFromLeft(const EE &ee)
Definition Vec.h:793
Vec & scalarTimesEq(const EE &ee)
Definition Vec.h:791
E & operator[](int i)
Select an element of this Vec and return a writable reference to it.
Definition Vec.h:604
Vec & scalarPlusEq(int ee)
Definition Vec.h:802
Vec & operator-=(const Vec< M, EE, SS > &r)
Subtract off a conforming Vec, of any element type and stride, provided that the element types are ad...
Definition Vec.h:543
Vec & operator/=(const EE &e)
Definition Vec.h:779
Vec< M, EReal, STRIDE *CNT< E >::RealStrideFactor > TReal
Type of this Vec cast to show only the real part of its element; this might affect the stride.
Definition Vec.h:275
EStdNumber StdNumber
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:311
CNT< E >::TSqTHerm ESqTHerm
Type of the expression E*~E ("row square"; symmetric).
Definition Vec.h:214
CNT< E >::TInvert EInvert
Packed type that can hold the value returned from invert(E), the inverse type of an element.
Definition Vec.h:224
const Vec< MM, ELT, STRIDE > & getSubVec(int i) const
Extract a const reference to a sub-Vec with size known at compile time.
Definition Vec.h:827
CNT< E >::THerm EHerm
Type of the Hermitian transpose of an element of this Vec.
Definition Vec.h:207
EPrecision Precision
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:312
Vec & scalarEq(int ee)
Definition Vec.h:801
const THerm & transpose() const
Non-operator version of Hermitian transpose; just a recast.
Definition Vec.h:662
SymMat< M, ESqTHerm > TSqTHerm
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:304
CNT< E >::Scalar EScalar
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:228
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
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
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 Vec.h:377
Vec< M, typename CNT< E >::template Result< P >::Sub, 1 > Sub
Definition Vec.h:381
Vec< M, typename CNT< E >::template Result< P >::Mul, 1 > Mul
Definition Vec.h:378
Vec< M, typename CNT< E >::template Result< P >::Dvd, 1 > Dvd
Definition Vec.h:379
Vec< M, typename CNT< E >::template Result< P >::Add, 1 > Add
Definition Vec.h:380
Definition Vec.h:386
DvdOp::Type Dvd
Definition Vec.h:400
MulCNTsNonConforming< M, 1, ArgDepth, Vec, ColSpacing, RowSpacing, CNT< P >::NRows, CNT< P >::NCols, CNT< P >::ArgDepth, P, CNT< P >::ColSpacing, CNT< P >::RowSpacing > MulOpNonConforming
Definition Vec.h:394
DvdCNTs< M, 1, ArgDepth, Vec, ColSpacing, RowSpacing, CNT< P >::NRows, CNT< P >::NCols, CNT< P >::ArgDepth, P, CNT< P >::ColSpacing, CNT< P >::RowSpacing > DvdOp
Definition Vec.h:399
AddCNTs< M, 1, ArgDepth, Vec, ColSpacing, RowSpacing, CNT< P >::NRows, CNT< P >::NCols, CNT< P >::ArgDepth, P, CNT< P >::ColSpacing, CNT< P >::RowSpacing > AddOp
Definition Vec.h:404
MulOp::Type Mul
Definition Vec.h:390
MulCNTs< M, 1, ArgDepth, Vec, ColSpacing, RowSpacing, CNT< P >::NRows, CNT< P >::NCols, CNT< P >::ArgDepth, P, CNT< P >::ColSpacing, CNT< P >::RowSpacing > MulOp
Definition Vec.h:389
AddOp::Type Add
Definition Vec.h:405
SubCNTs< M, 1, ArgDepth, Vec, ColSpacing, RowSpacing, CNT< P >::NRows, CNT< P >::NCols, CNT< P >::ArgDepth, P, CNT< P >::ColSpacing, CNT< P >::RowSpacing > SubOp
Definition Vec.h:409
MulOpNonConforming::Type MulNon
Definition Vec.h:395
SubOp::Type Sub
Definition Vec.h:410
Shape-preserving element substitution (always packed).
Definition Vec.h:418
Vec< M, P > Type
Definition Vec.h:419