diff --git a/src/ArbCall/ArbArgTypes.jl b/src/ArbCall/ArbArgTypes.jl index fcaa7be..5c2d651 100644 --- a/src/ArbCall/ArbArgTypes.jl +++ b/src/ArbCall/ArbArgTypes.jl @@ -9,9 +9,9 @@ Struct for conversion between C argument types in the Arb documentation and Julia types. """ struct ArbArgTypes - supported::Dict{String,DataType} + supported::Dict{String,Union{DataType,UnionAll}} unsupported::Set{String} - supported_reversed::Dict{DataType,String} + supported_reversed::Dict{Union{DataType,UnionAll},String} end function Base.getindex(arbargtypes::ArbArgTypes, key::AbstractString) @@ -22,65 +22,96 @@ end # Define the conversions we use for the rest of the code const arbargtypes = ArbArgTypes( - Dict{String,DataType}( + Dict{String,Union{DataType,UnionAll}}( + # Primitive "void" => Cvoid, - "void *" => Ptr{Cvoid}, "int" => Cint, "slong" => Int, "ulong" => UInt, - "double" => Cdouble, - "double *" => Vector{Float64}, + "double" => Float64, "complex_double" => ComplexF64, + "void *" => Ptr{Cvoid}, + "char *" => Cstring, + "slong *" => Vector{Int}, + "ulong *" => Vector{UInt}, + "double *" => Vector{Float64}, "complex_double *" => Vector{ComplexF64}, + # gmp.h + "mpz_t" => BigInt, + # mpfr.h + "mpfr_t" => BigFloat, + "mpfr_rnd_t" => Base.MPFR.MPFRRoundingMode, + # mag.h + "mag_t" => Mag, + # nfloat.h + "nfloat_ptr" => NFloat, + "nfloat_srcptr" => NFloat, + "gr_ctx_t" => nfloat_ctx_struct, # Actually in gr_types.h + # arf.h "arf_t" => Arf, + "arf_rnd_t" => arb_rnd, + # acf.h "acf_t" => Acf, + # arb.h "arb_t" => Arb, - "acb_t" => Acb, - "mag_t" => Mag, - "arb_srcptr" => ArbVector, "arb_ptr" => ArbVector, - "acb_srcptr" => AcbVector, + "arb_srcptr" => ArbVector, + # acb.h + "acb_t" => Acb, "acb_ptr" => AcbVector, + "acb_srcptr" => AcbVector, + # arb_poly.h "arb_poly_t" => ArbPoly, + # acb_poly.h "acb_poly_t" => AcbPoly, + # arb_mat.h "arb_mat_t" => ArbMatrix, + # acb_mat.h "acb_mat_t" => AcbMatrix, - "arf_rnd_t" => arb_rnd, - "mpfr_t" => BigFloat, - "mpfr_rnd_t" => Base.MPFR.MPFRRoundingMode, - "mpz_t" => BigInt, - "char *" => Cstring, - "slong *" => Vector{Int}, - "ulong *" => Vector{UInt}, ), - Set(["FILE *", "fmpr_t", "fmpr_rnd_t", "flint_rand_t", "bool_mat_t"]), - Dict{DataType,String}( + Set(["FILE *", "flint_rand_t"]), + Dict{Union{DataType,UnionAll},String}( + # Primitive Cvoid => "void", - Ptr{Cvoid} => "void *", Cint => "int", Int => "slong", UInt => "ulong", - Cdouble => "double", - Vector{Float64} => "double *", + Float64 => "double", ComplexF64 => "complex_double", + Ptr{Cvoid} => "void *", + Cstring => "char *", + Vector{Int} => "slong *", + Vector{UInt} => "ulong *", + Vector{Float64} => "double *", Vector{ComplexF64} => "complex_double *", + # gmp.h + BigInt => "mpz_t", + # mpfr.h + BigFloat => "mpfr_t", + Base.MPFR.MPFRRoundingMode => "mpfr_rnd_t", + # mag.h + Mag => "mag_t", + # nfloat.h + NFloat => "nfloat_ptr", + nfloat_ctx_struct => "gr_ctx_t", # Actually in gr_types.h + # arf.h Arf => "arf_t", + arb_rnd => "arf_rnd_t", + # acf.h Acf => "acf_t", + # arb.h Arb => "arb_t", - Acb => "acb_t", - Mag => "mag_t", ArbVector => "arb_ptr", + # acb.h + Acb => "acb_t", AcbVector => "acb_ptr", + # arb_poly.h ArbPoly => "arb_poly_t", + # acb_poly.h AcbPoly => "acb_poly_t", + # arb_mat.h ArbMatrix => "arb_mat_t", + # acb_mat.h AcbMatrix => "acb_mat_t", - arb_rnd => "arf_rnd_t", - BigFloat => "mpfr_t", - Base.MPFR.MPFRRoundingMode => "mpfr_rnd_t", - BigInt => "mpz_t", - Cstring => "char *", - Vector{Int} => "slong *", - Vector{UInt} => "ulong *", ), ) diff --git a/src/ArbCall/ArbCall.jl b/src/ArbCall/ArbCall.jl index 4ee6c7b..de3773b 100644 --- a/src/ArbCall/ArbCall.jl +++ b/src/ArbCall/ArbCall.jl @@ -12,6 +12,9 @@ import ..Arblib: cstructtype, arb_rnd, mag_struct, + nfloat_struct, + nfloat_ctx_struct, + _get_nfloat_ctx_struct, arf_struct, acf_struct, arb_struct, @@ -23,6 +26,7 @@ import ..Arblib: arb_mat_struct, acb_mat_struct, MagLike, + NFloatLike, ArfLike, AcfLike, ArbLike, diff --git a/src/ArbCall/ArbFPWrapFunction.jl b/src/ArbCall/ArbFPWrapFunction.jl index 7c59204..0ac50c9 100644 --- a/src/ArbCall/ArbFPWrapFunction.jl +++ b/src/ArbCall/ArbFPWrapFunction.jl @@ -101,7 +101,7 @@ function jlargs(af::ArbFPWrapFunction) cargs[end] == Carg{Cint}(:flags, false) || throw(ArgumentError("expected last argument to be flags::Cint, got $(cargs[end])")) - args = [:($(name(carg))::$(jltype(carg))) for carg in cargs[n+1:end-1]] + args = [jlarg(carg) for carg in cargs[n+1:end-1]] if basetype(af) == Float64 kwargs = [ diff --git a/src/ArbCall/ArbFunction.jl b/src/ArbCall/ArbFunction.jl index ab2049f..21e5403 100644 --- a/src/ArbCall/ArbFunction.jl +++ b/src/ArbCall/ArbFunction.jl @@ -64,21 +64,23 @@ is_series_method(af::ArbFunction) = (jltype(first(arguments(af))) <: Union{Arblib.ArbPolyLike,Arblib.AcbPolyLike}) const jlfname_prefixes = ( + "double", + "cdouble", + "mag", + "nfloat", + "ctx", "arf", "acf", "arb", "acb", - "mag", - "mat", "vec", "poly", - "scalar", + "mat", "fpwrap", - "double", - "cdouble", + "scalar", ) const jlfname_suffixes = - ("si", "ui", "d", "mag", "arf", "acf", "arb", "acb", "mpz", "mpfr", "str") + ("si", "ui", "d", "str", "mpz", "mpfr", "mag", "nfloat", "arf", "acf", "arb", "acb") function jlfname( arbfname::AbstractString; @@ -117,7 +119,7 @@ jlfname_series(af::ArbFunction) = jlfname_series(arbfname(af)) function jlargs(af::ArbFunction; argument_detection::Bool = true) cargs = arguments(af) - jl_arg_names_types = Tuple{Symbol,Any}[] + args = Expr[] kwargs = Expr[] prec_kwarg = false @@ -125,7 +127,7 @@ function jlargs(af::ArbFunction; argument_detection::Bool = true) flags_kwarg = false for (i, carg) in enumerate(cargs) if !argument_detection - push!(jl_arg_names_types, (name(carg), jltype(carg))) + push!(args, jlarg(carg)) continue end @@ -146,13 +148,13 @@ function jlargs(af::ArbFunction; argument_detection::Bool = true) push!(kwargs, extract_rounding_argument(carg)) elseif i > 1 && is_length_argument(carg, cargs[i-1]) push!(kwargs, extract_length_argument(carg, cargs[i-1])) + elseif is_ctx_argument(carg) + push!(kwargs, extract_ctx_argument(carg, first(cargs))) else - push!(jl_arg_names_types, (name(carg), jltype(carg))) + push!(args, jlarg(carg)) end end - args = [:($a::$T) for (a, T) in jl_arg_names_types] - return args, kwargs end @@ -199,13 +201,22 @@ function jlcode(af::ArbFunction, jl_fname = jlfname(af)) returnT = returntype(af) cargs = arguments(af) + where_type_parameters = unique(reduce(vcat, type_parameters.(cargs))) + + func_full_args_call = :($jl_fname($(jl_full_args...))) + + func_full_args_header = if isempty(where_type_parameters) + func_full_args_call + else + Expr(:where, func_full_args_call, where_type_parameters...) + end - func_full_args = :( - function $jl_fname($(jl_full_args...)) + func_full_args_body = :( + begin __ret = ccall( Arblib.@libflint($(arbfname(af))), $returnT, - $(Expr(:tuple, ctype.(cargs)...)), + $(Expr(:tuple, carg_expr.(cargs)...)), $(name.(cargs)...), ) $( @@ -220,7 +231,11 @@ function jlcode(af::ArbFunction, jl_fname = jlfname(af)) end ) + func_full_args = Expr(:function, func_full_args_header, func_full_args_body) + if is_series_method(af) + @assert isempty(where_type_parameters) # Currently not supported for series methods + # Note that this currently doesn't respect any custom function # name given as an argument. jl_fname_series = jlfname_series(af) @@ -242,9 +257,16 @@ function jlcode(af::ArbFunction, jl_fname = jlfname(af)) if isempty(jl_kwargs) return code else + func_kwarg_args_call = :($jl_fname($(jl_args...); $(jl_kwargs...))) + func_kwarg_args_header = if isempty(where_type_parameters) + func_kwarg_args_call + else + Expr(:where, func_kwarg_args_call, where_type_parameters...) + end + return quote $code - $jl_fname($(jl_args...); $(jl_kwargs...)) = $jl_fname($(name.(cargs)...)) + $func_kwarg_args_header = $jl_fname($(name.(cargs)...)) end end end diff --git a/src/ArbCall/Carg.jl b/src/ArbCall/Carg.jl index dc94365..7ada66a 100644 --- a/src/ArbCall/Carg.jl +++ b/src/ArbCall/Carg.jl @@ -22,8 +22,7 @@ function Carg(str::AbstractString) m = match(r"(?const)?\s*(?\w+(\s\*)?)\s+(?\w+)", str) isnothing(m) && throw(ArgumentError("string doesn't match c-argument pattern")) isconst = - !isnothing(m[:const]) || - (!isnothing(m[:type]) && (m[:type] == "arb_srcptr" || m[:type] == "acb_srcptr")) + !isnothing(m[:const]) || (!isnothing(m[:type]) && endswith(m[:type], "_srcptr")) return Carg{arbargtypes[m[:type]]}(m[:name], isconst) end @@ -37,8 +36,9 @@ Base.:(==)(a::Carg{T}, b::Carg{S}) where {T,S} = function arbsignature(ca::Carg) arbtype = arbargtypes.supported_reversed[rawtype(ca)] - if isconst(ca) && (arbtype == "arb_ptr" || arbtype == "acb_ptr") - return "$(split(arbtype, "_")[1])_srcptr $(name(ca))" + if isconst(ca) && endswith(arbtype, "_ptr") + const_arbtype = replace(arbtype, "_ptr" => "_srcptr") + return "$const_arbtype $(name(ca))" else return ifelse(isconst(ca), "const ", "") * "$arbtype $(name(ca))" end @@ -56,29 +56,48 @@ types with lower precision. In general the conversion is done using `Base.cconvert`. """ jltype(ca::Carg) = rawtype(ca) +# Primitive jltype(::Carg{Cint}) = Integer jltype(::Carg{Int}) = Integer jltype(::Carg{UInt}) = Unsigned -jltype(::Carg{Cdouble}) = Base.GMP.CdoubleMax +jltype(::Carg{Float64}) = Union{Float16,Float32,Float64} jltype(::Carg{ComplexF64}) = Union{ComplexF16,ComplexF32,ComplexF64} -jltype(::Carg{arb_rnd}) = Union{arb_rnd,RoundingMode} -jltype(::Carg{Base.MPFR.MPFRRoundingMode}) = Union{Base.MPFR.MPFRRoundingMode,RoundingMode} jltype(::Carg{Cstring}) = AbstractString -jltype(::Carg{Vector{Int}}) = Vector{<:Integer} -jltype(::Carg{Vector{UInt}}) = Vector{<:Unsigned} -jltype(::Carg{Vector{Float64}}) = Vector{<:Base.GMP.CdoubleMax} -jltype(::Carg{Vector{ComplexF64}}) = Vector{<:Union{ComplexF16,ComplexF32,ComplexF64}} +jltype(::Carg{Vector{Int}}) = Vector{Int} +jltype(::Carg{Vector{UInt}}) = Vector{UInt} +jltype(::Carg{Vector{Float64}}) = Vector{Float64} +jltype(::Carg{Vector{ComplexF64}}) = Vector{ComplexF64} +# mpfr.h +jltype(::Carg{Base.MPFR.MPFRRoundingMode}) = Union{Base.MPFR.MPFRRoundingMode,RoundingMode} +# mag.h jltype(::Carg{Mag}) = MagLike +# nfloat.h +jltype(::Carg{NFloat}) = NFloatLike +# arf.h jltype(::Carg{Arf}) = ArfLike +jltype(::Carg{arb_rnd}) = Union{arb_rnd,RoundingMode} +# acf.h jltype(::Carg{Acf}) = AcfLike +# arb.h jltype(::Carg{Arb}) = ArbLike -jltype(::Carg{Acb}) = AcbLike jltype(::Carg{ArbVector}) = ArbVectorLike +# acb.h +jltype(::Carg{Acb}) = AcbLike jltype(::Carg{AcbVector}) = AcbVectorLike -jltype(::Carg{ArbMatrix}) = ArbMatrixLike -jltype(::Carg{AcbMatrix}) = AcbMatrixLike +# arb_poly.h jltype(::Carg{ArbPoly}) = ArbPolyLike +# acb_poly.h jltype(::Carg{AcbPoly}) = AcbPolyLike +# arb_mat.h +jltype(::Carg{ArbMatrix}) = ArbMatrixLike +# acb_mat.h +jltype(::Carg{AcbMatrix}) = AcbMatrixLike + +type_parameters_from_type(type::UnionAll) = + [type.var.name; type_parameters_from_type(type.body)] +type_parameters_from_type(_) = Symbol[] + +type_parameters(ca::Carg) = type_parameters_from_type(jltype(ca)) """ ctype(ca::Carg) @@ -86,12 +105,59 @@ jltype(::Carg{AcbPoly}) = AcbPolyLike The type that should be used for the argument when passed to C code. """ ctype(ca::Carg) = rawtype(ca) -ctype(::Carg{T}) where {T<:Union{ArbVector,arb_vec_struct}} = Ptr{arb_struct} -ctype(::Carg{T}) where {T<:Union{AcbVector,acb_vec_struct}} = Ptr{acb_struct} +ctype(::Carg{Vector{T}}) where {T} = Ref{T} +ctype(::Carg{T}) where {T<:Union{BigFloat,BigInt}} = Ref{T} ctype(::Carg{T}) where {T<:Union{Mag,Arf,Acf,Arb,Acb,ArbPoly,AcbPoly,ArbMatrix,AcbMatrix}} = Ref{cstructtype(T)} -ctype(::Carg{T}) where {T<:Union{BigFloat,BigInt}} = Ref{T} -ctype(::Carg{Vector{T}}) where {T} = Ref{T} +ctype(::Carg{T}) where {T<:Union{ArbVector,arb_vec_struct}} = Ptr{arb_struct} +ctype(::Carg{T}) where {T<:Union{AcbVector,acb_vec_struct}} = Ptr{acb_struct} +ctype(::Carg{T}) where {T<:NFloat} = Ref{nfloat_struct{P,F}} where {P,F} +ctype(::Carg{T}) where {T<:nfloat_ctx_struct} = Ref{nfloat_ctx_struct{P,F}} where {P,F} + +""" + jlarg(ca::Carg{T}) where {T} + +Return an `Expr` for representing the argument in a Julia function +header. + +```jldoctest +julia> Arblib.ArbCall.jlarg(Arblib.ArbCall.Carg("const arb_t x")) +:(x::ArbLike) +julia> Arblib.ArbCall.jlarg(Arblib.ArbCall.Carg("slong prec")) +:(prec::Integer) +julia> Arblib.ArbCall.jlarg(Arblib.ArbCall.Carg("nfloat_ptr res")) +:(res::(NFloatLike){P,F}) +``` +""" +function jlarg(ca::Carg) + if jltype(ca) isa UnionAll + :($(name(ca))::$(jltype(ca)){$(type_parameters(ca)...)}) + else + :($(name(ca))::$(jltype(ca))) + end +end + +""" + carg_expr(ca::Carg{T}) where {T} + +Return a value for representing the argument in a `ccall`. + +```jldoctest +julia> Arblib.ArbCall.carg_expr(Arblib.ArbCall.Carg("const arb_t x")) +Ref{Arblib.arb_struct} +julia> Arblib.ArbCall.carg_expr(Arblib.ArbCall.Carg("slong prec")) +Int64 +julia> Arblib.ArbCall.carg_expr(Arblib.ArbCall.Carg("nfloat_ptr res")) +:((Ref{Arblib.nfloat_struct{P, F}} where {P, F}){P, F}) +``` +""" +function carg_expr(ca::Carg) + if ctype(ca) isa UnionAll + :($(ctype(ca)){$(type_parameters(ca)...)}) + else + :($(ctype(ca))) + end +end is_precision_argument(ca::Carg) = ca == Carg{Int}(:prec, false) @@ -105,42 +171,44 @@ is_length_argument(ca::Carg, prev_ca::Carg) = rawtype(ca) == Int && rawtype(prev_ca) ∈ (ArbVector, AcbVector) +is_ctx_argument(ca::Carg{T}) where {T} = T <: nfloat_ctx_struct + function extract_precision_argument(ca::Carg, first_ca::Carg) is_precision_argument(ca) || throw(ArgumentError("argument is not a valid precision argument, $ca")) # If the first argument has a precision, then use this otherwise # make it a mandatory kwarg if rawtype(first_ca) <: ArbTypes && rawtype(first_ca) != Mag - return Expr(:kw, :(prec::Integer), :(_precision($(name(first_ca))))) + return Expr(:kw, jlarg(ca), :(_precision($(name(first_ca))))) else - return :(prec::Integer) + return jlarg(ca) end end function extract_flag_argument(ca::Carg) is_flag_argument(ca) || throw(ArgumentError("argument is not a valid flag argument, $ca")) - return Expr(:kw, :(flags::Integer), 0) + return Expr(:kw, jlarg(ca), 0) end function extract_rounding_argument(ca::Carg) is_rounding_argument(ca) || throw(ArgumentError("argument is not a valid rounding argument, $ca")) - if rawtype(ca) == arb_rnd - return Expr(:kw, :(rnd::Union{Arblib.arb_rnd,RoundingMode}), :(RoundNearest)) - elseif rawtype(ca) == Base.MPFR.MPFRRoundingMode - return Expr( - :kw, - :(rnd::Union{Base.MPFR.MPFRRoundingMode,RoundingMode}), - :(RoundNearest), - ) - end + return Expr(:kw, jlarg(ca), :(RoundNearest)) end function extract_length_argument(ca::Carg, prev_ca::Carg) is_length_argument(ca, prev_ca) || throw(ArgumentError("argument is not a valid length argument, $ca")) - return Expr(:kw, :($(name(ca))::Integer), :(length($(name(prev_ca))))) + return Expr(:kw, jlarg(ca), :(length($(name(prev_ca))))) +end + +# TODO: This needs to handle the case when it is not the first +# argument we should get the context from. This happens for e.g. +# nfloat_get_arf. +function extract_ctx_argument(ca::Carg, first_ca::Carg) + is_ctx_argument(ca) || throw(ArgumentError("argument is not a valid ctx argument, $ca")) + return Expr(:kw, jlarg(ca), :(_get_nfloat_ctx_struct($(name(first_ca))))) end """ diff --git a/src/ArbCall/parse.jl b/src/ArbCall/parse.jl index fe8ac9d..e4bf9ed 100644 --- a/src/ArbCall/parse.jl +++ b/src/ArbCall/parse.jl @@ -192,6 +192,7 @@ function parse_and_generate_arbdoc( out_dir = "src/arbcalls/"; filenames = [ "mag", + "nfloat", "arf", "acf", "arb", diff --git a/src/Arblib.jl b/src/Arblib.jl index 124ff0d..265e7c3 100644 --- a/src/Arblib.jl +++ b/src/Arblib.jl @@ -54,6 +54,8 @@ include("types.jl") include("hash.jl") include("serialize.jl") +include("nfloat.jl") + include("ArbCall/ArbCall.jl") import .ArbCall: @arbcall_str, @arbfpwrapcall_str include("manual_overrides.jl") @@ -84,6 +86,7 @@ include("calc_integrate.jl") include("special-functions.jl") include("arbcalls/mag.jl") +include("arbcalls/nfloat.jl") include("arbcalls/arf.jl") include("arbcalls/acf.jl") include("arbcalls/arb.jl") @@ -109,4 +112,6 @@ include("arbcalls/arb_fpwrap.jl") include("arbcalls/fmpz_extras.jl") include("arbcalls/eigen.jl") +include("nfloat_init_contexts.jl") + end # module diff --git a/src/arbcalls/nfloat.jl b/src/arbcalls/nfloat.jl new file mode 100644 index 0000000..1a88390 --- /dev/null +++ b/src/arbcalls/nfloat.jl @@ -0,0 +1,200 @@ +### +### **nfloat.h** -- packed floating-point numbers with n-word precision +### + +### Types, macros and constants + +### Context objects +arbcall"int nfloat_ctx_init(gr_ctx_t ctx, slong prec, int flags)" + +### Basic operations and arithmetic +#ni arbcall"int nfloat_ctx_write(gr_stream_t out, gr_ctx_t ctx)" +arbcall"void nfloat_init(nfloat_ptr res, gr_ctx_t ctx)" +arbcall"void nfloat_clear(nfloat_ptr res, gr_ctx_t ctx)" +arbcall"void nfloat_swap(nfloat_ptr x, nfloat_ptr y, gr_ctx_t ctx)" +arbcall"int nfloat_set(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +#ni arbcall"truth_t nfloat_equal(nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int nfloat_ctx_set_real_prec(gr_ctx_t ctx, slong prec)" +arbcall"int nfloat_ctx_get_real_prec(slong * res, gr_ctx_t ctx)" +arbcall"int nfloat_zero(nfloat_ptr res, gr_ctx_t ctx)" +arbcall"int nfloat_one(nfloat_ptr res, gr_ctx_t ctx)" +arbcall"int nfloat_neg_one(nfloat_ptr res, gr_ctx_t ctx)" +arbcall"int nfloat_pos_inf(nfloat_ptr res, gr_ctx_t ctx)" +arbcall"int nfloat_neg_inf(nfloat_ptr res, gr_ctx_t ctx)" +arbcall"int nfloat_nan(nfloat_ptr res, gr_ctx_t ctx)" +#ni arbcall"truth_t nfloat_is_zero(nfloat_srcptr x, gr_ctx_t ctx)" +#ni arbcall"truth_t nfloat_is_one(nfloat_srcptr x, gr_ctx_t ctx)" +#ni arbcall"truth_t nfloat_is_neg_one(nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_set_ui(nfloat_ptr res, ulong x, gr_ctx_t ctx)" +arbcall"int nfloat_set_si(nfloat_ptr res, slong x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_set_fmpz(nfloat_ptr res, const fmpz_t x, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_set_mpn_2exp(nfloat_ptr res, nn_srcptr x, slong xn, slong exp, int xsgnbit, gr_ctx_t ctx)" +#ni arbcall"int nfloat_set_mpn_2exp(nfloat_ptr res, nn_srcptr x, slong xn, slong exp, int xsgnbit, gr_ctx_t ctx)" +arbcall"int nfloat_set_arf(nfloat_ptr res, const arf_t x, gr_ctx_t ctx)" +arbcall"int nfloat_get_arf(arf_t res, nfloat_srcptr x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_set_fmpq(nfloat_ptr res, const fmpq_t v, gr_ctx_t ctx)" +arbcall"int nfloat_set_d(nfloat_ptr res, double x, gr_ctx_t ctx)" +arbcall"int nfloat_set_str(nfloat_ptr res, const char * x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_set_other(nfloat_ptr res, gr_srcptr x, gr_ctx_t x_ctx, gr_ctx_t ctx)" +#ni arbcall"int nfloat_write(gr_stream_t out, nfloat_srcptr x, gr_ctx_t ctx)" +#ns arbcall"int nfloat_randtest(nfloat_ptr res, flint_rand_t state, gr_ctx_t ctx)" +#ni arbcall"int nfloat_cmp(int * res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +#ni arbcall"int nfloat_cmpabs(int * res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int nfloat_neg(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_abs(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_add(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int nfloat_sub(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int nfloat_mul(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int nfloat_submul(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int nfloat_addmul(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int nfloat_sqr(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_mul_2exp_si(nfloat_ptr res, nfloat_srcptr x, slong y, gr_ctx_t ctx)" +arbcall"int nfloat_inv(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_div(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int nfloat_div_ui(nfloat_ptr res, nfloat_srcptr x, ulong y, gr_ctx_t ctx)" +arbcall"int nfloat_div_si(nfloat_ptr res, nfloat_srcptr x, slong y, gr_ctx_t ctx)" +arbcall"int nfloat_sqrt(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_rsqrt(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_sgn(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_im(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_floor(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_ceil(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_trunc(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_nint(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_pow(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int nfloat_pi(nfloat_ptr res, gr_ctx_t ctx)" +arbcall"int nfloat_exp(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_expm1(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_log(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_log1p(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_sin(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_cos(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_tan(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_sinh(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_cosh(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_tanh(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_atan(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_gamma(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" +arbcall"int nfloat_zeta(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)" + +### Vector functions +arbcall"void _nfloat_vec_init(nfloat_ptr res, slong len, gr_ctx_t ctx)" +arbcall"void _nfloat_vec_clear(nfloat_ptr res, slong len, gr_ctx_t ctx)" +arbcall"int _nfloat_vec_set(nfloat_ptr res, nfloat_srcptr x, slong len, gr_ctx_t ctx)" +arbcall"int _nfloat_vec_zero(nfloat_ptr res, slong len, gr_ctx_t ctx)" +arbcall"int _nfloat_vec_add(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, slong len, gr_ctx_t ctx)" +arbcall"int _nfloat_vec_sub(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, slong len, gr_ctx_t ctx)" +arbcall"int _nfloat_vec_mul(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, slong len, gr_ctx_t ctx)" +arbcall"int _nfloat_vec_mul_scalar(nfloat_ptr res, nfloat_srcptr x, slong len, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int _nfloat_vec_addmul_scalar(nfloat_ptr res, nfloat_srcptr x, slong len, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int _nfloat_vec_submul_scalar(nfloat_ptr res, nfloat_srcptr x, slong len, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int _nfloat_vec_dot(nfloat_ptr res, nfloat_srcptr initial, int subtract, nfloat_srcptr x, nfloat_srcptr y, slong len, gr_ctx_t ctx)" +arbcall"int _nfloat_vec_dot_rev(nfloat_ptr res, nfloat_srcptr initial, int subtract, nfloat_srcptr x, nfloat_srcptr y, slong len, gr_ctx_t ctx)" + +### Matrix functions +#ni arbcall"int nfloat_mat_mul_fixed(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, slong max_extra_prec, gr_ctx_t ctx)" +#ni arbcall"int nfloat_mat_mul_block(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, slong min_block_size, gr_ctx_t ctx)" +#ni arbcall"int nfloat_mat_mul(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx)" +#ni arbcall"int nfloat_mat_nonsingular_solve_tril(gr_mat_t X, const gr_mat_t L, const gr_mat_t B, int unit, gr_ctx_t ctx)" +#ni arbcall"int nfloat_mat_nonsingular_solve_triu(gr_mat_t X, const gr_mat_t L, const gr_mat_t B, int unit, gr_ctx_t ctx)" +#ni arbcall"int nfloat_mat_lu(slong * rank, slong * P, gr_mat_t LU, const gr_mat_t A, int rank_check, gr_ctx_t ctx)" + +### Internal functions +arbcall"int _nfloat_underflow(nfloat_ptr res, int sgnbit, gr_ctx_t ctx)" +arbcall"int _nfloat_overflow(nfloat_ptr res, int sgnbit, gr_ctx_t ctx)" +arbcall"int _nfloat_cmp(nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int _nfloat_cmpabs(nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)" +arbcall"int _nfloat_add_1(nfloat_ptr res, ulong x0, slong xexp, int xsgnbit, ulong y0, slong delta, gr_ctx_t ctx)" +arbcall"int _nfloat_sub_1(nfloat_ptr res, ulong x0, slong xexp, int xsgnbit, ulong y0, slong delta, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_add_2(nfloat_ptr res, nn_srcptr xd, slong xexp, int xsgnbit, nn_srcptr yd, slong delta, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_sub_2(nfloat_ptr res, nn_srcptr xd, slong xexp, int xsgnbit, nn_srcptr yd, slong delta, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_add_3(nfloat_ptr res, nn_srcptr x, slong xexp, int xsgnbit, nn_srcptr y, slong delta, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_sub_3(nfloat_ptr res, nn_srcptr x, slong xexp, int xsgnbit, nn_srcptr y, slong delta, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_add_4(nfloat_ptr res, nn_srcptr x, slong xexp, int xsgnbit, nn_srcptr y, slong delta, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_sub_4(nfloat_ptr res, nn_srcptr x, slong xexp, int xsgnbit, nn_srcptr y, slong delta, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_add_n(nfloat_ptr res, nn_srcptr xd, slong xexp, int xsgnbit, nn_srcptr yd, slong delta, slong nlimbs, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_sub_n(nfloat_ptr res, nn_srcptr xd, slong xexp, int xsgnbit, nn_srcptr yd, slong delta, slong nlimbs, gr_ctx_t ctx)" + +### Complex numbers +arbcall"int nfloat_complex_ctx_init(gr_ctx_t ctx, slong prec, int flags)" +#ni arbcall"void nfloat_complex_init(nfloat_complex_ptr res, gr_ctx_t ctx)" +#ni arbcall"void nfloat_complex_clear(nfloat_complex_ptr res, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_zero(nfloat_complex_ptr res, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_get_acf(acf_t res, nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_set_acf(nfloat_complex_ptr res, const acf_t x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_get_acb(acb_t res, nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_set_acb(nfloat_complex_ptr res, const acb_t x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_write(gr_stream_t out, nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_randtest(nfloat_complex_ptr res, flint_rand_t state, gr_ctx_t ctx)" +#ni arbcall"void nfloat_complex_swap(nfloat_complex_ptr x, nfloat_complex_ptr y, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_set(nfloat_complex_ptr res, nfloat_complex_ptr x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_one(nfloat_complex_ptr res, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_neg_one(nfloat_complex_ptr res, gr_ctx_t ctx)" +#ni arbcall"truth_t nfloat_complex_is_zero(nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"truth_t nfloat_complex_is_one(nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"truth_t nfloat_complex_is_neg_one(nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_i(nfloat_complex_ptr res, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_pi(nfloat_complex_ptr res, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_conj(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_re(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_im(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"truth_t nfloat_complex_equal(nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_set_si(nfloat_complex_ptr res, slong x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_set_ui(nfloat_complex_ptr res, ulong x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_set_fmpz(nfloat_complex_ptr res, const fmpz_t x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_set_fmpq(nfloat_complex_ptr res, const fmpq_t x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_set_d(nfloat_complex_ptr res, double x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_set_other(nfloat_complex_ptr res, gr_srcptr x, gr_ctx_t x_ctx, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_neg(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_add(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_sub(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)" +arbcall"int _nfloat_complex_sqr_naive(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, gr_ctx_t ctx)" +arbcall"int _nfloat_complex_sqr_standard(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, gr_ctx_t ctx)" +arbcall"int _nfloat_complex_sqr_karatsuba(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, gr_ctx_t ctx)" +arbcall"int _nfloat_complex_sqr(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_sqr(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)" +arbcall"int _nfloat_complex_mul_naive(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, nfloat_srcptr c, nfloat_srcptr d, gr_ctx_t ctx)" +arbcall"int _nfloat_complex_mul_standard(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, nfloat_srcptr c, nfloat_srcptr d, gr_ctx_t ctx)" +arbcall"int _nfloat_complex_mul_karatsuba(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, nfloat_srcptr c, nfloat_srcptr d, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_mul(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_inv(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_div(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_mul_2exp_si(nfloat_complex_ptr res, nfloat_complex_srcptr x, slong y, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_cmp(int * res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_cmpabs(int * res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_abs(nfloat_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)" +#ni arbcall"void _nfloat_complex_vec_init(nfloat_complex_ptr res, slong len, gr_ctx_t ctx)" +#ni arbcall"void _nfloat_complex_vec_clear(nfloat_complex_ptr res, slong len, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_complex_vec_zero(nfloat_complex_ptr res, slong len, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_complex_vec_set(nfloat_complex_ptr res, nfloat_complex_srcptr x, slong len, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_complex_vec_add(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, slong len, gr_ctx_t ctx)" +#ni arbcall"int _nfloat_complex_vec_sub(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, slong len, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_mat_mul_fixed(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, slong max_extra_prec, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_mat_mul_block(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, slong min_block_size, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_mat_mul_reorder(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_mat_mul(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_mat_nonsingular_solve_tril(gr_mat_t X, const gr_mat_t L, const gr_mat_t B, int unit, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_mat_nonsingular_solve_triu(gr_mat_t X, const gr_mat_t L, const gr_mat_t B, int unit, gr_ctx_t ctx)" +#ni arbcall"int nfloat_complex_mat_lu(slong * rank, slong * P, gr_mat_t LU, const gr_mat_t A, int rank_check, gr_ctx_t ctx)" + +### Packed fixed-point arithmetic +#ni arbcall"void _nfixed_print(nn_srcptr x, slong nlimbs, slong exp)" +#ni arbcall"void _nfixed_vec_add(nn_ptr res, nn_srcptr a, nn_srcptr b, slong len, slong nlimbs)" +#ni arbcall"void _nfixed_vec_sub(nn_ptr res, nn_srcptr a, nn_srcptr b, slong len, slong nlimbs)" +#ni arbcall"void _nfixed_dot_2(nn_ptr res, nn_srcptr x, slong xstride, nn_srcptr y, slong ystride, slong len)" +#ni arbcall"void _nfixed_dot_3(nn_ptr res, nn_srcptr x, slong xstride, nn_srcptr y, slong ystride, slong len)" +#ni arbcall"void _nfixed_dot_4(nn_ptr res, nn_srcptr x, slong xstride, nn_srcptr y, slong ystride, slong len)" +#ni arbcall"void _nfixed_dot_5(nn_ptr res, nn_srcptr x, slong xstride, nn_srcptr y, slong ystride, slong len)" +#ni arbcall"void _nfixed_dot_6(nn_ptr res, nn_srcptr x, slong xstride, nn_srcptr y, slong ystride, slong len)" +#ni arbcall"void _nfixed_dot_7(nn_ptr res, nn_srcptr x, slong xstride, nn_srcptr y, slong ystride, slong len)" +#ni arbcall"void _nfixed_dot_8(nn_ptr res, nn_srcptr x, slong xstride, nn_srcptr y, slong ystride, slong len)" +#ni arbcall"void _nfixed_mat_mul_classical_precise(nn_ptr C, nn_srcptr A, nn_srcptr B, slong m, slong n, slong p, slong nlimbs)" +#ni arbcall"void _nfixed_mat_mul_classical(nn_ptr C, nn_srcptr A, nn_srcptr B, slong m, slong n, slong p, slong nlimbs)" +#ni arbcall"void _nfixed_mat_mul_waksman(nn_ptr C, nn_srcptr A, nn_srcptr B, slong m, slong n, slong p, slong nlimbs)" +#ni arbcall"void _nfixed_mat_mul_strassen(nn_ptr C, nn_srcptr A, nn_srcptr B, slong m, slong n, slong p, slong cutoff, slong nlimbs)" +#ni arbcall"void _nfixed_mat_mul(nn_ptr C, nn_srcptr A, nn_srcptr B, slong m, slong n, slong p, slong nlimbs)" +arbcall"void _nfixed_mat_mul_bound_classical(double * bound, double * error, slong m, slong n, slong p, double A, double B, slong nlimbs)" +arbcall"void _nfixed_mat_mul_bound_waksman(double * bound, double * error, slong m, slong n, slong p, double A, double B, slong nlimbs)" +arbcall"void _nfixed_mat_mul_bound_strassen(double * bound, double * error, slong m, slong n, slong p, double A, double B, slong cutoff, slong nlimbs)" +arbcall"void _nfixed_mat_mul_bound(double * bound, double * error, slong m, slong n, slong p, double A, double B, slong nlimbs)" +arbcall"void _nfixed_complex_mat_mul_bound(double * bound, double * error, slong m, slong n, slong p, double A, double B, double C, double D, slong nlimbs)" diff --git a/src/nfloat.jl b/src/nfloat.jl new file mode 100644 index 0000000..e34d39e --- /dev/null +++ b/src/nfloat.jl @@ -0,0 +1,239 @@ +# Type for handling the context for nfloat_t. In Flint it has the type +# gr_ctx_t which is a reference to a gr_ctx_struct. Both of these +# types are defined in src/gr_types.h in Flint. For type stability it +# seems best to create a separate type for a nfloat_ctx_struct, even +# if it is more general in theory. +const GR_CTX_STRUCT_DATA_BYTES = 6 * sizeof(UInt) +mutable struct nfloat_ctx_struct{P,F} + data::NTuple{GR_CTX_STRUCT_DATA_BYTES,UInt8} + which_ring::UInt + sizeof_elem::Int + methods::Ptr{Cvoid} + size_limit::UInt + + function nfloat_ctx_struct{P,F}() where {P,F} + @assert P isa Int && F isa Int + ctx = new{P,F}() + ret = init!(ctx, 64P, F) + iszero(ret) || throw(DomainError(P, "cannot set precision to this value")) + return ctx + end +end + +const NFLOAT_HEADER_LIMBS = 2 +mutable struct nfloat_struct{P,F} + head::NTuple{NFLOAT_HEADER_LIMBS,UInt} + d::NTuple{P,UInt} # FIXME: Should be different for 32 bit systems + + function nfloat_struct{P,F}() where {P,F} + @assert P isa Int && F isa Int + res = new{P,F}() + init!(res) + return res + end +end + +struct NFloat{P,F} <: AbstractFloat + nfloat::nfloat_struct{P,F} + + NFloat{P,F}() where {P,F} = new{P,F}(nfloat_struct{P,F}()) +end + +struct NFloatRef{P,F} <: AbstractFloat + nfloat_ptr::Ptr{nfloat_struct{P,F}} + parent::Union{Nothing} +end + +const NFloatLike{P,F} = Union{NFloat{P,F},NFloatRef{P,F},nfloat_struct{P,F}} + +nfloat_ctx_struct(::NFloatLike{P,F}) where {P,F} = nfloat_ctx_struct{P,F}() +nfloat_ctx_struct(::Type{NFloatLike{P,F}}) where {P,F} = nfloat_ctx_struct{P,F}() + +# The contexts are precomputed in nfloat_late.jl +@generated function _get_nfloat_ctx_struct( + ::Union{Type{<:NFloatLike{P,F}},NFloatLike{P,F}}, +) where {P,F} + Symbol(:_nfloat_ctx_struct_, P, :_, F) +end + +# Helper function for constructing a flag argument for NFloat +nfloat_flag(; + allow_underflow::Bool = false, + allow_inf::Bool = false, + allow_nan::Bool = false, +) = allow_underflow + 2allow_inf + 4allow_nan + +# As in types.jl + +cprefix(::Type{NFloat}) = :nfloat +cstruct(x::NFloat) = getfield(x, cprefix(NFloat)) +cstruct(x::nfloat_struct) = x +cstructtype(::Type{NFloat{P,F}}) where {P,F} = nfloat_struct{P,F} +cstructtype(::Type{NFloat}) = nfloat_struct +Base.convert(::Type{nfloat_struct{P,F}}, x::NFloat{P,F}) where {P,F} = cstruct(x) +Base.convert(::Type{nfloat_struct}, x::NFloat{P,F}) where {P,F} = cstruct(x) + +const NFloatOrRef{P,F} = Union{NFloat{P,F},NFloatRef{P,F}} + +cprefix(::Type{NFloatRef}) = :nfloat +cstruct(x::NFloatRef) = x.nfloat_ref +cstructtype(::Type{NFloatRef}) = nfloat_struct +Base.convert(::Type{Ptr{nfloat_struct}}, x::NFloatRef) = cstruct(x) +Base.cconvert(::Type{Ref{nfloat_struct}}, x::NFloatRef) = cstruct(x) + +_nonreftype(::Type{<:NFloatOrRef{P,F}}) where {P,F} = NFloat{P,F} + +parentstruct(x::NFloat) = cstruct(x) +parentstruct(x::NFloatRef) = x +parentstruct(x::nfloat_struct) = x + +Base.copy(x::T) where {T<:NFloatOrRef} = _nonreftype(T)(x) + +# As in precision.jl + +Base._precision_with_base_2(::Type{NFloatLike{P}}) where {P} = 64P +Base._precision_with_base_2(::NFloatLike{P}) where {P} = 64P + +Base.precision(T::Type{NFloatLike{P}}; base::Integer = 2) where {P} = + Base._precision(T, base) +Base.precision(x::NFloatLike; base::Integer = 2) = Base._precision(x, base) + +@inline _precision(x::NFloatLike) = precision(x) + +# As in setters.jl + +# NFloat +function set!(res::NFloatLike, x::Rational) + set!(res, numerator(x)) + div!(res, res, denominator(x)) + return res +end + +set!(res::NFloatLike, x::Complex) = + isreal(x) ? set!(res, real(x)) : throw(InexactError(:NFloat, NFloat, x)) + +set!(res::NFloatLike, ::Irrational{:π}) = pi!(res) + +# Arf +set!(res::ArfLike, x::NFloatLike) = (get!(res, x, _get_nfloat_ctx_struct(x)); res) + +# As in constructors.jl + +NFloat{P,F}(x) where {P,F} = (res = NFloat{P,F}(); set!(res, x); res) +# disambiguation +NFloat{P,F}(x::NFloatLike{P,F}) where {P,F} = (res = NFloat{P,F}(); set!(res, x); res) +NFloat{P,F}(x::Rational) where {P,F} = (res = NFloat{P,F}(); set!(res, x); res) +NFloat{P,F}(x::Complex) where {P,F} = (res = NFloat{P,F}(); set!(res, x); res) + +function NFloat{P,F}(str::AbstractString) where {P,F} + res = NFloat{P,F}() + ret = set!(res, str) + iszero(ret) || throw(ArgumentError("could not parse $str as an NFloat{$P,$F}")) + return res +end + +Base.zero(::Union{NFloat{P,F},Type{NFloat{P,F}}}) where {P,F} = NFloat{P,F}() +Base.one(::Union{NFloat{P,F},Type{NFloat{P,F}}}) where {P,F} = one!(NFloat{P,F}()) + +Base.zeros(::Type{<:NFloat}, n::Integer) = [zero(T) for _ = 1:n] +Base.ones(::Type{<:NFloat}, n::Integer) = [one(T) for _ = 1:n] + +# As in conversion.jl + +# TODO + +# As in predicates.jl + +NFLOAT_EXP(x::nfloat_struct) = reinterpret(Int, x.head[1]) +NFLOAT_EXP(x::NFloat) = NFLOAT_EXP(cstruct(x)) +const NFLOAT_EXP_ZERO = typemin(Int) +const NFLOAT_EXP_POS_INF = typemin(Int) + 1 +const NFLOAT_EXP_NEG_INF = typemin(Int) + 2 +const NFLOAT_EXP_NAN = typemin(Int) + 3 + +Base.iszero(x::NFloatOrRef) = NFLOAT_EXP(x) == NFLOAT_EXP_ZERO +Base.isone(x::NFloatOrRef) = false # TODO: Need to wrap nfloat_is_one which returns truth_t +Base.isfinite(x::NFloatOrRef) = !isinf(x) && !isnan(x) +Base.isinf(x::NFloatOrRef) = + (NFLOAT_EXP(x) == NFLOAT_EXP_POS_INF) || (NFLOAT_EXP(x) == NFLOAT_EXP_NEG_INF) +Base.isnan(x::NFloatOrRef) = NFLOAT_EXP(x) == NFLOAT_EXP_NAN + +# As in show.jl + +function Base.show(io::IO, x::NFloatOrRef) + if Base.get(io, :compact, false) + digits = min(6, digits_prec(precision(x))) + print(io, string(x; digits)) + else + print(io, string(x)) + end +end + +function Base.string( + z::NFloatOrRef; + digits::Integer = digits_prec(precision(z)), + remove_trailing_zeros::Bool = true, +) + z_arf = Arf(prec = precision(z)) + get!(z_arf, z, ctx = nfloat_ctx_struct(z)) + return string(z_arf; digits, remove_trailing_zeros) +end + +Base.show(io::IO, ::Type{NFloatLike}) = print(io, :NFloatLike) + +# As in promotion.jl + +Base.promote_rule( + ::Type{<:NFloatOrRef{P1,F1}}, + ::Type{<:Union{NFloatOrRef{P2,F2}}}, +) where {P1,P2,F1,F2} = NFloat{max(P1, P2),F1 | F2} + +# As in arithmetic.jl + +for (jf, af) in [(:+, :add!), (:-, :sub!), (:*, :mul!), (:/, :div!)] + @eval function Base.$jf(x::NFloatOrRef{P,F}, y::NFloatOrRef{P,F}) where {P,F} + z = zero(x) + $af(z, x, y) # TODO: Handle return code? + return z + end +end + +Base.:-(x::NFloat) = (res = zero(x); neg!(res, x); res) + +Base.abs(x::NFloat) = (res = zero(x); abs!(res, x); res) + +Base.:^(x::NFloatOrRef{P,F}, y::NFloatOrRef{P,F}) where {P,F} = + (res = zero(x); pow!(res, x, y); res) + +# As in elementary.jl + +for f in [ + :sqrt, + :log, + :log1p, + :exp, + :expm1, + :sin, + :cos, + :tan, + #:cot, + #:sec, + #:csc, + :atan, + #:asin, + #:acos, + :sinh, + :cosh, + :tanh, + #:coth, + #:sech, + #:csch, + #:atanh, + #:asinh, + #:acosh, +] + @eval Base.$f(x::NFloatOrRef) = (res = zero(x); $(Symbol(f, :!))(res, x); res) +end + + +export NFloat, NFloatRef diff --git a/src/nfloat_init_contexts.jl b/src/nfloat_init_contexts.jl new file mode 100644 index 0000000..cc38cdf --- /dev/null +++ b/src/nfloat_init_contexts.jl @@ -0,0 +1,5 @@ +for P = 1:66 + for F = 0:7 + @eval const $(Symbol(:_nfloat_ctx_struct_, P, :_, F)) = nfloat_ctx_struct{$P,$F}() + end +end diff --git a/src/promotion.jl b/src/promotion.jl index 16dfb63..e1f5237 100644 --- a/src/promotion.jl +++ b/src/promotion.jl @@ -1,25 +1,38 @@ ### Internal ### # Prioritise left Base.promote_rule(::Type{<:MagOrRef}, ::Type{<:Union{MagOrRef}}) = Mag -Base.promote_rule(::Type{<:ArfOrRef}, ::Type{<:Union{MagOrRef,ArfOrRef}}) = Arf -Base.promote_rule(::Type{<:AcfOrRef}, ::Type{<:Union{MagOrRef,ArfOrRef,AcfOrRef}}) = Acf -Base.promote_rule(::Type{<:ArbOrRef}, ::Type{<:Union{MagOrRef,ArfOrRef,ArbOrRef}}) = Arb +Base.promote_rule( + ::Type{<:NFloatOrRef{P,F}}, + ::Type{<:Union{MagOrRef,NFloatOrRef{P,F}}}, +) where {P,F} = NFloat{P,F} +Base.promote_rule(::Type{<:ArfOrRef}, ::Type{<:Union{MagOrRef,NFloatOrRef,ArfOrRef}}) = Arf +Base.promote_rule( + ::Type{<:AcfOrRef}, + ::Type{<:Union{MagOrRef,NFloatOrRef,ArfOrRef,AcfOrRef}}, +) = Acf +Base.promote_rule( + ::Type{<:ArbOrRef}, + ::Type{<:Union{MagOrRef,NFloatOrRef,ArfOrRef,ArbOrRef}}, +) = Arb Base.promote_rule( ::Type{<:AcbOrRef}, - ::Type{<:Union{MagOrRef,ArfOrRef,AcfOrRef,ArbOrRef,AcbOrRef}}, + ::Type{<:Union{MagOrRef,NFloatOrRef,ArfOrRef,AcfOrRef,ArbOrRef,AcbOrRef}}, ) = Acb -Base.promote_rule(::Type{ArbSeries}, ::Type{<:Union{MagOrRef,ArfOrRef,ArbOrRef}}) = - ArbSeries +Base.promote_rule( + ::Type{ArbSeries}, + ::Type{<:Union{MagOrRef,NFloatOrRef,ArfOrRef,ArbOrRef}}, +) = ArbSeries Base.promote_rule( ::Type{AcbSeries}, - ::Type{<:Union{MagOrRef,ArfOrRef,AcfOrRef,ArbOrRef,AcbOrRef,ArbSeries}}, + ::Type{<:Union{MagOrRef,NFloatOrRef,ArfOrRef,AcfOrRef,ArbOrRef,AcbOrRef,ArbSeries}}, ) = AcbSeries # Prioritise right Base.promote_rule( ::Type{<:MagOrRef}, ::Type{T}, -) where {T<:Union{ArfOrRef,ArbOrRef,AcfOrRef,AcbOrRef,ArbSeries,AcbSeries}} = _nonreftype(T) +) where {T<:Union{NFloatOrRef,ArfOrRef,ArbOrRef,AcfOrRef,AcbOrRef,ArbSeries,AcbSeries}} = + _nonreftype(T) Base.promote_rule( ::Type{<:ArfOrRef}, ::Type{T}, @@ -44,6 +57,7 @@ Base.promote_rule(::Type{ArbSeries}, ::Type{<:Union{AcfOrRef,AcbOrRef}}) = AcbSe # Always prioritise Arb types Base.promote_rule(::Type{<:MagOrRef}, ::Type{<:Base.GMP.CdoubleMax}) = Mag +Base.promote_rule(T::Type{<:NFloatOrRef}, ::Type{<:Real}) = _nonreftype(T) Base.promote_rule(::Type{<:ArfOrRef}, ::Type{<:Real}) = Arf Base.promote_rule(::Type{<:AcfOrRef}, ::Type{<:Number}) = Acf Base.promote_rule(::Type{<:ArbOrRef}, ::Type{<:Real}) = Arb diff --git a/test/ArbCall/ArbFPWrapFunction.jl b/test/ArbCall/ArbFPWrapFunction.jl index 0d99b0f..26f4fdf 100644 --- a/test/ArbCall/ArbFPWrapFunction.jl +++ b/test/ArbCall/ArbFPWrapFunction.jl @@ -155,9 +155,9 @@ ( "int arb_fpwrap_double_hypgeom_pfq(double * res, const double * a, slong p, const double * b, slong q, double z, int regularized, int flags)", [ - :(a::$(Vector{<:Union{Float16,Float32,Float64}})), + :(a::$(Vector{Float64})), :(p::$Integer), - :(b::$(Vector{<:Union{Float16,Float32,Float64}})), + :(b::$(Vector{Float64})), :(q::$Integer), :(z::$(Union{Float16,Float32,Float64})), :(regularized::$Integer), @@ -219,9 +219,11 @@ "int arb_fpwrap_cdouble_exp(complex_double * res, complex_double x, int flags)", ) af = Arblib.ArbCall.ArbFPWrapFunction(str) - eval(Arblib.ArbCall.jlcode(af)) + # Use a different name to avoid overwriting existing function + fname = Symbol(Arblib.ArbCall.jlfname(af), :_test) + eval(Arblib.ArbCall.jlcode(af, fname)) - f = eval(Arblib.ArbCall.jlfname(af)) + f = eval(fname) T = Arblib.ArbCall.basetype(af) args = zeros(T, length(Arblib.ArbCall.jlargs(af)[1])) @test f(args...) isa T @@ -237,21 +239,22 @@ af = Arblib.ArbCall.ArbFPWrapFunction( "int arb_fpwrap_double_bessel_j(double * res, double nu, double x, int flags)", ) - eval(Arblib.ArbCall.jlcode(af)) + # Use a different name to avoid overwriting existing function + eval(Arblib.ArbCall.jlcode(af, Symbol(Arblib.ArbCall.jlfname(af), :_test))) # Test that it errors on failure - @test !isnan(Arblib.fpwrap_bessel_j(1.0, 1e40)) - @test isnan(Arblib.fpwrap_bessel_j(1.0, 1e40, work_limit = 1)) - @test_throws ErrorException Arblib.fpwrap_bessel_j( + @test !isnan(fpwrap_bessel_j_test(1.0, 1e40)) + @test isnan(fpwrap_bessel_j_test(1.0, 1e40, work_limit = 1)) + @test_throws ErrorException fpwrap_bessel_j_test( 1.0, 1e40, error_on_failure = true, work_limit = 1, ) Arblib.ArbCall.fpwrap_error_on_failure_default_set(true) - @test_throws ErrorException Arblib.fpwrap_bessel_j(1.0, 1e40, work_limit = 1) + @test_throws ErrorException fpwrap_bessel_j_test(1.0, 1e40, work_limit = 1) @test isnan( - Arblib.fpwrap_bessel_j(1.0, 1e40, error_on_failure = false, work_limit = 1), + fpwrap_bessel_j_test(1.0, 1e40, error_on_failure = false, work_limit = 1), ) Arblib.ArbCall.fpwrap_error_on_failure_default_set(false) end diff --git a/test/ArbCall/ArbFunction.jl b/test/ArbCall/ArbFunction.jl index 3be4e77..6c91130 100644 --- a/test/ArbCall/ArbFunction.jl +++ b/test/ArbCall/ArbFunction.jl @@ -33,9 +33,6 @@ ("acb_set_fmpq", :set_fmpq), ("arb_bin_uiui", :bin_uiui), - # Deprecated types - ("arf_set_fmpr", :set_fmpr), - # Underscore methods ("_acb_vec_set", :set), @@ -160,7 +157,7 @@ ( "void arb_add(arb_t z, const arb_t x, const arb_t y, slong prec)", [:(z::$(Arblib.ArbLike)), :(x::$(Arblib.ArbLike)), :(y::$(Arblib.ArbLike))], - [Expr(:kw, :(prec::Integer), :(_precision(z)))], + [Expr(:kw, :(prec::$Integer), :(_precision(z)))], [ :(z::$(Arblib.ArbLike)), :(x::$(Arblib.ArbLike)), @@ -176,8 +173,12 @@ :(y::$(Arblib.ArfLike)), ], [ - Expr(:kw, :(prec::Integer), :(_precision(res))), - Expr(:kw, :(rnd::Union{Arblib.arb_rnd,RoundingMode}), :(RoundNearest)), + Expr(:kw, :(prec::$Integer), :(_precision(res))), + Expr( + :kw, + :(rnd::$(Union{Arblib.arb_rnd,RoundingMode})), + :(RoundNearest), + ), ], [ :(res::$(Arblib.ArfLike)), @@ -195,8 +196,12 @@ :(y::$(Arblib.AcfLike)), ], [ - Expr(:kw, :(prec::Integer), :(_precision(res))), - Expr(:kw, :(rnd::Union{Arblib.arb_rnd,RoundingMode}), :(RoundNearest)), + Expr(:kw, :(prec::$Integer), :(_precision(res))), + Expr( + :kw, + :(rnd::$(Union{Arblib.arb_rnd,RoundingMode})), + :(RoundNearest), + ), ], [ :(res::$(Arblib.AcfLike)), @@ -210,8 +215,8 @@ "void arb_lambertw(arb_t res, const arb_t x, int flags, slong prec)", [:(res::$(Arblib.ArbLike)), :(x::$(Arblib.ArbLike))], [ - Expr(:kw, :(flags::Integer), 0), - Expr(:kw, :(prec::Integer), :(_precision(res))), + Expr(:kw, :(flags::$Integer), 0), + Expr(:kw, :(prec::$Integer), :(_precision(res))), ], [ :(res::$(Arblib.ArbLike)), @@ -223,7 +228,7 @@ ( "int _acb_vec_is_zero(acb_srcptr vec, slong len)", [:(vec::$(Arblib.AcbVectorLike))], - [:($(Expr(:kw, :(len::Integer), :(length(vec)))))], + [Expr(:kw, :(len::$Integer), :(length(vec)))], [:(vec::$(Arblib.AcbVectorLike)), :(len::$Integer)], ), ) @@ -244,7 +249,7 @@ :(f::$(Arblib.ArbSeries)), Expr(:kw, :(n::$(Integer)), :(length(res))), ], - [Expr(:kw, :(prec::Integer), :(_precision(res)))], + [Expr(:kw, :(prec::$Integer), :(_precision(res)))], ), ( "void acb_poly_div_series(acb_poly_t Q, const acb_poly_t A, const acb_poly_t B, slong n, slong prec)", @@ -252,9 +257,9 @@ :(Q::$(Arblib.AcbSeries)), :(A::$(Arblib.AcbSeries)), :(B::$(Arblib.AcbSeries)), - Expr(:kw, :(n::$(Integer)), :(length(Q))), + Expr(:kw, :(n::$Integer), :(length(Q))), ], - [Expr(:kw, :(prec::Integer), :(_precision(Q)))], + [Expr(:kw, :(prec::$Integer), :(_precision(Q)))], ), ( "void acb_hypgeom_u_1f1_series(acb_poly_t res, const acb_poly_t a, const acb_poly_t b, const acb_poly_t z, slong len, slong prec)", @@ -263,9 +268,9 @@ :(a::$(Arblib.AcbSeries)), :(b::$(Arblib.AcbSeries)), :(z::$(Arblib.AcbSeries)), - Expr(:kw, :(len::$(Integer)), :(length(res))), + Expr(:kw, :(len::$Integer), :(length(res))), ], - [Expr(:kw, :(prec::Integer), :(_precision(res)))], + [Expr(:kw, :(prec::$Integer), :(_precision(res)))], ), ( "void arb_poly_mullow(arb_poly_t C, const arb_poly_t A, const arb_poly_t B, slong n, slong prec)", @@ -273,9 +278,9 @@ :(C::$(Arblib.ArbSeries)), :(A::$(Arblib.ArbSeries)), :(B::$(Arblib.ArbSeries)), - Expr(:kw, :(n::$(Integer)), :(length(C))), + Expr(:kw, :(n::$Integer), :(length(C))), ], - [Expr(:kw, :(prec::Integer), :(_precision(C)))], + [Expr(:kw, :(prec::$Integer), :(_precision(C)))], ), ) @test (args, kwargs) == diff --git a/test/ArbCall/Carg.jl b/test/ArbCall/Carg.jl index 5115710..7deb60b 100644 --- a/test/ArbCall/Carg.jl +++ b/test/ArbCall/Carg.jl @@ -8,35 +8,10 @@ @testset "Parsing" begin # Supported types for (str, name, isconst, jltype, ctype) in ( - ("mag_t res", :res, false, Arblib.MagLike, Ref{mag_struct}), - ("arf_t res", :res, false, Arblib.ArfLike, Ref{arf_struct}), - ("acf_t res", :res, false, Arblib.AcfLike, Ref{acf_struct}), - ("arb_t res", :res, false, Arblib.ArbLike, Ref{arb_struct}), - ("acb_t res", :res, false, Arblib.AcbLike, Ref{acb_struct}), - ("const mag_t x", :x, true, Arblib.MagLike, Ref{mag_struct}), - ("const arf_t x", :x, true, Arblib.ArfLike, Ref{arf_struct}), - ("const arb_t x", :x, true, Arblib.ArbLike, Ref{arb_struct}), - ("const acb_t x", :x, true, Arblib.AcbLike, Ref{acb_struct}), - ( - "arf_rnd_t rnd", - :rnd, - false, - Union{Arblib.arb_rnd,RoundingMode}, - Arblib.arb_rnd, - ), - ("mpfr_t x", :x, false, BigFloat, Ref{BigFloat}), - ( - "mpfr_rnd_t rnd", - :rnd, - false, - Union{Base.MPFR.MPFRRoundingMode,RoundingMode}, - Base.MPFR.MPFRRoundingMode, - ), - ("mpz_t x", :x, false, BigInt, Ref{BigInt}), ("int flags", :flags, false, Integer, Cint), ("slong x", :x, false, Integer, Int), ("ulong x", :x, false, Unsigned, UInt), - ("double x", :x, false, Base.GMP.CdoubleMax, Cdouble), + ("double x", :x, false, Union{Float16,Float32,Float64}, Float64), ( "complex_double x", :x, @@ -44,21 +19,14 @@ Union{ComplexF16,ComplexF32,ComplexF64}, ComplexF64, ), - ("slong * x", :x, false, Vector{<:Integer}, Ref{Int}), - ("ulong * x", :x, false, Vector{<:Unsigned}, Ref{UInt}), - ("double * x", :x, false, Vector{<:Base.GMP.CdoubleMax}, Ref{Float64}), - ( - "complex_double * x", - :x, - false, - Vector{<:Union{ComplexF16,ComplexF32,ComplexF64}}, - Ref{ComplexF64}, - ), + ("void * L", :L, false, Ptr{Cvoid}, Ptr{Cvoid}), ("const char * inp", :inp, true, AbstractString, Cstring), - ("arb_ptr v", :v, false, Arblib.ArbVectorLike, Ptr{arb_struct}), - ("arb_srcptr res", :res, true, Arblib.ArbVectorLike, Ptr{arb_struct}), - ("acb_ptr v", :v, false, Arblib.AcbVectorLike, Ptr{acb_struct}), - ("acb_srcptr res", :res, true, Arblib.AcbVectorLike, Ptr{acb_struct}), + ("slong * x", :x, false, Vector{Int}, Ref{Int}), + ("ulong * x", :x, false, Vector{UInt}, Ref{UInt}), + ("double * x", :x, false, Vector{Float64}, Ref{Float64}), + ("complex_double * x", :x, false, Vector{ComplexF64}, Ref{ComplexF64}), + ("mpz_t x", :x, false, BigInt, Ref{BigInt}), + ("mpfr_t x", :x, false, BigFloat, Ref{BigFloat}), ( "mpfr_rnd_t rnd", :rnd, @@ -66,20 +34,27 @@ Union{Base.MPFR.MPFRRoundingMode,RoundingMode}, Base.MPFR.MPFRRoundingMode, ), + ("mag_t res", :res, false, Arblib.MagLike, Ref{mag_struct}), + ("const mag_t x", :x, true, Arblib.MagLike, Ref{mag_struct}), + ("arf_t res", :res, false, Arblib.ArfLike, Ref{arf_struct}), + ("const arf_t x", :x, true, Arblib.ArfLike, Ref{arf_struct}), ( - "arb_mat_t mat", - :mat, - false, - Arblib.ArbMatrixLike, - Ref{Arblib.arb_mat_struct}, - ), - ( - "acb_mat_t mat", - :mat, + "arf_rnd_t rnd", + :rnd, false, - Arblib.AcbMatrixLike, - Ref{Arblib.acb_mat_struct}, + Union{Arblib.arb_rnd,RoundingMode}, + Arblib.arb_rnd, ), + ("acf_t res", :res, false, Arblib.AcfLike, Ref{acf_struct}), + ("const acf_t res", :res, true, Arblib.AcfLike, Ref{acf_struct}), + ("arb_t res", :res, false, Arblib.ArbLike, Ref{arb_struct}), + ("const arb_t x", :x, true, Arblib.ArbLike, Ref{arb_struct}), + ("arb_ptr v", :v, false, Arblib.ArbVectorLike, Ptr{arb_struct}), + ("arb_srcptr res", :res, true, Arblib.ArbVectorLike, Ptr{arb_struct}), + ("acb_t res", :res, false, Arblib.AcbLike, Ref{acb_struct}), + ("const acb_t x", :x, true, Arblib.AcbLike, Ref{acb_struct}), + ("acb_ptr v", :v, false, Arblib.AcbVectorLike, Ptr{acb_struct}), + ("acb_srcptr res", :res, true, Arblib.AcbVectorLike, Ptr{acb_struct}), ( "arb_poly_t mat", :mat, @@ -94,6 +69,20 @@ Arblib.AcbPolyLike, Ref{Arblib.acb_poly_struct}, ), + ( + "arb_mat_t mat", + :mat, + false, + Arblib.ArbMatrixLike, + Ref{Arblib.arb_mat_struct}, + ), + ( + "acb_mat_t mat", + :mat, + false, + Arblib.AcbMatrixLike, + Ref{Arblib.acb_mat_struct}, + ), ) arg = Arblib.ArbCall.Carg(str) @test Arblib.ArbCall.name(arg) == name @@ -103,13 +92,7 @@ end # Unsupported types - for str in ( - "FILE * file", - "fmpr_t x", - "fmpr_rnd_t rnd", - "flint_rand_t state", - "bool_mat_t mat", - ) + for str in ("FILE * file", "flint_rand_t state") @test_throws Arblib.ArbCall.UnsupportedArgumentType arg = Arblib.ArbCall.Carg(str) end @@ -117,12 +100,11 @@ # Unimplemented types for str in ( "fmpz_t x", - "fmpq_t x", - "mag_ptr res", "const fmpz_t x", + "fmpq_t x", "const fmpq_t x", + "mag_ptr res", "mag_srcptr res", - # Internal types "mp_limb_t lo", "mp_bitcnt_t r", @@ -142,12 +124,12 @@ @testset "arbsignature" begin for str in ( + "slong prec", + "ulong y", "arf_t x", - "arb_t x", "const arf_t y", + "arb_t x", "const arb_t x", - "slong prec", - "ulong y", "arb_ptr res", "arb_srcptr poly", "acb_ptr res", @@ -168,13 +150,13 @@ first_carg3 = Arblib.ArbCall.Carg("mag_t res") first_carg4 = Arblib.ArbCall.Carg("int n") @test Arblib.ArbCall.extract_precision_argument(carg, first_carg1) == - Expr(:kw, :(prec::Integer), :(_precision(res))) + Expr(:kw, :(prec::$Integer), :(_precision(res))) @test Arblib.ArbCall.extract_precision_argument(carg, first_carg2) == - Expr(:kw, :(prec::Integer), :(_precision(z))) + Expr(:kw, :(prec::$Integer), :(_precision(z))) @test Arblib.ArbCall.extract_precision_argument(carg, first_carg3) == - :(prec::Integer) + :(prec::$Integer) @test Arblib.ArbCall.extract_precision_argument(carg, first_carg4) == - :(prec::Integer) + :(prec::$Integer) @test_throws ArgumentError Arblib.ArbCall.extract_precision_argument( Arblib.ArbCall.Carg("int prec"), first_carg1, @@ -187,7 +169,7 @@ @test !Arblib.ArbCall.is_flag_argument(Arblib.ArbCall.Carg("int n")) @test Arblib.ArbCall.extract_flag_argument(Arblib.ArbCall.Carg("int flags")) == - Expr(:kw, :(flags::Integer), 0) + Expr(:kw, :(flags::$Integer), 0) @test_throws ArgumentError Arblib.ArbCall.extract_flag_argument( Arblib.ArbCall.Carg("slong flag"), ) @@ -202,12 +184,12 @@ @test Arblib.ArbCall.extract_rounding_argument( Arblib.ArbCall.Carg("arf_rnd_t rnd"), - ) == Expr(:kw, :(rnd::Union{Arblib.arb_rnd,RoundingMode}), :(RoundNearest)) + ) == Expr(:kw, :(rnd::$(Union{Arblib.arb_rnd,RoundingMode})), :(RoundNearest)) @test Arblib.ArbCall.extract_rounding_argument( Arblib.ArbCall.Carg("mpfr_rnd_t rnd"), ) == Expr( :kw, - :(rnd::Union{Base.MPFR.MPFRRoundingMode,RoundingMode}), + :(rnd::$(Union{Base.MPFR.MPFRRoundingMode,RoundingMode})), :(RoundNearest), ) @test_throws ArgumentError Arblib.ArbCall.extract_rounding_argument( @@ -234,11 +216,11 @@ @test Arblib.ArbCall.extract_length_argument(carg1, prev_carg) == - :($(Expr(:kw, :(lenA::Integer), :(length(A))))) + :($(Expr(:kw, :(lenA::$Integer), :(length(A))))) @test_throws ArgumentError Arblib.ArbCall.extract_length_argument( carg4, prev_carg, - ) == :($(Expr(:kw, :(lenA::Integer), :(length(A))))) + ) == :($(Expr(:kw, :(lenA::$Integer), :(length(A))))) end @testset "fpwrap_res_argument" begin diff --git a/test/runtests.jl b/test/runtests.jl index 311f064..e90942a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -24,7 +24,21 @@ DocMeta.setdocmeta!(Arblib, :DocTestSetup, :(using Arblib); recursive = true) # ArbSeries and AcbSeries. Aqua.test_all( Arblib, - ambiguities = (exclude = [Mag, Arf, Acf, Arb, Acb, ArbSeries, AcbSeries, +, *],), + ambiguities = ( + exclude = [ + Mag, + NFloat, + NFloatRef, + Arf, + Acf, + Arb, + Acb, + ArbSeries, + AcbSeries, + +, + *, + ], + ), ) include("ArbCall/runtests.jl")