Skip to content

Commit

Permalink
fix #311 betainc in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Nelson-numerical-software committed Jul 26, 2020
1 parent 34aaf11 commit c19c9bd
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 5 deletions.
Expand Up @@ -168,6 +168,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\cpp\betaincBuiltin.cpp" />
<ClCompile Include="..\cpp\gammaBuiltin.cpp" />
<ClCompile Include="..\cpp\Gateway.cpp" />
<ClCompile Include="dllMain.c" />
Expand Down Expand Up @@ -196,6 +197,7 @@
<Text Include="..\..\CMakeLists.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\betaincBuiltin.hpp" />
<ClInclude Include="..\include\gammaBuiltin.hpp" />
<ClInclude Include="..\include\nlsSpecial_functions_builtin_exports.h" />
</ItemGroup>
Expand Down
Expand Up @@ -24,6 +24,9 @@
<ClCompile Include="dllMain.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\cpp\betaincBuiltin.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\CMakeLists.txt" />
Expand All @@ -46,5 +49,8 @@
<ClInclude Include="..\include\gammaBuiltin.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\betaincBuiltin.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
4 changes: 4 additions & 0 deletions modules/special_functions/builtin/cpp/Gateway.cpp
Expand Up @@ -25,6 +25,7 @@
//=============================================================================
#include "NelsonGateway.hpp"
#include "gammaBuiltin.hpp"
#include "betaincBuiltin.hpp"
//=============================================================================
using namespace Nelson;
//=============================================================================
Expand All @@ -33,6 +34,9 @@ const std::wstring gatewayName = L"elementary_functions";
static const nlsGateway gateway[] = {
{ "gamma", (void*)Nelson::SpecialFunctionsGateway::gammaBuiltin, 1, 1,
CPP_BUILTIN_WITH_EVALUATOR },
{ "betainc", (void*)Nelson::SpecialFunctionsGateway::betaincBuiltin, 1, 3,
CPP_BUILTIN_WITH_EVALUATOR },

};
//=============================================================================
NLSGATEWAYFUNC(gateway)
Expand Down
57 changes: 57 additions & 0 deletions modules/special_functions/builtin/cpp/betaincBuiltin.cpp
@@ -0,0 +1,57 @@
//=============================================================================
// Copyright (c) 2016-present Allan CORNET (Nelson)
//=============================================================================
// This file is part of the Nelson.
//=============================================================================
// LICENCE_BLOCK_BEGIN
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// This program 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
// LICENCE_BLOCK_END
//=============================================================================
#include "betaincBuiltin.hpp"
#include "Error.hpp"
#include "BetaIncomplete.hpp"
#include "OverloadFunction.hpp"
#include "ClassName.hpp"
//=============================================================================
using namespace Nelson;
//=============================================================================
ArrayOfVector
Nelson::SpecialFunctionsGateway::betaincBuiltin(Evaluator* eval, int nLhs, const ArrayOfVector& argIn)
{
ArrayOfVector retval;
if (argIn.size() != 3) {
Error(ERROR_WRONG_NUMBERS_INPUT_ARGS);
}
if (nLhs > 1) {
Error(ERROR_WRONG_NUMBERS_OUTPUT_ARGS);
}
bool bSuccess = false;
if (eval->mustOverloadBasicTypes()) {
retval = OverloadFunction(eval, nLhs, argIn, "betainc", bSuccess);
}
if (!bSuccess) {
bool needToOverload = false;
retval.push_back(BetaIncomplete(argIn[0], argIn[1], argIn[2], needToOverload));
if (needToOverload) {
retval = OverloadFunction(eval, nLhs, argIn, "betainc");
}
}
return retval;
}
//=============================================================================
38 changes: 38 additions & 0 deletions modules/special_functions/builtin/include/betaincBuiltin.hpp
@@ -0,0 +1,38 @@
//=============================================================================
// Copyright (c) 2016-present Allan CORNET (Nelson)
//=============================================================================
// This file is part of the Nelson.
//=============================================================================
// LICENCE_BLOCK_BEGIN
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// This program 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
// LICENCE_BLOCK_END
//=============================================================================
#pragma once
//=============================================================================
#include "ArrayOf.hpp"
#include "Evaluator.hpp"
//=============================================================================
namespace Nelson {
namespace SpecialFunctionsGateway {
ArrayOfVector
betaincBuiltin(Evaluator* eval, int nLhs, const ArrayOfVector& argIn);
}
//=============================================================================
} // namespace Nelson
//=============================================================================
2 changes: 2 additions & 0 deletions modules/special_functions/src/c/nlsSpecial_functions.vcxproj
Expand Up @@ -168,10 +168,12 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\cpp\BetaIncomplete.cpp" />
<ClCompile Include="..\cpp\Gamma.cpp" />
<ClCompile Include="dllMain.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\BetaIncomplete.hpp" />
<ClInclude Include="..\include\Gamma.hpp" />
</ItemGroup>
<ItemGroup>
Expand Down
Expand Up @@ -21,11 +21,17 @@
<ClCompile Include="dllMain.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\cpp\BetaIncomplete.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\Gamma.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\BetaIncomplete.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\CMakeLists.txt" />
Expand Down
120 changes: 120 additions & 0 deletions modules/special_functions/src/cpp/BetaIncomplete.cpp
@@ -0,0 +1,120 @@
//=============================================================================
// Copyright (c) 2016-present Allan CORNET (Nelson)
//=============================================================================
// This file is part of the Nelson.
//=============================================================================
// LICENCE_BLOCK_BEGIN
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// This program 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
// LICENCE_BLOCK_END
//=============================================================================
#include <boost/math/special_functions/beta.hpp>
#include "nlsConfig.h"
#include "BetaIncomplete.hpp"
#include "Error.hpp"
//=============================================================================
namespace Nelson {
//=============================================================================
inline Dimensions
maxDimensions(Dimensions& a, Dimensions& b)
{
Dimensions ret;
for (unsigned int i = 0; i < std::min(a.getLength(), b.getLength()); i++) {
ret[i] = (a.getAt(i, false) > b.getAt(i, false)) ? a.getAt(i, false) : b.getAt(i, false);
}
return ret;
}
//=============================================================================
template <class T>
ArrayOf
BetaIncomplete(const Dimensions& retDims, Class destinationType, indexType maxLen,
const ArrayOf& X, const ArrayOf& Y,
const ArrayOf& Z)
{
T* result = (T*)ArrayOf::allocateArrayOf(
destinationType, retDims.getElementCount(), stringVector(), false);
ArrayOf res = ArrayOf(destinationType, retDims, result);
auto* ptrX = (T*)X.getDataPointer();
auto* ptrY = (T*)Y.getDataPointer();
auto* ptrZ = (T*)Z.getDataPointer();
bool fails = false;
#if defined(_NLS_WITH_OPENMP)
#pragma omp parallel for
#endif
for (ompIndexType i = 0; i < (ompIndexType)maxLen; ++i) {
T x = (X.isScalar()) ? ptrX[0] : ptrX[i];
T y = (Y.isScalar()) ? ptrY[0] : ptrY[i];
T z = (Z.isScalar()) ? ptrZ[0] : ptrZ[i];
try {
result[i] = boost::math::ibeta(y, z, x);
} catch (...) {
fails = true;
}
}
if (fails) {
Error(_("Error evaluating betainc."));
}
return res;
}
//=============================================================================
ArrayOf
BetaIncomplete(const ArrayOf& X, const ArrayOf& Y, const ArrayOf& Z, bool& needOverload)
{
ArrayOf res;
if (X.getDataClass() == NLS_DOUBLE || X.getDataClass() == NLS_SINGLE && !X.isSparse()) {
needOverload = false;
} else {
needOverload = true;
return res;
}
if (Y.getDataClass() == NLS_DOUBLE || Y.getDataClass() == NLS_SINGLE && !Y.isSparse()) {
needOverload = false;
} else {
needOverload = true;
return res;
}
if (Z.getDataClass() == NLS_DOUBLE || Z.getDataClass() == NLS_SINGLE && !Z.isSparse()) {
needOverload = false;
} else {
needOverload = true;
return res;
}
indexType maxLen = std::max(X.getLength(), std::max(Y.getLength(), Z.getLength()));
Dimensions retDims
= maxDimensions(X.getDimensions(), maxDimensions(Y.getDimensions(), Z.getDimensions()));
if (!(X.isScalar()) && !retDims.equals(X.getDimensions())) {
Error(_("Wrong size of the first argument."));
}
if (!(Y.isScalar()) && !retDims.equals(Y.getDimensions())) {
Error(_("Wrong size of the second argument."));
}
if (!(Z.isScalar()) && !retDims.equals(Z.getDimensions())) {
Error(_("Wrong size of the third argument."));
}
if (X.getDataClass() == NLS_DOUBLE) {
res = BetaIncomplete<double>(retDims, NLS_DOUBLE, maxLen, X, Y, Z);
} else if (X.getDataClass() == NLS_SINGLE) {
res = BetaIncomplete<single>(retDims, NLS_SINGLE, maxLen, X, Y, Z);
} else {
needOverload = true;
}
return res;
}
//=============================================================================
} // namespace Nelson
//=============================================================================
35 changes: 35 additions & 0 deletions modules/special_functions/src/include/BetaIncomplete.hpp
@@ -0,0 +1,35 @@
//=============================================================================
// Copyright (c) 2016-present Allan CORNET (Nelson)
//=============================================================================
// This file is part of the Nelson.
//=============================================================================
// LICENCE_BLOCK_BEGIN
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// This program 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
// LICENCE_BLOCK_END
//=============================================================================
#pragma once
//=============================================================================
#include "ArrayOf.hpp"
#include "nlsSpecial_functions_exports.h"
//=============================================================================
namespace Nelson {
NLSSPECIAL_FUNCTIONS_IMPEXP ArrayOf
BetaIncomplete(const ArrayOf& X, const ArrayOf& Y, const ArrayOf& Z, bool& needOverload);
}
//=============================================================================
11 changes: 7 additions & 4 deletions modules/types/src/cpp/Dimensions.cpp
Expand Up @@ -93,7 +93,8 @@ Dimensions::getMax()
return maxL;
}
//=============================================================================
indexType& Dimensions::operator[](indexType i)
indexType&
Dimensions::operator[](indexType i)
{
if (i >= maxDims) {
Error(_("Too many dimensions! Current limit is") + " " + std::to_string(Nelson::maxDims)
Expand All @@ -110,14 +111,16 @@ indexType& Dimensions::operator[](indexType i)
}
//=============================================================================
indexType
Dimensions::getAt(indexType i)
Dimensions::getAt(indexType i, bool checkLength)
{
if (i >= maxDims) {
Error(_("Too many dimensions! Current limit is") + " " + std::to_string(Nelson::maxDims)
+ ".");
}
if (i >= length) {
Error(_("Invalid dimension position."));
if (checkLength) {
if (i >= length) {
Error(_("Invalid dimension position."));
}
}
return data[i];
}
Expand Down
2 changes: 1 addition & 1 deletion modules/types/src/include/Dimensions.hpp
Expand Up @@ -114,7 +114,7 @@ class NLSTYPES_IMPEXP Dimensions
* Throws an exception if the argument is bigger tha maxIndex or length.
*/
indexType
getAt(indexType i);
getAt(indexType i, bool checkLength = true);
/**
* Get the number of currently allocated dimensions.
*/
Expand Down

0 comments on commit c19c9bd

Please sign in to comment.