Skip to content

Commit

Permalink
Merge 350aee1 into 6c29bfa
Browse files Browse the repository at this point in the history
  • Loading branch information
raulepure committed Oct 17, 2019
2 parents 6c29bfa + 350aee1 commit 9e6484d
Show file tree
Hide file tree
Showing 16 changed files with 766 additions and 17 deletions.
34 changes: 32 additions & 2 deletions deps/src/coeffs.cpp
@@ -1,10 +1,36 @@
#include "coeffs.h"

auto transExt_helper(coeffs cf, jlcxx::ArrayRef<uint8_t *> param)
{
auto len = param.size();
char ** param_ptr = new char *[len];
for (int i = 0; i < len; i++) {
param_ptr[i] = reinterpret_cast<char *>(param[i]);
}
ring r = rDefault(cf, len, param_ptr);
r->order[0] = ringorder_dp;
delete[] param_ptr;
TransExtInfo extParam;
extParam.r = r;
return nInitChar(n_transExt, &extParam);
}

auto transExt_to_poly(number a, coeffs cf, ring r)
{
assume(cf->extRing != NULL);
ring ext = cf->extRing;
fraction f = (fraction)a;
nMapFunc nMap = n_SetMap(ext->cf, r->cf);
rChangeCurrRing(r);
return p_PermPoly(f->numerator, NULL, ext, r, nMap, NULL);
}
void singular_define_coeffs(jlcxx::Module & Singular)
{
/* initialise a coefficient ring */
Singular.method("nInitChar", &nInitChar);

/* Helper to construct transcendental Extensions */
Singular.method("transExt_helper", &transExt_helper);
Singular.method("transExt_to_poly", &transExt_to_poly);
/* get the characteristic of a coefficient domain */
Singular.method("n_GetChar", [](coeffs n) { return n_GetChar(n); });

Expand All @@ -20,6 +46,11 @@ void singular_define_coeffs(jlcxx::Module & Singular)
return reinterpret_cast<void *>(n_SetMap(x, y));
});

/* Identity function on coefficient ring */
Singular.method("ndCopyMap", []() {
return reinterpret_cast<void *>(ndCopyMap);
});

