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