Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
// Minimal native C++ example for libuap: no Python, no MATLAB.
//
// Builds a small 2D model with a flaw, runs a full-matrix-capture forward, then
// one misfit-and-gradient evaluation, and prints checksums. Demonstrates that
// the core is usable directly from C++.
//
// Build with CMake (see CMakeLists.txt), or directly:
// cl /O2 /EHsc /std:c++14 example_main.cpp (MSVC)
// g++ -O2 -std=c++14 example_main.cpp -o example_main (GCC/Clang)
#include <cmath>
#include <cstdio>
#include <vector>
#include "libuap.hpp"
constexpr double PI = 3.14159265358979323846;
int main() {
const int n = 41;
const int dims[2] = {n, n};
const double h = 1.0e-3, dt = 1.5e-7;
const int nt = 300;
const double f0 = 0.4e6;
const std::size_t N = uap::cell_count(dims, 2);
// Ricker wavelet.
std::vector<double> wavelet(nt);
for (int i = 0; i < nt; ++i) {
double t = i * dt - 1.0 / f0;
double a = (PI * f0 * t) * (PI * f0 * t);
wavelet[i] = (1.0 - 2.0 * a) * std::exp(-a);
}
// Uniform 3000 m/s medium with a low-velocity circular flaw.
std::vector<double> m(N);
const double cx = (n - 1) * h / 2.0;
for (int iy = 0; iy < n; ++iy)
for (int ix = 0; ix < n; ++ix) {
double x = ix * h, y = iy * h;
double r = std::hypot(x - 0.60 * (n - 1) * h, y - 0.50 * (n - 1) * h);
double c = (r <= 0.004) ? 2600.0 : 3000.0;
m[static_cast<std::size_t>(iy) * n + ix] = 1.0 / (c * c);
}
// A ring of 12 elements (linear indices).
const int ne = 12;
std::vector<int> elem(ne);
for (int k = 0; k < ne; ++k) {
double th = 2.0 * PI * k / ne;
int ix = static_cast<int>(std::lround((cx + 0.016 * std::cos(th)) / h));
int iy = static_cast<int>(std::lround((cx + 0.016 * std::sin(th)) / h));
elem[k] = iy * n + ix;
}
// Forward.
std::vector<double> data(static_cast<std::size_t>(ne) * nt * ne);
uap::forward_fmc(m.data(), dims, 2, h, dt, nt, elem.data(), ne, elem.data(), ne,
wavelet.data(), data.data());
double s = 0.0;
for (double v : data) s += std::abs(v);
std::printf("forward: sum|data| = %.6e\n", s);
// Misfit and gradient from a uniform starting model, with the flaw data as target.
std::vector<double> m0(N, 1.0 / (3000.0 * 3000.0)), grad(N);
double J = uap::misfit_and_gradient(m0.data(), dims, 2, h, dt, nt, elem.data(), ne,
elem.data(), ne, wavelet.data(), data.data(), grad.data());
double gs = 0.0;
for (double v : grad) gs += std::abs(v);
std::printf("misfit J = %.6e, sum|grad| = %.6e\n", J, gs);
std::printf("libuap native example OK\n");
return 0;
}
9b8abb22fThis file is pinned to the selected release. Download the original to open it in your design tool.