Skip to content

Commit 701d90f

Browse files
committed
solved ambiguities by adding 'oncoeffs' for half of uses of merge and some methods
1 parent 42bf9dc commit 701d90f

File tree

3 files changed

+91
-86
lines changed

3 files changed

+91
-86
lines changed

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
name = "ModuleElts"
22
uuid = "4249f315-58d4-4c46-b324-3577fc7dfca0"
33
authors = ["Jean Michel <jean.michel@imj-prg.fr>"]
4-
version = "0.1.3"
4+
version = "0.1.4"
55

66
[deps]
77
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
88

99
[compat]
1010
LinearAlgebra = "1"
11+
Test = "1.6"
1112
julia = "1"
1213

1314
[extras]

README.md

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
**`ModuleElts`** &mdash; *Module*.
33

44

5-
65
Module Elements –- elements of free modules.
76

8-
A `ModuleElt{K,V}` represents an element of a free module where basis elements are of type `K` and coefficients of type `V`. Usually you want objects of type `V` to be elements of a (non-necessarily commutative) ring, but it could also be useful if they just belong to an abelian group. This is similar to the SageMath CombinatorialFreeModule. You can also see them as `SparseVector`s where keys can be of type `K` instead of integers.
7+
A `ModuleElt{K,V}` represents an element of a free module where the basis elements are of type `K` and the coefficients are of type `V`. Usually you want objects of type `V` to be elements of a (not necessarily commutative) ring, but it can also be useful if they just belong to an abelian group. This is similar to the SageMath CombinatorialFreeModule. You can also think of them as `SparseVector`s, where the keys can be of type `K` instead of integers.
98

10-
This basic data structure is used in my packages as an efficient representation at many places. For example, the `Monomial` type representing multivariate monomials is a `ModuleElt{Symbol,Int}`:
9+
This basic data structure is used in many places in my packages as an efficient representation. For example, the type `Monomial`, which represents multivariate monomials is a `ModuleElt{Symbol,Int}`:
1110

1211
`x^2y^-3` is represented by `ModuleElt(:x=>2,:y=>-3)`
1312

@@ -23,19 +22,19 @@ We provide two implementations:
2322

2423
* `HModuleElt`, an implementation by `Dict`s
2524

26-
This requires that the type `K` is hashable. It is a very simple implementation since the interface of the type is close to that of dicts; the only difference is weeding out keys which have a zero cofficient –- which is necessary since for testing equality of module elements one needs a canonical form for each element.
25+
This requires the type `K` to be hashable. This is a very simple implementation since the interface of the type is close to that of dicts; the only difference is that keys with cofficient zero are discarded –- which is necessary, since for checking the equality of module elements one needs a canonical form for each element.
2726

2827
* `ModuleElt`, a faster implementation by a vector of pairs sorted by key.
2928

30-
This requires that the type `K` has a `isless` method. This implementation is two to four times faster than the `Dict` one and requires half the memory.
29+
This requires that the type `K` has an `isless` method. This implementation is two to four times faster than the `Dict` implementation and requires half the memory.
3130

32-
Both implementations have the same methods, which are mostly the same methods as a `Dict` (`haskey`, `getindex`, `setindex`, `keys`, `values`. `pairs`, `first`, `iterate`, `length`, `eltype`, `copy`), with some exceptions. Adding elements is implemented as `merge(+,...)` which is a variation on `merge` for `Dict`s where keys with zero value are deleted after the operation (here `+` can be replaced by any operation `op` with the property that `op(0,x)=op(x,0)=x`).
31+
Both implementations have the same methods, which are mostly the same methods as a `Dict` (`haskey`, `getindex`, `setindex`, `keys`, `values`. `pairs`, `first`, `iterate`, `length`, `eltype`, `copy`), with some exceptions. Adding elements is implemented as `merge(+,...)` which is a variation on `merge` for `Dict`s where keys with coefficient zero are discarded after the operation (here `+` can be replaced by any operation `op` with the property that `op(0,x)=op(x,0)=x`).
3332

