diff --git a/benchmarks/cpp/benchmark.cpp b/benchmarks/cpp/benchmark.cpp index 125912b00..cb7c51684 100644 --- a/benchmarks/cpp/benchmark.cpp +++ b/benchmarks/cpp/benchmark.cpp @@ -111,7 +111,7 @@ template void run_timings(int l_max, int n_tries, int n_samples auto ddsph1 = std::vector(n_samples * 9 * (l_max + 1) * (l_max + 1), 0.0); { - SphericalHarmonics calculator(l_max, false); + SolidHarmonics calculator(l_max); sxyz[0] = xyz[0]; sxyz[1] = xyz[1]; sxyz[2] = xyz[2]; @@ -143,7 +143,7 @@ template void run_timings(int l_max, int n_tries, int n_samples } { - SphericalHarmonics calculator(l_max, true); + SphericalHarmonics calculator(l_max); benchmark("Call without derivatives (normalized)", n_samples, n_tries, [&]() { calculator.compute(xyz, sph1); }); diff --git a/examples/c/example.c b/examples/c/example.c index af235208c..34fee88f7 100644 --- a/examples/c/example.c +++ b/examples/c/example.c @@ -42,32 +42,36 @@ int main(int argc, char* argv[]) { /* ===== API calls ===== */ // opaque pointer declaration: initializes buffers and numerical factors - sphericart_calculator_t* calculator = sphericart_new(l_max, 0); + sphericart_spherical_harmonics_calculator_t* calculator = + sphericart_spherical_harmonics_new(l_max); // function calls // without derivatives - sphericart_compute_array(calculator, xyz, 3 * n_samples, sph, sph_size); + sphericart_spherical_harmonics_compute_array(calculator, xyz, 3 * n_samples, sph, sph_size); // with derivatives - sphericart_compute_array_with_gradients( + sphericart_spherical_harmonics_compute_array_with_gradients( calculator, xyz, 3 * n_samples, sph, sph_size, dsph, dsph_size ); // with second derivatives - sphericart_compute_array_with_hessians( + sphericart_spherical_harmonics_compute_array_with_hessians( calculator, xyz, 3 * n_samples, sph, sph_size, dsph, dsph_size, ddsph, ddsph_size ); // per-sample calculation - we reuse the same arrays for simplicity, but // only the first item is computed - sphericart_compute_sample(calculator, xyz, 3, sph, sph_size); - sphericart_compute_sample_with_gradients(calculator, xyz, 3, sph, sph_size, dsph, dsph_size); - sphericart_compute_sample_with_hessians( + sphericart_spherical_harmonics_compute_sample(calculator, xyz, 3, sph, sph_size); + sphericart_spherical_harmonics_compute_sample_with_gradients( + calculator, xyz, 3, sph, sph_size, dsph, dsph_size + ); + sphericart_spherical_harmonics_compute_sample_with_hessians( calculator, xyz, 3, sph, sph_size, dsph, dsph_size, ddsph, ddsph_size ); // float version - sphericart_calculator_f_t* calculator_f = sphericart_new_f(l_max, 0); + sphericart_spherical_harmonics_calculator_f_t* calculator_f = + sphericart_spherical_harmonics_new_f(l_max); - sphericart_compute_array_with_gradients_f( + sphericart_spherical_harmonics_compute_array_with_gradients_f( calculator_f, xyz_f, 3 * n_samples, sph_f, sph_size, dsph_f, dsph_size ); @@ -83,12 +87,12 @@ int main(int argc, char* argv[]) { /* ===== clean up ===== */ // frees up data arrays and sph object pointers - sphericart_delete(calculator); + sphericart_spherical_harmonics_delete(calculator); free(xyz); free(sph); free(dsph); - sphericart_delete_f(calculator_f); + sphericart_spherical_harmonics_delete_f(calculator_f); free(xyz_f); free(sph_f); free(dsph_f); diff --git a/sphericart/include/sphericart.h b/sphericart/include/sphericart.h index b7a45c304..f7c4c257e 100644 --- a/sphericart/include/sphericart.h +++ b/sphericart/include/sphericart.h @@ -13,8 +13,10 @@ #include "sphericart.hpp" -using sphericart_calculator_t = sphericart::SphericalHarmonics; -using sphericart_calculator_f_t = sphericart::SphericalHarmonics; +using sphericart_spherical_harmonics_calculator_t = sphericart::SphericalHarmonics; +using sphericart_spherical_harmonics_calculator_f_t = sphericart::SphericalHarmonics; +using sphericart_solid_harmonics_calculator_t = sphericart::SolidHarmonics; +using sphericart_solid_harmonics_calculator_f_t = sphericart::SolidHarmonics; extern "C" { @@ -23,25 +25,50 @@ extern "C" { * Opaque type to hold a spherical harmonics calculator object, that contains * pre-computed factors and allocated buffer space for calculations. * - * The `sphericart_calculator_t` performs calculations with `double` data type. + * The `sphericart_spherical_harmonics_calculator_t` performs calculations with `double` data type. */ -struct sphericart_calculator_t; +struct sphericart_spherical_harmonics_calculator_t; /** - * A type referring to the `sphericart_calculator_t` struct. + * A type referring to the `sphericart_spherical_harmonics_calculator_t` struct. */ -typedef struct sphericart_calculator_t sphericart_calculator_t; +typedef struct sphericart_spherical_harmonics_calculator_t sphericart_spherical_harmonics_calculator_t; /** - * Similar to `sphericart_calculator_t`, but operating on the `float` data + * Similar to `sphericart_spherical_harmonics_calculator_t`, but operating on the `float` data * type. */ -struct sphericart_calculator_f_t; +struct sphericart_spherical_harmonics_calculator_f_t; /** - * A type referring to the `sphericart_calculator_f_t` struct. + * A type referring to the `sphericart_spherical_harmonics_calculator_f_t` struct. */ -typedef struct sphericart_calculator_f_t sphericart_calculator_f_t; +typedef struct sphericart_spherical_harmonics_calculator_f_t + sphericart_spherical_harmonics_calculator_f_t; + +/** + * Opaque type to hold a solid harmonics calculator object, that contains + * pre-computed factors and allocated buffer space for calculations. + * + * The `sphericart_solid_harmonics_calculator_t` performs calculations with `double` data type. + */ +struct sphericart_solid_harmonics_calculator_t; + +/** + * A type referring to the `sphericart_solid_harmonics_calculator_t` struct. + */ +typedef struct sphericart_solid_harmonics_calculator_t sphericart_solid_harmonics_calculator_t; + +/** + * Similar to `sphericart_solid_harmonics_calculator_t`, but operating on the `float` data + * type. + */ +struct sphericart_solid_harmonics_calculator_f_t; + +/** + * A type referring to the `sphericart_solid_harmonics_calculator_f_t` struct. + */ +typedef struct sphericart_solid_harmonics_calculator_f_t sphericart_solid_harmonics_calculator_f_t; #endif /** @@ -51,39 +78,41 @@ typedef struct sphericart_calculator_f_t sphericart_calculator_f_t; * * @param l_max The maximum degree of the spherical harmonics to be * calculated. - * @param normalized If `false`, computes the scaled spherical harmonics, - * which are polynomials in the Cartesian coordinates of the input points. If - * `true`, computes the normalized spherical harmonics that are - * evaluated on the unit sphere. In practice, this simply computes the - * scaled harmonics at the normalized coordinates \f$(x/r, y/r, z/r)\f$, - * and adapts the derivatives accordingly. * - * @return A pointer to a `sphericart_calculator_t` object + * @return A pointer to a `sphericart_spherical_harmonics_calculator_t` object * */ -SPHERICART_EXPORT sphericart_calculator_t* sphericart_new(size_t l_max, bool normalized); +SPHERICART_EXPORT sphericart_spherical_harmonics_calculator_t* sphericart_spherical_harmonics_new( + size_t l_max +); /** - * Similar to `sphericart_new`, but it returns a `sphericart_calculator_f_t`, - * which performs calculations on the `float` type. + * Similar to `sphericart_spherical_harmonics_new`, but it returns a + * `sphericart_spherical_harmonics_calculator_f_t`, which performs calculations on the `float` type. */ -SPHERICART_EXPORT sphericart_calculator_f_t* sphericart_new_f(size_t l_max, bool normalized); +SPHERICART_EXPORT sphericart_spherical_harmonics_calculator_f_t* sphericart_spherical_harmonics_new_f( + size_t l_max +); /** - * Deletes a previously allocated `sphericart_calculator_t` calculator. + * Deletes a previously allocated `sphericart_spherical_harmonics_calculator_t` calculator. */ -SPHERICART_EXPORT void sphericart_delete(sphericart_calculator_t* calculator); +SPHERICART_EXPORT void sphericart_spherical_harmonics_delete( + sphericart_spherical_harmonics_calculator_t* calculator +); /** - * Deletes a previously allocated `sphericart_calculator_f_t` calculator. + * Deletes a previously allocated `sphericart_spherical_harmonics_calculator_f_t` calculator. */ -SPHERICART_EXPORT void sphericart_delete_f(sphericart_calculator_f_t* calculator); +SPHERICART_EXPORT void sphericart_spherical_harmonics_delete_f( + sphericart_spherical_harmonics_calculator_f_t* calculator +); /** * This function calculates the spherical harmonics and, optionally, their * derivatives for an array of 3D points. * - * @param calculator A pointer to a `sphericart_calculator_t` struct + * @param calculator A pointer to a `sphericart_spherical_harmonics_calculator_t` struct * that holds prefactors and options to compute the spherical * harmonics. * @param xyz An array of size `n_samples x 3`. It contains the Cartesian @@ -105,8 +134,8 @@ SPHERICART_EXPORT void sphericart_delete_f(sphericart_calculator_f_t* calculator * @param sph_length size of the sph allocation, should be `n_samples * * (l_max + 1) * (l_max + 1)` */ -SPHERICART_EXPORT void sphericart_compute_array( - sphericart_calculator_t* calculator, +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_array( + sphericart_spherical_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -117,7 +146,7 @@ SPHERICART_EXPORT void sphericart_compute_array( * This function calculates the spherical harmonics and their * derivatives for an array of 3D points. * - * @param calculator A pointer to a `sphericart_calculator_t` struct + * @param calculator A pointer to a `sphericart_spherical_harmonics_calculator_t` struct * that holds prefactors and options to compute the spherical * harmonics. * @param xyz An array of size `n_samples x 3`. It contains the Cartesian @@ -151,8 +180,8 @@ SPHERICART_EXPORT void sphericart_compute_array( * @param dsph_length size of the dsph allocation, which should be `n_samples * * 3 * (l_max + 1) * (l_max + 1)` */ -SPHERICART_EXPORT void sphericart_compute_array_with_gradients( - sphericart_calculator_t* calculator, +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_array_with_gradients( + sphericart_spherical_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -165,7 +194,7 @@ SPHERICART_EXPORT void sphericart_compute_array_with_gradients( * This function calculates the spherical harmonics, their * derivatives and second derivatives for an array of 3D points. * - * @param calculator A pointer to a `sphericart_calculator_t` struct + * @param calculator A pointer to a `sphericart_spherical_harmonics_calculator_t` struct * that holds prefactors and options to compute the spherical * harmonics. * @param xyz An array of size `n_samples x 3`. It contains the Cartesian @@ -211,8 +240,8 @@ SPHERICART_EXPORT void sphericart_compute_array_with_gradients( * @param ddsph_length size of the dsph allocation, which should be * `n_samples * 3 * 3* (l_max + 1) * (l_max + 1)` */ -SPHERICART_EXPORT void sphericart_compute_array_with_hessians( - sphericart_calculator_t* calculator, +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_array_with_hessians( + sphericart_spherical_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -224,11 +253,11 @@ SPHERICART_EXPORT void sphericart_compute_array_with_hessians( ); /** - * Similar to :func:`sphericart_compute_array`, but it computes the spherical + * Similar to :func:`sphericart_spherical_harmonics_compute_array`, but it computes the spherical * harmonics for a single 3D point in space. */ -SPHERICART_EXPORT void sphericart_compute_sample( - sphericart_calculator_t* calculator, +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_sample( + sphericart_spherical_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -236,11 +265,11 @@ SPHERICART_EXPORT void sphericart_compute_sample( ); /** - * Similar to :func:`sphericart_compute_array_with_gradients`, but it + * Similar to :func:`sphericart_spherical_harmonics_compute_array_with_gradients`, but it * computes the spherical harmonics for a single 3D point in space. */ -SPHERICART_EXPORT void sphericart_compute_sample_with_gradients( - sphericart_calculator_t* calculator, +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_sample_with_gradients( + sphericart_spherical_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -250,11 +279,328 @@ SPHERICART_EXPORT void sphericart_compute_sample_with_gradients( ); /** - * Similar to :func:`sphericart_compute_array_with_hessians`, but it computes + * Similar to :func:`sphericart_spherical_harmonics_compute_array_with_hessians`, but it computes * the spherical harmonics for a single 3D point in space. */ -SPHERICART_EXPORT void sphericart_compute_sample_with_hessians( - sphericart_calculator_t* calculator, +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_sample_with_hessians( + sphericart_spherical_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length, + double* dsph, + size_t dsph_length, + double* ddsph, + size_t ddsph_length +); + +/** + * Similar to :func:`sphericart_spherical_harmonics_compute_array`, but using the `float` data + * type. + */ +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_array_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length +); + +/** + * Similar to :func:`sphericart_spherical_harmonics_compute_array_with_gradients`, but using the + * `float` data type. + */ +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_array_with_gradients_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length, + float* dsph, + size_t dsph_length +); + +/** + * Similar to :func:`sphericart_spherical_harmonics_compute_array_with_hessians`, but using the + * `float` data type. + */ +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_array_with_hessians_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length, + float* dsph, + size_t dsph_length, + float* ddsph, + size_t ddsph_length +); + +/** + * Get the number of OpenMP threads used by a calculator. + * If `sphericart` is computed without OpenMP support returns 1. + */ +SPHERICART_EXPORT int sphericart_spherical_harmonics_omp_num_threads( + sphericart_spherical_harmonics_calculator_t* calculator +); + +SPHERICART_EXPORT int sphericart_spherical_harmonics_omp_num_threads_f( + sphericart_spherical_harmonics_calculator_f_t* calculator +); + +/** + * Similar to :func:`sphericart_spherical_harmonics_compute_sample`, but using the `float` data + * type. + */ +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_sample_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length +); + +/** + * Similar to :func:`sphericart_spherical_harmonics_compute_sample_with_gradients`, but using the + * `float` data type. + */ +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_sample_with_gradients_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length, + float* dsph, + size_t dsph_length +); + +/** + * Similar to :func:`sphericart_spherical_harmonics_compute_sample_with_hessians`, but using the + * `float` data type. + */ +SPHERICART_EXPORT void sphericart_spherical_harmonics_compute_sample_with_hessians_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length, + float* dsph, + size_t dsph_length, + float* ddsph, + size_t ddsph_length +); + +/** + * Initializes a solid harmonics calculator and returns a pointer that + * can then be used by functions that evaluate solid harmonics over + * arrays or individual samples. + * + * @param l_max The maximum degree of the solid harmonics to be + * calculated. + * + * @return A pointer to a `sphericart_solid_harmonics_calculator_t` object + * + */ +SPHERICART_EXPORT sphericart_solid_harmonics_calculator_t* sphericart_solid_harmonics_new(size_t l_max +); + +/** + * Similar to `sphericart_solid_harmonics_new`, but it returns a + * `sphericart_solid_harmonics_calculator_f_t`, which performs calculations on the `float` type. + */ +SPHERICART_EXPORT sphericart_solid_harmonics_calculator_f_t* sphericart_solid_harmonics_new_f(size_t l_max +); + +/** + * Deletes a previously allocated `sphericart_solid_harmonics_calculator_t` calculator. + */ +SPHERICART_EXPORT void sphericart_solid_harmonics_delete( + sphericart_solid_harmonics_calculator_t* calculator +); + +/** + * Deletes a previously allocated `sphericart_solid_harmonics_calculator_f_t` calculator. + */ +SPHERICART_EXPORT void sphericart_solid_harmonics_delete_f( + sphericart_solid_harmonics_calculator_f_t* calculator +); + +/** + * This function calculates the solid harmonics and, optionally, their + * derivatives for an array of 3D points. + * + * @param calculator A pointer to a `sphericart_solid_harmonics_calculator_t` struct + * that holds prefactors and options to compute the solid + * harmonics. + * @param xyz An array of size `n_samples x 3`. It contains the Cartesian + * coordinates of the 3D points for which the solid harmonics are + * to be computed, organized along two dimensions. The outer dimension is + * `n_samples` long, accounting for different samples, while the inner + * dimension has size 3 and it represents the x, y, and z coordinates + * respectively. + * @param xyz_length size of the xyz allocation, i.e, `3 * n_samples` + * @param sph pointer to the first element of an array containing `n_samples + * * (l_max + 1) * (l_max + 1)` elements. On exit, this array will contain + * the solid harmonics organized along two dimensions. The leading + * dimension is `n_samples` long and it represents the different + * samples, while the inner dimension size is `(l_max + 1) * (l_max + 1)` + * long and it contains the solid harmonics. These are laid out in + * lexicographic order. For example, if `l_max=2`, it will contain + * `(l, m) = (0, 0), (1, -1), (1, 0), (1, 1), (2, -2), (2, -1), (2, 0), (2, + * 1), (2, 2)`, in this order. + * @param sph_length size of the sph allocation, should be `n_samples * + * (l_max + 1) * (l_max + 1)` + */ +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_array( + sphericart_solid_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length +); + +/** + * This function calculates the solid harmonics and their + * derivatives for an array of 3D points. + * + * @param calculator A pointer to a `sphericart_solid_harmonics_calculator_t` struct + * that holds prefactors and options to compute the solid + * harmonics. + * @param xyz An array of size `n_samples x 3`. It contains the Cartesian + * coordinates of the 3D points for which the solid harmonics are + * to be computed, organized along two dimensions. The outer dimension is + * `n_samples` long, accounting for different samples, while the inner + * dimension has size 3 and it represents the x, y, and z coordinates + * respectively. + * @param xyz_length size of the xyz allocation, i.e, `3 * n_samples` + * @param sph pointer to the first element of an array containing `n_samples + * * (l_max + 1) * (l_max + 1)` elements. On exit, this array will contain + * the solid harmonics organized along two dimensions. The leading + * dimension is `n_samples` long and it represents the different + * samples, while the inner dimension size is `(l_max + 1) * (l_max + 1)` + * long and it contains the solid harmonics. These are laid out in + * lexicographic order. For example, if `l_max=2`, it will contain + * `(l, m) = (0, 0), (1, -1), (1, 0), (1, 1), (2, -2), (2, -1), (2, 0), (2, + * 1), (2, 2)`, in this order. + * @param sph_length size of the sph allocation, should be `n_samples * + * (l_max + 1) * (l_max + 1)` + * @param dsph pointer to the first element of an array containing `n_samples + * * `n_samples * 3 * (l_max + 1) * (l_max + 1)` elements. On exit, this + * array will contain the solid harmonics' derivatives organized + * along three dimensions. As for the `sph` parameter, the leading + * dimension represents the different samples, while the inner-most + * dimension size is `(l_max + 1) * (l_max + 1)`, and it represents + * the degree and order of the solid harmonics (again, organized in + * lexicographic order). The intermediate dimension corresponds to + * different spatial derivatives of the solid harmonics: x, y, + * and z, respectively. + * @param dsph_length size of the dsph allocation, which should be `n_samples + * * 3 * (l_max + 1) * (l_max + 1)` + */ +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_array_with_gradients( + sphericart_solid_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length, + double* dsph, + size_t dsph_length +); + +/** + * This function calculates the solid harmonics, their + * derivatives and second derivatives for an array of 3D points. + * + * @param calculator A pointer to a `sphericart_solid_harmonics_calculator_t` struct + * that holds prefactors and options to compute the solid + * harmonics. + * @param xyz An array of size `n_samples x 3`. It contains the Cartesian + * coordinates of the 3D points for which the solid harmonics are + * to be computed, organized along two dimensions. The outer dimension is + * `n_samples` long, accounting for different samples, while the inner + * dimension has size 3 and it represents the x, y, and z coordinates + * respectively. + * @param xyz_length size of the xyz allocation, i.e, `3 * n_samples` + * @param sph pointer to the first element of an array containing `n_samples + * * (l_max + 1) * (l_max + 1)` elements. On exit, this array will contain + * the solid harmonics organized along two dimensions. The leading + * dimension is `n_samples` long and it represents the different + * samples, while the inner dimension size is `(l_max + 1) * (l_max + 1)` + * long and it contains the solid harmonics. These are laid out in + * lexicographic order. For example, if `l_max=2`, it will contain + * `(l, m) = (0, 0), (1, -1), (1, 0), (1, 1), (2, -2), (2, -1), (2, 0), (2, + * 1), (2, 2)`, in this order. + * @param sph_length size of the sph allocation, should be `n_samples * + * (l_max + 1) * (l_max + 1)` + * @param dsph pointer to the first element of an array containing + * `n_samples * 3 * (l_max + 1) * (l_max + 1)` elements. On exit, + * this array will contain the solid harmonics' derivatives organized + * along three dimensions. As for the `sph` parameter, the leading + * dimension represents the different samples, while the inner-most + * dimension size is `(l_max + 1) * (l_max + 1)`, and it represents + * the degree and order of the solid harmonics (again, organized in + * lexicographic order). The intermediate dimension corresponds to + * different spatial derivatives of the solid harmonics: x, y, + * and z, respectively. + * @param dsph_length size of the dsph allocation, which should be `n_samples + * * 3 * (l_max + 1) * (l_max + 1)` + * @param ddsph pointer to the first element of an array containing + * `n_samples * 3 * 3 * (l_max + 1) * (l_max + 1)` elements. On exit, + * this array will contain the solid harmonics' second derivatives + * organized along four dimensions. As for the `sph` parameter, the leading + * dimension represents the different samples, while the inner-most dimension + * size is `(l_max + 1) * (l_max + 1)`, and it represents the degree and + * order of the solid harmonics (again, organized in lexicographic + * order). The intermediate dimensions correspond to the different spatial + * second derivatives of the solid harmonics, i.e., to the dimensions of + * the hessian matrix. + * @param ddsph_length size of the dsph allocation, which should be + * `n_samples * 3 * 3* (l_max + 1) * (l_max + 1)` + */ +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_array_with_hessians( + sphericart_solid_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length, + double* dsph, + size_t dsph_length, + double* ddsph, + size_t ddsph_length +); + +/** + * Similar to :func:`sphericart_solid_harmonics_compute_array`, but it computes the solid + * harmonics for a single 3D point in space. + */ +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_sample( + sphericart_solid_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length +); + +/** + * Similar to :func:`sphericart_solid_harmonics_compute_array_with_gradients`, but it + * computes the solid harmonics for a single 3D point in space. + */ +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_sample_with_gradients( + sphericart_solid_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length, + double* dsph, + size_t dsph_length +); + +/** + * Similar to :func:`sphericart_solid_harmonics_compute_array_with_hessians`, but it computes + * the solid harmonics for a single 3D point in space. + */ +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_sample_with_hessians( + sphericart_solid_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -266,11 +612,11 @@ SPHERICART_EXPORT void sphericart_compute_sample_with_hessians( ); /** - * Similar to :func:`sphericart_compute_array`, but using the `float` data + * Similar to :func:`sphericart_solid_harmonics_compute_array`, but using the `float` data * type. */ -SPHERICART_EXPORT void sphericart_compute_array_f( - sphericart_calculator_f_t* calculator, +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_array_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -278,11 +624,11 @@ SPHERICART_EXPORT void sphericart_compute_array_f( ); /** - * Similar to :func:`sphericart_compute_array_with_gradients`, but using the + * Similar to :func:`sphericart_solid_harmonics_compute_array_with_gradients`, but using the * `float` data type. */ -SPHERICART_EXPORT void sphericart_compute_array_with_gradients_f( - sphericart_calculator_f_t* calculator, +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_array_with_gradients_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -292,11 +638,11 @@ SPHERICART_EXPORT void sphericart_compute_array_with_gradients_f( ); /** - * Similar to :func:`sphericart_compute_array_with_hessians`, but using the + * Similar to :func:`sphericart_solid_harmonics_compute_array_with_hessians`, but using the * `float` data type. */ -SPHERICART_EXPORT void sphericart_compute_array_with_hessians_f( - sphericart_calculator_f_t* calculator, +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_array_with_hessians_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -308,11 +654,11 @@ SPHERICART_EXPORT void sphericart_compute_array_with_hessians_f( ); /** - * Similar to :func:`sphericart_compute_sample`, but using the `float` data + * Similar to :func:`sphericart_solid_harmonics_compute_sample`, but using the `float` data * type. */ -SPHERICART_EXPORT void sphericart_compute_sample_f( - sphericart_calculator_f_t* calculator, +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_sample_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -320,11 +666,11 @@ SPHERICART_EXPORT void sphericart_compute_sample_f( ); /** - * Similar to :func:`sphericart_compute_sample_with_gradients`, but using the + * Similar to :func:`sphericart_solid_harmonics_compute_sample_with_gradients`, but using the * `float` data type. */ -SPHERICART_EXPORT void sphericart_compute_sample_with_gradients_f( - sphericart_calculator_f_t* calculator, +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_sample_with_gradients_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -334,11 +680,11 @@ SPHERICART_EXPORT void sphericart_compute_sample_with_gradients_f( ); /** - * Similar to :func:`sphericart_compute_sample_with_hessians`, but using the + * Similar to :func:`sphericart_solid_harmonics_compute_sample_with_hessians`, but using the * `float` data type. */ -SPHERICART_EXPORT void sphericart_compute_sample_with_hessians_f( - sphericart_calculator_f_t* calculator, +SPHERICART_EXPORT void sphericart_solid_harmonics_compute_sample_with_hessians_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -353,9 +699,13 @@ SPHERICART_EXPORT void sphericart_compute_sample_with_hessians_f( * Get the number of OpenMP threads used by a calculator. * If `sphericart` is computed without OpenMP support returns 1. */ -SPHERICART_EXPORT int sphericart_omp_num_threads(sphericart_calculator_t* calculator); +SPHERICART_EXPORT int sphericart_solid_harmonics_omp_num_threads( + sphericart_solid_harmonics_calculator_t* calculator +); -SPHERICART_EXPORT int sphericart_omp_num_threads_f(sphericart_calculator_f_t* calculator); +SPHERICART_EXPORT int sphericart_solid_harmonics_omp_num_threads_f( + sphericart_solid_harmonics_calculator_f_t* calculator +); #ifdef __cplusplus } diff --git a/sphericart/src/sphericart-capi.cpp b/sphericart/src/sphericart-capi.cpp index ee4d09387..a5024dd97 100644 --- a/sphericart/src/sphericart-capi.cpp +++ b/sphericart/src/sphericart-capi.cpp @@ -3,16 +3,334 @@ #include "sphericart.h" #include "sphericart.hpp" -extern "C" sphericart_calculator_t* sphericart_new(size_t l_max, bool normalized) { +extern "C" sphericart_spherical_harmonics_calculator_t* sphericart_spherical_harmonics_new(size_t l_max +) { + try { + return new sphericart::SphericalHarmonics(l_max); + } catch (...) { + // TODO: better error handling + return nullptr; + } +} + +extern "C" void sphericart_spherical_harmonics_delete( + sphericart_spherical_harmonics_calculator_t* calculator +) { + try { + delete calculator; + } catch (...) { + // nothing to do + } +} + +extern "C" void sphericart_spherical_harmonics_compute_array( + sphericart_spherical_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length +) { + try { + calculator->compute_array(xyz, xyz_length, sph, sph_length); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" void sphericart_spherical_harmonics_compute_array_with_gradients( + sphericart_spherical_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length, + double* dsph, + size_t dsph_length +) { + try { + calculator->compute_array_with_gradients(xyz, xyz_length, sph, sph_length, dsph, dsph_length); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" void sphericart_spherical_harmonics_compute_array_with_hessians( + sphericart_spherical_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length, + double* dsph, + size_t dsph_length, + double* ddsph, + size_t ddsph_length +) { + try { + calculator->compute_array_with_hessians( + xyz, xyz_length, sph, sph_length, dsph, dsph_length, ddsph, ddsph_length + ); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" void sphericart_spherical_harmonics_compute_sample( + sphericart_spherical_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length +) { + try { + calculator->compute_sample(xyz, xyz_length, sph, sph_length); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" void sphericart_spherical_harmonics_compute_sample_with_gradients( + sphericart_spherical_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length, + double* dsph, + size_t dsph_length +) { + try { + calculator->compute_sample_with_gradients( + xyz, xyz_length, sph, sph_length, dsph, dsph_length + ); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" void sphericart_spherical_harmonics_compute_sample_with_hessians( + sphericart_spherical_harmonics_calculator_t* calculator, + const double* xyz, + size_t xyz_length, + double* sph, + size_t sph_length, + double* dsph, + size_t dsph_length, + double* ddsph, + size_t ddsph_length +) { + try { + calculator->compute_sample_with_hessians( + xyz, xyz_length, sph, sph_length, dsph, dsph_length, ddsph, ddsph_length + ); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" sphericart_spherical_harmonics_calculator_f_t* sphericart_spherical_harmonics_new_f( + size_t l_max +) { + try { + return new sphericart::SphericalHarmonics(l_max); + } catch (...) { + // TODO: better error handling + return nullptr; + } +} + +extern "C" void sphericart_spherical_harmonics_delete_f( + sphericart_spherical_harmonics_calculator_f_t* calculator +) { + try { + delete calculator; + } catch (...) { + // nothing to do + } +} + +extern "C" void sphericart_spherical_harmonics_compute_array_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length +) { + try { + calculator->compute_array(xyz, xyz_length, sph, sph_length); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" void sphericart_spherical_harmonics_compute_array_with_gradients_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length, + float* dsph, + size_t dsph_length +) { + try { + calculator->compute_array_with_gradients(xyz, xyz_length, sph, sph_length, dsph, dsph_length); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" void sphericart_spherical_harmonics_compute_array_with_hessians_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length, + float* dsph, + size_t dsph_length, + float* ddsph, + size_t ddsph_length +) { + try { + calculator->compute_array_with_hessians( + xyz, xyz_length, sph, sph_length, dsph, dsph_length, ddsph, ddsph_length + ); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" void sphericart_spherical_harmonics_compute_sample_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length +) { try { - return new sphericart::SphericalHarmonics(l_max, normalized); + calculator->compute_sample(xyz, xyz_length, sph, sph_length); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" void sphericart_spherical_harmonics_compute_sample_with_gradients_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length, + float* dsph, + size_t dsph_length +) { + try { + calculator->compute_sample_with_gradients( + xyz, xyz_length, sph, sph_length, dsph, dsph_length + ); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" void sphericart_spherical_harmonics_compute_sample_with_hessians_f( + sphericart_spherical_harmonics_calculator_f_t* calculator, + const float* xyz, + size_t xyz_length, + float* sph, + size_t sph_length, + float* dsph, + size_t dsph_length, + float* ddsph, + size_t ddsph_length +) { + try { + calculator->compute_sample_with_hessians( + xyz, xyz_length, sph, sph_length, dsph, dsph_length, ddsph, ddsph_length + ); + } catch (const std::exception& e) { + // TODO: better error handling + printf("fatal error: %s\n", e.what()); + abort(); + } catch (...) { + printf("fatal error: unknown exception type\n"); + abort(); + } +} + +extern "C" int sphericart_spherical_harmonics_omp_num_threads( + sphericart_spherical_harmonics_calculator_t* calculator +) { + return calculator->get_omp_num_threads(); +} + +extern "C" int sphericart_spherical_harmonics_omp_num_threads_f( + sphericart_spherical_harmonics_calculator_f_t* calculator +) { + return calculator->get_omp_num_threads(); +} + +extern "C" sphericart_solid_harmonics_calculator_t* sphericart_solid_harmonics_new(size_t l_max) { + try { + return new sphericart::SolidHarmonics(l_max); } catch (...) { // TODO: better error handling return nullptr; } } -extern "C" void sphericart_delete(sphericart_calculator_t* calculator) { +extern "C" void sphericart_solid_harmonics_delete(sphericart_solid_harmonics_calculator_t* calculator +) { try { delete calculator; } catch (...) { @@ -20,8 +338,8 @@ extern "C" void sphericart_delete(sphericart_calculator_t* calculator) { } } -extern "C" void sphericart_compute_array( - sphericart_calculator_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_array( + sphericart_solid_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -39,8 +357,8 @@ extern "C" void sphericart_compute_array( } } -extern "C" void sphericart_compute_array_with_gradients( - sphericart_calculator_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_array_with_gradients( + sphericart_solid_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -60,8 +378,8 @@ extern "C" void sphericart_compute_array_with_gradients( } } -extern "C" void sphericart_compute_array_with_hessians( - sphericart_calculator_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_array_with_hessians( + sphericart_solid_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -85,8 +403,8 @@ extern "C" void sphericart_compute_array_with_hessians( } } -extern "C" void sphericart_compute_sample( - sphericart_calculator_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_sample( + sphericart_solid_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -104,8 +422,8 @@ extern "C" void sphericart_compute_sample( } } -extern "C" void sphericart_compute_sample_with_gradients( - sphericart_calculator_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_sample_with_gradients( + sphericart_solid_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -127,8 +445,8 @@ extern "C" void sphericart_compute_sample_with_gradients( } } -extern "C" void sphericart_compute_sample_with_hessians( - sphericart_calculator_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_sample_with_hessians( + sphericart_solid_harmonics_calculator_t* calculator, const double* xyz, size_t xyz_length, double* sph, @@ -152,16 +470,17 @@ extern "C" void sphericart_compute_sample_with_hessians( } } -extern "C" sphericart_calculator_f_t* sphericart_new_f(size_t l_max, bool normalized) { +extern "C" sphericart_solid_harmonics_calculator_f_t* sphericart_solid_harmonics_new_f(size_t l_max) { try { - return new sphericart::SphericalHarmonics(l_max, normalized); + return new sphericart::SolidHarmonics(l_max); } catch (...) { // TODO: better error handling return nullptr; } } -extern "C" void sphericart_delete_f(sphericart_calculator_f_t* calculator) { +extern "C" void sphericart_solid_harmonics_delete_f(sphericart_solid_harmonics_calculator_f_t* calculator +) { try { delete calculator; } catch (...) { @@ -169,8 +488,8 @@ extern "C" void sphericart_delete_f(sphericart_calculator_f_t* calculator) { } } -extern "C" void sphericart_compute_array_f( - sphericart_calculator_f_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_array_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -188,8 +507,8 @@ extern "C" void sphericart_compute_array_f( } } -extern "C" void sphericart_compute_array_with_gradients_f( - sphericart_calculator_f_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_array_with_gradients_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -209,8 +528,8 @@ extern "C" void sphericart_compute_array_with_gradients_f( } } -extern "C" void sphericart_compute_array_with_hessians_f( - sphericart_calculator_f_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_array_with_hessians_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -234,8 +553,8 @@ extern "C" void sphericart_compute_array_with_hessians_f( } } -extern "C" void sphericart_compute_sample_f( - sphericart_calculator_f_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_sample_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -253,8 +572,8 @@ extern "C" void sphericart_compute_sample_f( } } -extern "C" void sphericart_compute_sample_with_gradients_f( - sphericart_calculator_f_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_sample_with_gradients_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -276,8 +595,8 @@ extern "C" void sphericart_compute_sample_with_gradients_f( } } -extern "C" void sphericart_compute_sample_with_hessians_f( - sphericart_calculator_f_t* calculator, +extern "C" void sphericart_solid_harmonics_compute_sample_with_hessians_f( + sphericart_solid_harmonics_calculator_f_t* calculator, const float* xyz, size_t xyz_length, float* sph, @@ -301,10 +620,14 @@ extern "C" void sphericart_compute_sample_with_hessians_f( } } -extern "C" int sphericart_omp_num_threads(sphericart_calculator_t* calculator) { +extern "C" int sphericart_solid_harmonics_omp_num_threads( + sphericart_solid_harmonics_calculator_t* calculator +) { return calculator->get_omp_num_threads(); } -extern "C" int sphericart_omp_num_threads_f(sphericart_calculator_f_t* calculator) { +extern "C" int sphericart_solid_harmonics_omp_num_threads_f( + sphericart_solid_harmonics_calculator_f_t* calculator +) { return calculator->get_omp_num_threads(); } diff --git a/sphericart/tests/test_derivatives.cpp b/sphericart/tests/test_derivatives.cpp index d7ed4a8f2..ba0d3f6d1 100644 --- a/sphericart/tests/test_derivatives.cpp +++ b/sphericart/tests/test_derivatives.cpp @@ -177,26 +177,27 @@ int main() { } for (int l_max = 0; l_max < l_max_max; l_max++) { // Test for a range of l_max values - sphericart::SphericalHarmonics calculator = + sphericart::SphericalHarmonics calculator_spherical = sphericart::SphericalHarmonics(l_max); - is_passed = check_gradient_call(l_max, calculator, xyz); + is_passed = check_gradient_call(l_max, calculator_spherical, xyz); if (!is_passed) { std::cout << "Test failed" << std::endl; return -1; } - is_passed = check_hessian_call(l_max, calculator, xyz); + is_passed = check_hessian_call(l_max, calculator_spherical, xyz); if (!is_passed) { std::cout << "Test failed" << std::endl; return -1; } - sphericart::SolidHarmonics calculator = sphericart::SolidHarmonics(l_max); - is_passed = check_gradient_call(l_max, calculator, xyz); + sphericart::SolidHarmonics calculator_solid = + sphericart::SolidHarmonics(l_max); + is_passed = check_gradient_call(l_max, calculator_solid, xyz); if (!is_passed) { std::cout << "Test failed" << std::endl; return -1; } - is_passed = check_hessian_call(l_max, calculator, xyz); + is_passed = check_hessian_call(l_max, calculator_solid, xyz); if (!is_passed) { std::cout << "Test failed" << std::endl; return -1; diff --git a/sphericart/tests/test_hardcoding.cpp b/sphericart/tests/test_hardcoding.cpp index 7ea37c40f..c468ac1be 100644 --- a/sphericart/tests/test_hardcoding.cpp +++ b/sphericart/tests/test_hardcoding.cpp @@ -78,7 +78,7 @@ int main(int argc, char* argv[]) { auto sph1 = std::vector(n_samples * (l_max + 1) * (l_max + 1), 0.0); auto dsph1 = std::vector(n_samples * 3 * (l_max + 1) * (l_max + 1), 0.0); - SphericalHarmonics SH(l_max); + SolidHarmonics SH(l_max); SH.compute_with_gradients(xyz, sph1, dsph1); int size3 = 3 * (l_max + 1) * (l_max + 1); // Size of the third dimension in derivative