Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:54:02

0001 #ifndef DataFormat_Math_ExtVec_H
0002 #define DataFormat_Math_ExtVec_H
0003 
0004 #include <type_traits>
0005 
0006 #ifdef __clang__
0007 #define VECTOR_EXT(N) __attribute__((ext_vector_type(N)))
0008 #else
0009 #define VECTOR_EXT(N) __attribute__((vector_size(N)))
0010 #endif
0011 
0012 typedef float VECTOR_EXT(8) cms_float32x2_t;
0013 typedef float VECTOR_EXT(16) cms_float32x4_t;
0014 typedef float VECTOR_EXT(32) cms_float32x8_t;
0015 typedef double VECTOR_EXT(16) cms_float64x2_t;
0016 typedef double VECTOR_EXT(32) cms_float64x4_t;
0017 typedef double VECTOR_EXT(64) cms_float64x8_t;
0018 
0019 typedef long double VECTOR_EXT(32) cms_float128x2_t;
0020 typedef long double VECTOR_EXT(64) cms_float128x4_t;
0021 typedef long double VECTOR_EXT(128) cms_float128x8_t;
0022 
0023 // template<typename T, int N> using ExtVec =  T __attribute__( ( vector_size( N*sizeof(T) ) ) );
0024 
0025 template <typename T, int N>
0026 struct ExtVecTraits {
0027   //  typedef T __attribute__( ( vector_size( N*sizeof(T) ) ) ) type;
0028 };
0029 
0030 template <>
0031 struct ExtVecTraits<float, 2> {
0032   typedef float VECTOR_EXT(2 * sizeof(float)) type;
0033 };
0034 
0035 template <>
0036 struct ExtVecTraits<float, 4> {
0037   typedef float VECTOR_EXT(4 * sizeof(float)) type;
0038 };
0039 
0040 template <>
0041 struct ExtVecTraits<double, 2> {
0042   typedef double VECTOR_EXT(2 * sizeof(double)) type;
0043 };
0044 
0045 template <>
0046 struct ExtVecTraits<double, 4> {
0047   typedef double VECTOR_EXT(4 * sizeof(double)) type;
0048 };
0049 
0050 template <>
0051 struct ExtVecTraits<long double, 2> {
0052   typedef long double VECTOR_EXT(2 * sizeof(long double)) type;
0053 };
0054 
0055 template <>
0056 struct ExtVecTraits<long double, 4> {
0057   typedef long double VECTOR_EXT(4 * sizeof(long double)) type;
0058 };
0059 
0060 template <typename T, int N>
0061 using ExtVec = typename ExtVecTraits<T, N>::type;
0062 
0063 template <typename T>
0064 using Vec4 = ExtVec<T, 4>;
0065 template <typename T>
0066 using Vec2 = ExtVec<T, 2>;
0067 
0068 template <typename V>
0069 inline auto xy(V v) -> Vec2<typename std::remove_reference<decltype(v[0])>::type> {
0070   typedef typename std::remove_reference<decltype(v[0])>::type T;
0071   return Vec2<T>{v[0], v[1]};
0072 }
0073 
0074 template <typename V>
0075 inline auto zw(V v) -> Vec2<typename std::remove_reference<decltype(v[0])>::type> {
0076   typedef typename std::remove_reference<decltype(v[0])>::type T;
0077   return Vec2<T>{v[2], v[3]};
0078 }
0079 
0080 template <typename Vec, typename F>
0081 inline Vec apply(Vec v, F f) {
0082   typedef typename std::remove_reference<decltype(v[0])>::type T;
0083   constexpr int N = sizeof(Vec) / sizeof(T);
0084   Vec ret;
0085   for (int i = 0; i != N; ++i)
0086     ret[i] = f(v[i]);
0087   return ret;
0088 }
0089 
0090 template <typename Vec>
0091 inline Vec cross3(Vec x, Vec y) {
0092   //  typedef Vec4<T> Vec;
0093   // yz - zy, zx - xz, xy - yx, 0
0094   Vec x1200{x[1], x[2], x[0], x[0]};
0095   Vec y2010{y[2], y[0], y[1], y[0]};
0096   Vec x2010{x[2], x[0], x[1], x[0]};
0097   Vec y1200{y[1], y[2], y[0], y[0]};
0098   return x1200 * y2010 - x2010 * y1200;
0099 }
0100 
0101 template <typename V1, typename V2>
0102 inline auto cross2(V1 x, V2 y) -> typename std::remove_reference<decltype(x[0])>::type {
0103   return x[0] * y[1] - x[1] * y[0];
0104 }
0105 
0106 /*
0107 template<typename T> 
0108 T dot_product(Vec4<T>  x, Vec4<T>  y) {
0109   auto res = x*y;
0110   T ret=0;
0111   for (int i=0;i!=4;++i) ret+=res[i];
0112   return ret;
0113 }
0114 */
0115 
0116 /*
0117 template<typename V, int K> 
0118 inline
0119 V get1(V v) { return (V){v[K]}; }
0120 */
0121 
0122 /*
0123 template<typename T, int N> 
0124 inline
0125 T dot(ExtVec<T,N>  x, ExtVec<T,N>  y) {
0126   T ret=0;
0127   for (int i=0;i!=N;++i) ret+=x[i]*y[i];
0128   return ret;
0129 }
0130 */
0131 
0132 template <typename V>
0133 inline auto dot(V x, V y) -> typename std::remove_reference<decltype(x[0])>::type {
0134   typedef typename std::remove_reference<decltype(x[0])>::type T;
0135   constexpr int N = sizeof(V) / sizeof(T);
0136   T ret = 0;
0137   for (int i = 0; i != N; ++i)
0138     ret += x[i] * y[i];
0139   return ret;
0140 }
0141 
0142 template <typename V1, typename V2>
0143 inline auto dot2(V1 x, V2 y) -> typename std::remove_reference<decltype(x[0])>::type {
0144   typedef typename std::remove_reference<decltype(x[0])>::type T;
0145   T ret = 0;
0146   for (int i = 0; i != 2; ++i)
0147     ret += x[i] * y[i];
0148   return ret;
0149 }
0150 
0151 typedef Vec2<float> Vec2F;
0152 typedef Vec4<float> Vec4F;
0153 typedef Vec4<float> Vec3F;
0154 typedef Vec2<double> Vec2D;
0155 typedef Vec4<double> Vec3D;
0156 typedef Vec4<double> Vec4D;
0157 
0158 /*
0159 template<typename T>
0160 struct As3D {
0161   Vec4<T> const & v;
0162   As3D(Vec4<T> const &iv ) : v(iv){}
0163 };
0164 template<typename T>
0165 inline As3D<T> as3D(Vec4<T> const &v ) { return v;}
0166 */
0167 
0168 template <typename V>
0169 struct As3D {
0170   V const& v;
0171   As3D(V const& iv) : v(iv) {}
0172 };
0173 template <typename V>
0174 inline As3D<V> as3D(V const& v) {
0175   return v;
0176 }
0177 
0178 // rotations
0179 
0180 template <typename T>
0181 struct Rot3 {
0182   typedef Vec4<T> Vec;
0183   Vec axis[3];
0184 
0185   constexpr Rot3() : axis{{(Vec){T(1), 0, 0, 0}}, {(Vec){0, T(1), 0, 0}}, {(Vec){0, 0, T(1), 0}}} {}
0186 
0187   constexpr Rot3(Vec4<T> ix, Vec4<T> iy, Vec4<T> iz) : axis{ix, iy, iz} {}
0188 
0189   constexpr Rot3(T xx, T xy, T xz, T yx, T yy, T yz, T zx, T zy, T zz)
0190       : axis{{(Vec){xx, xy, xz, 0}}, {(Vec){yx, yy, yz, 0}}, {(Vec){zx, zy, zz, 0}}} {}
0191 
0192   constexpr Rot3 transpose() const {
0193     return Rot3(
0194         axis[0][0], axis[1][0], axis[2][0], axis[0][1], axis[1][1], axis[2][1], axis[0][2], axis[1][2], axis[2][2]);
0195   }
0196 
0197   constexpr Vec4<T> x() const { return axis[0]; }
0198   constexpr Vec4<T> y() const { return axis[1]; }
0199   constexpr Vec4<T> z() const { return axis[2]; }
0200 
0201   // toLocal...
0202   constexpr Vec4<T> rotate(Vec4<T> v) const { return transpose().rotateBack(v); }
0203 
0204   // toGlobal...
0205   constexpr Vec4<T> rotateBack(Vec4<T> v) const { return v[0] * axis[0] + v[1] * axis[1] + v[2] * axis[2]; }
0206 
0207   Rot3 rotate(Rot3 const& r) const {
0208     Rot3 tr = transpose();
0209     return Rot3(tr.rotateBack(r.axis[0]), tr.rotateBack(r.axis[1]), tr.rotateBack(r.axis[2]));
0210   }
0211 
0212   constexpr Rot3 rotateBack(Rot3 const& r) const {
0213     return Rot3(rotateBack(r.axis[0]), rotateBack(r.axis[1]), rotateBack(r.axis[2]));
0214   }
0215 };
0216 
0217 typedef Rot3<float> Rot3F;
0218 
0219 typedef Rot3<double> Rot3D;
0220 
0221 template <typename T>
0222 inline constexpr Rot3<T> operator*(Rot3<T> const& rh, Rot3<T> const& lh) {
0223   return lh.rotateBack(rh);
0224 }
0225 
0226 template <typename T>
0227 struct Rot2 {
0228   typedef Vec2<T> Vec;
0229   Vec2<T> axis[2];
0230 
0231   constexpr Rot2() : axis{{(Vec){T(1), 0}}, {(Vec){0, T(1)}}} {}
0232 
0233   constexpr Rot2(Vec2<T> ix, Vec2<T> iy) : axis{ix, iy} {}
0234 
0235   constexpr Rot2(T xx, T xy, T yx, T yy) : Rot2((Vec){xx, xy}, (Vec){yx, yy}) {}
0236 
0237   constexpr Rot2 transpose() const { return Rot2(axis[0][0], axis[1][0], axis[0][1], axis[1][1]); }
0238 
0239   constexpr Vec2<T> x() const { return axis[0]; }
0240   constexpr Vec2<T> y() const { return axis[1]; }
0241 
0242   // toLocal...
0243   constexpr Vec2<T> rotate(Vec2<T> v) const { return transpose().rotateBack(v); }
0244 
0245   // toGlobal...
0246   constexpr Vec2<T> rotateBack(Vec2<T> v) const { return v[0] * axis[0] + v[1] * axis[1]; }
0247 
0248   Rot2 rotate(Rot2 const& r) const {
0249     Rot2 tr = transpose();
0250     return Rot2(tr.rotateBack(r.axis[0]), tr.rotateBack(r.axis[1]));
0251   }
0252 
0253   constexpr Rot2 rotateBack(Rot2 const& r) const { return Rot2(rotateBack(r.axis[0]), rotateBack(r.axis[1])); }
0254 };
0255 
0256 typedef Rot2<float> Rot2F;
0257 
0258 typedef Rot2<double> Rot2D;
0259 
0260 template <typename T>
0261 inline constexpr Rot2<T> operator*(Rot2<T> const& rh, Rot2<T> const& lh) {
0262   return lh.rotateBack(rh);
0263 }
0264 
0265 #include <iosfwd>
0266 std::ostream& operator<<(std::ostream& out, Vec2D const& v);
0267 std::ostream& operator<<(std::ostream& out, Vec2F const& v);
0268 std::ostream& operator<<(std::ostream& out, Vec4F const& v);
0269 std::ostream& operator<<(std::ostream& out, Vec4D const& v);
0270 
0271 std::ostream& operator<<(std::ostream& out, As3D<Vec4F> const& v);
0272 std::ostream& operator<<(std::ostream& out, As3D<Vec4D> const& v);
0273 
0274 std::ostream& operator<<(std::ostream& out, Rot3F const& v);
0275 std::ostream& operator<<(std::ostream& out, Rot3D const& v);
0276 std::ostream& operator<<(std::ostream& out, Rot2F const& v);
0277 std::ostream& operator<<(std::ostream& out, Rot2D const& v);
0278 
0279 #ifdef USE_INLINE_IO
0280 #include <ostream>
0281 std::ostream& operator<<(std::ostream& out, ::Vec4F const& v) {
0282   return out << '(' << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << ')';
0283 }
0284 std::ostream& operator<<(std::ostream& out, ::Vec4D const& v) {
0285   return out << '(' << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << ')';
0286 }
0287 std::ostream& operator<<(std::ostream& out, ::Vec2F const& v) { return out << '(' << v[0] << ", " << v[1] << ')'; }
0288 std::ostream& operator<<(std::ostream& out, ::Vec2D const& v) { return out << '(' << v[0] << ", " << v[1] << ')'; }
0289 
0290 std::ostream& operator<<(std::ostream& out, ::As3D<Vec4F> const& v) {
0291   return out << '(' << v.v[0] << ", " << v.v[1] << ", " << v.v[2] << ')';
0292 }
0293 
0294 std::ostream& operator<<(std::ostream& out, ::As3D<Vec4D> const& v) {
0295   return out << '(' << v.v[0] << ", " << v.v[1] << ", " << v.v[2] << ')';
0296 }
0297 
0298 std::ostream& operator<<(std::ostream& out, ::Rot3F const& r) {
0299   return out << as3D(r.axis[0]) << '\n' << as3D(r.axis[1]) << '\n' << as3D(r.axis[2]);
0300 }
0301 
0302 std::ostream& operator<<(std::ostream& out, ::Rot3D const& r) {
0303   return out << as3D(r.axis[0]) << '\n' << as3D(r.axis[1]) << '\n' << as3D(r.axis[2]);
0304 }
0305 
0306 std::ostream& operator<<(std::ostream& out, ::Rot2F const& r) { return out << r.axis[0] << '\n' << r.axis[1]; }
0307 
0308 std::ostream& operator<<(std::ostream& out, ::Rot2D const& r) { return out << r.axis[0] << '\n' << r.axis[1]; }
0309 #endif
0310 
0311 #endif