Contents

# Operators and functions for type FAN

&<
```&<(F1::FAN, F2::FAN)::boolean
&>(F2::FAN, F1::FAN)::boolean
F1 &< F2
F2 &> F1
```

Test whether F1 is a proper subfan of F2. F1 and F2 must lie in the same ambient space.

&<=
```&<=(F1::FAN, F2::FAN)::boolean
&<=(F2::FAN, F1::FAN)::boolean
F1 &<= F2
F2 &>= F1
```

Test whether F1 is a subfan of F2. F1 and F2 must lie in the same ambient space.

&<>
```&<>(F1::FAN, F2::FAN)::boolean
F1 &<> F2
```

Test whether F1 and F2 describe different fans. This is true if the fans lie in different ambient spaces.

&=
```&=(F1::FAN, F2::FAN)::boolean
F1 &= F2
```

Test whether F1 and F2 describe the same fan. This is false if the fans lie in different ambient spaces.

&x
```&x(F1::FAN, ...)::FAN
F1::FAN &x F2::FAN
```

The Cartesian product of its arguments. See CONE[&x].

Examples
 FAN[`&x`]() &= zerofan(0);
true
ambientdim
```ambientdim(F::FAN)::nonnegint
```

The dimension of the ambient space.

codim
```codim(F::FAN)::nonnegint
```

The codimension of F is that of the linear hull of its elements. Note that dim(F) and codim(F) do not necessarily add up to ambientdim(F). See also dim and ambientdim.

Examples
 F := fan(poshull([1, 0]), poshull([0, 1]));
F := FAN(2,0,[2, 0])
 dim(F), codim(F), ambientdim(F);
1, 0, 2
contains
```contains(F::FAN, C::CONE)::boolean
contains(F::FAN, C::CONE, C2::name)::boolean
```

Test whether C is contained in the fan F. If there is a third argument C2, it will be assigned the corresponding element of F (of type FANCONE) in this case. It is essentially the same as C, but with the added information that it belongs to a fan.

Examples
 F := fan(posorthant(2));
F := FAN(2,0,[0, 1])
 contains(F, poshull([1, 1]));
false
 C := poshull([1, 0]); contains(F, C, 'C2'); C2;
C := CONE(2,1,0,1,1)
true
FANCONE(2,1,0,1,1)
 C &= C2;
true
convert/PCOMPLEX
```convert(F::FAN, PCOMPLEX)::PCOMPLEX
```

Convert F to a polyhedral complex by "dehomogenizing" it. See CONE[convert/POLYHEDRON].

convert/affine
```convert(F::FAN, affine)::PCOMPLEX
convert(F::FAN, affine, v::vec)::PCOMPLEX
```

Convert F to a polyhedral complex containing the same cones, but now considered as polyhedra. If a third argument v is given, the origin will be shifted to v. See CONE[convert/affine].

dim
```dim(F::FAN)::nonnegint
```

The dimension of F is the maximum of the dimensions of the cones in F.

fan
```fan(arg1::{CONE, FAN}, ...)::FAN
```

This function creates an object of type FAN representing the fan generated by all the arguments. The given cones must be compatible, but may be redundant. A fan as argument is equivalent to the sequence of its (maximal) cones. See also CONE[arecompatible].

flagf
```flagf(F::FAN, S::set(integer))::nonnegint
```

The flag f-number of F indexed by S. This is the number of chains of cones in F of dimensions given by S.

Examples
 F := facefan(cube(3));
F := FAN(3,0,[0, 0, 6])
 flagf(F, {2, 3});
24
 flagf(F, {0, 1, 2, 3});
48
By definition, one has:
 flagf(F, {});
1
flagh
```flagh(F::FAN, S::set(integer))::nonnegint
```

The flag h-number of F indexed by S. This is the alternating sum over all flagf(F, T) where T runs over all subsets of S.

Examples
 F := facefan(cube(3));
