diff --git a/CMakeLists.txt b/CMakeLists.txt index 0584fd8..8649b1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,21 @@ LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/configure/cmake) # Export compilation commands for IDEs and autocompletion set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +# Options +# ---------------------------------------------- +# Use floats instead of doubles +option (DFLOAT "Use float numbers instead of doubles" OFF) +message(STATUS "Floats are ${DFLOAT}") + +# Use long integers for indexing +option (DLONG "Use long integers (64bit) for indexing" ON) +if (NOT (CMAKE_SIZEOF_VOID_P EQUAL 8)) + message(STATUS "Disabling long integers (64bit) on 32bit machine") + set(DLONG OFF) +endif() +message(STATUS "Long integers (64bit) are ${DLONG}") + + # Set Compiler flags # ---------------------------------------------- set(CMAKE_POSITION_INDEPENDENT_CODE ON) # -fPIC @@ -33,6 +48,13 @@ if (NOT MSVC) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g") endif (NOT MSVC) +# Generate header file with the global options +# --------------------------------------------- +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure/qdldl_configure.h.in + ${CMAKE_CURRENT_SOURCE_DIR}/include/qdldl_configure.h + NEWLINE_STYLE LF) + + # Set sources # ---------------------------------------------- set( diff --git a/README.md b/README.md index d5eea9d..5ef03cf 100644 --- a/README.md +++ b/README.md @@ -39,19 +39,6 @@ To install (uninstall) the libraries and headers you can simply run `make instal ## Calling QDLDL -### Including the header -QDLDL uses its own default internal types for integers, floats and booleans. If you want to override these types with your own you must first define them explicitly before including the library -```c -typedef mybool QDLDL_bool; -typedef myint QDLDL_int; -typedef myfloat QDLDL_float; - -/* Then define this symbol to prevent type redefinitions */ -#define QDLDL_TYPES_DEFINED - -#include "qdldl.h" -``` - ### Main API The QDLDL API consists of 5 functions documented in [`include/qdldl.h`](./include/qdldl.h). @@ -73,6 +60,14 @@ The matrices `D` and `Dinv` are both diagonal matrices, with the diagonal values The matrix input `A` should be quasidefinite. The API provides some (non-comprehensive) error checking to protect against non-quasidefinite or non-upper triangular inputs. +### Custom types for integer, floats and booleans +QDLDL uses its own internal types for integers, floats and booleans (`QDLDL_int, QDLDL_float, QDLDL_bool`. They can be specified using the cmake options: + +- `DFLOAT` (default false): uses float numbers instead of doubles +- `DLONG` (default true): uses long integers for indexing (for large matrices) + +Note that the `QDLDL_bool` type is defined as the standard `bool` type for C standards >= C99. Before the `bool` type was not defined and for earlier standards QDLDL sets `QDLDL_bool = QDLDL_int`. + ## Linking QDLDL diff --git a/configure/qdldl_configure.h.in b/configure/qdldl_configure.h.in new file mode 100644 index 0000000..e7fc1bf --- /dev/null +++ b/configure/qdldl_configure.h.in @@ -0,0 +1,18 @@ +#ifndef OSQP_CONFIGURE_H +# define OSQP_CONFIGURE_H + +# ifdef __cplusplus +extern "C" { +# endif /* ifdef __cplusplus */ + +/* DFLOAT */ +#cmakedefine DFLOAT + +/* DLONG */ +#cmakedefine DLONG + +# ifdef __cplusplus +} +# endif /* ifdef __cplusplus */ + +#endif /* ifndef OSQP_CONFIGURE_H */ diff --git a/include/.gitignore b/include/.gitignore new file mode 100644 index 0000000..c5bfa1c --- /dev/null +++ b/include/.gitignore @@ -0,0 +1 @@ +qdldl_configure.h diff --git a/include/qdldl.h b/include/qdldl.h index 7b9cf96..9cb1e0b 100644 --- a/include/qdldl.h +++ b/include/qdldl.h @@ -1,19 +1,31 @@ #ifndef QDLDL_H # define QDLDL_H -//Define external bool, int and float types if they -//are not already defined externally. If you wish -//to have your own types defined here, then define -//QDLDL_TYPES_DEFINED elsewhere and manually define -//the types QDLDL_bool, QDLDL_int and QDLDL_float - -#ifndef QDLDL_TYPES_DEFINED - #include - #define QDLDL_TYPES_DEFINED - typedef bool QDLDL_bool; - typedef long long QDLDL_int; - typedef double QDLDL_float; -# endif +// Include qdldl configure options +#include "qdldl_configure.h" + +// Custom types +// Integers +# ifdef DLONG // long integers +typedef long long QDLDL_int; /* for indices */ +# else // standard integers +typedef int QDLDL_int; /* for indices */ +# endif /* ifdef DLONG */ + +// Doubles +# ifndef DFLOAT // Doubles +typedef double QDLDL_float; /* for numerical values */ +# else // Floats +typedef float QDLDL_float; /* for numerical values */ +# endif /* ifndef DFLOAT */ + +// Define bool if standard > C89 +#if __STDC_VERSION__ >= 199901L +#include +typedef bool QDLDL_bool; +#else +typedef QDLDL_int QDLDL_bool; +#endif # ifdef __cplusplus diff --git a/tests/qdldl_tester.c b/tests/qdldl_tester.c index 3ca481c..06be17f 100644 --- a/tests/qdldl_tester.c +++ b/tests/qdldl_tester.c @@ -18,14 +18,14 @@ void qdprint_arrayi(const QDLDL_int* data, QDLDL_int n,char* varName); void qdprint_arrayf(const QDLDL_float* data, QDLDL_int n, char* varName); // Include tests -// #include "test_basic.h" -// #include "test_identity.h" -// #include "test_rank_deficient.h" -// #include "test_singleton.h" -// #include "test_sym_structure.h" -// #include "test_tril_structure.h" -// #include "test_two_by_two.h" -// #include "test_zero_on_diag.h" +#include "test_basic.h" +#include "test_identity.h" +#include "test_rank_deficient.h" +#include "test_singleton.h" +#include "test_sym_structure.h" +#include "test_tril_structure.h" +#include "test_two_by_two.h" +#include "test_zero_on_diag.h" #include "test_osqp_kkt.h" @@ -33,14 +33,14 @@ int tests_run = 0; static char* all_tests() { - // mu_run_test(test_basic); - // mu_run_test(test_identity); - // mu_run_test(test_rank_deficient); - // mu_run_test(test_singleton); - // mu_run_test(test_sym_structure); - // mu_run_test(test_tril_structure); - // mu_run_test(test_two_by_two); - // mu_run_test(test_zero_on_diag); + mu_run_test(test_basic); + mu_run_test(test_identity); + mu_run_test(test_rank_deficient); + mu_run_test(test_singleton); + mu_run_test(test_sym_structure); + mu_run_test(test_tril_structure); + mu_run_test(test_two_by_two); + mu_run_test(test_zero_on_diag); mu_run_test(test_osqp_kkt); return 0; @@ -115,11 +115,6 @@ int ldl_factor_solve(QDLDL_int An, bwork = (QDLDL_bool*)malloc(sizeof(QDLDL_bool)*An); fwork = (QDLDL_float*)malloc(sizeof(QDLDL_float)*An); - // DEBUG arguments - printf("Arguments for etree\n"); - printf("An = %lli\n", An); - qdprint_arrayi(Ap, An + 1, "Ap"); - qdprint_arrayi(Ai, Ap[An], "Ai"); /*-------------------------------- * elimination tree calculation @@ -141,16 +136,6 @@ int ldl_factor_solve(QDLDL_int An, Li = (QDLDL_int*)malloc(sizeof(QDLDL_int)*sumLnz); Lx = (QDLDL_float*)malloc(sizeof(QDLDL_float)*sumLnz); - - // DEBUG arguments - printf("Arguments for factor\n"); - qdprint_arrayi(Ap, An + 1, "Ap"); - qdprint_arrayi(Ai, Ap[An], "Ai"); - qdprint_arrayf(Ax, Ap[An], "Ax"); - qdprint_arrayi(Lnz, An, "Lnz"); - qdprint_arrayi(etree, An, "etree"); - - //now factor factorStatus = QDLDL_factor(An,Ap,Ai,Ax,Lp,Li,Lx,D,Dinv,Lnz,etree,bwork,iwork,fwork); @@ -161,11 +146,6 @@ int ldl_factor_solve(QDLDL_int An, return factorStatus; } - // DEBUG (print L factorization) - qdprint_arrayi(Lp, An + 1, "Lp"); - qdprint_arrayi(Li, Lp[Ln], "Li"); - qdprint_arrayf(Lx, Lp[Ln], "Lx"); - /*-------------------------------- * solve *---------------------------------*/