This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD status.

1217. Quaternion support

Section: 28.4 [complex.numbers] Status: NAD Submitter: Ted Shaneyfelt Opened: 2009-09-26 Last modified: 2019-02-26

Priority: Not Prioritized

View all other issues in [complex.numbers].

View all issues with NAD 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.

[LEWG Kona 2017]

Recommend SG6 - We note that complex<complex> is the wrong way to spell this

[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: