Files
cKit/Foundation/c_Matrix.c
T

353 lines
14 KiB
C
Raw Normal View History

2026-08-29 01:50:50 +08:00
#include <c_Matrix.h>
2026-08-30 01:48:03 +08:00
c_err_t c_Matrix_Init(c_Matrix_t* self, c_size_t rows, c_size_t cols, c_size_t item_size, c_Allocator_t* allocator) {
if (!self || rows == 0 || cols == 0 || item_size == 0) return C_ERR_PARAM;
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
// 防止 rows * cols * item_size 发生整型乘法回绕引发的堆踩踏
if (rows > (c_size_t)-1 / (cols * item_size)) return C_ERR_OUTOFBOUND;
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
self->allocator = (allocator != NULL) ? *allocator : c_DefaultAllocator;
2026-08-29 01:50:50 +08:00
self->rows = rows;
self->cols = cols;
2026-08-30 01:48:03 +08:00
self->item_size = item_size;
// 一次性开辟完美的连续空间
c_size_t total_bytes = self->rows * self->cols * self->item_size;
self->data = c_Allocator_Alloc(&self->allocator, total_bytes);
if (!self->data) return C_ERR_NOMEM;
// 默认执行物理抹零清洁
memset(self->data, 0, total_bytes);
return C_ERR_OK;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
// 物理销毁
2026-08-29 01:50:50 +08:00
void c_Matrix_Destroy(c_Matrix_t* self) {
2026-08-30 01:48:03 +08:00
if (!self) return;
if (self->data) {
c_Allocator_Free(&self->allocator, self->data);
self->data = NULL;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
self->rows = 0;
self->cols = 0;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
// 定点安全写入 (值深度复制)
c_err_t c_Matrix_Write(c_Matrix_t* self, c_size_t r, c_size_t c, const void* item) {
if (!self || !item || r >= self->rows || c >= self->cols) return C_ERR_PARAM;
// 行优先扁平化寻址计算
c_size_t index = r * self->cols + c;
char* target = (char*)self->data + (index * self->item_size);
memcpy(target, item, self->item_size);
return C_ERR_OK;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
// 定点安全读取 (安全拷贝副本)
c_err_t c_Matrix_Read(const c_Matrix_t* self, c_size_t r, c_size_t c, void* out_item) {
if (!self || !out_item || r >= self->rows || c >= self->cols) return C_ERR_PARAM;
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
c_size_t index = r * self->cols + c;
const char* source = (const char*)self->data + (index * self->item_size);
memcpy(out_item, source, self->item_size);
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
return C_ERR_OK;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
// 只读原位窥探指针 (由于是固定一维连续空间,只要不销毁,此指针极其平稳安全)
void* c_Matrix_Get(const c_Matrix_t* self, c_size_t r, c_size_t c) {
if (!self || r >= self->rows || c >= self->cols) return NULL;
c_size_t index = r * self->cols + c;
return (char*)self->data + (index * self->item_size);
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
// 批量全局抹值填充
c_err_t c_Matrix_Fill(c_Matrix_t* self, const void* item) {
if (!self || !item) return C_ERR_PARAM;
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
c_size_t total_elements = self->rows * self->cols;
char* target = (char*)self->data;
for (c_size_t i = 0; i < total_elements; i++) {
memcpy(target, item, self->item_size);
target += self->item_size;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
return C_ERR_OK;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
// 极致高速的一整行搬迁导出接口 (常用于图像处理的一行扫描线批量搬运)
c_err_t c_Matrix_CopyRow(const c_Matrix_t* self, c_size_t r, void* out_row_buffer) {
if (!self || !out_row_buffer || r >= self->rows) return C_ERR_PARAM;
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
// 因为行优先存储,整行的数据在物理上是 100% 绝对连续的一条线
// 我们可以直接通过一次 memcpy 瞬时打包带走一整行,效率达到硬件总线传输极限
const char* row_start = (const char*)self->data + (r * self->cols * self->item_size);
size_t row_bytes = self->cols * self->item_size;
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
memcpy(out_row_buffer, row_start, row_bytes);
return C_ERR_OK;
2026-08-29 01:50:50 +08:00
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
2026-08-30 01:48:03 +08:00
// 辅助寻址内部宏
#define MAT_ELEMENT(mat, idx) ((char*)(mat)->data + ((idx) * (mat)->item_size))
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
/**
* @brief 逐元素(Element-wise)矩阵运算通用驱动函数(内部私有)
*/
static c_err_t c_Matrix_ElementWiseCore(c_Matrix_t* out, const c_Matrix_t* lhs, const c_Matrix_t* rhs,
c_Matrix_OpFn_t op, void* ud) {
if (!out || !lhs || !rhs || !op) return C_ERR_PARAM;
// 强御安全校验:矩阵运算要求维度必须完全空间对齐一致
if (lhs->rows != rhs->rows || lhs->cols != rhs->cols ||
lhs->rows != out->rows || lhs->cols != out->cols ||
lhs->item_size != rhs->item_size || lhs->item_size != out->item_size) {
return C_ERR_OUTOFBOUND;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
c_size_t total_elements = lhs->rows * lhs->cols;
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
// 【工业级内核性能极致拉平】:直接抛弃二维坐标计算,用一维指针流极速推进
2026-08-29 01:50:50 +08:00
for (c_size_t i = 0; i < total_elements; i++) {
2026-08-30 01:48:03 +08:00
void* out_ptr = MAT_ELEMENT(out, i);
const void* lhs_ptr = MAT_ELEMENT(lhs, i);
const void* rhs_ptr = MAT_ELEMENT(rhs, i);
op(out_ptr, lhs_ptr, rhs_ptr, ud); // 驱动具体类型算子
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
return C_ERR_OK;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
c_err_t c_Matrix_Add(c_Matrix_t* out, const c_Matrix_t* lhs, const c_Matrix_t* rhs, c_Matrix_OpFn_t add_op, void* ud) {
return c_Matrix_ElementWiseCore(out, lhs, rhs, add_op, ud);
}
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
c_err_t c_Matrix_Sub(c_Matrix_t* out, const c_Matrix_t* lhs, const c_Matrix_t* rhs, c_Matrix_OpFn_t sub_op, void* ud) {
return c_Matrix_ElementWiseCore(out, lhs, rhs, sub_op, ud);
}
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
c_err_t c_Matrix_Div(c_Matrix_t* out, const c_Matrix_t* lhs, const c_Matrix_t* rhs, c_Matrix_OpFn_t div_op, void* ud) {
return c_Matrix_ElementWiseCore(out, lhs, rhs, div_op, ud);
}
/**
* @brief 经典线性代数标准矩阵乘法 (Matrix Multiplication: O(N^3))
* @note 满足拓扑条件:lhs(M x K) * rhs(K x N) = out(M x N)
*/
c_err_t c_Matrix_Mul(c_Matrix_t* out, const c_Matrix_t* lhs, const c_Matrix_t* rhs,
c_Matrix_OpFn_t mul_op, c_Matrix_OpFn_t add_op, void* ud) {
if (!out || !lhs || !rhs || !mul_op || !add_op) return C_ERR_PARAM;
// 拓扑几何边界校验
if (lhs->cols != rhs->rows || out->rows != lhs->rows || out->cols != rhs->cols ||
lhs->item_size != rhs->item_size || lhs->item_size != out->item_size) {
return C_ERR_OUTOFBOUND;
}
c_size_t M = lhs->rows;
c_size_t K = lhs->cols;
c_size_t N = rhs->cols;
// 分配一个栈上的临时缓冲区,用来暂存单次乘法的中间值(避免频繁分配堆内存导致碎片)
// 由于是泛型,大小通过 item_size 动态抹平
void* temp_mul_res = c_Allocator_Alloc(&out->allocator, out->item_size);
if (!temp_mul_res) return C_ERR_NOMEM;
for (c_size_t i = 0; i < M; i++) {
for (c_size_t j = 0; j < N; j++) {
void* out_cell = (char*)out->data + ((i * N + j) * out->item_size);
// 每次计算新格子前,首先执行干净的物理抹零(清空历史残存值)
memset(out_cell, 0, out->item_size);
for (c_size_t k = 0; k < K; k++) {
const void* lhs_cell = (char*)lhs->data + ((i * K + k) * lhs->item_size);
const void* rhs_cell = (char*)rhs->data + ((k * N + j) * rhs->item_size);
// 1. 计算当前权重的乘积:temp_mul_res = lhs_cell * rhs_cell
mul_op(temp_mul_res, lhs_cell, rhs_cell, ud);
// 2. 累加到目标格子中:out_cell = out_cell + temp_mul_res
add_op(out_cell, out_cell, temp_mul_res, ud);
}
}
}
c_Allocator_Free(&out->allocator, temp_mul_res);
return C_ERR_OK;
}
/**
* @brief 标量运算通用驱动核心(内部私有)
*/
2026-08-30 01:50:36 +08:00
C_STATIC_FORCE_INLINE
c_err_t c_Matrix_ScalarCore(c_Matrix_t* out, const c_Matrix_t* in, const void* scalar,
2026-08-30 01:48:03 +08:00
c_Matrix_OpFn_t op, void* ud) {
if (!out || !in || !scalar || !op) return C_ERR_PARAM;
if (in->rows != out->rows || in->cols != out->cols || in->item_size != out->item_size) {
return C_ERR_OUTOFBOUND;
}
c_size_t total_elements = in->rows * in->cols;
for (c_size_t i = 0; i < total_elements; i++) {
void* out_ptr = MAT_ELEMENT(out, i);
const void* in_ptr = MAT_ELEMENT(in, i);
op(out_ptr, in_ptr, scalar, ud); // 驱动单元素与标量运算
}
return C_ERR_OK;
}
c_err_t c_Matrix_AddScalar(c_Matrix_t* out, const c_Matrix_t* in, const void* scalar, c_Matrix_OpFn_t add_op, void* ud) {
return c_Matrix_ScalarCore(out, in, scalar, add_op, ud);
}
c_err_t c_Matrix_SubScalar(c_Matrix_t* out, const c_Matrix_t* in, const void* scalar, c_Matrix_OpFn_t sub_op, void* ud) {
return c_Matrix_ScalarCore(out, in, scalar, sub_op, ud);
}
c_err_t c_Matrix_MulScalar(c_Matrix_t* out, const c_Matrix_t* in, const void* scalar, c_Matrix_OpFn_t mul_op, void* ud) {
return c_Matrix_ScalarCore(out, in, scalar, mul_op, ud);
}
c_err_t c_Matrix_DivScalar(c_Matrix_t* out, const c_Matrix_t* in, const void* scalar, c_Matrix_OpFn_t div_op, void* ud) {
return c_Matrix_ScalarCore(out, in, scalar, div_op, ud);
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
// 矩阵转置实现 (M x N -> N x M)
c_err_t c_Matrix_Transpose(c_Matrix_t* out, const c_Matrix_t* in) {
if (!out || !in || !out->data || !in->data) return C_ERR_PARAM;
// 空间几何拓扑强校验
if (out->rows != in->cols || out->cols != in->rows || out->item_size != in->item_size) {
return C_ERR_OUTOFBOUND;
}
c_size_t r_max = in->rows;
c_size_t c_max = in->cols;
c_size_t item_sz = in->item_size;
// 行优先数据错位映射搬运:in(r, c) -> out(c, r)
for (c_size_t r = 0; r < r_max; r++) {
for (c_size_t c = 0; c < c_max; c++) {
const char* src_cell = (const char*)in->data + ((r * c_max + c) * item_sz);
char* dst_cell = (char*)out->data + ((c * r_max + r) * item_sz);
memcpy(dst_cell, src_cell, item_sz); // 泛型值原装迁徙
}
}
return C_ERR_OK;
}
/**
* @brief 内部私有递归核心:拉普拉斯代数余子式展开
*/
static void c_Matrix_DetInternal(c_Matrix_t* mat, void* out_det,
c_Matrix_OpFn_t add_op, c_Matrix_OpFn_t sub_op,
c_Matrix_OpFn_t mul_op, c_Matrix_NegFn_t neg_op,
void* ud) {
c_size_t n = mat->rows;
c_size_t item_sz = mat->item_size;
// 基本边界 1: 1x1 方阵,行列式值即为其唯一的单体元素本身
2026-08-29 01:50:50 +08:00
if (n == 1) {
2026-08-30 01:48:03 +08:00
memcpy(out_det, mat->data, item_sz);
return;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
// 基本边界 2: 2x2 方阵,计算 ad - bc 快速通路,消除不必要的低层递归
if (n == 2) {
char* a = (char*)mat->data + (0 * item_sz);
char* b = (char*)mat->data + (1 * item_sz);
char* c = (char*)mat->data + (2 * item_sz);
char* d = (char*)mat->data + (3 * item_sz);
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
// 分配栈上局部存储,避开堆碎片
void* ad = c_Allocator_Alloc(&mat->allocator, item_sz);
void* bc = c_Allocator_Alloc(&mat->allocator, item_sz);
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
mul_op(ad, a, d, ud); // a * d
mul_op(bc, b, c, ud); // b * c
sub_op(out_det, ad, bc, ud); // ad - bc
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
c_Allocator_Free(&mat->allocator, ad);
c_Allocator_Free(&mat->allocator, bc);
return;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
// 递归分支: n > 2,固定沿第 0 行进行展开
memset(out_det, 0, item_sz); // 抹零累加器
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
// 原地创建子方阵控制头 (大小为 n-1)
c_Matrix_t sub_mat;
sub_mat.allocator = mat->allocator;
sub_mat.rows = n - 1;
sub_mat.cols = n - 1;
sub_mat.item_size = item_sz;
c_size_t sub_bytes = sub_mat.rows * sub_mat.cols * item_sz;
sub_mat.data = c_Allocator_Alloc(&mat->allocator, sub_bytes);
if (!sub_mat.data) return;
void* sub_det = c_Allocator_Alloc(&mat->allocator, item_sz);
void* term = c_Allocator_Alloc(&mat->allocator, item_sz);
void* neg_term = c_Allocator_Alloc(&mat->allocator, item_sz);
// 遍历第 0 行的每一列 c
for (c_size_t c = 0; c < n; c++) {
// 构建割裂后的代数余子式子方阵数据块
c_size_t sub_r = 0;
for (c_size_t r = 1; r < n; r++) { // 跳过第 0 行
c_size_t sub_c = 0;
for (c_size_t j = 0; j < n; j++) {
if (j == c) continue; // 跳过当前列
const char* src = (const char*)mat->data + ((r * n + j) * item_sz);
char* dst = (char*)sub_mat.data + ((sub_r * (n - 1) + sub_c) * item_sz);
memcpy(dst, src, item_sz);
sub_c++;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
sub_r++;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
// 递归求解子方阵的行列式
c_Matrix_DetInternal(&sub_mat, sub_det, add_op, sub_op, mul_op, neg_op, ud);
// 计算当前项的系数乘积 term = mat(0, c) * sub_det
const void* current_element = (const char*)mat->data + (c * item_sz);
mul_op(term, current_element, sub_det, ud);
// 根据棋盘格正负号规则 ((-1)^(r+c)):当前第 0 行第 c 列,当 c 为奇数时取反
if (c % 2 == 1) {
neg_op(neg_term, term, ud); // 取负号
add_op(out_det, out_det, neg_term, ud); // 累加负项
} else {
add_op(out_det, out_det, term, ud); // 累加正项
2026-08-29 01:50:50 +08:00
}
}
2026-08-30 01:48:03 +08:00
// 异常安全性层级强力物理释放,绝不产生多级残留
c_Allocator_Free(&mat->allocator, sub_mat.data);
c_Allocator_Free(&mat->allocator, sub_det);
c_Allocator_Free(&mat->allocator, term);
c_Allocator_Free(&mat->allocator, neg_term);
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
// 行列式主驱动包装接口
c_err_t c_Matrix_Determinant(c_Matrix_t* self, void* out_det,
c_Matrix_OpFn_t add_op, c_Matrix_OpFn_t sub_op,
c_Matrix_OpFn_t mul_op, c_Matrix_NegFn_t neg_op,
void* ud) {
if (!self || !out_det || !add_op || !sub_op || !mul_op || !neg_op) return C_ERR_PARAM;
2026-08-29 01:50:50 +08:00
2026-08-30 01:48:03 +08:00
// 强行约束约束:只有正方矩阵具备行列式
if (self->rows != self->cols || self->rows == 0) {
return C_ERR_OUTOFBOUND;
2026-08-29 01:50:50 +08:00
}
2026-08-30 01:48:03 +08:00
c_Matrix_DetInternal(self, out_det, add_op, sub_op, mul_op, neg_op, ud);
return C_ERR_OK;
2026-08-29 01:50:50 +08:00
}