5#include <batmat/dtypes.hpp>
6#include <batmat/linalg/gemm.hpp>
7#include <batmat/linalg/gemv.hpp>
8#include <batmat/linalg/potrf.hpp>
9#include <batmat/linalg/shift.hpp>
10#include <batmat/linalg/symv.hpp>
11#include <batmat/linalg/syomv.hpp>
12#include <batmat/linalg/trsm.hpp>
13#include <guanaqo/print.hpp>
20using namespace batmat::linalg;
21using namespace cyqlone::linalg;
23[[nodiscard]]
constexpr index_t
get_depth(index_t n) {
24 return static_cast<index_t
>(std::bit_width(
static_cast<std::make_unsigned_t<index_t>
>(n) - 1));
28template <index_t VL,
class T, StorageOrder DefaultOrder>
31 using vl_t = std::integral_constant<index_t, VL>;
32 using align_t = std::integral_constant<index_t, VL *
alignof(T)>;
33 static constexpr index_t
v = VL;
36 template <StorageOrder O = DefaultOrder>
38 template <StorageOrder O = DefaultOrder>
40 template <StorageOrder O = DefaultOrder>
42 template <StorageOrder O = DefaultOrder>
54 [&]<index_t... Levels>(std::integer_sequence<index_t, Levels...>) {
56 }(std::make_integer_sequence<index_t, lv>{});
57 auto M =
lv == 0 ? M0 :
pcr_M.batch(0);
64 static constexpr auto r = 1 << l;
65 auto M = l == 0 ? M0 :
pcr_M.batch(0), K = l == 0 ? K0 :
pcr_Y.batch(l);
67 auto M_next =
pcr_M.batch(0);
69 if constexpr (l + 1 <
lv) {
70 auto K_next =
pcr_Y.batch(l + 1);
78 add(U, K.transposed());
86 [&]<index_t... Levels>(std::integer_sequence<index_t, Levels...>) {
88 }(std::make_integer_sequence<index_t, lv>{});
95 static constexpr auto r = 1 << l;
98 if constexpr (l + 1 <
lv)
105auto λ_max_power(
const Mat &M,
const Mat &K,
int max_it,
typename Mat::value_type tol) {
108 using T =
typename Mat::value_type;
110 typename Mat::batch_size_type,
typename Mat::depth_type>
111 x{{.rows = M.rows(), .cols = 1}}, Ax{{.rows = M.rows(), .cols = 1}};
115 for (k = 0; k < max_it; ++k) {
118 λ_old = std::exchange(λ,
dot(x, Ax));
120 scale(T(1) / norm, Ax, x);
121 if (abs(λ - λ_old) < tol * abs(λ))
124 return std::make_pair(λ, k + 1);
141 using T = batmat::real_t;
143 static_assert(N > 1,
"No suitable vector length available");
145 constexpr index_t n = 15;
153 std::mt19937 rng(12345);
154 std::uniform_real_distribution<T> dist(-1, 1);
155 std::ranges::generate(A, [&] {
return dist(rng); });
156 std::ranges::generate(B, [&] {
return dist(rng); });
157 std::ranges::generate(b, [&] {
return dist(rng); });
166 solver.factor_pcr(M, K);
178 constexpr auto ε = std::numeric_limits<T>::epsilon();
179 const int max_it = 100 * N * n;
182 << (it <= max_it ?
"" :
"approx., ") << it <<
" iter.)\n";
184 const auto η = res_norm.norm_2() / (normM *
norm_2(x) +
norm_2(b));
187#if CYQLONE_WITH_MATIO
189 std::filesystem::path filename =
"test-pcr.mat";
197 std::cout <<
"Saved system and solution to " << filename <<
"\n";
200 return η < ε * static_cast<T>(100 * n * N) ? 0 : 1;
std::string float_to_str(F value, int precision)
void syrk_sub(VA &&A, Structured< VC, SD > C, Structured< VD, SD > D, Opts... opts)
void syomv(Structured< VA, SA > A, VB &&B, VD &&D)
void trsm(Structured< VA, SA > A, VB &&B, VD &&D, with_rotate_B_t< RotB >={})
void gemm_neg(VA &&A, VB &&B, VD &&D, TilingOptions packing={}, Opts... opts)
void unpack(VA &&A, VB &&B)
Copy a compact batch of matrices A to multiple scalar matrices B.
void gemm(VA &&A, VB &&B, VD &&D, TilingOptions packing={}, Opts... opts)
void syrk(Structured< VA, SA > A, Structured< VD, SD > D, Opts... opts)
norms< simdified_value_t< Vx > >::result norms_all(Vx &&x)
Compute the norms (max, 1-norm, and 2-norm) of a vector.
void add(VA &&A, VB &&B, VC &&C, with_rotate_t< Rotate >={})
Add two matrices or vectors C = A + B. Rotate affects B.
void symv_add(Structured< VA, SA > A, VB &&B, VC &&C, VD &&D)
void negate(VA &&A, VB &&B, with_rotate_t< Rotate >={})
Negate a matrix or vector B = -A.
void syrk_add(VA &&A, Structured< VC, SD > C, Structured< VD, SD > D, Opts... opts)
void copy(VA &&A, VB &&B, Opts... opts)
void potrf(Structured< VC, SC > C, Structured< VD, SC > D, simdified_value_t< VC > regularization=0)
simdified_value_t< Vx > dot(Vx &&x, Vy &&y)
Compute the dot product of two vectors.
void gemv_sub(VA &&A, VB &&B, VC &&C, VD &&D, Opts... opts)
simdified_value_t< Vx > norm_2(Vx &&x)
Compute the 2-norm of a vector.
void scale(T alpha, Vx &&x, Vz &&z)
Multiply a vector by a scalar z = αx.
void symv(Structured< VA, SA > A, VB &&B, VD &&D)
constexpr auto triu(M &&m)
constexpr auto tril(M &&m)
MatFilePtr create_mat(const std::filesystem::path &filename)
Create and open a new .mat file for writing.
void add_to_mat(mat_t *mat, const std::string &varname, float value)
Add a value to an open .mat file.
Functions for exporting and loading matrices and OCP data to and from .mat files.
constexpr with_rotate_D_t< I > with_rotate_D
constexpr with_rotate_t< I > with_rotate
simd_view_types< std::remove_const_t< T >, Abi >::template matrix< T, Order > matrix
constexpr with_rotate_C_t< I > with_rotate_C
constexpr with_rotate_A_t< I > with_rotate_A
constexpr index_t vl_or_largest
auto λ_max_power(const Mat &M, const Mat &K, int max_it, typename Mat::value_type tol)
constexpr index_t get_depth(index_t n)
auto unpacked(const M &matrix)
void add_to_diagonal(const value_type &t)
View< T, I, S, D, DefaultStride, O > view_type
void set_constant(value_type t)
typename view_type::const_view_type const_view_type
std::integral_constant< index_t, VL > vl_t
batmat::matrix::Matrix< value_type, index_t, vl_t, index_t, O, align_t > bmatrix
matrix< O >::const_view_type view
void factor_pcr_level(view<> M0, view<> K0)
std::integral_constant< index_t, VL *alignof(T)> align_t
void factor_pcr(view<> M0, view<> K0)
void solve_pcr(mut_view<> λ)
matrix< O >::view_type mut_view
batmat::matrix::Matrix< value_type, index_t, vl_t, vl_t, O, align_t > matrix
void solve_pcr_level(mut_view<> λ, mut_view<> work_pcr) const
static constexpr index_t lv
static constexpr index_t v
void solve_pcr(mut_view<> λ, mut_view<> work_pcr) const
batmat::matrix::Matrix< value_type, index_t, vl_t, index_t, O, align_t > matrix