ExtMath.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/calculator/ExtMath.cpp#2 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2004-2009 SQLstream, Inc.
00006 // Copyright (C) 2009-2009 LucidEra, Inc.
00007 //
00008 // This program is free software; you can redistribute it and/or modify it
00009 // under the terms of the GNU General Public License as published by the Free
00010 // Software Foundation; either version 2 of the License, or (at your option)
00011 // any later version approved by The Eigenbase Project.
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 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 
00024 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/calculator/ExtMath.h"
00026 #include "fennel/calculator/ExtendedInstructionTable.h"
00027 #include "fennel/tuple/StandardTypeDescriptor.h"
00028 #include <cstdlib>   // for std::abs()
00029 #include <math.h>
00030 
00031 FENNEL_BEGIN_NAMESPACE
00032 
00033 
00034 void
00035 mathLn(
00036     RegisterRef<double>* result,
00037     RegisterRef<double>* x)
00038 {
00039     assert(StandardTypeDescriptor::isApprox(x->type()));
00040 
00041     if (x->isNull()) {
00042         result->toNull();
00043     } else if (x->value() <= 0.0) {
00044         result->toNull();
00045         // SQL99 Part 2 Section 22.1 22-023 "invalid parameter value"
00046         throw "22023";
00047     } else {
00048         result->value(log(x->value())); //using the c math library log
00049     }
00050 }
00051 
00052 void
00053 mathLn(
00054     RegisterRef<double>* result,
00055     RegisterRef<long long>* x)
00056 {
00057     assert(StandardTypeDescriptor::isExact(x->type()));
00058 
00059     if (x->isNull()) {
00060         result->toNull();
00061     } else if (x->value() <= 0) {
00062         result->toNull();
00063         // SQL99 Part 2 Section 22.1 22-023 "invalid parameter value"
00064         throw "22023";
00065     } else {
00066         result->value(log(double(x->value()))); //using the c math library log
00067     }
00068 }
00069 
00070 void
00071 mathLog10(
00072     RegisterRef<double>* result,
00073     RegisterRef<double>* x)
00074 {
00075     assert(StandardTypeDescriptor::isApprox(x->type()));
00076 
00077     if (x->isNull()) {
00078         result->toNull();
00079     } else if (x->value() <= 0.0) {
00080         result->toNull();
00081         // SQL99 Part 2 Section 22.1 22-023 "invalid parameter value"
00082         throw "22023";
00083     } else {
00084         result->value(log10(x->value()));
00085     }
00086 }
00087 
00088 void
00089 mathLog10(
00090     RegisterRef<double>* result,
00091     RegisterRef<long long>* x)
00092 {
00093     assert(StandardTypeDescriptor::isExact(x->type()));
00094 
00095     if (x->isNull()) {
00096         result->toNull();
00097     } else if (x->value() <= 0) {
00098         result->toNull();
00099         // SQL99 Part 2 Section 22.1 22-023 "invalid parameter value"
00100         throw "22023";
00101     } else {
00102         result->value(log10(double(x->value())));
00103     }
00104 }
00105 
00106 void
00107 mathAbs(
00108     RegisterRef<double>* result,
00109     RegisterRef<double>* x)
00110 {
00111     assert(StandardTypeDescriptor::isApprox(x->type()));
00112 
00113     if (x->isNull()) {
00114         result->toNull();
00115     } else {
00116         result->value(fabs(x->value()));
00117     }
00118 }
00119 
00120 void
00121 mathAbs(
00122     RegisterRef<long long>* result,
00123     RegisterRef<long long>* x)
00124 {
00125     assert(x->type() == STANDARD_TYPE_INT_64);
00126 
00127     if (x->isNull()) {
00128         result->toNull();
00129     } else {
00130         // Due to various include problems with gcc, it's easy to get
00131         // abs doubly defined. Just arbitrarily using std::abs to
00132         // avoid problems with gcc3.x built-ins.
00133         result->value(std::abs(x->value()));
00134     }
00135 }
00136 
00137 void
00138 mathPow(
00139     RegisterRef<double>* result,
00140     RegisterRef<double>* x,
00141     RegisterRef<double>* y)
00142 {
00143     assert(StandardTypeDescriptor::isApprox(x->type()));
00144     assert(StandardTypeDescriptor::isApprox(y->type()));
00145 
00146     if (x->isNull() || y->isNull()) {
00147         result->toNull();
00148     } else {
00149         double r = pow(x->value(), y->value());
00150         if ((x->value() == 0.0 && y->value() < 0.0) ||
00151             (x->value() <  0.0 && isnan(r)))
00152         {
00153             // we should get here when x^y have
00154             // x=0 AND y < 0 OR
00155             // x<0 AND y is an non integer.
00156             // If this is the case then the result is NaN
00157 
00158             result->toNull();
00159             // SQL99 Part 2 Section 22.1 22-023 "invalid parameter value"
00160             throw "22023";
00161 
00162         } else {
00163             result->value(r);
00164         }
00165     }
00166 }
00167 
00168 void
00169 ExtMathRegister(ExtendedInstructionTable* eit)
00170 {
00171     assert(eit != NULL);
00172 
00173     vector<StandardTypeDescriptorOrdinal> params_2D;
00174     params_2D.push_back(STANDARD_TYPE_DOUBLE);
00175     params_2D.push_back(STANDARD_TYPE_DOUBLE);
00176 
00177     vector<StandardTypeDescriptorOrdinal> params_DI;
00178     params_DI.push_back(STANDARD_TYPE_DOUBLE);
00179     params_DI.push_back(STANDARD_TYPE_INT_64);
00180 
00181     vector<StandardTypeDescriptorOrdinal> params_DII;
00182     params_DII.push_back(STANDARD_TYPE_DOUBLE);
00183     params_DII.push_back(STANDARD_TYPE_INT_64);
00184     params_DII.push_back(STANDARD_TYPE_INT_64);
00185 
00186     vector<StandardTypeDescriptorOrdinal> params_DID;
00187     params_DID.push_back(STANDARD_TYPE_DOUBLE);
00188     params_DID.push_back(STANDARD_TYPE_INT_64);
00189     params_DID.push_back(STANDARD_TYPE_DOUBLE);
00190 
00191     vector<StandardTypeDescriptorOrdinal> params_DDI;
00192     params_DDI.push_back(STANDARD_TYPE_DOUBLE);
00193     params_DDI.push_back(STANDARD_TYPE_DOUBLE);
00194     params_DDI.push_back(STANDARD_TYPE_INT_64);
00195 
00196 
00197     vector<StandardTypeDescriptorOrdinal> params_3D(params_2D);
00198     params_3D.push_back(STANDARD_TYPE_DOUBLE);
00199 
00200     vector<StandardTypeDescriptorOrdinal> params_2I;
00201     params_2I.push_back(STANDARD_TYPE_INT_64);
00202     params_2I.push_back(STANDARD_TYPE_INT_64);
00203 
00204     vector<StandardTypeDescriptorOrdinal> params_3I(params_2I);
00205     params_3I.push_back(STANDARD_TYPE_INT_64);
00206 
00207     eit->add(
00208         "LN", params_2D,
00209         (ExtendedInstruction2<double, double>*) NULL,
00210         &mathLn);
00211 
00212     eit->add(
00213         "LN", params_DI,
00214         (ExtendedInstruction2<double, long long>*) NULL,
00215         &mathLn);
00216 
00217     eit->add(
00218         "LOG10", params_2D,
00219         (ExtendedInstruction2<double, double>*) NULL,
00220         &mathLog10);
00221 
00222     eit->add(
00223         "LOG10", params_DI,
00224         (ExtendedInstruction2<double, long long>*) NULL,
00225         &mathLog10);
00226 
00227     eit->add(
00228         "ABS", params_2D,
00229         (ExtendedInstruction2<double, double>*) NULL,
00230         &mathAbs);
00231 
00232     eit->add(
00233         "ABS", params_2I,
00234         (ExtendedInstruction2<long long, long long>*) NULL,
00235         &mathAbs);
00236 
00237     eit->add(
00238         "POW", params_3D,
00239         (ExtendedInstruction3<double, double, double>*) NULL,
00240         &mathPow);
00241 
00242 }
00243 
00244 
00245 FENNEL_END_NAMESPACE
00246 
00247 // End ExtMath.cpp

Generated on Mon Jun 22 04:00:17 2009 for Fennel by  doxygen 1.5.1