00001 /*************************************************************************** 00002 * blitz/zero.h Zero elements 00003 * 00004 * $Id: zero.h,v 1.5 2003/12/11 03:44:22 julianc Exp $ 00005 * 00006 * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU General Public License 00010 * as published by the Free Software Foundation; either version 2 00011 * of the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * Suggestions: blitz-dev@oonumerics.org 00019 * Bugs: blitz-bugs@oonumerics.org 00020 * 00021 * For more information, please see the Blitz++ Home Page: 00022 * http://oonumerics.org/blitz/ 00023 * 00024 ***************************************************************************/ 00025 00026 /* 00027 * The purpose of the ZeroElement class is to provide an lvalue for 00028 * non-const element access of matrices with zero elements. For 00029 * example, a tridiagonal matrix has many elements which are 00030 * always zero: 00031 * 00032 * [ x x 0 0 ] 00033 * [ x x x 0 ] 00034 * [ 0 x x x ] 00035 * [ 0 0 x x ] 00036 * 00037 * To implement an operator()(int i, int j) for a tridiagonal 00038 * matrix which may be used as an lvalue 00039 * 00040 * e.g. Matrix<double, Tridiagonal> M(4,4); 00041 * M(1,2) = 3.0L; 00042 * 00043 * some way of returning an lvalue for the zero elements is needed. 00044 * (Either that, or an intermediate class must be returned -- but 00045 * this is less efficient). The solution used for the Blitz++ 00046 * library is to have a unique zero element for each numeric 00047 * type (float, double, etc.). This zero element is then 00048 * returned as an lvalue when needed. 00049 * 00050 * The disadvantage is the possibility of setting the global 00051 * zero-element to something non-zero. 00052 */ 00053 00054 #ifndef BZ_ZERO_H 00055 #define BZ_ZERO_H 00056 00057 #ifndef BZ_BLITZ_H 00058 #include <blitz/blitz.h> 00059 #endif 00060 00061 BZ_NAMESPACE(blitz) 00062 00063 template<typename P_numtype> 00064 class ZeroElement { 00065 public: 00066 typedef P_numtype T_numtype; 00067 00068 static T_numtype& zero() 00069 { 00070 return zero_; 00071 } 00072 00073 private: 00074 static T_numtype zero_; 00075 }; 00076 00077 // Specialization of ZeroElement for complex<float>, complex<double>, 00078 // and complex<long double> 00079 00080 #define BZZERO_DECLARE(T) \ 00081 template<> \ 00082 class ZeroElement<T > { \ 00083 public: \ 00084 static T& zero() \ 00085 { return zero_; } \ 00086 private: \ 00087 static T zero_; \ 00088 } 00089 00090 #ifdef BZ_HAVE_COMPLEX 00091 BZZERO_DECLARE(complex<float>); 00092 BZZERO_DECLARE(complex<double>); 00093 BZZERO_DECLARE(complex<long double>); 00094 #endif // BZ_HAVE_COMPLEX 00095 00096 // initialization of static data member for general class template 00097 00098 template<typename P_numtype> 00099 P_numtype ZeroElement<P_numtype>::zero_ = 0; 00100 00101 BZ_NAMESPACE_END 00102 00103 #endif // BZ_ZERO_H 00104