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