mirror of https://github.com/emgucv/emgucv.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.1 KiB
76 lines
2.1 KiB
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 2004-2021 by EMGU Corporation. All rights reserved.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#ifndef EMGU_DOUBLE_OPS_H
|
|
#define EMGU_DOUBLE_OPS_H
|
|
|
|
#include "sse.h"
|
|
namespace doubleOps
|
|
{
|
|
inline void weightedSum(const double* d1, const double* d2, int elementCount, double w1, double w2, double* r)
|
|
{
|
|
double* end = r + elementCount;
|
|
#if EMGU_SSE2
|
|
__m128d f = _mm_set_pd(w1, w2);
|
|
|
|
#if EMGU_SSE4_1
|
|
if(simdSSE4_1)
|
|
{
|
|
while(r < end) _mm_store_sd(r++, _mm_dp_pd(_mm_set_pd(*d1++, *d2++), f, 0x33));
|
|
return;
|
|
}
|
|
#endif
|
|
while (r < end)
|
|
{
|
|
__m128d v = _mm_mul_pd(_mm_set_pd(*d1++, *d2++), f);
|
|
_mm_store_sd(r++, _mm_add_pd(v, _mm_shuffle_pd(v, v, 1)));
|
|
}
|
|
#else
|
|
while( r < end)
|
|
*r++ = *d1++ * w1 + *d2++ * w2;
|
|
#endif
|
|
}
|
|
|
|
inline void mulS(const double* d, double scale, int length, double* result)
|
|
{
|
|
const double* current = d;
|
|
const double* end = d+length;
|
|
#if EMGU_SSE2
|
|
__m128d _scale = _mm_set1_pd(scale);
|
|
for(const double* stop = d + (length & -2); current < stop; current+=2, result+=2)
|
|
_mm_storeu_pd(result,_mm_mul_pd(_mm_loadu_pd(current), _scale));
|
|
#endif
|
|
while (current < end)
|
|
{
|
|
*result++ = (*current++) * scale;
|
|
}
|
|
}
|
|
|
|
inline void add(const double* d1, const double* d2, int length, double* result)
|
|
{
|
|
const double* current1 = d1;
|
|
const double* current2 = d2;
|
|
const double* end1 = d1 + length;
|
|
#if EMGU_SSE2
|
|
for(const double* stop1 = d1 + (length &-2); current1 < stop1; current1+=2, current2 +=2, result +=2)
|
|
_mm_storeu_pd(result, _mm_add_pd(_mm_loadu_pd(current1), _mm_loadu_pd(current2)));
|
|
#endif
|
|
while(current1 < end1)
|
|
{
|
|
*result++ = (*current1++) + (*current2++);
|
|
}
|
|
}
|
|
|
|
inline bool containsNaN(const double* d, int length)
|
|
{
|
|
for (int i = 0; i < length; i++)
|
|
if (d[i] != d[i]) return true;
|
|
return false;
|
|
}
|
|
}
|
|
#endif
|