|
Blender
V2.59
|
00001 /* 00002 * $Id: NM_Scalar.h 35158 2011-02-25 11:49:19Z jesterking $ 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * The Original Code is: all of this file. 00023 * 00024 * Contributor(s): none yet. 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <math.h> 00035 #include <iostream> 00036 00037 template <class T> 00038 class NM_Scalar { 00039 public: 00040 NM_Scalar() {} 00041 explicit NM_Scalar(T value, T error = 0.0) : 00042 m_value(value), m_error(error) {} 00043 00044 T getValue() const { return m_value; } 00045 T getError() const { return m_error; } 00046 00047 operator T() const { return m_value; } 00048 00049 NM_Scalar operator-() const { 00050 return NM_Scalar<T>(-m_value, m_error); 00051 } 00052 00053 NM_Scalar& operator=(T value) { 00054 m_value = value; 00055 m_error = 0.0; 00056 return *this; 00057 } 00058 00059 NM_Scalar& operator+=(const NM_Scalar& x) { 00060 m_value += x.m_value; 00061 m_error = (fabs(m_value) * (m_error + 1.0) + 00062 fabs(x.m_value) * (x.m_error + 1.0)) / 00063 fabs(m_value + x.m_value); 00064 return *this; 00065 } 00066 00067 NM_Scalar& operator-=(const NM_Scalar& x) { 00068 m_value -= x.m_value; 00069 m_error = (fabs(m_value) * (m_error + 1.0) + 00070 fabs(x.m_value) * (x.m_error + 1.0)) / 00071 fabs(m_value - x.m_value); 00072 return *this; 00073 } 00074 00075 NM_Scalar& operator*=(const NM_Scalar& x) { 00076 m_value *= x.m_value; 00077 m_error += x.m_error + 1.0; 00078 return *this; 00079 } 00080 00081 NM_Scalar& operator/=(const NM_Scalar& x) { 00082 m_value /= x.m_value; 00083 m_error += x.m_error + 1.0; 00084 return *this; 00085 } 00086 00087 private: 00088 T m_value; 00089 T m_error; 00090 }; 00091 00092 template <class T> 00093 inline NM_Scalar<T> operator+(const NM_Scalar<T>& x, const NM_Scalar<T>& y) { 00094 return x.getValue() == 0.0 && y.getValue() == 0.0 ? 00095 NM_Scalar<T>(0.0, 0.0) : 00096 NM_Scalar<T>(x.getValue() + y.getValue(), 00097 (fabs(x.getValue()) * (x.getError() + 1.0) + 00098 fabs(y.getValue()) * (y.getError() + 1.0)) / 00099 fabs(x.getValue() + y.getValue())); 00100 } 00101 00102 template <class T> 00103 inline NM_Scalar<T> operator-(const NM_Scalar<T>& x, const NM_Scalar<T>& y) { 00104 return x.getValue() == 0.0 && y.getValue() == 0.0 ? 00105 NM_Scalar<T>(0.0, 0.0) : 00106 NM_Scalar<T>(x.getValue() - y.getValue(), 00107 (fabs(x.getValue()) * (x.getError() + 1.0) + 00108 fabs(y.getValue()) * (y.getError() + 1.0)) / 00109 fabs(x.getValue() - y.getValue())); 00110 } 00111 00112 template <class T> 00113 inline NM_Scalar<T> operator*(const NM_Scalar<T>& x, const NM_Scalar<T>& y) { 00114 return NM_Scalar<T>(x.getValue() * y.getValue(), 00115 x.getError() + y.getError() + 1.0); 00116 } 00117 00118 template <class T> 00119 inline NM_Scalar<T> operator/(const NM_Scalar<T>& x, const NM_Scalar<T>& y) { 00120 return NM_Scalar<T>(x.getValue() / y.getValue(), 00121 x.getError() + y.getError() + 1.0); 00122 } 00123 00124 template <class T> 00125 inline std::ostream& operator<<(std::ostream& os, const NM_Scalar<T>& x) { 00126 return os << x.getValue() << '[' << x.getError() << ']'; 00127 } 00128 00129 template <class T> 00130 inline NM_Scalar<T> sqrt(const NM_Scalar<T>& x) { 00131 return NM_Scalar<T>(sqrt(x.getValue()), 00132 0.5 * x.getError() + 1.0); 00133 } 00134 00135 template <class T> 00136 inline NM_Scalar<T> acos(const NM_Scalar<T>& x) { 00137 return NM_Scalar<T>(acos(x.getValue()), x.getError() + 1.0); 00138 } 00139 00140 template <class T> 00141 inline NM_Scalar<T> cos(const NM_Scalar<T>& x) { 00142 return NM_Scalar<T>(cos(x.getValue()), x.getError() + 1.0); 00143 } 00144 00145 template <class T> 00146 inline NM_Scalar<T> sin(const NM_Scalar<T>& x) { 00147 return NM_Scalar<T>(sin(x.getValue()), x.getError() + 1.0); 00148 } 00149 00150 template <class T> 00151 inline NM_Scalar<T> fabs(const NM_Scalar<T>& x) { 00152 return NM_Scalar<T>(fabs(x.getValue()), x.getError()); 00153 } 00154 00155 template <class T> 00156 inline NM_Scalar<T> pow(const NM_Scalar<T>& x, const NM_Scalar<T>& y) { 00157 return NM_Scalar<T>(pow(x.getValue(), y.getValue()), 00158 fabs(y.getValue()) * x.getError() + 1.0); 00159 } 00160