Singular.method("nApplyMapFunc",
[](void * map, snumber * x, coeffs a, coeffs b) {
return reinterpret_cast<nMapFunc>(map)(x, a, b);
Expand Down Expand Up @@ -209,5 +240,4 @@ void singular_define_coeffs(jlcxx::Module & Singular)
Singular.method("mpz_init_set_si_internal", [](void* x, long y ){
mpz_init_set_si(reinterpret_cast<mpz_ptr>(x),y);
});

}
1 change: 1 addition & 0 deletions deps/src/coeffs.h
@@ -1,5 +1,6 @@
#ifndef COEFFS_INCLUDE
#define COEFFS_INCLUDE
#define TRANSEXT_PRIVATES

#include "includes.h"

Expand Down
5 changes: 2 additions & 3 deletions deps/src/ideals.cpp
Expand Up @@ -232,10 +232,9 @@ void singular_define_ideals(jlcxx::Module & Singular)
return h;
});
Singular.method("maMapIdeal", [](ideal map_id, ring pr, ideal im_id,
ring im) {

ring im, void * cf_map) {
rChangeCurrRing(pr);
return maMapIdeal(map_id, pr, im_id, im, ndCopyMap);
return maMapIdeal(map_id, pr, im_id, im, reinterpret_cast<nMapFunc>(cf_map));
});
Singular.method("idMinBase", [](ideal I, ring r) {
rChangeCurrRing(r);
Expand Down
3 changes: 3 additions & 0 deletions deps/src/includes.h
Expand Up @@ -26,6 +26,8 @@
#include <polys/monomials/ring.h>
#include <polys/monomials/p_polys.h>
#include <polys/simpleideals.h>
#include "polys/ext_fields/algext.h"
#include "polys/ext_fields/transext.h"
#include <kernel/GBEngine/kstd1.h>
#include <kernel/GBEngine/syz.h>
#include <kernel/GBEngine/tgb.h>
Expand All @@ -39,6 +41,7 @@
#include <Singular/ipid.h>
#include <Singular/subexpr.h>
#include <Singular/lists.h>
#include "Singular/maps_ip.h"
#include <Singular/idrec.h>
#include <Singular/tok.h>
#include <Singular/links/silink.h>
Expand Down
10 changes: 7 additions & 3 deletions deps/src/rings.cpp
Expand Up @@ -72,6 +72,10 @@ void singular_define_rings(jlcxx::Module & Singular)
});
Singular.method("rBitmask",
[](ip_sring * r) { return (unsigned int)r->bitmask; });
Singular.method("rPar", [](coeffs cf){
coeffs cf_ptr = nCopyCoeff(cf);
return n_NumberOfParameters(cf_ptr);
});
Singular.method("p_Delete", [](spolyrec * p, ip_sring * r) {
return p_Delete(&p, r);
});
Expand Down Expand Up @@ -293,9 +297,9 @@ void singular_define_rings(jlcxx::Module & Singular)
return p_Diff(p_cp, i, r);
});
Singular.method("maMapPoly",
[](poly map_p, ring pr, ideal im_id, ring im) {
rChangeCurrRing(pr);
return maMapPoly(map_p, pr, im_id, im, ndCopyMap);
[](poly map_p, ring pr, ideal im_id, ring im, void * cf_map) {
rChangeCurrRing(pr);
return maMapPoly(map_p, pr, im_id, im, reinterpret_cast<nMapFunc>(cf_map));
});
Singular.method("p_GetOrder",
[](poly p, ring r) {
Expand Down
1 change: 1 addition & 0 deletions deps/src/singular.cpp
Expand Up @@ -38,6 +38,7 @@ JLCXX_MODULE define_julia_module(jlcxx::Module & Singular)
Singular.set_const("n_Zn", n_Zn);
Singular.set_const("n_Zp", n_Zp);
Singular.set_const("n_GF", n_GF);
Singular.set_const("n_transExt", n_transExt);
Singular.set_const("n_unknown", n_unknown);
Singular.add_type<snumber>("number");
Singular.add_type<__mpz_struct>("__mpz_struct");
Expand Down
1 change: 1 addition & 0 deletions docs/make.jl
Expand Up @@ -13,6 +13,7 @@ makedocs(
"rational.md",
"modn.md",
"modp.md",
"transExt.md",
"GF.md",
"nemo.md"
],
Expand Down
115 changes: 115 additions & 0 deletions docs/src/transExt.md
@@ -0,0 +1,115 @@
```@meta
CurrentModule = Singular
```

# Function fields

Function fields are implemented via the Singular `n_transExt` type for prime fields of any characteristic.

The associated function field is represented by a parent object which can be constructed
by a call to the `FunctionField` constructor.

The types of the parent objects and elements of the associated function fields are given
in the following table according to the library providing them.

Library | Element type | Parent type
----------------|---------------|--------------------
Singular | `n_transExt` | `Singular.N_FField`

All function field element types belong directly to the abstract type `FieldElem` and
all the parent object types belong to the abstract type `Field`.

## Function field functionality

Singular.jl function fields implement the Field interface of AbstractAlgebra.jl.

[https://nemocas.github.io/AbstractAlgebra.jl/fields.html](https://nemocas.github.io/AbstractAlgebra.jl/fields.html)

Below, we describe the functionality that is specific to Singular function field and not
already listed at the given link.

### Constructors

The following constructors are available to create function fields and their elements.

```@docs
Singular.FunctionField(::Field, ::Array{String, 1}; ::Bool)
```

In case the user does not want to specify a transcendece basis the following
constructor can be used.

```@docs
Singular.FunctionField(::Field, ::Int; ::Bool)
```

Given a function field $F$, we also have the following coercions in addition to the
standard ones expected.

```julia
F(n::fmpz)
```

Coerce a Flint integer value into the field.

**Examples**

```julia
F1, (a, b, c) = FunctionField(QQ, ["a", "b", "c"])

x1 = a*b + c

F2, (a1, a2, a3) = FunctionField(Fp(5), 3)

x2 = a1^5 + a2*a3^4
```

### Basic manipulation

```@docs
numerator(::n_transExt)
```

```@docs
denominator(::n_transExt)
```

```@docs
Singular.transcendence_degree(::N_FField)
```

```@docs
Singular.transcendence_basis(::N_FField)
```

```@docs
Singular.characteristic(::N_FField)
```

```@docs
isunit(::n_transExt)
```

```@docs
Singular.n_transExt_to_spoly(::n_transExt)
```

**Examples**

```julia
F1, (a, b, c) = FunctionField(QQ, ["a", "b", "c"])
x = F(5)*a
y = a^2 *b+a*b+b^2

isunit(x)
char = characteristic(F1)
d = transcendence_degree(F1)

S, = PolynomialRing(QQ, ["a", "b", "c"])

p = n_transExt_to_spoly(y, parent_ring = S)

F2, = FunctionField(Fp(7), 4)
B = transcendence_basis(F2)
```

2 changes: 2 additions & 0 deletions src/Number.jl
Expand Up @@ -10,4 +10,6 @@ include("number/n_Zp.jl")

include("number/n_GF.jl")

include("number/n_transExt.jl")

include("number/n_unknown.jl")
2 changes: 1 addition & 1 deletion src/Singular.jl
Expand Up @@ -34,7 +34,7 @@ export base_ring, elem_type, parent_type, parent

export ResidueRing, PolynomialRing, Ideal, MaximalIdeal, FreeModule

export ZZ, QQ, FiniteField, CoefficientRing, Fp
export ZZ, QQ, FiniteField, FunctionField, CoefficientRing, Fp

###############################################################################
#
Expand Down
7 changes: 4 additions & 3 deletions src/map/alghom.jl
Expand Up @@ -30,7 +30,7 @@ function map_ideal(f::Map(SAlgHom), I::sideal)
end

return Ideal(f.codomain, libSingular.maMapIdeal(I.ptr, f.domain.ptr,
f.ptr, f.codomain.ptr))
f.ptr, f.codomain.ptr, libSingular.ndCopyMap()))
end

function map_poly(f::Map(SAlgHom), p::spoly)
Expand All @@ -40,7 +40,7 @@ function map_poly(f::Map(SAlgHom), p::spoly)
algebra homomorphism.")
end
return f.codomain(libSingular.maMapPoly(p.ptr, f.domain.ptr, f.ptr,
f.codomain.ptr))
f.codomain.ptr, libSingular.ndCopyMap()))
end

