21 const int N =
static_cast<int>(x.size());
22 const int M = 2 * (N + 1);
23 CVector y(
static_cast<std::size_t
>(M),
cplx{0.0, 0.0});
24 for (
int j = 0; j < N; ++j) {
25 const auto sj =
static_cast<std::size_t
>(j);
26 y[sj + 1] =
cplx{x[sj], 0.0};
27 y[
static_cast<std::size_t
>(M - 1 - j)] =
cplx{-x[sj], 0.0};
29 CVector Y(
static_cast<std::size_t
>(M));
31 Vector out(
static_cast<std::size_t
>(N));
32 for (
int k = 0; k < N; ++k) {
33 out[
static_cast<std::size_t
>(k)] =
34 -Y[
static_cast<std::size_t
>(k) + 1].imag() / 2.0;
39static void dst_rows(std::vector<double>& A,
int N) {
40 Vector row(
static_cast<std::size_t
>(N));
41 for (
int i = 0; i < N; ++i) {
42 const std::size_t base =
43 static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N);
44 for (
int j = 0; j < N; ++j) {
45 row[
static_cast<std::size_t
>(j)] = A[base + j];
48 for (
int j = 0; j < N; ++j) {
49 A[base + j] = row[
static_cast<std::size_t
>(j)];
54static void dst_cols(std::vector<double>& A,
int N) {
55 Vector col(
static_cast<std::size_t
>(N));
56 for (
int j = 0; j < N; ++j) {
57 const std::size_t sj =
static_cast<std::size_t
>(j);
58 for (
int i = 0; i < N; ++i) {
59 col[
static_cast<std::size_t
>(i)] =
60 A[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N)) + sj];
63 for (
int i = 0; i < N; ++i) {
64 A[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N)) + sj] =
65 col[
static_cast<std::size_t
>(i)];
71static void dst2d(std::vector<double>& A,
int N) {
76static void check_n(
int N) {
77 if (N <= 0 || (N & (N + 1)) != 0) {
78 throw std::invalid_argument(
79 "pde::poisson2d: N must equal 2^p - 1 (e.g. 7, 15, 31, 63, ...)");
83static std::vector<double> flatten(
const Matrix& M,
int N) {
84 std::vector<double> v(
static_cast<std::size_t
>(N) *
static_cast<std::size_t
>(N));
85 for (
int i = 0; i < N; ++i) {
86 for (
int j = 0; j < N; ++j) {
87 v[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N))
88 +
static_cast<std::size_t
>(j)] =
89 M(
static_cast<idx>(i),
static_cast<idx>(j));
95static Matrix unflatten(
const std::vector<double>& v,
int N) {
97 for (
int i = 0; i < N; ++i) {
98 for (
int j = 0; j < N; ++j) {
99 M(
static_cast<idx>(i),
static_cast<idx>(j)) =
100 v[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N))
101 +
static_cast<std::size_t
>(j)];
111 const double h = 1.0 / (N + 1);
112 const double pi = M_PI;
114 std::vector<double> buf = flatten(f, N);
115 const std::size_t NN =
static_cast<std::size_t
>(N) *
static_cast<std::size_t
>(N);
116 for (std::size_t k = 0; k < NN; ++k) {
121 std::vector<double> lam(
static_cast<std::size_t
>(N));
122 for (
int k = 0; k < N; ++k) {
123 lam[
static_cast<std::size_t
>(k)] = 2.0 * (1.0 - std::cos((k + 1) *
pi / (N + 1)));
125 for (
int i = 0; i < N; ++i) {
126 for (
int j = 0; j < N; ++j) {
127 buf[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N))
128 +
static_cast<std::size_t
>(j)] /=
129 lam[
static_cast<std::size_t
>(i)] + lam[
static_cast<std::size_t
>(j)];
133 const double s = (2.0 / (N + 1)) * (2.0 / (N + 1));
134 for (
double& v : buf) {
138 return unflatten(buf, N);
143 const double pi = M_PI;
144 const double N1sq =
static_cast<double>(N + 1) * (N + 1);
146 std::vector<double> buf = flatten(f, N);
149 for (
int i = 0; i < N; ++i) {
150 const double ji = i + 1;
151 for (
int j = 0; j < N; ++j) {
152 const double jj = j + 1;
153 buf[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N))
154 +
static_cast<std::size_t
>(j)] *=
155 4.0 / (N1sq *
pi *
pi * ((ji * ji) + (jj * jj)));
160 return unflatten(buf, N);
FFT interface with backend dispatch.
Matrix poisson2d(const Matrix &f, int N)
Solve using continuous eigenvalues .
Matrix poisson2d_fd(const Matrix &f, int N)
Solve using finite-difference eigenvalues.
void fft(const CVector &in, CVector &out, FFTBackend b=default_fft_backend)
BasicMatrix< real > Matrix
Double-precision dense matrix with full backend dispatch (CPU + GPU).
BasicVector< real > Vector
Real-valued dense vector with full backend dispatch (CPU + GPU)
std::complex< real > cplx
BasicVector< cplx > CVector
Complex-valued dense vector (sequential; no GPU)
2D Poisson equation solved via the Discrete Sine Transform.
Dense vector storage and operations.