6namespace py = pybind11;
8py::array_t<int16_t> markov_reconstruct_cpp(py::array_t<float> coeffs,
9 py::array_t<int16_t> initial,
10 py::array_t<int16_t> resid) {
11 // Get array buffers
12 auto coeffs_buf = coeffs.request();
13 auto initial_buf = initial.request();
14 auto resid_buf = resid.request();
16 // Get raw pointers to data
17 float *coeffs_ptr = static_cast<float *>(coeffs_buf.ptr);
18 int16_t *initial_ptr = static_cast<int16_t *>(initial_buf.ptr);
19 int16_t *resid_ptr = static_cast<int16_t *>(resid_buf.ptr);
21 // Calculate dimensions
22 size_t M = initial_buf.shape[0] + 1; // Number of samples used in prediction
23 size_t output_size = resid_buf.shape[0] + initial_buf.shape[0];
25 // Create output array with explicit shape and memory ownership
26 std::vector<ssize_t> shape = {static_cast<ssize_t>(output_size)};
27 py::array_t<int16_t> output(shape);
28 py::buffer_info output_buf = output.request(true); // Request writable buffer
29 int16_t *output_ptr = static_cast<int16_t *>(output_buf.ptr);
31 // Copy initial values with bounds check
32 for (size_t i = 0; i < initial_buf.shape[0] && i < output_size; i++) {
33 output_ptr[i] = initial_ptr[i];
34 }
36 size_t resid_size = resid_buf.shape[0];
38 // Reconstruct signal iteratively
39 for (size_t i = 0; i < resid_size; i++) {
40 float prediction = 0.0f;
42 // Calculate prediction using coefficients (excluding bias term)
43 for (size_t j = 0; j < M - 1; j++) {
44 float term = coeffs_ptr[j] * static_cast<float>(output_ptr[i + j]);
45 prediction += term;
46 }
48 // Add bias term separately
49 prediction += coeffs_ptr[coeffs_buf.shape[0] - 1];
51 // Round prediction to nearest integer
52 float rounded_prediction = std::round(prediction);
54 // Add residual and store result
55 int16_t final_value = static_cast<int16_t>(
56 rounded_prediction + static_cast<float>(resid_ptr[i]));
57 output_ptr[i + M - 1] = final_value;
58 }
60 return output;
61}
63PYBIND11_MODULE(markov_reconstruct_cpp_ext, m) {
64 m.doc() = "C++ implementation of markov_reconstruct using pybind11";
65 m.def("markov_reconstruct_cpp", &markov_reconstruct_cpp,
66 "Reconstruct signal from Markov model parameters and residuals",
67 py::arg("coeffs"), py::arg("initial"), py::arg("resid"));
68}