88static inline void _sp_nd_order(
int *
const restrict unknown_ids,
const int count,
const int *
const restrict unknown_x,
89 const int *
const restrict unknown_y,
const int reach)
97 _index_range *stack = (_index_range *)malloc(
sizeof(_index_range) * capacity);
99 stack[stack_top++] = (_index_range){ 0, count };
107 const _index_range range = stack[--stack_top];
108 const int length = range.end - range.begin;
109 if(length <= 64)
continue;
111 int xmin = INT_MAX, xmax = INT_MIN, ymin = INT_MAX, ymax = INT_MIN;
112 for(
int i = range.begin;
i < range.end;
i++)
114 const int unknown_id = unknown_ids[
i];
115 xmin =
MIN(xmin, unknown_x[unknown_id]);
116 xmax =
MAX(xmax, unknown_x[unknown_id]);
117 ymin =
MIN(ymin, unknown_y[unknown_id]);
118 ymax =
MAX(ymax, unknown_y[unknown_id]);
121 const int extent_x = xmax - xmin + 1;
122 const int extent_y = ymax - ymin + 1;
123 if(
MAX(extent_x, extent_y) <= 2 * reach + 1)
continue;
127 const int split_on_x = (extent_x >= extent_y);
128 const int *
const coord = split_on_x ? unknown_x : unknown_y;
129 const int cut_position = (split_on_x ? xmin + extent_x / 2 : ymin + extent_y / 2);
135 int left_end = range.begin;
136 int right_end = range.end;
140 const int coord_value = coord[unknown_ids[
i]];
141 if(coord_value < cut_position)
143 const int swap_id = unknown_ids[
i];
144 unknown_ids[
i] = unknown_ids[left_end];
145 unknown_ids[left_end] = swap_id;
149 else if(coord_value >= cut_position + reach)
156 const int swap_id = unknown_ids[
i];
157 unknown_ids[
i] = unknown_ids[right_end];
158 unknown_ids[right_end] = swap_id;
163 if(left_end == range.begin && right_end == range.end)
continue;
164 if(stack_top + 2 > capacity)
167 _index_range *grown = (_index_range *)realloc(stack,
sizeof(_index_range) * capacity);
171 if(left_end - range.begin > 64) stack[stack_top++] = (_index_range){ range.begin, left_end };
172 if(right_end - left_end > 64) stack[stack_top++] = (_index_range){ left_end, right_end };
271 const int *
const restrict matrix_row_index,
272 const double *
const restrict matrix_values,
const int cache_id)
298 const int reach_top =
_sp_ereach(
dimension, matrix_col_ptr, matrix_row_index,
k, parent, elim_stack, mark);
299 for(
int reach_pos = reach_top; reach_pos <
dimension; reach_pos++) col_count[elim_stack[reach_pos]]++;
317 col_fill[
i] =
factor->col_ptr[
i] + 1;
329 const int reach_top =
_sp_ereach(
dimension, matrix_col_ptr, matrix_row_index,
k, parent, elim_stack, mark);
333 for(
int entry = matrix_col_ptr[
k]; entry < matrix_col_ptr[
k + 1]; entry++)
335 const int i = matrix_row_index[entry];
337 work[
i] = matrix_values[entry];
339 pivot = matrix_values[entry];
341 for(
int reach_pos = reach_top; reach_pos <
dimension; reach_pos++)
343 const int j = elim_stack[reach_pos];
347 const double multiplier = work[j] /
factor->values[
factor->col_ptr[j]];
351 for(
int entry =
factor->col_ptr[j] + 1; entry < col_fill[j]; entry++)
352 work[
factor->row_index[entry]] -=
factor->values[entry] * multiplier;
353 pivot -= multiplier * multiplier;
355 const int slot = col_fill[j]++;
357 factor->values[slot] = multiplier;
359 if(!(pivot > 0.0))
goto fail;
static int _sp_ereach(const int dimension, const int *const restrict col_ptr, const int *const restrict row_index, const int k, const int *const restrict parent, int *const restrict pattern_stack, int *const restrict mark)
static void _sp_nd_order(int *const restrict unknown_ids, const int count, const int *const restrict unknown_x, const int *const restrict unknown_y, const int reach)
static _sp_chol_t * _sp_chol_factor(const int dimension, const int *const restrict matrix_col_ptr, const int *const restrict matrix_row_index, const double *const restrict matrix_values, const int cache_id)
static void _sp_etree(const int dimension, const int *const restrict col_ptr, const int *const restrict row_index, int *const restrict parent, int *const restrict ancestor)