|
| 1 | +const NCONSTYLE = "Valid ncon style network" |
| 2 | + |
1 | 3 | # check if a list of indices specifies a tensor contraction in ncon style |
2 | 4 | function isnconstyle(network) |
| 5 | + return _nconstyle_error(network) == NCONSTYLE |
| 6 | +end |
| 7 | + |
| 8 | +function _nconstyle_error(network) |
3 | 9 | allindices = Vector{Int}() |
4 | 10 | for ind in network |
5 | | - all(i -> isa(i, Integer), ind) || return false |
| 11 | + all(i -> isa(i, Integer), ind) || return "All indices must be integers" |
6 | 12 | append!(allindices, ind) |
7 | 13 | end |
8 | 14 | while length(allindices) > 0 |
9 | 15 | i = pop!(allindices) |
10 | 16 | if i > 0 # positive labels represent contractions or traces and should appear twice |
11 | 17 | k = findfirst(isequal(i), allindices) |
12 | | - k === nothing && return false |
| 18 | + k === nothing && return "Index $i appears only once in the network" |
13 | 19 | l = findnext(isequal(i), allindices, k + 1) |
14 | | - l !== nothing && return false |
| 20 | + l !== nothing && return "Index $i appears more than twice in the network" |
15 | 21 | deleteat!(allindices, k) |
16 | 22 | elseif i < 0 # negative labels represent open indices and should appear once |
17 | | - findfirst(isequal(i), allindices) === nothing || return false |
| 23 | + findfirst(isequal(i), allindices) === nothing || return "Index $i appears more than once in the network" |
18 | 24 | else # i == 0 |
19 | | - return false |
| 25 | + return "Index 0 is not allowed in the network" |
20 | 26 | end |
21 | 27 | end |
22 | | - return true |
| 28 | + return NCONSTYLE |
| 29 | +end |
| 30 | + |
| 31 | +function nconstylecheck(network) |
| 32 | + err = _nconstyle_error(network) |
| 33 | + err === NCONSTYLE || throw(ArgumentError(err)) |
| 34 | + return nothing |
23 | 35 | end |
24 | 36 |
|
25 | 37 | function ncontree(network) |
|
0 commit comments