14 for (i = 0; i < tensor->
dim0; ++i) {
15 for (j = 0; j < tensor->
dim1; ++j) {
16 for (k = 0; k < tensor->
dim2; ++k) {
26 if (lmmc_tensor3_validate(tensor) !=
LMMC_STATUS_OK || out_norm == NULL) {
30 lmmc_scaled_sumsq_init(&acc);
31 for (
size_t i = 0; i < tensor->
dim0; ++i) {
32 for (
size_t j = 0; j < tensor->
dim1; ++j) {
33 for (
size_t k = 0; k < tensor->
dim2; ++k) {
34 lmmc_scaled_sumsq_add(
43 *out_norm = lmmc_scaled_sumsq_norm(&acc);
48 size_t i = 0, j = 0, k = 0;
49 lmmc_status_t st = lmmc_tensor3_validate_binary(a, b, out_tensor);
58 for (i = 0; i < a->
dim0; ++i) {
59 for (j = 0; j < a->
dim1; ++j) {
60 for (k = 0; k < a->
dim2; ++k) {
63 if (!lmmc_is_finite(va) || !lmmc_is_finite(vb)) {
68 if (!lmmc_is_finite(&vr)) {
81 size_t i = 0, j = 0, k = 0;
82 lmmc_status_t st = lmmc_tensor3_validate_binary(a, b, out_tensor);
91 for (i = 0; i < a->
dim0; ++i) {
92 for (j = 0; j < a->
dim1; ++j) {
93 for (k = 0; k < a->
dim2; ++k) {
96 if (!lmmc_is_finite(va) || !lmmc_is_finite(vb)) {
101 if (!lmmc_is_finite(&vr)) {
114 size_t i = 0, j = 0, k = 0;
115 lmmc_status_t st = lmmc_tensor3_validate_binary(a, b, out_tensor);
124 for (i = 0; i < a->
dim0; ++i) {
125 for (j = 0; j < a->
dim1; ++j) {
126 for (k = 0; k < a->
dim2; ++k) {
129 if (!lmmc_is_finite(va) || !lmmc_is_finite(vb)) {
134 if (!lmmc_is_finite(&vr)) {
147 size_t i = 0, j = 0, k = 0;
148 lmmc_status_t st = lmmc_tensor3_validate_binary(a, b, out_tensor);
160 for (i = 0; i < a->
dim0; ++i) {
161 for (j = 0; j < a->
dim1; ++j) {
162 for (k = 0; k < a->
dim2; ++k) {
165 if (!lmmc_is_finite(va) || !lmmc_is_finite(vb) ||
LMMC_REAL_CMP(vb, &zero) == 0) {
171 if (!lmmc_is_finite(&vr)) {
186 size_t i = 0, j = 0, k = 0;
193 if (!lmmc_tensor3_same_shape(tensor, out_tensor)) {
197 if (!lmmc_is_finite(&alpha)) {
202 for (i = 0; i < tensor->
dim0; ++i) {
203 for (j = 0; j < tensor->
dim1; ++j) {
204 for (k = 0; k < tensor->
dim2; ++k) {
206 if (!lmmc_is_finite(v)) {
211 if (!lmmc_is_finite(&vr)) {
224 size_t i = 0, j = 0, k = 0;
228 if (lmmc_tensor3_validate(tensor) !=
LMMC_STATUS_OK || out_sum == NULL) {
235 for (i = 0; i < tensor->
dim0; ++i) {
236 for (j = 0; j < tensor->
dim1; ++j) {
237 for (k = 0; k < tensor->
dim2; ++k) {
239 if (!lmmc_is_finite(v)) {
246 if (!lmmc_is_finite(&sum)) {
261 size_t i = 0, j = 0, k = 0;
264 if (lmmc_tensor3_validate(tensor) !=
LMMC_STATUS_OK || out_max == NULL) {
269 if (!lmmc_is_finite(&max_v)) {
274 for (i = 0; i < tensor->
dim0; ++i) {
275 for (j = 0; j < tensor->
dim1; ++j) {
276 for (k = 0; k < tensor->
dim2; ++k) {
278 if (!lmmc_is_finite(v)) {
294 size_t i = 0, j = 0, k = 0;
297 if (lmmc_tensor3_validate(tensor) !=
LMMC_STATUS_OK || out_min == NULL) {
302 if (!lmmc_is_finite(&min_v)) {
307 for (i = 0; i < tensor->
dim0; ++i) {
308 for (j = 0; j < tensor->
dim1; ++j) {
309 for (k = 0; k < tensor->
dim2; ++k) {
311 if (!lmmc_is_finite(v)) {
329 !lmmc_mat_descriptor_is_valid(out_matrix)) {
335 const size_t rows = axis == 0 ? tensor->
dim1 : tensor->
dim0;
336 const size_t cols = axis == 2 ? tensor->
dim1 : tensor->
dim2;
337 if (out_matrix->
rows != rows || out_matrix->
cols != cols) {
344 const lmmc_real_t* data,
size_t count,
size_t stride,
347 for (
size_t i = 0; i < count; ++i) {
349 if (!lmmc_is_finite(v)) {
354 if (!lmmc_is_finite(sum)) {
366 lmmc_status_t st = lmmc_tensor3_validate_axis_sum(tensor, axis, out_matrix);
368 const size_t dims[3] = {tensor->
dim0, tensor->
dim1, tensor->
dim2};
370 const size_t row_stride = axis == 0 ? tensor->
stride1 : tensor->
stride0;
371 const size_t col_stride = axis == 2 ? tensor->
stride1 : tensor->
stride2;
372 for (
size_t row = 0; row < out_matrix->
rows; ++row) {
373 for (
size_t col = 0; col < out_matrix->
cols; ++col) {
374 const size_t offset = row * row_stride + col * col_stride;
375 st = lmmc_tensor3_sum_line(
376 &tensor->
data[offset], dims[axis], strides[axis], &sum, &tmp_sum);
#define LMMC_REAL_CLEAR(x)
释放一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_INIT(x)
初始化一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_ADD(res, a, b)
计算 *res = *a + *b 。
#define LMMC_REAL_DIV(res, a, b)
计算 *res = *a / *b 。
#define LMMC_REAL_SUB(res, a, b)
计算 *res = *a - *b 。
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
#define LMMC_REAL_MUL(res, a, b)
计算 *res = *a * *b 。
#define LMMC_REAL_CMP(a, b)
比较 *a 与 *b ,返回 -1/0/1 。
#define LMMC_REAL_SET_D(dst, dbl)
将一个 double 字面量赋值到 lmmc_real_t 。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_INVALID_ARGUMENT
lmmc_status_t lmmc_tensor3_sum(const lmmc_tensor3_t *tensor, lmmc_real_t *out_sum)
累加全部元素。
lmmc_status_t lmmc_tensor3_add(const lmmc_tensor3_t *a, const lmmc_tensor3_t *b, lmmc_tensor3_t *out_tensor)
同形状张量逐元素加法。
lmmc_status_t lmmc_tensor3_sum_axis(const lmmc_tensor3_t *tensor, size_t axis, lmmc_mat_t *out_matrix)
沿指定轴求和,结果为二维矩阵。
lmmc_status_t lmmc_tensor3_min(const lmmc_tensor3_t *tensor, lmmc_real_t *out_min)
求最小元素。
lmmc_status_t lmmc_tensor3_div(const lmmc_tensor3_t *a, const lmmc_tensor3_t *b, lmmc_tensor3_t *out_tensor)
同形状张量逐元素除法,b 中元素须非零。
lmmc_status_t lmmc_tensor3_fill(lmmc_tensor3_t *tensor, lmmc_real_t value)
用 value 填充张量所有元素。
lmmc_status_t lmmc_tensor3_scale(const lmmc_tensor3_t *tensor, lmmc_real_t alpha, lmmc_tensor3_t *out_tensor)
标量乘:out = alpha * tensor。
lmmc_status_t lmmc_tensor3_sub(const lmmc_tensor3_t *a, const lmmc_tensor3_t *b, lmmc_tensor3_t *out_tensor)
同形状张量逐元素减法。
lmmc_status_t lmmc_tensor3_max(const lmmc_tensor3_t *tensor, lmmc_real_t *out_max)
求最大元素。
lmmc_status_t lmmc_tensor3_mul(const lmmc_tensor3_t *a, const lmmc_tensor3_t *b, lmmc_tensor3_t *out_tensor)
同形状张量逐元素乘法(Hadamard)。
lmmc_status_t lmmc_tensor3_norm_fro(const lmmc_tensor3_t *tensor, lmmc_real_t *out_norm)
用缩放平方和计算张量 Frobenius 范数。