Replies: 4 comments 5 replies
-
I don't know what it should do except throwing an error? |
Beta Was this translation helpful? Give feedback.
-
To me the diskussion is in the wrong direction. If there is demand, we can add a sparse-univariate type, following the univariate interface. However, "just swapping in and out" is always tricky: in the dense case, iteration is usually over all coefficients (by degree), while in the sparse case, it is usually only over the non-zero ones. Asymptotically fast methods that apply to the dense case are at best not harmful in the sparse case, ... |
Beta Was this translation helpful? Give feedback.
-
for what it is worth, there is an incomplete sparse univariate in AA. |
Beta Was this translation helpful? Give feedback.
-
I agree it would be nice to have
But I think it is a bad idea, unless we absolutely have to, to treat implicitly mulitivariate types where there is only one variable, as univariate. Discussion is also about access to non-existing coefficients: in all(?) dense versions, non-existing coeffs are always accessible and yield zero. In the multivariate world, non-existing coeffs are errors. If you want a generic interface, this has to be along coeffs + exponents, however, I have a feeling that using this interface for dense polys means one is doing things badly. A user wants this, their choice. |
Beta Was this translation helpful? Give feedback.
-
I have been looking at the polynomial part of AbstractAlgebra and Nemo. The speed is fantastic! But I find that the interface could be more consistent. There are multiple types of polynomial implementations with similar capabilities, but their APIs are not consistent. It would be great if one could replace PolynomialRing(ZZ, "x") with PolynomialRing(ZZ, ["x"]) or LaurentPolynomialRing(ZZ, "x") or LaurentPolynomialRing(ZZ, ["x"]), etc. without breaking any code, say if one suspected that sparse polynomials might do the job faster or if 1/x is needed for new functionality. Maybe some functions don't make sense for all rings, but when they do make sense, it would be great to have them available with consistent names.
I also wonder why shifting of Laurent polynomials and series is split into shift_left and shift_right. How about shift(p, s), where s can have either sign?
Here is a start of some function signatures that ought to make sense for all types of polynomials and series:
PS, s = PolynomialRing(ZZ, "s")
P1, (z,) = PolynomialRing(ZZ, ["z"])
P2, (x,y) = PolynomialRing(ZZ, ["x", "y"])
PU = UniversalPolynomialRing(ZZ)
u = gen(PU, "u")
LS, t = LaurentPolynomialRing(ZZ, "t")
L1, (c,) = LaurentPolynomialRing(ZZ, ["c"])
L2, (a,b) = LaurentPolynomialRing(ZZ, ["a", "b"])
gen(polyring)
gen(PS) == s
gen(P1) == z
gen(P2) # error
gen(PU) # u
gen(LS) == t
gen(L1) == c
gen(L2) # error
gen(polyring, i::Int)
gen(PS, 1) == s
gen(PS, 2) # error
gen(P1, 1) == z
gen(P2, 2) == y
gen(PU, 1) == u
gen(LS, 1) == t
gen(L1, 1) == c
gen(L2, 1) == a
gen(polyring, v::Union{String,Symbol})
gen(PS, "s") == s
gen(PS, :s) == s
gen(P1, "z") == z
gen(P2, :x) == x
gen(P2, "y") == y
gen(PU, "u") == u
gen(LS, :t) == t
gen(L2, "b") == b
gens(polyring, vars::Vector)
gens(PS, ["s"]) == (s,)
gens(P1, ["z"]) == (z,)
gens(P2, ["y"]) == (y,)
gens(P2, ["y", "x"]) == (y, x)
gens(PU, ["u"]) == (u,)
gens(LS, ["t"]) == (t,)
gens(L1, ["c"]) == (c,)
gens(L2, ["a"]) == (a,)
gens(L2, ["a", "b"]) == (a, b)
coeff(poly, e::Int) # get single coefficient
coeff((s+2)^3, 2) == 6
coeff(z, 1) == 1
coeff(x, 1) # error
coeff(u, 1) == 1 # could also be an error, since number of variables can change.
coeff((t - 2t^-1)^3, -1) == 12
coeff((c - 2c^-1)^3, -1) == 12
coeff(a, 1) # error
coeff(poly, exp::Vector{Int}) # get single coefficient
coeff(s, [1]) == 1
coeff(z, [1]) == 1
coeff(x, [1]) # error
coeff(x, [1,0]) == 1
coeff(u, [1]) == 1
coeff(t, [1]) == 1
coeff((a+b)^2, [1,1]) == 2
coeff(poly, vars::Vector, exp::Vector{Int})
coeff(s, [s], [1]) == 1
coeff(u, [u], [1]) == 1
coeff(xy, [x], [1]) == y
coeff(u, [u], [1]) == 1
coeff((c-c^-1)^3, [c], -1) ==
coeff((2a + 3b^-1)^3, [a,b], [1,-2]) == 54
coeff((2a + 3b^-1)^3, [a], [1]) == 54a*b^-2
shift(poly, s::Int)
shift(s, 1) == s^2
shift(s, -1) == 1
shift(s, -2) # error
shift(z, 1) == z^2
shift(x, 1) # error
shift(u, 1) == u^2
shift(t, 1) == t^2
shift(t, -3) == t^-2
shift(c, -2) == c^-1
shift(a, 1) # error
shift(poly, s::Vector{Int})
shift(s, [1]) == s^2
shift(z, [1]) == z^2
shift(x, [1]) # error
shift(x, [-1,2]) == y^2
shift(u, [1]) == u^2
shift(t, [1]) == t^2
shift(c, [1]) == c^2
shift(b, [1,-3]) == a*b^-2
shift(poly, vars::Vector, s::vector{Int})
shift(s, [s], [1]) == s^2
shift(z, [z], [1]) == z^2
shift(x, [x], [1]) == x^2
shift(x, [y,x], [3,-1]) == y^3
shift(u, [u], [1]) == u^2
shift(t, [t], [1]) == t^2
shift(c, [c], [1]) == c^2
shift(a, [b], [-1]) == ab^-1
shift(a, [a,b], [-3,3]) == a^-2b^3
Beta Was this translation helpful? Give feedback.
All reactions