00001 #include <more/math/spinor.h>
00002
00003 namespace more {
00004 namespace math {
00005
00006 struct coalpha_tag {};
00007 struct cobeta_tag {};
00008 extern coalpha_tag coalpha;
00009 extern cobeta_tag cobeta;
00010
00011 template<typename T>
00012 struct cospinor {
00013 template<typename U> friend class cospinor;
00014 cospinor() {}
00015 cospinor(zero_tag) : u(0), d(0) {}
00016 cospinor(coalpha_tag) : u(1), d(0) {}
00017 cospinor(cobeta_tag) : u(0), d(1) {}
00018 template<typename U>
00019 cospinor(const cospinor<U>& x) : u(x.u), d(x.d) {}
00020
00021 T operator()(half_tag) const { return u; }
00022 T operator()(minus_half_tag) const { return d; }
00023 T& operator()(half_tag) { return u; }
00024 T& operator()(minus_half_tag) { return d; }
00025 T operator()(pm_half i) const { return i==half? u : d; }
00026 T& operator()(pm_half i) { return i==half? u : d; }
00027
00028 template<typename U>
00029 cospinor& operator=(const cospinor<U>& rhs) {
00030 u = rhs.u;
00031 d = rhs.d;
00032 return *this;
00033 }
00034 template<typename U>
00035 cospinor& operator+=(const cospinor<U>& rhs) {
00036 u += rhs.u;
00037 d += rhs.d;
00038 return *this;
00039 }
00040 template<typename U>
00041 cospinor& operator-=(const cospinor<U>& rhs) {
00042 u -= rhs.u;
00043 d -= rhs.d;
00044 return *this;
00045 }
00046 template<typename U>
00047 cospinor& operator*=(const U& rhs) {
00048 u *= rhs;
00049 d *= rhs;
00050 return *this;
00051 }
00052 template<typename U>
00053 cospinor& operator/=(const U& rhs) {
00054 u /= rhs;
00055 d /= rhs;
00056 return *this;
00057 }
00058 template<typename U>
00059 cospinor& operator*=(const spinopr<U>&);
00060
00061 cospinor& negate() { u = -u; d = -d; return *this; }
00062
00063 private:
00064 T u, d;
00065 };
00066
00067 template<typename T>
00068 inline cospinor<T>
00069 operator*(T x, coalpha_tag) {
00070 cospinor<T> z;
00071 z( half) = x;
00072 z(-half) = 0;
00073 return z;
00074 }
00075 template<typename T>
00076 inline cospinor<T>
00077 operator*(T x, cobeta_tag) {
00078 cospinor<T> z;
00079 z( half) = 0;
00080 z(-half) = x;
00081 return z;
00082 }
00083 template<typename T>
00084 inline T
00085 operator*(coalpha_tag, const spinor<T>& x) {
00086 return x(half);
00087 }
00088 template<typename T>
00089 inline T
00090 operator*(cobeta_tag, const spinor<T>& x) {
00091 return x(-half);
00092 }
00093 template<typename T>
00094 inline T
00095 operator*(const cospinor<T>& x, alpha_tag) {
00096 return x(half);
00097 }
00098 template<typename T>
00099 inline T
00100 operator*(const cospinor<T>& x, beta_tag) {
00101 return x(-half);
00102 }
00103
00104
00105
00106
00107 template<typename T>
00108 inline cospinor<T>
00109 operator+(const cospinor<T>& x) {
00110 return x;
00111 }
00112 template<typename T>
00113 inline cospinor<T>
00114 operator-(const cospinor<T>& x) {
00115 return cospinor<T>(x).negate();
00116 }
00117 template<typename T, typename U>
00118 inline cospinor< typename plus_type_<T, U>::eval >
00119 operator+(const cospinor<T>& x, const cospinor<U>& y) {
00120 return cospinor< typename plus_type_<T, U>::eval >(x) += y;
00121 }
00122 template<typename T, typename U>
00123 inline cospinor< typename minus_type_<T, U>::eval >
00124 operator-(const cospinor<T>& x, const cospinor<U>& y) {
00125 return cospinor< typename minus_type_<T, U>::eval >(x) -= y;
00126 }
00127 template<typename T, typename U>
00128 inline cospinor< typename times_type_<T, U>::eval >
00129 operator*(const cospinor<T>& x, U y) {
00130 return cospinor< typename times_type_<T, U>::eval >(x) *= y;
00131 }
00132 template<typename T, typename U>
00133 inline cospinor< typename times_type_<T, U>::eval >
00134 operator*(T x, const cospinor<U>& y) {
00135 return cospinor< typename times_type_<T, U>::eval >(y) *= x;
00136 }
00137 template<typename T, typename U>
00138 inline cospinor< typename divides_type_<T, U>::eval >
00139 operator/(const cospinor<T>& x, U y) {
00140 return cospinor< typename divides_type_<T, U>::eval >(x) /= y;
00141 }
00142
00143
00144
00145
00146 template<typename T, typename U>
00147 inline typename times_type_<T, U>::eval
00148 operator*(const cospinor<T>& x, const spinor<U>& y) {
00149 return x(-half)*y(-half) + x(half)*y(half);
00150 }
00151 template<typename T, typename U>
00152 inline spinopr< typename times_type_<T, U>::eval >
00153 operator*(const spinor<T>& x, const cospinor<U>& y) {
00154 return spinopr< typename times_type_<T, U>::eval >(x, adj(y));
00155 }
00156
00157
00158 template<typename T>
00159 template<typename U>
00160 inline cospinor<T>&
00161 cospinor<T>::operator*=(const spinopr<U>& rhs) {
00162 T us = u;
00163
00164
00165 u *= rhs( half, half); u += d *rhs(-half, half);
00166 d *= rhs(-half, -half); d += us*rhs( half, -half);
00167 return *this;
00168 }
00169 template<typename T>
00170 inline cospinor<T>
00171 operator*(const cospinor<T>& x, const spinopr<T>& y) {
00172 return cospinor<T>(x) *= y;
00173 }
00174
00175 template<typename T>
00176 std::ostream& operator<<(std::ostream&, const cospinor<T>&);
00177 template<typename T>
00178 std::istream& operator>>(std::istream&, cospinor<T>&);
00179
00180 template<> struct norm_type_<coalpha_tag> { typedef one_tag eval; };
00181 template<> struct norm_type_<cobeta_tag> { typedef one_tag eval; };
00182
00183 template<typename T>
00184 inline typename norm_type_<T>::eval
00185 norm(const cospinor<T>& x) { return norm(x(half)) + norm(x(-half)); }
00186 template<typename T>
00187 inline typename norm_type_<T>::eval
00188 abs(const cospinor<T>& x) { return sqrt(norm(x)); }
00189
00190
00191
00192
00193
00194 template<typename T>
00195 inline T
00196 real_dot(const cospinor< std::complex<T> >& x,
00197 const cospinor< std::complex<T> >& y) {
00198 return real(x(-half))*real(y(-half)) + imag(x(-half))*imag(y(-half))
00199 + real(x( half))*real(y( half)) + imag(x( half))*imag(y( half));
00200 }
00201
00202 template<typename T>
00203 inline cospinor<T>
00204 adj(const spinor<T>& x) {
00205 return conj(coalpha*x)*coalpha + conj(cobeta*x)*cobeta;
00206 }
00207 template<typename T>
00208 inline spinor<T>
00209 adj(const cospinor<T>& x) {
00210 return conj(x*alpha)*alpha + conj(x*beta)*beta;
00211 }
00212 template<typename T>
00213 inline T
00214 sum(const cospinor<T>& x) {
00215 return x(half) + x(-half);
00216 }
00217 template<typename T>
00218 inline bool
00219 finite(const cospinor<T>& x) {
00220 return finite(x(half)) && finite(x(-half));
00221 }
00222
00223 }}