LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
precond_row.c
浏览该文件的文档.
1#include "precond_internal.h"
2
3lmmc_status_t lmmc_ilu_row_bytes(size_t n, size_t fill, size_t* bytes) {
4 size_t values, indices, marks;
5 if (!lmmc_safe_mul_size(n, sizeof(lmmc_real_t), &values) ||
6 !lmmc_safe_mul_size(fill, 2, &indices)) {
8 }
9 if (!lmmc_safe_add_size(indices, n, &indices) ||
10 !lmmc_safe_mul_size(indices, sizeof(size_t), &indices)) {
12 }
13 if (!lmmc_safe_mul_size(n, 2, &marks)) {
15 }
16 const size_t alignment = _Alignof(size_t);
17 size_t padding = (alignment - values % alignment) % alignment;
18 if (!lmmc_safe_add_size(values, padding, &values) ||
19 !lmmc_safe_add_size(values, indices, bytes)) {
21 }
22 if (!lmmc_safe_add_size(*bytes, marks, bytes)) {
24 }
25 return LMMC_STATUS_OK;
26}
27
28lmmc_status_t lmmc_ilu_row_create(size_t n, size_t fill, size_t bytes,
29 lmmc_ilu_row_t* row) {
30 row->values = lmmc_memory_alloc(bytes);
31 if (row->values == NULL) {
33 }
34 memset(row->values, 0, bytes);
35 size_t values = n * sizeof(lmmc_real_t);
36 const size_t alignment = _Alignof(size_t);
37 values += (alignment - values % alignment) % alignment;
38 row->active = (size_t*)((unsigned char*)row->values + values);
39 row->lower = row->active + n;
40 row->upper = row->lower + fill;
41 row->present = (unsigned char*)(row->upper + fill);
42 row->processed = row->present + n;
43 row->count = 0;
44 return LMMC_STATUS_OK;
45}
46
48 for (size_t p = 0; p < row->count; ++p) {
49 size_t col = row->active[p];
50 row->present[col] = 0;
51 row->processed[col] = 0;
52 row->values[col] = 0.0;
53 }
54 row->count = 0;
55}
56
57static void lmmc_ilu_sort_columns(size_t* values, size_t count) {
58 for (size_t i = 1; i < count; ++i) {
59 size_t key = values[i];
60 size_t j = i;
61 while (j > 0 && values[j - 1] > key) {
62 values[j] = values[j - 1];
63 --j;
64 }
65 values[j] = key;
66 }
67}
68
69static size_t lmmc_ilu_smallest_entry(const lmmc_real_t* values,
70 const size_t* cols, size_t count) {
71 size_t minimum = 0;
72 lmmc_real_t minimum_abs = fabs(values[cols[0]]);
73 for (size_t i = 1; i < count; ++i) {
74 lmmc_real_t magnitude = fabs(values[cols[i]]);
75 if (magnitude < minimum_abs) {
76 minimum_abs = magnitude;
77 minimum = i;
78 }
79 }
80 return minimum;
81}
82
83void lmmc_ilu_select(const lmmc_ilu_row_t* row, size_t i, int lower,
84 lmmc_real_t drop_tol, size_t max_keep, size_t* cols, size_t* count) {
85 size_t selected = 0;
86 for (size_t p = 0; p < row->count; ++p) {
87 size_t col = row->active[p];
88 if (!row->present[col]) {
89 continue;
90 }
91 if (lower ? col >= i : col <= i) {
92 continue;
93 }
94 lmmc_real_t magnitude = fabs(row->values[col]);
95 if (magnitude <= drop_tol) {
96 continue;
97 }
98 if (selected < max_keep) {
99 cols[selected++] = col;
100 }
101 else {
102 size_t minimum = lmmc_ilu_smallest_entry(row->values, cols, selected);
103 if (magnitude > fabs(row->values[cols[minimum]])) {
104 cols[minimum] = col;
105 }
106 }
107 }
108 lmmc_ilu_sort_columns(cols, selected);
109 *count = selected;
110}
double lmmc_real_t
Public and internal LMMC real type.
void * lmmc_memory_alloc(size_t size)
lmmc_status_t lmmc_ilu_row_create(size_t n, size_t fill, size_t bytes, lmmc_ilu_row_t *row)
unsigned char * processed
lmmc_status_t lmmc_ilu_row_bytes(size_t n, size_t fill, size_t *bytes)
void lmmc_ilu_select(const lmmc_ilu_row_t *row, size_t i, int lower, lmmc_real_t drop_tol, size_t max_keep, size_t *cols, size_t *count)
unsigned char * present
void lmmc_ilu_row_reset(lmmc_ilu_row_t *row)
行工作区仅分配一次,以下指针均借用该内存。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT