numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
generate_halton_nodes.h
Go to the documentation of this file.
1/*
2 * Copyright 2024 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <algorithm>
23#include <array>
24#include <cstddef>
25#include <vector>
26
27#include <Eigen/Core>
28
31
32namespace num_collect::rbf {
33
34namespace impl {
35
46template <base::concepts::real_scalar Scalar>
47void generate_halton_nodes_impl(Eigen::VectorX<Scalar>& buffer,
48 index_type num_nodes, index_type base_sequence_size) {
49 buffer = Eigen::VectorX<Scalar>::Zero(num_nodes + 1);
50 index_type current_size = 1;
51 Scalar sequence_interval =
52 static_cast<Scalar>(1) / static_cast<Scalar>(base_sequence_size);
53 while (current_size <= num_nodes) {
54 const index_type current_sequence_size = std::max<index_type>(2,
55 std::min<index_type>(
56 base_sequence_size, (num_nodes + current_size) / current_size));
57 index_type dest_end = current_size; // save the last index.
58 for (index_type i = 1; i < current_sequence_size; ++i) {
59 const index_type dest_begin = current_size * i;
60 dest_end = dest_begin + current_size;
61 if (dest_end > num_nodes + 1 || dest_end < 0) {
62 dest_end = num_nodes + 1;
63 }
64 if (dest_end <= dest_begin) {
65 break;
66 }
67 const index_type dest_size = dest_end - dest_begin;
68 const Scalar value_offset =
69 static_cast<Scalar>(i) * sequence_interval;
70 buffer.segment(dest_begin, dest_size) =
71 buffer.head(dest_size).array() + value_offset;
72 }
73 current_size = dest_end;
74 sequence_interval /= static_cast<Scalar>(base_sequence_size);
75 }
76}
77
78} // namespace impl
79
89template <base::concepts::real_scalar Scalar, index_type Dimensions>
90[[nodiscard]] auto generate_halton_nodes(index_type num_nodes)
91 -> std::vector<Eigen::Vector<Scalar, Dimensions>> {
92 std::vector<Eigen::Vector<Scalar, Dimensions>> nodes(
93 static_cast<std::size_t>(num_nodes));
94
95 constexpr index_type supported_dimensions = 6;
96 static_assert(Dimensions <= supported_dimensions);
97 static_assert(Dimensions > 1);
98 constexpr std::array<index_type,
99 static_cast<std::size_t>(supported_dimensions)>
100 base_sequence_sizes{2, 3, 5, 7, 11, 13};
101
102 Eigen::VectorX<Scalar> buffer;
103 for (index_type d = 0; d < Dimensions; ++d) {
104 impl::generate_halton_nodes_impl(buffer, num_nodes,
105 base_sequence_sizes[static_cast<std::size_t>(d)]);
106 for (index_type i = 0; i < num_nodes; ++i) {
107 nodes[static_cast<std::size_t>(i)](d) = buffer(i + 1);
108 }
109 }
110
111 return nodes;
112}
113
121template <base::concepts::real_scalar Scalar>
122[[nodiscard]] auto generate_1d_halton_nodes(index_type num_nodes)
123 -> std::vector<Scalar> {
124 Eigen::VectorX<Scalar> buffer;
125 constexpr index_type base_sequence_size = 2;
126 impl::generate_halton_nodes_impl(buffer, num_nodes, base_sequence_size);
127
128 std::vector<Scalar> nodes;
129 nodes.reserve(static_cast<std::size_t>(num_nodes));
130 for (index_type i = 1; i <= num_nodes; ++i) {
131 nodes.push_back(buffer(i));
132 }
133 return nodes;
134}
135
136} // namespace num_collect::rbf
Definition of index_type type.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
void generate_halton_nodes_impl(Eigen::VectorX< Scalar > &buffer, index_type num_nodes, index_type base_sequence_size)
Generate a vector of Halton sequence for a single dimension fornberg2015.
Namespace of RBF interpolation.
auto generate_halton_nodes(index_type num_nodes) -> std::vector< Eigen::Vector< Scalar, Dimensions > >
Generate Halton nodes fornberg2015.
auto generate_1d_halton_nodes(index_type num_nodes) -> std::vector< Scalar >
Generate Halton nodes in 1 dimension fornberg2015.
Definition of real_scalar concept.