99 double foldr(
double proto,
const dvec_op& operation,
int limit = LEN);
104 double operator()(
double a,
double b)
const {
return a * b; }
109 double operator()(
double a,
double b)
const {
return a + b; }
114 double operator()(
double a,
double b)
const {
return a - b; }
136#if defined(__SSE2__) && defined(__GNUC__) && defined(HAVE_EMMINTRIN_H) && defined(HAVE_EMMINTRIN)
137# define __x86_vector__
139#ifdef HAVE_EMMINTRIN_H
140# include <emmintrin.h>
144#define VEC_ALIGN __attribute__((aligned(16)))
163 for (
int i = 0; i < LEN/2; i++) {
166 data.v[i] = _mm_load_pd(&t[i*2]);
173 for (
int i = 0; i < LEN/2; i++) {
175 data.v[i] = _mm_load_pd(&vals[i*2]);
182 for (
int i = 0; i < LEN/2; i++) {
183 data.v[i] = p.data.v[i];
190 for (
int i = 0; i < LEN/2; i++) data.v[i] = d.v[i];
196 for (
int i = 0; i < LEN/2; i++) data.v[i] = f.v[i];
203 for (
int i = 0; i < LEN/2; i++) {
204 data.v[i] = p.data.v[i];
214 _mm_store_pd(t, data.v[index/2]);
222 for (
int i = 0; i < LEN/2; i++) {
223 _mm_storeu_pd(&arr[i*2], data.v[i]);
231 for (
int i = 0; i < LEN/2; i++) {
232 _mm_store_pd(&arr[i*2], data.v[i]);
244 for (
int i = 0; i < LEN; i++)
245 if (fabs(ta[i]-tb[i]) >
VEQUALITY)
return false;
249#define DOP_IMPL(__op__) { \
250 dvec_internal<LEN> result; \
251 for (int i = 0; i < LEN/2; i++) { \
252 result.v[i] = __op__(data.v[i], b.data.v[i]); \
254 return dvec<LEN>(result); \
261 DOP_IMPL(_mm_add_pd);
268 DOP_IMPL(_mm_sub_pd);
275 DOP_IMPL(_mm_mul_pd);
282 DOP_IMPL(_mm_div_pd);
290 for (
int i = 0; i < LEN/2; i++) {
291 r.v[i] = _mm_mul_pd(data.v[i], s.data.v[i]);
293 for (
int i = 0; i < LEN/2; i++) {
294 r.v[i] = _mm_add_pd(r.v[i], b.data.v[i]);
304 for (
int i = 0; i < LEN; i++) _t[i] = s;
315 double val = identity;
316 for (
int i = limit-1; i >= 0; i--) {
317 val = op(_t[i], val);
328 double val = identity;
329 for (
int i = 0; i < limit; i++) {
330 val = op(val, _t[i]);
342 for (
int i = 0; i < limit; i++) {
356 for (
int i = 0; i < LEN; i++) {
372 vec2d(
double x_,
double y_) {
376 vec2d(
const vec2d& proto) {
380 vec2d& operator=(
const vec2d& b) {
385 double operator[](
int index)
const {
387 _mm_store_pd(v, _vec);
391 void ustore(
double* arr)
const {
394 _mm_store_pd(v, _vec);
399 double x()
const {
return (*
this)[0]; }
400 double y()
const {
return (*
this)[1]; }
402 vec2d operator+(
const vec2d& b)
const {
403 return vec2d(_mm_add_pd(_vec, b._vec));
406 vec2d operator-(
const vec2d& b)
const {
407 return vec2d(_mm_sub_pd(vec(), b.vec()));
410 vec2d operator*(
const vec2d& b)
const {
411 return vec2d(_mm_mul_pd(vec(), b.vec()));
414 vec2d operator/(
const vec2d& b)
const {
415 return vec2d(_mm_div_pd(vec(), b.vec()));
418 vec2d madd(
const double& scalar,
const vec2d& b)
const {
419 return madd(vec2d(scalar, scalar), b);
422 vec2d madd(
const vec2d& s,
const vec2d& b)
const {
423 return vec2d(_mm_add_pd(_mm_mul_pd(vec(), s.vec()), b.vec()));
430 vec2d(
const v2df& result) {
434 v2df vec()
const {
return _vec; }
436 void _init(
double x_,
double y_) {
440 _vec = _mm_load_pd(v);
448 out <<
"<" << v.x() <<
"," << v.y() <<
">";
453# define __fpu_vector__
457#define VEC_ALIGN __attribute__((aligned(16)))
473 for (
int i = 0; i < LEN; i++)
480 for (
int i = 0; i < LEN; i++)
487 for (
int i = 0; i < LEN; i++)
494 for (
int i = 0; i < LEN; i++)
495 data.v[i] = p.data.v[i];
501 for (
int i = 0; i < LEN; i++)
508 for (
int i = 0; i < LEN; i++)
516 for (
int i = 0; i < LEN; i++)
517 data.v[i] = p.data.v[i];
525 return data.v[index];
546 for (
int i = 0; i < LEN; i++)
554 for (
int i = 0; i < LEN; i++)
562 for (
int i = 0; i < LEN; i++)
563 if (fabs(data.v[i]-b.data.v[i]) >
VEQUALITY)
return false;
572 for (
int i = 0; i < LEN; i++)
573 r.v[i] = data.v[i] + b.data.v[i];
582 for (
int i = 0; i < LEN; i++)
583 r.v[i] = data.v[i] - b.data.v[i];
592 for (
int i = 0; i < LEN; i++)
593 r.v[i] = data.v[i] * b.data.v[i];
602 for (
int i = 0; i < LEN; i++)
603 r.v[i] = data.v[i] / b.data.v[i];
612 for (
int i = 0; i < LEN; i++)
613 r.v[i] = data.v[i] * s.data.v[i] + b.data.v[i];
622 for (
int i = 0; i < LEN; i++)
623 r.v[i] = data.v[i] * s + b.data.v[i];
631 double val = identity;
632 for (
int i = limit-1; i >= 0; i--) {
633 val = op(data.v[i], val);
641 double val = identity;
642 for (
int i = 0; i < limit; i++) {
643 val = op(val, data.v[i]);
653 for (
int i = 0; i < limit; i++) {
654 r.v[i] = op(data.v[i]);
665 for (
int i = 0; i < LEN; i++) {
681 vec2d(
double xin,
double yin) {
685 vec2d(
const vec2d& proto) {
686 _init(proto.v[0], proto.v[1]);
689 vec2d& operator=(
const vec2d& b) {
695 double operator[](
int index)
const {
return v[index]; }
697 double x()
const {
return v[0]; }
698 double y()
const {
return v[1]; }
700 vec2d operator+(
const vec2d& b)
const {
701 return vec2d(v[0] + b.v[0], v[1] + b.v[1]);
704 vec2d operator-(
const vec2d& b)
const {
705 return vec2d(v[0] - b.v[0], v[1] - b.v[1]);
708 vec2d operator*(
const vec2d& b)
const {
709 return vec2d(v[0] * b.v[0], v[1] * b.v[1]);
712 vec2d operator/(
const vec2d& b)
const {
713 return vec2d(v[0] / b.v[0], v[1] / b.v[1]);
716 vec2d madd(
const double& scalar,
const vec2d& b)
const {
717 return vec2d(v[0]*scalar+b.v[0], v[1]*scalar+b.v[1]);
720 vec2d madd(
const vec2d& s,
const vec2d& b)
const {
721 return vec2d(v[0]*s.v[0]+b.v[0], v[1]*s.v[1]+b.v[1]);
728 void _init(
double xin,
double yin) {
730 v = (
double*)((((uintptr_t)m) + 0x10L) & ~0xFL);
739 out <<
"<" << v.x() <<
"," << v.y() <<
">";
746inline bool vequals(
const vec2d& a,
const vec2d& b) {
767 pt2d_t _a = {m[0], m[1]};
768 pt2d_t _b = {m[3], m[2]};
775 double tmp[4]
VEC_ALIGN = {m[3], -m[1], -m[2], m[0]};
784 pt2d_t _a = {m[0], m[2]};
785 pt2d_t _b = {m[1], m[3]};
809void move(pt2d_t a,
const double *b) {
double operator()(double a, double b) const
double operator()(double a, double b) const
double operator()(double a) const
double operator()(double a, double b) const
virtual double operator()(double a, double b) const =0
virtual double operator()(double a) const =0
void u_store(double *arr) const
dvec< LEN > operator-(const dvec< LEN > &b)
double foldr(double proto, const dvec_op &operation, int limit=LEN)
dvec< LEN > operator+(const dvec< LEN > &b)
void a_store(double *arr) const
dvec< LEN > madd(const double s, const dvec< LEN > &b)
dvec(const dvec< LEN > &p)
dvec< LEN > & operator=(const dvec< LEN > &p)
dvec< LEN > madd(const dvec< LEN > &s, const dvec< LEN > &b)
bool operator==(const dvec< LEN > &b) const
void a_store(float *arr) const
dvec< LEN > operator/(const dvec< LEN > &b)
dvec< LEN > operator*(const dvec< LEN > &b)
double operator[](int index) const
double foldl(double proto, const dvec_op &operation, int limit=LEN)
void u_store(float *arr) const
dvec< LEN > map(const dvec_unop &operation, int limit=LEN)
Header file for the BRL-CAD common definitions.
fastf_t mat2d_t[4] VEC_ALIGN
void pt2dsub(pt2d_t r, pt2d_t a, pt2d_t b)
std::ostream & operator<<(std::ostream &out, const dvec< LEN > &v)
void mat2d_pt2d_mul(pt2d_t r, mat2d_t m, pt2d_t p)
bool mat2d_inverse(mat2d_t inv, mat2d_t m)
bool vequals(const vec2d &a, const vec2d &b)
void move(pt2d_t a, const double *b)
void int float float float * scale
#define __attribute__(ignore)
double fastf_t
fastest 64-bit (or larger) floating point type
#define NEAR_ZERO(val, epsilon)
fundamental vector, matrix, quaternion math macros