Sage contains core modules and provides interfaces to packages which can also be used individually. Because some of the functionality exists both in the Sage core and the individual packages, the code needs to be slightly changed depending on whether functions are used via Sage or via an individual package.
Contents of this page:
fcastone sageExample.cxt sageExample.csvThe following files are used in the code examples below (the "txt" extensions should be removed after saving the files):
import subprocess import string from sage.all import * pipe = subprocess.Popen("fcastone -N sageExample.cxt filename.slf", \ shell=True, bufsize=1,stdout=subprocess.PIPE).stdout text = pipe.readlines() pipe.close() text= text[(text.index("[relation]\n") +1):] for i in range(len(text)): text[i] = string.split(text[i]) M1 = Matrix(GF(2),text) print M1
from networkx import * G = read_edgelist("sageExample.csv",delimiter=",")or into Sage:
import networkx from sage.all import * G = networkx.read_edgelist("sageExample.csv",delimiter=",") G2 = Graph(G)In this case G is a graph in the NetworkX format whereas G2 is the same graph in Sage's format. G can use NetworkX functions (e.g. G.nodes()), whereas G2 can use either Sage functions (G2.show()) or NetworkX functions (G2.networkx_graph().nodes()).
NetworkX can be used to analyse the (bipartite) graph consisting
of formal objects and formal attributes in a variety of manners. NetworkX also
allows to convert the data into a number of other
formats, including matrices.
NetworkX: Importing concept lattices as graphs
In order to import a concept lattice as a graph into NetworkX, the
"dot" file of the lattice as produced by FcaStone
can be converted into a csv file of the lattice graph using the
following Python script. The script reads a file sageExample.dot and
outputs a file sageExampleLattice.csv. This script will only work with
dot files produced by FcaStone, not dot files in general.
import re
file = open("sageExample.dot","r")
text = file.readlines()
file.close()
outputfile = open("sageExampleLattice.csv","w")
keyword1 = re.compile(r"\[|\{|\}")
keyword2 = re.compile(r" -> ")
for line in text:
if not keyword1.search (line):
outputfile.write(keyword2.sub(",",line))
This can be read into NetworkX using
G = networkx.read_edgelist("sageExampleLattice.csv",delimiter=",",create_using=DiGraph())
.
If pygraphviz or pydot are installed, it is also possible to read a
dot file into NetworkX using read_dot(path). Most likely the dot
file produced by FcaStone might need to be edited before it can be
read in this manner because it contains invisible edges for placing the
labels.
In order to visualise the graphs using NetworkX (without Sage), one needs to install
further software. If
Graphviz is installed, then the proper interfaces
are established via pygraphviz or pydot. If one does not want
to also install those tools, there is a very primitive write_gif()
function that produces gifs using Graphviz without pygraphviz or pydot.
The code is available here
and some more information on how to use it is on
this page.
To install write_gif() one can save it as writegif.py into the readwrite directory
in NetworkX and edit the __init__.py file in that directory to import
it.
There are different ways of importing formal contexts:
a) Convert the context to slf format and delete everything before and
including "[relation]". Then use:
In a similar manner the context can be converted into a
Scipy sparse matrix using to_scipy_sparse_matrix(G).
The following table shows some of Sage's matrix operations that
could be useful for FCA:
NetworkX: Producing gif files of the graphs (via Graphviz)
Using Sage, graphs can be visualised using G.show().
Matrices: importing formal contexts as matrices
There are at least three different ways of representing matrices in
Sage: using the Sage core, using Numpy and using Sympy which all have
different functions and structures. Currently there does not seem to
be an implementation of Relation Algebra or Boolean Matrix Algebra in
Sage therefore not all context operations that are common for FCA
applications are available. But Sage does allow Matrices to be
represented over GF(2) which ensures that they contain only 0s and 1s.
import numpy
from sage.all import *
M1 = Matrix(numpy.loadtxt("sageExampleMatrix.txt"))
N1 = M1.change_ring(GF(2))
or b) import a csv file of a context, convert it to a graph and from
there into a matrix:
import networkx
import numpy
from sage.all import *
G = networkx.read_edgelist("sageExample.csv",delimiter=",")
M2 = networkx.to_numpy_matrix(G,['girl','woman','boy','man',\
'female','juvenile','adult','male'])[0:4,4:9]
N2 = Matrix(numpy.array(M2)).change_ring(GF(2))
The conversion from a graph to a matrix depends on which graph node
corresponds to which matrix row/column. Therefore the to_numpy_matrix()
function needs to know the sequence of the formal objects and
attributes. The Numpy matrix is then reduced to those rows and columns
which form the context (by using [0:4,4:9]) and converted into the Sage
Matrix format. After issuing these statements N1 and N2 are equal.
dual matrix (mirrored along diagonal) | transpose(N1) |
apposition of N1 and N2 | N1.augment(N2) |
subposition of N1 and N2 | N1.stack(N2) |
null matrix of dimension i | Matrix(GF(2),i,i,0) |
diagonal matrix of dimension i | Matrix(GF(2),i,i,1) |
test for equality | N1 == N2 |
test for containment | N1 < N2 |
switching rows i and j | N1.swap_rows(i,j) |
switching columns i and j | N1.swap_columns(i,j) |
forming a submatrix | N1.submatrix(i,j,k,l) |
calculating density | N1.density() |
import networkx from sage.all import * G = networkx.read_edgelist("sageExampleLattice.csv",delimiter=",",create_using=DiGraph()) P = Poset((G.networkx_graph().nodes(),G.networkx_graph().edges()),cover_relations=True) P.show() P1 = Poset(G) P1 == P P.top() P.bottom() P.is_meet_semilattice() L = LatticePoset(G) L.is_distributive()
If anybody is interested, the Sage community might be
willing
to help with respect to how to build Sage components.
References
fcastone.sourceforge.net
www.upriss.org.uk