Simbody 3.9
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
33#include <tuple>
34
35namespace SimTK {
36
37
38// The following functions are used internally by Vec.
39
40// Hide from Doxygen.
42namespace Impl {
43
44// For those wimpy compilers that don't unroll short, constant-limit loops,
45// Peter Eastman added these recursive template implementations of
46// elementwise add, subtract, and copy. Sherm added multiply and divide.
47
48template <class E1, int S1, class E2, int S2> void
49conformingAdd(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2,
50 Vec<1,typename CNT<E1>::template Result<E2>::Add>& result) {
51 result[0] = r1[0] + r2[0];
52}
53template <int N, class E1, int S1, class E2, int S2> void
54conformingAdd(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2,
55 Vec<N,typename CNT<E1>::template Result<E2>::Add>& result) {
56 conformingAdd(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1),
57 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2),
58 reinterpret_cast<Vec<N-1,typename CNT<E1>::
59 template Result<E2>::Add>&>(result));
60 result[N-1] = r1[N-1] + r2[N-1];
61}
62
63template <class E1, int S1, class E2, int S2> void
64conformingSubtract(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2,
65 Vec<1,typename CNT<E1>::template Result<E2>::Sub>& result) {
66 result[0] = r1[0] - r2[0];
67}
68template <int N, class E1, int S1, class E2, int S2> void
69conformingSubtract(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2,
70 Vec<N,typename CNT<E1>::template Result<E2>::Sub>& result) {
71 conformingSubtract(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1),
72 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2),
73 reinterpret_cast<Vec<N-1,typename CNT<E1>::
74 template Result<E2>::Sub>&>(result));
75 result[N-1] = r1[N-1] - r2[N-1];
76}
77
78template <class E1, int S1, class E2, int S2> void
79elementwiseMultiply(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2,
80 Vec<1,typename CNT<E1>::template Result<E2>::Mul>& result) {
81 result[0] = r1[0] * r2[0];
82}
83template <int N, class E1, int S1, class E2, int S2> void
84elementwiseMultiply(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2,
85 Vec<N,typename CNT<E1>::template Result<E2>::Mul>& result) {
86 elementwiseMultiply(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1),
87 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2),
88 reinterpret_cast<Vec<N-1,typename CNT<E1>::
89 template Result<E2>::Mul>&>(result));
90 result[N-1] = r1[N-1] * r2[N-1];
91}
92
93template <class E1, int S1, class E2, int S2> void
94elementwiseDivide(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2,
95 Vec<1,typename CNT<E1>::template Result<E2>::Dvd>& result) {
96 result[0] = r1[0] / r2[0];
97}
98template <int N, class E1, int S1, class E2, int S2> void
99elementwiseDivide(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2,
100 Vec<N,typename CNT<E1>::template Result<E2>::Dvd>& result) {
101 elementwiseDivide(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1),
102 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2),
103 reinterpret_cast<Vec<N-1,typename CNT<E1>::
104 template Result<E2>::Dvd>&>(result));
105 result[N-1] = r1[N-1] / r2[N-1];
106}
107
108template <class E1, int S1, class E2, int S2> void
109copy(Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2) {
110 r1[0] = r2[0];
111}
112template <int N, class E1, int S1, class E2, int S2> void
113copy(Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2) {
114 copy(reinterpret_cast<Vec<N-1,E1,S1>&>(r1),
115 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2));
116 r1[N-1] = r2[N-1];
117}
118
119}
185template <int M, class ELT, int STRIDE>
186class Vec {
187public:
193 typedef ELT E;
195 typedef typename CNT<E>::TNeg ENeg;
200 typedef typename CNT<E>::TReal EReal;
204 typedef typename CNT<E>::TImag EImag;
207 typedef typename CNT<E>::TComplex EComplex;
209 typedef typename CNT<E>::THerm EHerm;
211 typedef typename CNT<E>::TPosTrans EPosTrans;
214 typedef typename CNT<E>::TSqHermT ESqHermT;
216 typedef typename CNT<E>::TSqTHerm ESqTHerm;
218 typedef typename CNT<E>::TSqrt ESqrt;
220 typedef typename CNT<E>::TAbs EAbs;
223 typedef typename CNT<E>::TStandard EStandard;
226 typedef typename CNT<E>::TInvert EInvert;
229
230 typedef typename CNT<E>::Scalar EScalar;
232 typedef typename CNT<E>::Number ENumber;
236
239 #ifndef SWIG
240 enum {
241 NRows = M,
242 NCols = 1,
244 NActualElements = (M-1)*STRIDE + 1, // no trailing gap
249 RealStrideFactor = 1, // composite types don't change size when
250 // cast from complex to real or imaginary
252 ? CNT<E>::ArgDepth + 1
260 };
261 #endif
262
263 // These are reinterpretations of the current data, so have the
264 // same packing (stride).
265
291 typedef E TElement;
293 typedef E TRow;
295 typedef Vec TCol;
296
297 // These are the results of calculations, so are returned in new, packed
298 // memory. Be sure to refer to element types here which are also packed.
299 typedef Vec<M,ESqrt,1> TSqrt; // Note stride
300 typedef Vec<M,EAbs,1> TAbs; // Note stride
304
305 typedef ESqHermT TSqHermT; // result of self dot product
306 typedef SymMat<M,ESqTHerm> TSqTHerm; // result of self outer product
307
308 // These recurse right down to the underlying scalar type no matter how
309 // deep the elements are.
320 static int size() { return M; }
322 static int nrow() { return M; }
324 static int ncol() { return 1; }
325
326
330 ScalarNormSq sum(0);
332 return sum;
333 }
334
339 TSqrt sqrt() const {
340 TSqrt vsqrt;
342 return vsqrt;
343 }
344
350 TAbs vabs;
352 return vabs;
353 }
354
362 return vstd;
363 }
364
368 EStandard sum() const {
369 E sum(0);
370 for (int i=0;i<M;++i) sum += d[i*STRIDE];
371 return CNT<E>::standardize(sum);
372 }
373
374
375 // This gives the resulting vector type when (v[i] op P) is applied to
376 // each element of v. It is a vector of length M, stride 1, and element
377 // types which are the regular composite result of E op P. Typically P is
378 // a scalar type but it doesn't have to be.
385
386 // This is the composite result for v op P where P is some kind of
387 // appropriately shaped non-scalar type.
414
420 template <class P> struct Substitute {
421 typedef Vec<M,P> Type;
422 };
423
427 constexpr Vec(){
428 #ifndef NDEBUG
429 setToNaN();
430 #endif
431 }
432
433 // It's important not to use the default copy constructor or copy
434 // assignment because the compiler doesn't understand that we may
435 // have noncontiguous storage and will try to copy the whole array.
436
440 constexpr Vec(const Vec& src) {
441 assignElementsFromVec(src);
442 }
447 constexpr Vec& operator=(const Vec& src) {
448 assignElementsFromVec(src);
449 return *this;
450 }
451
454 template <int SS>
455 constexpr Vec(const Vec<M,E,SS>& src) {
456 assignElementsFromVec(src);
457 }
458
461 template <int SS>
462 constexpr Vec(const Vec<M,ENeg,SS>& src) {
463 assignElementsFromVec(src);
464 }
465
468 template <class EE, int SS>
469 explicit constexpr Vec(const Vec<M,EE,SS>& src) {
470 assignElementsFromVec(src);
471 }
472
475 explicit constexpr Vec(const E& e) {for (int i=0;i<M;++i) d[i*STRIDE]=e;}
476
481 explicit constexpr Vec(const ENeg& ne) {
482 const E e = ne; // requires floating point negation
483 for (int i=0;i<M;++i) d[i*STRIDE]=e;
484 }
485
490 explicit Vec(int i) {new (this) Vec(E(Precision(i)));}
491
492 // A bevy of constructors for Vecs up to length 9.
493
495 constexpr Vec(const E& e0, const E& e1)
496 requires (M == 2)
497 { assignElements(e0, e1);}
498
499 constexpr Vec(const E& e0, const E& e1, const E& e2)
500 requires (M == 3)
501 { assignElements(e0, e1, e2); }
502
503 constexpr Vec(const E& e0, const E& e1, const E& e2, const E& e3)
504 requires (M == 4)
505 { assignElements(e0, e1, e2, e3); }
506
507 constexpr Vec(
508 const E& e0,
509 const E& e1,
510 const E& e2,
511 const E& e3,
512 const E& e4)
513 requires (M == 5)
514 { assignElements(e0, e1, e2, e3, e4); }
515
516 constexpr Vec(
517 const E& e0,
518 const E& e1,
519 const E& e2,
520 const E& e3,
521 const E& e4,
522 const E& e5)
523 requires (M == 6)
524 { assignElements(e0, e1, e2, e3, e4, e5); }
525
526 constexpr Vec(
527 const E& e0,
528 const E& e1,
529 const E& e2,
530 const E& e3,
531 const E& e4,
532 const E& e5,
533 const E& e6)
534 requires (M == 7)
535 { assignElements(e0, e1, e2, e3, e4, e5, e6); }
536
537 constexpr Vec(
538 const E& e0,
539 const E& e1,
540 const E& e2,
541 const E& e3,
542 const E& e4,
543 const E& e5,
544 const E& e6,
545 const E& e7)
546 requires (M == 8)
547 { assignElements(e0, e1, e2, e3, e4, e5, e6, e7); }
548
549 constexpr Vec(
550 const E& e0,
551 const E& e1,
552 const E& e2,
553 const E& e3,
554 const E& e4,
555 const E& e5,
556 const E& e6,
557 const E& e7,
558 const E& e8)
559 requires (M == 9)
560 { assignElements(e0, e1, e2, e3, e4, e5, e6, e7, e8); }
561
566 template <class EE> explicit Vec(const EE* p)
567 { assert(p); for(int i=0;i<M;++i) d[i*STRIDE]=p[i]; }
568
573 template <class EE> Vec& operator=(const EE* p)
574 { assert(p); for(int i=0;i<M;++i) d[i*STRIDE]=p[i]; return *this; }
575
578 template <class EE, int SS> Vec& operator=(const Vec<M,EE,SS>& vv)
579 { Impl::copy(*this, vv); return *this; }
580
583 template <class EE, int SS> Vec& operator+=(const Vec<M,EE,SS>& r)
584 { for(int i=0;i<M;++i) d[i*STRIDE] += r[i]; return *this; }
588 template <class EE, int SS> Vec& operator+=(const Vec<M,negator<EE>,SS>& r)
589 { for(int i=0;i<M;++i) d[i*STRIDE] -= -(r[i]); return *this; }
590
593 template <class EE, int SS> Vec& operator-=(const Vec<M,EE,SS>& r)
594 { for(int i=0;i<M;++i) d[i*STRIDE] -= r[i]; return *this; }
598 template <class EE, int SS> Vec& operator-=(const Vec<M,negator<EE>,SS>& r)
599 { for(int i=0;i<M;++i) d[i*STRIDE] += -(r[i]); return *this; }
600
601 // Conforming binary ops with 'this' on left, producing new packed result.
602 // Cases: v=v+v, v=v-v, m=v*r
603
605 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Add>
608 Impl::conformingAdd(*this, r, result);
609 return result;
610 }
612 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Sub>
615 Impl::conformingSubtract(*this, r, result);
616 return result;
617 }
618
621 template <class EE, int SS> Mat<M,M,typename CNT<E>::template Result<EE>::Mul>
624 for (int j=0;j<M;++j) result(j) = scalarMultiply(r(j));
625 return result;
626 }
627
629 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Mul>
632 Impl::elementwiseMultiply(*this, r, result);
633 return result;
634 }
636 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Dvd>
639 Impl::elementwiseDivide(*this, r, result);
640 return result;
641 }
642
646 constexpr const E& operator[](int i) const
647 { assert(0 <= i && i < M); return d[i*STRIDE]; }
649 constexpr const E& operator()(int i) const {return (*this)[i];}
650
654 constexpr E& operator[](int i) {assert(0 <= i && i < M); return d[i*STRIDE];}
656 constexpr E& operator()(int i) {return (*this)[i];}
657
658 ScalarNormSq normSqr() const { return scalarNormSqr(); }
661
674 if (CNT<E>::IsScalar) {
676 } else {
678 for (int i=0; i<M; ++i)
681 }
682 }
683
685 SimTK_NODISCARD TInvert invert() const {assert(false); return TInvert();} // TODO default inversion
686
688 const Vec& operator+() const { return *this; }
692 const TNeg& operator-() const { return negate(); }
695 TNeg& operator-() { return updNegate(); }
699 const THerm& operator~() const { return transpose(); }
703 THerm& operator~() { return updTranspose(); }
704
706 SimTK_NODISCARD const TNeg& negate() const { return *reinterpret_cast<const TNeg*>(this); }
709 TNeg& updNegate() { return *reinterpret_cast< TNeg*>(this); }
710
712 SimTK_NODISCARD const THerm& transpose() const { return *reinterpret_cast<const THerm*>(this); }
715 THerm& updTranspose() { return *reinterpret_cast< THerm*>(this); }
716
722 { return *reinterpret_cast<const TPosTrans*>(this); }
725 { return *reinterpret_cast<TPosTrans*>(this); }
726
731 const TReal& real() const { return *reinterpret_cast<const TReal*>(this); }
734 TReal& real() { return *reinterpret_cast< TReal*>(this); }
735
736 // Had to contort these next two routines to get them through VC++ 7.net
737
742 const TImag& imag() const {
743 const int offs = ImagOffset;
744 const EImag* p = reinterpret_cast<const EImag*>(this);
745 return *reinterpret_cast<const TImag*>(p+offs);
746 }
750 const int offs = ImagOffset;
751 EImag* p = reinterpret_cast<EImag*>(this);
752 return *reinterpret_cast<TImag*>(p+offs);
753 }
754
759 { return *reinterpret_cast<const TWithoutNegator*>(this); }
763 { return *reinterpret_cast<TWithoutNegator*>(this); }
764
765 // These are elementwise binary operators, (this op ee) by default but
766 // (ee op this) if 'FromLeft' appears in the name. The result is a packed
767 // Vec<M> but the element type may change. These are mostly used to
768 // implement global operators. We call these "scalar" operators but
769 // actually the "scalar" can be a composite type.
770
771 //TODO: consider converting 'e' to Standard Numbers as precalculation and
772 // changing return type appropriately.
774 scalarMultiply(const EE& e) const {
776 for (int i=0; i<M; ++i) result[i] = (*this)[i] * e;
777 return result;
778 }
780 scalarMultiplyFromLeft(const EE& e) const {
782 for (int i=0; i<M; ++i) result[i] = e * (*this)[i];
783 return result;
784 }
785
786 // TODO: should precalculate and store 1/e, while converting to Standard
787 // Numbers. Note that return type should change appropriately.
789 scalarDivide(const EE& e) const {
791 for (int i=0; i<M; ++i) result[i] = (*this)[i] / e;
792 return result;
793 }
795 scalarDivideFromLeft(const EE& e) const {
797 for (int i=0; i<M; ++i) result[i] = e / (*this)[i];
798 return result;
799 }
800
802 scalarAdd(const EE& e) const {
804 for (int i=0; i<M; ++i) result[i] = (*this)[i] + e;
805 return result;
806 }
807 // Add is commutative, so no 'FromLeft'.
808
810 scalarSubtract(const EE& e) const {
812 for (int i=0; i<M; ++i) result[i] = (*this)[i] - e;
813 return result;
814 }
816 scalarSubtractFromLeft(const EE& e) const {
818 for (int i=0; i<M; ++i) result[i] = e - (*this)[i];
819 return result;
820 }
821
822 // Generic assignments for any element type not listed explicitly, including scalars.
823 // These are done repeatedly for each element and only work if the operation can
824 // be performed leaving the original element type.
825 template <class EE> Vec& operator =(const EE& e) {return scalarEq(e);}
826 template <class EE> Vec& operator+=(const EE& e) {return scalarPlusEq(e);}
827 template <class EE> Vec& operator-=(const EE& e) {return scalarMinusEq(e);}
828 template <class EE> Vec& operator*=(const EE& e) {return scalarTimesEq(e);}
829 template <class EE> Vec& operator/=(const EE& e) {return scalarDivideEq(e);}
830
831 // Generalized element assignment & computed assignment methods. These will work
832 // for any assignment-compatible element, not just scalars.
833 template <class EE> Vec& scalarEq(const EE& ee)
834 { for(int i=0;i<M;++i) d[i*STRIDE] = ee; return *this; }
835 template <class EE> Vec& scalarPlusEq(const EE& ee)
836 { for(int i=0;i<M;++i) d[i*STRIDE] += ee; return *this; }
837 template <class EE> Vec& scalarMinusEq(const EE& ee)
838 { for(int i=0;i<M;++i) d[i*STRIDE] -= ee; return *this; }
839 template <class EE> Vec& scalarMinusEqFromLeft(const EE& ee)
840 { for(int i=0;i<M;++i) d[i*STRIDE] = ee - d[i*STRIDE]; return *this; }
841 template <class EE> Vec& scalarTimesEq(const EE& ee)
842 { for(int i=0;i<M;++i) d[i*STRIDE] *= ee; return *this; }
843 template <class EE> Vec& scalarTimesEqFromLeft(const EE& ee)
844 { for(int i=0;i<M;++i) d[i*STRIDE] = ee * d[i*STRIDE]; return *this; }
845 template <class EE> Vec& scalarDivideEq(const EE& ee)
846 { for(int i=0;i<M;++i) d[i*STRIDE] /= ee; return *this; }
847 template <class EE> Vec& scalarDivideEqFromLeft(const EE& ee)
848 { for(int i=0;i<M;++i) d[i*STRIDE] = ee / d[i*STRIDE]; return *this; }
849
850 // Specialize for int to avoid warnings and ambiguities.
851 Vec& scalarEq(int ee) {return scalarEq(Precision(ee));}
859
862 void setToNaN() {
863 (*this) = CNT<ELT>::getNaN();
864 }
865
867 void setToZero() {
868 (*this) = ELT(0);
869 }
870
876 template <int MM>
877 const Vec<MM,ELT,STRIDE>& getSubVec(int i) const {
878 assert(0 <= i && i + MM <= M);
879 return Vec<MM,ELT,STRIDE>::getAs(&(*this)[i]);
880 }
886 template <int MM>
888 assert(0 <= i && i + MM <= M);
889 return Vec<MM,ELT,STRIDE>::updAs(&(*this)[i]);
890 }
891
892
896 template <int MM>
897 static const Vec& getSubVec(const Vec<MM,ELT,STRIDE>& v, int i) {
898 assert(0 <= i && i + M <= MM);
899 return getAs(&v[i]);
900 }
904 template <int MM>
906 assert(0 <= i && i + M <= MM);
907 return updAs(&v[i]);
908 }
909
913 Vec<M-1,ELT,1> drop1(int p) const {
914 assert(0 <= p && p < M);
915 Vec<M-1,ELT,1> out;
916 int nxt=0;
917 for (int i=0; i<M-1; ++i, ++nxt) {
918 if (nxt==p) ++nxt; // skip the loser
919 out[i] = (*this)[nxt];
920 }
921 return out;
922 }
923
927 template <class EE> Vec<M+1,ELT,1> append1(const EE& v) const {
929 Vec<M,ELT,1>::updAs(&out[0]) = (*this);
930 out[M] = v;
931 return out;
932 }
933
934
940 template <class EE> Vec<M+1,ELT,1> insert1(int p, const EE& v) const {
941 assert(0 <= p && p <= M);
942 if (p==M) return append1(v);
944 int nxt=0;
945 for (int i=0; i<M; ++i, ++nxt) {
946 if (i==p) out[nxt++] = v;
947 out[nxt] = (*this)[i];
948 }
949 return out;
950 }
951
954 static const Vec& getAs(const ELT* p)
955 { return *reinterpret_cast<const Vec*>(p); }
958 static Vec& updAs(ELT* p)
959 { return *reinterpret_cast<Vec*>(p); }
960
961
966
968 bool isNaN() const {
969 for (int i=0; i<M; ++i)
970 if (CNT<ELT>::isNaN((*this)[i]))
971 return true;
972 return false;
973 }
974
977 bool isInf() const {
978 bool seenInf = false;
979 for (int i=0; i<M; ++i) {
980 const ELT& e = (*this)[i];
981 if (!CNT<ELT>::isFinite(e)) {
982 if (!CNT<ELT>::isInf(e))
983 return false; // something bad was found
984 seenInf = true;
985 }
986 }
987 return seenInf;
988 }
989
992 bool isFinite() const {
993 for (int i=0; i<M; ++i)
994 if (!CNT<ELT>::isFinite((*this)[i]))
995 return false;
996 return true;
997 }
998
1002
1005 template <class E2, int RS2>
1006 bool isNumericallyEqual(const Vec<M,E2,RS2>& v, double tol) const {
1007 for (int i=0; i<M; ++i)
1008 if (!CNT<ELT>::isNumericallyEqual((*this)[i], v[i], tol))
1009 return false;
1010 return true;
1011 }
1012
1016 template <class E2, int RS2>
1017 bool isNumericallyEqual(const Vec<M,E2,RS2>& v) const {
1018 const double tol = std::max(getDefaultTolerance(),v.getDefaultTolerance());
1019 return isNumericallyEqual(v, tol);
1020 }
1021
1027 (const ELT& e,
1028 double tol = getDefaultTolerance()) const
1029 {
1030 for (int i=0; i<M; ++i)
1031 if (!CNT<ELT>::isNumericallyEqual((*this)[i], e, tol))
1032 return false;
1033 return true;
1034 }
1035
1036 // Functions to be used for Scripting in MATLAB and languages that do not support operator overloading
1038 std::string toString() const {
1039 std::stringstream stream;
1040 stream << (*this);
1041 return stream.str();
1042 }
1043
1045 void set(int i, const E& value)
1046 { (*this)[i] = value; }
1047
1049 const E& get(int i) const
1050 { return operator[](i); }
1051
1052private:
1053 template<typename ElementsRowByRowTuple, int... Idx>
1054 requires (sizeof...(Idx) == M)
1055 constexpr void assignElementsFromTuple(
1057 std::integer_sequence<int, Idx...>)
1058 {
1059 (((*this)[Idx] = std::get<Idx>(els)) , ...);
1060 }
1061
1062 template<typename R, int... Idx>
1063 requires (sizeof...(Idx) == M)
1064 constexpr void assignElementsFromRange(
1065 R&& range,
1066 std::integer_sequence<int, Idx...>)
1067 {
1068 (((*this)[Idx] = range[Idx]) , ...);
1069 }
1070
1071 template <class EE, int SS>
1072 constexpr void assignElementsFromVec(const Vec<M, EE, SS>& v)
1073 {
1074 assignElementsFromRange(v, std::make_integer_sequence<int, M>{});
1075 }
1076
1077 template<typename... Els>
1078 requires (sizeof...(Els) == M)
1079 constexpr void assignElements(Els&&... els)
1080 {
1081 assignElementsFromTuple(
1082 std::make_tuple(std::forward<Els>(els)...),
1083 std::make_integer_sequence<int, M>{}
1084 );
1085 }
1086
1087 // TODO: should be an array of scalars rather than elements to control
1088 // packing more carefully.
1089 ELT d[NActualElements]; // data
1090};
1091
1093// Global operators involving two vectors. //
1094// v+v, v-v, v==v, v!=v //
1096
1097// v3 = v1 + v2 where all v's have the same length M.
1098template <int M, class E1, int S1, class E2, int S2> inline
1102 ::AddOp::perform(l,r);
1103}
1104
1105// v3 = v1 - v2, similar to +
1106template <int M, class E1, int S1, class E2, int S2> inline
1110 ::SubOp::perform(l,r);
1111}
1112
1114template <int M, class E1, int S1, class E2, int S2> inline bool
1116{ for (int i=0; i < M; ++i) if (l[i] != r[i]) return false;
1117 return true; }
1119template <int M, class E1, int S1, class E2, int S2> inline bool
1120operator!=(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) {return !(l==r);}
1121
1123template <int M, class E1, int S1, class E2> inline bool
1124operator==(const Vec<M,E1,S1>& v, const E2& e)
1125{ for (int i=0; i < M; ++i) if (v[i] != e) return false;
1126 return true; }
1128template <int M, class E1, int S1, class E2> inline bool
1129operator!=(const Vec<M,E1,S1>& v, const E2& e) {return !(v==e);}
1130
1132template <int M, class E1, int S1, class E2, int S2> inline bool
1133operator<(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r)
1134{ for (int i=0; i < M; ++i) if (l[i] >= r[i]) return false;
1135 return true; }
1137template <int M, class E1, int S1, class E2> inline bool
1138operator<(const Vec<M,E1,S1>& v, const E2& e)
1139{ for (int i=0; i < M; ++i) if (v[i] >= e) return false;
1140 return true; }
1141
1143template <int M, class E1, int S1, class E2, int S2> inline bool
1145{ for (int i=0; i < M; ++i) if (l[i] <= r[i]) return false;
1146 return true; }
1148template <int M, class E1, int S1, class E2> inline bool
1149operator>(const Vec<M,E1,S1>& v, const E2& e)
1150{ for (int i=0; i < M; ++i) if (v[i] <= e) return false;
1151 return true; }
1152
1155template <int M, class E1, int S1, class E2, int S2> inline bool
1156operator<=(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r)
1157{ for (int i=0; i < M; ++i) if (l[i] > r[i]) return false;
1158 return true; }
1161template <int M, class E1, int S1, class E2> inline bool
1162operator<=(const Vec<M,E1,S1>& v, const E2& e)
1163{ for (int i=0; i < M; ++i) if (v[i] > e) return false;
1164 return true; }
1165
1168template <int M, class E1, int S1, class E2, int S2> inline bool
1170{ for (int i=0; i < M; ++i) if (l[i] < r[i]) return false;
1171 return true; }
1174template <int M, class E1, int S1, class E2> inline bool
1175operator>=(const Vec<M,E1,S1>& v, const E2& e)
1176{ for (int i=0; i < M; ++i) if (v[i] < e) return false;
1177 return true; }
1178
1180// Global operators involving a vector and a scalar. //
1182
1183// I haven't been able to figure out a nice way to templatize for the
1184// built-in reals without introducing a lot of unwanted type matches
1185// as well. So we'll just grind them out explicitly here.
1186
1187// SCALAR MULTIPLY
1188
1189// v = v*real, real*v
1190template <int M, class E, int S> inline
1192operator*(const Vec<M,E,S>& l, const float& r)
1193 { return Vec<M,E,S>::template Result<float>::MulOp::perform(l,r); }
1194template <int M, class E, int S> inline
1196operator*(const float& l, const Vec<M,E,S>& r) {return r*l;}
1197
1198template <int M, class E, int S> inline
1200operator*(const Vec<M,E,S>& l, const double& r)
1201 { return Vec<M,E,S>::template Result<double>::MulOp::perform(l,r); }
1202template <int M, class E, int S> inline
1204operator*(const double& l, const Vec<M,E,S>& r) {return r*l;}
1205
1206// v = v*int, int*v -- just convert int to v's precision float
1207template <int M, class E, int S> inline
1209operator*(const Vec<M,E,S>& l, int r) {return l * (typename CNT<E>::Precision)r;}
1210template <int M, class E, int S> inline
1212operator*(int l, const Vec<M,E,S>& r) {return r * (typename CNT<E>::Precision)l;}
1213
1214// Complex, conjugate, and negator are all easy to templatize.
1215
1216// v = v*complex, complex*v
1217template <int M, class E, int S, class R> inline
1219operator*(const Vec<M,E,S>& l, const std::complex<R>& r)
1220 { return Vec<M,E,S>::template Result<std::complex<R> >::MulOp::perform(l,r); }
1221template <int M, class E, int S, class R> inline
1223operator*(const std::complex<R>& l, const Vec<M,E,S>& r) {return r*l;}
1224
1225// v = v*conjugate, conjugate*v (convert conjugate->complex)
1226template <int M, class E, int S, class R> inline
1228operator*(const Vec<M,E,S>& l, const conjugate<R>& r) {return l*(std::complex<R>)r;}
1229template <int M, class E, int S, class R> inline
1231operator*(const conjugate<R>& l, const Vec<M,E,S>& r) {return r*(std::complex<R>)l;}
1232
1233// v = v*negator, negator*v: convert negator to standard number
1234template <int M, class E, int S, class R> inline
1236operator*(const Vec<M,E,S>& l, const negator<R>& r) {return l * (typename negator<R>::StdNumber)(R)r;}
1237template <int M, class E, int S, class R> inline
1239operator*(const negator<R>& l, const Vec<M,E,S>& r) {return r * (typename negator<R>::StdNumber)(R)l;}
1240
1241
1242// SCALAR DIVIDE. This is a scalar operation when the scalar is on the right,
1243// but when it is on the left it means scalar * pseudoInverse(vec), which is
1244// a row.
1245
1246// v = v/real, real/v
1247template <int M, class E, int S> inline
1249operator/(const Vec<M,E,S>& l, const float& r)
1250 { return Vec<M,E,S>::template Result<float>::DvdOp::perform(l,r); }
1251template <int M, class E, int S> inline
1252typename CNT<float>::template Result<Vec<M,E,S> >::Dvd
1253operator/(const float& l, const Vec<M,E,S>& r)
1254 { return CNT<float>::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); }
1255
1256template <int M, class E, int S> inline
1258operator/(const Vec<M,E,S>& l, const double& r)
1259 { return Vec<M,E,S>::template Result<double>::DvdOp::perform(l,r); }
1260template <int M, class E, int S> inline
1261typename CNT<double>::template Result<Vec<M,E,S> >::Dvd
1262operator/(const double& l, const Vec<M,E,S>& r)
1263 { return CNT<double>::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); }
1264
1265// v = v/int, int/v -- just convert int to v's precision float
1266template <int M, class E, int S> inline
1268operator/(const Vec<M,E,S>& l, int r) {return l / (typename CNT<E>::Precision)r;}
1269template <int M, class E, int S> inline
1271operator/(int l, const Vec<M,E,S>& r) {return (typename CNT<E>::Precision)l / r;}
1272
1273
1274// Complex, conjugate, and negator are all easy to templatize.
1275
1276// v = v/complex, complex/v
1277template <int M, class E, int S, class R> inline
1279operator/(const Vec<M,E,S>& l, const std::complex<R>& r)
1280 { return Vec<M,E,S>::template Result<std::complex<R> >::DvdOp::perform(l,r); }
1281template <int M, class E, int S, class R> inline
1283operator/(const std::complex<R>& l, const Vec<M,E,S>& r)
1284 { return CNT<std::complex<R> >::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); }
1285
1286// v = v/conjugate, conjugate/v (convert conjugate->complex)
1287template <int M, class E, int S, class R> inline
1289operator/(const Vec<M,E,S>& l, const conjugate<R>& r) {return l/(std::complex<R>)r;}
1290template <int M, class E, int S, class R> inline
1292operator/(const conjugate<R>& l, const Vec<M,E,S>& r) {return (std::complex<R>)l/r;}
1293
1294// v = v/negator, negator/v: convert negator to number
1295template <int M, class E, int S, class R> inline
1297operator/(const Vec<M,E,S>& l, const negator<R>& r) {return l/(typename negator<R>::StdNumber)(R)r;}
1298template <int M, class E, int S, class R> inline
1299typename CNT<R>::template Result<Vec<M,E,S> >::Dvd
1300operator/(const negator<R>& l, const Vec<M,E,S>& r) {return (typename negator<R>::StdNumber)(R)l/r;}
1301
1302
1303// Add and subtract are odd as scalar ops. They behave as though the
1304// scalar stands for a vector each of whose elements is that scalar,
1305// and then a normal vector add or subtract is done.
1306
1307// SCALAR ADD
1308
1309// v = v+real, real+v
1310template <int M, class E, int S> inline
1312operator+(const Vec<M,E,S>& l, const float& r)
1313 { return Vec<M,E,S>::template Result<float>::AddOp::perform(l,r); }
1314template <int M, class E, int S> inline
1316operator+(const float& l, const Vec<M,E,S>& r) {return r+l;}
1317
1318template <int M, class E, int S> inline
1320operator+(const Vec<M,E,S>& l, const double& r)
1321 { return Vec<M,E,S>::template Result<double>::AddOp::perform(l,r); }
1322template <int M, class E, int S> inline
1324operator+(const double& l, const Vec<M,E,S>& r) {return r+l;}
1325
1326// v = v+int, int+v -- just convert int to v's precision float
1327template <int M, class E, int S> inline
1329operator+(const Vec<M,E,S>& l, int r) {return l + (typename CNT<E>::Precision)r;}
1330template <int M, class E, int S> inline
1332operator+(int l, const Vec<M,E,S>& r) {return r + (typename CNT<E>::Precision)l;}
1333
1334// Complex, conjugate, and negator are all easy to templatize.
1335
1336// v = v+complex, complex+v
1337template <int M, class E, int S, class R> inline
1339operator+(const Vec<M,E,S>& l, const std::complex<R>& r)
1340 { return Vec<M,E,S>::template Result<std::complex<R> >::AddOp::perform(l,r); }
1341template <int M, class E, int S, class R> inline
1343operator+(const std::complex<R>& l, const Vec<M,E,S>& r) {return r+l;}
1344
1345// v = v+conjugate, conjugate+v (convert conjugate->complex)
1346template <int M, class E, int S, class R> inline
1348operator+(const Vec<M,E,S>& l, const conjugate<R>& r) {return l+(std::complex<R>)r;}
1349template <int M, class E, int S, class R> inline
1351operator+(const conjugate<R>& l, const Vec<M,E,S>& r) {return r+(std::complex<R>)l;}
1352
1353// v = v+negator, negator+v: convert negator to standard number
1354template <int M, class E, int S, class R> inline
1356operator+(const Vec<M,E,S>& l, const negator<R>& r) {return l + (typename negator<R>::StdNumber)(R)r;}
1357template <int M, class E, int S, class R> inline
1359operator+(const negator<R>& l, const Vec<M,E,S>& r) {return r + (typename negator<R>::StdNumber)(R)l;}
1360
1361// SCALAR SUBTRACT -- careful, not commutative.
1362
1363// v = v-real, real-v
1364template <int M, class E, int S> inline
1366operator-(const Vec<M,E,S>& l, const float& r)
1367 { return Vec<M,E,S>::template Result<float>::SubOp::perform(l,r); }
1368template <int M, class E, int S> inline
1369typename CNT<float>::template Result<Vec<M,E,S> >::Sub
1370operator-(const float& l, const Vec<M,E,S>& r)
1371 { return CNT<float>::template Result<Vec<M,E,S> >::SubOp::perform(l,r); }
1372
1373template <int M, class E, int S> inline
1375operator-(const Vec<M,E,S>& l, const double& r)
1376 { return Vec<M,E,S>::template Result<double>::SubOp::perform(l,r); }
1377template <int M, class E, int S> inline
1378typename CNT<double>::template Result<Vec<M,E,S> >::Sub
1379operator-(const double& l, const Vec<M,E,S>& r)
1380 { return CNT<double>::template Result<Vec<M,E,S> >::SubOp::perform(l,r); }
1381
1382// v = v-int, int-v // just convert int to v's precision float
1383template <int M, class E, int S> inline
1385operator-(const Vec<M,E,S>& l, int r) {return l - (typename CNT<E>::Precision)r;}
1386template <int M, class E, int S> inline
1388operator-(int l, const Vec<M,E,S>& r) {return (typename CNT<E>::Precision)l - r;}
1389
1390
1391// Complex, conjugate, and negator are all easy to templatize.
1392
1393// v = v-complex, complex-v
1394template <int M, class E, int S, class R> inline
1396operator-(const Vec<M,E,S>& l, const std::complex<R>& r)
1397 { return Vec<M,E,S>::template Result<std::complex<R> >::SubOp::perform(l,r); }
1398template <int M, class E, int S, class R> inline
1400operator-(const std::complex<R>& l, const Vec<M,E,S>& r)
1401 { return CNT<std::complex<R> >::template Result<Vec<M,E,S> >::SubOp::perform(l,r); }
1402
1403// v = v-conjugate, conjugate-v (convert conjugate->complex)
1404template <int M, class E, int S, class R> inline
1406operator-(const Vec<M,E,S>& l, const conjugate<R>& r) {return l-(std::complex<R>)r;}
1407template <int M, class E, int S, class R> inline
1409operator-(const conjugate<R>& l, const Vec<M,E,S>& r) {return (std::complex<R>)l-r;}
1410
1411// v = v-negator, negator-v: convert negator to standard number
1412template <int M, class E, int S, class R> inline
1414operator-(const Vec<M,E,S>& l, const negator<R>& r) {return l-(typename negator<R>::StdNumber)(R)r;}
1415template <int M, class E, int S, class R> inline
1416typename CNT<R>::template Result<Vec<M,E,S> >::Sub
1417operator-(const negator<R>& l, const Vec<M,E,S>& r) {return (typename negator<R>::StdNumber)(R)l-r;}
1418
1419// Vec I/O
1420template <int M, class E, int S, class CHAR, class TRAITS> inline
1421std::basic_ostream<CHAR,TRAITS>&
1422operator<<(std::basic_ostream<CHAR,TRAITS>& o, const Vec<M,E,S>& v) {
1423 o << "~[" << v[0]; for(int i=1;i<M;++i) o<<','<<v[i]; o<<']'; return o;
1424}
1425
1428template <int M, class E, int S, class CHAR, class TRAITS> inline
1429std::basic_istream<CHAR,TRAITS>&
1430operator>>(std::basic_istream<CHAR,TRAITS>& is, Vec<M,E,S>& v) {
1431 CHAR tilde;
1432 is >> tilde; if (is.fail()) return is;
1433 if (tilde != CHAR('~')) {
1434 tilde = CHAR(0);
1435 is.unget(); if (is.fail()) return is;
1436 }
1437
1439 is >> openBracket; if (is.fail()) return is;
1440 if (openBracket==CHAR('('))
1441 closeBracket = CHAR(')');
1442 else if (openBracket==CHAR('['))
1443 closeBracket = CHAR(']');
1444 else {
1445 closeBracket = CHAR(0);
1446 is.unget(); if (is.fail()) return is;
1447 }
1448
1449 // If we saw a "~" but then we didn't see any brackets, that's an
1450 // error. Set the fail bit and return.
1451 if (tilde != CHAR(0) && closeBracket == CHAR(0)) {
1452 is.setstate( std::ios::failbit );
1453 return is;
1454 }
1455
1456 for (int i=0; i < M; ++i) {
1457 is >> v[i];
1458 if (is.fail()) return is;
1459 if (i != M-1) {
1460 CHAR c; is >> c; if (is.fail()) return is;
1461 if (c != ',') is.unget();
1462 if (is.fail()) return is;
1463 }
1464 }
1465
1466 // Get the closing bracket if there was an opening one. If we don't
1467 // see the expected character we'll set the fail bit in the istream.
1468 if (closeBracket != CHAR(0)) {
1469 CHAR closer; is >> closer; if (is.fail()) return is;
1470 if (closer != closeBracket) {
1471 is.unget(); if (is.fail()) return is;
1472 is.setstate( std::ios::failbit );
1473 }
1474 }
1475
1476 return is;
1477}
1478
1479} //namespace SimTK
1480
1481
1482#endif //SimTK_SIMMATRIX_SMALLMATRIX_VEC_H_
Mandatory first inclusion for any Simbody source or header file.
#define SimTK_NODISCARD
Warn if a caller fails to capture or use the return value of a method.
Definition SimTKcommon/include/SimTKcommon/internal/common.h:315
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:100
Definition NTraits.h:486
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:186
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:954
Vec & scalarMinusEq(const EE &ee)
Definition Vec.h:837
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:339
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:1027
void setToNaN()
Set every scalar in this Vec to NaN; this is the default initial value in Debug builds,...
Definition Vec.h:862
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:958
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:223
TPosTrans & updPositionalTranspose()
Positional transpose returning a writable reference.
Definition Vec.h:724
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:286
CNT< E >::TWithoutNegator EWithoutNegator
Element type, stripped of negator<> if it has one.
Definition Vec.h:197
CNT< E >::Number ENumber
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:232
CNT< E >::TNeg ENeg
Negated version of this Vec's element type; ENeg==negator< E >.
Definition Vec.h:195
bool isInf() const
Return true if any element of this Vec contains a +Infinity or -Infinity somewhere but no element con...
Definition Vec.h:977
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:927
ELT E
Element type of this Vec.
Definition Vec.h:193
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:289
Vec< M, E, STRIDE > T
The type of this Vec.
Definition Vec.h:267
void setToZero()
Set every scalar in this Vec to zero.
Definition Vec.h:867
constexpr Vec(const E &e0, const E &e1, const E &e2, const E &e3)
Definition Vec.h:503
EScalar Scalar
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:310
constexpr Vec(const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5)
Definition Vec.h:516
bool isNaN() const
Return true if any element of this Vec contains a NaN anywhere.
Definition Vec.h:968
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:622
std::string toString() const
Print Vec into a string and return it.
Definition Vec.h:1038
Vec & operator-=(const EE &e)
Definition Vec.h:827
CNT< E >::StdNumber EStdNumber
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:233
constexpr 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:526
E TElement
Element type of this Vec.
Definition Vec.h:291
Vec & scalarPlusEq(const EE &ee)
Definition Vec.h:835
TInvert invert() const
This method is not supported for Vec objects.
Definition Vec.h:685
CNT< ScalarNormSq >::TSqrt norm() const
Definition Vec.h:660
Vec< M, typename CNT< E >::template Result< EE >::Dvd > scalarDivide(const EE &e) const
Definition Vec.h:789
constexpr 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:462
Vec< M, EComplex, STRIDE > TComplex
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:282
Vec TCol
Type of a column of this CNT object (for a Vec, the whole thing).
Definition Vec.h:295
Vec< M, typename CNT< E >::template Result< EE >::Mul > elementwiseMultiply(const Vec< M, EE, SS > &r) const
Elementwise multiply (Matlab " .* " operator).
Definition Vec.h:630
Vec & scalarMinusEqFromLeft(int ee)
Definition Vec.h:856
const E & get(int i) const
Variant of operator[] that's scripting friendly to get const reference to ith entry.
Definition Vec.h:1049
Vec< M, typename CNT< E >::template Result< EE >::Add > scalarAdd(const EE &e) const
Definition Vec.h:802
Vec< M, EAbs, 1 > TAbs
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:300
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:731
Vec< M, typename CNT< EE >::template Result< E >::Sub > scalarSubtractFromLeft(const EE &e) const
Definition Vec.h:816
CNT< E >::ULessScalar EULessScalar
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:231
bool isFinite() const
Return true if no element of this Vec contains an Infinity or a NaN anywhere.
Definition Vec.h:992
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:573
CNT< E >::TNormalize ENormalize
Packed type that can hold the value returned from normalize(E).
Definition Vec.h:228
static int ncol()
The number of columns in a Vec is always 1.
Definition Vec.h:324
constexpr E & operator[](int i)
Select an element of this Vec and return a writable reference to it.
Definition Vec.h:654
constexpr const E & operator()(int i) const
Same as const operator[] above.
Definition Vec.h:649
TNeg & updNegate()
Non-operator version of unary negation; recasts and returns a writable reference.
Definition Vec.h:709
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:578
constexpr 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:455
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:913
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:490
constexpr Vec & operator=(const Vec &src)
Copy assignment operator copies the logically-included elements from the source Vec; gaps due to stri...
Definition Vec.h:447
Vec< M, EWithoutNegator, STRIDE > TWithoutNegator
Type of this Vec with negator removed from its element type, if the element is negated.
Definition Vec.h:273
Vec< M, ENormalize, 1 > TNormalize
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:303
Vec< M, typename CNT< EE >::template Result< E >::Mul > scalarMultiplyFromLeft(const EE &e) const
Definition Vec.h:780
TImag & imag()
Recast to show only the imaginary portion of this Vec and return a writable reference.
Definition Vec.h:749
Vec & scalarTimesEqFromLeft(int ee)
Definition Vec.h:857
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:613
TWithoutNegator & updCastAwayNegatorIfAny()
Recast to remove negators from this Vec's type if present and return a writable reference.
Definition Vec.h:762
constexpr Vec(const Vec &src)
Copy constructor copies the logically-included elements from the source Vec; gaps due to stride are n...
Definition Vec.h:440
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:897
Vec & operator+=(const EE &e)
Definition Vec.h:826
Vec< M, ESqrt, 1 > TSqrt
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:299
THerm & operator~()
Recast to Hermitian transposed type and return a writable reference; the effect is that writing to el...
Definition Vec.h:703
constexpr Vec(const E &e)
Construction from a single value of this Vec's element type assigns that value to each element.
Definition Vec.h:475
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:598
ScalarNormSq scalarNormSqr() const
Scalar norm square is sum( conjugate squares of all underlying scalars ), where conjugate square of s...
Definition Vec.h:329
Vec & scalarMinusEq(int ee)
Definition Vec.h:853
Vec< M, typename CNT< E >::template Result< EE >::Dvd > elementwiseDivide(const Vec< M, EE, SS > &r) const
Elementwise divide (Matlab " ./ " operator).
Definition Vec.h:637
static double getDefaultTolerance()
For approximate comparisons, the default tolerance to use for a vector is the same as its elements' d...
Definition Vec.h:1001
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:673
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:758
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:965
constexpr const E & operator[](int i) const
Select an element of this Vec and return a const reference to it.
Definition Vec.h:646
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:606
Vec & scalarEq(const EE &ee)
Definition Vec.h:833
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:1006
Vec< M, typename CNT< E >::template Result< EE >::Sub > scalarSubtract(const EE &e) const
Definition Vec.h:810
ScalarNormSq normSqr() const
Definition Vec.h:658
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:368
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:359
Vec< M, typename CNT< EE >::template Result< E >::Dvd > scalarDivideFromLeft(const EE &e) const
Definition Vec.h:795
Vec & scalarMinusEqFromLeft(const EE &ee)
Definition Vec.h:839
const TNeg & negate() const
Non-operator version of unary negation; just a recast.
Definition Vec.h:706
void set(int i, const E &value)
Variant of operator[] that's scripting friendly to set ith entry.
Definition Vec.h:1045
constexpr E & operator()(int i)
Same as non-const operator[] above.
Definition Vec.h:656
CNT< E >::TAbs EAbs
Type required to hold the result of abs(E).
Definition Vec.h:220
Vec & scalarDivideEqFromLeft(int ee)
Definition Vec.h:858
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:692
Vec & scalarDivideEq(const EE &ee)
Definition Vec.h:845
constexpr Vec(const Vec< M, EE, SS > &src)
Construct a Vec from a Vec of the same length, with any stride.
Definition Vec.h:469
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:583
static int nrow()
The number of rows in a Vec is the number of elements.
Definition Vec.h:322
constexpr Vec(const E &e0, const E &e1, const E &e2)
Definition Vec.h:499
Vec & scalarTimesEq(int ee)
Definition Vec.h:854
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:566
CNT< E >::TSqHermT ESqHermT
Type of the expression ~E*E (default vector and matrix square; symmetric).
Definition Vec.h:214
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:200
THerm & updTranspose()
Non-operator version of Hermitian transpose; recasts and returns a writable reference.
Definition Vec.h:715
constexpr Vec(const E &e0, const E &e1, const E &e2, const E &e3, const E &e4)
Definition Vec.h:507
constexpr Vec(const E &e0, const E &e1)
Construct a Vec<M,E> from M elements of type E, etc.
Definition Vec.h:495
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:207
CNT< E >::TPosTrans EPosTrans
Type of a positional transpose of an element of this Vec.
Definition Vec.h:211
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:588
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:905
constexpr 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:549
TReal & real()
Recast to show only the real portion of this Vec and return a writable reference.
Definition Vec.h:734
CNT< E >::Precision EPrecision
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:234
ESqHermT TSqHermT
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:305
CNT< E >::ScalarNormSq EScalarNormSq
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:235
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:742
Vec & scalarDivideEqFromLeft(const EE &ee)
Definition Vec.h:847
Vec & operator*=(const EE &e)
Definition Vec.h:828
Vec< M, typename CNT< E >::template Result< EE >::Mul > scalarMultiply(const EE &e) const
Definition Vec.h:774
EScalarNormSq ScalarNormSq
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:315
@ SignInterpretation
Definition Vec.h:259
@ IsStdNumber
Definition Vec.h:257
@ IsULessScalar
Definition Vec.h:255
@ NRows
Definition Vec.h:241
@ ArgDepth
Definition Vec.h:251
@ RealStrideFactor
Definition Vec.h:249
@ ColSpacing
Definition Vec.h:247
@ NPackedElements
Definition Vec.h:243
@ IsNumber
Definition Vec.h:256
@ IsPrecision
Definition Vec.h:258
@ RowSpacing
Definition Vec.h:246
@ NActualElements
Definition Vec.h:244
@ NCols
Definition Vec.h:242
@ ImagOffset
Definition Vec.h:248
@ IsScalar
Definition Vec.h:254
@ NActualScalars
Definition Vec.h:245
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:204
const TPosTrans & positionalTranspose() const
Positional transpose turns this Vec into a Row but does not transpose the individual elements.
Definition Vec.h:721
TNeg & operator-()
Recast to negated type and return a writable reference; writing to this will cause the negated result...
Definition Vec.h:695
EULessScalar ULessScalar
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:311
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:281
Vec & scalarDivideEq(int ee)
Definition Vec.h:855
Vec< M, EStandard, 1 > TStandard
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:301
ENumber Number
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:312
Vec< MM, ELT, STRIDE > & updSubVec(int i)
Extract a writable reference to a sub-Vec with size known at compile time.
Definition Vec.h:887
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:940
CNT< E >::TSqrt ESqrt
Type required to hold the result of sqrt(E).
Definition Vec.h:218
const THerm & operator~() const
The Hermitian transpose operator recasts this Vec to a type that specifies the opposite storage order...
Definition Vec.h:699
Vec< M, ENeg, STRIDE > TNeg
Type this Vec would have if its elements were interpreted as negated.
Definition Vec.h:270
TAbs abs() const
Elementwise absolute value; that is, the return value has the same dimension as this Vec but with eac...
Definition Vec.h:349
constexpr 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:537
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:1017
static int size()
The number of elements in this Vec (note that stride does not affect this number.)
Definition Vec.h:320
constexpr 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:481
Row< M, EInvert, 1 > TInvert
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:302
E TRow
Type of a row of this CNT object (for a Vec, just its element type).
Definition Vec.h:293
const Vec & operator+() const
Unary plus does nothing.
Definition Vec.h:688
Vec & scalarTimesEqFromLeft(const EE &ee)
Definition Vec.h:843
Vec & scalarTimesEq(const EE &ee)
Definition Vec.h:841
Vec & scalarPlusEq(int ee)
Definition Vec.h:852
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:593
Vec & operator/=(const EE &e)
Definition Vec.h:829
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:277
constexpr Vec()
Default construction initializes Vec's elements to NaN when debugging but leaves them uninitialized g...
Definition Vec.h:427
EStdNumber StdNumber
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:313
CNT< E >::TSqTHerm ESqTHerm
Type of the expression E*~E ("row square"; symmetric).
Definition Vec.h:216
CNT< E >::TInvert EInvert
Packed type that can hold the value returned from invert(E), the inverse type of an element.
Definition Vec.h:226
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:877
CNT< E >::THerm EHerm
Type of the Hermitian transpose of an element of this Vec.
Definition Vec.h:209
EPrecision Precision
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:314
Vec & scalarEq(int ee)
Definition Vec.h:851
const THerm & transpose() const
Non-operator version of Hermitian transpose; just a recast.
Definition Vec.h:712
SymMat< M, ESqTHerm > TSqTHerm
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:306
CNT< E >::Scalar EScalar
These compile-time constants are required of every Composite Numerical Type (CNT).
Definition Vec.h:230
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:670
@ MAX_RESOLVED_DEPTH
Definition CompositeNumericalTypes.h:120
std::ostream & operator<<(std::ostream &o, const ContactForce &f)
Definition CompliantContactSubsystem.h:387
bool operator>=(const L &left, const R &right)
Definition SimTKcommon/include/SimTKcommon/internal/common.h:682
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:676
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:664
Definition Vec.h:379
Vec< M, typename CNT< E >::template Result< P >::Sub, 1 > Sub
Definition Vec.h:383
Vec< M, typename CNT< E >::template Result< P >::Mul, 1 > Mul
Definition Vec.h:380
Vec< M, typename CNT< E >::template Result< P >::Dvd, 1 > Dvd
Definition Vec.h:381
Vec< M, typename CNT< E >::template Result< P >::Add, 1 > Add
Definition Vec.h:382
Definition Vec.h:388
DvdOp::Type Dvd
Definition Vec.h:402
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:396
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:401
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:406
MulOp::Type Mul
Definition Vec.h:392
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:391
AddOp::Type Add
Definition Vec.h:407
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:411
MulOpNonConforming::Type MulNon
Definition Vec.h:397
SubOp::Type Sub
Definition Vec.h:412
Shape-preserving element substitution (always packed).
Definition Vec.h:420
Vec< M, P > Type
Definition Vec.h:421