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)] = -Y[
static_cast<std::size_t
>(k) + 1].imag() / 2.0;
38static void dst_rows(std::vector<double>& A,
int N) {
39 Vector row(
static_cast<std::size_t
>(N));
40 for (
int i = 0; i < N; ++i) {
41 const std::size_t base =
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N);
42 for (
int j = 0; j < N; ++j) { row[
static_cast<std::size_t
>(j)] = A[base + j]; }
44 for (
int j = 0; j < N; ++j) { A[base + j] = row[
static_cast<std::size_t
>(j)]; }
48static void dst_cols(std::vector<double>& A,
int N) {
49 Vector col(
static_cast<std::size_t
>(N));
50 for (
int j = 0; j < N; ++j) {
51 const std::size_t sj =
static_cast<std::size_t
>(j);
52 for (
int i = 0; i < N; ++i) {
53 col[
static_cast<std::size_t
>(i)] = A[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N)) + sj];
56 for (
int i = 0; i < N; ++i) {
57 A[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N)) + sj] = col[
static_cast<std::size_t
>(i)];
63static void dst2d(std::vector<double>& A,
int N) {
68static void check_n(
int N) {
69 if (N <= 0 || (N & (N + 1)) != 0) {
70 throw std::invalid_argument(
71 "pde::poisson2d: N must equal 2^p - 1 (e.g. 7, 15, 31, 63, ...)");
75static std::vector<double> flatten(
const Matrix& M,
int N) {
76 std::vector<double> v(
static_cast<std::size_t
>(N) *
static_cast<std::size_t
>(N));
77 for (
int i = 0; i < N; ++i) {
78 for (
int j = 0; j < N; ++j) {
79 v[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N)) +
static_cast<std::size_t
>(j)] =
80 M(
static_cast<idx>(i),
static_cast<idx>(j));
86static Matrix unflatten(
const std::vector<double>& v,
int N) {
87 Matrix M(
static_cast<idx>(N),
static_cast<idx>(N));
88 for (
int i = 0; i < N; ++i) {
89 for (
int j = 0; j < N; ++j) {
90 M(
static_cast<idx>(i),
static_cast<idx>(j)) =
91 v[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N)) +
static_cast<std::size_t
>(j)];
108 const double h = 1.0 / (N + 1);
109 const double pi = M_PI;
111 std::vector<double> buf = flatten(f, N);
112 const std::size_t NN =
static_cast<std::size_t
>(N) *
static_cast<std::size_t
>(N);
113 for (std::size_t k = 0; k < NN; ++k) { buf[k] *= h * h; }
116 std::vector<double> lam(
static_cast<std::size_t
>(N));
117 for (
int k = 0; k < N; ++k) {
118 lam[
static_cast<std::size_t
>(k)] = 2.0 * (1.0 - std::cos((k + 1) *
pi / (N + 1)));
120 for (
int i = 0; i < N; ++i) {
121 for (
int j = 0; j < N; ++j) {
122 buf[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N)) +
static_cast<std::size_t
>(j)] /=
123 lam[
static_cast<std::size_t
>(i)] + lam[
static_cast<std::size_t
>(j)];
127 const double s = (2.0 / (N + 1)) * (2.0 / (N + 1));
128 for (
double& v : buf) { v *= s; }
130 return unflatten(buf, N);
147 const double pi = M_PI;
148 const double N1sq =
static_cast<double>(N + 1) * (N + 1);
150 std::vector<double> buf = flatten(f, N);
153 for (
int i = 0; i < N; ++i) {
154 const double ji = i + 1;
155 for (
int j = 0; j < N; ++j) {
156 const double jj = j + 1;
157 buf[(
static_cast<std::size_t
>(i) *
static_cast<std::size_t
>(N)) +
static_cast<std::size_t
>(j)] *=
158 4.0 / (N1sq *
pi *
pi * ((ji * ji) + (jj * jj)));
163 return unflatten(buf, N);
Dense row-major matrix with optional GPU storage.
FFT interface with backend dispatch.
Matrix poisson2d(const Matrix &f, int N)
Solve -Delta u = f on (0,1)^2 (Dirichlet) via DST with exact eigenvalues.
Matrix poisson2d_fd(const Matrix &f, int N)
Solve -Delta u = f on (0,1)^2 (Dirichlet) via DST with FD eigenvalues.
void fft(const CVector &in, CVector &out, FFTBackend b=default_fft_backend)
Forward complex DFT. out must be pre-allocated to in.size().
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.