Added own camera object and its vectorial dependency.

This commit is contained in:
Martin Felis
2021-11-12 11:00:39 +01:00
parent b78045ffe7
commit 94cc4aeb1d
53 changed files with 7413 additions and 50 deletions
+229
View File
@@ -0,0 +1,229 @@
/* Specific - Minimal C++ spec framework.
The zlib/libpng License
Copyright (c) 2008 Mikko Lehtonen
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "spec.h"
#include <iostream>
namespace specific {
void SpecWriter::startGroup(std::string /*group*/, std::string /*description*/) {}
void SpecWriter::addFailedAssertation(std::string msg, const char *file, int line) {
mFailures.push_back( SpecFailure(msg,file,line) );
}
void SpecWriter::addSpecResult(SpecResult r) {
mResults.push_back( r );
}
void SpecWriter::start() {}
void SpecWriter::stop() {
std::cout << std::endl;
size_t nth = 0;
for(std::vector<SpecFailure>::iterator i=mFailures.begin(); i != mFailures.end(); ++i, ++nth)
{
std::cout << std::endl;
std::cout << (nth+1) << ") Failed assertation at " << i->file << ":"
<< i->line << ":" << std::endl << " " << i->msg << std::endl;
}
std::cout << std::endl << mResults.size() << " examples, " << mFailures.size() << " failures" << std::endl;
}
void ProgressWriter::addSpecResult(SpecResult r) {
SpecWriter::addSpecResult(r);
switch(r.type) {
case SpecResult::PASSED:
std::cout << ".";
break;
case SpecResult::FAILED:
std::cout << "F";
break;
case SpecResult::ERRORED:
std::cout << "E";
break;
}
std::cout << std::flush;
}
void SpecdocWriter::startGroup(std::string group, std::string description) {
std::cout << group << ": " << description << std::endl;
}
void SpecdocWriter::addSpecResult(SpecResult r) {
SpecWriter::addSpecResult(r);
size_t nth = mFailures.size();
std::cout << "- " << r.test;
switch(r.type) {
case SpecResult::PASSED:
std::cout << " [OK]";
break;
case SpecResult::FAILED:
std::cout << " [FAILED - " << nth << "]";
break;
case SpecResult::ERRORED:
std::cout << " [ERROR - "<< nth <<"]";
break;
}
std::cout << std::endl;
}
class spec_failure {};
SpecBase::SpecBase() : mWriter(NULL), mName(NULL),
mFailed(false), mLastFailed(false), mError(false), mExecutionPoint(0), mContinuePoint(0)
{
SpecRunner::getInstance().add(this);
}
SpecBase::~SpecBase() {
}
bool SpecBase::startSpec(const char* name)
{
endSpec();
mExecutionPoint++;
if(mExecutionPoint <= mContinuePoint) return false;
mContinuePoint++;
mName = name;
return true;
}
void SpecBase::endSpec()
{
if(!mName) return;
SpecResult r;
r.group = getGroup();
r.description = getDescription();
r.type = SpecResult::PASSED;
if(mLastFailed) r.type = SpecResult::FAILED;
if(mError) r.type = SpecResult::ERRORED;
r.test = mName;
mWriter->addSpecResult( r );
mName = NULL;
}
void SpecBase::should_test(bool value, const char* message, const char* file, int line) {
mLastFailed=false;
if(!value) {
mWriter->addFailedAssertation(message, file, line);
mLastFailed = mFailed = true;
throw spec_failure();
}
}
void SpecBase::error(std::string msg) {
mWriter->addFailedAssertation(msg, "exception", 0);
mLastFailed = true;
mFailed = true;
mError = true;
}
bool SpecBase::done() {
if( mError ) {
mError = false;
return false;
}
return true;
}
SpecRunner::SpecRunner() {}
SpecRunner::~SpecRunner() { }
SpecRunner& SpecRunner::getInstance() {
static SpecRunner* instance = NULL;
if( instance == NULL ) {
instance = new SpecRunner;
}
return *instance;
}
bool SpecRunner::run(SpecWriter& writer, const std::string subset) {
bool success = true;
writer.start();
std::vector<SpecBase*>::iterator i = mSpecs.begin();
for(; i != mSpecs.end(); ++i) {
SpecBase *b = *i;
if( b->getGroup().find(subset, 0) == std::string::npos ) continue;
b->mContinuePoint = 0;
b->setWriter(&writer);
writer.startGroup( b->getGroup(), b->getDescription() );
do {
b->mExecutionPoint = 0;
try {
b->specify();
} catch(spec_failure& e) {
b->mError=true;
} catch( std::exception& e) {
b->error(e.what());
} catch( ... ) {
b->error("unknown exception");
}
b->endSpec();
} while( !b->done() );
success = success && b->isSuccessful();
}
writer.stop();
return success;
}
}
+217
View File
@@ -0,0 +1,217 @@
/* Specific - Minimal C++ spec framework.
The zlib/libpng License
Copyright (c) 2008 Mikko Lehtonen
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef SPECIFIC_SPEC_H
#define SPECIFIC_SPEC_H
#include <string>
#include <vector>
#include <stdexcept>
#include <sstream>
namespace specific {
class SpecResult {
public:
typedef enum {
PASSED,
FAILED,
ERRORED
} Type;
Type type;
std::string group;
std::string description;
std::string test;
};
class SpecFailure {
public:
SpecFailure(std::string amsg, const char* afile, int aline)
: msg(amsg), file(afile), line(aline) { }
std::string msg;
const char* file;
int line;
};
class SpecWriter {
public:
std::vector<SpecResult> mResults;
std::vector<SpecFailure> mFailures;
SpecWriter() {}
virtual ~SpecWriter() {}
virtual void startGroup(std::string group, std::string description);
virtual void addFailedAssertation(std::string msg, const char *file, int line);
virtual void addSpecResult(SpecResult r);
virtual void start();
virtual void stop();
};
class ProgressWriter : public SpecWriter {
public:
void addSpecResult(SpecResult r);
};
class SpecdocWriter : public SpecWriter {
public:
void startGroup(std::string group, std::string description);
void addSpecResult(SpecResult r);
};
template<class T> std::string inspect(const T& value) {
std::stringstream ss;
ss << value;
return ss.str();
}
class SpecBase {
public:
SpecBase();
virtual ~SpecBase();
virtual void specify() = 0;
void setWriter(SpecWriter* w) { mWriter = w; }
bool startSpec(const char* name);
void endSpec();
void should_test(bool value, const char* message, const char* file, int line);
template<typename T1, typename T2> void should_equal_template(const T1& a, const T2& b, const char* file, int line) {
std::stringstream ss;
ss << "`" << ::specific::inspect(a) << "'" << " == " << "`" << ::specific::inspect(b) << "'";
should_test( a == b, ss.str().c_str(), file, line);
}
template<typename T1, typename T2> void should_not_equal_template(const T1& a, const T2& b, const char* file, int line) {
std::stringstream ss;
ss << "`" << ::specific::inspect(a) << "'" << " != " << "`" << ::specific::inspect(b) << "'";
should_test( a != b, ss.str().c_str(), file, line);
}
virtual std::string getGroup() = 0;
virtual std::string getDescription() = 0;
bool isSuccessful() { return !mFailed; }
bool done();
void error(std::string msg);
SpecWriter* mWriter;
const char* mName;
bool mFailed;
bool mLastFailed;
bool mError;
int mExecutionPoint;
int mContinuePoint;
char *mFile;
std::string mErrorMessage;
int mLine;
};
class SpecRunner {
public:
static SpecRunner& getInstance();
void add(SpecBase* spec) { mSpecs.push_back( spec ); }
bool run(SpecWriter& writer, const std::string subset = "");
private:
std::vector<SpecBase*> mSpecs;
SpecRunner();
~SpecRunner();
};
#define SPEC_UNIQUE_NAME3(x,y) x##y
#define SPEC_UNIQUE_NAME2(x,y) SPEC_UNIQUE_NAME3(x,y)
#define SPEC_NAME(x) SPEC_UNIQUE_NAME2(SPEC_##x, SPEC_UNIQUE_NAME2(_startingOnLine, __LINE__) )
#define describe(group, description) \
class SPEC_NAME(group) : public specific::SpecBase \
{ \
public: \
void specify(); \
std::string getGroup() { return #group; } \
std::string getDescription() { return description; } \
}; \
static SPEC_NAME(group) SPEC_UNIQUE_NAME2(SPEC_NAME(group), _instance); \
void SPEC_NAME(group)::specify()
#define it(description) if(startSpec(description))
// Matchers
#define should_be_true(a) should_test(a, #a, __FILE__, __LINE__)
#define should_be_false(a) should_be_true( !a )
#ifndef SPECIFIC_NO_OSTREAM
#define should_equal(a, b) should_equal_template( a,b, __FILE__, __LINE__ )
#define should_not_equal(a, b) should_not_equal_template( a,b, __FILE__, __LINE__ )
#else
#define should_equal(a, b) should_be_true( (a) == (b) )
#define should_not_equal(a, b) should_be_true( (a) != (b) )
#endif
#define should_throw(code, what) \
do { \
bool _thrown = false; \
try { \
code ; \
} catch(what& e) { \
_thrown = true; \
} \
should_test(_thrown, "should throw exception " #what, __FILE__, __LINE__); \
} while(0)
}
#endif /* Include guard */
+215
View File
@@ -0,0 +1,215 @@
#ifndef VECTORIAL_SPEC_HELPER_H
#define VECTORIAL_SPEC_HELPER_H
#define VECTORIAL_OSTREAM
#include "spec.h"
#include "vectorial/vectorial.h"
#ifdef VECTORIAL_HAVE_SIMD2F
#include "vectorial/simd2f.h"
#endif
#include <cmath>
#include <cstdlib>
#include <iostream>
#define should_be_close_to(a,b,tolerance) should_be_close_to_(this, a,b,tolerance,__FILE__,__LINE__)
#define should_be_equal_simd4f( a, b, tolerance) should_be_equal_simd4f_(this, a,b,tolerance,__FILE__,__LINE__)
#define should_be_equal_simd2f( a, b, tolerance) should_be_equal_simd2f_(this, a,b,tolerance,__FILE__,__LINE__)
#define should_be_equal_vec4f( a, b, tolerance) should_be_equal_vec4f_(this, a,b,tolerance,__FILE__,__LINE__)
#define should_be_equal_vec3f( a, b, tolerance) should_be_equal_vec3f_(this, a,b,tolerance,__FILE__,__LINE__)
#define should_be_equal_vec2f( a, b, tolerance) should_be_equal_vec2f_(this, a,b,tolerance,__FILE__,__LINE__)
#define should_be_equal_simd4x4f( a, b, tolerance) should_be_equal_simd4x4f_(this, a,b,tolerance,__FILE__,__LINE__)
#define should_be_equal_mat4f( a, b, tolerance) should_be_equal_mat4f_(this, a,b,tolerance,__FILE__,__LINE__)
// Based on:
// http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
//
static inline bool compare_floats(float A, float B, int maxUlps)
{
// Make sure maxUlps is non-negative and small enough that the
// default NAN won't compare as equal to anything.
// assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
union {
float f;
int i;
} f2iA, f2iB;
f2iA.f = A;
f2iB.f = B;
int aInt = f2iA.i;
// int aInt = *(int*)&A;
// Make aInt lexicographically ordered as a twos-complement int
if (aInt < 0)
aInt = 0x80000000 - aInt;
// Make bInt lexicographically ordered as a twos-complement int
int bInt = f2iB.i;
// int bInt = *(int*)&B;
if (bInt < 0)
bInt = 0x80000000 - bInt;
int intDiff = abs(aInt - bInt);
if (intDiff <= maxUlps)
return true;
return false;
}
static inline void should_be_close_to_(specific::SpecBase *spec, float a, float b, int tolerance, const char *file, int line) {
bool equal=true;
if( !compare_floats(a,b,tolerance) ) equal = false;
std::stringstream ss;
ss << a << " == " << b << " (with tolerance of " << tolerance << ")";
spec->should_test(equal, ss.str().c_str(), file, line);
}
#ifdef VECTORIAL_HAVE_SIMD2F
static inline void should_be_equal_simd2f_(specific::SpecBase *spec, const simd2f& a, const simd2f& b, int tolerance, const char *file, int line) {
bool equal=true;
if( !compare_floats( simd2f_get_x(a), simd2f_get_x(b), tolerance) ) equal = false;
if( !compare_floats( simd2f_get_y(a), simd2f_get_y(b), tolerance) ) equal = false;
std::stringstream ss;
ss << a << " == " << b << " (with tolerance of " << tolerance << ")";
spec->should_test(equal, ss.str().c_str(), file, line);
}
#endif
static inline void should_be_equal_simd4f_(specific::SpecBase *spec, const simd4f& a, const simd4f& b, int tolerance, const char *file, int line) {
bool equal=true;
if( !compare_floats( simd4f_get_x(a), simd4f_get_x(b), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_y(a), simd4f_get_y(b), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_z(a), simd4f_get_z(b), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_w(a), simd4f_get_w(b), tolerance) ) equal = false;
std::stringstream ss;
ss << a << " == " << b << " (with tolerance of " << tolerance << ")";
spec->should_test(equal, ss.str().c_str(), file, line);
}
static inline void should_be_equal_vec4f_(specific::SpecBase *spec, const vectorial::vec4f& a, const vectorial::vec4f& b, int tolerance, const char *file, int line) {
bool equal=true;
if( !compare_floats( a.x(), b.x(), tolerance) ) equal = false;
if( !compare_floats( a.y(), b.y(), tolerance) ) equal = false;
if( !compare_floats( a.z(), b.z(), tolerance) ) equal = false;
if( !compare_floats( a.w(), b.w(), tolerance) ) equal = false;
std::stringstream ss;
ss << a << " == " << b << " (with tolerance of " << tolerance << ")";
spec->should_test(equal, ss.str().c_str(), file, line);
}
static inline void should_be_equal_vec3f_(specific::SpecBase *spec, const vectorial::vec3f& a, const vectorial::vec3f& b, int tolerance, const char *file, int line) {
bool equal=true;
if( !compare_floats( a.x(), b.x(), tolerance) ) equal = false;
if( !compare_floats( a.y(), b.y(), tolerance) ) equal = false;
if( !compare_floats( a.z(), b.z(), tolerance) ) equal = false;
std::stringstream ss;
ss << a << " == " << b << " (with tolerance of " << tolerance << ")";
spec->should_test(equal, ss.str().c_str(), file, line);
}
static inline void should_be_equal_vec2f_(specific::SpecBase *spec, const vectorial::vec2f& a, const vectorial::vec2f& b, int tolerance, const char *file, int line) {
bool equal=true;
if( !compare_floats( a.x(), b.x(), tolerance) ) equal = false;
if( !compare_floats( a.y(), b.y(), tolerance) ) equal = false;
std::stringstream ss;
ss << a << " == " << b << " (with tolerance of " << tolerance << ")";
spec->should_test(equal, ss.str().c_str(), file, line);
}
static inline void should_be_equal_simd4x4f_(specific::SpecBase *spec, const simd4x4f& a, const simd4x4f& b, int tolerance, const char *file, int line) {
bool equal=true;
if( !compare_floats( simd4f_get_x(a.x), simd4f_get_x(b.x), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_y(a.x), simd4f_get_y(b.x), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_z(a.x), simd4f_get_z(b.x), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_w(a.x), simd4f_get_w(b.x), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_x(a.y), simd4f_get_x(b.y), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_y(a.y), simd4f_get_y(b.y), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_z(a.y), simd4f_get_z(b.y), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_w(a.y), simd4f_get_w(b.y), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_x(a.z), simd4f_get_x(b.z), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_y(a.z), simd4f_get_y(b.z), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_z(a.z), simd4f_get_z(b.z), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_w(a.z), simd4f_get_w(b.z), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_x(a.w), simd4f_get_x(b.w), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_y(a.w), simd4f_get_y(b.w), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_z(a.w), simd4f_get_z(b.w), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_w(a.w), simd4f_get_w(b.w), tolerance) ) equal = false;
std::stringstream ss;
ss << a << " == " << b << " (with tolerance of " << tolerance << ")";
spec->should_test(equal, ss.str().c_str(), file, line);
}
static inline void should_be_equal_mat4f_(specific::SpecBase *spec, const vectorial::mat4f& a, const vectorial::mat4f& b, int tolerance, const char *file, int line) {
bool equal=true;
if( !compare_floats( simd4f_get_x(a.value.x), simd4f_get_x(b.value.x), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_y(a.value.x), simd4f_get_y(b.value.x), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_z(a.value.x), simd4f_get_z(b.value.x), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_w(a.value.x), simd4f_get_w(b.value.x), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_x(a.value.y), simd4f_get_x(b.value.y), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_y(a.value.y), simd4f_get_y(b.value.y), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_z(a.value.y), simd4f_get_z(b.value.y), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_w(a.value.y), simd4f_get_w(b.value.y), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_x(a.value.z), simd4f_get_x(b.value.z), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_y(a.value.z), simd4f_get_y(b.value.z), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_z(a.value.z), simd4f_get_z(b.value.z), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_w(a.value.z), simd4f_get_w(b.value.z), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_x(a.value.w), simd4f_get_x(b.value.w), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_y(a.value.w), simd4f_get_y(b.value.w), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_z(a.value.w), simd4f_get_z(b.value.w), tolerance) ) equal = false;
if( !compare_floats( simd4f_get_w(a.value.w), simd4f_get_w(b.value.w), tolerance) ) equal = false;
std::stringstream ss;
ss << a << " == " << b << " (with tolerance of " << tolerance << " ulps)";
spec->should_test(equal, ss.str().c_str(), file, line);
}
#endif
+55
View File
@@ -0,0 +1,55 @@
/* Specific - Minimal C++ spec framework.
The zlib/libpng License
Copyright (c) 2008 Mikko Lehtonen
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "spec.h"
#include <cstdlib>
int main(int argc, char *argv[])
{
std::string subset("");
specific::ProgressWriter progressWriter;
specific::SpecdocWriter specdocWriter;
specific::SpecWriter* writer = &progressWriter;
for(size_t i = 1; i < size_t(argc); ++i) {
if( std::string("-s") == argv[i] ) {
writer = &specdocWriter;
} else {
subset = argv[i];
}
}
bool success = specific::SpecRunner::getInstance().run(*writer, subset);
return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
+29
View File
@@ -0,0 +1,29 @@
#include "spec_helper.h"
#include <iostream>
using vectorial::vec4f;
using vectorial::mat4f;
const int epsilon = 1;
describe(mat4f, "constructing") {
it("should have default constructor that does nothing..") {
mat4f x;
}
it("should have constructor that constructs from four vec4") {
mat4f x( vec4f(1,2,3,4), vec4f(5,6,7,8), vec4f(9,10,11,12), vec4f(13,14,15,16) );
// octave mat4f: [1,5,9,13 ; 2,6,10,14 ; 3,7,11,15 ; 4,8,12,16 ]
should_be_equal_mat4f(x, simd4x4f_create(simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 4.000000000000000f), simd4f_create(5.000000000000000f, 6.000000000000000f, 7.000000000000000f, 8.000000000000000f), simd4f_create(9.000000000000000f, 10.000000000000000f, 11.000000000000000f, 12.000000000000000f), simd4f_create(13.000000000000000f, 14.000000000000000f, 15.000000000000000f, 16.000000000000000f)), epsilon );
}
it("should have static function to create identity matrix") {
mat4f x = mat4f::identity();
// octave mat4f: [1,0,0,0;0,1,0,0;0,0,1,0;0,0,0,1]
should_be_equal_mat4f(x, simd4x4f_create(simd4f_create(1.000000000000000f, 0.000000000000000f, 0.000000000000000f, 0.000000000000000f), simd4f_create(0.000000000000000f, 1.000000000000000f, 0.000000000000000f, 0.000000000000000f), simd4f_create(0.000000000000000f, 0.000000000000000f, 1.000000000000000f, 0.000000000000000f), simd4f_create(0.000000000000000f, 0.000000000000000f, 0.000000000000000f, 1.000000000000000f)), epsilon );
}
}
+242
View File
@@ -0,0 +1,242 @@
#include "spec_helper.h"
const int epsilon = 1;
#ifdef VECTORIAL_HAVE_SIMD2F
describe(simd2f, "sanity") {
it("VECTORIAL_SIMD_TYPE should be defined to a string") {
std::cout << "Simd type: " << VECTORIAL_SIMD_TYPE << std::endl;
}
}
describe(simd2f, "creating") {
it("should be possible to create with simd2f_create") {
simd2f x = simd2f_create(1, 2);
should_be_close_to( simd2f_get_x(x), 1, epsilon);
should_be_close_to( simd2f_get_y(x), 2, epsilon);
// octave simd2f: [1,2]
should_be_equal_simd2f(x, simd2f_create(1.000000000000000f, 2.000000000000000f), epsilon );
}
it("should have simd2f_zero for zero vector") {
simd2f x = simd2f_zero();
// octave simd2f: [0,0]
should_be_equal_simd2f(x, simd2f_create(0.000000000000000f, 0.000000000000000f), epsilon );
}
}
#ifdef _MSC_VER
#include <malloc.h>
#else
#include <alloca.h>
#endif
#define unaligned_mem(n) ((float*)((unsigned char*)alloca(sizeof(float)*n+4)+4))
describe(simd2f, "utilities") {
it("should have simd2f_uload2 for loading two float values from float an unaligned array into simd2f") {
float *f = unaligned_mem(2);
f[0] = 1;
f[1] = 2;
simd2f x = simd2f_uload2(f);
// octave simd2f: [1,2]
should_be_equal_simd2f(x, simd2f_create(1.000000000000000f, 2.000000000000000f), epsilon );
}
it("should have simd2f_ustore2 for storing two float values from simd2f to an unaligned array") {
float *f = unaligned_mem(2);
f[0] = -1;
f[1] = -1;
simd2f a = simd2f_create(1,2);
simd2f_ustore2(a, f);
should_be_close_to(f[0], 1, epsilon);
should_be_close_to(f[1], 2, epsilon);
}
it("should have simd2f_splat that expands a single scalar to all elements") {
simd2f x = simd2f_splat(42);
// octave simd2f: [42,42]
should_be_equal_simd2f(x, simd2f_create(42.000000000000000f, 42.000000000000000f), epsilon );
}
it("should have simd2f_splat_x,y splatting of an element") {
simd2f a = simd2f_create(1,2);
simd2f x;
x = simd2f_splat_x(a);
// octave simd2f: [1,1]
should_be_equal_simd2f(x, simd2f_create(1.000000000000000f, 1.000000000000000f), epsilon );
x = simd2f_splat_y(a);
// octave simd2f: [2,2]
should_be_equal_simd2f(x, simd2f_create(2.000000000000000f, 2.000000000000000f), epsilon );
}
#if 0
it("should have simd2f_sum that adds elements") {
simd2f a = simd2f_create(1,2);
simd2f x = simd2f_sum(a);
// octave simd2f: [sum([1,2]), sum([1,2,3,4])]
should_be_equal_simd2f(x, simd2f_create(3.000000000000000f, 10.000000000000000f), epsilon );
}
#endif
it("should have simd2f_reciprocal") {
simd2f a = simd2f_create(0.00001f, 2.00001f);
simd2f x = simd2f_reciprocal(a);
// octave simd2f: 1 ./ [0.00001, 2.00001]
should_be_equal_simd2f(x, simd2f_create(99999.999999999985448f, 0.499997500012500f), epsilon );
}
it("should have simd2f_sqrt") {
simd2f a = simd2f_create(0.00001f, 2.00001f);
simd2f x = simd2f_sqrt(a);
// octave simd2f: sqrt([0.00001, 2.00001])
should_be_equal_simd2f(x, simd2f_create(0.003162277660168f, 1.414217097902582f), epsilon );
x = simd2f_sqrt( simd2f_create(0.0f, 0.0f) );
// octave simd2f: sqrt([0, 0])
should_be_equal_simd2f(x, simd2f_create(0.000000000000000f, 0.000000000000000f), epsilon );
}
it("should have simd2f_rsqrt for reciprocal of square-root") {
simd2f a = simd2f_create(0.00001f, 2.00001f);
simd2f x = simd2f_rsqrt(a);
const int epsilon = 4; // Grant larger error
// octave simd2f: 1 ./ sqrt([0.00001, 2.00001])
should_be_equal_simd2f(x, simd2f_create(316.227766016837904f, 0.707105013426224f), epsilon );
}
}
describe(simd2f, "arithmetic with another simd2f") {
it("should have simd2f_add for component-wise addition") {
simd2f a = simd2f_create(1,2);
simd2f b = simd2f_create(10,20);
simd2f x = simd2f_add(a,b);
// octave simd2f: [1,2] + [10,20]
should_be_equal_simd2f(x, simd2f_create(11.000000000000000f, 22.000000000000000f), epsilon );
}
it("should have simd2f_sub for component-wise subtraction") {
simd2f a = simd2f_create(1,2);
simd2f b = simd2f_create(10,20);
simd2f x = simd2f_sub(b,a);
// octave simd2f: [10,20] - [1,2]
should_be_equal_simd2f(x, simd2f_create(9.000000000000000f, 18.000000000000000f), epsilon );
}
it("should have simd2f_mul for component-wise multiply") {
simd2f a = simd2f_create(1,2);
simd2f b = simd2f_create(10,20);
simd2f x = simd2f_mul(a,b);
// octave simd2f: [1,2] .* [10,20]
should_be_equal_simd2f(x, simd2f_create(10.000000000000000f, 40.000000000000000f), epsilon );
}
it("should have simd2f_div for component-wise division") {
simd2f a = simd2f_create(1,2);
simd2f b = simd2f_create(10,20);
simd2f x = simd2f_div(b,a);
// octave simd2f: [10,20] ./ [1,2]
should_be_equal_simd2f(x, simd2f_create(10.000000000000000f, 10.000000000000000f), epsilon );
}
it("should have simd2f_madd for multiply-add") {
simd2f a = simd2f_create(1,2);
simd2f b = simd2f_create(100,100);
simd2f c = simd2f_create(6,7);
simd2f x = simd2f_madd(a,b,c);
// octave simd2f: [1,2] .* [100,100] .+ [6,7]
should_be_equal_simd2f(x, simd2f_create(106.000000000000000f, 207.000000000000000f), epsilon );
}
}
describe(simd2f, "vector math") {
it("should have simd2f_dot2 for two component dot product") {
simd2f a = simd2f_create(1,2);
simd2f b = simd2f_create(10,20);
simd2f x = simd2f_dot2(a,b);
// octave simd2f: [dot([1, 2], [10, 20]),dot([1, 2], [10, 20])]
should_be_equal_simd2f(x, simd2f_create(50.000000000000000f, 50.000000000000000f), epsilon );
}
it("should have simd2f_length2 for two component vector length") {
simd2f a = simd2f_create(1,2);
simd2f x = simd2f_length2(a);
// octave simd2f: [norm([1,2]),norm([1,2])]
should_be_equal_simd2f(x, simd2f_create(2.236067977499790f, 2.236067977499790f), epsilon );
}
it("should have simd2f_length2_squared for two component squared vector length") {
simd2f a = simd2f_create(1,2);
simd2f x = simd2f_length2_squared(a);
// octave simd2f: ([dot([1,2], [1,2]), dot([1,2], [1,2])])
should_be_equal_simd2f(x, simd2f_create(5.000000000000000f, 5.000000000000000f), epsilon );
}
it("should have simd2f_normalize2 for normalizing two component vector to unit length") {
simd2f a = simd2f_create(1,2);
simd2f x = simd2f_normalize2(a);
// octave simd2f: [1,2] / norm([1,2])
should_be_equal_simd2f(x, simd2f_create(0.447213595499958f, 0.894427190999916f), epsilon );
}
}
describe(simd2f, "min-max") {
it("should have simd2f_min for choosing minimum elements") {
simd2f a = simd2f_create(1.0f, 2.0f);
simd2f b = simd2f_create(2.0f, -2.0f);
simd2f x = simd2f_min(a,b);
should_be_equal_simd2f(x, simd2f_create(1.0f, -2.0f), epsilon);
}
it("should have simd2f_max for choosing maximum elements") {
simd2f a = simd2f_create(1.0f, 2.0f);
simd2f b = simd2f_create(2.0f, -2.0f);
simd2f x = simd2f_max(a,b);
should_be_equal_simd2f(x, simd2f_create(2.0f, 2.0f), epsilon);
}
}
#endif
+457
View File
@@ -0,0 +1,457 @@
#include "spec_helper.h"
const int epsilon = 1;
describe(simd4f, "sanity") {
it("VECTORIAL_SIMD_TYPE should be defined to a string") {
std::cout << "Simd type: " << VECTORIAL_SIMD_TYPE << std::endl;
}
}
describe(simd4f, "creating") {
it("should be possible to create with simd4f_create") {
simd4f x = simd4f_create(1, 2, 3, 4);
should_be_close_to( simd4f_get_x(x), 1, epsilon);
should_be_close_to( simd4f_get_y(x), 2, epsilon);
should_be_close_to( simd4f_get_z(x), 3, epsilon);
should_be_close_to( simd4f_get_w(x), 4, epsilon);
// octave simd4f: [1,2,3,4]
should_be_equal_simd4f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 4.000000000000000f), epsilon );
}
it("should have simd4f_zero for zero vector") {
simd4f x = simd4f_zero();
// octave simd4f: [0,0,0,0]
should_be_equal_simd4f(x, simd4f_create(0.000000000000000f, 0.000000000000000f, 0.000000000000000f, 0.000000000000000f), epsilon );
}
}
#ifdef _MSC_VER
#include <malloc.h>
#else
#include <alloca.h>
#endif
#define unaligned_mem(n) ((float*)((unsigned char*)alloca(sizeof(float)*n+4)+4))
describe(simd4f, "utilities") {
it("should have simd4f_uload4 for loading four float values from an unaligned float array into simd4f") {
float *f = unaligned_mem(4);
f[0] = 1;
f[1] = 2;
f[2] = 3;
f[3] = 4;
simd4f x = simd4f_uload4(f);
// octave simd4f: [1,2,3,4]
should_be_equal_simd4f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 4.000000000000000f), epsilon );
}
it("should have simd4f_uload3 for loading three float values from an unaligned float array into simd4f") {
float *f = unaligned_mem(3);
f[0] = 1;
f[1] = 2;
f[2] = 3;
simd4f x = simd4f_uload3(f);
// octave simd4f: [1,2,3]
should_be_equal_simd4f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 0.0f), epsilon );
}
it("should have simd4f_uload2 for loading two float values from float an unaligned array into simd4f") {
float *f = unaligned_mem(2);
f[0] = 1;
f[1] = 2;
simd4f x = simd4f_uload2(f);
// octave simd4f: [1,2]
should_be_equal_simd4f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have simd4f_ustore4 for storing four float values from simd4f to an unaligned array") {
float *f = unaligned_mem(4);
f[0] = -1;
f[1] = -1;
f[2] = -1;
f[3] = -1;
simd4f a = simd4f_create(1,2,3,4);
simd4f_ustore4(a, f);
should_be_close_to(f[0], 1, epsilon);
should_be_close_to(f[1], 2, epsilon);
should_be_close_to(f[2], 3, epsilon);
should_be_close_to(f[3], 4, epsilon);
}
it("should have simd4f_ustore3 for storing three float values from simd4f to an unaligned array") {
float *f = unaligned_mem(3);
f[0] = -1;
f[1] = -1;
f[2] = -1;
simd4f a = simd4f_create(1,2,3,4);
simd4f_ustore3(a, f);
should_be_close_to(f[0], 1, epsilon);
should_be_close_to(f[1], 2, epsilon);
should_be_close_to(f[2], 3, epsilon);
}
it("should have simd4f_ustore2 for storing two float values from simd4f to an unaligned array") {
float *f = unaligned_mem(2);
f[0] = -1;
f[1] = -1;
simd4f a = simd4f_create(1,2,3,4);
simd4f_ustore2(a, f);
should_be_close_to(f[0], 1, epsilon);
should_be_close_to(f[1], 2, epsilon);
}
it("should have simd4f_splat that expands a single scalar to all elements") {
simd4f x = simd4f_splat(42);
// octave simd4f: [42,42,42,42]
should_be_equal_simd4f(x, simd4f_create(42.000000000000000f, 42.000000000000000f, 42.000000000000000f, 42.000000000000000f), epsilon );
}
it("should have simd4f_splat_x,y,z,w splatting of an element") {
simd4f a = simd4f_create(1,2,3,4);
simd4f x;
x = simd4f_splat_x(a);
// octave simd4f: [1,1,1,1]
should_be_equal_simd4f(x, simd4f_create(1.000000000000000f, 1.000000000000000f, 1.000000000000000f, 1.000000000000000f), epsilon );
x = simd4f_splat_y(a);
// octave simd4f: [2,2,2,2]
should_be_equal_simd4f(x, simd4f_create(2.000000000000000f, 2.000000000000000f, 2.000000000000000f, 2.000000000000000f), epsilon );
x = simd4f_splat_z(a);
// octave simd4f: [3,3,3,3]
should_be_equal_simd4f(x, simd4f_create(3.000000000000000f, 3.000000000000000f, 3.000000000000000f, 3.000000000000000f), epsilon );
x = simd4f_splat_w(a);
// octave simd4f: [4,4,4,4]
should_be_equal_simd4f(x, simd4f_create(4.000000000000000f, 4.000000000000000f, 4.000000000000000f, 4.000000000000000f), epsilon );
}
it("should have simd4f_sum that adds elements") {
simd4f a = simd4f_create(1,2,3,4);
simd4f x = simd4f_sum(a);
// octave simd4f: [sum([1,2,3,4]), sum([1,2,3,4]), sum([1,2,3,4]), sum([1,2,3,4])]
should_be_equal_simd4f(x, simd4f_create(10.000000000000000f, 10.000000000000000f, 10.000000000000000f, 10.000000000000000f), epsilon );
}
it("should have simd4f_reciprocal") {
simd4f a = simd4f_create(0.00001f, 2.00001f, 3.0f, 99999999.0f);
simd4f x = simd4f_reciprocal(a);
// octave simd4f: 1 ./ [0.00001, 2.00001, 3.0, 99999999.0]
should_be_equal_simd4f(x, simd4f_create(99999.999999999985448f, 0.499997500012500f, 0.333333333333333f, 0.000000010000000f), epsilon );
}
it("should have simd4f_sqrt") {
simd4f a = simd4f_create(0.00001f, 2.00001f, 3.0f, 99999999.0f);
simd4f x = simd4f_sqrt(a);
// octave simd4f: sqrt([0.00001, 2.00001, 3.0, 99999999.0])
should_be_equal_simd4f(x, simd4f_create(0.003162277660168f, 1.414217097902582f, 1.732050807568877f, 9999.999949999999444f), epsilon );
x = simd4f_sqrt( simd4f_create(0.0f, 0.0f, 0.0f, 0.0f) );
// octave simd4f: sqrt([0, 0, 0, 0])
should_be_equal_simd4f(x, simd4f_create(0.000000000000000f, 0.000000000000000f, 0.000000000000000f, 0.000000000000000f), epsilon );
}
it("should have simd4f_rsqrt for reciprocal of square-root") {
simd4f a = simd4f_create(0.00001f, 2.00001f, 3.0f, 99999999.0f);
simd4f x = simd4f_rsqrt(a);
const int epsilon = 4; // Grant larger error
// octave simd4f: 1 ./ sqrt([0.00001, 2.00001, 3.0, 99999999.0])
should_be_equal_simd4f(x, simd4f_create(316.227766016837904f, 0.707105013426224f, 0.577350269189626f, 0.000100000000500f), epsilon );
}
}
describe(simd4f, "arithmetic with another simd4f") {
it("should have simd4f_add for component-wise addition") {
simd4f a = simd4f_create(1,2,3,4);
simd4f b = simd4f_create(10,20,30,40);
simd4f x = simd4f_add(a,b);
// octave simd4f: [1,2,3,4] + [10,20,30,40]
should_be_equal_simd4f(x, simd4f_create(11.000000000000000f, 22.000000000000000f, 33.000000000000000f, 44.000000000000000f), epsilon );
}
it("should have simd4f_sub for component-wise subtraction") {
simd4f a = simd4f_create(1,2,3,4);
simd4f b = simd4f_create(10,20,30,40);
simd4f x = simd4f_sub(b,a);
// octave simd4f: [10,20,30,40] - [1,2,3,4]
should_be_equal_simd4f(x, simd4f_create(9.000000000000000f, 18.000000000000000f, 27.000000000000000f, 36.000000000000000f), epsilon );
}
it("should have simd4f_mul for component-wise multiply") {
simd4f a = simd4f_create(1,2,3,4);
simd4f b = simd4f_create(10,20,30,40);
simd4f x = simd4f_mul(a,b);
// octave simd4f: [1,2,3,4] .* [10,20,30,40]
should_be_equal_simd4f(x, simd4f_create(10.000000000000000f, 40.000000000000000f, 90.000000000000000f, 160.000000000000000f), epsilon );
}
it("should have simd4f_div for component-wise division") {
simd4f a = simd4f_create(1,2,3,4);
simd4f b = simd4f_create(10,20,30,40);
simd4f x = simd4f_div(b,a);
// octave simd4f: [10,20,30,40] ./ [1,2,3,4]
should_be_equal_simd4f(x, simd4f_create(10.000000000000000f, 10.000000000000000f, 10.000000000000000f, 10.000000000000000f), epsilon );
}
it("should have simd4f_madd for multiply-add") {
simd4f a = simd4f_create(1,2,3,4);
simd4f b = simd4f_create(100,100,100,100);
simd4f c = simd4f_create(6,7,8,9);
simd4f x = simd4f_madd(a,b,c);
// octave simd4f: [1,2,3,4] .* [100,100,100,100] .+ [6,7,8,9]
should_be_equal_simd4f(x, simd4f_create(106.000000000000000f, 207.000000000000000f, 308.000000000000000f, 409.000000000000000f), epsilon );
}
}
describe(simd4f, "vector math") {
it("should have simd4f_dot4 for four component dot product") {
simd4f a = simd4f_create(1,2,3,4);
simd4f b = simd4f_create(10,20,30,40);
simd4f x = simd4f_dot4(a,b);
// octave simd4f: [dot([1, 2, 3, 4], [10, 20, 30, 40]),dot([1, 2, 3, 4], [10, 20, 30, 40]),dot([1, 2, 3, 4], [10, 20, 30, 40]),dot([1, 2, 3, 4], [10, 20, 30, 40])]
should_be_equal_simd4f(x, simd4f_create(300.000000000000000f, 300.000000000000000f, 300.000000000000000f, 300.000000000000000f), epsilon );
}
it("should have simd4f_dot3_scalar for three component dot product returning float") {
simd4f a = simd4f_create(1,2,3,9999);
simd4f b = simd4f_create(10,20,30,-9990);
float x = simd4f_dot3_scalar(a,b);
// octave float: dot([1, 2, 3], [10, 20, 30])
should_be_close_to(x, 140.000000000000000f, epsilon );
}
it("should have simd4f_dot3 for three component dot product returning simd4f") {
simd4f a = simd4f_create(1,2,3,9999);
simd4f b = simd4f_create(10,20,30,-9990);
simd4f x = simd4f_dot3(a,b);
// octave simd4f: [dot([1, 2, 3], [10, 20, 30]),dot([1, 2, 3], [10, 20, 30]),dot([1, 2, 3], [10, 20, 30]),dot([1, 2, 3], [10, 20, 30])]
should_be_equal_simd4f(x, simd4f_create(140.000000000000000f, 140.000000000000000f, 140.000000000000000f, 140.000000000000000f), epsilon );
}
it("should have simd4f_dot2 for two component dot product") {
simd4f a = simd4f_create(1,2,3,9999);
simd4f b = simd4f_create(10,20,30,-9990);
simd4f x = simd4f_dot2(a,b);
// octave simd4f: [dot([1, 2], [10, 20]),dot([1, 2], [10, 20]),dot([1, 2], [10, 20]),dot([1, 2], [10, 20])]
should_be_equal_simd4f(x, simd4f_create(50.000000000000000f, 50.000000000000000f, 50.000000000000000f, 50.000000000000000f), epsilon );
}
it("should have simd4f_length4 for four component vector length") {
simd4f a = simd4f_create(1,2,-3,9999);
simd4f x = simd4f_length4(a);
// octave simd4f: [norm([1,2,-3,9999]), norm([1,2,-3,9999]), norm([1,2,-3,9999]), norm([1,2,-3,9999])]
should_be_equal_simd4f(x, simd4f_create(9999.000700069982486f, 9999.000700069982486f, 9999.000700069982486f, 9999.000700069982486f), epsilon );
}
it("should have simd4f_length3 for three component vector length") {
simd4f a = simd4f_create(1,2,-3,9999);
simd4f x = simd4f_length3(a);
// octave simd4f: [norm([1,2,-3]), norm([1,2,-3]), norm([1,2,-3]), norm([1,2,-3])]
should_be_equal_simd4f(x, simd4f_create(3.741657386773941f, 3.741657386773941f, 3.741657386773941f, 3.741657386773941f), epsilon );
}
it("should have simd4f_length2 for two component vector length") {
simd4f a = simd4f_create(1,2,-3,9999);
simd4f x = simd4f_length2(a);
// octave simd4f: [norm([1,2]),norm([1,2]),norm([1,2]),norm([1,2])]
should_be_equal_simd4f(x, simd4f_create(2.236067977499790f, 2.236067977499790f, 2.236067977499790f, 2.236067977499790f), epsilon );
}
it("should have simd4f_length4_squared for four component squared vector length") {
simd4f a = simd4f_create(1,2,-3,9999);
simd4f x = simd4f_length4_squared(a);
// octave simd4f: ([(dot([1,2,-3,9999], [1,2,-3,9999])), (dot([1,2,-3,9999], [1,2,-3,9999])), (dot([1,2,-3,9999], [1,2,-3,9999])), (dot([1,2,-3,9999], [1,2,-3,9999]))])
should_be_equal_simd4f(x, simd4f_create(99980015.000000000000000f, 99980015.000000000000000f, 99980015.000000000000000f, 99980015.000000000000000f), epsilon );
}
it("should have simd4f_length3_squared for three component squared vector length") {
simd4f a = simd4f_create(1,2,-3,9999);
simd4f x = simd4f_length3_squared(a);
// octave simd4f: ([dot([1,2,-3], [1,2,-3]), dot([1,2,-3], [1,2,-3]), dot([1,2,-3], [1,2,-3]), dot([1,2,-3], [1,2,-3])])
should_be_equal_simd4f(x, simd4f_create(14.000000000000000f, 14.000000000000000f, 14.000000000000000f, 14.000000000000000f), epsilon );
}
it("should have simd4f_length2_squared for two component squared vector length") {
simd4f a = simd4f_create(1,2,-3,9999);
simd4f x = simd4f_length2_squared(a);
// octave simd4f: ([dot([1,2], [1,2]), dot([1,2], [1,2]), dot([1,2], [1,2]), dot([1,2], [1,2])])
should_be_equal_simd4f(x, simd4f_create(5.000000000000000f, 5.000000000000000f, 5.000000000000000f, 5.000000000000000f), epsilon );
}
it("should have simd4f_cross3 for cross product") {
simd4f a = simd4f_create(1,12,3,-9999);
simd4f b = simd4f_create(5,6,-17, 9999);
simd4f x = simd4f_cross3(a,b);
// octave simd4f: horzcat( cross( [1,12,3], [5,6,-17] ) , [0] )
should_be_equal_simd4f(x, simd4f_create(-222.000000000000000f, 32.000000000000000f, -54.000000000000000f, 0.000000000000000f), epsilon );
}
it("should have simd4f_normalize4 for normalizing four const vector to unit length") {
simd4f a = simd4f_create(1,2,3,4);
simd4f x = simd4f_normalize4(a);
// octave simd4f: [1,2,3,4] / norm([1,2,3,4])
should_be_equal_simd4f(x, simd4f_create(0.182574185835055f, 0.365148371670111f, 0.547722557505166f, 0.730296743340221f), epsilon );
}
it("should have simd4f_normalize3 for normalizing three component vector to unit length") {
simd4f a = simd4f_create(1,2,3,0);
simd4f x = simd4f_normalize3(a);
// octave simd4f: [1,2,3,0] / norm([1,2,3])
should_be_equal_simd4f(x, simd4f_create(0.267261241912424f, 0.534522483824849f, 0.801783725737273f, 0.000000000000000f), epsilon );
}
it("should have simd4f_normalize2 for normalizing two component vector to unit length") {
simd4f a = simd4f_create(1,2,0,0);
simd4f x = simd4f_normalize2(a);
// octave simd4f: [1,2,0,0] / norm([1,2])
should_be_equal_simd4f(x, simd4f_create(0.447213595499958f, 0.894427190999916f, 0.000000000000000f, 0.000000000000000f), epsilon );
}
}
describe(simd4f, "shuffles and merges") {
it("should have simd4f_shuffle_wxyz") {
simd4f a = simd4f_create(1,2,3,4);
simd4f x = simd4f_shuffle_wxyz(a);
should_be_equal_simd4f(x, simd4f_create(4,1,2,3), epsilon );
}
it("should have simd4f_shuffle_zwxy") {
simd4f a = simd4f_create(1,2,3,4);
simd4f x = simd4f_shuffle_zwxy(a);
should_be_equal_simd4f(x, simd4f_create(3,4,1,2), epsilon );
}
it("should have simd4f_shuffle_yzwx") {
simd4f a = simd4f_create(1,2,3,4);
simd4f x = simd4f_shuffle_yzwx(a);
should_be_equal_simd4f(x, simd4f_create(2,3,4,1), epsilon );
}
it("should have simd4f_merge_high") {
simd4f a = simd4f_create(1,2,3,4);
simd4f b = simd4f_create(5,6,7,8);
simd4f x = simd4f_merge_high(a,b);
should_be_equal_simd4f(x, simd4f_create(3,4,7,8), epsilon );
}
}
describe(simd4f, "signs") {
it("should have simd4f_flip_sign_0101 for flipping even elements sign") {
simd4f a = simd4f_create(1,2,3,4);
simd4f x = simd4f_flip_sign_0101(a);
should_be_equal_simd4f(x, simd4f_create(1,-2,3,-4), epsilon );
}
it("should have simd4f_flip_sign_1010 for flipping even elements sign") {
simd4f a = simd4f_create(1,2,3,4);
simd4f x = simd4f_flip_sign_1010(a);
should_be_equal_simd4f(x, simd4f_create(-1,2,-3,4), epsilon );
}
}
describe(simd4f, "min-max") {
it("should have simd4f_min for choosing minimum elements") {
simd4f a = simd4f_create(1.0f, 2.0f, -300000000.0f, -0.000002f);
simd4f b = simd4f_create(2.0f, -2.0f, 300000000.0f, 0.000001f);
simd4f x = simd4f_min(a,b);
should_be_equal_simd4f(x, simd4f_create(1.0f, -2.0f, -300000000.0f, -0.000002f), epsilon);
}
it("should have simd4f_max for choosing maximum elements") {
simd4f a = simd4f_create(1.0f, 2.0f, -300000000.0f, -0.000002f);
simd4f b = simd4f_create(2.0f, -2.0f, 300000000.0f, 0.000001f);
simd4f x = simd4f_max(a,b);
should_be_equal_simd4f(x, simd4f_create(2.0f, 2.0f, 300000000.0f, 0.000001f), epsilon);
}
}
describe(simd4f, "zeroing")
{
it("should have simd4f_zero_w that zeros the last element")
{
const float nan = sqrtf(-1.0f);
simd4f a = simd4f_create(1.0f, 2.0f, 3.0f, 4.0f);
simd4f b = simd4f_create(1.0f, 2.0f, 3.0f, nan);
simd4f x = simd4f_zero_w(a);
should_be_equal_simd4f(x, simd4f_create(1.0f, 2.0f, 3.0f, 0.0f), epsilon);
x = simd4f_zero_w(b);
should_be_equal_simd4f(x, simd4f_create(1.0f, 2.0f, 3.0f, 0.0f), epsilon);
}
it("should have simd4f_zero_zw that zeros the last element")
{
const float nan = sqrtf(-1.0f);
simd4f a = simd4f_create(1.0f, 2.0f, 3.0f, 4.0f);
simd4f b = simd4f_create(1.0f, 2.0f, nan, nan);
simd4f x = simd4f_zero_zw(a);
should_be_equal_simd4f(x, simd4f_create(1.0f, 2.0f, 0.0f, 0.0f), epsilon);
x = simd4f_zero_zw(b);
should_be_equal_simd4f(x, simd4f_create(1.0f, 2.0f, 0.0f, 0.0f), epsilon);
}
}
+381
View File
@@ -0,0 +1,381 @@
#include "spec_helper.h"
const int epsilon = 1;
#ifndef M_PI
#define M_PI 3.141592f
#endif
describe(simd4x4f, "creating") {
it("should be possible to create with params") {
simd4x4f x = simd4x4f_create(simd4f_create(1, 2, 3, 4 ),
simd4f_create(5, 6, 7, 8 ),
simd4f_create(9, 10, 11, 12 ),
simd4f_create(13, 14, 15, 16 ));
should_be_equal_simd4f( x.x, simd4f_create(1, 2, 3, 4 ) , epsilon);
should_be_equal_simd4f( x.y, simd4f_create(5, 6, 7, 8 ) , epsilon);
should_be_equal_simd4f( x.z, simd4f_create(9, 10, 11, 12 ), epsilon);
should_be_equal_simd4f( x.w, simd4f_create(13, 14, 15, 16 ), epsilon);
// octave simd4x4f: [1,5,9,13 ; 2,6,10,14 ; 3,7,11,15 ; 4,8,12,16 ]
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 4.000000000000000f), simd4f_create(5.000000000000000f, 6.000000000000000f, 7.000000000000000f, 8.000000000000000f), simd4f_create(9.000000000000000f, 10.000000000000000f, 11.000000000000000f, 12.000000000000000f), simd4f_create(13.000000000000000f, 14.000000000000000f, 15.000000000000000f, 16.000000000000000f)), epsilon );
}
it("should be possible to set to identity") {
simd4x4f x;
simd4x4f_identity(&x);
// octave simd4x4f: [1,0,0,0; 0,1,0,0; 0,0,1,0; 0,0,0,1]
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(1.000000000000000f, 0.000000000000000f, 0.000000000000000f, 0.000000000000000f), simd4f_create(0.000000000000000f, 1.000000000000000f, 0.000000000000000f, 0.000000000000000f), simd4f_create(0.000000000000000f, 0.000000000000000f, 1.000000000000000f, 0.000000000000000f), simd4f_create(0.000000000000000f, 0.000000000000000f, 0.000000000000000f, 1.000000000000000f)), epsilon );
}
}
describe(simd4x4f, "loading and storing") {
it("should be possible to load from array of 16 floats with simd4x4f_uload") {
simd4x4f x;
float f[16] = {1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16 };
simd4x4f_uload(&x, f);
should_be_equal_simd4x4f(x, simd4x4f_create( simd4f_create(1,2,3,4),
simd4f_create(5,6,7,8),
simd4f_create(9,10,11,12),
simd4f_create(13,14,15,16) ), epsilon);
}
}
describe(simd4x4f, "matrix utility") {
it("should have simd4x4f_transpose_inplace for transpose") {
simd4x4f x = simd4x4f_create(simd4f_create(1, 2, 3, 4 ),
simd4f_create(5, 6, 7, 8 ),
simd4f_create(9, 10, 11, 12 ),
simd4f_create(13, 14, 15, 16 ));
simd4x4f_transpose_inplace(&x);
// octave simd4x4f: transpose([1,5,9,13 ; 2,6,10,14 ; 3,7,11,15 ; 4,8,12,16 ])
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(1.000000000000000f, 5.000000000000000f, 9.000000000000000f, 13.000000000000000f), simd4f_create(2.000000000000000f, 6.000000000000000f, 10.000000000000000f, 14.000000000000000f), simd4f_create(3.000000000000000f, 7.000000000000000f, 11.000000000000000f, 15.000000000000000f), simd4f_create(4.000000000000000f, 8.000000000000000f, 12.000000000000000f, 16.000000000000000f)), epsilon );
}
it("should have simd4x4f_transpose for transpose") {
simd4x4f in = simd4x4f_create(simd4f_create(1, 2, 3, 4 ),
simd4f_create(5, 6, 7, 8 ),
simd4f_create(9, 10, 11, 12 ),
simd4f_create(13, 14, 15, 16 ));
simd4x4f x;
simd4x4f_transpose(&in, &x);
// octave simd4x4f: transpose([1,5,9,13 ; 2,6,10,14 ; 3,7,11,15 ; 4,8,12,16 ])
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(1.000000000000000f, 5.000000000000000f, 9.000000000000000f, 13.000000000000000f), simd4f_create(2.000000000000000f, 6.000000000000000f, 10.000000000000000f, 14.000000000000000f), simd4f_create(3.000000000000000f, 7.000000000000000f, 11.000000000000000f, 15.000000000000000f), simd4f_create(4.000000000000000f, 8.000000000000000f, 12.000000000000000f, 16.000000000000000f)), epsilon );
}
it("should have simd4x4f_matrix_vector_mul for matrix-vector multiply") {
simd4x4f a = simd4x4f_create(simd4f_create( 1, 9, 17, 25 ),
simd4f_create( 3, 11, 19, 27 ),
simd4f_create( 5, 13, 21, 29 ),
simd4f_create( 7, 15, 23, 31 ));
simd4f b = simd4f_create( 26, -28, 30, -32 );
simd4f x;
simd4x4f_matrix_vector_mul(&a, &b, &x);
// octave simd4f: [1,3,5,7;9,11,13,15;17,19,21,23;25,27,29,31] * [26;-28;30;-32]
should_be_equal_simd4f(x, simd4f_create(-132.000000000000000f, -164.000000000000000f, -196.000000000000000f, -228.000000000000000f), epsilon );
}
it("should have simd4x4f_matrix_vector3_mul for matrix-vector3 multiply") {
simd4x4f a = simd4x4f_create(simd4f_create( 1, 9, 17, 25 ),
simd4f_create( 3, 11, 19, 27 ),
simd4f_create( 5, 13, 21, 29 ),
simd4f_create( 7, 15, 23, 31 ));
simd4f b = simd4f_create( 26, -28, 30, -32 );
simd4f x;
simd4x4f_matrix_vector3_mul(&a, &b, &x);
// TODO octave simd4f:
}
it("should have simd4x4f_matrix_vector3_mul for matrix-vector3 multiply") {
simd4x4f a = simd4x4f_create(simd4f_create( 1, 9, 17, 25 ),
simd4f_create( 3, 11, 19, 27 ),
simd4f_create( 5, 13, 21, 29 ),
simd4f_create( 7, 15, 23, 31 ));
simd4f b = simd4f_create( 26, -28, 30, -32 );
simd4f x;
simd4x4f_matrix_vector3_mul(&a, &b, &x);
// TODO octave simd4f:
}
it("should have simd4x4f_matrix_point3_mul") { /* TODO */ }
it("should have simd4x4f_inv_ortho_matrix_point3_mul for transforming point with inverse of a orhtonormal matrix") {
simd4x4f a = simd4x4f_create(simd4f_create( 0, -1, 0, 0 ),
simd4f_create( 1, 0, 0, 0 ),
simd4f_create( 0, 0, 1, 0 ),
simd4f_create( 1, 2, 3, 1 ));
simd4f b = simd4f_create(5,6,7,0);
simd4f x;
simd4x4f_inv_ortho_matrix_point3_mul(&a, &b, &x);
// octave simd4f: inverse([0,1,0,1; -1,0,0,2; 0,0,1,3; 0,0,0,1]) * [5;6;7;1] .* [1;1;1;0]
should_be_equal_simd4f(x, simd4f_create(-4.000000000000000f, 4.000000000000000f, 4.000000000000000f, 0.000000000000000f), epsilon );
}
it("should have simd4x4f_matrix_mul for matrix multiply") {
simd4x4f a = simd4x4f_create(simd4f_create( 1, 9, 17, 25 ),
simd4f_create( 3, 11, 19, 27 ),
simd4f_create( 5, 13, 21, 29 ),
simd4f_create( 7, 15, 23, 31 ));
simd4x4f b = simd4x4f_create(simd4f_create( 2 , -10, 18 , -26 ),
simd4f_create( -4, 12, -20, 28 ),
simd4f_create( 6, -14, 22, -30 ),
simd4f_create( -8, 16, -24, 32 ));
simd4x4f x;
simd4x4f_matrix_mul(&a, &b, &x);
// octave simd4x4f: [1,3,5,7;9,11,13,15;17,19,21,23;25,27,29,31] * [2,-4,6,-8;-10,12,-14,16;18,-20,22,-24;-26,28,-30,32]
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(-120.000000000000000f, -248.000000000000000f, -376.000000000000000f, -504.000000000000000f), simd4f_create(128.000000000000000f, 256.000000000000000f, 384.000000000000000f, 512.000000000000000f), simd4f_create(-136.000000000000000f, -264.000000000000000f, -392.000000000000000f, -520.000000000000000f), simd4f_create(144.000000000000000f, 272.000000000000000f, 400.000000000000000f, 528.000000000000000f)), epsilon );
}
it("should have simd4x4f_inverse for calculating inverse matrix") {
simd4x4f a = simd4x4f_create(simd4f_create(7, 2, 87, 5 ),
simd4f_create(5, 24, 6, 3 ),
simd4f_create(4, 6, 5, 6 ),
simd4f_create(5, 7, 4, 6 ));
simd4x4f x;
simd4x4f_inverse(&a, &x);
// octave simd4x4f: inverse( [7,5,4,5 ; 2,24,6,7 ; 87,6,5,4 ; 5,3,6,6] )
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(0.015309310560300f, -0.049885440533222f, -1.081337221412206f, 1.093522182878568f), simd4f_create(-0.004061653822120f, 0.054051239325141f, 0.123620079150177f, -0.147260987294314f), simd4f_create(0.011247656738180f, 0.004165798791918f, 0.042282857737971f, -0.053738804415747f), simd4f_create(-0.015517600499896f, -0.024265777962924f, 0.728702353676318f, -0.536971464278276f)), epsilon );
simd4x4f x2;
simd4x4f_matrix_mul(&x, &a, &x2);
simd4x4f identity;
simd4x4f_identity(&identity);
// Allow larger error for M * M' = I
const int epsilon = 0x35100000;
should_be_equal_simd4x4f(x2, identity, epsilon);
}
}
describe(simd4x4f, "math on elements") {
it("should have simd4x4f_add for element-wise addition") {
simd4x4f a = simd4x4f_create(simd4f_create(1, 2, 3, 4 ),
simd4f_create(5, 6, 7, 8 ),
simd4f_create(9, 10, 11, 12 ),
simd4f_create(13, 14, 15, 16 ));
simd4x4f b = simd4x4f_create(simd4f_create( 2 , -10, 18 , -26 ),
simd4f_create( -4, 12, -20, 28 ),
simd4f_create( 6, -14, 22, -30 ),
simd4f_create( -8, 16, -24, 32 ));
simd4x4f x;
simd4x4f_add(&a, &b, &x);
// octave simd4x4f: [1,5,9,13 ; 2,6,10,14 ; 3,7,11,15 ; 4,8,12,16 ] + [2,-4,6,-8;-10,12,-14,16;18,-20,22,-24;-26,28,-30,32]
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(3.000000000000000f, -8.000000000000000f, 21.000000000000000f, -22.000000000000000f), simd4f_create(1.000000000000000f, 18.000000000000000f, -13.000000000000000f, 36.000000000000000f), simd4f_create(15.000000000000000f, -4.000000000000000f, 33.000000000000000f, -18.000000000000000f), simd4f_create(5.000000000000000f, 30.000000000000000f, -9.000000000000000f, 48.000000000000000f)), epsilon );
}
it("should have simd4x4f_sub for element-wise substraction") {
simd4x4f a = simd4x4f_create(simd4f_create(1, 2, 3, 4 ),
simd4f_create(5, 6, 7, 8 ),
simd4f_create(9, 10, 11, 12 ),
simd4f_create(13, 14, 15, 16 ));
simd4x4f b = simd4x4f_create(simd4f_create( 2 , -10, 18 , -26 ),
simd4f_create( -4, 12, -20, 28 ),
simd4f_create( 6, -14, 22, -30 ),
simd4f_create( -8, 16, -24, 32 ));
simd4x4f x;
simd4x4f_sub(&a, &b, &x);
// octave simd4x4f: [1,5,9,13 ; 2,6,10,14 ; 3,7,11,15 ; 4,8,12,16 ] - [2,-4,6,-8;-10,12,-14,16;18,-20,22,-24;-26,28,-30,32]
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(-1.000000000000000f, 12.000000000000000f, -15.000000000000000f, 30.000000000000000f), simd4f_create(9.000000000000000f, -6.000000000000000f, 27.000000000000000f, -20.000000000000000f), simd4f_create(3.000000000000000f, 24.000000000000000f, -11.000000000000000f, 42.000000000000000f), simd4f_create(21.000000000000000f, -2.000000000000000f, 39.000000000000000f, -16.000000000000000f)), epsilon );
}
it("should have simd4x4f_mul for element-wise multiplication") {
simd4x4f a = simd4x4f_create(simd4f_create(1, 2, 3, 4 ),
simd4f_create(5, 6, 7, 8 ),
simd4f_create(9, 10, 11, 12 ),
simd4f_create(13, 14, 15, 16 ));
simd4x4f b = simd4x4f_create(simd4f_create( 2 , -10, 18 , -26 ),
simd4f_create( -4, 12, -20, 28 ),
simd4f_create( 6, -14, 22, -30 ),
simd4f_create( -8, 16, -24, 32 ));
simd4x4f x;
simd4x4f_mul(&a, &b, &x);
// octave simd4x4f: [1,5,9,13 ; 2,6,10,14 ; 3,7,11,15 ; 4,8,12,16 ] .* [2,-4,6,-8;-10,12,-14,16;18,-20,22,-24;-26,28,-30,32]
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(2.000000000000000f, -20.000000000000000f, 54.000000000000000f, -104.000000000000000f), simd4f_create(-20.000000000000000f, 72.000000000000000f, -140.000000000000000f, 224.000000000000000f), simd4f_create(54.000000000000000f, -140.000000000000000f, 242.000000000000000f, -360.000000000000000f), simd4f_create(-104.000000000000000f, 224.000000000000000f, -360.000000000000000f, 512.000000000000000f)), epsilon );
}
it("should have simd4x4f_div for element-wise division") {
simd4x4f a = simd4x4f_create(simd4f_create(1, 2, 3, 4 ),
simd4f_create(5, 6, 7, 8 ),
simd4f_create(9, 10, 11, 12 ),
simd4f_create(13, 14, 15, 16 ));
simd4x4f b = simd4x4f_create(simd4f_create( 2 , -10, 18 , -26 ),
simd4f_create( -4, 12, -20, 28 ),
simd4f_create( 6, -14, 22, -30 ),
simd4f_create( -8, 16, -24, 32 ));
simd4x4f x;
simd4x4f_div(&a, &b, &x);
// octave simd4x4f: [1,5,9,13 ; 2,6,10,14 ; 3,7,11,15 ; 4,8,12,16 ] ./ [2,-4,6,-8;-10,12,-14,16;18,-20,22,-24;-26,28,-30,32]
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(0.500000000000000f, -0.200000000000000f, 0.166666666666667f, -0.153846153846154f), simd4f_create(-1.250000000000000f, 0.500000000000000f, -0.350000000000000f, 0.285714285714286f), simd4f_create(1.500000000000000f, -0.714285714285714f, 0.500000000000000f, -0.400000000000000f), simd4f_create(-1.625000000000000f, 0.875000000000000f, -0.625000000000000f, 0.500000000000000f)), epsilon );
}
}
describe(simd4x4f, "creating projection and view matrices") {
it("should have simd4x4f_perspective for creating perspective projection matrix") {
const float fov = 10.0f * M_PI / 180.0f;
const float aspect = 1.6f;
const float znear = 2.0f;
const float zfar = 50.0f;
const int epsilon = 50;
simd4x4f x;
simd4x4f_perspective(&x, fov, aspect, znear, zfar);
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(7.14378, 0, 0, 0),
simd4f_create(0, 11.4301, 0, 0),
simd4f_create(0, 0, -1.08333, -1),
simd4f_create(-0, -0, -4.16667, -0)), epsilon);
}
it("should have simd4x4f_ortho for creating orthogonal projection matrix") {
simd4x4f x;
simd4x4f_ortho(&x, -10, 20, -30, 40, -50, 60);
const int epsilon = 20;
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(0.0666667, 0, 0, 0),
simd4f_create(0, 0.0285714, 0, 0),
simd4f_create(-0, -0, -0.0181818, -0),
simd4f_create(-0.333333, -0.142857, -0.0909091, 1)), epsilon);
}
it("should have simd4x4f_lookat for creating look-at matrix") {
simd4f eye = simd4f_create(1,2,3,0);
simd4f center = simd4f_create(3,4,5,0);
simd4f up = simd4f_create(0,1,0,0);
simd4x4f x;
simd4x4f_lookat(&x, eye, center, up);
const int epsilon = 40;
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(-0.707107, -0.408248, -0.57735, 0),
simd4f_create(0, 0.816497, -0.57735, 0),
simd4f_create(0.707107, -0.408248, -0.57735, 0),
simd4f_create(-1.41421, 0, 3.4641, 1)), epsilon);
}
it("should have simd4x4f_translation for creating translation matrix") {
simd4x4f x;
simd4x4f_translation(&x, 1,2,3);
// octave simd4x4f: [1,0,0,1; 0,1,0,2; 0,0,1,3; 0,0,0,1]
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(1.000000000000000f, 0.000000000000000f, 0.000000000000000f, 0.000000000000000f), simd4f_create(0.000000000000000f, 1.000000000000000f, 0.000000000000000f, 0.000000000000000f), simd4f_create(0.000000000000000f, 0.000000000000000f, 1.000000000000000f, 0.000000000000000f), simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 1.000000000000000f)), epsilon );
}
it("should have simd4x4f_axis_rotation for creating a rotation matrix along a axis") {
simd4x4f x;
simd4x4f_axis_rotation(&x, 45 * M_PI / 180.0f, simd4f_create(1,2,3,0));
const int epsilon = 20;
should_be_equal_simd4x4f(x, simd4x4f_create(simd4f_create(0.728028, 0.608789, -0.315202, 0),
simd4f_create(-0.525105, 0.790791, 0.314508, 0),
simd4f_create(0.440727, -0.0634566, 0.895395, 0),
simd4f_create(0, 0, 0, 1)), epsilon);
}
}
+255
View File
@@ -0,0 +1,255 @@
#include "spec_helper.h"
#include <iostream>
using vectorial::vec2f;
const int epsilon = 1;
describe(vec2f, "constructing") {
it("should have default constructor that does nothing..") {
vec2f x;
}
it("should have constructor with element values") {
vec2f x(10,20);
// octave vec2f: [10,20]
should_be_equal_vec2f(x, simd4f_create(10.000000000000000f, 20.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have constructor that loads from a float array") {
float ary[2] = { 1,2 };
vec2f x(ary);
// octave vec2f: [1,2]
should_be_equal_vec2f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 0.0f, 0.0f), epsilon );
}
}
describe(vec2f, "loads and stores") {
it("should have method for loading from a float array") {
float ary[2] = { 1, 2 };
vec2f x(-1, -1 );
x.load(ary);
// octave vec2f: [1,2]
should_be_equal_vec2f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have method for storing to a float array") {
float ary[2] = { -1, -1 };
vec2f x(1, 2);
x.store(ary);
should_be_close_to(ary[0], 1, epsilon);
should_be_close_to(ary[1], 2, epsilon);
}
}
describe(vec2f, "arithmetic with another vec2f") {
it("should have operator+ for component-wise addition") {
vec2f a(1,2);
vec2f b(10,20);
vec2f x = a + b;
// octave vec2f: [1,2] + [10,20]
should_be_equal_vec2f(x, simd4f_create(11.000000000000000f, 22.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator- for component-wise subtraction") {
vec2f a(1,2);
vec2f b(10,20);
vec2f x = b - a;
// octave vec2f: [10,20] - [1,2]
should_be_equal_vec2f(x, simd4f_create(9.000000000000000f, 18.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator* for component-wise multiplication") {
vec2f a(1,2);
vec2f b(10,20);
vec2f x = a * b;
// octave vec2f: [1,2] .* [10,20]
should_be_equal_vec2f(x, simd4f_create(10.000000000000000f, 40.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator/ for component-wise division") {
vec2f a(1,2);
vec2f b(10,20);
vec2f x = b / a;
// octave vec2f: [10,20] ./ [1,2]
should_be_equal_vec2f(x, simd4f_create(10.000000000000000f, 10.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator+= for component-wise addition") {
vec2f x(1,2);
vec2f b(10,20);
x += b;
// octave vec2f: [1,2] + [10,20]
should_be_equal_vec2f(x, simd4f_create(11.000000000000000f, 22.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator-= for component-wise subtraction") {
vec2f a(1,2);
vec2f x(10,20);
x -= a;
// octave vec2f: [10,20] - [1,2]
should_be_equal_vec2f(x, simd4f_create(9.000000000000000f, 18.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator*= for component-wise multiplication") {
vec2f x(1,2);
vec2f b(10,20);
x *= b;
// octave vec2f: [1,2] .* [10,20]
should_be_equal_vec2f(x, simd4f_create(10.000000000000000f, 40.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator/= for component-wise division") {
vec2f a(1,2);
vec2f x(10,20);
x /= a;
// octave vec2f: [10,20] ./ [1,2]
should_be_equal_vec2f(x, simd4f_create(10.000000000000000f, 10.000000000000000f, 0.0f, 0.0f), epsilon );
}
}
describe(vec2f, "arithmetic with scalar") {
it("should have operator+ for component-wise addition") {
vec2f a(1,2);
float b=10;
vec2f x = a + b;
// octave vec2f: [1,2] + 10
should_be_equal_vec2f(x, simd4f_create(11.000000000000000f, 12.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator- for component-wise subtraction") {
float a=10;
vec2f b(10,20);
vec2f x = b - a;
// octave vec2f: [10,20] - 10
should_be_equal_vec2f(x, simd4f_create(0.000000000000000f, 10.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator* for component-wise multiplication") {
vec2f a(1,2);
float b=10;
vec2f x = a * b;
// octave vec2f: [1,2] .* 10
should_be_equal_vec2f(x, simd4f_create(10.000000000000000f, 20.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator/ for component-wise division") {
vec2f a(10,20);
float b=10;
vec2f x = a / b;
// octave vec2f: [10,20] ./ 10
should_be_equal_vec2f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator+ for component-wise addition (float as lhs)") {
vec2f b(1,2);
float a=10;
vec2f x = a + b;
// octave vec2f: 10 + [1,2]
should_be_equal_vec2f(x, simd4f_create(11.000000000000000f, 12.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator- for component-wise subtraction (float as lhs)") {
float b=50;
vec2f a(10,20);
vec2f x = b - a;
// octave vec2f: 50 - [10,20]
should_be_equal_vec2f(x, simd4f_create(40.000000000000000f, 30.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator* for component-wise multiplication (float as lhs)") {
vec2f b(1,2);
float a=10;
vec2f x = a * b;
// octave vec2f: 10 .* [1,2]
should_be_equal_vec2f(x, simd4f_create(10.000000000000000f, 20.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have operator* for component-wise multiplication (float as lhs)") {
vec2f b(10,20);
float a=40;
vec2f x = a / b;
// octave vec2f: 40 ./ [10,20]
should_be_equal_vec2f(x, simd4f_create(4.000000000000000f, 2.000000000000000f, 0.0f, 0.0f), epsilon );
}
}
describe(vec2f, "vector math") {
it("should have unary minus operator") {
vec2f a(1,2);
vec2f x = -a;
// octave vec2f: -[1,2]
should_be_equal_vec2f(x, simd4f_create(-1.000000000000000f, -2.000000000000000f, 0.0f, 0.0f), epsilon );
}
it("should have dot function") {
vec2f a(1,2);
vec2f b(6,7);
float x = vectorial::dot(a,b);
// octave vec2f: dot([1,2],[6,7])
should_be_close_to(x, 20.000000000000000f, epsilon );
}
it("should have length_squared function") {
vec2f a(1,2);
float x = vectorial::length_squared(a);
// octave vec2f: dot([1,2],[1,2])
should_be_close_to(x, 5.000000000000000f, epsilon );
}
it("should have length function") {
vec2f a(1,2);
float x = vectorial::length(a);
// octave vec2f: norm([1,2])
should_be_close_to(x, 2.236067977499790f, epsilon );
}
it("should have normalize function") {
vec2f a(1,2);
vec2f x = vectorial::normalize(a);
// octave vec2f: [1,2] / norm([1,2])
should_be_equal_vec2f(x, simd4f_create(0.447213595499958f, 0.894427190999916f, 0.0f, 0.0f), epsilon );
}
}
+263
View File
@@ -0,0 +1,263 @@
#include "spec_helper.h"
#include <iostream>
using vectorial::vec3f;
const int epsilon = 1;
describe(vec3f, "constructing") {
it("should have default constructor that does nothing..") {
vec3f x;
}
it("should have constructor with element values") {
vec3f x(10,20,30);
// octave vec3f: [10,20,30]
should_be_equal_vec3f(x, simd4f_create(10.000000000000000f, 20.000000000000000f, 30.000000000000000f, 0.0f), epsilon );
}
it("should have constructor that loads from a float array") {
float ary[3] = { 1,2,3 };
vec3f x(ary);
// octave vec3f: [1,2,3]
should_be_equal_vec3f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 0.0f), epsilon );
}
}
describe(vec3f, "loads and stores") {
it("should have method for loading from a float array") {
float ary[3] = { 1,2,3 };
vec3f x(-1, -1, -1 );
x.load(ary);
// octave vec3f: [1,2,3]
should_be_equal_vec3f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 0.0f), epsilon );
}
it("should have method for storing to a float array") {
float ary[3] = { -1, -1, -1 };
vec3f x(1, 2, 3);
x.store(ary);
should_be_close_to(ary[0], 1, epsilon);
should_be_close_to(ary[1], 2, epsilon);
should_be_close_to(ary[2], 3, epsilon);
}
}
describe(vec3f, "arithmetic with another vec3f") {
it("should have operator+ for component-wise addition") {
vec3f a(1,2,3);
vec3f b(10,20,30);
vec3f x = a + b;
// octave vec3f: [1,2,3] + [10,20,30]
should_be_equal_vec3f(x, simd4f_create(11.000000000000000f, 22.000000000000000f, 33.000000000000000f, 0.0f), epsilon );
}
it("should have operator- for component-wise subtraction") {
vec3f a(1,2,3);
vec3f b(10,20,30);
vec3f x = b - a;
// octave vec3f: [10,20,30] - [1,2,3]
should_be_equal_vec3f(x, simd4f_create(9.000000000000000f, 18.000000000000000f, 27.000000000000000f, 0.0f), epsilon );
}
it("should have operator* for component-wise multiplication") {
vec3f a(1,2,3);
vec3f b(10,20,30);
vec3f x = a * b;
// octave vec3f: [1,2,3] .* [10,20,30]
should_be_equal_vec3f(x, simd4f_create(10.000000000000000f, 40.000000000000000f, 90.000000000000000f, 0.0f), epsilon );
}
it("should have operator/ for component-wise division") {
vec3f a(1,2,3);
vec3f b(10,20,30);
vec3f x = b / a;
// octave vec3f: [10,20,30] ./ [1,2,3]
should_be_equal_vec3f(x, simd4f_create(10.000000000000000f, 10.000000000000000f, 10.000000000000000f, 0.0f), epsilon );
}
it("should have operator+= for component-wise addition") {
vec3f x(1,2,3);
vec3f b(10,20,30);
x += b;
// octave vec3f: [1,2,3] + [10,20,30]
should_be_equal_vec3f(x, simd4f_create(11.000000000000000f, 22.000000000000000f, 33.000000000000000f, 0.0f), epsilon );
}
it("should have operator-= for component-wise subtraction") {
vec3f a(1,2,3);
vec3f x(10,20,30);
x -= a;
// octave vec3f: [10,20,30] - [1,2,3]
should_be_equal_vec3f(x, simd4f_create(9.000000000000000f, 18.000000000000000f, 27.000000000000000f, 0.0f), epsilon );
}
it("should have operator*= for component-wise multiplication") {
vec3f x(1,2,3);
vec3f b(10,20,30);
x *= b;
// octave vec3f: [1,2,3] .* [10,20,30]
should_be_equal_vec3f(x, simd4f_create(10.000000000000000f, 40.000000000000000f, 90.000000000000000f, 0.0f), epsilon );
}
it("should have operator/= for component-wise division") {
vec3f a(1,2,3);
vec3f x(10,20,30);
x /= a;
// octave vec3f: [10,20,30] ./ [1,2,3]
should_be_equal_vec3f(x, simd4f_create(10.000000000000000f, 10.000000000000000f, 10.000000000000000f, 0.0f), epsilon );
}
}
describe(vec3f, "arithmetic with scalar") {
it("should have operator+ for component-wise addition") {
vec3f a(1,2,3);
float b=10;
vec3f x = a + b;
// octave vec3f: [1,2,3] + 10
should_be_equal_vec3f(x, simd4f_create(11.000000000000000f, 12.000000000000000f, 13.000000000000000f, 0.0f), epsilon );
}
it("should have operator- for component-wise subtraction") {
float a=10;
vec3f b(10,20,30);
vec3f x = b - a;
// octave vec3f: [10,20,30] - 10
should_be_equal_vec3f(x, simd4f_create(0.000000000000000f, 10.000000000000000f, 20.000000000000000f, 0.0f), epsilon );
}
it("should have operator* for component-wise multiplication") {
vec3f a(1,2,3);
float b=10;
vec3f x = a * b;
// octave vec3f: [1,2,3] .* 10
should_be_equal_vec3f(x, simd4f_create(10.000000000000000f, 20.000000000000000f, 30.000000000000000f, 0.0f), epsilon );
}
it("should have operator/ for component-wise division") {
vec3f a(10,20,30);
float b=10;
vec3f x = a / b;
// octave vec3f: [10,20,30] ./ 10
should_be_equal_vec3f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 0.0f), epsilon );
}
it("should have operator+ for component-wise addition (float as lhs)") {
vec3f b(1,2,3);
float a=10;
vec3f x = a + b;
// octave vec3f: 10 + [1,2,3]
should_be_equal_vec3f(x, simd4f_create(11.000000000000000f, 12.000000000000000f, 13.000000000000000f, 0.0f), epsilon );
}
it("should have operator- for component-wise subtraction (float as lhs)") {
float b=50;
vec3f a(10,20,30);
vec3f x = b - a;
// octave vec3f: 50 - [10,20,30]
should_be_equal_vec3f(x, simd4f_create(40.000000000000000f, 30.000000000000000f, 20.000000000000000f, 0.0f), epsilon );
}
it("should have operator* for component-wise multiplication (float as lhs)") {
vec3f b(1,2,3);
float a=10;
vec3f x = a * b;
// octave vec3f: 10 .* [1,2,3]
should_be_equal_vec3f(x, simd4f_create(10.000000000000000f, 20.000000000000000f, 30.000000000000000f, 0.0f), epsilon );
}
it("should have operator* for component-wise multiplication (float as lhs)") {
vec3f b(10,20,30);
float a=40;
vec3f x = a / b;
// octave vec3f: 40 ./ [10,20,30]
should_be_equal_vec3f(x, simd4f_create(4.000000000000000f, 2.000000000000000f, 1.333333333333333f, 0.0f), epsilon );
}
}
describe(vec3f, "vector math") {
it("should have unary minus operator") {
vec3f a(1,2,3);
vec3f x = -a;
// octave vec3f: -[1,2,3]
should_be_equal_vec3f(x, simd4f_create(-1.000000000000000f, -2.000000000000000f, -3.000000000000000f, 0.0f), epsilon );
}
it("should have dot function") {
vec3f a(1,2,3);
vec3f b(6,7,8);
float x = vectorial::dot(a,b);
// octave vec3f: dot([1,2,3],[6,7,8])
should_be_close_to(x, 44.000000000000000f, epsilon );
}
it("should have cross function") {
vec3f a(1,2,3);
vec3f b(6,7,8);
vec3f x = vectorial::cross(a,b);
// octave vec3f: cross([1,2,3],[6,7,8])
should_be_equal_vec3f(x, simd4f_create(-5.000000000000000f, 10.000000000000000f, -5.000000000000000f, 0.0f), epsilon );
}
it("should have length_squared function") {
vec3f a(1,2,3);
float x = vectorial::length_squared(a);
// octave vec3f: dot([1,2,3],[1,2,3])
should_be_close_to(x, 14.000000000000000f, epsilon );
}
it("should have length function") {
vec3f a(1,2,3);
float x = vectorial::length(a);
// octave vec3f: norm([1,2,3])
should_be_close_to(x, 3.741657386773941f, epsilon );
}
it("should have normalize function") {
vec3f a(1,2,3);
vec3f x = vectorial::normalize(a);
// octave vec3f: [1,2,3] / norm([1,2,3])
should_be_equal_vec3f(x, simd4f_create(0.267261241912424f, 0.534522483824849f, 0.801783725737273f, 0.0f), epsilon );
}
}
+258
View File
@@ -0,0 +1,258 @@
#include "spec_helper.h"
#include <iostream>
using vectorial::vec4f;
const int epsilon = 1;
describe(vec4f, "constructing") {
it("should have default constructor that does nothing..") {
vec4f x;
}
it("should have constructor with element values") {
vec4f x(10,20,30,40);
// octave vec4f: [10,20,30,40]
should_be_equal_vec4f(x, simd4f_create(10.000000000000000f, 20.000000000000000f, 30.000000000000000f, 40.000000000000000f), epsilon );
}
it("should have constructor that loads from a float array") {
float ary[4] = { 1,2,3,4 };
vec4f x(ary);
// octave vec4f: [1,2,3,4]
should_be_equal_vec4f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 4.000000000000000f), epsilon );
}
}
describe(vec4f, "loads and stores") {
it("should have method for loading from a float array") {
float ary[4] = { 1,2,3,4 };
vec4f x(-1, -1, -1, -1);
x.load(ary);
// octave vec4f: [1,2,3,4]
should_be_equal_vec4f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 4.000000000000000f), epsilon );
}
it("should have method for storing to a float array") {
float ary[4] = { -1, -1, -1, -1 };
vec4f x(1, 2, 3, 4);
x.store(ary);
should_be_close_to(ary[0], 1, epsilon);
should_be_close_to(ary[1], 2, epsilon);
should_be_close_to(ary[2], 3, epsilon);
should_be_close_to(ary[3], 4, epsilon);
}
}
describe(vec4f, "arithmetic with another vec4f") {
it("should have operator+ for component-wise addition") {
vec4f a(1,2,3,4);
vec4f b(10,20,30,40);
vec4f x = a + b;
// octave vec4f: [1,2,3,4] + [10,20,30,40]
should_be_equal_vec4f(x, simd4f_create(11.000000000000000f, 22.000000000000000f, 33.000000000000000f, 44.000000000000000f), epsilon );
}
it("should have operator- for component-wise subtraction") {
vec4f a(1,2,3,4);
vec4f b(10,20,30,40);
vec4f x = b - a;
// octave vec4f: [10,20,30,40] - [1,2,3,4]
should_be_equal_vec4f(x, simd4f_create(9.000000000000000f, 18.000000000000000f, 27.000000000000000f, 36.000000000000000f), epsilon );
}
it("should have operator* for component-wise multiplication") {
vec4f a(1,2,3,4);
vec4f b(10,20,30,40);
vec4f x = a * b;
// octave vec4f: [1,2,3,4] .* [10,20,30,40]
should_be_equal_vec4f(x, simd4f_create(10.000000000000000f, 40.000000000000000f, 90.000000000000000f, 160.000000000000000f), epsilon );
}
it("should have operator/ for component-wise division") {
vec4f a(1,2,3,4);
vec4f b(10,20,30,40);
vec4f x = b / a;
// octave vec4f: [10,20,30,40] ./ [1,2,3,4]
should_be_equal_vec4f(x, simd4f_create(10.000000000000000f, 10.000000000000000f, 10.000000000000000f, 10.000000000000000f), epsilon );
}
it("should have operator+= for component-wise addition") {
vec4f x(1,2,3,4);
vec4f b(10,20,30,40);
x += b;
// octave vec4f: [1,2,3,4] + [10,20,30,40]
should_be_equal_vec4f(x, simd4f_create(11.000000000000000f, 22.000000000000000f, 33.000000000000000f, 44.000000000000000f), epsilon );
}
it("should have operator-= for component-wise subtraction") {
vec4f a(1,2,3,4);
vec4f x(10,20,30,40);
x -= a;
// octave vec4f: [10,20,30,40] - [1,2,3,4]
should_be_equal_vec4f(x, simd4f_create(9.000000000000000f, 18.000000000000000f, 27.000000000000000f, 36.000000000000000f), epsilon );
}
it("should have operator*= for component-wise multiplication") {
vec4f x(1,2,3,4);
vec4f b(10,20,30,40);
x *= b;
// octave vec4f: [1,2,3,4] .* [10,20,30,40]
should_be_equal_vec4f(x, simd4f_create(10.000000000000000f, 40.000000000000000f, 90.000000000000000f, 160.000000000000000f), epsilon );
}
it("should have operator/= for component-wise division") {
vec4f a(1,2,3,4);
vec4f x(10,20,30,40);
x /= a;
// octave vec4f: [10,20,30,40] ./ [1,2,3,4]
should_be_equal_vec4f(x, simd4f_create(10.000000000000000f, 10.000000000000000f, 10.000000000000000f, 10.000000000000000f), epsilon );
}
}
describe(vec4f, "arithmetic with scalar") {
it("should have operator+ for component-wise addition") {
vec4f a(1,2,3,4);
float b=10;
vec4f x = a + b;
// octave vec4f: [1,2,3,4] + 10
should_be_equal_vec4f(x, simd4f_create(11.000000000000000f, 12.000000000000000f, 13.000000000000000f, 14.000000000000000f), epsilon );
}
it("should have operator- for component-wise subtraction") {
float a=10;
vec4f b(10,20,30,40);
vec4f x = b - a;
// octave vec4f: [10,20,30,40] - 10
should_be_equal_vec4f(x, simd4f_create(0.000000000000000f, 10.000000000000000f, 20.000000000000000f, 30.000000000000000f), epsilon );
}
it("should have operator* for component-wise multiplication") {
vec4f a(1,2,3,4);
float b=10;
vec4f x = a * b;
// octave vec4f: [1,2,3,4] .* 10
should_be_equal_vec4f(x, simd4f_create(10.000000000000000f, 20.000000000000000f, 30.000000000000000f, 40.000000000000000f), epsilon );
}
it("should have operator/ for component-wise division") {
vec4f a(10,20,30,40);
float b=10;
vec4f x = a / b;
// octave vec4f: [10,20,30,40] ./ 10
should_be_equal_vec4f(x, simd4f_create(1.000000000000000f, 2.000000000000000f, 3.000000000000000f, 4.000000000000000f), epsilon );
}
it("should have operator+ for component-wise addition (float as lhs)") {
vec4f b(1,2,3,4);
float a=10;
vec4f x = a + b;
// octave vec4f: 10 + [1,2,3,4]
should_be_equal_vec4f(x, simd4f_create(11.000000000000000f, 12.000000000000000f, 13.000000000000000f, 14.000000000000000f), epsilon );
}
it("should have operator- for component-wise subtraction (float as lhs)") {
float b=50;
vec4f a(10,20,30,40);
vec4f x = b - a;
// octave vec4f: 50 - [10,20,30,40]
should_be_equal_vec4f(x, simd4f_create(40.000000000000000f, 30.000000000000000f, 20.000000000000000f, 10.000000000000000f), epsilon );
}
it("should have operator* for component-wise multiplication (float as lhs)") {
vec4f b(1,2,3,4);
float a=10;
vec4f x = a * b;
// octave vec4f: 10 .* [1,2,3,4]
should_be_equal_vec4f(x, simd4f_create(10.000000000000000f, 20.000000000000000f, 30.000000000000000f, 40.000000000000000f), epsilon );
}
it("should have operator* for component-wise multiplication (float as lhs)") {
vec4f b(10,20,30,40);
float a=40;
vec4f x = a / b;
// octave vec4f: 40 ./ [10,20,30,40]
should_be_equal_vec4f(x, simd4f_create(4.000000000000000f, 2.000000000000000f, 1.333333333333333f, 1.000000000000000f), epsilon );
}
}
describe(vec4f, "vector math") {
it("should have unary minus operator") {
vec4f a(1,2,3,4);
vec4f x = -a;
// octave vec4f: -[1,2,3,4]
should_be_equal_vec4f(x, simd4f_create(-1.000000000000000f, -2.000000000000000f, -3.000000000000000f, -4.000000000000000f), epsilon );
}
it("should have dot function") {
vec4f a(1,2,3,4);
vec4f b(6,7,8,9);
float x = vectorial::dot(a,b);
// octave vec4f: dot([1,2,3,4],[6,7,8,9])
should_be_close_to(x, 80.000000000000000f, epsilon );
}
it("should have length_squared function") {
vec4f a(1,2,3,4);
float x = vectorial::length_squared(a);
// octave vec4f: dot([1,2,3,4],[1,2,3,4])
should_be_close_to(x, 30.000000000000000f, epsilon );
}
it("should have length function") {
vec4f a(1,2,3,4);
float x = vectorial::length(a);
// octave vec4f: norm([1,2,3,4])
should_be_close_to(x, 5.477225575051661f, epsilon );
}
it("should have normalize function") {
vec4f a(1,2,3,4);
vec4f x = vectorial::normalize(a);
// octave vec4f: [1,2,3,4] / norm([1,2,3,4])
should_be_equal_vec4f(x, simd4f_create(0.182574185835055f, 0.365148371670111f, 0.547722557505166f, 0.730296743340221f), epsilon );
}
}