//# QMath.cc: class to manipulate physical, dimensioned quantities //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2003 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# $Id$ #ifndef CASA_QMATH_TCC #define CASA_QMATH_TCC //# Includes #include #include #include #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN template Quantum operator+(const Quantum &left, const Qtype &other) { Quantum loc; loc = left; loc += other; return loc; } template Quantum operator+(const Qtype &left, const Quantum &other) { Quantum loc; loc = other; loc += left; return loc; } template Quantum operator-(const Quantum &left, const Qtype &other) { Quantum loc; loc = left; loc -= other; return loc; } template Quantum operator-(const Qtype &left, const Quantum &other) { Quantum loc; loc = other; loc -= left; return loc; } template Quantum operator*(const Quantum &left, const Qtype &other) { Quantum loc = left; loc *= other; return loc; } template Quantum operator*(const Qtype &left, const Quantum &other) { Quantum loc; loc = other; loc *= left; return loc; } template Quantum operator/(const Quantum &left, const Qtype &other) { Quantum loc = left; loc /= other; return loc; } template Quantum operator/(const Qtype &left, const Quantum &other) { Quantum loc; loc = other; loc /= left; return loc; } // pow. Implemented as a repeated multiplication/division: // - to cater for all data types // - only Int powers allowed // - limited values of exponentials foreseen template Quantum pow(const Quantum &left, Int p) { if (::abs(p) >= 100) throw (AipsError("Quantum::pow exponent too large")); // Make sure 1 in current data type available Quantum res; Qtype tmp; tmp = left.getValue() * 0. + 1.; Int i; if (p>=0) { for (i=0; ip; i--) tmp /= left.getValue(); } res.setValue(tmp); if (p == 0 || left.getUnit().empty()) res.setUnit(""); else { String sloc = "(" + left.getUnit() + ")"; if (p < 0) { sloc += "-"; p = -p; } if (p/10 != 0) sloc += Char(Int(p)/10 + '0'); sloc += Char(Int(p)%10 + '0'); res.setUnit(sloc); } return res; } template Quantum root(const Quantum &left, Int p) { if (p == 0) throw (AipsError("Quantum::root exponent zero")); Quantum res; res.setValue(casacore::pow(left.getValue(), 1.0/Double(p))); UnitVal vres(left.getFullUnit().getValue().root(p)); ostringstream oss; oss << vres.getDim(); res.setUnit(String(oss)); res.setValue(res.getValue() * vres.getFac()); return res; } template Quantum sqrt(const Quantum &left) { return root(left, 2); } template Quantum abs(const Quantum &left) { Qtype tmp = left.getValue(); Qtype ret; ret = abs((tmp)); return (Quantum(ret,left)); } template Quantum ceil(const Quantum &left) { Qtype tmp = left.getValue(); Qtype ret; ret = ceil((tmp)); return (Quantum(ret,left)); } template Quantum floor(const Quantum &left) { Qtype tmp = left.getValue(); Qtype ret; ret = floor((tmp)); return (Quantum(ret,left)); } template Quantum sin(const Quantum &left) { if (left.getFullUnit().getValue() != UnitVal::ANGLE) { throw (AipsError("Quantum::sin illegal unit type '" + left.getUnit() + "'")); } Quantum res; res.setValue(left.getBaseValue()); res.setValue(sin((res.getValue()))); res.setUnit(""); return (res); } template Quantum cos(const Quantum &left) { if (left.getFullUnit().getValue() != UnitVal::ANGLE) { throw (AipsError("Quantum::cos illegal unit type '" + left.getUnit() + "'")); } Quantum res; res.setValue(left.getBaseValue()); res.setValue(cos((res.getValue()))); res.setUnit(""); return (res); } template Quantum tan(const Quantum &left) { if (left.getFullUnit().getValue() != UnitVal::ANGLE) { throw (AipsError("Quantum::tan illegal unit type '" + left.getUnit() + "'")); } Quantum res; res.setValue(left.getBaseValue()); res.setValue(tan((res.getValue()))); res.setUnit(""); return (res); } template Quantum asin(const Quantum &left) { if (left.getFullUnit().getValue() != UnitVal::NODIM) { throw (AipsError("Quantum::asin illegal unit type '" + left.getUnit() + "'")); } Quantum res; res.setValue(left.getBaseValue()); res.setValue(asin((res.getValue()))); res.setUnit("rad"); return (res); } template Quantum acos(const Quantum &left) { if (left.getFullUnit().getValue() != UnitVal::NODIM) { throw (AipsError("Quantum::acos illegal unit type '" + left.getUnit() + "'")); } Quantum res; res.setValue(left.getBaseValue()); res.setValue(acos((res.getValue()))); res.setUnit("rad"); return (res); } template Quantum atan(const Quantum &left) { if (left.getFullUnit().getValue() != UnitVal::NODIM) { throw (AipsError("Quantum::atan illegal unit type '" + left.getUnit() + "'")); } Quantum res; res.setValue(left.getBaseValue()); res.setValue(atan((res.getValue()))); res.setUnit("rad"); return (res); } template Quantum atan2(const Quantum &left, const Quantum &other) { if ((left.getFullUnit().getValue() != UnitVal::NODIM) || (other.getFullUnit().getValue() != UnitVal::NODIM)) { throw (AipsError("Quantum::atan2 illegal unit type '" + left.getUnit() + "'")); } Quantum res; Qtype tmp; tmp = other.getBaseValue(); res.setValue(left.getBaseValue()); res.setValue(atan2((res.getValue()),(tmp))); res.setUnit("rad"); return (res); } template Quantum atan2(const Quantum &left, const Qtype &other) { Quantum res; res = other; return (atan2(left,res)); } template Quantum atan2(const Qtype &left, const Quantum &other) { Quantum res; res = left; return (atan2(res,other)); } template Quantum log(const Quantum &left) { if (left.getFullUnit().getValue() != UnitVal::NODIM) { throw (AipsError("Quantum::log illegal unit type '" + left.getUnit() + "'")); } Quantum res; res.setValue(left.getBaseValue()); res.setValue(log((res.getValue()))); res.setUnit(""); return (res); } template Quantum log10(const Quantum &left) { if (left.getFullUnit().getValue() != UnitVal::NODIM) { throw (AipsError("Quantum::log10 illegal unit type '" + left.getUnit() + "'")); } Quantum res; res.setValue(left.getBaseValue()); res.setValue(log10((res.getValue()))); res.setUnit(""); return (res); } template Quantum exp(const Quantum &left) { if (left.getFullUnit().getValue() != UnitVal::NODIM) { throw (AipsError("Quantum::exp illegal unit type '" + left.getUnit() + "'")); } Quantum res; res.setValue(left.getBaseValue()); res.setValue(exp((res.getValue()))); res.setUnit(""); return (res); } template Quantum min(const Quantum &left, const Quantum &other) { return left < other ? left : other; } template Quantum max(const Quantum &left, const Quantum &other) { return left > other ? left : other; } } //# NAMESPACE CASACORE - END #endif