Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/math/spinor.h

Go to the documentation of this file.
00001 //  Copyright (C) 2000--2002  Petter Urkedal (petter.urkedal@matfys.lth.se)
00002 //
00003 //  This file is free software; you can redistribute it and/or modify
00004 //  it under the terms of the GNU General Public License as published by
00005 //  the Free Software Foundation; either version 2 of the License, or
00006 //  (at your option) any later version.
00007 //
00008 //  This file is distributed in the hope that it will be useful,
00009 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //  GNU General Public License for more details.
00012 //
00013 //  You should have received a copy of the GNU General Public License
00014 //  along with this program; if not, write to the Free Software
00015 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 //
00017 //  As a special exception, you may use this file as part of a free
00018 //  software library without restriction.  Specifically, if other files
00019 //  instantiate templates or use macros or inline functions from this
00020 //  file, or you compile this file and link it with other files to
00021 //  produce an executable, this file does not by itself cause the
00022 //  resulting executable to be covered by the GNU General Public
00023 //  License.  This exception does not however invalidate any other
00024 //  reasons why the executable file might be covered by the GNU General
00025 //  Public License.
00026 //
00027 //  $Id: spinor.h,v 1.1 2002/05/30 18:01:38 petter_urkedal Exp $
00028 
00029 
00030 #ifndef MORE_MATH_SPINOR_H
00031 #define MORE_MATH_SPINOR_H
00032 
00033 #include <iosfwd>
00034 #include <more/math/math.h>
00035 #include <more/math/complex.h>
00036 #include <more/bits/mathbits.h>
00037 #include <more/math/qtypes.h>
00038 #include <more/io/fwd.h>
00039 
00040 namespace more {
00041 namespace math {
00042 
00043   struct alpha_tag {};
00044   struct beta_tag {};
00045 
00046   extern alpha_tag alpha;
00047   extern beta_tag beta;
00048 
00049   struct sigma_x_tag {};
00050   struct sigma_y_tag {};
00051   struct sigma_z_tag {};
00052   extern sigma_x_tag sigma_x;
00053   extern sigma_y_tag sigma_y;
00054   extern sigma_z_tag sigma_z;
00055 
00056 
00057   template<typename T> struct spinopr;
00058 
00059   template<typename T>
00060     struct spinor {
00061         template<typename U> friend class spinor;
00062         spinor() {}
00063         spinor(zero_tag) : u(0), d(0) {}
00064         spinor(alpha_tag) : u(1), d(0) {}
00065         spinor(beta_tag) : u(0), d(1) {}
00066         template<typename U>
00067           spinor(const spinor<U>& x) : u(x.u), d(x.d) {}
00068 
00069         T operator()(half_tag) const { return u; }
00070         T operator()(minus_half_tag) const { return d; }
00071         T& operator()(half_tag) { return u; }
00072         T& operator()(minus_half_tag) { return d; }
00073         T operator()(pm_half i) const { return i==half? u : d; }
00074         T& operator()(pm_half i) { return i==half? u : d; }
00075 
00076         template<typename U>
00077           spinor& operator=(const spinor<U>& rhs) {
00078               u = rhs.u;
00079               d = rhs.d;
00080               return *this;
00081           }
00082         template<typename U>
00083           spinor& operator+=(const spinor<U>& rhs) {
00084               u += rhs.u;
00085               d += rhs.d;
00086               return *this;
00087           }
00088         template<typename U>
00089           spinor& operator-=(const spinor<U>& rhs) {
00090               u -= rhs.u;
00091               d -= rhs.d;
00092               return *this;
00093           }
00094         template<typename U>
00095           spinor& operator*=(const U& rhs) {
00096               u *= rhs;
00097               d *= rhs;
00098               return *this;
00099           }
00100         template<typename U>
00101           spinor& operator/=(const U& rhs) {
00102               u /= rhs;
00103               d /= rhs;
00104               return *this;
00105           }
00106         template<typename U>
00107           spinor& left_multiply(const spinopr<U>&);
00108 
00109         spinor& negate() { u = -u; d = -d; return *this; }
00110 
00111         void sync(io::syncstream&);
00112 
00113       private:
00114         T u, d;
00115     };
00116 
00117   template<typename T>
00118     struct spinopr {
00119         template<typename U> friend class spinopr;
00120         spinopr() {}
00121         spinopr(zero_tag) : uu(0), du(0), ud(0), dd(0) {}
00122         spinopr(one_tag) : uu(1), du(0), ud(0), dd(1) {}
00123         spinopr(sigma_x_tag) : uu(0), du(1), ud(1), dd(0) {}
00124         spinopr(sigma_y_tag)
00125             : uu(0), du(T(1)*onei), ud(-T(1)*onei), dd(0) {}
00126         spinopr(sigma_z_tag) : uu(1), du(0), ud(0), dd(-1) {}
00127         spinopr(T x, sigma_x_tag) : uu(0), du(x), ud(x), dd(0) {}
00128         spinopr(T x, sigma_y_tag)
00129             : uu(0), du(x*onei), ud(-x*onei), dd(0) {}
00130         spinopr(T x, sigma_z_tag) : uu(x), du(0), ud(0), dd(-x) {}
00131         template<typename U>
00132           spinopr(const U& x) : uu(x), du(0), ud(0), dd(x) {}
00133         template<typename U>
00134           spinopr(const spinopr<U>& x)
00135               : uu(x.uu), du(x.du), ud(x.ud), dd(x.dd) {}
00136         template<typename U, typename V>
00137           spinopr(const spinor<U>& x, const spinor<V>& y)
00138               : uu(x(half)*conj(y( half))), du(x(-half)*conj(y( half))),
00139                 ud(x(half)*conj(y(-half))), dd(x(-half)*conj(y(-half))) {}
00140 
00141         T operator()(half_tag, half_tag) const { return uu; }
00142         T operator()(half_tag, minus_half_tag) const { return ud; }
00143         T operator()(minus_half_tag, half_tag) const { return du; }
00144         T operator()(minus_half_tag, minus_half_tag) const { return dd; }
00145         T& operator()(half_tag, half_tag) { return uu; }
00146         T& operator()(half_tag, minus_half_tag) { return ud; }
00147         T& operator()(minus_half_tag, half_tag) { return du; }
00148         T& operator()(minus_half_tag, minus_half_tag) { return dd; }
00149         T operator()(pm_half i, pm_half j) const {
00150             return i == half? (j == half? uu : ud)
00151                             : (j == half? du : dd);
00152         }
00153         T& operator()(pm_half i, pm_half j) {
00154             return i == half? (j == half? uu : ud)
00155                             : (j == half? du : dd);
00156         }
00157 
00158         spinopr& operator=(const zero_tag& rhs) {
00159             uu = ud = du = dd = T(0);
00160             return *this;
00161         }
00162         spinopr& operator=(const one_tag& rhs) {
00163             uu = dd = T(1);
00164             ud = du = T(0);
00165             return *this;
00166         }
00167         template<typename U>
00168           spinopr& operator=(const spinopr<U>& rhs) {
00169               uu = rhs.uu;
00170               du = rhs.du;
00171               ud = rhs.ud;
00172               dd = rhs.dd;
00173               return *this;
00174           }
00175         template<typename U>
00176           spinopr& operator+=(const spinopr<U>& rhs) {
00177               uu += rhs.uu;
00178               du += rhs.du;
00179               ud += rhs.ud;
00180               dd += rhs.dd;
00181               return *this;
00182           }
00183         template<typename U>
00184           spinopr& operator-=(const spinopr<U>& rhs) {
00185               uu -= rhs.uu;
00186               du -= rhs.du;
00187               ud -= rhs.ud;
00188               dd -= rhs.dd;
00189               return *this;
00190           }
00191         template<typename U>
00192           spinopr& operator*=(const spinopr<U>& rhs) {
00193               T uus = uu, dus = du;
00194               uu = uu*rhs.uu + ud*rhs.du;
00195               du = du*rhs.uu + dd*rhs.du;
00196               ud = uus*rhs.ud + ud*rhs.dd;
00197               dd = dus*rhs.ud + dd*rhs.dd;
00198               return *this;
00199           }
00200 
00201         template<typename U>
00202           spinopr& operator=(const U& rhs) {
00203               uu = rhs;
00204               du = 0;
00205               ud = 0;
00206               dd = rhs;
00207               return *this;
00208           }
00209         template<typename U>
00210           spinopr& operator+=(const U& rhs) {
00211               uu += rhs;
00212               dd += rhs;
00213               return *this;
00214           }
00215         template<typename U>
00216           spinopr& operator-=(const U& rhs) {
00217               uu -= rhs;
00218               dd -= rhs;
00219               return *this;
00220           }
00221         template<typename U>
00222           spinopr& operator*=(const U& rhs) {
00223               uu *= rhs;
00224               du *= rhs;
00225               ud *= rhs;
00226               dd *= rhs;
00227               return *this;
00228           }
00229         template<typename U>
00230           spinopr& operator/=(const U& rhs) {
00231               return *this *= 1.0/rhs;
00232           }
00233         spinopr& operator*=(sigma_x_tag) {
00234             T uus = uu, dus = du;
00235             uu = ud;
00236             du = dd;
00237             ud = uus;
00238             dd = dus;
00239             return *this;
00240         }
00241         spinopr& operator*=(sigma_y_tag) {
00242             T uus = uu, dus = du;
00243             uu = onei*ud;
00244             du = onei*dd;
00245             ud = -onei*uus;
00246             dd = -onei*dus;
00247             return *this;
00248         }
00249         spinopr& operator*=(sigma_z_tag) {
00250             ud = -ud;
00251             dd = -dd;
00252             return *this;
00253         }
00254         spinopr& left_multiply(sigma_x_tag) {
00255             T uus = uu, uds = ud;
00256             uu = du;
00257             du = uus;
00258             ud = dd;
00259             dd = uds;
00260             return *this;
00261         }
00262         spinopr& left_multiply(sigma_y_tag) {
00263             T uus = uu, uds = ud;
00264             uu = -onei*du;
00265             du =  onei*uus;
00266             ud = -onei*dd;
00267             dd =  onei*uds;
00268             return *this;
00269         }
00270         spinopr& left_multiply(sigma_z_tag) {
00271             du = -du;
00272             dd = -dd;
00273             return *this;
00274         }
00275         spinopr& negate() {
00276             uu = -uu;
00277             du = -du;
00278             ud = -ud;
00279             dd = -dd;
00280             return *this;
00281         }
00282         spinopr& adj() {
00283             T dus = du;
00284             uu = conj(uu);
00285             du = conj(ud);
00286             ud = conj(dus);
00287             dd = conj(dd);
00288             return *this;
00289         }
00290 
00291         void sync(io::syncstream&);
00292 
00293       private:
00294         T uu, du, ud, dd;
00295     };
00296 
00297 
00298   // -- alpha_tag, beta_tag --
00299 
00300   template<typename T>
00301     inline spinor<T>
00302     operator*(T x, alpha_tag) {
00303         spinor<T> z;
00304         z( half) = x;
00305         z(-half) = 0;
00306         return z;
00307     }
00308   template<typename T>
00309     inline spinor<T>
00310     operator*(T x, beta_tag) {
00311         spinor<T> z;
00312         z( half) = 0;
00313         z(-half) = x;
00314         return z;
00315     }
00316 
00317 
00318   // -- sigma_x, sigma_y, sigma_z --
00319 
00320   template<typename T>
00321     inline spinopr<T> operator*(T x, sigma_x_tag) {
00322         return spinopr<T>(x, sigma_x_tag());
00323     }
00324   template<typename T>
00325     inline spinopr<T> operator*(sigma_x_tag, T y) {
00326         return spinopr<T>(y, sigma_x_tag());
00327     }
00328   template<typename T>
00329     inline spinopr<T> operator*(T x, sigma_y_tag) {
00330         return spinopr<T>(x, sigma_y_tag());
00331     }
00332   template<typename T>
00333     inline spinopr<T> operator*(sigma_y_tag, T y) {
00334         return spinopr<T>(y, sigma_y_tag());
00335     }
00336   template<typename T>
00337     inline spinopr<T> operator*(T x, sigma_z_tag) {
00338         return spinopr<T>(x, sigma_z_tag());
00339     }
00340   template<typename T>
00341     inline spinopr<T> operator*(sigma_z_tag, T y) {
00342         return spinopr<T>(y, sigma_z_tag());
00343     }
00344 
00345   template<typename T>
00346     inline spinopr<T>
00347     operator*(const spinopr<T>& x, sigma_x_tag) {
00348         return spinopr<T>(x) *= sigma_x_tag();
00349     }
00350   template<typename T>
00351     inline spinopr<T>
00352     operator*(sigma_x_tag, const spinopr<T>& y) {
00353         return spinopr<T>(y).left_multiply(sigma_x_tag());
00354     }
00355   template<typename T>
00356     inline spinopr<T>
00357     operator*(const spinopr<T>& x, sigma_y_tag) {
00358         return spinopr<T>(x) *= sigma_y_tag();
00359     }
00360   template<typename T>
00361     inline spinopr<T>
00362     operator*(sigma_y_tag, const spinopr<T>& y) {
00363         return spinopr<T>(y).left_multiply(sigma_y_tag());
00364     }
00365   template<typename T>
00366     inline spinopr<T>
00367     operator*(const spinopr<T>& x, sigma_z_tag) {
00368         return spinopr<T>(x) *= sigma_z_tag();
00369     }
00370   template<typename T>
00371     inline spinopr<T>
00372     operator*(sigma_z_tag, const spinopr<T>& y) {
00373         return spinopr<T>(y).left_multiply(sigma_z_tag());
00374     }
00375 
00376   template<typename T>
00377     inline spinopr<T> operator+(const spinopr<T>& x, sigma_x_tag) {
00378         return x + spinopr<T>(sigma_x_tag());
00379     }
00380   template<typename T>
00381     inline spinopr<T> operator+(sigma_x_tag, const spinopr<T>& y) {
00382         return spinopr<T>(sigma_x_tag()) + y;
00383     }
00384   template<typename T>
00385     inline spinopr<T> operator+(const spinopr<T>& x, sigma_y_tag) {
00386         return x + spinopr<T>(sigma_y_tag());
00387     }
00388   template<typename T>
00389     inline spinopr<T> operator+(sigma_y_tag, const spinopr<T>& y) {
00390         return spinopr<T>(sigma_y_tag()) + y;
00391     }
00392   template<typename T>
00393     inline spinopr<T> operator+(const spinopr<T>& x, sigma_z_tag) {
00394         return x + spinopr<T>(sigma_z_tag());
00395     }
00396   template<typename T>
00397     inline spinopr<T> operator+(sigma_z_tag, const spinopr<T>& y) {
00398         return spinopr<T>(sigma_z_tag()) + y;
00399     }
00400 
00401 
00402   // -- spinor --
00403 
00404   template<typename T>
00405     inline spinor<T>
00406     operator+(const spinor<T>& x) {
00407         return x;
00408     }
00409   template<typename T>
00410     inline spinor<T>
00411     operator-(const spinor<T>& x) {
00412         return spinor<T>(x).negate();
00413     }
00414   template<typename T, typename U>
00415     inline spinor< typename plus_type_<T, U>::eval >
00416     operator+(const spinor<T>& x, const spinor<U>& y) {
00417         return spinor< typename plus_type_<T, U>::eval >(x) += y;
00418     }
00419   template<typename T, typename U>
00420     inline spinor< typename minus_type_<T, U>::eval >
00421     operator-(const spinor<T>& x, const spinor<U>& y) {
00422         return spinor< typename minus_type_<T, U>::eval >(x) -= y;
00423     }
00424 #if 0
00425   template<typename T, typename U>
00426     inline spinor< typename times_type_<T, U>::eval >
00427     operator*(const spinor<T>& x, U y) {
00428         return spinor< typename times_type_<T, U>::eval >(x) *= y;
00429     }
00430   template<typename T, typename U>
00431     inline spinor< typename times_type_<T, U>::eval >
00432     operator*(T x, const spinor<U>& y) {
00433         return spinor< typename times_type_<T, U>::eval >(y) *= x;
00434     }
00435   template<typename T, typename U>
00436     inline spinor< typename divides_type_<T, U>::eval >
00437     operator/(const spinor<T>& x, U y) {
00438         return spinor< typename divides_type_<T, U>::eval >(x) /= y;
00439     }
00440 #else
00441   template<typename T>
00442     inline spinor<T>
00443     operator*(const spinor<T>& x, T y) {
00444         return spinor<T>(x) *= y;
00445     }
00446   template<typename T>
00447     inline spinor<T>
00448     operator*(T x, const spinor<T>& y) {
00449         return spinor<T>(y) *= x;
00450     }
00451   template<typename T>
00452     inline spinor<T>
00453     operator/(const spinor<T>& x, T y) {
00454         return spinor<T>(x) /= y;
00455     }
00456   template<typename T>
00457     inline spinor< std::complex<T> >
00458     operator*(const spinor< std::complex<T> >& x, T y) {
00459         return spinor< std::complex<T> >(x) *= y;
00460     }
00461   template<typename T>
00462     inline spinor< std::complex<T> >
00463     operator*(T x, const spinor< std::complex<T> >& y) {
00464         return spinor< std::complex<T> >(y) *= x;
00465     }
00466   template<typename T>
00467     inline spinor< std::complex<T> >
00468     operator/(const spinor< std::complex<T> >& x, T y) {
00469         return spinor< std::complex<T> >(x) /= y;
00470     }
00471   template<typename T>
00472     inline spinor<T>
00473     operator*(const spinor<T>& x, const std::complex<T>& y) {
00474         return spinor<T>(x) *= y;
00475     }
00476   template<typename T>
00477     inline spinor<T>
00478     operator*(const std::complex<T>& x, const spinor<T>& y) {
00479         return spinor<T>(y) *= x;
00480     }
00481   template<typename T>
00482     inline spinor<T>
00483     operator/(const spinor<T>& x, const std::complex<T>& y) {
00484         return spinor<T>(x) /= y;
00485     }
00486 #endif
00487 
00488 
00489   // -- spinopr --
00490 
00491   template<typename T>
00492     inline spinopr<T>
00493     operator+(const spinopr<T>& x) {
00494         return x;
00495     }
00496   template<typename T>
00497     inline spinopr<T>
00498     operator-(const spinopr<T>& x) {
00499         return spinopr<T>(x).negate();
00500     }
00501 
00502   template<typename T, typename U>
00503     inline spinopr<typename plus_type_<T, U>::eval>
00504     operator+(const spinopr<T>& x, const spinopr<U>& y) {
00505         return spinopr<typename plus_type_<T, U>::eval>(x) += y;
00506     }
00507   template<typename T, typename U>
00508     inline spinopr<typename minus_type_<T, U>::eval>
00509     operator-(const spinopr<T>& x, const spinopr<U>& y) {
00510         return spinopr<typename minus_type_<T, U>::eval>(x) -= y;
00511     }
00512   template<typename T, typename U>
00513     inline spinopr<typename times_type_<T, U>::eval>
00514     operator*(const spinopr<T>& x, const spinopr<U>& y) {
00515         return spinopr<typename times_type_<T, U>::eval>(x) *= y;
00516     }
00517 
00518   template<typename T, typename U>
00519     inline spinopr<typename plus_type_<T, U>::eval>
00520     operator+(const spinopr<T>& x, U y) {
00521         return spinopr<typename plus_type_<T, U>::eval>(x) += y;
00522     }
00523   template<typename T, typename U>
00524     inline spinopr<typename plus_type_<T, U>::eval>
00525     operator+(T x, const spinopr<U>& y) {
00526         return spinopr<typename plus_type_<T, U>::eval>(y) += x;
00527     }
00528   template<typename T, typename U>
00529     inline spinopr<typename minus_type_<T, U>::eval>
00530     operator-(const spinopr<T>& x, U y) {
00531         return spinopr<typename minus_type_<T, U>::eval>(x) -= y;
00532     }
00533   template<typename T, typename U>
00534     inline spinopr<typename minus_type_<T, U>::eval>
00535     operator-(T x, const spinopr<U>& y) {
00536         return spinopr<typename minus_type_<T, U>::eval>(y).negate() += x;
00537     }
00538   template<typename T, typename U>
00539     inline spinopr<typename times_type_<T, U>::eval>
00540     operator*(const spinopr<T>& x, U y) {
00541         return spinopr<typename times_type_<T, U>::eval>(x) *= y;
00542     }
00543   template<typename T, typename U>
00544     inline spinopr<typename times_type_<T, U>::eval>
00545     operator*(T x, const spinopr<U>& y) {
00546         return spinopr<typename times_type_<T, U>::eval>(y) *= x;
00547     }
00548   template<typename T, typename U>
00549     inline spinopr<typename divides_type_<T, U>::eval>
00550     operator/(const spinopr<T>& x, U y) {
00551         return spinopr<typename divides_type_<T, U>::eval>(x) /= y;
00552     }
00553 
00554 
00555   // -- spinopr, spinor, cospinor --
00556 
00557   template<typename T>
00558     template<typename U>
00559     inline spinor<T>&
00560     spinor<T>::left_multiply(const spinopr<U>& lhs) {
00561         T us = u;
00562         u = lhs( half, half)*u  + lhs( half, -half)*d;
00563         d = lhs(-half, half)*us + lhs(-half, -half)*d;
00564 //      u *= lhs( half,  half);  u += lhs( half, -half)*d;
00565 //      d *= lhs(-half, -half);  d += lhs(-half,  half)*us;
00566         return *this;
00567     }
00568   template<typename T>
00569     inline spinor<T>
00570     operator*(const spinopr<T>& x, const spinor<T>& y) {
00571         return spinor<T>(y).left_multiply(x);
00572     }
00573 
00574 
00575   // -- IO --
00576 
00577   template<typename T>
00578     std::ostream& operator<<(std::ostream&, const spinor<T>&);
00579   template<typename T>
00580     std::ostream& operator<<(std::ostream&, const spinopr<T>&);
00581   template<typename T>
00582     std::istream& operator>>(std::istream&, spinor<T>&);
00583   template<typename T>
00584     std::istream& operator>>(std::istream&, spinopr<T>&);
00585 
00586 
00587 
00588   // --- VARIOUS, i.e. not yet systematized! ---
00589 
00590   // -- spinor, cospinor --
00591 
00592   template<typename T> struct norm_type_< spinor<T> >
00593     { typedef typename norm_type_<T>::eval eval; };
00594   template<typename T> struct norm_type_< spinopr<T> >
00595     { typedef typename norm_type_<T>::eval eval; };
00596   template<typename T> struct scalar_type_< spinor<T> >
00597     { typedef typename scalar_type_<T>::eval eval; };
00598   template<typename T>
00599     struct scalar_type_< spinopr<T> > { typedef T eval; };
00600 
00601   template<> struct norm_type_<alpha_tag> { typedef one_tag eval; };
00602   template<> struct norm_type_<beta_tag> { typedef one_tag eval; };
00603   template<typename T>
00604     struct outer_product_type_< spinor<T> > { typedef spinopr<T> eval; };
00605 
00606   template<typename T>
00607     inline typename norm_type_<T>::eval
00608     norm(const spinor<T>& x) { return norm(x(half)) + norm(x(-half)); }
00609   template<typename T>
00610     inline typename norm_type_<T>::eval
00611     abs(const spinor<T>& x) { return sqrt(norm(x)); }
00612   template<typename T>
00613     inline typename norm_type_<T>::eval
00614     norm(const spinopr<T>& x) {
00615         return norm(x( half, half)) + norm(x( half, -half))
00616              + norm(x(-half, half)) + norm(x(-half, -half));
00617     }
00618   template<typename T>
00619     inline typename norm_type_<T>::eval
00620     abs(const spinopr<T>& x) { return sqrt(norm(x)); }
00621 
00622   template<typename T>
00623     inline T
00624     dot(const spinor<T>& x, const spinor<T>& y) {
00625         return conj(x(-half))*y(-half) + conj(x(half))*y(half);
00626     }
00627   template<typename T>
00628     inline T
00629     real_dot(const spinor< std::complex<T> >& x,
00630              const spinor< std::complex<T> >& y) {
00631         return real(x(-half))*real(y(-half)) + imag(x(-half))*imag(y(-half))
00632              + real(x( half))*real(y( half)) + imag(x( half))*imag(y( half));
00633     }
00634   template<typename T>
00635     inline spinopr<T>
00636     outer_prod(const spinor<T>& x, const spinor<T>& y) {
00637         return spinopr<T>(x, y);
00638     }
00639 
00640   template<typename T>
00641     inline spinopr<T>
00642     adj(const spinopr<T>& x) { return spinopr<T>(x).adj(); }
00643 
00644   template<typename T>
00645     inline T
00646     trace(const spinopr<T>& x) {
00647         return x(half, half) + x(-half, -half);
00648     }
00649   template<typename T>
00650     inline T
00651     det(const spinopr<T>& x) {
00652         return x(half, half)*x(-half, -half) - x(half, -half)*x(-half, half);
00653     }
00654   template<typename T>
00655     inline T
00656     sum(const spinor<T>& x) {
00657         return x(half) + x(-half);
00658     }
00659 
00660   template<typename T>
00661     inline bool
00662     finite(const spinor<T>& x) {
00663         return finite(x(half)) && finite(x(-half));
00664     }
00665   template<typename T>
00666     inline bool
00667     finite(const spinopr<T>& x) {
00668         return finite(x( half, half)) && finite(x( half, -half))
00669             && finite(x(-half, half)) && finite(x(-half, -half));
00670     }
00671   template<typename T>
00672     spinopr<T>
00673     sin(spinopr<T> const& x);
00674   template<typename T>
00675     spinopr<T>
00676     cos(spinopr<T> const& x);
00677   template<typename T>
00678     spinopr<T>
00679     tan(spinopr<T> const& x);
00680   template<typename T>
00681     spinopr<T>
00682     sinh(spinopr<T> const& x);
00683   template<typename T>
00684     spinopr<T>
00685     cosh(spinopr<T> const& x);
00686   template<typename T>
00687     spinopr<T>
00688     tanh(spinopr<T> const& x);
00689   template<typename T>
00690     spinopr<T>
00691     exp(spinopr<T> const& x);
00692   template<typename T>
00693     spinopr<T>
00694     log(spinopr<T> const& x);
00695   template<typename T>
00696     spinopr<T>
00697     sqrt(spinopr<T> const& x);
00698 }
00699   using namespace math;
00700 }
00701 
00702 #endif

Generated on Sat Sep 7 19:11:19 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.