F := FAN(3,0,[0, 0, 6])
 flagh(F, {2, 3});
7
fvector
```fvector(F::FAN)::Array
```

An Array indexed from 0 to ambientdim(F) giving the number of cones in each dimension.

Examples
 F := normalfan(cube(2)); fvector(F);
F := FAN(2,0,[0, 4])
Array(0 .. 2,{(0) = 1, (1) = 4, (2) = 4},datatype = anything,storage = rectangular,order = Fortran_order)
genhvector
```genhvector(F::FAN0)::Array
```

Stanley's generalized h-vector (which equals for, say, complete or affine F the intersection homology Betti numbers of the associated toric variety). For simplicial F this is the same as the ordinary h-vector.

Examples
 F := facefan(cube(3));
F := FAN(3,0,[0, 0, 6])
 genhvector(F);
Array(0 .. 3,{(0) = 1, (1) = 5, (2) = 5, (3) = 1},datatype = anything,storage = rectangular,order = Fortran_order)
homology
```homology(F::FAN, F0::FAN, rational)::Array
homology(F::FAN, F0::FAN, integer)::Array
homology(F::FAN, F0::FAN, specfunc(prime, integer))::Array
```

An Array indexed from 0 to ambientdim(F) giving the homology (with closed support) of F relative to the subfan F0. If F0 is omitted, then absolute homology is computed. One can choose between rational, integer and prime field coefficients. The default is rational. In the case of field coefficients, each Array entry is of type nonnegint and gives the corresponding Betti number. If integer is specified, each entry is of type MODZ and describes the corresponding Abelian group.

See PCOMPLEX[homology] for ways to override the default routine for Smith normal form computations.

 F := facefan(cube(3)); homology(skeleton(F, 2), integer(3));
F := FAN(3,0,[0, 0, 6])
Array(0 .. 3,{(2) = 5},datatype = anything,storage = rectangular,order = Fortran_order)
A single cone has vanishing homology. (This is why the function homology is not defined for cones.)
 F := fan(posorthant(3)); homology(F, integer);
F := FAN(3,0,[0, 0, 1])
Array(0 .. 3,{(1) = 0, (2) = 0, (3) = 0, (0) = 0},datatype = anything,storage = rectangular,order = Fortran_order)
hplanes
```hplanes(F::FAN)::list(vec)
```

This is the same as hplanes(C) where C is the linear hull of F. See CONE[hplanes].

image
```image(F::FAN, A::{mat, rational, real_infinity})::FAN
```

The image of the fan F under the linear map specified by A. See CONE[image] for more on the allowed values of A. Note that unlike the preimage, the image of a fan is not necessarily a fan.

Examples
 F := facefan(cube(2)); image(F, [[1,0]]);
F := FAN(2,0,[0, 4])
Error, (in FAN[image]) arguments must be compatible
iscomplete
```iscomplete(F::FAN)::boolean
```

Test whether F is complete. A fan is complete if its cones fill up the whole ambient space.

ispointed
```ispointed(F::FAN)::boolean
```

Test whether F is pointed. A fan is pointed if all its cones are, or, equivalently, if lines(F) is the empty list. See lines.

ispolytopal
```ispolytopal(F::FAN)::boolean
ispolytopal(F::FAN, P::name)::boolean
```

Test whether F is polytopal. A fan is polytopal if it is the normal fan of a polytope. If this is true and a second argument is given, it receives such a polytope. See POLYHEDRON[normalfan].

Examples
 ispolytopal(normalfan(cube(2)), 'P');
true
 P; vertices(P);
POLYTOPE(2,2,4,4)
[[1, 0], [0, 0], [1, 1], [0, 1]]
Note that P is not the polytope we started with:
 P &= cube(3);
false
Polytopal fans need not be pointed:
 ispolytopal(fan(fullcone(3)), 'P');
true
 P; vertices(P);
