原文:http://www.boost.org/libs/math/octonion/octonion.html

c++boost.gif (8819 bytes)Class octonion

四元数同様、八元数も複素数と 関係深いものである。

理論物理学では、八元数をよく利用するようである。

実質的には、八元数は単純に八つの実数 から成るものであり、 のように書く。ここで、 , , は 四元数の説明で用いたものと同様のものであり、 , , , は 本質的には , , と 同じ役割をするが全く異なるものである。

八元数における加法、乗法を定義する。これらにより、四元数の加法、乗法を一般化 できる。ここでの中心となる新事項は、 "乗法には交換法則が成り立たないものがあり、今は結合法則も成り立たない" (i.e. ある四元数 , , となる)である。 以下に早見表を上げる:

八元数やそれに類するものの詳細については、他のドキュメント( document, errata and addenda )に記述されている。

指数関数のような伝統的な構造のものは、あまり変更せずに八元数の領域に適用できる が、平方根を持つようなものはそうではない。指数関数が閉じた形の関数であるのは 最初に定義した人物によるものだが、八元数において指数関数が存在することは ずっと前に知られていることである。

Acknowledgements

数式の編集には Nisus Writer を使用した。Jens Maurer氏には推敲(has helped with portability and standard adherence)とプレビューの管理で協力して戴いた。 諸々の感謝については History の部分で述べる。このライブラリを議論し 協力してくださった方々に感謝する。

Header File

インターフェースと実装を提供するのがヘッダ octonion.h である。

Test Program

テストプログラムoctonion_test.cppは、 float, double, long double型での八元数の特殊化のテストを 行なう。(出力サンプル)

以下の環境で動作確認をした:

  • PowerPC G3 -- CodeWarrior for Mac OS Professional Edition v6(Metroworks)

Synopsis

namespace boost
{
	namespace math
	{
		
		template<typename T> class octonion;
		template<>           class octonion<float>;
		template<>           class octonion<double>; 
		template<>           class octonion<long double>; 
		
		// operators
		
