diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c8b28557..f1b5e5d9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -260,7 +260,7 @@ To add a new kernel, you need to follow these steps. 1. Place your kernel header file in the inst/include/kernels/concrete directory. The file name should match the kernel's name. For instance, if your header file is named UnivariateMaternStationary.hpp, it can be invoked using either univariate_matern_stationary or UnivariateMaternStationary. The naming linkage is handled automatically, so there's no additional setup required on your part. -2. Derive from the base class located in kernel.hpp and implement the necessary functions. +2. Derive from the base class located in Kernel.hpp and implement the necessary functions. 3. Ensure your kernel includes all the requisite functions that adhere to the established naming conventions found in other kernels. This will allow for proper support and integration of your new kernel. diff --git a/inst/include/kernels/concrete/UnivariatePowExpStationary.hpp b/inst/include/kernels/concrete/UnivariatePowExpStationary.hpp new file mode 100644 index 00000000..111e51ca --- /dev/null +++ b/inst/include/kernels/concrete/UnivariatePowExpStationary.hpp @@ -0,0 +1,85 @@ + +// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file UnivariatePowExpStationary.hpp + * @brief Defines the UnivariatePowExpStationary class, a univariate stationary PowExp kernel. + * @version 1.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @author Suhas Shankar + * @author Mary Lai Salvana + * @date 2024-11-22 + * + * This file provides the declaration of the UnivariatePowExpStationary class, which is a subclass of the Kernel class + * and represents a univariate stationary PowExp kernel. It provides a method for generating a covariance matrix + * using a set of input locations and kernel parameters. + * +**/ + +#ifndef EXAGEOSTATCPP_UNIVARIATEMATERNSTATIONARY_HPP +#define EXAGEOSTATCPP_UNIVARIATEMATERNSTATIONARY_HPP + +#include + +namespace exageostat::kernels { + + /** + * @class UnivariatePowExpStationary + * @brief A class representing a Univariate PowExp Stationary kernel. + * @details This class represents a Univariate PowExp Stationary, which is a subclass of the Kernel class. + * It provides a method for generating a covariance matrix using a set of input locations and kernel parameters. + * + */ + template + class UnivariatePowExpStationary : public Kernel { + + public: + + /** + * @brief Constructs a new UnivariatePowExpStationary object. + * @details Initializes a new UnivariatePowExpStationary object with default values. + */ + UnivariatePowExpStationary(); + + /** + * @brief Virtual destructor to allow calls to the correct concrete destructor. + * + */ + ~UnivariatePowExpStationary() override = default; + + /** + * @brief Generates a covariance matrix using a set of locations and kernel parameters. + * @copydoc Kernel::GenerateCovarianceMatrix() + */ + void + GenerateCovarianceMatrix(T *apMatrixA, const int &aRowsNumber, const int &aColumnsNumber, const int &aRowOffset, + const int &aColumnOffset, dataunits::Locations &aLocation1, + dataunits::Locations &aLocation2, dataunits::Locations &aLocation3, + T *apLocalTheta, const int &aDistanceMetric) override; + + /** + * @brief Creates a new UnivariatePowExpStationary object. + * @details This method creates a new UnivariatePowExpStationary object and returns a pointer to it. + * @return A pointer to the new UnivariatePowExpStationary object. + * + */ + static Kernel *Create(); + + private: + //// Used plugin name for static registration + static bool plugin_name; + }; + + /** + * @brief Instantiates the Data Generator class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(UnivariatePowExpStationary) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_UNIVARIATEMATERNSTATIONARY_HPP diff --git a/src/kernels/CMakeLists.txt b/src/kernels/CMakeLists.txt index 7a8a55da..290444d1 100644 --- a/src/kernels/CMakeLists.txt +++ b/src/kernels/CMakeLists.txt @@ -13,7 +13,7 @@ # Automatically add all kernels in the concrete directory. file(GLOB ALL_KERNELS ${CMAKE_CURRENT_SOURCE_DIR}/concrete/*.cpp) -# Add the Configurations.cpp file to the list of source files. +# Add the kernel.cpp file to the list with other kernels. set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Kernel.cpp ${ALL_KERNELS} diff --git a/src/kernels/concrete/UnivariatePowExpStationary.cpp b/src/kernels/concrete/UnivariatePowExpStationary.cpp new file mode 100644 index 00000000..da225320 --- /dev/null +++ b/src/kernels/concrete/UnivariatePowExpStationary.cpp @@ -0,0 +1,66 @@ + +// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file UnivariatePowExpStationary.cpp + * @brief Implementation of the UnivariatePowExpStationary kernel. + * @version 1.0.1 + * @author Sameh Abdulah + * @author Mahmoud ElKarargy + * @date 2023-04-14 +**/ + +#include +#include + +using namespace exageostat::kernels; +using namespace exageostat::dataunits; +using namespace exageostat::helpers; + +template +UnivariatePowExpStationary::UnivariatePowExpStationary() { + this->mP = 1; + this->mParametersNumber = 3; +} + +template +Kernel *UnivariatePowExpStationary::Create() { + KernelsConfigurations::GetParametersNumberKernelMap()["UnivariatePowExpStationary"] = 3; + return new UnivariatePowExpStationary(); +} + +namespace exageostat::kernels { + template bool UnivariatePowExpStationary::plugin_name = plugins::PluginRegistry>::Add( + "UnivariatePowExpStationary", UnivariatePowExpStationary::Create); +} + +template +void +UnivariatePowExpStationary::GenerateCovarianceMatrix(T *apMatrixA, const int &aRowsNumber, const int &aColumnsNumber, + const int &aRowOffset, const int &aColumnOffset, + Locations &aLocation1, Locations &aLocation2, + Locations &aLocation3, T *aLocalTheta, + const int &aDistanceMetric) { + + const T sigma_square = aLocalTheta[0]; + const T nu = aLocalTheta[2]; + int i0 = aRowOffset; + int flag = 0; + int j0; + int i, j; + T dist; + + for (i = 0; i < aRowsNumber; i++) { + j0 = aColumnOffset; + for (j = 0; j < aColumnsNumber; j++) { + dist = DistanceCalculationHelpers::CalculateDistance(aLocation1, aLocation2, i0, j0, aDistanceMetric, + flag); + dist = pow(dist, nu); + *(apMatrixA + i + j * aRowsNumber) = (dist == 0.0) ? sigma_square : sigma_square * exp(-(dist / aLocalTheta[1])); + j0++; + } + i0++; + } +} diff --git a/tests/cpp-tests/kernels/CMakeLists.txt b/tests/cpp-tests/kernels/CMakeLists.txt index 01d039c3..c6b2813b 100644 --- a/tests/cpp-tests/kernels/CMakeLists.txt +++ b/tests/cpp-tests/kernels/CMakeLists.txt @@ -8,26 +8,11 @@ # @author Mahmoud ElKarargy # @date 2023-04-29 -set(EXAGEOSTAT_TESTFILES +# Automatically add all kernels tests in the concrete directory. +file(GLOB ALL_KERNELS ${CMAKE_CURRENT_SOURCE_DIR}/concrete/*.cpp) - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestBivariateMaternFlexible.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDsigmaSquare.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestBivariateMaternParsimonious.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternNuggetsStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateSpacetimeMaternStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDnu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDbeta.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdsigmaSquare.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdsigmaSquareBeta.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdsigmaSquareNu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdbetaBeta.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdbetaNu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdnuNu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestBivariateSpacetimeMaternStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternNonGaussian.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateExpNonGaussian.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestTrivariateMaternParsimonious.cpp +set(SOURCES + ${ALL_KERNELS} ${EXAGEOSTAT_TESTFILES} PARENT_SCOPE - ) + ) \ No newline at end of file diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariatePowExpStationary.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariatePowExpStationary.cpp new file mode 100644 index 00000000..2942d703 --- /dev/null +++ b/tests/cpp-tests/kernels/concrete/TestUnivariatePowExpStationary.cpp @@ -0,0 +1,73 @@ + +// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file TestUnivariatePowExpStationary.cpp + * @brief Unit tests for the TestUnivariatePowExpStationary kernel in the ExaGeoStat software package. + * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariatePowExpStationary kernel + * in the ExaGeoStat software package. The tests cover the generation of data using this kernel with various configurations. + * @version 1.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-01-16 +**/ + +#include +#include +#include + +using namespace std; + +using namespace exageostat::configurations; +using namespace exageostat::api; +using namespace exageostat::common; +using namespace exageostat::hardware; + +void TEST_KERNEL_GENERATION_UnivariatePowExpStationary() { + + SECTION("UnivariatePowExpStationary") + { + + // Create a new synthetic_data_configurations object with the provided command line arguments + Configurations synthetic_data_configurations; + + int N = 9; + synthetic_data_configurations.SetProblemSize(N); + synthetic_data_configurations.SetKernelName("UnivariatePowExpStationary"); + synthetic_data_configurations.SetDimension(Dimension2D); + + vector initial_theta{1, 0.1, 0.5}; + synthetic_data_configurations.SetInitialTheta(initial_theta); + + int dts = 5; + synthetic_data_configurations.SetDenseTileSize(dts); + synthetic_data_configurations.SetComputation(EXACT_DENSE); + // initialize ExaGeoStat Hardware. + auto hardware = ExaGeoStatHardware(EXACT_DENSE, 3, 0); + + int seed = 0; + srand(seed); + exageostat::dataunits::ExaGeoStatData data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, + data); + + auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, + exageostat::common::DESCRIPTOR_Z).chameleon_desc; + auto *A = (double *) CHAM_descriptorZ->mat; + // Define the expected output + double expected_output_data[] = { -1.272336, -2.362813, 0.616384, -0.072468, 0.401498, -1.559690, 0.211848, + 0.776627, -1.524810}; + + for (size_t i = 0; i < N; i++) { + double diff = A[i] - expected_output_data[i]; + REQUIRE(diff == Catch::Approx(0.0).margin(1e-6)); + } + } +} + +TEST_CASE("Univariate Pow-Exp Stationary kernel test") { + TEST_KERNEL_GENERATION_UnivariatePowExpStationary(); + +}