...
This commit is contained in:
parent
01485ed2e1
commit
cfe1fc8fab
@ -142,4 +142,9 @@ if (WITH_TESTS)
|
|||||||
set(ASTROM_TEST_APP astrom_test)
|
set(ASTROM_TEST_APP astrom_test)
|
||||||
add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp)
|
add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp)
|
||||||
target_link_libraries(${ASTROM_TEST_APP} ERFA_LIB)
|
target_link_libraries(${ASTROM_TEST_APP} ERFA_LIB)
|
||||||
|
|
||||||
|
set(FITPACK_TEST_APP fitpack_test)
|
||||||
|
add_executable(${FITPACK_TEST_APP} tests/fitpack_test.cpp)
|
||||||
|
target_link_libraries(${FITPACK_TEST_APP} fitpack)
|
||||||
|
# target_include_directories(${FITPACK_TEST_APP} PRIVATE fitpack)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -20,11 +20,12 @@ enable_language(Fortran CXX)
|
|||||||
include(FortranCInterface)
|
include(FortranCInterface)
|
||||||
FortranCInterface_HEADER(FortranCInterface.h
|
FortranCInterface_HEADER(FortranCInterface.h
|
||||||
MACRO_NAMESPACE "FC_"
|
MACRO_NAMESPACE "FC_"
|
||||||
SYMBOL_NAMESPACE "fp_"
|
# SYMBOL_NAMESPACE "fp_"
|
||||||
SYMBOLS ${func_str}
|
SYMBOL_NAMESPACE ""
|
||||||
|
# SYMBOLS ${func_str}
|
||||||
|
SYMBOLS ${func_name}
|
||||||
)
|
)
|
||||||
|
FortranCInterface_VERIFY(CXX)
|
||||||
|
|
||||||
add_library(fitpack STATIC ${src_files} fitpack.h)
|
add_library(fitpack STATIC ${src_files} fitpack.h)
|
||||||
set(FITPACK_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,38 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <expected>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace mcc::fitpack
|
#include "/home/timur/PROGRAMS/C++/build-mountcontrol-Desktop-Debug/cxx/fitpack/FortranCInterface.h"
|
||||||
{
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void curfit(int* iopt,
|
|
||||||
int* m,
|
|
||||||
double* x,
|
|
||||||
double* y,
|
|
||||||
double* w,
|
|
||||||
double* xb,
|
|
||||||
double* xe,
|
|
||||||
int* k,
|
|
||||||
double* s,
|
|
||||||
int* nest,
|
|
||||||
int* n,
|
|
||||||
double* t,
|
|
||||||
double* c,
|
|
||||||
double* fp,
|
|
||||||
double* wrk,
|
|
||||||
int* lwrk,
|
|
||||||
int* iwrk,
|
|
||||||
int* ier);
|
|
||||||
|
|
||||||
void splev(double* t, int* n, double* c, int* k, double* x, double* y, int* m, int* e, int* ier);
|
|
||||||
|
|
||||||
void splder(double* t, int* n, double* c, int* k, int* nu, double* x, double* y, int* m, int* e, double* wrk, int* ier);
|
|
||||||
|
|
||||||
void surfit(int* iopt,
|
void surfit(int* iopt,
|
||||||
int* m,
|
int* m,
|
||||||
double* x,
|
double* x,
|
||||||
@ -130,7 +105,11 @@ void sphere(int* iopt,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <std::ranges::contiguous_range TethaT,
|
namespace mcc::fitpack
|
||||||
|
{
|
||||||
|
|
||||||
|
template <int IOPT = 0,
|
||||||
|
std::ranges::contiguous_range TethaT,
|
||||||
std::ranges::contiguous_range PhiT,
|
std::ranges::contiguous_range PhiT,
|
||||||
std::ranges::contiguous_range FuncT,
|
std::ranges::contiguous_range FuncT,
|
||||||
typename WeightT,
|
typename WeightT,
|
||||||
@ -156,7 +135,8 @@ int fitpack_sphere_smooth(const TethaT& tetha,
|
|||||||
std::same_as<std::ranges::range_value_t<PhiT>, double> &&
|
std::same_as<std::ranges::range_value_t<PhiT>, double> &&
|
||||||
std::same_as<std::ranges::range_value_t<FuncT>, double> &&
|
std::same_as<std::ranges::range_value_t<FuncT>, double> &&
|
||||||
std::same_as<std::ranges::range_value_t<TKnotT>, double> &&
|
std::same_as<std::ranges::range_value_t<TKnotT>, double> &&
|
||||||
std::same_as<std::ranges::range_value_t<PKnotT>, double>,
|
std::same_as<std::ranges::range_value_t<PKnotT>, double> &&
|
||||||
|
std::same_as<std::ranges::range_value_t<CoeffT>, double>,
|
||||||
"Input ranges elements type must be double!");
|
"Input ranges elements type must be double!");
|
||||||
|
|
||||||
if constexpr (std::ranges::contiguous_range<WeightT>) {
|
if constexpr (std::ranges::contiguous_range<WeightT>) {
|
||||||
@ -164,7 +144,11 @@ int fitpack_sphere_smooth(const TethaT& tetha,
|
|||||||
"Input ranges elements type must be double!");
|
"Input ranges elements type must be double!");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto m = std::min(std::min(std::ranges::size(tetha), std::ranges::size(phi)), std::ranges::size(func));
|
|
||||||
|
static_assert(IOPT != -1 || IOPT != 0 || IOPT != 1, "Invalid IOPT template parameter value!");
|
||||||
|
|
||||||
|
|
||||||
|
int m = std::min(std::min(std::ranges::size(tetha), std::ranges::size(phi)), std::ranges::size(func));
|
||||||
if (m < 2) {
|
if (m < 2) {
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
@ -210,33 +194,47 @@ int fitpack_sphere_smooth(const TethaT& tetha,
|
|||||||
const int uv = u * v;
|
const int uv = u * v;
|
||||||
const int v2 = v * v;
|
const int v2 = v * v;
|
||||||
|
|
||||||
const int lwrk1 = 185 + 52 * v + 10 * u + 14 * uv + 8 * (u - 1) * v2 + 8 * m;
|
int lwrk1 = 185 + 52 * v + 10 * u + 14 * uv + 8 * (u - 1) * v2 + 8 * m;
|
||||||
const int lwrk2 = 48 + 21 * v + 7 * uv + 4 * (u - 1) * v2;
|
int lwrk2 = 48 + 21 * v + 7 * uv + 4 * (u - 1) * v2;
|
||||||
const int kwrk = m + uv;
|
int kwrk = m + uv;
|
||||||
|
|
||||||
std::unique_ptr<double> wrk1{new double(lwrk1)};
|
std::vector<double> wrk1(lwrk1);
|
||||||
std::unique_ptr<double> wrk2{new double(lwrk2)};
|
std::vector<double> wrk2(lwrk2);
|
||||||
std::unique_ptr<int> iwrk{new int(kwrk)};
|
std::vector<int> iwrk(kwrk);
|
||||||
|
|
||||||
const int n_coeffs = (ntest - 4) * (npest - 4);
|
const int n_coeffs = (ntest - 4) * (npest - 4);
|
||||||
if (std::ranges::size(coeffs) < n_coeffs) { // resize
|
if (std::ranges::size(coeffs) < n_coeffs) { // resize
|
||||||
std::ranges::fill_n(std::back_inserter(coeffs), n_coeffs - std::ranges::size(coeffs), 0.0);
|
std::ranges::fill_n(std::back_inserter(coeffs), n_coeffs - std::ranges::size(coeffs), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int iopt = 0;
|
int iopt = IOPT;
|
||||||
|
|
||||||
|
auto tetha_ptr = const_cast<double*>(std::ranges::data(tetha));
|
||||||
|
auto phi_ptr = const_cast<double*>(std::ranges::data(phi));
|
||||||
|
auto func_ptr = const_cast<double*>(std::ranges::data(func));
|
||||||
|
auto tetha_knots_ptr = const_cast<double*>(std::ranges::data(tetha_knots));
|
||||||
|
auto phi_knots_ptr = const_cast<double*>(std::ranges::data(phi_knots));
|
||||||
|
|
||||||
if constexpr (std::ranges::contiguous_range<WeightT>) {
|
if constexpr (std::ranges::contiguous_range<WeightT>) {
|
||||||
res = sphere(&iopt, &m, std::ranges::data(tetha), std::ranges::data(phi), std::ranges::data(func),
|
auto weight_ptr = const_cast<double*>(std::ranges::data(weight));
|
||||||
std::ranges::data(weight), &s_par, &ntest, &npest, &eps, &ntest, std::ranges::data(tetha_knots),
|
|
||||||
&npest, std::ranges::data(phi_knots), std::ranges::data(coeffs), &resi2_sum, wrk1.get(), &lwrk1,
|
sphere(&iopt, &m, tetha_ptr, phi_ptr, func_ptr, weight_ptr, &s_par, &ntest, &npest, &eps, &ntest,
|
||||||
wrk2.get(), &lwrk2, iwrk.get(), &kwrk, &res);
|
tetha_knots_ptr, &npest, phi_knots_ptr, std::ranges::data(coeffs), &resi2_sum, wrk1.data(), &lwrk1,
|
||||||
|
wrk2.data(), &lwrk2, iwrk.data(), &kwrk, &res);
|
||||||
|
// sphere(&iopt, &m, std::ranges::data(tetha), std::ranges::data(phi), std::ranges::data(func),
|
||||||
|
// std::ranges::data(weight), &s_par, &ntest, &npest, &eps, &ntest, std::ranges::data(tetha_knots),
|
||||||
|
// &npest, std::ranges::data(phi_knots), std::ranges::data(coeffs), &resi2_sum, wrk1.data(), &lwrk1,
|
||||||
|
// wrk2.data(), &lwrk2, iwrk.data(), &kwrk, &res);
|
||||||
} else {
|
} else {
|
||||||
std::vector<double> weight_vec(m, weight);
|
std::vector<double> weight_vec(m, weight);
|
||||||
|
|
||||||
res = sphere(&iopt, &m, std::ranges::data(tetha), std::ranges::data(phi), std::ranges::data(func),
|
sphere(&iopt, &m, tetha_ptr, phi_ptr, func_ptr, weight_vec.data(), &s_par, &ntest, &npest, &eps, &ntest,
|
||||||
weight_vec.data(), &s_par, &ntest, &npest, &eps, &ntest, std::ranges::data(tetha_knots), &npest,
|
tetha_knots_ptr, &npest, phi_knots_ptr, std::ranges::data(coeffs), &resi2_sum, wrk1.data(), &lwrk1,
|
||||||
std::ranges::data(phi_knots), std::ranges::data(coeffs), &resi2_sum, wrk1.get(), &lwrk1,
|
wrk2.data(), &lwrk2, iwrk.data(), &kwrk, &res);
|
||||||
wrk2.get(), &lwrk2, iwrk.get(), &kwrk, &res);
|
// res = sphere(&iopt, &m, std::ranges::data(tetha), std::ranges::data(phi), std::ranges::data(func),
|
||||||
|
// weight_vec.data(), &s_par, &ntest, &npest, &eps, &ntest, std::ranges::data(tetha_knots), &npest,
|
||||||
|
// std::ranges::data(phi_knots), std::ranges::data(coeffs), &resi2_sum, wrk1.get(), &lwrk1,
|
||||||
|
// wrk2.get(), &lwrk2, iwrk.get(), &kwrk, &res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -257,8 +255,8 @@ int fitpack_sphere_fit(const TethaT& tetha,
|
|||||||
const PhiT& phi,
|
const PhiT& phi,
|
||||||
const FuncT& func,
|
const FuncT& func,
|
||||||
const WeightT& weight,
|
const WeightT& weight,
|
||||||
const TKnotT& tetha_knots,
|
TKnotT& tetha_knots,
|
||||||
const PKnotT& phi_knots,
|
PKnotT& phi_knots,
|
||||||
CoeffT& coeffs,
|
CoeffT& coeffs,
|
||||||
double& resi2_sum,
|
double& resi2_sum,
|
||||||
double eps = std::numeric_limits<double>::epsilon())
|
double eps = std::numeric_limits<double>::epsilon())
|
||||||
@ -267,104 +265,73 @@ int fitpack_sphere_fit(const TethaT& tetha,
|
|||||||
int nt = std::ranges::size(tetha_knots);
|
int nt = std::ranges::size(tetha_knots);
|
||||||
int np = std::ranges::size(phi_knots);
|
int np = std::ranges::size(phi_knots);
|
||||||
|
|
||||||
return fitpack_sphere_smooth(tetha, phi, func, weight, s, nt, np, tetha_knots, phi_knots, coeffs, resi2_sum, eps);
|
return fitpack_sphere_smooth<-1>(tetha, phi, func, weight, s, nt, np, tetha_knots, phi_knots, coeffs, resi2_sum,
|
||||||
|
eps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
template <std::ranges::contiguous_range TethaT,
|
template <std::ranges::contiguous_range TXT,
|
||||||
std::ranges::contiguous_range PhiT,
|
std::ranges::contiguous_range TYT,
|
||||||
std::ranges::contiguous_range FuncT,
|
std::ranges::contiguous_range XT,
|
||||||
typename WeightT,
|
std::ranges::contiguous_range YT,
|
||||||
std::ranges::contiguous_range TKnotT,
|
std::ranges::contiguous_range CoeffT,
|
||||||
std::ranges::contiguous_range PKnotT,
|
std::ranges::contiguous_range FuncT>
|
||||||
std::ranges::contiguous_range CoeffT>
|
int fitpack_eval_spl2d(const TXT& tx,
|
||||||
int fitpack_sphere_fit(const TethaT& tetha,
|
const TYT& ty,
|
||||||
const PhiT& phi,
|
const CoeffT& coeffs,
|
||||||
const FuncT& func,
|
const XT& x,
|
||||||
const WeightT& weight,
|
const YT& y,
|
||||||
const TKnotT& tetha_knots,
|
FuncT& func,
|
||||||
const PKnotT& phi_knots,
|
int kx = 3,
|
||||||
CoeffT& coeffs,
|
int ky = 3)
|
||||||
double& resi2_sum,
|
|
||||||
double eps = std::numeric_limits<double>::epsilon())
|
|
||||||
requires((std::ranges::contiguous_range<WeightT> || std::convertible_to<WeightT, double>) &&
|
|
||||||
std::ranges::output_range<CoeffT, double>)
|
|
||||||
{
|
{
|
||||||
static_assert(std::same_as<std::ranges::range_value_t<TethaT>, double> &&
|
static_assert(std::same_as<std::ranges::range_value_t<TXT>, double> &&
|
||||||
std::same_as<std::ranges::range_value_t<PhiT>, double> &&
|
std::same_as<std::ranges::range_value_t<TYT>, double> &&
|
||||||
std::same_as<std::ranges::range_value_t<FuncT>, double> &&
|
std::same_as<std::ranges::range_value_t<XT>, double> &&
|
||||||
std::same_as<std::ranges::range_value_t<TKnotT>, double> &&
|
std::same_as<std::ranges::range_value_t<YT>, double> &&
|
||||||
std::same_as<std::ranges::range_value_t<PKnotT>, double>,
|
std::same_as<std::ranges::range_value_t<CoeffT>, double> &&
|
||||||
|
std::same_as<std::ranges::range_value_t<FuncT>, double>,
|
||||||
"Input ranges elements type must be double!");
|
"Input ranges elements type must be double!");
|
||||||
|
|
||||||
if constexpr (std::ranges::contiguous_range<WeightT>) {
|
if (kx < 0 || ky < 0) {
|
||||||
static_assert(std::same_as<std::ranges::range_value_t<WeightT>, double>,
|
|
||||||
"Input ranges elements type must be double!");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto m = std::min(std::min(std::ranges::size(tetha), std::ranges::size(phi)), std::ranges::size(func));
|
|
||||||
if (m < 2) {
|
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
const auto nt = std::ranges::size(tetha_knots);
|
int ier = 0;
|
||||||
const auto np = std::ranges::size(phi_knots);
|
|
||||||
|
|
||||||
// number of knots must be >= 8 for the qubic b-splines
|
int ntx = std::ranges::size(tx);
|
||||||
if (std::min(nt, np) < 8) {
|
int nty = std::ranges::size(ty);
|
||||||
|
|
||||||
|
auto n_coeffs = (ntx - kx - 1) * (nty - ky - 1);
|
||||||
|
if (std::ranges::size(coeffs) < n_coeffs) {
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (std::ranges::contiguous_range<WeightT>) {
|
int mx = std::ranges::size(x), my = std::ranges::size(y);
|
||||||
m = std::min(m, std::ranges::size(weight));
|
int N = mx * my;
|
||||||
if (m < 2) {
|
|
||||||
return 10;
|
if (std::ranges::size(func) < N) {
|
||||||
}
|
std::ranges::fill_n(std::back_inserter(func), N - std::ranges::size(func), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute working arrays sizes according to sphere.f
|
// compute sizes of working arrays according to bispev.f
|
||||||
const int u = nt - 7;
|
int lwrk = mx * (kx + 1) + my * (ky + 1);
|
||||||
const int v = np - 7;
|
std::vector<double> wrk(lwrk);
|
||||||
const int uv = u * v;
|
|
||||||
const int v2 = v * v;
|
|
||||||
|
|
||||||
const int lwrk1 = 185 + 52 * v + 10 * u + 14 * uv + 8 * (u - 1) * v2 + 8 * m;
|
int kwrk = mx + my;
|
||||||
const int lwrk2 = 48 + 21 * v + 7 * uv + 4 * (u - 1) * v2;
|
std::vector<int> iwrk(kwrk);
|
||||||
const int kwrk = m + uv;
|
|
||||||
|
|
||||||
std::unique_ptr<double> wrk1{new double(lwrk1)};
|
auto tx_ptr = const_cast<double*>(std::ranges::data(tx));
|
||||||
std::unique_ptr<double> wrk2{new double(lwrk2)};
|
auto ty_ptr = const_cast<double*>(std::ranges::data(ty));
|
||||||
std::unique_ptr<int> iwrk{new int(kwrk)};
|
auto coeffs_ptr = const_cast<double*>(std::ranges::data(coeffs));
|
||||||
|
auto x_ptr = const_cast<double*>(std::ranges::data(x));
|
||||||
|
auto y_ptr = const_cast<double*>(std::ranges::data(y));
|
||||||
|
|
||||||
const int n_coeffs = (nt - 4) * (np - 4);
|
bispev(tx_ptr, &ntx, ty_ptr, &nty, coeffs_ptr, &kx, &ky, x_ptr, &mx, y_ptr, &my, std::ranges::data(func),
|
||||||
if (std::ranges::size(coeffs) < n_coeffs) { // resize
|
wrk.data(), &lwrk, iwrk.data(), &kwrk, &ier);
|
||||||
std::ranges::fill_n(std::back_inserter(coeffs), n_coeffs - std::ranges::size(coeffs), 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int iopt = -1;
|
return ier;
|
||||||
const double s = 100.0;
|
|
||||||
|
|
||||||
if constexpr (std::ranges::contiguous_range<WeightT>) {
|
|
||||||
res = sphere(&iopt, &m, std::ranges::data(tetha), std::ranges::data(phi), std::ranges::data(func),
|
|
||||||
std::ranges::data(weight), &s, &nt, &np, &eps, &nt, std::ranges::data(tetha_knots), &np,
|
|
||||||
std::ranges::data(phi_knots), std::ranges::data(coeffs), &resi2_sum, wrk1.get(), &lwrk1,
|
|
||||||
wrk2.get(), &lwrk2, iwrk.get(), &kwrk, &res);
|
|
||||||
} else {
|
|
||||||
std::vector<double> weight_vec(m, weight);
|
|
||||||
|
|
||||||
res = sphere(&iopt, &m, std::ranges::data(tetha), std::ranges::data(phi), std::ranges::data(func),
|
|
||||||
weight_vec.data(), &s, &nt, &np, &eps, &nt, std::ranges::data(tetha_knots), &np,
|
|
||||||
std::ranges::data(phi_knots), std::ranges::data(coeffs), &resi2_sum, wrk1.get(), &lwrk1,
|
|
||||||
wrk2.get(), &lwrk2, iwrk.get(), &kwrk, &res);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
} // namespace mcc::fitpack
|
} // namespace mcc::fitpack
|
||||||
|
|||||||
108
cxx/tests/fitpack_test.cpp
Normal file
108
cxx/tests/fitpack_test.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <random>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
|
// #include <fitpack.h>
|
||||||
|
#include "../fitpack/fitpack.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// size_t nt = 3, np = 5, N = nt * np, i = 1;
|
||||||
|
size_t nt = 10, np = 20, N = nt * np, i = 1;
|
||||||
|
double ts = std::numbers::pi / (nt + 1);
|
||||||
|
double ps = 2.0 * std::numbers::pi / (np + 1);
|
||||||
|
|
||||||
|
std::vector<double> tetha(N), phi(N), func(N);
|
||||||
|
|
||||||
|
auto gen_func = [](double st, size_t& idx) {
|
||||||
|
double v = st * idx;
|
||||||
|
++idx;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto print_func = [](const auto& r, std::string_view name) {
|
||||||
|
std::cout << name << ": ";
|
||||||
|
for (auto& el : r) {
|
||||||
|
std::cout << el << " ";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// std::ranges::generate(tetha, std::bind(gen_func, ts, i));
|
||||||
|
|
||||||
|
// i = 1;
|
||||||
|
// std::ranges::generate(phi, std::bind(gen_func, ps, i));
|
||||||
|
|
||||||
|
size_t k = 1;
|
||||||
|
i = 0;
|
||||||
|
for (size_t j = 0; j < nt; ++j) {
|
||||||
|
std::ranges::fill_n(tetha.begin() + i * np, np, ts * (i + 1));
|
||||||
|
std::ranges::generate(phi | std::views::drop(i * np) | std::views::take(np), std::bind(gen_func, ps, k));
|
||||||
|
++i;
|
||||||
|
k = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uniform_real_distribution<double> distr{-0.1, 0.1};
|
||||||
|
std::random_device device;
|
||||||
|
std::mt19937 engine{device()};
|
||||||
|
|
||||||
|
std::ranges::generate(func, [ii = 0, &distr, &engine, &tetha, &phi]() mutable {
|
||||||
|
double v = (5.0 + tetha[ii]) * 1.3 + (3.0 + phi[ii]) * 3.1 + distr(engine);
|
||||||
|
++ii;
|
||||||
|
return v;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
size_t ntk = 3, npk = 6, nf = (ntk + 4) * (npk + 4);
|
||||||
|
std::vector<double> tk(ntk + 8), pk(npk + 8), coeffs(nf);
|
||||||
|
ts = std::numbers::pi / (ntk + 1);
|
||||||
|
ps = 2.0 * std::numbers::pi / (npk + 1);
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
std::ranges::generate(tk | std::views::drop(4) | std::views::take(ntk), std::bind(gen_func, ts, i));
|
||||||
|
i = 1;
|
||||||
|
std::ranges::generate(pk | std::views::drop(4) | std::views::take(npk), std::bind(gen_func, ps, i));
|
||||||
|
|
||||||
|
|
||||||
|
double rs = 0.0;
|
||||||
|
int ec = mcc::fitpack::fitpack_sphere_fit(tetha, phi, func, 1.0, tk, pk, coeffs, rs);
|
||||||
|
|
||||||
|
std::cout << "FIT EC = " << ec << "\n";
|
||||||
|
std::cout << "FIT RESI = " << rs << "\n";
|
||||||
|
|
||||||
|
print_func(coeffs, "coeffs");
|
||||||
|
|
||||||
|
// print_func(tetha, "tetha");
|
||||||
|
// print_func(phi, "phi");
|
||||||
|
print_func(tk, "tetha_knots");
|
||||||
|
print_func(func, "func");
|
||||||
|
|
||||||
|
std::cout << "\n\n";
|
||||||
|
|
||||||
|
k = 1;
|
||||||
|
ts = std::numbers::pi / (nt + 1);
|
||||||
|
std::ranges::generate_n(tetha.begin(), nt, std::bind(gen_func, ts, k));
|
||||||
|
|
||||||
|
std::vector<double> f_func;
|
||||||
|
tetha.resize(nt);
|
||||||
|
phi.resize(np);
|
||||||
|
|
||||||
|
ec = mcc::fitpack::fitpack_eval_spl2d(tk, pk, coeffs, tetha, phi, f_func);
|
||||||
|
// ec = mcc::fitpack::fitpack_eval_spl2d(pk, tk, coeffs, phi, tetha, f_func);
|
||||||
|
std::cout << "EVAL EC = " << ec << "\n";
|
||||||
|
print_func(f_func, "func");
|
||||||
|
|
||||||
|
std::cout << "\n\n";
|
||||||
|
|
||||||
|
for (size_t l = 0; l < f_func.size(); ++l) {
|
||||||
|
auto r = f_func[l] - func[l];
|
||||||
|
std::cout << r << " ";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user