		template<typename T> inline octonion<T> operator + (T const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator + (octonion<T> const & lhs, T const & rhs);
		template<typename T> inline octonion<T> operator + (::std::complex<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator + (octonion<T> const & lhs, ::std::complex<T> const & rhs);
		template<typename T> inline octonion<T> operator + (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator + (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
		template<typename T> inline octonion<T> operator + (octonion<T> const & lhs, octonion<T> const & rhs);
		
		template<typename T> inline octonion<T> operator - (T const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator - (octonion<T> const & lhs, T const & rhs);
		template<typename T> inline octonion<T> operator - (::std::complex<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator - (octonion<T> const & lhs, ::std::complex<T> const & rhs);
		template<typename T> inline octonion<T> operator - (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator - (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
		template<typename T> inline octonion<T> operator - (octonion<T> const & lhs, octonion<T> const & rhs);
		
		template<typename T> inline octonion<T> operator * (T const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator * (octonion<T> const & lhs, T const & rhs);
		template<typename T> inline octonion<T> operator * (::std::complex<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator * (octonion<T> const & lhs, ::std::complex<T> const & rhs);
		template<typename T> inline octonion<T> operator * (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator * (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
		template<typename T> inline octonion<T> operator * (octonion<T> const & lhs, octonion<T> const & rhs);
		
		template<typename T> inline octonion<T> operator / (T const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator / (octonion<T> const & lhs, T const & rhs);
		template<typename T> inline octonion<T> operator / (::std::complex<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator / (octonion<T> const & lhs, ::std::complex<T> const & rhs);
		template<typename T> inline octonion<T> operator / (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline octonion<T> operator / (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
		template<typename T> inline octonion<T> operator / (octonion<T> const & lhs, octonion<T> const & rhs); 
		
		template<typename T> inline octonion<T> operator + (octonion<T> const & o);
		template<typename T> inline octonion<T> operator - (octonion<T> const & o); 
		
		template<typename T> inline bool operator == (T const & lhs, octonion<T> const & rhs);
		template<typename T> inline bool operator == (octonion<T> const & lhs, T const & rhs);
		template<typename T> inline bool operator == (::std::complex<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline bool operator == (octonion<T> const & lhs, ::std::complex<T> const & rhs);
		template<typename T> inline bool operator == (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline bool operator == (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
		template<typename T> inline bool operator == (octonion<T> const & lhs, octonion<T> const & rhs);
		
		template<typename T> inline bool operator != (T const & lhs, octonion<T> const & rhs);
		template<typename T> inline bool operator != (octonion<T> const & lhs, T const & rhs);
		template<typename T> inline bool operator != (::std::complex<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline bool operator != (octonion<T> const & lhs, ::std::complex<T> const & rhs);
		template<typename T> inline bool operator != (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
		template<typename T> inline bool operator != (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
		template<typename T> inline bool operator != (octonion<T> const & lhs, octonion<T> const & rhs); 
		
		template<typename T, typename charT, class traits>
		::std::basic_istream<charT,traits> &	operator >> (::std::basic_istream<charT,traits> & is, octonion<T> & o);
		
		template<typename T, typename charT, class traits>
		::std::basic_ostream<charT,traits> &	operator << (::std::basic_ostream<charT,traits> & os, octonion<T> const & o);
		
		// values
		
		template<typename T>	inline T		real(octonion<T> const & o);
		template<typename T>	inline octonion<T>	unreal(octonion<T> const & o);
		
		template<typename T>	inline T		sup(octonion<T> const & o);
		template<typename T>	inline T		l1(octonion<T>const & o);	
		template<typename T>	inline T		abs(octonion<T> const & o);
		template<typename T>	inline T		norm(octonion<T>const  & o);
		template<typename T>	inline octonion<T>	conj(octonion<T> const & o);
		
		template<typename T>	inline octonion<T>	spherical(T const & rho, T const & theta, T const & phi1, T const & phi2, T const & phi3, T const & phi4, T const & phi5, T const & phi6);
		template<typename T>	inline octonion<T>	multipolar(T const & rho1, T const & theta1, T const & rho2, T const & theta2, T const & rho3, T const & theta3, T const & rho4, T const & theta4);
		template<typename T>	inline octonion<T>	cylindrical(T const & r, T const & angle, T const & h1, T const & h2, T const & h3, T const & h4, T const & h5, T const & h6);
		
		// transcendentals
		
		template<typename T>	inline octonion<T>	exp(octonion<T> const & o);
		template<typename T>	inline octonion<T>	cos(octonion<T> const & o);
		template<typename T>	inline octonion<T>	sin(octonion<T> const & o);
		template<typename T>	inline octonion<T>	tan(octonion<T> const & o);
		template<typename T>	inline octonion<T>	cosh(octonion<T> const & o);
		template<typename T>	inline octonion<T>	sinh(octonion<T> const & o);
		template<typename T>	inline octonion<T>	tanh(octonion<T> const & o);
		
		template<typename T>	octonion<T>		pow(octonion<T> const & o, int n);
		
	}
}

Template class octonion

namespace boost
{
	namespace math
	{
	
		template<typename T>
		class octonion
		{
		public:
			
			typedef T value_type;
			
			explicit		octonion(T const & requested_a = T(), T const & requested_b = T(), T const & requested_c = T(), T const & requested_d = T(), T const & requested_e = T(), T const & requested_f = T(), T const & requested_g = T(), T const & requested_h = T());
			explicit		octonion(::std::complex<T> const & z0, ::std::complex<T> const & z1 = ::std::complex<T>(), ::std::complex<T> const & z2 = ::std::complex<T>(), ::std::complex<T> const & z3 = ::std::complex<T>());
			explicit		octonion(::boost::math::quaternion<T> const & q0, ::boost::math::quaternion<T> const & q1 = ::boost::math::quaternion<T>());
			template<typename X> explicit	octonion(octonion<X> const & a_recopier);
			
			T			real() const;
			octonion<T>		unreal() const;
			
			T			R_component_1() const;
			T			R_component_2() const;
			T			R_component_3() const;
			T			R_component_4() const;
			T			R_component_5() const;
			T			R_component_6() const;
			T			R_component_7() const;
			T			R_component_8() const;
			
			::std::complex<T>	C_component_1() const;
			::std::complex<T>	C_component_2() const;
			::std::complex<T>	C_component_3() const;
			::std::complex<T>	C_component_4() const;
			
			::boost::math::quaternion<T>	H_component_1() const;
			::boost::math::quaternion<T>	H_component_2() const;
			
			octonion<T> &	operator = (octonion<T> const  & a_affecter);
			template<typename X>	octonion<T> &	operator = (octonion<X> const  & a_affecter);
			octonion<T> &	operator = (T const  & a_affecter);
			octonion<T> &	operator = (::std::complex<T> const & a_affecter);
			octonion<T> &	operator = (::boost::math::quaternion<T> const & a_affecter);
			
			octonion<T> &	operator += (T const & rhs);
			octonion<T> &	operator += (::std::complex<T> const & rhs);
			octonion<T> &	operator += (::boost::math::quaternion<T> const & rhs);
			template<typename X>	octonion<T> &	operator += (octonion<X> const & rhs);
			
			octonion<T> &	operator -= (T const & rhs);
			octonion<T> &	operator -= (::std::complex<T> const & rhs);
			octonion<T> &	operator -= (::boost::math::quaternion<T> const & rhs);
			template<typename X>	octonion<T> &	operator -= (octonion<X> const & rhs);
			
			octonion<T> &	operator *= (T const & rhs);
			octonion<T> &	operator *= (::std::complex<T> const & rhs);
			octonion<T> &	operator *= (::boost::math::quaternion<T> const & rhs);
			template<typename X>	octonion<T> &	operator *= (octonion<X> const & rhs);
			
			octonion<T> &	operator /= (T const & rhs);
			octonion<T> &	operator /= (::std::complex<T> const & rhs);
			octonion<T> &	operator /= (::boost::math::quaternion<T> const & rhs);
			template<typename X>	octonion<T> &	operator /= (octonion<X> const & rhs);
			
		};
		
	}
}

octonion specializations

namespace boost
{
	namespace math
	{
		
		template<>
		class octonion<float>
		{
		public:
			
			typedef float value_type;
			
			explicit		octonion(float const & requested_a = 0.0f, float const & requested_b = 0.0f, float const & requested_c = 0.0f, float const & requested_d = 0.0f, float const & requested_e = 0.0f, float const & requested_f = 0.0f, float const & requested_g = 0.0f, float const & requested_h = 0.0f);
			explicit		octonion(::std::complex<float> const & z0, ::std::complex<float> const & z1 = ::std::complex<float>(), ::std::complex<float> const & z2 = ::std::complex<float>(), ::std::complex<float> const & z3 = ::std::complex<float>());
			explicit		octonion(::boost::math::quaternion<float> const & q0, ::boost::math::quaternion<float> const & q1 = ::boost::math::quaternion<float>());
			explicit		octonion(octonion<double> const & a_recopier);
			explicit		octonion(octonion<long double> const & a_recopier);
			
			float			real() const;
			octonion<float>	unreal() const;
			
			float			R_component_1() const;
			float			R_component_2() const;
			float			R_component_3() const;
			float			R_component_4() const;
			float			R_component_5() const;
			float			R_component_6() const;
			float			R_component_7() const;
			float			R_component_8() const;
			
			::std::complex<float>	C_component_1() const;
			::std::complex<float>	C_component_2() const;
			::std::complex<float>	C_component_3() const;
			::std::complex<float>	C_component_4() const;
			
			::boost::math::octonion<float>	H_component_1() const;
			::boost::math::octonion<float>	H_component_2() const;
			
			octonion<float> &	operator = (octonion<float> const & a_affecter);
			template<typename X>	octonion<float> &	operator = (octonion<X>const  & a_affecter);
			octonion<float> &	operator = (float const & a_affecter);
			octonion<float> &	operator = (::std::complex<float> const & a_affecter);
			octonion<float> &	operator = (::boost::math::quaternion<float> const & a_affecter);
			
			octonion<float> &	operator += (float const & rhs);
			octonion<float> &	operator += (::std::complex<float> const & rhs);
			template<typename X>	octonion<float> &	operator += (octonion<X> const & rhs);
			
			octonion<float> &	operator -= (float const & rhs);
			octonion<float> &	operator -= (::std::complex<float> const & rhs);
			octonion<float> &	operator -= (::boost::math::quaternion<float> const & rhs);
			template<typename X>	octonion<float> &	operator -= (octonion<X> const & rhs);
			
			octonion<float> &	operator *= (float const & rhs);
			octonion<float> &	operator *= (::std::complex<float> const & rhs);
			octonion<float> &	operator *= (::boost::math::quaternion<float> const & rhs);
			template<typename X>	octonion<float> &	operator *= (octonion<X> const & rhs);
			
			octonion<float> &	operator /= (float const & rhs);
			octonion<float> &	operator /= (::std::complex<float> const & rhs);
			octonion<float> &	operator /= (::boost::math::quaternion<float> const & rhs);
			template<typename X>	octonion<float> &	operator /= (octonion<X> const & rhs);
		};
		
		
		template<>
		class octonion<double>
		{
		public:
			
			typedef double value_type;
			
			explicit		octonion(double const & requested_a = 0.0, double const & requested_b = 0.0, double const & requested_c = 0.0, double const & requested_d = 0.0, double const & requested_e = 0.0, double const & requested_f = 0.0, double const & requested_g = 0.0, double const & requested_h = 0.0);
			explicit		octonion(::std::complex<double> const & z0, ::std::complex<double> const & z1 = ::std::complex<double>(), ::std::complex<double> const & z2 = ::std::complex<double>(), ::std::complex<double> const & z3 = ::std::complex<double>());
			explicit		octonion(::boost::math::quaternion<double> const & q0, ::boost::math::quaternion<double> const & q1 = ::boost::math::quaternion<double>());
			explicit		octonion(octonion<float> const & a_recopier);
			explicit		octonion(octonion<long double> const & a_recopier);
			
			double			real() const;
			octonion<double>	unreal() const;
			
			double			R_component_1() const;
			double			R_component_2() const;
			double			R_component_3() const;
			double			R_component_4() const;
			double			R_component_5() const;
			double			R_component_6() const;
			double			R_component_7() const;
			double			R_component_8() const;
			
			::std::complex<double>	C_component_1() const;
			::std::complex<double>	C_component_2() const;
			::std::complex<double>	C_component_3() const;
			::std::complex<double>	C_component_4() const;
			
			::boost::math::quaternion<double>	H_component_1() const;
			::boost::math::quaternion<double>	H_component_2() const;
			
			octonion<double> &	operator = (octonion<double> const & a_affecter);
			template<typename X>	octonion<double> &	operator = (octonion<X> const & a_affecter);
			octonion<double> &	operator = (double const & a_affecter);
			octonion<double> &	operator = (::std::complex<double> const & a_affecter);
			octonion<double> &	operator = (::boost::math::quaternion<double> const & a_affecter);
			
			octonion<double> &	operator += (double const & rhs);
			octonion<double> &	operator += (::std::complex<double> const & rhs);
			octonion<double> &	operator += (::boost::math::quaternion<double> const & rhs);
			template<typename X> octonion<double> &	operator += (octonion<X> const & rhs);
			
			octonion<double> &	operator -= (double const & rhs);
			octonion<double> &	operator -= (::std::complex<double> const & rhs);
			octonion<double> &	operator -= (::boost::math::quaternion<double> const & rhs);
			template<typename X> octonion<double> &	operator -= (octonion<X> const & rhs);
			
			octonion<double> &	operator *= (double const & rhs);
			octonion<double> &	operator *= (::std::complex<double> const & rhs);
			octonion<double> &	operator *= (::boost::math::quaternion<double> const & rhs);
			template<typename X> octonion<double> &	operator *= (octonion<X> const & rhs);
			
			octonion<double> &	operator /= (double const & rhs);
			octonion<double> &	operator /= (::std::complex<double> const & rhs);
			octonion<double> &	operator /= (::boost::math::quaternion<double> const & rhs);
			template<typename X>	octonion<double> &	operator /= (octonion<X> const & rhs);
		};
		
		
		template<>
		class octonion<long double>
		{
		public:
			
			typedef long double value_type;
			
			explicit			octonion(long double const & requested_a = 0.0L, long double const & requested_b = 0.0L, long double const & requested_c = 0.0L, long double const & requested_d = 0.0L, long double const & requested_e = 0.0L, long double const & requested_f = 0.0L, long double const & requested_g = 0.0L, long double const & requested_h = 0.0L);
			explicit			octonion(	::std::complex<long double> const & z0, ::std::complex<long double> const & z1 = ::std::complex<long double>(), ::std::complex<long double> const & z2 = ::std::complex<long double>(), ::std::complex<long double> const & z3 = ::std::complex<long double>());
			explicit			octonion(	::boost::math::quaternion<long double> const & q0, ::boost::math::quaternion<long double> const & z1 = ::boost::math::quaternion<long double>());
			explicit			octonion(octonion<float> const & a_recopier);
			explicit			octonion(octonion<double> const & a_recopier);
			
			long double			real() const;
			octonion<long double>		unreal() const;
			
			long double			R_component_1() const;
			long double			R_component_2() const;
			long double			R_component_3() const;
			long double			R_component_4() const;
			long double			R_component_5() const;
			long double			R_component_6() const;
			long double			R_component_7() const;
			long double			R_component_8() const;
			
			::std::complex<long double>	C_component_1() const;
			::std::complex<long double>	C_component_2() const;
			::std::complex<long double>	C_component_3() const;
			::std::complex<long double>	C_component_4() const;
			
			::boost::math::quaternion<long double>	H_component_1() const;
			::boost::math::quaternion<long double>	H_component_2() const;
			
			octonion<long double> &	operator = (octonion<long double> const & a_affecter);
			template<typename X>	octonion<long double> &	operator = (octonion<X> const & a_affecter);
			octonion<long double> &	operator = (long double const & a_affecter);
			octonion<long double> &	operator = (::std::complex<long double> const & a_affecter);
			octonion<long double> &	operator = (::boost::math::quaternion<long double> const & a_affecter);
			
			octonion<long double> &	operator += (long double const & rhs);
			octonion<long double> &	operator += (::std::complex<long double> const & rhs);
			octonion<long double> &	operator += (::boost::math::quaternion<long double> const & rhs);
			template<typename X>	octonion<long double> &	operator += (octonion<X> const & rhs);
			
			octonion<long double> &	operator -= (long double const & rhs);
			octonion<long double> &	operator -= (::std::complex<long double> const & rhs);
			octonion<long double> &	operator -= (::boost::math::quaternion<long double> const & rhs);
			template<typename X>	octonion<long double> &	operator -= (octonion<X> const & rhs);
			
			octonion<long double> &	operator *= (long double const & rhs);
			octonion<long double> &	operator *= (::std::complex<long double> const & rhs);
			octonion<long double> &	operator *= (::boost::math::quaternion<long double> const & rhs);
			template<typename X>	octonion<long double> &	operator *= (octonion<X> const & rhs);
			
			octonion<long double> &	operator /= (long double const & rhs);
			octonion<long double> &	operator /= (::std::complex<long double> const & rhs);
			octonion<long double> &	operator /= (::boost::math::quaternion<long double> const & rhs);
			template<typename X>	octonion<long double> &	operator /= (octonion<X> const & rhs);
		};
		
	}
}

octonion typedefs

value_type

typedef T value_type;

テンプレート版

typedef float value_type;

float型の特殊化版

typedef double value_type;

double型の特殊化版

typedef long double value_type;

long double型の特殊化版

これらにより、テンプレートが作られる型へのアクセスが容易になる。

octonion member functions

Constructors

explicit		octonion(T const & requested_a = T(), T const & requested_b = T(), T const & requested_c = T(), T const & requested_d = T(), T const & requested_e = T(), T const & requested_f = T(), T const & requested_g = T(), T const & requested_h = T());
explicit		octonion(::std::complex<T> const & z0, ::std::complex<T> const & z1 = ::std::complex<T>(), ::std::complex<T> const & z2 = ::std::complex<T>(), ::std::complex<T> const & z3 = ::std::complex<T>());
explicit		octonion(::boost::math::quaternion<T> const & q0, ::boost::math::quaternion<T> const & q1 = ::boost::math::quaternion<T>());
template<typename X> explicit	octonion(octonion<X> const & a_recopier);

テンプレート版

explicit		octonion(float const & requested_a = 0.0f, float const & requested_b = 0.0f, float const & requested_c = 0.0f, float const & requested_d = 0.0f, float const & requested_e = 0.0f, float const & requested_f = 0.0f, float const & requested_g = 0.0f, float const & requested_h = 0.0f);
explicit		octonion(::std::complex<float> const & z0, ::std::complex<float> const & z1 = ::std::complex<float>(), ::std::complex<float> const & z2 = ::std::complex<float>(), ::std::complex<float> const & z3 = ::std::complex<float>());
explicit		octonion(::boost::math::quaternion<float> const & q0, ::boost::math::quaternion<float> const & q1 = ::boost::math::quaternion<float>());
explicit		octonion(octonion<double> const & a_recopier); 
explicit		octonion(octonion<long double> const & a_recopier);

float型の特殊化版

explicit		octonion(double const & requested_a = 0.0, double const & requested_b = 0.0, double const & requested_c = 0.0, double const & requested_d = 0.0, double const & requested_e = 0.0, double const & requested_f = 0.0, double const & requested_g = 0.0, double const & requested_h = 0.0);
explicit		octonion(::std::complex<double> const & z0, ::std::complex<double> const & z1 = ::std::complex<double>(), ::std::complex<double> const & z2 = ::std::complex<double>(), ::std::complex<double> const & z3 = ::std::complex<double>());
explicit		octonion(::boost::math::quaternion<double> const & q0, ::boost::math::quaternion<double> const & q1 = ::boost::math::quaternion<double>());
explicit		octonion(octonion<float> const & a_recopier);
explicit		octonion(octonion<long double> const & a_recopier);

double型の特殊化版

explicit		octonion(long double const & requested_a = 0.0L, long double const & requested_b = 0.0L, long double const & requested_c = 0.0L, long double const & requested_d = 0.0L, long double const & requested_e = 0.0L, long double const & requested_f = 0.0L, long double const & requested_g = 0.0L, long double const & requested_h = 0.0L);
explicit		octonion(	::std::complex<long double> const & z0, ::std::complex<long double> const & z1 = ::std::complex<long double>(), ::std::complex<long double> const & z2 = ::std::complex<long double>(), ::std::complex<long double> const & z3 = ::std::complex<long double>());
explicit		octonion(::boost::math::quaternion<long double> const & q0, ::boost::math::quaternion<long double> const & q1 = ::boost::math::quaternion<long double>());
explicit		octonion(octonion<float> const & a_recopier);
explicit		octonion(octonion<double> const & a_recopier);

long doubleの特殊化版

デフォルトのコンストラクタはそれぞれの版で提供され、 それぞれのコンポーネント はその型でのデフォルト値で初期化される( i.e.浮動小数ではゼロ )。 また、このコンストラクタは1〜8つまで 基底型の引数をとることができる。 さらに、コンストラクタが提供されるのは、同じ基底型を有する1〜4つの複素数、または 同じ基底型を有する1〜2つの四元数から八元数を作るためである。 ( A constructor is also provided to build octonions from one to four complex numbers sharing the same base type, and another taking one or two quaternions sharing the same base type. ) 特殊化版が他の2つの特殊化版からのコピーコンストラクタを持っている間は、 特殊化されていないテンプレートはテンプレート化されたコピーコンストラクタを 持ち、精度を損なう危険があるときでは明示的である。 ( The unspecialized template also sports a templarized copy constructor, while the specialized forms have copy constructors from the other two specializations, which are explicit when a risk of precision loss exists. ) 特殊化されていないもののために、基底型のコンストラクタが 発生してはならない。

同じ型からのコピーコンストラクタ、及びデストラクタはコンパイラによって提供 される。

Other member functions

T			real() const;
octonion<T>		unreal() const;

八元数は、複素数と同様に "実部" という重要な概念を持っているが、 複素数と異なり "虚部" という重要な概念は存在しない。その代わり、 "実部ではない部分" があり、それこそが八元数である。また、( 複素数の 場合とは対照的に )通例単純ではない。最初の2つの関数がこれらを返す。

T			R_component_1() const;
T			R_component_2() const;
T			R_component_3() const;
T			R_component_4() const;
T			R_component_5() const;
T			R_component_6() const;
T			R_component_7() const;
T			R_component_8() const;

八元数は8つの実成分を持っており、これら8つの関数が値を返す。 それゆえに、 realR_component_1 は同じ値を返す。

::std::complex<T>	C_component_1() const;
::std::complex<T>	C_component_2() const;
::std::complex<T>	C_component_3() const;
::std::complex<T>	C_component_4() const;

同様に、八元数は4つの複素数を成分として持つ。 実際、八元数は複素数四次元空間のベクトル場であるが ( octonions are indeed a (left) vector field over the complexes ) 、どのような八元数 についても (※最後の項の中は"-") と書けることに注意。しかしながら、C_component_n関数が返すのは、 コンストラクタを用いた八元数を作るのに利用できるであろう複素数であり、 八元数の成分ではない

::boost::math::quaternion<T>	H_component_1() const;
::boost::math::quaternion<T>	H_component_2() const;

同様にどのような八元数 についても と書けるが、四元数を成分とした、ベクトル空間のような構造という意味は無い。 H_component_n関数が返すのは、コンストラクタを用いた八元数を 作るのに利用できるであろう四元数である。

octonion member operators

Assignment operators

octonion<T> & operator = (octonion<T> const & a_affecter);
template<typename X> octonion<T> & operator = (octonion<X> const & a_affecter);
octonion<T> & operator = (T const & a_affecter);
octonion<T> & operator = (::std::complex<T> const & a_affecter);
octonion<T> & operator = (::boost::math::quaternion<T> const & a_affecter);

これらは代入を行ない、必要があれば変換する( 例えば、基底型からの 代入では、その値は実部へと変換される。すなわち、他の成分はゼロとなる )。 特殊化版でない場合、基底型の代入演算子は発生してはならない。

Other member operators

octonion<T> &	operator += (T const & rhs)
octonion<T> &	operator += (::std::complex<T> const & rhs);
octonion<T> &	operator += (::boost::math::quaternion<T> const & rhs);
template<typename X>	octonion<T> &	operator += (octonion<X> const & rhs);

これらは数学演算子 (*this)+rhs を求めて代入を行なう。 特殊化版でないものは例外 安全の強い保証を尊守している。 特殊化版では、例外の安全性を保証するために、代入まで行なう。 特殊化版でない場合、基底型の代入演算子は発生してはならない。

octonion<T> &	operator -= (T const & rhs)
octonion<T> &	operator -= (::std::complex<T> const & rhs);
octonion<T> &	operator -= (::boost::math::quaternion<T> const & rhs);
template<typename X>	octonion<T> &	operator -= (octonion<X> const & rhs);

これらは数学演算子 (*this)-rhs を求めて代入を行なう。 特殊化版でないものは例外 安全の強い保証を尊守している。 特殊化版では、例外の安全性を保証するために、代入まで行なう。 特殊化版でない場合、基底型の代入演算子は発生してはならない。

octonion<T> &	operator *= (T const & rhs)
octonion<T> &	operator *= (::std::complex<T> const & rhs);
octonion<T> &	operator *= (::boost::math::quaternion<T> const & rhs);
template<typename X>	octonion<T> &	operator *= (octonion<X> const & rhs);

これらは数学演算子 (*this)*rhs を、 前述した通りの順序で、求めて代入を行なう( 八元数では 乗法の可換でないため、乗法の順序は重要である )。 特殊化版でないものは例外 安全の強い保証を尊守している。 特殊化版では、例外の安全性を保証するために、代入まで行なう。 特殊化版でない場合、基底型の代入演算子は発生してはならない。 また、八元数では乗法の結合法則が成り立たないことから、 論理を明確にするために二つの集合の乗法では いつでも 要素をまとめるべきである( もちろんこの事が重要でないときもあるが、 大抵は重要である )。

octonion<T> &	operator /= (T const & rhs)
octonion<T> &	operator /= (::std::complex<T> const & rhs);
octonion<T> &	operator /= (::boost::math::quaternion<T> const & rhs);
template<typename X>	octonion<T> &	operator /= (octonion<X> const & rhs);

これらは数学演算子 (*this)*inverse_of(rhs) との積を、前述した通りの順序で、 求めて代入を行なう( 八元数では 乗法の可換でないため、乗法の順序は重要である )。 特殊化版でないものは例外 安全の強い保証を尊守している。 特殊化版では、例外の安全性を保証するために、代入まで行なう。 特殊化版でない場合、基底型の代入演算子は発生してはならない。 この乗法では、括弧で括った二つの要素をまとめることを忘れずに 行ないなさい。

octonion non-member operations

template<typename T>	inline octonion<T>	operator + (octonion<T> const & o);

この単項演算子はただ o を返す。

template<typename T>	inline octonion<T>	operator - (octonion<T> const & o);

この単項演算子は o の逆符号のものを返す。

template<typename T>	inline octonion<T>	operator + (T const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator + (octonion<T> const & lhs, T const & rhs);
template<typename T>	inline octonion<T>	operator + (::std::complex<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator + (octonion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T>	inline octonion<T>	operator + (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator + (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
template<typename T>	inline octonion<T>	operator + (octonion<T> const & lhs, octonion<T> const & rhs);

これらの演算子は octonion<T>(lhs) += rhs を返す。

template<typename T>	inline octonion<T>	operator - (T const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator - (octonion<T> const & lhs, T const & rhs);
template<typename T>	inline octonion<T>	operator - (::std::complex<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator - (octonion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T>	inline octonion<T>	operator - (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator - (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
template<typename T>	inline octonion<T>	operator - (octonion<T> const & lhs, octonion<T> const & rhs);

これらの演算子は octonion<T>(lhs) -= rhs を返す。

template<typename T>	inline octonion<T>	operator * (T const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator * (octonion<T> const & lhs, T const & rhs);
template<typename T>	inline octonion<T>	operator * (::std::complex<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator * (octonion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T>	inline octonion<T>	operator * (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator * (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
template<typename T>	inline octonion<T>	operator * (octonion<T> const & lhs, octonion<T> const & rhs);

これら演算子子は octonion<T>(lhs) *= rhs を返す。

template<typename T>	inline octonion<T>	operator / (T const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator / (octonion<T> const & lhs, T const & rhs);
template<typename T>	inline octonion<T>	operator / (::std::complex<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator / (octonion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T>	inline octonion<T>	operator / (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline octonion<T>	operator / (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
template<typename T>	inline octonion<T>	operator / (octonion<T> const & lhs, octonion<T> const & rhs);

これらの演算子は octonion<T>(lhs) /= rhs を返す。 ゼロでの除法は、もちろんエラーになる...。

template<typename T>	inline bool	operator == (T const & lhs, octonion<T> const & rhs);
template<typename T>	inline bool	operator == (octonion<T> const & lhs, T const & rhs);
template<typename T>	inline bool	operator == (::std::complex<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline bool	operator == (octonion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T>	inline bool	operator == (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline bool	operator == (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
template<typename T>	inline bool	operator == (octonion<T> const & lhs, octonion<T> const & rhs);

これらは、 octonion<T>(lhs) の四つの成分とこれらの 対応成分とが等しければ true を返す。 どんな浮動小数点型のものであっても、本質的には意味が無い。

template<typename T>	inline bool	operator != (T const & lhs, octonion<T> const & rhs);
template<typename T>	inline bool	operator != (octonion<T> const & lhs, T const & rhs);
template<typename T>	inline bool	operator != (::std::complex<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline bool	operator != (octonion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T>	inline bool	operator != (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs);
template<typename T>	inline bool	operator != (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs);
template<typename T>	inline bool	operator != (octonion<T> const & lhs, octonion<T> const & rhs);

これらは、 octonion<T>(lhs) == octonion<T>(rhs) が 偽のときのみ、 true を返す。 どんな浮動小数点型のものであっても、本質的には意味が無い。

template<typename T, typename charT, class traits>
::std::basic_istream<charT,traits> &	operator >> (::std::basic_istream<charT,traits> & is, octonion<T> & o);

八元数 o を引き出す。妥当なようならばどのような書式でも 受けいれる。しかしながらこのことが多大なあいまいさに引き起こし、 これらを向上させるためにいくつかの解決がなされた。 疑念がある場合は実態を示す。

入力値は T に変換できなければならない。 不正な入力に出くわしたときは、 is.setstate(ios::failbit) を呼ぶ( ios::failure (27.4.5.3) が発生するかもしれない )。

返り値は ( Returns is. )。

template<typename T, typename charT, class traits>
::std::basic_ostream<charT,traits> &	operator << (::std::basic_ostream<charT,traits> & os, octonion<T> const & o);

以下に示す通り、あたかも実装されたかのように、 八元数 o をストリーム os に挿入する:

	template<typename T, typename charT, class traits>
	::std::basic_ostream<charT,traits> &	operator << (	::std::basic_ostream<charT,traits> & os,
								octonion<T> const & o)
					{
						::std::basic_ostringstream<charT,traits>	s;
						
						s.flags(os.flags());
						s.imbue(os.getloc());
						s.precision(os.precision());
						
						s << '('	<< o.R_component_1() << ','
								<< o.R_component_2() << ','
								<< o.R_component_3() << ','
								<< o.R_component_4() << ','
								<< o.R_component_5() << ','
								<< o.R_component_6() << ','
								<< o.R_component_7() << ','
								<< o.R_component_8() << ')';
									
						return os << s.str();
					}

octonion value operations

template<typename T>	inline T		real(octonion<T> const & o);
template<typename T>	inline octonion<T>	unreal(octonion<T> const & o);

これらはそれぞれ、 o.real()o.unreal() を返す。

template<typename T>	inline octonion<T>	conj(octonion<T> const & o);

これは八元数の共役を返す。

template<typename T>	inline T	 	sup(octonion<T> const & o);

これは八元数の最大ノルム( abs(o.R_component_1())...abs(o.Rcomponent_8())間の 最大値)を返す。

template<typename T>	inline T	 	l1(octonion<T> const & o);

これは八元数の1-ノルム( abs(o.R_component_1())+...+abs(o.R_component_8()) )を返す。

template<typename T>	inline T	 	abs(octonion<T> const & o);

これは八元数の大きさ(ユークリッドノルム)を返す。

template<typename T>	inline T		norm(octonion<T>const  & o);

これは八元数の(ケイリー)ノルムを返す。"ノルム"という言葉から ユークリッドノルム(二次関数のようなもの)を連想する人々にとっては、 "ノルム"が混乱を招くものかもしれない。八元数(として 知られる数学的なもの)についてのこの表現としては、(大きさとして 知られている)ユークリッドノルムはケイリーノルムの 平方根である。

template<typename T>	inline octonion<T>	spherical(T const & rho, T const & theta, T const & phi1, T const & phi2, T const & phi3, T const & phi4, T const & phi5, T const & phi6);
template<typename T>	inline octonion<T>	multipolar(T const & rho1, T const & theta1, T const & rho2, T const & theta2, T const & rho3, T const & theta3, T const & rho4, T const & theta4);
template<typename T>	inline octonion<T>	cylindrical(T const & r, T const & angle, T const & h1, T const & h2, T const & h3, T const & h4, T const & h5, T const & h6);

これらは、polarが複素数を構築するように、八元数を構築する。 ただし、八元数にとって極座標が全く同等であるというわけではない。

sphericalは単にpolarを置換したもので、 入力として(明確な)大きさと、三つの視点から得られる多次元球上の点を取る。 最初のシータ theta
spherical is a simple transposition of polar, it takes as inputs a (positive) magnitude and a point on the hypersphere, given by three angles. The first of these, theta has a natural range of -pi to +pi, and the other two have natural ranges of -pi/2 to +pi/2 (as is the case with the usual spherical coordinates in R^3). Due to the many symmetries and periodicities, nothing untoward happens if the magnitude is negative or the angles are outside their natural ranges. The expected degeneracies (a magnitude of zero ignores the angles settings...) do happen however.

cylindrical is likewise a simple transposition of the usual cylindrical coordinates in R^3, which in turn is another derivative of planar polar coordinates. The first two inputs are the polar coordinates of the first C component of the octonion. The third and fourth inputs are placed into the third and fourth R components of the octonion, respectively.

multipolar is yet another simple generalization of polar coordinates. This time, both C components of the octonion are given in polar coordinates.

In this version of our implementation of octonions, there is no analogue of the complex value operation arg as the situation is somewhat more complicated.

octonion transcendentals

There is no log or sqrt provided for octonions in this implementation, and pow is likewise restricted to integral powers of the exponent. There are several reasons to this: on the one hand, the equivalent of analytic continuation for octonions ("branch cuts") remains to be investigated thoroughly (by me, at any rate...), and we wish to avoid the nonsense introduced in the standard by exponentiations of complexes by complexes (which is well defined, but not in the standard...). Talking of nonsense, saying that pow(0,0) is "implementation defined" is just plain brain-dead...

We do, however provide several transcendentals, chief among which is the exponential. That it allows for a "closed formula" is a result of the author (the existence and definition of the exponential, on the octonions among others, on the other hand, is a few centuries old). Basically, any converging power series with real coefficients which allows for a closed formula in C can be transposed to O. More transcendentals of this type could be added in a further revision upon request. It should be noted that it is these functions which force the dependency upon the boost/math/special_functions/sinc.hpp and the boost/math/special_functions/sinhc.hpp headers.

exp

template<typename T>	inline octonion<T>	exp(octonion<T> const & o);

Computes the exponential of the octonion.

cos

template<typename T>	inline octonion<T>	cos(octonion<T> const & o);

Computes the cosine of the octonion

sin

template<typename T>	inline octonion<T>	sin(octonion<T> const & o);

Computes the sine of the octonion.

tan

template<typename T>	inline octonion<T>	tan(octonion<T> const & o);

Computes the tangent of the octonion.

cosh

template<typename T>	inline octonion<T>	cosh(octonion<T> const & o);

Computes the hyperbolic cosine of the octonion.

sinh

template<typename T>	inline octonion<T>	sinh(octonion<T> const & o);

Computes the hyperbolic sine of the octonion.

tanh

template<typename T>	inline octonion<T>	tanh(octonion<T> const & o);

Computes the hyperbolic tangent of the octonion.

pow

template<typename T>	octonion<T>		pow(octonion<T> const & o, int n);

Computes the n-th power of the octonion q.

History

  • 1.5.3 - 01/02/2002: bugfix and Gcc 2.95.3 compatibility by Douglas Gregor (gregod@cs.rpi.edu).
  • 1.5.2 - 07/07/2001: introduced namespace math.
  • 1.5.1 - 07/06/2001: (end of Boost review) now includes <boost/math/special_functions/sinc.hpp> and <boost/math/special_functions/sinhc.hpp> instead of <boost/special_functions.hpp>; corrected bug in sin (Daryle Walker); removed check for self-assignment (Gary Powel); made converting functions explicit (Gary Powel); added overflow guards for division operators and abs (Peter Schmitteckert); added sup and l1; used Vesa Karvonen's CPP metaprograming technique to simplify code.
  • 1.5.0 - 23/03/2001: boostification, inlining of all operators except input, output and pow, fixed exception safety of some members (template version).
  • 1.4.0 - 09/01/2001: added tan and tanh.
  • 1.3.1 - 08/01/2001: cosmetic fixes.
  • 1.3.0 - 12/07/2000: pow now uses Maarten Hilferink's (mhilferink@tip.nl) algorithm.
  • 1.2.0 - 25/05/2000: fixed the division operators and output; changed many signatures.
  • 1.1.0 - 23/05/2000: changed sinc into sinc_pi; added sin, cos, sinh, cosh.
  • 1.0.0 - 10/08/1999: first public version.

Revised 01 Feb 2002

© Copyright Hubert Holin 2001, 2002. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This software is provided "as is" without express or implied  warranty, and with no claim as to its suitability for any purpose.