POLYTOPE(3,0,1,1)
[[0, 0, 0]]
An example of a regular, complete, non-polytopal fan (due to Demazure, cf. Fulton, Introduction to toric varieties, p. 71):
 v := [[-1, 0, 0], [ 0,-1, 0], [ 0, 0,-1], [ 1, 1, 1], [ 1, 1, 0], [ 0, 1, 1], [ 1, 0, 1]]; F := fan(op(map(x -> poshull(v[x[1]], v[x[2]], v[x[3]]), [[1,2,3], [1,2,6], [2,6,7], [6,7,4], [2,3,7], [3,7,5], [7,5,4], [3,1,5], [1,5,6], [5,6,4]])));
v := [[-1, 0, 0], [0, -1, 0], [0, 0, -1], [1, 1, 1], [1, 1, 0], [0, 1, 1], [1, 0, 1]]
F := FAN(3,0,[0, 0, 10])
 isregular(F), iscomplete(F), ispolytopal(F);
true, true, false
isquasipolytopal
```isquasipolytopal(F::FAN)::boolean
isquasipolytopal(F::FAN, P::name)::boolean
```

Test whether F is quasipolytopal. A fan is quasipolytopal if it is a subfan of the normal fan of a polytope or, equivalently, of a polyhedron. If this is true and a second argument is given, it receives such a polyhedron. Note that a fan is polytopal if and only if it is complete and quasipolytopal. See &<=, iscomplete and ispolytopal.

Examples
 F := fan(posorthant(2)); ispolytopal(F);
F := FAN(2,0,[0, 1])
false
 isquasipolytopal(F, 'P');
true
 P; vertices(P); rays(P);
POLYHEDRON(2,2,0,[1, 2],[2])
[[0, 0]]
[[1, 0], [0, 1]]
isregular
```isregular(F::FAN)::boolean
```

Test whether F is regular. A fan is regular if all its cones are. See CONE[isregular].

Examples
 isregular(facefan(cube(2)));
false
 isregular(normalfan(cube(2)));
true
issimplicial
```issimplicial(F::FAN)::boolean
```

Test whether F is simplicial, that is, whether all cones in F are so. See CONE[issimplicial].

lines
```lines(F::FAN)::list(vec)
```

returns a basis for the lineality space of F.

maximal
```maximal(F::FAN)::list(FANCONE)
maximal(F::FAN, list)::list(FANCONE)
maximal(F::FAN, array)::array(list(FANCONE))
```

The maximal elements of F, either as list (which is the default) or as array. The elements of the list are ordered by non-increasing dimension. The array is indexed from 0 to the ambient dimension; its n-th entry is a list of the maximal elements of F of dimension n.

The return type array may change to Array in future versions.

minimal
```minimal(F::FAN)::list(FANCONE)
```

The unique minimal element of F, which is the common lineality space of all elements of F. In order to be symmetric to the function maximal, the result is wrapped up in a list.

preimage
```preimage(F::FAN, A::{mat, rational, real_infinity})::FAN
```

The preimage of the fan F under the linear map specified by A. See CONE[preimage] for more on the allowed types of A.

projspace
```projspace(n::integer)::FAN
```

A fan whose corresponding toric variety is projective n-space.

rays
```rays(F::FAN)::list(vec)
```

The rays of F are its one-dimensional elements.

regularpart
```regularpart(F::FAN)::FAN
```

The regular part of a fan is the subfan of all regular cones in it. See CONE[isregular].

regularsubdiv
```regularsubdiv(F::FAN0)::FAN
```

A subdivision of F in which all cones are regular. The regular part of F will not be modified.

simplicialsubdiv
```simplicialsubdiv(F::FAN0)::FAN
```

A subdivision of F in which all cones are simplicial. The simplicial part of F will not be modified, nor will new rays be introduced.

skeleton
```skeleton(F::FAN, n::integer)::FAN
```

The n-skeleton of F is the subfan of all cones of dimension at most n.