function (f::SAlgHom)(p::spoly)
Expand Down Expand Up @@ -70,7 +70,8 @@ function compose(f::Map(SAlgHom), g::Map(SAlgHom))
R = g.domain
S = g.codomain

ptr = libSingular.maMapIdeal(f.ptr, R.ptr, g.ptr, S.ptr)
ptr = libSingular.maMapIdeal(f.ptr, R.ptr, g.ptr, S.ptr,
libSingular.ndCopyMap())

V = Array{spoly, 1}()

Expand Down
68 changes: 68 additions & 0 deletions src/number/NumberTypes.jl
Expand Up @@ -366,6 +366,74 @@ function _n_GF_clear_fn(n::n_GF)
nothing
end

###############################################################################
#
# SingularTranscendentalExtensionField/n_transExt
#
###############################################################################

const N_FFieldID = Dict{Tuple{Field, Array{Symbol, 1}}, Field}()

mutable struct N_FField <: Field
ptr::libSingular.coeffs
base_ring::Field
refcount::Int

function N_FField(F::Field, S::Array{Symbol, 1})
if haskey(N_FFieldID, (F, S))
d = N_FFieldID[F, S]::N_FField
else
v = [pointer(Base.Vector{UInt8}(string(str)*"\0")) for str in S]
cf = libSingular.nCopyCoeff(F.ptr)
ptr = libSingular.transExt_helper(cf, v)
d = new(ptr, F, 1)
N_FFieldID[F, S] = d
finalizer(_N_FField_clear_fn, d)
end
return d
end
end

function _N_FField_clear_fn(cf::N_FField)
cf.refcount -= 1
if cf.refcount == 0
libSingular.nKillChar(cf.ptr)
end
end

mutable struct n_transExt <: Nemo.FieldElem
ptr::libSingular.number
parent::N_FField

function n_transExt(c::N_FField)
z = new(libSingular.n_Init(0, c.ptr))
c.refcount += 1
finalizer(_n_transExt_clear_fn, z)
return z
end

function n_transExt(c::N_FField, n::Int)
z = new(libSingular.n_Init(n, c.ptr))
c.refcount += 1
finalizer(_n_transExt_clear_fn, z)
return z
end

function n_transExt(c::N_FField, n::libSingular.number)
z = new(n)
c.refcount += 1
finalizer(_n_transExt_clear_fn, z)
return z
end
end

function _n_transExt_clear_fn(n::n_transExt)
R = parent(n)
libSingular.n_Delete(n.ptr, parent(n).ptr)
_N_FField_clear_fn(R)
nothing
end

###############################################################################
#
# SingularCoefficientRing/n_unknown
Expand Down

0 comments on commit 9e6484d

Please sign in to comment.