Skip to content

Commit 777a613

Browse files
committed
feat: Add ND Hybercube array
This functionality is required for ND cubic interpolation Signed-off-by: Sietze van Buuren <s.van.buuren@gmail.com>
1 parent 7808531 commit 777a613

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

include/arrayn.hpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#pragma once
2+
3+
#include <mdspan/mdspan.hpp>
4+
#include <array>
5+
#include <cstddef>
6+
7+
8+
namespace cip {
9+
10+
11+
constexpr std::size_t power(std::size_t base, std::size_t exp) {
12+
return exp == 0 ? 1 : base * power(base, exp - 1);
13+
}
14+
15+
16+
template <std::size_t Value, std::size_t... I>
17+
constexpr std::extents<std::size_t, ((void)I, Value)...>
18+
make_extents(std::index_sequence<I...>) {
19+
return {};
20+
}
21+
22+
23+
template<typename T, std::size_t N, std::size_t Size>
24+
class NDHyperArray {
25+
static constexpr std::size_t total_size = power(Size, N);
26+
using Array = std::array<T, total_size>;
27+
using ExtentsType = decltype(make_extents<Size>(std::make_index_sequence<N>{}));
28+
using Mdspan = std::mdspan<T, ExtentsType>;
29+
public:
30+
NDHyperArray()
31+
: mdspan(data.data())
32+
{}
33+
34+
~NDHyperArray() = default;
35+
36+
template<typename... Index>
37+
T& operator()(Index... idx) {
38+
return mdspan(idx...);
39+
}
40+
41+
template<typename... Index>
42+
const T& operator()(Index... idx) const {
43+
return mdspan(idx...);
44+
}
45+
46+
private:
47+
Array data;
48+
Mdspan mdspan;
49+
50+
};
51+
52+
53+
} // namespace cip

include/cubinterpp.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "utils.hpp"
44
#include "slopes.hpp"
55
#include "vectorn.hpp"
6+
#include "arrayn.hpp"
67
#include "linear_interp.hpp"
78
#include "cubic_spline.hpp"
89
#include "cubic_splines_1d.hpp"

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ FetchContent_Declare(
2222
FetchContent_MakeAvailable(googletest)
2323

2424
cubinterpp_add_test(test_vectorn)
25+
cubinterpp_add_test(test_arrayn)
2526
cubinterpp_add_test(test_linear_interp)
2627
cubinterpp_add_test(test_cubic_splines_1d)
2728
cubinterpp_add_test(test_cubic_splines_2d)

tests/test_arrayn.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <gtest/gtest.h>
2+
#include <cubinterpp.hpp>
3+
4+
5+
// Test a 1-dimensional NDHyperArray.
6+
TEST(NDHyperArrayTest, OneDArray) {
7+
cip::NDHyperArray<int, 1, 4> arr;
8+
arr(0) = 10;
9+
arr(1) = 20;
10+
arr(2) = 30;
11+
arr(3) = 40;
12+
EXPECT_EQ(arr(0), 10);
13+
EXPECT_EQ(arr(1), 20);
14+
EXPECT_EQ(arr(2), 30);
15+
EXPECT_EQ(arr(3), 40);
16+
}
17+
18+
19+
// Test a 2-dimensional NDHyperArray.
20+
TEST(NDHyperArrayTest, TwoDArray) {
21+
cip::NDHyperArray<int, 2, 4> arr;
22+
arr(0, 0) = 1;
23+
arr(0, 1) = 2;
24+
arr(1, 0) = 3;
25+
arr(3, 3) = 4;
26+
EXPECT_EQ(arr(0, 0), 1);
27+
EXPECT_EQ(arr(0, 1), 2);
28+
EXPECT_EQ(arr(1, 0), 3);
29+
EXPECT_EQ(arr(3, 3), 4);
30+
}
31+
32+
33+
// Test a 3-dimensional NDHyperArray.
34+
TEST(NDHyperArrayTest, ThreeDArray) {
35+
cip::NDHyperArray<double, 3, 4> arr;
36+
arr(1, 2, 3) = 3.14159;
37+
arr(0, 0, 0) = 2.71828;
38+
EXPECT_NEAR(arr(1, 2, 3), 3.14159, 1e-6);
39+
EXPECT_NEAR(arr(0, 0, 0), 2.71828, 1e-6);
40+
}
41+
42+
43+
// Test const access to ensure the const overload of operator() works.
44+
TEST(NDHyperArrayTest, ConstAccess) {
45+
cip::NDHyperArray<int, 2, 4> arr;
46+
arr(2, 2) = 99;
47+
const cip::NDHyperArray<int, 2, 4>& constArr = arr;
48+
EXPECT_EQ(constArr(2, 2), 99);
49+
}

0 commit comments

Comments
 (0)