stellarsubdiv
```stellarsubdiv(F::FAN)::FAN
```

support
```support(F::FAN, v1::vec, ...)::{FANCONE, FAIL}
```

The support of v1, ... in F. This is the smallest cone in F containing all given vectors. If no such cone exists, the function returns FAIL. See also CONE[support].

traverse
```traverse(F::FAN, g::procedure)::set(set(vec))
```

This is some kind of map for fans instead of lists. It calls g(f, convert(rays(f), set)) for every element f of F. (Whether or not the entire fan is traversed is actually controlled by the return value of g.) For performance reasons, f is a face of some (maximal) cone in F, hence of type CFACE, not FANCONE. The result of g must evaluate to a boolean value. If it is false, then the faces of f are skipped. The function traverse returns a set. Before we describe it in detail, let us give a (silly) example:

 infolevel[g] := 1: g := proc(f) userinfo(1, g, rays(f)); dim(f) > 2 end;
g := proc (f) userinfo(1,g,rays(f)); 2 < dim(f) end proc
(Note that we could use the second argument of g instead of calling rays(f).)
 F := facefan(cube(3));
F := FAN(3,0,[0, 0, 6])
The following call lists all faces of dimension at least 2. (Think about the strict inequality in the definition of g!)
 A := traverse(F, g):
g: [[1, -1, -1], [1, 1, -1], [1, -1, 1], [1, 1, 1]]
g: [[1, -1, 1], [1, 1, 1]]
g: [[1, 1, -1], [1, 1, 1]]
g: [[1, -1, -1], [1, -1, 1]]
g: [[1, -1, -1], [1, 1, -1]]
g: [[-1, -1, 1], [1, -1, 1], [-1, 1, 1], [1, 1, 1]]
g: [[-1, 1, 1], [1, 1, 1]]
g: [[-1, -1, 1], [-1, 1, 1]]
g: [[-1, -1, 1], [1, -1, 1]]
g: [[-1, 1, -1], [1, 1, -1], [-1, 1, 1], [1, 1, 1]]
g: [[-1, 1, -1], [-1, 1, 1]]
g: [[-1, 1, -1], [1, 1, -1]]
g: [[-1, -1, -1], [-1, 1, -1], [-1, -1, 1], [-1, 1, 1]]
g: [[-1, -1, -1], [-1, -1, 1]]
g: [[-1, -1, -1], [-1, 1, -1]]
g: [[-1, -1, -1], [1, -1, -1], [-1, -1, 1], [1, -1, 1]]
g: [[-1, -1, -1], [1, -1, -1]]
g: [[-1, -1, -1], [1, -1, -1], [-1, 1, -1], [1, 1, -1]]
The format of the result of traverse is as follows: It is a set containing the sets of rays of all cones for which g was called:
 A;
{{[1, -1, 1], [1, 1, 1]}, {[1, -1, -1], [1, 1, -1]}, {[1, -1, -1], [1, -1, 1]}, {[1, 1, -1], [1, 1, 1]}, {[-1, -1, 1], [1, -1, 1]}, {[-1, 1, 1], [1, 1, 1]}, {[-1, -1, 1], [-1, 1, 1]}, {[-1, 1, -1], [-1, 1, 1]}, {[-1, 1, -1], [1, 1, -1]}, {[-1, -1, -1], [-1, -1, 1]}, {[-1, -1, -1], [-1, 1, -1]}, {[-1, -1, -1], [1, -1, -1]}, {[-1, -1, 1], [1, -1, 1], [-1, 1, 1], [1, 1, 1]}, {[1, -1, -1], [1, 1, -1], [1, -1, 1], [1, 1, 1]}, {[-1, -1, -1], [1, -1, -1], [-1, 1, -1], [1, 1, -1]}, {[-1, -1, -1], [1, -1, -1], [-1, -1, 1], [1, -1, 1]}, {[-1, -1, -1], [-1, 1, -1], [-1, -1, 1], [-1, 1, 1]}, {[-1, 1, -1], [1, 1, -1], [-1, 1, 1], [1, 1, 1]}}

