========= *** How to Use Our Algorithm In Your C/C++ code *** =======

We supply two routines 'oqs_quartic_solver(...)' and 'oqs_quartic_solver_cmplx(...)',
which are defined in the files 'quartic_solver.c' and 'quartic_solver_cmplx.c', respectively.
Latter files can be found in the folder 'Src/'. 
The routine 'oqs_quartic_solver(...)' is declared as follows:

void oqs_quartic_solver(double coeff[5], complex double roots[4])   

and this routine calculates the roots of the following quartic equation with real coefficients
   
   coeff[4]*x^4 + coeff[3]*x^3 + coeff[2]*x^2 + coeff[1]*x + coeff[0] = 0

The four roots will be stored in the complex array 'roots[]'. 

The routine 'oqs_quartic_solve_cmplx(...)' is declared as follows:

void oqs_quartic_solver_cmplx(complex double coeff[5], complex double roots[4])  

and this routine calculates the roots of the following quartic equation with complex coefficients: 

coeff[4]*x^4 + coeff[3]*x^3 + coeff[2]*x^2 + coeff[1]*x + coeff[0] = 0

The four roots will be stored in the complex array 'roots[]'. 

To use these routines, one has to compile the sources first and then they have to be linked
against the code which calls the routines.
To give an example, consider the case of a source code 'my_code.c' which contains the 'main()'
function and which calls the routine 'quartic_solver(...)'.
Note that in 'my_code.c' one has to insert a line as the following one:

extern void oqs_quartic_solver(double coeff[5], complex double roots[4]);
  
to properly declare the routine before calling it.
Let us assume that we have installed the gnu compiler 'gcc' and we are in the 
folder where we copied both 'quartic_solver.c' and 'my_code.c'.
First, we compile the sources as follows (where '>' is the shell prompt string):

>gcc -c quartic_solver.c my_code.c

thus generating the object files 'quartic_solver.o' and 'my_code.o'.
Then, we generate the executable as follows:

>gcc quartic_solver.o my_code.o -o my_code

'my_code' is now the executable which uses our algorithm for solving quartics with real coefficients.

================== *** Compiling  *** ==================

Run the command

> make 

to compile the sources. 
In the folder named "bin" the following 4 executables will be created

1) accuracytest

2) statanalysis

3) timingtest

4) simpletest

=================== *** Cleaning *** =====================

To clean all the executables and the object files type (where '>' is the shell prompt string):

> make clean

========= *** Perform All Tests At Once *** ==========

In the root directory of this package there is a Python script called 'run_all_tests.py',
which executes all the tests at once (i.e. accuracy, statistical and timing tests).
Before using this script please compile the drivers (see above).

The syntax of this script is:

./run_all_tests.py [-nruns/-nr <number of runs for timing tests>|-nstat/-ns <number of quartics for statistical tests>|
-ntimings/-nt <number of quartics for timing tests>]

where the command line arguments are optional and  

<number of runs for timing tests> is the number of runs to average over the timing tests [ default: 10 ]

<number of quartics for statistical tests> is the number of quartics to generate for the statistical tests [ default: 100000 ]

<number of quartics for timing tests> is the number of quartics to generate for the timing tests [ default: 500000 ]

Examples (where '>' is the shell prompt string):

> ./run_all_tests

which runs all the tests with default values (see above)

> ./run_all_tests -ns 10000 -nr 5 -nt 100000

which runs the statistical tests generating 10000 quartics and performs the timing tests
averaging over 5 runs and generating 100000 quartics.

The script will generate the following files:

1) 'accuracytest.out'
   This file reports the results of all the accuracy tests which can be found in Tables 2 and 3 in the manuscript

2) 'F_of_eps_rel-XXX.dat', where XXX can be ODM, FLO, STR, FER, FQS, HQR, SHM or HQRL,
   Each of these files contains for a specific algorithm the cumulative distribution 
   function as defined in Eq. (113) of the manuscript.
   For example, to show the cumulative distribution of the ODM algorithm, one can use the command:
   
   > gnuplot

   gnuplot>set logscale y

   gnuplot>plot 'F_of_eps_rel-ODM.dat' using 1:2 with lines
   
   where '>' is the shell prompt string and 'gnuplot>' is the gnuplot prompt string
       
3) 'timings_sampleB.txt' and ' timings_sampleF.txt'
   These files report the results of the timings tests. 
   For each algorithm the average execution time (AVG) and the resulting
   standard deviation (STDDEV) are shown.   

Examples of all these files, which have been obtained by executing the command

> ./run_all_tests.py

can be found in the zip file 'tests_out.zip'

========= *** Description of the Executables for the Tests *** =========

1) accuracytest

It performs the accuracy tests shown in Table 1 of the manuscript
for all the solvers (ODM,FLO,STR,FER,FQS and HQR).
The syntax is (where '>' is the shell prompt string):

> accuracytest <case>

where <case> is an integer between 1 and 24, which corresponds to the 24
cases shown in Table 1 of the manuscript.

2) statanalysis

it performs the statistical analyses shown in Figs. 2-4 of the manuscript. 
The syntax is the following (where '>' is the shell prompt string):

> statanalysis <trials> <output> <sample> <solver>

where

<trials>: it is the number of roots (samples A-E) or coefficients (sample F) to generate

<output>: every <output> trials save the the probability distribution function P(eps_rel) 
	in the file named P_of_eps_rel-XXX.dat and the cumulative distribution function F(eps_rel) 
	in the file named F_of_eps_rel-XXX.dat, where XXX can be ODM, FLO, STR, FER, FQS, HQR, SHM or HQRL  

<sample>: it is an integer between 0 and 5 which specifies the sample to generate 
	according to Table 4 with 0={sample A}, 1={sample B}, 2={sample C}, 3={sample D}, 4={sample E} and
	5={sample F}

<solver>: it is an integer between 0 and 7 which specifies the quartic equation solver to use 
	for the analysis, where 0=HQR, 1=FQS, 2=FER, 3=STR, 4=FLO, 5=ODM, 6=SHM and 7=HQRL 
	(-1 test all the solvers at once)
 
3) timingtest

to perform a timing test run the command (where '>' is the shell prompt string):

> time timingtest <solver> <trials>

where 

<solver> is an integer between 1 and 7 which specifies the quartic equation solver to test 
with 1=ODM, 2=FLO, 3=STR, 4=FER, 5=FQS, 6=HQR and 7=SHM.

<trials> is the number of quartic equations to solve. Roots are generated according sample B in Table 4
of the manuscript

If <solver> is smaller than 1 or greater than 6 none of the solvers is used and only the roots are 
randomly generated.

4) simpletest

It calculates the roots of two quartics with complex 
and real coefficients.
The roots of these quartics are calculated by the routines 
oqs_quartic_solver() and oqs_quartic_solver_cmplx() 
which can be found in the files quartic_solver.c 
and quartic_solver_cmplx.c respectively. 