34-
A module element can also be negated, or multiplied or divided (`/`or `//` or `\`) by some element (acting on coefficients) if the method is defined between type `V` and that element; the order of the arguments is respected, which allows to implement left and right modules when multiplication for `V` is non-commutative. There are also `zero` and `iszero` methods.
33+
A module element can also be negated, or multiplied or divided (`/`or `//` or `\`) by any element (acting on coefficients) if the method is defined between the type `V` and that element; the order of the arguments is respected, which allows to implement left and right modules if the multiplication is not commutative for `V`. There are also `zero` and `iszero` methods.
3534

3635
`ModuleElt`s have methods `cmp` and `isless` which `HModuleElt`s don't have (the definition is lexicographic order). There is also `ModuleElts.merge2` which does the same as merge but is valid for more general operations – thus is more expensive since it needs more checks for zero results (I use it with `min` and `max` which implement `gcd` and `lcm` for `Monomial`s and `CycPol`s).
3736

38-
We show now an an example; here basis elements are `Symbol`s and coefficients are `Int`. As you can see in the examples, at the REPL (or in Jupyter or Pluto, when `IO` has the `:limit` attribute) the `show` method gives a nice display where the coefficients (bracketed if necessary, which is when they have inner occurences of `+-*/`) preced the keys. The `repr` method gives a representation which can be read back in julia:
37+
We now show an an example; here the basis elements are `Symbol`s and the coefficients are `Int`. As you can see from the examples, at the REPL (or in Jupyter or Pluto, when `IO` has the `:limit` attribute) the `show` method gives a nice display where the coefficients (bracketed if necessary, that is when they have inner occurrences of `+-*/`) precede the keys. The `repr` method gives a representation which can be read back in julia:
3938

4039
```julia-repl
4140
julia> a=ModuleElt(:xy=>1,:yx=>-1)
@@ -113,7 +112,7 @@ julia> eltype(a)
113112
Pair{Symbol, Int64}
114113
```
115114

116-
In both implementations the constructor normalizes the constructed element, removing zero coefficients and merging duplicate basis elements, adding the corresponding coefficients (and sorting the basis in the default implementation). If you know this normalisation is unnecessary, to get maximum speed you can disable this by giving the keyword `check=false` to the constructor.
115+
In both implementations the constructor normalises the constructed element, removing zero coefficients and merging duplicate basis elements, adding the corresponding coefficients (and sorting the basis in the default implementation). If you know that this normalisation is unnecessary, you can disable it for maximum speed by passing the keyword `check=false` to the constructor.
117116

118117
```julia-repl
119118
julia> a=ModuleElt(:yy=>1, :yx=>2, :xy=>3, :yy=>-1;check=false)
@@ -123,27 +122,27 @@ julia> a=ModuleElt(:yy=>1, :yx=>2, :xy=>3, :yy=>-1)
123122
3:xy+2:yx
124123
```
125124

126-
Adding or subtracting `ModuleElt`s does promotion on the type of the keys and the coefficients if needed:
125+
Adding or subtracting `ModuleElt`s does promotion on the type of the keys and the coefficients, if needed:
127126

128127
```julia-repl
129128
julia> a+ModuleElt([:z=>1.0])
130129
3.0:xy+2.0:yx+1.0:z
131130
```
132131

133132

134-
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/6864a7ae33c8167bec30dd4f058e1cceab6d7536/src/ModuleElts.jl#L1-L171' class='documenter-source'>source</a><br>
133+
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/42bf9dcb247a7c08d9c6015068475ddd9b32784b/src/ModuleElts.jl#L1-L173' class='documenter-source'>source</a><br>
135134

136135
<a id='ModuleElts.ModuleElt' href='#ModuleElts.ModuleElt'>#</a>
137136
**`ModuleElts.ModuleElt`** &mdash; *Type*.
138137

139138

140139

141-
`ModuleElt{K,V}` has a similar interface to `Dict{K,V}`, but instead of assuming that `K` is hashable, it assumes that `K` is sortable. It also has the advantage that ModuleElts are naturally sortable.
140+
`ModuleElt{K,V}` has a similar interface to `Dict{K,V}`, but instead of assuming that `K` is hashable, it assumes that `K` is sortable. This also has the advantage that ModuleElts are naturally sortable.
142141

143-
The only field, a `Vector{Pair{K,V}}`, is kept sorted by `K`; the constructor by default checks sorting, adds values with same key, and suppresses keys with zero value. This can be bypassed by the keyword `check=false`.
142+
The only field, a `Vector{Pair{K,V}}`, is kept sorted by `K`; by default, the constructor checks sorting, adds values with the same key, and deletes keys with zero value. This can be overriden with the keyword `check=false`.
144143

145144

146-
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/6864a7ae33c8167bec30dd4f058e1cceab6d7536/src/ModuleElts.jl#L215-L224' class='documenter-source'>source</a><br>
145+
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/42bf9dcb247a7c08d9c6015068475ddd9b32784b/src/ModuleElts.jl#L217-L225' class='documenter-source'>source</a><br>
147146

148147
<a id='Base.merge-Tuple{Function, ModuleElt, ModuleElt}' href='#Base.merge-Tuple{Function, ModuleElt, ModuleElt}'>#</a>
149148
**`Base.merge`** &mdash; *Method*.
@@ -163,7 +162,7 @@ The code is only valid for `op`s such that `op(0,x)=op(x,0)=x` otherwise the
163162
`merge(op,m::ModuleElt)` does `v->op(v)` on the values of `m`.
164163

165164

166-
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/6864a7ae33c8167bec30dd4f058e1cceab6d7536/src/ModuleElts.jl#L253-L268' class='documenter-source'>source</a><br>
165+
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/42bf9dcb247a7c08d9c6015068475ddd9b32784b/src/ModuleElts.jl#L254-L269' class='documenter-source'>source</a><br>
167166

168167
<a id='ModuleElts.merge2' href='#ModuleElts.merge2'>#</a>
169168
**`ModuleElts.merge2`** &mdash; *Function*.
@@ -172,28 +171,28 @@ The code is only valid for `op`s such that `op(0,x)=op(x,0)=x` otherwise the
172171

173172
`merge2(op::Function,a::ModuleElt,b::ModuleElt)`
174173

175-
does `op` between coefficients of the same basis element in `a` and `b`. This version works for general ops (not necessarily commutative or which need not satisfy op(0,x)=op(x,0)=x), but has too much overhead currently to replace `merge` for + or other ops such that op(0,x)==op(x,0)=x. It is useful for max or min which do lcm and gcd of `Monomial`s or `CycPol`s.
174+
does `op` between coefficients of the same basis element in `a` and `b`. This version works for general ops (not necessarily commutative or not satisfying op(0,x)=op(x,0)=x). It currently has too much overhead to replace `merge` for + or other ops such that op(0,x)==op(x,0)=x. It is useful for max or min which do lcm and gcd of `Monomial`s or `CycPol`s.
176175

177176

178-
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/6864a7ae33c8167bec30dd4f058e1cceab6d7536/src/ModuleElts.jl#L291-L299' class='documenter-source'>source</a><br>
177+
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/42bf9dcb247a7c08d9c6015068475ddd9b32784b/src/ModuleElts.jl#L292-L300' class='documenter-source'>source</a><br>
179178

180179
<a id='Base.getindex-Tuple{ModuleElt, Any}' href='#Base.getindex-Tuple{ModuleElt, Any}'>#</a>
181180
**`Base.getindex`** &mdash; *Method*.
182181

183182

184183

185-
`getindex(x::ModuleElt,key)` returns the value associated to the given `key` in `x`. It returns zero if the key does not occur in `x`.
184+
`getindex(x::ModuleElt,key)` returns the value in `x` associated with the `given key`. It returns zero if the key does not occur in `x`.
186185

187186

188-
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/6864a7ae33c8167bec30dd4f058e1cceab6d7536/src/ModuleElts.jl#L340-L343' class='documenter-source'>source</a><br>
187+
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/42bf9dcb247a7c08d9c6015068475ddd9b32784b/src/ModuleElts.jl#L341-L344' class='documenter-source'>source</a><br>
189188

190189
<a id='Base.setindex!-Tuple{ModuleElt, Any, Any}' href='#Base.setindex!-Tuple{ModuleElt, Any, Any}'>#</a>
191190
**`Base.setindex!`** &mdash; *Method*.
192191

193192

194193

195-
`setindex!(x::ModuleElt,v,key)` sets `v` as the value associated to the given `key` in `x`. Setting a value to zero or for a new key is expensive.
194+
`setindex!(x::ModuleElt,v,key)` sets `v` as the value in `x` associated with the given `key`. Setting a value to zero or for a new key is expensive.
196195

197196

198-
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/6864a7ae33c8167bec30dd4f058e1cceab6d7536/src/ModuleElts.jl#L350-L353' class='documenter-source'>source</a><br>
197+
<a target='_blank' href='https://github.com/jmichel7/ModuleElts.jl/blob/42bf9dcb247a7c08d9c6015068475ddd9b32784b/src/ModuleElts.jl#L351-L355' class='documenter-source'>source</a><br>
199198

0 commit comments

Comments
 (0)