vector_fpu.h

Go to the documentation of this file.
00001 /*                    V E C T O R _ F P U . H
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 2008-2012 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * version 2.1 as published by the Free Software Foundation.
00010  *
00011  * This library is distributed in the hope that it will be useful, but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this file; see the file named COPYING for more
00018  * information.
00019  */
00020 /** @file vector_fpu.h
00021  *
00022  *
00023  */
00024 
00025 #ifndef __VECTOR_FPU
00026 #define __VECTOR_FPU
00027 
00028 #include "common.h"
00029 
00030 #ifdef __GNUC__
00031 #undef VEC_ALIGN
00032 #define VEC_ALIGN __attribute__((aligned(16)))
00033 #endif
00034 
00035 template<int LEN>
00036 struct vec_internal {
00037     double v[LEN] VEC_ALIGN;
00038 };
00039 
00040 template<int LEN>
00041 inline dvec<LEN>::dvec(double s)
00042 {
00043     for (int i = 0; i < LEN; i++)
00044         data.v[i] = s;
00045 }
00046 
00047 template<int LEN>
00048 inline dvec<LEN>::dvec(const double* vals, bool UNUSED(aligned))
00049 {
00050     for (int i = 0; i < LEN; i++)
00051         data.v[i] = vals[i];
00052 }
00053 
00054 template<int LEN>
00055 inline dvec<LEN>::dvec(const dvec<LEN>& p)
00056 {
00057     for (int i = 0; i < LEN; i++)
00058         data.v[i] = p.data.v[i];
00059 }
00060 
00061 template<int LEN>
00062 inline dvec<LEN>::dvec(const vec_internal<LEN>& d)
00063 {
00064     for (int i = 0; i < LEN; i++)
00065         data.v[i] = d.v[i];
00066 }
00067 
00068 template<int LEN>
00069 inline dvec<LEN>&
00070 dvec<LEN>::operator=(const dvec<LEN>& p)
00071 {
00072     for (int i = 0; i < LEN; i++)
00073         data.v[i] = p.data.v[i];
00074     return *this;
00075 }
00076 
00077 template<int LEN>
00078 inline double
00079 dvec<LEN>::operator[](int index) const
00080 {
00081     return data.v[index];
00082 }
00083 
00084 template<int LEN>
00085 inline void
00086 dvec<LEN>::u_store(double* arr) const
00087 {
00088     a_store(arr);
00089 }
00090 
00091 template<int LEN>
00092 inline void
00093 dvec<LEN>::a_store(double* arr) const
00094 {
00095     for (int i = 0; i < LEN; i++)
00096         arr[i] = data.v[i];
00097 }
00098 
00099 template<int LEN>
00100 inline bool
00101 dvec<LEN>::operator==(const dvec<LEN>& b) const
00102 {
00103     for (int i = 0; i < LEN; i++)
00104         if (fabs(data.v[i]-b.data.v[i]) > VEQUALITY) return false;
00105     return true;
00106 }
00107 
00108 template<int LEN>
00109 inline dvec<LEN>
00110 dvec<LEN>::operator+(const dvec<LEN>& b)
00111 {
00112     vec_internal<LEN> r;
00113     for (int i = 0; i < LEN; i++)
00114         r.v[i] = data.v[i] + b.data.v[i];
00115     return dvec<LEN>(r);
00116 }
00117 
00118 template<int LEN>
00119 inline dvec<LEN>
00120 dvec<LEN>::operator-(const dvec<LEN>& b)
00121 {
00122     vec_internal<LEN> r;
00123     for (int i = 0; i < LEN; i++)
00124         r.v[i] = data.v[i] - b.data.v[i];
00125     return dvec<LEN>(r);
00126 }
00127 
00128 template<int LEN>
00129 inline dvec<LEN>
00130 dvec<LEN>::operator*(const dvec<LEN>& b)
00131 {
00132     vec_internal<LEN> r;
00133     for (int i = 0; i < LEN; i++)
00134         r.v[i] = data.v[i] * b.data.v[i];
00135     return dvec<LEN>(r);
00136 }
00137 
00138 template<int LEN>
00139 inline dvec<LEN>
00140 dvec<LEN>::operator/(const dvec<LEN>& b)
00141 {
00142     vec_internal<LEN> r;
00143     for (int i = 0; i < LEN; i++)
00144         r.v[i] = data.v[i] / b.data.v[i];
00145     return dvec<LEN>(r);
00146 }
00147 
00148 template<int LEN>
00149 inline dvec<LEN>
00150 dvec<LEN>::madd(const dvec<LEN>& s, const dvec<LEN>& b)
00151 {
00152     vec_internal<LEN> r;
00153     for (int i = 0; i < LEN; i++)
00154         r.v[i] = data.v[i] * s.data.v[i] + b.data.v[i];
00155     return dvec<LEN>(r);
00156 }
00157 
00158 template<int LEN>
00159 inline dvec<LEN>
00160 dvec<LEN>::madd(const double s, const dvec<LEN>& b)
00161 {
00162     vec_internal<LEN> r;
00163     for (int i = 0; i < LEN; i++)
00164         r.v[i] = data.v[i] * s +  b.data.v[i];
00165     return dvec<LEN>(r);
00166 }
00167 
00168 template<int LEN>
00169 inline double
00170 dvec<LEN>::foldr(double identity, const dvec_op& op, int limit)
00171 {
00172     double val = identity;
00173     for (int i = limit-1; i >= 0; i--) {
00174         val = op(data.v[i], val);
00175     }
00176     return val;
00177 }
00178 template<int LEN>
00179 inline double
00180 dvec<LEN>::foldl(double identity, const dvec_op& op, int limit)
00181 {
00182     double val = identity;
00183     for (int i = 0; i < limit; i++) {
00184         val = op(val, data.v[i]);
00185     }
00186     return val;
00187 }
00188 
00189 template<int LEN>
00190 inline dvec<LEN>
00191 dvec<LEN>::map(const dvec_unop& op, int limit)
00192 {
00193     vec_internal<LEN> r;
00194     for (int i = 0; i < limit; i++) {
00195         r.v[i] = op(data.v[i]);
00196     }
00197     return dvec<LEN>(r);
00198 }
00199 
00200 
00201 template <int LEN>
00202 inline std::ostream&
00203 operator<<(std::ostream& out, const dvec<LEN>& v)
00204 {
00205     out << "<";
00206     for (int i = 0; i < LEN; i++) {
00207         out << v.data.v[i];
00208         if (i != LEN-1)
00209             out << ",";
00210     }
00211     out << ">";
00212     return out;
00213 }
00214 
00215 class vec2d {
00216 public:
00217 
00218     vec2d() {
00219         _init(0, 0);
00220     }
00221 
00222     vec2d(double xin, double yin) {
00223         _init(xin, yin);
00224     }
00225 
00226     vec2d(const vec2d& proto) {
00227         _init(proto.v[0], proto.v[1]);
00228     }
00229 
00230     vec2d& operator=(const vec2d& b) {
00231         v[0] = b.v[0];
00232         v[1] = b.v[1];
00233         return *this;
00234     }
00235 
00236     double operator[](int index) const { return v[index]; }
00237 
00238     double x() const { return v[0]; }
00239     double y() const { return v[1]; }
00240 
00241     vec2d operator+(const vec2d& b) const {
00242         return vec2d(v[0] + b.v[0], v[1] + b.v[1]);
00243     }
00244 
00245     vec2d operator-(const vec2d& b) const {
00246         return vec2d(v[0] - b.v[0], v[1] - b.v[1]);
00247     }
00248 
00249     vec2d operator*(const vec2d& b) const {
00250         return vec2d(v[0] * b.v[0], v[1] * b.v[1]);
00251     }
00252 
00253     vec2d operator/(const vec2d& b) const {
00254         return vec2d(v[0] / b.v[0], v[1] / b.v[1]);
00255     }
00256 
00257     vec2d madd(const double& scalar, const vec2d& b) const {
00258         return vec2d(v[0]*scalar+b.v[0], v[1]*scalar+b.v[1]);
00259     }
00260 
00261     vec2d madd(const vec2d& s, const vec2d& b) const {
00262         return vec2d(v[0]*s.v[0]+b.v[0], v[1]*s.v[1]+b.v[1]);
00263     }
00264 
00265 private:
00266     double* v;
00267     double  m[4];
00268 
00269     void _init(double xin, double yin) {
00270         // align to 16-byte boundary
00271         v = (double*)((((uintptr_t)m) + 0x10L) & ~0xFL);
00272         v[0] = xin;
00273         v[1] = yin;
00274     }
00275 };
00276 
00277 inline std::ostream&
00278 operator<<(std::ostream& out, const vec2d& v)
00279 {
00280     out << "<" << v.x() << "," << v.y() << ">";
00281     return out;
00282 }
00283 
00284 #endif
00285 
00286 /*
00287  * Local Variables:
00288  * mode: C++
00289  * tab-width: 8
00290  * indent-tabs-mode: t
00291  * c-file-style: "stroustrup"
00292  * End:
00293  * ex: shiftwidth=4 tabstop=8
00294  */
Generated on Tue Dec 11 13:14:27 2012 for LIBBN by  doxygen 1.6.3