The call traverse(F, g) is equivalent to traverse2(F, g, proc() end), see traverse2.

Examples
The following statements just produce the f-vector of F (and this is more or less how fvector is actually implemented):
 fv := Array(0..ambientdim(F)): traverse(F, proc(f) global fv; local d; d := dim(f); fv[d] := fv[d]+1; true end): fv;
Array(0 .. 3,{(0) = 1, (1) = 8, (2) = 12, (3) = 6},datatype = anything,storage = rectangular,order = Fortran_order)
The functions skeleton and regularpart also use traverse.
traverse2
```traverse2(F::FAN, g2::procedure)::set(set(vec))
traverse2(F::FAN, g1::procedure, g2::procedure)::set(set(vec))
```

The first variant calls g2(f0::CFACE, f1::CFACE, convert(rays(f0), set), convert(rays(f1), set)) for every pair f0, f1 such that f0 is a facet of f1. Both faces have the same domain. The second variant calls g1(f1::CFACE, convert(rays(f1), set)) for every element f1 of F. If g1 returns true, then for all facets f0 of f1 it calls g2(f0, f1, ...) and does the same recursively for f0 instead of f1. The result is in both cases like that of traverse.

The function homology is implemented with the help of traverse2.

Examples
 infolevel[g] := 1: g := proc(f) userinfo(1, g, rays(f)); dim(f) > 2 end; g2 := proc(f0, f1) userinfo(1, g, rays(f0), rays(f1)) end;
g := proc (f) userinfo(1,g,rays(f)); 2 < dim(f) end proc
g2 := proc (f0, f1) userinfo(1,g,rays(f0),rays(f1)) end proc
 F := facefan(cube(2));
F := FAN(2,0,[0, 4])
 traverse2(F, g2);
g2: [[-1, -1]] [[-1, -1], [-1, 1]]
g2: [] [[-1, -1]]
g2: [[-1, 1]] [[-1, -1], [-1, 1]]
g2: [] [[-1, 1]]
g2: [[-1, -1]] [[-1, -1], [1, -1]]
g2: [[1, -1]] [[-1, -1], [1, -1]]
g2: [] [[1, -1]]
g2: [[-1, 1]] [[-1, 1], [1, 1]]
g2: [[1, 1]] [[-1, 1], [1, 1]]
g2: [] [[1, 1]]
g2: [[1, -1]] [[1, -1], [1, 1]]
g2: [[1, 1]] [[1, -1], [1, 1]]
{{}, {[-1, -1], [-1, 1]}, {[1, -1], [-1, -1]}, {[-1, 1]}, {[-1, -1]}, {[1, 1], [1, -1]}, {[1, 1], [-1, 1]}, {[1, 1]}, {[1, -1]}}
 traverse2(F, g, g2);
g: [[-1, -1], [-1, 1]]
g: [[-1, -1], [1, -1]]
g: [[-1, 1], [1, 1]]
g: [[1, -1], [1, 1]]
{{[-1, -1], [-1, 1]}, {[1, -1], [-1, -1]}, {[1, 1], [1, -1]}, {[1, 1], [-1, 1]}}
wprojspace
```wprojspace(w0::posint, ..., wn::posint)::FAN
```

A fan corresponding to a weighted projective space with weights w0, ... wn (which is an n-dimensional toric variety). See also projspace and lensspace.

Examples
Scaling all weights by a common factor does not change the result.
 wprojspace(2, 6) &= wprojspace(1, 3);
true
If all weights are equal, then one gets a projective space.
 F := wprojspace(1,1,1); rays(F);
F := FAN(2,0,[0, 3])
{[0, 1], [1, -1], [-1, 0]}
zerofan
```zerofan(n::integer)::FAN
```

The origin as fan in n-space.