#include <inttypes.h>
#include <stdlib.h>
#include "klu.h"
#include "constants.h"
struct InterfaceComplexKLU {
klu_common common;
klu_symbolic *symbolic;
klu_numeric *numeric;
C_BOOL initialization_completed;
C_BOOL factorization_completed;
};
struct InterfaceComplexKLU *complex_solver_klu_new() {
struct InterfaceComplexKLU *solver = (struct InterfaceComplexKLU *)malloc(sizeof(struct InterfaceComplexKLU));
if (solver == NULL) {
return NULL;
}
solver->symbolic = NULL;
solver->numeric = NULL;
solver->initialization_completed = C_FALSE;
solver->factorization_completed = C_FALSE;
return solver;
}
void complex_solver_klu_drop(struct InterfaceComplexKLU *solver) {
if (solver == NULL) {
return;
}
if (solver->symbolic != NULL) {
klu_free_symbolic(&solver->symbolic, &solver->common);
free(solver->symbolic);
}
if (solver->numeric != NULL) {
klu_free_numeric(&solver->numeric, &solver->common);
free(solver->numeric);
}
free(solver);
}
int32_t complex_solver_klu_initialize(struct InterfaceComplexKLU *solver,
int32_t ordering,
int32_t scaling,
int32_t ndim,
const int32_t *col_pointers,
const int32_t *row_indices) {
if (solver == NULL) {
return ERROR_NULL_POINTER;
}
if (solver->initialization_completed == C_TRUE) {
return ERROR_ALREADY_INITIALIZED;
}
klu_defaults(&solver->common);
if (ordering >= 0) {
solver->common.ordering = ordering;
}
if (scaling >= 0) {
solver->common.scale = scaling;
}
solver->symbolic = klu_analyze(ndim,
(int32_t *)col_pointers,
(int32_t *)row_indices,
&solver->common);
if (solver->symbolic == NULL) {
return KLU_ERROR_ANALYZE;
}
solver->initialization_completed = C_TRUE;
return SUCCESSFUL_EXIT;
}
int32_t complex_solver_klu_factorize(struct InterfaceComplexKLU *solver,
int32_t *effective_ordering,
int32_t *effective_scaling,
double *cond_estimate,
C_BOOL compute_cond,
const int32_t *col_pointers,
const int32_t *row_indices,
const COMPLEX64 *values) {
if (solver == NULL) {
return ERROR_NULL_POINTER;
}
if (solver->initialization_completed == C_FALSE) {
return ERROR_NEED_INITIALIZATION;
}
if (solver->factorization_completed == C_TRUE) {
klu_free_numeric(&solver->numeric, &solver->common);
solver->numeric = NULL;
}
solver->numeric = klu_z_factor((int32_t *)col_pointers,
(int32_t *)row_indices,
(COMPLEX64 *)values,
solver->symbolic,
&solver->common);
if (solver->numeric == NULL) {
return KLU_ERROR_FACTOR;
}
*effective_ordering = solver->common.ordering;
*effective_scaling = solver->common.scale;
if (compute_cond == C_TRUE) {
int status = klu_z_condest((int32_t *)col_pointers,
(COMPLEX64 *)values,
solver->symbolic,
solver->numeric,
&solver->common);
if (status == C_FALSE) {
return KLU_ERROR_COND_EST;
}
*cond_estimate = solver->common.condest;
}
solver->factorization_completed = C_TRUE;
return SUCCESSFUL_EXIT;
}
int32_t complex_solver_klu_solve(struct InterfaceComplexKLU *solver,
int32_t ndim,
COMPLEX64 *in_rhs_out_x) {
if (solver == NULL) {
return ERROR_NULL_POINTER;
}
if (solver->factorization_completed == C_FALSE) {
return ERROR_NEED_FACTORIZATION;
}
klu_z_solve(solver->symbolic,
solver->numeric,
ndim,
1,
in_rhs_out_x,
&solver->common);
return SUCCESSFUL_EXIT;
}