Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native quaternion implementation #166

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions core/include/core/G3Map.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include <G3Frame.h>
#include <G3Vector.h>
#include <G3Quat.h>
#include <map>
#include <sstream>
#include <complex>
Expand Down Expand Up @@ -80,8 +79,6 @@ G3MAP_OF(std::string, G3VectorVectorString, G3MapVectorVectorString);
G3MAP_OF(std::string, std::vector<std::complex<double> >, G3MapVectorComplexDouble);
G3MAP_OF(std::string, G3VectorTime, G3MapVectorTime);
G3MAP_OF(std::string, std::string, G3MapString);
G3MAP_OF(std::string, quat, G3MapQuat);
G3MAP_OF(std::string, G3VectorQuat, G3MapVectorQuat);

#define G3MAP_SPLIT(key, value, name, version) \
typedef G3Map< key, value > name; \
Expand Down
141 changes: 94 additions & 47 deletions core/include/core/G3Quat.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,96 @@
#define _CORE_G3QUAT_H

#include <G3Vector.h>
#include <G3Map.h>

#include <boost/math/quaternion.hpp>
#include <cereal/types/vector.hpp>
class G3Quat : public G3FrameObject
{
public:
G3Quat() : buf_{0, 0, 0, 0}, versor_(false) {}
G3Quat(double a, double b, double c, double d, bool versor=false) :
buf_{a, b, c, d}, versor_(false) {}
G3Quat(const G3Quat &q) : buf_{q.a(), q.b(), q.c(), q.d()},
versor_(q.versor_) {}

double a() const { return buf_[0]; }
double b() const { return buf_[1]; }
double c() const { return buf_[2]; }
double d() const { return buf_[3]; }

bool is_versor() const { return versor_; }
G3Quat versor() const;

double real() const;
G3Quat unreal() const;
G3Quat conj() const;
double norm() const;
double abs() const;

G3Quat operator ~() const;

G3Quat &operator +=(const G3Quat &);
G3Quat &operator -=(const G3Quat &);
G3Quat &operator *=(double);
G3Quat &operator *=(const G3Quat &);
G3Quat &operator /=(double);
G3Quat &operator /=(const G3Quat &);

G3Quat operator +(const G3Quat &) const;
G3Quat operator -(const G3Quat &) const;
G3Quat operator *(double) const;
G3Quat operator *(const G3Quat &) const;
G3Quat operator /(double) const;
G3Quat operator /(const G3Quat &) const;

bool operator ==(const G3Quat &) const;
bool operator !=(const G3Quat &) const;

template <class A> void serialize(A &ar, unsigned v);

typedef boost::math::quaternion<double> quat;
void * buffer();

namespace cereal
{
// Define cereal serialization for the Quaternions
template<class A>
void serialize(A & ar, quat & q, unsigned version)
{
using namespace cereal;
double a, b, c, d;
a = q.R_component_1();
b = q.R_component_2();
c = q.R_component_3();
d = q.R_component_4();
ar & make_nvp("a", a);
ar & make_nvp("b", b);
ar & make_nvp("c", c);
ar & make_nvp("d", d);
q = quat(a,b,c,d);
}
std::string Description() const;
std::string Summary() const { return Description(); }

private:
double buf_[4];
bool versor_;

void versor_inplace();

SET_LOGGER("G3Quat");
};

namespace cereal {
template <class A> struct specialize<A, G3Quat, cereal::specialization::member_serialize> {};
}

quat cross3(quat a, quat b);
double dot3(quat a, quat b);
G3_POINTERS(G3Quat);
G3_SERIALIZABLE(G3Quat, 1);

G3Quat operator *(double, const G3Quat &);
G3Quat operator /(double, const G3Quat &);

inline double real(const G3Quat &q) { return q.real(); };
inline G3Quat unreal(const G3Quat &q) { return q.unreal(); };
inline G3Quat conj(const G3Quat &q) { return q.conj(); };
inline double norm(const G3Quat &q) { return q.norm(); }
inline double abs(const G3Quat &q) { return q.abs(); }

G3Quat pow(const G3Quat &, int);

G3VECTOR_OF(quat, G3VectorQuat);
G3Quat cross3(const G3Quat &a, const G3Quat &b);
double dot3(const G3Quat &a, const G3Quat &b);

G3VECTOR_SPLIT(G3Quat, G3VectorQuat, 2);

class G3TimestreamQuat : public G3VectorQuat
{
public:
G3TimestreamQuat() : G3VectorQuat() {}
G3TimestreamQuat(std::vector<quat>::size_type s) : G3VectorQuat(s) {}
G3TimestreamQuat(std::vector<quat>::size_type s,
const quat &val) : G3VectorQuat(s, val) {}
G3TimestreamQuat(std::vector<G3Quat>::size_type s) : G3VectorQuat(s) {}
G3TimestreamQuat(std::vector<G3Quat>::size_type s,
const G3Quat &val) : G3VectorQuat(s, val) {}
G3TimestreamQuat(const G3TimestreamQuat &r) : G3VectorQuat(r),
start(r.start), stop(r.stop) {}
G3TimestreamQuat(const G3VectorQuat &r) : G3VectorQuat(r) {}
Expand All @@ -62,52 +114,47 @@ namespace cereal {
G3_POINTERS(G3TimestreamQuat);
G3_SERIALIZABLE(G3TimestreamQuat, 1);

namespace boost {
namespace math {
quat operator ~(quat);
};
};

G3VectorQuat operator ~ (const G3VectorQuat &);
G3VectorQuat operator * (const G3VectorQuat &, double);
G3VectorQuat &operator *= (G3VectorQuat &, double);
G3VectorQuat operator / (const G3VectorQuat &, double);
G3VectorQuat operator / (double, const G3VectorQuat &);
G3VectorQuat operator / (const G3VectorQuat &, const quat &);
G3VectorQuat operator / (const quat &, const G3VectorQuat &);
G3VectorQuat operator / (const G3VectorQuat &, const G3Quat &);
G3VectorQuat operator / (const G3Quat &, const G3VectorQuat &);
G3VectorQuat operator / (const G3VectorQuat &, const G3VectorQuat &);
G3VectorQuat &operator /= (G3VectorQuat &, double);
G3VectorQuat &operator /= (G3VectorQuat &, const quat &);
G3VectorQuat &operator /= (G3VectorQuat &, const G3Quat &);
G3VectorQuat &operator /= (G3VectorQuat &, const G3VectorQuat &);
G3VectorQuat operator * (const G3VectorQuat &, const G3VectorQuat &);
G3VectorQuat &operator *= (G3VectorQuat &, const G3VectorQuat &);
G3VectorQuat operator * (double, const G3VectorQuat &);
G3VectorQuat operator * (const G3VectorQuat &, quat);
G3VectorQuat operator * (quat, const G3VectorQuat &);
G3VectorQuat &operator *= (G3VectorQuat &, quat);
G3VectorQuat operator * (const G3VectorQuat &, const G3Quat &);
G3VectorQuat operator * (const G3Quat &, const G3VectorQuat &);
G3VectorQuat &operator *= (G3VectorQuat &, const G3Quat &);

G3VectorQuat pow(const G3VectorQuat &a, double b);
G3VectorQuat pow(const G3VectorQuat &a, int b);

G3TimestreamQuat operator ~ (const G3TimestreamQuat &);
G3TimestreamQuat operator * (const G3TimestreamQuat &, double);
G3TimestreamQuat operator * (double, const G3TimestreamQuat &);
G3TimestreamQuat operator / (const G3TimestreamQuat &, double);
G3TimestreamQuat operator / (double, const G3TimestreamQuat &);
G3TimestreamQuat operator / (const G3TimestreamQuat &, const quat &);
G3TimestreamQuat operator / (const quat &, const G3TimestreamQuat &);
G3TimestreamQuat operator / (const G3TimestreamQuat &, const G3Quat &);
G3TimestreamQuat operator / (const G3Quat &, const G3TimestreamQuat &);
G3TimestreamQuat operator / (const G3TimestreamQuat &, const G3VectorQuat &);
G3TimestreamQuat &operator /= (G3TimestreamQuat &, double);
G3TimestreamQuat &operator /= (G3TimestreamQuat &, const quat &);
G3TimestreamQuat &operator /= (G3TimestreamQuat &, const G3Quat &);
G3TimestreamQuat &operator /= (G3TimestreamQuat &, const G3VectorQuat &);
G3TimestreamQuat operator * (const G3TimestreamQuat &, const G3VectorQuat &);
G3TimestreamQuat &operator *= (G3TimestreamQuat &, const G3VectorQuat &);
G3TimestreamQuat operator * (double, const G3TimestreamQuat &);
G3TimestreamQuat operator * (const G3TimestreamQuat &, quat);
G3TimestreamQuat operator * (quat, const G3TimestreamQuat &);
G3TimestreamQuat &operator *= (G3TimestreamQuat &, quat);
G3TimestreamQuat operator * (const G3TimestreamQuat &, const G3Quat &);
G3TimestreamQuat operator * (const G3Quat &, const G3TimestreamQuat &);
G3TimestreamQuat &operator *= (G3TimestreamQuat &, const G3Quat &);

G3TimestreamQuat pow(const G3TimestreamQuat &a, double b);
G3TimestreamQuat pow(const G3TimestreamQuat &a, int b);

G3MAP_OF(std::string, G3VectorQuat, G3MapVectorQuat);
G3MAP_SPLIT(std::string, G3Quat, G3MapQuat, 2);

#endif
1 change: 1 addition & 0 deletions core/python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ def fix_logging_crash():
from .dataextensions import *
from .frameextensions import *
from .timestreamextensions import *
from .quatextensions import *

from .g3decorators import cache_frame_data, scan_func_cache_data
21 changes: 21 additions & 0 deletions core/python/quatextensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import numpy as np
from . import G3Quat, G3VectorQuat, G3TimestreamQuat

__all__ = []


def quat_ufunc(self, ufunc, method, *inputs, **kwargs):
"""Numpy ufunc interface for vectorized quaternion methods."""
if method == "__call__" and len(inputs) == 1 and not kwargs:
if ufunc.__name__ == "absolute":
return self.abs()
if ufunc.__name__ == "conjugate":
return self.conj()
if ufunc.__name__ == "reciprocal":
return G3Quat(1, 0, 0, 0) / self
return NotImplemented


G3Quat.__array_ufunc__ = quat_ufunc
G3VectorQuat.__array_ufunc__ = quat_ufunc
G3TimestreamQuat.__array_ufunc__ = quat_ufunc
6 changes: 0 additions & 6 deletions core/src/G3Map.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,12 @@ std::string G3MapFrameObject::Description() const
G3_SERIALIZABLE_CODE(G3MapDouble);
G3_SERIALIZABLE_CODE(G3MapMapDouble);
G3_SERIALIZABLE_CODE(G3MapString);
G3_SERIALIZABLE_CODE(G3MapQuat);
G3_SERIALIZABLE_CODE(G3MapVectorBool);
G3_SERIALIZABLE_CODE(G3MapVectorDouble);
G3_SERIALIZABLE_CODE(G3MapVectorString);
G3_SERIALIZABLE_CODE(G3MapVectorVectorString);
G3_SERIALIZABLE_CODE(G3MapVectorComplexDouble);
G3_SERIALIZABLE_CODE(G3MapVectorTime);
G3_SERIALIZABLE_CODE(G3MapVectorQuat);

G3_SPLIT_SERIALIZABLE_CODE(G3MapInt);
G3_SPLIT_SERIALIZABLE_CODE(G3MapVectorInt);
Expand All @@ -246,8 +244,6 @@ PYBINDINGS("core") {
register_g3map<G3MapInt>("G3MapInt", "Mapping from strings to ints.");
register_g3map<G3MapString>("G3MapString", "Mapping from strings to "
"strings.");
register_g3map<G3MapQuat>("G3MapQuat", "Mapping from strings to "
"quaternions.");
register_g3map<G3MapVectorBool>("G3MapVectorBool", "Mapping from "
"strings to arrays of booleans.");
register_g3map<G3MapVectorDouble>("G3MapVectorDouble", "Mapping from "
Expand All @@ -262,8 +258,6 @@ PYBINDINGS("core") {
"Mapping from strings to lists of lists of strings.");
register_g3map<G3MapVectorTime>("G3MapVectorTime", "Mapping from "
"strings to lists of G3 time objects.");
register_g3map<G3MapVectorQuat>("G3MapVectorQuat", "Mapping from "
"strings to lists of quaternions.");

// Special handling to get the object proxying right
register_g3map<G3MapFrameObject, true>("G3MapFrameObject", "Mapping "
Expand Down
Loading
Loading