1217. Quaternion support

Section: 29.5 [complex.numbers] Status: LEWG Submitter: Ted Shaneyfelt Opened: 2009-09-26 Last modified: 2017-03-03

Priority: Not Prioritized

View other active issues in [complex.numbers].

View all other issues in [complex.numbers].

View all issues with LEWG status.

Discussion:

Concerning mathematically proper operation of the type:

complex<complex<T> >

Generally accepted mathematical semantics of such a construct correspond to quaternions through Cayly-Dickson construct

(w+xi) + (y+zi) j

The proper implementation seems straightforward by adding a few declarations like those below. I have included operator definition for combining real scalars and complex types, as well, which seems appropriate, as algebra of complex numbers allows mixing complex and real numbers with operators. It also allows for constructs such as complex<double> i=(0,1), x = 12.34 + 5*i;

Quaternions are often used in areas such as computer graphics, where, for example, they avoid the problem of Gimbal lock when rotating objects in 3D space, and can be more efficient than matrix multiplications, although I am applying them to a different field.

/////////////////////////ALLOW OPERATORS TO COMBINE REAL SCALARS AND COMPLEX VALUES /////////////////////////
template<typename T,typename S> complex<T> operator+(const complex<T> x,const S a) {
    complex<T> result(x.real()+a, x.imag());
    return result;
}
template<typename T,typename S> complex<T> operator+(const S a,const complex<T> x) {
    complex<T> result(a+x.real(), x.imag());
    return result;
}
template<typename T,typename S> complex<T> operator-(const complex<T> x,const S a) {
    complex<T> result(x.real()-a, x.imag());
    return result;
}
template<typename T,typename S> complex<T> operator-(const S a,const complex<T> x) {
    complex<T> result(a-x.real(), x.imag());
    return result;
}
template<typename T,typename S> complex<T> operator*(const complex<T> x,const S a) {
    complex<T> result(x.real()*a, x.imag()*a);
    return result;
}
template<typename T,typename S> complex<T> operator*(const S a,const complex<T> x) {
    complex<T> result(a*x.real(), a*x.imag());
    return result;
}

/////////////////////////PROPERLY IMPLEMENT QUATERNION SEMANTICS/////////////////////////
template<typename T> double normSq(const complex<complex<T> >q) {
    return q.real().real()*q.real().real()
         + q.real().imag()*q.real().imag()
         + q.imag().real()*q.imag().real()
         + q.imag().imag()*q.imag().imag();
}
template<typename T> double norm(const complex<complex<T> >q) {
    return sqrt(normSq(q));
}
/////// Cayley-Dickson Construction
template<typename T> complex<complex<T> > conj(const complex<complex<T> > x) {
    complex<complex<T> > result(conj(x.real()),-x.imag());
    return result;
}
template<typename T> complex<complex<T> > operator*(const complex<complex<T> > ab,const complex<complex<T> > cd) {
    complex<T> re(ab.real()*cd.real()-conj(cd.imag())*ab.imag());
    complex<T> im(cd.imag()*ab.real()+ab.imag()*conj(cd.real()));
    complex<complex<double> > q(re,im);
    return q;
}
//// Quaternion division
template<typename S,typename T> complex<complex<T> > operator/(const complex<complex<T> > q,const S a) {
    return q * (1/a);
}
template<typename S,typename T> complex<complex<T> > operator/(const S a,const complex<complex<T> > q) {
    return a*conj(q)/normSq(q);
}
template<typename T> complex<complex<T> > operator/(const complex<complex<T> > n, const complex<complex<T> > d) {
    return n * (conj(d)/normSq(d));
}

[ 2009-10 Santa Cruz: ]

NAD Future. There is no consensus or time to move this into C++0X.

[2017-03-03, Kona]

SG6 suggests this issue is a new feature, not a problem with the existing standard, and should therefore be closed NAD. However, SG6 invites papers that bring the proposal up to date with the current standard.

Proposed resolution: