{-| module : Data.Number.Flint.NF.QQbar.FFI copyright : (c) 2022 Hartmut Monien license : GNU GPL, version 2 or above (see LICENSE) maintainer : hmonien@uni-bonn.de -} module Data.Number.Flint.NF.QQbar.FFI ( -- * Algebraic numbers represented by minimal polynomials -- * Types QQbar (..) , CQQbar (..) , newQQbar , newQQbarFromFmpz , newQQbarFromFmpq , newQQbarFromDouble , withQQbar , withNewQQbar -- * Assignment , qqbar_swap , qqbar_set , qqbar_set_si , qqbar_set_ui , qqbar_set_fmpz , qqbar_set_fmpq , qqbar_set_re_im , qqbar_set_d , qqbar_set_re_im_d -- * Properties , qqbar_degree , qqbar_is_rational , qqbar_is_integer , qqbar_is_algebraic_integer , qqbar_is_zero , qqbar_is_one , qqbar_is_neg_one , qqbar_is_i , qqbar_is_neg_i , qqbar_is_real , qqbar_height , qqbar_height_bits , qqbar_within_limits , qqbar_binop_within_limits -- * Conversions , _qqbar_get_fmpq , qqbar_get_fmpq , qqbar_get_fmpz -- * Special values , qqbar_zero , qqbar_one , qqbar_i , qqbar_phi -- * Input and output , qqbar_get_str , qqbar_get_strn , qqbar_get_strnd , qqbar_print , qqbar_printn , qqbar_printnd -- * Random generation , qqbar_randtest , qqbar_randtest_real , qqbar_randtest_nonreal -- * Comparisons , qqbar_equal , qqbar_equal_fmpq_poly_val , qqbar_cmp_re , qqbar_cmp_im , qqbar_cmpabs_re , qqbar_cmpabs_im , qqbar_cmpabs , qqbar_cmp_root_order , qqbar_hash -- * Complex parts , qqbar_conj , qqbar_re , qqbar_im , qqbar_re_im , qqbar_abs , qqbar_abs2 , qqbar_sgn , qqbar_sgn_re , qqbar_sgn_im , qqbar_csgn -- * Integer parts , qqbar_floor , qqbar_ceil -- * Arithmetic , qqbar_neg , qqbar_add , qqbar_add_fmpq , qqbar_add_fmpz , qqbar_add_ui , qqbar_add_si , qqbar_sub , qqbar_sub_fmpq , qqbar_sub_fmpz , qqbar_sub_ui , qqbar_sub_si , qqbar_fmpq_sub , qqbar_fmpz_sub , qqbar_ui_sub , qqbar_si_sub , qqbar_mul , qqbar_mul_fmpq , qqbar_mul_fmpz , qqbar_mul_ui , qqbar_mul_si , qqbar_mul_2exp_si , qqbar_sqr , qqbar_inv , qqbar_div , qqbar_div_fmpq , qqbar_div_fmpz , qqbar_div_ui , qqbar_div_si , qqbar_fmpq_div , qqbar_fmpz_div , qqbar_ui_div , qqbar_si_div , qqbar_scalar_op -- * Powers and roots , qqbar_sqrt , qqbar_sqrt_ui , qqbar_rsqrt , qqbar_pow_ui , qqbar_pow_si , qqbar_pow_fmpz , qqbar_pow_fmpq , qqbar_root_ui , qqbar_fmpq_root_ui , qqbar_fmpq_pow_si_ui , qqbar_pow -- * Numerical enclosures , qqbar_get_acb , qqbar_get_arb , qqbar_get_arb_re , qqbar_get_arb_im , qqbar_cache_enclosure -- * Numerator and denominator , qqbar_denominator , qqbar_numerator -- * Conjugates , qqbar_conjugates -- * Polynomial evaluation , _qqbar_evaluate_fmpq_poly , qqbar_evaluate_fmpq_poly , _qqbar_evaluate_fmpz_poly , qqbar_evaluate_fmpz_poly , qqbar_evaluate_fmpz_mpoly_iter , qqbar_evaluate_fmpz_mpoly_horner , qqbar_evaluate_fmpz_mpoly -- * Polynomial roots , qqbar_roots_fmpz_poly , qqbar_roots_fmpq_poly , qqbar_eigenvalues_fmpz_mat , qqbar_eigenvalues_fmpq_mat -- * Roots of unity and trigonometric functions , qqbar_root_of_unity , qqbar_is_root_of_unity , qqbar_exp_pi_i , qqbar_cos_pi , qqbar_sin_pi , qqbar_tan_pi , qqbar_cot_pi , qqbar_sec_pi , qqbar_csc_pi , qqbar_log_pi_i , qqbar_atan_pi , qqbar_asin_pi , qqbar_acos_pi , qqbar_acot_pi , qqbar_asec_pi , qqbar_acsc_pi -- * Guessing and simplification , qqbar_guess , qqbar_express_in_field -- * Symbolic expressions and conversion to radicals , qqbar_get_quadratic , qqbar_set_fexpr , qqbar_get_fexpr_repr , qqbar_get_fexpr_root_nearest , qqbar_get_fexpr_root_indexed , qqbar_get_fexpr_formula -- * Internal functions , qqbar_fmpz_poly_composed_op , qqbar_binary_op , _qqbar_validate_uniqueness , _qqbar_validate_existence_uniqueness , _qqbar_enclosure_raw , qqbar_enclosure_raw , _qqbar_acb_lindep ) where -- Algebraic numbers represented by minimal polynomials ------------------------ import Foreign.Ptr import Foreign.ForeignPtr import Foreign.Storable import Foreign.C.Types import Foreign.C.String import Foreign.Marshal.Alloc import Data.Number.Flint.Flint import Data.Number.Flint.Fmpz import Data.Number.Flint.Fmpz.Mat import Data.Number.Flint.Fmpz.Poly import Data.Number.Flint.Fmpz.MPoly import Data.Number.Flint.Fmpq import Data.Number.Flint.Fmpq.Poly import Data.Number.Flint.Arb.Types import Data.Number.Flint.Acb.Types #include -- qq_bar_t -------------------------------------------------------------------- data QQbar = QQbar {-# UNPACK #-} !(ForeignPtr CQQbar) type CQQbar = CFlint QQbar instance Storable CQQbar where {-# INLINE sizeOf #-} sizeOf _ = #{size qqbar_t} {-# INLINE alignment #-} alignment _ = #{alignment qqbar_t} peek = undefined poke = undefined -- | Create a QQbar. newQQbar = do p <- mallocForeignPtr withForeignPtr p qqbar_init addForeignPtrFinalizer p_qqbar_clear p return $ QQbar p -- | Create a QQbar from Fmpz. newQQbarFromFmpz x = do p <- mallocForeignPtr withForeignPtr p $ \p -> do qqbar_init p withFmpz x $ \x -> qqbar_set_fmpz p x addForeignPtrFinalizer p_qqbar_clear p return $ QQbar p -- | Create a QQbar from Fmpq. newQQbarFromFmpq x = do p <- mallocForeignPtr withForeignPtr p $ \p -> do qqbar_init p withFmpq x $ \x -> qqbar_set_fmpq p x addForeignPtrFinalizer p_qqbar_clear p return $ QQbar p -- | Create a QQbar from Double. newQQbarFromDouble x = do p <- mallocForeignPtr withForeignPtr p $ \p -> do qqbar_init p qqbar_set_d p (realToFrac x) addForeignPtrFinalizer p_qqbar_clear p return $ QQbar p -- | Use QQbar in `f`. {-# INLINE withQQbar #-} withQQbar (QQbar p) f = do withForeignPtr p $ \fp -> (QQbar p,) <$> f fp -- | Apply `f` to new QQbar. {-# INLINE withNewQQbar #-} withNewQQbar f = do x <- newQQbar withQQbar x f -- Memory management ----------------------------------------------------------- -- | /qqbar_init/ /res/ -- -- Initializes the variable /res/ for use, and sets its value to zero. foreign import ccall "qqbar.h qqbar_init" qqbar_init :: Ptr CQQbar -> IO () -- | /qqbar_clear/ /res/ -- -- Clears the variable /res/, freeing or recycling its allocated memory. foreign import ccall "qqbar.h qqbar_clear" qqbar_clear :: Ptr CQQbar -> IO () foreign import ccall "qqbar.h &qqbar_clear" p_qqbar_clear :: FunPtr (Ptr CQQbar -> IO ()) -- | /_qqbar_vec_init/ /len/ -- -- Returns a pointer to an array of /len/ initialized /qqbar_struct/:s. foreign import ccall "qqbar.h _qqbar_vec_init" _qqbar_vec_init :: CLong -> IO (Ptr CQQbar) -- | /_qqbar_vec_clear/ /vec/ /len/ -- -- Clears all /len/ entries in the vector /vec/ and frees the vector -- itself. foreign import ccall "qqbar.h _qqbar_vec_clear" _qqbar_vec_clear :: Ptr CQQbar -> CLong -> IO () -- Assignment ------------------------------------------------------------------ -- | /qqbar_swap/ /x/ /y/ -- -- Swaps the values of /x/ and /y/ efficiently. foreign import ccall "qqbar.h qqbar_swap" qqbar_swap :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_set/ /res/ /x/ foreign import ccall "qqbar.h qqbar_set" qqbar_set :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_set_si/ /res/ /x/ foreign import ccall "qqbar.h qqbar_set_si" qqbar_set_si :: Ptr CQQbar -> CLong -> IO () -- | /qqbar_set_ui/ /res/ /x/ foreign import ccall "qqbar.h qqbar_set_ui" qqbar_set_ui :: Ptr CQQbar -> CULong -> IO () -- | /qqbar_set_fmpz/ /res/ /x/ foreign import ccall "qqbar.h qqbar_set_fmpz" qqbar_set_fmpz :: Ptr CQQbar -> Ptr CFmpz -> IO () -- | /qqbar_set_fmpq/ /res/ /x/ -- -- Sets /res/ to the value /x/. foreign import ccall "qqbar.h qqbar_set_fmpq" qqbar_set_fmpq :: Ptr CQQbar -> Ptr CFmpq -> IO () -- | /qqbar_set_re_im/ /res/ /x/ /y/ -- -- Sets /res/ to the value \(x + yi\). foreign import ccall "qqbar.h qqbar_set_re_im" qqbar_set_re_im :: Ptr CQQbar -> Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_set_d/ /res/ /x/ foreign import ccall "qqbar.h qqbar_set_d" qqbar_set_d :: Ptr CQQbar -> CDouble -> IO CInt -- | /qqbar_set_re_im_d/ /res/ /x/ /y/ -- -- Sets /res/ to the value /x/ or \(x + yi\) respectively. These functions -- performs error handling: if /x/ and /y/ are finite, the conversion -- succeeds and the return flag is 1. If /x/ or /y/ is non-finite (infinity -- or NaN), the conversion fails and the return flag is 0. foreign import ccall "qqbar.h qqbar_set_re_im_d" qqbar_set_re_im_d :: Ptr CQQbar -> CDouble -> CDouble -> IO CInt -- Properties ------------------------------------------------------------------ -- | /qqbar_degree/ /x/ -- -- Returns the degree of /x/, i.e. the degree of the minimal polynomial. foreign import ccall "qqbar.h qqbar_degree" qqbar_degree :: Ptr CQQbar -> IO CLong -- | /qqbar_is_rational/ /x/ -- -- Returns whether /x/ is a rational number. foreign import ccall "qqbar.h qqbar_is_rational" qqbar_is_rational :: Ptr CQQbar -> IO CInt -- | /qqbar_is_integer/ /x/ -- -- Returns whether /x/ is an integer (an element of \(\mathbb{Z}\)). foreign import ccall "qqbar.h qqbar_is_integer" qqbar_is_integer :: Ptr CQQbar -> IO CInt -- | /qqbar_is_algebraic_integer/ /x/ -- -- Returns whether /x/ is an algebraic integer, i.e. whether its minimal -- polynomial has leading coefficient 1. foreign import ccall "qqbar.h qqbar_is_algebraic_integer" qqbar_is_algebraic_integer :: Ptr CQQbar -> IO CInt -- | /qqbar_is_zero/ /x/ foreign import ccall "qqbar.h qqbar_is_zero" qqbar_is_zero :: Ptr CQQbar -> IO CInt -- | /qqbar_is_one/ /x/ foreign import ccall "qqbar.h qqbar_is_one" qqbar_is_one :: Ptr CQQbar -> IO CInt -- | /qqbar_is_neg_one/ /x/ -- -- Returns whether /x/ is the number \(0\), \(1\), \(-1\). foreign import ccall "qqbar.h qqbar_is_neg_one" qqbar_is_neg_one :: Ptr CQQbar -> IO CInt -- | /qqbar_is_i/ /x/ foreign import ccall "qqbar.h qqbar_is_i" qqbar_is_i :: Ptr CQQbar -> IO CInt -- | /qqbar_is_neg_i/ /x/ -- -- Returns whether /x/ is the imaginary unit \(i\) (respectively \(-i\)). foreign import ccall "qqbar.h qqbar_is_neg_i" qqbar_is_neg_i :: Ptr CQQbar -> IO CInt -- | /qqbar_is_real/ /x/ -- -- Returns whether /x/ is a real number. foreign import ccall "qqbar.h qqbar_is_real" qqbar_is_real :: Ptr CQQbar -> IO CInt -- | /qqbar_height/ /res/ /x/ -- -- Sets /res/ to the height of /x/ (the largest absolute value of the -- coefficients of the minimal polynomial of /x/). foreign import ccall "qqbar.h qqbar_height" qqbar_height :: Ptr CFmpz -> Ptr CQQbar -> IO () -- | /qqbar_height_bits/ /x/ -- -- Returns the height of /x/ (the largest absolute value of the -- coefficients of the minimal polynomial of /x/) measured in bits. foreign import ccall "qqbar.h qqbar_height_bits" qqbar_height_bits :: Ptr CQQbar -> IO CLong -- | /qqbar_within_limits/ /x/ /deg_limit/ /bits_limit/ -- -- Checks if /x/ has degree bounded by /deg_limit/ and height bounded by -- /bits_limit/ bits, returning 0 (false) or 1 (true). If /deg_limit/ is -- set to 0, the degree check is skipped, and similarly for /bits_limit/. foreign import ccall "qqbar.h qqbar_within_limits" qqbar_within_limits :: Ptr CQQbar -> CLong -> CLong -> IO CInt -- | /qqbar_binop_within_limits/ /x/ /y/ /deg_limit/ /bits_limit/ -- -- Checks if \(x + y\), \(x - y\), \(x \cdot y\) and \(x / y\) certainly -- have degree bounded by /deg_limit/ (by multiplying the degrees for /x/ -- and /y/ to obtain a trivial bound). For /bits_limits/, the sum of the -- bit heights of /x/ and /y/ is checked against the bound (this is only a -- heuristic). If /deg_limit/ is set to 0, the degree check is skipped, and -- similarly for /bits_limit/. foreign import ccall "qqbar.h qqbar_binop_within_limits" qqbar_binop_within_limits :: Ptr CQQbar -> Ptr CQQbar -> CLong -> CLong -> IO CInt -- Conversions ----------------------------------------------------------------- -- | /_qqbar_get_fmpq/ /num/ /den/ /x/ -- -- Sets /num/ and /den/ to the numerator and denominator of /x/. Aborts if -- /x/ is not a rational number. foreign import ccall "qqbar.h _qqbar_get_fmpq" _qqbar_get_fmpq :: Ptr CFmpz -> Ptr CFmpz -> Ptr CQQbar -> IO () -- | /qqbar_get_fmpq/ /res/ /x/ -- -- Sets /res/ to /x/. Aborts if /x/ is not a rational number. foreign import ccall "qqbar.h qqbar_get_fmpq" qqbar_get_fmpq :: Ptr CFmpq -> Ptr CQQbar -> IO () -- | /qqbar_get_fmpz/ /res/ /x/ -- -- Sets /res/ to /x/. Aborts if /x/ is not an integer. foreign import ccall "qqbar.h qqbar_get_fmpz" qqbar_get_fmpz :: Ptr CFmpz -> Ptr CQQbar -> IO () -- Special values -------------------------------------------------------------- -- | /qqbar_zero/ /res/ -- -- Sets /res/ to the number 0. foreign import ccall "qqbar.h qqbar_zero" qqbar_zero :: Ptr CQQbar -> IO () -- | /qqbar_one/ /res/ -- -- Sets /res/ to the number 1. foreign import ccall "qqbar.h qqbar_one" qqbar_one :: Ptr CQQbar -> IO () -- | /qqbar_i/ /res/ -- -- Sets /res/ to the imaginary unit \(i\). foreign import ccall "qqbar.h qqbar_i" qqbar_i :: Ptr CQQbar -> IO () -- | /qqbar_phi/ /res/ -- -- Sets /res/ to the golden ratio \(\varphi = \tfrac{1}{2}(\sqrt{5} + 1)\). foreign import ccall "qqbar.h qqbar_phi" qqbar_phi :: Ptr CQQbar -> IO () -- Input and output ------------------------------------------------------------ foreign import ccall "qqbar.h qqbar_get_str" qqbar_get_str :: Ptr CQQbar -> IO CString foreign import ccall "qqbar.h qqbar_get_strn" qqbar_get_strn :: Ptr CQQbar -> CLong -> IO CString foreign import ccall "qqbar.h qqbar_get_strnd" qqbar_get_strnd :: Ptr CQQbar -> CLong -> IO CString -- | /qqbar_print/ /x/ -- -- Prints /res/ to standard output. The output shows the degree and the -- list of coefficients of the minimal polynomial followed by a decimal -- representation of the enclosing interval. This function is mainly -- intended for debugging. qqbar_print :: Ptr CQQbar -> IO () qqbar_print x = do printCStr qqbar_get_str x return () -- | /qqbar_printn/ /x/ /n/ -- -- Prints /res/ to standard output. The output shows a decimal -- approximation to /n/ digits. qqbar_printn :: Ptr CQQbar -> CLong -> IO () qqbar_printn x digits = do printCStr (\x -> qqbar_get_strn x digits) x return () -- | /qqbar_printnd/ /x/ /n/ -- -- Prints /res/ to standard output. The output shows a decimal -- approximation to /n/ digits, followed by the degree of the number. qqbar_printnd :: Ptr CQQbar -> CLong -> IO () qqbar_printnd x digits = do printCStr (\x -> qqbar_get_strnd x digits) x return () -- For example, /print/, /printn/ and /printnd/ with \(n = 6\) give the -- following output for the numbers 0, 1, \(i\), \(\varphi\), -- \(\sqrt{2}-\sqrt{3} i\): -- Random generation ----------------------------------------------------------- -- | /qqbar_randtest/ /res/ /state/ /deg/ /bits/ -- -- Sets /res/ to a random algebraic number with degree up to /deg/ and with -- height (measured in bits) up to /bits/. foreign import ccall "qqbar.h qqbar_randtest" qqbar_randtest :: Ptr CQQbar -> Ptr CFRandState -> CLong -> CLong -> IO () -- | /qqbar_randtest_real/ /res/ /state/ /deg/ /bits/ -- -- Sets /res/ to a random real algebraic number with degree up to /deg/ and -- with height (measured in bits) up to /bits/. foreign import ccall "qqbar.h qqbar_randtest_real" qqbar_randtest_real :: Ptr CQQbar -> Ptr CFRandState -> CLong -> CLong -> IO () -- | /qqbar_randtest_nonreal/ /res/ /state/ /deg/ /bits/ -- -- Sets /res/ to a random nonreal algebraic number with degree up to /deg/ -- and with height (measured in bits) up to /bits/. Since all algebraic -- numbers of degree 1 are real, /deg/ must be at least 2. foreign import ccall "qqbar.h qqbar_randtest_nonreal" qqbar_randtest_nonreal :: Ptr CQQbar -> Ptr CFRandState -> CLong -> CLong -> IO () -- Comparisons ----------------------------------------------------------------- -- | /qqbar_equal/ /x/ /y/ -- -- Returns whether /x/ and /y/ are equal. foreign import ccall "qqbar.h qqbar_equal" qqbar_equal :: Ptr CQQbar -> Ptr CQQbar -> IO CInt -- | /qqbar_equal_fmpq_poly_val/ /x/ /f/ /y/ -- -- Returns whether /x/ is equal to \(f(y)\). This function is more -- efficient than evaluating \(f(y)\) and comparing the results. foreign import ccall "qqbar.h qqbar_equal_fmpq_poly_val" qqbar_equal_fmpq_poly_val :: Ptr CQQbar -> Ptr CFmpqPoly -> Ptr CQQbar -> IO CInt -- | /qqbar_cmp_re/ /x/ /y/ -- -- Compares the real parts of /x/ and /y/, returning -1, 0 or +1. foreign import ccall "qqbar.h qqbar_cmp_re" qqbar_cmp_re :: Ptr CQQbar -> Ptr CQQbar -> IO CInt -- | /qqbar_cmp_im/ /x/ /y/ -- -- Compares the imaginary parts of /x/ and /y/, returning -1, 0 or +1. foreign import ccall "qqbar.h qqbar_cmp_im" qqbar_cmp_im :: Ptr CQQbar -> Ptr CQQbar -> IO CInt -- | /qqbar_cmpabs_re/ /x/ /y/ -- -- Compares the absolute values of the real parts of /x/ and /y/, returning -- -1, 0 or +1. foreign import ccall "qqbar.h qqbar_cmpabs_re" qqbar_cmpabs_re :: Ptr CQQbar -> Ptr CQQbar -> IO CInt -- | /qqbar_cmpabs_im/ /x/ /y/ -- -- Compares the absolute values of the imaginary parts of /x/ and /y/, -- returning -1, 0 or +1. foreign import ccall "qqbar.h qqbar_cmpabs_im" qqbar_cmpabs_im :: Ptr CQQbar -> Ptr CQQbar -> IO CInt -- | /qqbar_cmpabs/ /x/ /y/ -- -- Compares the absolute values of /x/ and /y/, returning -1, 0 or +1. foreign import ccall "qqbar.h qqbar_cmpabs" qqbar_cmpabs :: Ptr CQQbar -> Ptr CQQbar -> IO CInt -- | /qqbar_cmp_root_order/ /x/ /y/ -- -- Compares /x/ and /y/ using an arbitrary but convenient ordering defined -- on the complex numbers. This is useful for sorting the roots of a -- polynomial in a canonical order. -- -- We define the root order as follows: real roots come first, in -- descending order. Nonreal roots are subsequently ordered first by real -- part in descending order, then in ascending order by the absolute value -- of the imaginary part, and then in descending order of the sign. This -- implies that complex conjugate roots are adjacent, with the root in the -- upper half plane first. foreign import ccall "qqbar.h qqbar_cmp_root_order" qqbar_cmp_root_order :: Ptr CQQbar -> Ptr CQQbar -> IO CInt -- | /qqbar_hash/ /x/ -- -- Returns a hash of /x/. As currently implemented, this function only -- hashes the minimal polynomial of /x/. The user should mix in some bits -- based on the numerical value if it is critical to distinguish between -- conjugates of the same minimal polynomial. This function is also likely -- to produce serial runs of values for lexicographically close minimal -- polynomials. This is not necessarily a problem for use in hash tables, -- but if it is important that all bits in the output are random, the user -- should apply an integer hash function to the output. foreign import ccall "qqbar.h qqbar_hash" qqbar_hash :: Ptr CQQbar -> IO CULong -- Complex parts --------------------------------------------------------------- -- | /qqbar_conj/ /res/ /x/ -- -- Sets /res/ to the complex conjugate of /x/. foreign import ccall "qqbar.h qqbar_conj" qqbar_conj :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_re/ /res/ /x/ -- -- Sets /res/ to the real part of /x/. foreign import ccall "qqbar.h qqbar_re" qqbar_re :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_im/ /res/ /x/ -- -- Sets /res/ to the imaginary part of /x/. foreign import ccall "qqbar.h qqbar_im" qqbar_im :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_re_im/ /res1/ /res2/ /x/ -- -- Sets /res1/ to the real part of /x/ and /res2/ to the imaginary part of -- /x/. foreign import ccall "qqbar.h qqbar_re_im" qqbar_re_im :: Ptr CQQbar -> Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_abs/ /res/ /x/ -- -- Sets /res/ to the absolute value of /x/: foreign import ccall "qqbar.h qqbar_abs" qqbar_abs :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_abs2/ /res/ /x/ -- -- Sets /res/ to the square of the absolute value of /x/. foreign import ccall "qqbar.h qqbar_abs2" qqbar_abs2 :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_sgn/ /res/ /x/ -- -- Sets /res/ to the complex sign of /x/, defined as 0 if /x/ is zero and -- as \(x / |x|\) otherwise. foreign import ccall "qqbar.h qqbar_sgn" qqbar_sgn :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_sgn_re/ /x/ -- -- Returns the sign of the real part of /x/ (-1, 0 or +1). foreign import ccall "qqbar.h qqbar_sgn_re" qqbar_sgn_re :: Ptr CQQbar -> IO CInt -- | /qqbar_sgn_im/ /x/ -- -- Returns the sign of the imaginary part of /x/ (-1, 0 or +1). foreign import ccall "qqbar.h qqbar_sgn_im" qqbar_sgn_im :: Ptr CQQbar -> IO CInt -- | /qqbar_csgn/ /x/ -- -- Returns the extension of the real sign function taking the value 1 for -- /x/ strictly in the right half plane, -1 for /x/ strictly in the left -- half plane, and the sign of the imaginary part when /x/ is on the -- imaginary axis. Equivalently, -- \(\operatorname{csgn}(x) = x / \sqrt{x^2}\) except that the value is 0 -- when /x/ is zero. foreign import ccall "qqbar.h qqbar_csgn" qqbar_csgn :: Ptr CQQbar -> IO CInt -- Integer parts --------------------------------------------------------------- -- | /qqbar_floor/ /res/ /x/ -- -- Sets /res/ to the floor function of /x/. If /x/ is not real, the value -- is defined as the floor function of the real part of /x/. foreign import ccall "qqbar.h qqbar_floor" qqbar_floor :: Ptr CFmpz -> Ptr CQQbar -> IO () -- | /qqbar_ceil/ /res/ /x/ -- -- Sets /res/ to the ceiling function of /x/. If /x/ is not real, the value -- is defined as the ceiling function of the real part of /x/. foreign import ccall "qqbar.h qqbar_ceil" qqbar_ceil :: Ptr CFmpz -> Ptr CQQbar -> IO () -- Arithmetic ------------------------------------------------------------------ -- | /qqbar_neg/ /res/ /x/ -- -- Sets /res/ to the negation of /x/. foreign import ccall "qqbar.h qqbar_neg" qqbar_neg :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_add/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_add" qqbar_add :: Ptr CQQbar -> Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_add_fmpq/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_add_fmpq" qqbar_add_fmpq :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpq -> IO () -- | /qqbar_add_fmpz/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_add_fmpz" qqbar_add_fmpz :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpz -> IO () -- | /qqbar_add_ui/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_add_ui" qqbar_add_ui :: Ptr CQQbar -> Ptr CQQbar -> CULong -> IO () -- | /qqbar_add_si/ /res/ /x/ /y/ -- -- Sets /res/ to the sum of /x/ and /y/. foreign import ccall "qqbar.h qqbar_add_si" qqbar_add_si :: Ptr CQQbar -> Ptr CQQbar -> CLong -> IO () -- | /qqbar_sub/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_sub" qqbar_sub :: Ptr CQQbar -> Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_sub_fmpq/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_sub_fmpq" qqbar_sub_fmpq :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpq -> IO () -- | /qqbar_sub_fmpz/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_sub_fmpz" qqbar_sub_fmpz :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpz -> IO () -- | /qqbar_sub_ui/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_sub_ui" qqbar_sub_ui :: Ptr CQQbar -> Ptr CQQbar -> CULong -> IO () -- | /qqbar_sub_si/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_sub_si" qqbar_sub_si :: Ptr CQQbar -> Ptr CQQbar -> CLong -> IO () -- | /qqbar_fmpq_sub/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_fmpq_sub" qqbar_fmpq_sub :: Ptr CQQbar -> Ptr CFmpq -> Ptr CQQbar -> IO () -- | /qqbar_fmpz_sub/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_fmpz_sub" qqbar_fmpz_sub :: Ptr CQQbar -> Ptr CFmpz -> Ptr CQQbar -> IO () -- | /qqbar_ui_sub/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_ui_sub" qqbar_ui_sub :: Ptr CQQbar -> CULong -> Ptr CQQbar -> IO () -- | /qqbar_si_sub/ /res/ /x/ /y/ -- -- Sets /res/ to the difference of /x/ and /y/. foreign import ccall "qqbar.h qqbar_si_sub" qqbar_si_sub :: Ptr CQQbar -> CLong -> Ptr CQQbar -> IO () -- | /qqbar_mul/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_mul" qqbar_mul :: Ptr CQQbar -> Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_mul_fmpq/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_mul_fmpq" qqbar_mul_fmpq :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpq -> IO () -- | /qqbar_mul_fmpz/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_mul_fmpz" qqbar_mul_fmpz :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpz -> IO () -- | /qqbar_mul_ui/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_mul_ui" qqbar_mul_ui :: Ptr CQQbar -> Ptr CQQbar -> CULong -> IO () -- | /qqbar_mul_si/ /res/ /x/ /y/ -- -- Sets /res/ to the product of /x/ and /y/. foreign import ccall "qqbar.h qqbar_mul_si" qqbar_mul_si :: Ptr CQQbar -> Ptr CQQbar -> CLong -> IO () -- | /qqbar_mul_2exp_si/ /res/ /x/ /e/ -- -- Sets /res/ to /x/ multiplied by \(2^e\). foreign import ccall "qqbar.h qqbar_mul_2exp_si" qqbar_mul_2exp_si :: Ptr CQQbar -> Ptr CQQbar -> CLong -> IO () -- | /qqbar_sqr/ /res/ /x/ -- -- Sets /res/ to the square of /x/. foreign import ccall "qqbar.h qqbar_sqr" qqbar_sqr :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_inv/ /res/ /x/ /y/ -- -- Sets /res/ to the multiplicative inverse of /y/. Division by zero calls -- /flint_abort/. foreign import ccall "qqbar.h qqbar_inv" qqbar_inv :: Ptr CQQbar -> Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_div/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_div" qqbar_div :: Ptr CQQbar -> Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_div_fmpq/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_div_fmpq" qqbar_div_fmpq :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpq -> IO () -- | /qqbar_div_fmpz/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_div_fmpz" qqbar_div_fmpz :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpz -> IO () -- | /qqbar_div_ui/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_div_ui" qqbar_div_ui :: Ptr CQQbar -> Ptr CQQbar -> CULong -> IO () -- | /qqbar_div_si/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_div_si" qqbar_div_si :: Ptr CQQbar -> Ptr CQQbar -> CLong -> IO () -- | /qqbar_fmpq_div/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_fmpq_div" qqbar_fmpq_div :: Ptr CQQbar -> Ptr CFmpq -> Ptr CQQbar -> IO () -- | /qqbar_fmpz_div/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_fmpz_div" qqbar_fmpz_div :: Ptr CQQbar -> Ptr CFmpz -> Ptr CQQbar -> IO () -- | /qqbar_ui_div/ /res/ /x/ /y/ foreign import ccall "qqbar.h qqbar_ui_div" qqbar_ui_div :: Ptr CQQbar -> CULong -> Ptr CQQbar -> IO () -- | /qqbar_si_div/ /res/ /x/ /y/ -- -- Sets /res/ to the quotient of /x/ and /y/. Division by zero calls -- /flint_abort/. foreign import ccall "qqbar.h qqbar_si_div" qqbar_si_div :: Ptr CQQbar -> CLong -> Ptr CQQbar -> IO () -- | /qqbar_scalar_op/ /res/ /x/ /a/ /b/ /c/ -- -- Sets /res/ to the rational affine transformation \((ax+b)/c\), performed -- as a single operation. There are no restrictions on /a/, /b/ and /c/ -- except that /c/ must be nonzero. Division by zero calls /flint_abort/. foreign import ccall "qqbar.h qqbar_scalar_op" qqbar_scalar_op :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO () -- Powers and roots ------------------------------------------------------------ -- | /qqbar_sqrt/ /res/ /x/ foreign import ccall "qqbar.h qqbar_sqrt" qqbar_sqrt :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_sqrt_ui/ /res/ /x/ -- -- Sets /res/ to the principal square root of /x/. foreign import ccall "qqbar.h qqbar_sqrt_ui" qqbar_sqrt_ui :: Ptr CQQbar -> CULong -> IO () -- | /qqbar_rsqrt/ /res/ /x/ -- -- Sets /res/ to the reciprocal of the principal square root of /x/. -- Division by zero calls /flint_abort/. foreign import ccall "qqbar.h qqbar_rsqrt" qqbar_rsqrt :: Ptr CQQbar -> Ptr CQQbar -> IO () -- | /qqbar_pow_ui/ /res/ /x/ /n/ foreign import ccall "qqbar.h qqbar_pow_ui" qqbar_pow_ui :: Ptr CQQbar -> Ptr CQQbar -> CULong -> IO () -- | /qqbar_pow_si/ /res/ /x/ /n/ foreign import ccall "qqbar.h qqbar_pow_si" qqbar_pow_si :: Ptr CQQbar -> Ptr CQQbar -> CULong -> IO () -- | /qqbar_pow_fmpz/ /res/ /x/ /n/ foreign import ccall "qqbar.h qqbar_pow_fmpz" qqbar_pow_fmpz :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpz -> IO () -- | /qqbar_pow_fmpq/ /res/ /x/ /n/ -- -- Sets /res/ to /x/ raised to the /n/-th power. Raising zero to a negative -- power aborts. foreign import ccall "qqbar.h qqbar_pow_fmpq" qqbar_pow_fmpq :: Ptr CQQbar -> Ptr CQQbar -> Ptr CFmpq -> IO () -- | /qqbar_root_ui/ /res/ /x/ /n/ foreign import ccall "qqbar.h qqbar_root_ui" qqbar_root_ui :: Ptr CQQbar -> Ptr CQQbar -> CULong -> IO () -- | /qqbar_fmpq_root_ui/ /res/ /x/ /n/ -- -- Sets /res/ to the principal /n/-th root of /x/. The order /n/ must be -- positive. foreign import ccall "qqbar.h qqbar_fmpq_root_ui" qqbar_fmpq_root_ui :: Ptr CQQbar -> Ptr CFmpq -> CULong -> IO () -- | /qqbar_fmpq_pow_si_ui/ /res/ /x/ /m/ /n/ -- -- Sets /res/ to the principal branch of \(x^{m/n}\). The order /n/ must be -- positive. Division by zero calls /flint_abort/. foreign import ccall "qqbar.h qqbar_fmpq_pow_si_ui" qqbar_fmpq_pow_si_ui :: Ptr CQQbar -> Ptr CFmpq -> CLong -> CULong -> IO () -- | /qqbar_pow/ /res/ /x/ /y/ -- -- General exponentiation: if \(x^y\) is an algebraic number, sets /res/ to -- this value and returns 1. If \(x^y\) is transcendental or undefined, -- returns 0. Note that this function returns 0 instead of aborting on -- division zero. foreign import ccall "qqbar.h qqbar_pow" qqbar_pow :: Ptr CQQbar -> Ptr CQQbar -> Ptr CQQbar -> IO CInt -- Numerical enclosures -------------------------------------------------------- -- The following functions guarantee a polished output in which both the -- real and imaginary parts are accurate to /prec/ bits and exact when -- exactly representable (that is, when a real or imaginary part is a -- sufficiently small dyadic number). In some cases, the computations -- needed to polish the output may be expensive. When polish is -- unnecessary, @qqbar_enclosure_raw@ may be used instead. Alternatively, -- @qqbar_cache_enclosure@ can be used to avoid recomputations. -- -- | /qqbar_get_acb/ /res/ /x/ /prec/ -- -- Sets /res/ to an enclosure of /x/ rounded to /prec/ bits. foreign import ccall "qqbar.h qqbar_get_acb" qqbar_get_acb :: Ptr CAcb -> Ptr CQQbar -> CLong -> IO () -- | /qqbar_get_arb/ /res/ /x/ /prec/ -- -- Sets /res/ to an enclosure of /x/ rounded to /prec/ bits, assuming that -- /x/ is a real number. If /x/ is not real, /res/ is set to -- \([\operatorname{NaN} \pm \infty]\). foreign import ccall "qqbar.h qqbar_get_arb" qqbar_get_arb :: Ptr CArb -> Ptr CQQbar -> CLong -> IO () -- | /qqbar_get_arb_re/ /res/ /x/ /prec/ -- -- Sets /res/ to an enclosure of the real part of /x/ rounded to /prec/ -- bits. foreign import ccall "qqbar.h qqbar_get_arb_re" qqbar_get_arb_re :: Ptr CArb -> Ptr CQQbar -> CLong -> IO () -- | /qqbar_get_arb_im/ /res/ /x/ /prec/ -- -- Sets /res/ to an enclosure of the imaginary part of /x/ rounded to -- /prec/ bits. foreign import ccall "qqbar.h qqbar_get_arb_im" qqbar_get_arb_im :: Ptr CArb -> Ptr CQQbar -> CLong -> IO () -- | /qqbar_cache_enclosure/ /res/ /prec/ -- -- Polishes the internal enclosure of /res/ to at least /prec/ bits of -- precision in-place. Normally, /qqbar/ operations that need -- high-precision enclosures compute them on the fly without caching the -- results; if /res/ will be used as an invariant operand for many -- operations, calling this function as a precomputation step can improve -- performance. foreign import ccall "qqbar.h qqbar_cache_enclosure" qqbar_cache_enclosure :: Ptr CQQbar -> CLong -> IO () -- Numerator and denominator --------------------------------------------------- -- | /qqbar_denominator/ /res/ /y/ -- -- Sets /res/ to the denominator of /y/, i.e. the leading coefficient of -- the minimal polynomial of /y/. foreign import ccall "qqbar.h qqbar_denominator" qqbar_denominator :: Ptr CFmpz -> Ptr CQQbar -> IO () -- | /qqbar_numerator/ /res/ /y/ -- -- Sets /res/ to the numerator of /y/, i.e. /y/ multiplied by its -- denominator. foreign import ccall "qqbar.h qqbar_numerator" qqbar_numerator :: Ptr CQQbar -> Ptr CQQbar -> IO () -- Conjugates ------------------------------------------------------------------ -- | /qqbar_conjugates/ /res/ /x/ -- -- Sets the entries of the vector /res/ to the /d/ algebraic conjugates of -- /x/, including /x/ itself, where /d/ is the degree of /x/. The output is -- sorted in a canonical order (as defined by @qqbar_cmp_root_order@). foreign import ccall "qqbar.h qqbar_conjugates" qqbar_conjugates :: Ptr CQQbar -> Ptr CQQbar -> IO () -- Polynomial evaluation ------------------------------------------------------- -- | /_qqbar_evaluate_fmpq_poly/ /res/ /poly/ /den/ /len/ /x/ foreign import ccall "qqbar.h _qqbar_evaluate_fmpq_poly" _qqbar_evaluate_fmpq_poly :: Ptr CQQbar -> Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CQQbar -> IO () -- | /qqbar_evaluate_fmpq_poly/ /res/ /poly/ /x/ foreign import ccall "qqbar.h qqbar_evaluate_fmpq_poly" qqbar_evaluate_fmpq_poly :: Ptr CQQbar -> Ptr CFmpqPoly -> Ptr CQQbar -> IO () -- | /_qqbar_evaluate_fmpz_poly/ /res/ /poly/ /len/ /x/ foreign import ccall "qqbar.h _qqbar_evaluate_fmpz_poly" _qqbar_evaluate_fmpz_poly :: Ptr CQQbar -> Ptr CFmpz -> CLong -> Ptr CQQbar -> IO () -- | /qqbar_evaluate_fmpz_poly/ /res/ /poly/ /x/ -- -- Sets /res/ to the value of the given polynomial /poly/ evaluated at the -- algebraic number /x/. These methods detect simple special cases and -- automatically reduce /poly/ if its degree is greater or equal to that of -- the minimal polynomial of /x/. In the generic case, evaluation is done -- by computing minimal polynomials of representation matrices. foreign import ccall "qqbar.h qqbar_evaluate_fmpz_poly" qqbar_evaluate_fmpz_poly :: Ptr CQQbar -> Ptr CFmpzPoly -> Ptr CQQbar -> IO () -- | /qqbar_evaluate_fmpz_mpoly_iter/ /res/ /poly/ /x/ /deg_limit/ /bits_limit/ /ctx/ foreign import ccall "qqbar.h qqbar_evaluate_fmpz_mpoly_iter" qqbar_evaluate_fmpz_mpoly_iter :: Ptr CQQbar -> Ptr CFmpzMPoly ->Ptr CQQbar -> CLong -> CLong -> Ptr CFmpzMPolyCtx -> IO CInt -- | /qqbar_evaluate_fmpz_mpoly_horner/ /res/ /poly/ /x/ /deg_limit/ /bits_limit/ /ctx/ foreign import ccall "qqbar.h qqbar_evaluate_fmpz_mpoly_horner" qqbar_evaluate_fmpz_mpoly_horner :: Ptr CQQbar -> Ptr CFmpzMPoly ->Ptr CQQbar -> CLong -> CLong -> Ptr CFmpzMPolyCtx -> IO CInt -- | /qqbar_evaluate_fmpz_mpoly/ /res/ /poly/ /x/ /deg_limit/ /bits_limit/ /ctx/ -- -- Sets /res/ to the value of /poly/ evaluated at the algebraic numbers -- given in the vector /x/. The number of variables is defined by the -- context object /ctx/. -- -- The parameters /deg_limit/ and /bits_limit/ define evaluation limits: if -- any temporary result exceeds these limits (not necessarily the final -- value, in case of cancellation), the evaluation is aborted and 0 -- (failure) is returned. If evaluation succeeds, 1 is returned. -- -- The /iter/ version iterates over all terms in succession and computes -- the powers that appear. The /horner/ version uses a multivariate -- implementation of the Horner scheme. The default algorithm currently -- uses the Horner scheme. foreign import ccall "qqbar.h qqbar_evaluate_fmpz_mpoly" qqbar_evaluate_fmpz_mpoly :: Ptr CQQbar -> Ptr CFmpzMPoly ->Ptr CQQbar -> CLong -> CLong -> Ptr CFmpzMPolyCtx -> IO CInt -- Polynomial roots ------------------------------------------------------------ -- | /qqbar_roots_fmpz_poly/ /res/ /poly/ /flags/ foreign import ccall "qqbar.h qqbar_roots_fmpz_poly" qqbar_roots_fmpz_poly :: Ptr CQQbar -> Ptr CFmpzPoly -> CInt -> IO () -- | /qqbar_roots_fmpq_poly/ /res/ /poly/ /flags/ -- -- Sets the entries of the vector /res/ to the /d/ roots of the polynomial -- /poly/. Roots with multiplicity appear with repetition in the output -- array. By default, the roots will be sorted in a convenient canonical -- order (as defined by @qqbar_cmp_root_order@). Instances of a repeated -- root always appear consecutively. -- -- The following /flags/ are supported: -- -- - QQBAR_ROOTS_IRREDUCIBLE - if set, /poly/ is assumed to be -- irreducible (it may still have constant content), and no polynomial -- factorization is performed internally. -- - QQBAR_ROOTS_UNSORTED - if set, the roots will not be guaranteed to -- be sorted (except for repeated roots being listed consecutively). foreign import ccall "qqbar.h qqbar_roots_fmpq_poly" qqbar_roots_fmpq_poly :: Ptr CQQbar -> Ptr CFmpqPoly -> CInt -> IO () -- | /qqbar_eigenvalues_fmpz_mat/ /res/ /mat/ /flags/ foreign import ccall "qqbar.h qqbar_eigenvalues_fmpz_mat" qqbar_eigenvalues_fmpz_mat :: Ptr CQQbar -> Ptr CFmpzMat -> CInt -> IO () -- | /qqbar_eigenvalues_fmpq_mat/ /res/ /mat/ /flags/ -- -- Sets the entries of the vector /res/ to the eigenvalues of the square -- matrix /mat/. These functions compute the characteristic polynomial of -- /mat/ and then call @qqbar_roots_fmpz_poly@ with the same flags. foreign import ccall "qqbar.h qqbar_eigenvalues_fmpq_mat" qqbar_eigenvalues_fmpq_mat :: Ptr CQQbar -> Ptr CFmpzMat -> CInt -> IO () -- Roots of unity and trigonometric functions ---------------------------------- -- The following functions use word-size integers /p/ and /q/ instead of -- /fmpq_t/ instances to express rational numbers. This is to emphasize -- that the computations are feasible only with small /q/ in this -- representation of algebraic numbers since the associated minimal -- polynomials have degree \(O(q)\). The input /p/ and /q/ do not need to -- be reduced /a priori/, but should not be close to the word boundaries -- (they may be added and subtracted internally). -- -- | /qqbar_root_of_unity/ /res/ /p/ /q/ -- -- Sets /res/ to the root of unity \(e^{2 \pi i p / q}\). foreign import ccall "qqbar.h qqbar_root_of_unity" qqbar_root_of_unity :: Ptr CQQbar -> CLong -> CULong -> IO () -- | /qqbar_is_root_of_unity/ /p/ /q/ /x/ -- -- If /x/ is not a root of unity, returns 0. If /x/ is a root of unity, -- returns 1. If /p/ and /q/ are not /NULL/ and /x/ is a root of unity, -- this also sets /p/ and /q/ to the minimal integers with \(0 \le p < q\) -- such that \(x = e^{2 \pi i p / q}\). foreign import ccall "qqbar.h qqbar_is_root_of_unity" qqbar_is_root_of_unity :: Ptr CLong -> Ptr CULong -> Ptr CQQbar -> IO CInt -- | /qqbar_exp_pi_i/ /res/ /p/ /q/ -- -- Sets /res/ to the root of unity \(e^{\pi i p / q}\). foreign import ccall "qqbar.h qqbar_exp_pi_i" qqbar_exp_pi_i :: Ptr CQQbar -> CLong -> CULong -> IO () -- | /qqbar_cos_pi/ /res/ /p/ /q/ foreign import ccall "qqbar.h qqbar_cos_pi" qqbar_cos_pi :: Ptr CQQbar -> CLong -> CULong -> IO () -- | /qqbar_sin_pi/ /res/ /p/ /q/ foreign import ccall "qqbar.h qqbar_sin_pi" qqbar_sin_pi :: Ptr CQQbar -> CLong -> CULong -> IO () -- | /qqbar_tan_pi/ /res/ /p/ /q/ foreign import ccall "qqbar.h qqbar_tan_pi" qqbar_tan_pi :: Ptr CQQbar -> CLong -> CULong -> IO CInt -- | /qqbar_cot_pi/ /res/ /p/ /q/ foreign import ccall "qqbar.h qqbar_cot_pi" qqbar_cot_pi :: Ptr CQQbar -> CLong -> CULong -> IO CInt -- | /qqbar_sec_pi/ /res/ /p/ /q/ foreign import ccall "qqbar.h qqbar_sec_pi" qqbar_sec_pi :: Ptr CQQbar -> CLong -> CULong -> IO CInt -- | /qqbar_csc_pi/ /res/ /p/ /q/ -- -- Sets /res/ to the trigonometric function \(\cos(\pi x)\), -- \(\sin(\pi x)\), etc., with \(x = \tfrac{p}{q}\). The functions tan, -- cot, sec and csc return the flag 1 if the value exists, and return 0 if -- the evaluation point is a pole of the function. foreign import ccall "qqbar.h qqbar_csc_pi" qqbar_csc_pi :: Ptr CQQbar -> CLong -> CULong -> IO CInt -- | /qqbar_log_pi_i/ /p/ /q/ /x/ -- -- If \(y = \operatorname{log}(x) / (\pi i)\) is algebraic, and hence -- necessarily rational, sets \(y = p / q\) to the reduced such fraction -- with \(-1 < y \le 1\) and returns 1. If /y/ is not algebraic, returns 0. foreign import ccall "qqbar.h qqbar_log_pi_i" qqbar_log_pi_i :: Ptr CLong -> Ptr CULong -> Ptr CQQbar -> IO CInt -- | /qqbar_atan_pi/ /p/ /q/ /x/ -- -- If \(y = \operatorname{atan}(x) / \pi\) is algebraic, and hence -- necessarily rational, sets \(y = p / q\) to the reduced such fraction -- with \(|y| < \tfrac{1}{2}\) and returns 1. If /y/ is not algebraic, -- returns 0. foreign import ccall "qqbar.h qqbar_atan_pi" qqbar_atan_pi :: Ptr CLong -> Ptr CULong -> Ptr CQQbar -> IO CInt -- | /qqbar_asin_pi/ /p/ /q/ /x/ -- -- If \(y = \operatorname{asin}(x) / \pi\) is algebraic, and hence -- necessarily rational, sets \(y = p / q\) to the reduced such fraction -- with \(|y| \le \tfrac{1}{2}\) and returns 1. If /y/ is not algebraic, -- returns 0. foreign import ccall "qqbar.h qqbar_asin_pi" qqbar_asin_pi :: Ptr CLong -> Ptr CULong -> Ptr CQQbar -> IO CInt -- | /qqbar_acos_pi/ /p/ /q/ /x/ -- -- If \(y = \operatorname{acos}(x) / \pi\) is algebraic, and hence -- necessarily rational, sets \(y = p / q\) to the reduced such fraction -- with \(0 \le y \le 1\) and returns 1. If /y/ is not algebraic, returns -- 0. foreign import ccall "qqbar.h qqbar_acos_pi" qqbar_acos_pi :: Ptr CLong -> Ptr CULong -> Ptr CQQbar -> IO CInt -- | /qqbar_acot_pi/ /p/ /q/ /x/ -- -- If \(y = \operatorname{acot}(x) / \pi\) is algebraic, and hence -- necessarily rational, sets \(y = p / q\) to the reduced such fraction -- with \(-\tfrac{1}{2} < y \le \tfrac{1}{2}\) and returns 1. If /y/ is not -- algebraic, returns 0. foreign import ccall "qqbar.h qqbar_acot_pi" qqbar_acot_pi :: Ptr CLong -> Ptr CULong -> Ptr CQQbar -> IO CInt -- | /qqbar_asec_pi/ /p/ /q/ /x/ -- -- If \(y = \operatorname{asec}(x) / \pi\) is algebraic, and hence -- necessarily rational, sets \(y = p / q\) to the reduced such fraction -- with \(0 \le y \le 1\) and returns 1. If /y/ is not algebraic, returns -- 0. foreign import ccall "qqbar.h qqbar_asec_pi" qqbar_asec_pi :: Ptr CLong -> Ptr CULong -> Ptr CQQbar -> IO CInt -- | /qqbar_acsc_pi/ /p/ /q/ /x/ -- -- If \(y = \operatorname{acsc}(x) / \pi\) is algebraic, and hence -- necessarily rational, sets \(y = p / q\) to the reduced such fraction -- with \(-\tfrac{1}{2} \le y \le \tfrac{1}{2}\) and returns 1. If /y/ is -- not algebraic, returns 0. foreign import ccall "qqbar.h qqbar_acsc_pi" qqbar_acsc_pi :: Ptr CLong -> Ptr CULong -> Ptr CQQbar -> IO CInt -- Guessing and simplification ------------------------------------------------- -- | /qqbar_guess/ /res/ /z/ /max_deg/ /max_bits/ /flags/ /prec/ -- -- Attempts to find an algebraic number /res/ of degree at most /max_deg/ -- and height at most /max_bits/ bits matching the numerical enclosure /z/. -- The return flag indicates success. This is only a heuristic method, and -- the return flag neither implies a rigorous proof that /res/ is the -- correct result, nor a rigorous proof that no suitable algebraic number -- with the given /max_deg/ and /max_bits/ exists. (Proof of nonexistence -- could in principle be computed, but this is not yet implemented.) -- -- The working precision /prec/ should normally be the same as the -- precision used to compute /z/. It does not make much sense to run this -- algorithm with precision smaller than O(/max_deg/ ยท /max_bits/). -- -- This function does a single iteration at the target /max_deg/, -- /max_bits/, and /prec/. For best performance, one should invoke this -- function repeatedly with successively larger parameters when the size of -- the intended solution is unknown or may be much smaller than a -- worst-case bound. foreign import ccall "qqbar.h qqbar_guess" qqbar_guess :: Ptr CQQbar -> Ptr CAcb -> CLong -> CLong -> CInt -> CLong -> IO CInt -- | /qqbar_express_in_field/ /res/ /alpha/ /x/ /max_bits/ /flags/ /prec/ -- -- Attempts to express /x/ in the number field generated by /alpha/, -- returning success (0 or 1). On success, /res/ is set to a polynomial /f/ -- of degree less than the degree of /alpha/ and with height (counting both -- the numerator and the denominator, when the coefficients of /g/ are put -- on a common denominator) bounded by /max_bits/ bits, such that -- \(f(\alpha) = x\). -- -- (Exception: the /max_bits/ parameter is currently ignored if /x/ is -- rational, in which case /res/ is just set to the value of /x/.) -- -- This function looks for a linear relation heuristically using a working -- precision of /prec/ bits. If /x/ is expressible in terms of /alpha/, -- then this function is guaranteed to succeed when /prec/ is taken large -- enough. The identity \(f(\alpha) = x\) is checked rigorously, i.e. a -- return value of 1 implies a proof of correctness. In principle, choosing -- a sufficiently large /prec/ can be used to prove that /x/ does not lie -- in the field generated by /alpha/, but the present implementation does -- not support doing so automatically. -- -- This function does a single iteration at the target /max_bits/ and and -- /prec/. For best performance, one should invoke this function repeatedly -- with successively larger parameters when the size of the intended -- solution is unknown or may be much smaller than a worst-case bound. foreign import ccall "qqbar.h qqbar_express_in_field" qqbar_express_in_field :: Ptr CFmpqPoly -> Ptr CQQbar -> Ptr CQQbar -> CLong -> CInt -> CLong -> IO CInt -- Symbolic expressions and conversion to radicals ----------------------------- -- fexptr_t -------------------------------------------------------------------- data FExpr = FExpr {-# UNPACK #-} !(ForeignPtr CFExpr) type CFExpr = CFlint FExpr -------------------------------------------------------------------------------- -- | /qqbar_get_quadratic/ /a/ /b/ /c/ /q/ /x/ /factoring/ -- -- Assuming that /x/ has degree 1 or 2, computes integers /a/, /b/, /c/ and -- /q/ such that -- -- \[`\] -- \[x = \frac{a + b \sqrt{c}}{q}\] -- -- and such that /c/ is not a perfect square, /q/ is positive, and /q/ has -- no content in common with both /a/ and /b/. In other words, this -- determines a quadratic field \(\mathbb{Q}(\sqrt{c})\) containing /x/, -- and then finds the canonical reduced coefficients /a/, /b/ and /q/ -- expressing /x/ in this field. For convenience, this function supports -- rational /x/, for which /b/ and /c/ will both be set to zero. The -- following remarks apply to irrationals. -- -- The radicand /c/ will not be a perfect square, but will not -- automatically be squarefree since this would require factoring the -- discriminant. As a special case, /c/ will be set to \(-1\) if /x/ is a -- Gaussian rational number. Otherwise, behavior is controlled by the -- /factoring/ parameter. -- -- - If /factoring/ is 0, no factorization is performed apart from -- removing powers of two. -- - If /factoring/ is 1, a complete factorization is performed (/c/ will -- be minimal). This can be very expensive if the discriminant is -- large. -- - If /factoring/ is 2, a smooth factorization is performed to remove -- small factors from /c/. This is a tradeoff that provides pretty -- output in most cases while avoiding extreme worst-case slowdown. The -- smooth factorization guarantees finding all small factors (up to -- some trial division limit determined internally by Flint), but large -- factors are only found heuristically. foreign import ccall "qqbar.h qqbar_get_quadratic" qqbar_get_quadratic :: Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> Ptr CQQbar -> CInt -> IO () -- | /qqbar_set_fexpr/ /res/ /expr/ -- -- Sets /res/ to the algebraic number represented by the symbolic -- expression /expr/, returning 1 on success and 0 on failure. -- -- This function performs a \"static\" evaluation using /qqbar/ arithmetic, -- supporting only closed-form expressions with explicitly algebraic -- subexpressions. It can be used to recover values generated by -- @qqbar_get_expr_formula@ and variants. For evaluating more complex -- expressions involving other types of values or requiring symbolic -- simplifications, the user should preprocess /expr/ so that it is in a -- form which can be parsed by @qqbar_set_fexpr@. -- -- The following expressions are supported: -- -- - Integer constants -- - Arithmetic operations with algebraic operands -- - Square roots of algebraic numbers -- - Powers with algebraic base and exponent an explicit rational number -- - NumberI, GoldenRatio, RootOfUnity -- - Floor, Ceil, Abs, Sign, Csgn, Conjugate, Re, Im, Max, Min -- - Trigonometric functions with argument an explicit rational number -- times Pi -- - Exponentials with argument an explicit rational number times Pi * -- NumberI -- - The Decimal() constructor -- - AlgebraicNumberSerialized() (assuming valid data, which is not -- checked) -- - PolynomialRootIndexed() -- - PolynomialRootNearest() -- -- Examples of formulas that are not supported, despite the value being an -- algebraic number: -- -- - @Pi - Pi@ (general transcendental simplifications are not performed) -- - @1 \/ Infinity@ (only numbers are handled) -- - @Sum(n, For(n, 1, 10))@ (only static evaluation is performed) foreign import ccall "qqbar.h qqbar_set_fexpr" qqbar_set_fexpr :: Ptr CQQbar -> Ptr CFExpr -> IO CInt -- | /qqbar_get_fexpr_repr/ /res/ /x/ -- -- Sets /res/ to a symbolic expression reflecting the exact internal -- representation of /x/. The output will have the form -- @AlgebraicNumberSerialized(List(coeffs), enclosure)@. The output can be -- converted back to a @qqbar_t@ value using @qqbar_set_fexpr@. This is the -- recommended format for serializing algebraic numbers as it requires -- minimal computation, but it has the disadvantage of not being -- human-readable. foreign import ccall "qqbar.h qqbar_get_fexpr_repr" qqbar_get_fexpr_repr :: Ptr CFExpr -> Ptr CQQbar -> IO () -- | /qqbar_get_fexpr_root_nearest/ /res/ /x/ -- -- Sets /res/ to a symbolic expression unambiguously describing /x/ in the -- form @PolynomialRootNearest(List(coeffs), point)@ where /point/ is an -- approximation of /x/ guaranteed to be closer to /x/ than any conjugate -- root. The output can be converted back to a @qqbar_t@ value using -- @qqbar_set_fexpr@. This is a useful format for human-readable -- presentation, but serialization and deserialization can be expensive. foreign import ccall "qqbar.h qqbar_get_fexpr_root_nearest" qqbar_get_fexpr_root_nearest :: Ptr CFExpr -> Ptr CQQbar -> IO () -- | /qqbar_get_fexpr_root_indexed/ /res/ /x/ -- -- Sets /res/ to a symbolic expression unambiguously describing /x/ in the -- form @PolynomialRootIndexed(List(coeffs), index)@ where /index/ is the -- index of /x/ among its conjugate roots in the builtin root sort order. -- The output can be converted back to a @qqbar_t@ value using -- @qqbar_set_fexpr@. This is a useful format for human-readable -- presentation when the numerical value is important, but serialization -- and deserialization can be expensive. foreign import ccall "qqbar.h qqbar_get_fexpr_root_indexed" qqbar_get_fexpr_root_indexed :: Ptr CFExpr -> Ptr CQQbar -> IO () -- | /qqbar_get_fexpr_formula/ /res/ /x/ /flags/ -- -- Attempts to express the algebraic number /x/ as a closed-form expression -- using arithmetic operations, radicals, and possibly exponentials or -- trigonometric functions, but without using @PolynomialRootNearest@ or -- @PolynomialRootIndexed@. Returns 0 on failure and 1 on success. -- -- The /flags/ parameter toggles different methods for generating formulas. -- It can be set to any combination of the following. If /flags/ is 0, only -- rational numbers will be handled. -- -- QQBAR_FORMULA_ALL -- -- Toggles all methods (potentially expensive). -- -- QQBAR_FORMULA_GAUSSIANS -- -- Detect Gaussian rational numbers \(a + bi\). -- -- QQBAR_FORMULA_QUADRATICS -- -- Solve quadratics in the form \(a + b \sqrt{d}\). -- -- QQBAR_FORMULA_CYCLOTOMICS -- -- Detect elements of cyclotomic fields. This works by trying plausible -- cyclotomic fields (based on the degree of the input), using LLL to find -- candidate number field elements, and certifying candidates through an -- exact computation. Detection is heuristic and is not guaranteed to find -- all cyclotomic numbers. -- -- QQBAR_FORMULA_CUBICS QQBAR_FORMULA_QUARTICS QQBAR_FORMULA_QUINTICS -- -- Solve polynomials of degree 3, 4 and (where applicable) 5 using cubic, -- quartic and quintic formulas (not yet implemented). -- -- QQBAR_FORMULA_DEPRESSION -- -- Use depression to try to generate simpler numbers. -- -- QQBAR_FORMULA_DEFLATION -- -- Use deflation to try to generate simpler numbers. This allows handling -- number of the form \(a^{1/n}\) where /a/ can be represented in closed -- form. -- -- QQBAR_FORMULA_SEPARATION -- -- Try separating real and imaginary parts or sign and magnitude of complex -- numbers. This allows handling numbers of the form \(a + bi\) or -- \(m \cdot s\) (with \(m > 0, |s| = 1\)) where /a/ and /b/ or /m/ and /s/ -- can be represented in closed form. This is only attempted as a fallback -- after other methods fail: if an explicit Cartesian or magnitude-sign -- represented is desired, the user should manually separate the number -- into complex parts before calling @qqbar_get_fexpr_formula@. -- -- QQBAR_FORMULA_EXP_FORM QQBAR_FORMULA_TRIG_FORM -- QQBAR_FORMULA_RADICAL_FORM QQBAR_FORMULA_AUTO_FORM -- -- Select output form for cyclotomic numbers. The /auto/ form (equivalent -- to no flags being set) results in radicals for numbers of low degree, -- trigonometric functions for real numbers, and complex exponentials for -- nonreal numbers. The other flags (not fully implemented) can be used to -- force exponential form, trigonometric form, or radical form. foreign import ccall "qqbar.h qqbar_get_fexpr_formula" qqbar_get_fexpr_formula :: Ptr CFExpr -> Ptr CQQbar -> CULong -> IO CInt -- Internal functions ---------------------------------------------------------- -- | /qqbar_fmpz_poly_composed_op/ /res/ /A/ /B/ /op/ -- -- Given nonconstant polynomials /A/ and /B/, sets /res/ to a polynomial -- whose roots are \(a+b\), \(a-b\), \(ab\) or \(a/b\) for all roots /a/ of -- /A/ and all roots /b/ of /B/. The parameter /op/ selects the arithmetic -- operation: 0 for addition, 1 for subtraction, 2 for multiplication and 3 -- for division. If /op/ is 3, /B/ must not have zero as a root. foreign import ccall "qqbar.h qqbar_fmpz_poly_composed_op" qqbar_fmpz_poly_composed_op :: Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> CInt -> IO () -- | /qqbar_binary_op/ /res/ /x/ /y/ /op/ -- -- Performs a binary operation using a generic algorithm. This does not -- check for special cases. foreign import ccall "qqbar.h qqbar_binary_op" qqbar_binary_op :: Ptr CQQbar -> Ptr CQQbar -> Ptr CQQbar -> CInt -> IO () -- | /_qqbar_validate_uniqueness/ /res/ /poly/ /z/ /max_prec/ -- -- Given /z/ known to be an enclosure of at least one root of /poly/, -- certifies that the enclosure contains a unique root, and in that case -- sets /res/ to a new (possibly improved) enclosure for the same root, -- returning 1. Returns 0 if uniqueness cannot be certified. -- -- The enclosure is validated by performing a single step with the interval -- Newton method. The working precision is determined from the accuracy of -- /z/, but limited by /max_prec/ bits. -- -- This method slightly inflates the enclosure /z/ to improve the chances -- that the interval Newton step will succeed. Uniqueness on this larger -- interval implies uniqueness of the original interval, but not existence; -- when existence has not been ensured a priori, -- @_qqbar_validate_existence_uniqueness@ should be used instead. foreign import ccall "qqbar.h _qqbar_validate_uniqueness" _qqbar_validate_uniqueness :: Ptr CAcb -> Ptr CFmpzPoly -> Ptr CAcb -> CLong -> IO CInt -- | /_qqbar_validate_existence_uniqueness/ /res/ /poly/ /z/ /max_prec/ -- -- Given any complex interval /z/, certifies that the enclosure contains a -- unique root of /poly/, and in that case sets /res/ to a new (possibly -- improved) enclosure for the same root, returning 1. Returns 0 if -- existence and uniqueness cannot be certified. -- -- The enclosure is validated by performing a single step with the interval -- Newton method. The working precision is determined from the accuracy of -- /z/, but limited by /max_prec/ bits. foreign import ccall "qqbar.h _qqbar_validate_existence_uniqueness" _qqbar_validate_existence_uniqueness :: Ptr CAcb -> Ptr CFmpzPoly -> Ptr CAcb -> CLong -> IO CInt -- | /_qqbar_enclosure_raw/ /res/ /poly/ /z/ /prec/ foreign import ccall "qqbar.h _qqbar_enclosure_raw" _qqbar_enclosure_raw :: Ptr CAcb -> Ptr CFmpzPoly -> Ptr CAcb -> CLong -> IO () -- | /qqbar_enclosure_raw/ /res/ /x/ /prec/ -- -- Sets /res/ to an enclosure of /x/ accurate to about /prec/ bits (the -- actual accuracy can be slightly lower, or higher). -- -- This function uses repeated interval Newton steps to polish the initial -- enclosure /z/, doubling the working precision each time. If any step -- fails to improve the accuracy significantly, the root is recomputed from -- scratch to higher precision. -- -- If the initial enclosure is accurate enough, /res/ is set to this value -- without rounding and without further computation. foreign import ccall "qqbar.h qqbar_enclosure_raw" qqbar_enclosure_raw :: Ptr CAcb -> Ptr CQQbar -> CLong -> IO () -- | /_qqbar_acb_lindep/ /rel/ /vec/ /len/ /check/ /prec/ -- -- Attempts to find an integer vector /rel/ giving a linear relation -- between the elements of the real or complex vector /vec/, using the LLL -- algorithm. -- -- The working precision is set to the minimum of /prec/ and the relative -- accuracy of /vec/ (that is, the difference between the largest magnitude -- and the largest error magnitude within /vec/). 95% of the bits within -- the working precision are used for the LLL matrix, and the remaining 5% -- bits are used to validate the linear relation by evaluating the linear -- combination and checking that the resulting interval contains zero. This -- validation does not prove the existence or nonexistence of a linear -- relation, but it provides a quick heuristic way to eliminate spurious -- relations. -- -- If /check/ is set, the return value indicates whether the validation was -- successful; otherwise, the return value simply indicates whether the -- algorithm was executed normally (failure may occur, for example, if the -- input vector is non-finite). -- -- In principle, this method can be used to produce a proof that no linear -- relation exists with coefficients up to a specified bit size, but this -- has not yet been implemented. foreign import ccall "qqbar.h _qqbar_acb_lindep" _qqbar_acb_lindep :: Ptr CFmpz -> Ptr CAcb -> CLong -> CInt -> CLong -> IO CInt