{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Data in an algebraixlib program is represented as `MathObject`s. `MathObject`s come in four types: `Atom`, `Couplet`, `Set`, and `Multiset`. `Multiset`s are a mathematical construct like sets. Their difference is that they remove the restriction that all elements have to be unique. Usually a multiset will be denoted as a function that maps an element in the multiset to a whole integer that represents the number of times that element is in the multiset." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The `Multiset` MathObject" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from algebraixlib.mathobjects import Atom, Set, Couplet, Multiset\n", "\n", "# Construct a multiset\n", "ms_1 = Multiset({'a': 2, 'b': 3})\n", "ms_2 = Multiset(['b', 'b', 'c'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Multiset` mathobjects can be constructed in two manners: one provides a dictionary of the elements and their multiples, the other takes a list or array and the constructor tallies the equal elements." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['a':2, 'b':3]\n", "['b':2, 'c':1]\n" ] } ], "source": [ "print(ms_1)\n", "print(ms_2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The printed representation of a multiset is annotated in brackets and Python dictionary style sytax for representing elements and the number of times that element in in the multiset." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Multisets can tell you about the data in them using iteration and `get_multiplicity` method." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This multiset has a cardinality of 5\n", "There are 2 elements of 'a' in ms_1\n", "'a'\n", "'a'\n", "'b'\n", "'b'\n", "'b'\n" ] } ], "source": [ "# Multiplicity and Iteration functions.\n", "a = Atom('a')\n", "print(\"This multiset has a cardinality of \" + str(ms_1.cardinality))\n", "print(\"There are \" + str(ms_1.get_multiplicity(a)) + \" elements of \" + str(a) + \" in ms_1\") \n", "# iteration\n", "for elem in ms_1:\n", " print(elem)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that when iterating over a multiset, the iterator returns an element for its multiple number of times." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next code snippet loads some utility functions that will render a mathobject into LaTeX markup, making them easier to read." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Loading utility printing functions.\n", "import algebraixlib.util.latexprinter\n", "algebraixlib.util.latexprinter.Config.colorize_output = False\n", "\n", "from algebraixlib.util.latexprinter import math_object_to_latex, iprint_latex\n", "from IPython.display import Math, display" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Multiset Algebra Operations\n", "The same operations that are available in the set algebra haven been implemented in the multiset algebra. The notable difference is that the operations take account for the multiples of elements." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The union operation in the Multiset algebra takes the `max` of all the multiples merges the arguments into one result multiset, while the intersect operation takes the `min` of all the multiples merges the arguments into one result multiset." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$ms\\_1 = \\left[\\mbox{'a'}:\\ 2,\\ \\mbox{'b'}:\\ 3\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$ms\\_2 = \\left[\\mbox{'b'}:\\ 2,\\ \\mbox{'c'}:\\ 1\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_union = ms\\_1 \\cup ms\\_2$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_union = \\left[\\mbox{'a'}:\\ 2,\\ \\mbox{'b'}:\\ 3,\\ \\mbox{'c'}:\\ 1\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import algebraixlib.algebras.multisets as multisets\n", "\n", "iprint_latex(\"ms_1\", ms_1)\n", "iprint_latex(\"ms_2\", ms_2)\n", "iprint_latex(\"simple_union\", \"ms\\_1 \\cup ms\\_2\")\n", "simple_union = multisets.union(ms_1, ms_2) # Execute the operation\n", "iprint_latex(\"simple_union\", simple_union)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$simple\\_intersect = ms\\_1 \\cap ms\\_2$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_intersect = \\left[\\mbox{'b'}:\\ 2\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "iprint_latex(\"simple_intersect\", \"ms\\_1 \\cap ms\\_2\")\n", "simple_intersect = multisets.intersect(ms_1, ms_2) # Execute the operation\n", "iprint_latex(\"simple_intersect\", simple_intersect)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This algebra also provides operations `add` and `minus`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The addition operation in the algebra sums all the multiples of like values in the arguments into one result multiset. And the minus operation subtracts elements of the right multiset from the left argument. For values <=0, the elements are removed from the `multiset`, since a multiple is defined as being greater than 0." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$simple\\_add = ms\\_1 + ms\\_2$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_add = \\left[\\mbox{'a'}:\\ 2,\\ \\mbox{'b'}:\\ 5,\\ \\mbox{'c'}:\\ 1\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "iprint_latex(\"simple_add\", \"ms\\_1 + ms\\_2\")\n", "simple_add = multisets.add(ms_1, ms_2) # Execute the operation\n", "iprint_latex(\"simple_add\", simple_add)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$simple\\_minus = ms\\_1 - ms\\_2$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_minus = \\left[\\mbox{'a'}:\\ 2,\\ \\mbox{'b'}:\\ 1\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "iprint_latex(\"simple_minus\", \"ms\\_1 - ms\\_2\")\n", "simple_minus = multisets.minus(ms_1, ms_2) # Execute the operation\n", "iprint_latex(\"simple_minus\", simple_minus)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Multiclan Algebra Operations\n", "Like multisets, where set elements are not restricted to be unique, multiclans allow the same flexibility for relations: the elements of the relation are not restricted to being unique. Unlike multisets, which have an explicit object, multiclans do not have an object. Instead they are defined by a multiset of a relations." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Building some relations for our multiclans.\n", "rel_1 = Set(Couplet('x', 'y'), Couplet('w', 'y'))\n", "rel_2 = Set(Couplet('a', 'x'), Couplet('b', 'w'))\n", "rel_3 = Set(Couplet('x', 'z'), Couplet('v', 'y'))\n", "rel_4 = Set(Couplet('c', 'z'), Couplet('a', 'v'))\n", "rel_5 = Set(Couplet('b', 'w'), Couplet('w', 'y'))\n", "rel_6 = Set(Couplet('a', 'x'), Couplet('x', 'y'))" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Creating multiclans (multisets of relations)\n", "mc_1 = Multiset({rel_1: 2, rel_3: 3})\n", "mc_2 = Multiset({rel_2: 5, rel_4: 1})\n", "mc_3 = Multiset({rel_1: 2, rel_6: 7})\n", "mc_4 = Multiset({rel_2: 5, rel_5: 11})" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$mc\\_1 = \\left[\\begin{array}{l}\\left\\{\\mbox{'v'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'z'}}\\right\\}:\\ 3,\\\\\n", "\\left\\{\\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 2\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$mc\\_2 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'v'}},\\ \\mbox{'c'}{\\mapsto}{\\mbox{'z'}}\\right\\}:\\ 1,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'w'}}\\right\\}:\\ 5\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$mc\\_3 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 7,\\\\\n", "\\left\\{\\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 2\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$mc\\_4 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'w'}}\\right\\}:\\ 5,\\\\\n", "\\left\\{\\mbox{'b'}{\\mapsto}{\\mbox{'w'}},\\ \\mbox{'w'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 11\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "iprint_latex(\"mc_1\", mc_1)\n", "iprint_latex(\"mc_2\", mc_2)\n", "iprint_latex(\"mc_3\", mc_3)\n", "iprint_latex(\"mc_4\", mc_4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that all the multiclans used prime numbers for multiplicities. This was purposely done to help the reader know which left hand and right hand relations were used for the inner operation. Since the operation will be result in the product of the multiples, in most cases you can factor the result multiplicty yielding the two argument's prime numbers." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`transpose` swaps the left and right components of the couplets in each relation; multiplicity is unaffected." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$mc\\_1 = \\left[\\begin{array}{l}\\left\\{\\mbox{'v'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'z'}}\\right\\}:\\ 3,\\\\\n", "\\left\\{\\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 2\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_transpose = \\overleftrightarrow{mc\\_1}$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_transpose = \\left[\\begin{array}{l}\\left\\{\\mbox{'y'}{\\mapsto}{\\mbox{'v'}},\\ \\mbox{'z'}{\\mapsto}{\\mbox{'x'}}\\right\\}:\\ 3,\\\\\n", "\\left\\{\\mbox{'y'}{\\mapsto}{\\mbox{'w'}},\\ \\mbox{'y'}{\\mapsto}{\\mbox{'x'}}\\right\\}:\\ 2\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import algebraixlib.algebras.multiclans as multiclans\n", "\n", "simple_transpose = multiclans.transpose(mc_1)\n", "iprint_latex(\"mc_1\", mc_1)\n", "\n", "simple_transpose = multiclans.transpose(mc_1)\n", "iprint_latex(\"simple_transpose\", \"\\overleftrightarrow{mc\\_1}\")\n", "iprint_latex(\"simple_transpose\", simple_transpose)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "multiclan's compose applies a cross compose of the relations in each sides multiclan, the multiplicity is the product of each sides multiplicity." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/latex": [ "$$mc\\_1 = \\left[\\begin{array}{l}\\left\\{\\mbox{'v'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'z'}}\\right\\}:\\ 3,\\\\\n", "\\left\\{\\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 2\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$mc\\_2 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'v'}},\\ \\mbox{'c'}{\\mapsto}{\\mbox{'z'}}\\right\\}:\\ 1,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'w'}}\\right\\}:\\ 5\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_compose\\_1 = mc\\_1 \\circ mc\\_2$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_compose\\_1 = \\left[\\begin{array}{l}\\left\\{\\right\\}:\\ 2,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 3,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 10,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'z'}}\\right\\}:\\ 15\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "iprint_latex(\"mc_1\", mc_1)\n", "iprint_latex(\"mc_2\", mc_2)\n", "simple_compose_1 = multiclans.compose(mc_1, mc_2)\n", "iprint_latex(\"simple_compose_1\", \"mc\\_1 \\circ mc\\_2\")\n", "iprint_latex(\"simple_compose_1\", simple_compose_1)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$simple\\_compose\\_2 = mc\\_2 \\circ mc\\_1$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_compose\\_2 = \\left[\\begin{array}{l}\\left\\{\\right\\}:\\ 30\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "simple_compose_2 = multiclans.compose(mc_2, mc_1)\n", "iprint_latex(\"simple_compose_2\", \"mc\\_2 \\circ mc\\_1\")\n", "iprint_latex(\"simple_compose_2\", simple_compose_2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`cross_union` applies the relation's union for all relations in the multiclan of each argument. Again the resulting multiple is the product of the two relations multiples." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$simple\\_cross\\_union\\_1 = mc\\_1 \\blacktriangledown mc\\_2$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_cross\\_union\\_1 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'v'}},\\ \\mbox{'c'}{\\mapsto}{\\mbox{'z'}},\\ \\mbox{'v'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'z'}}\\right\\}:\\ 3,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'v'}},\\ \\mbox{'c'}{\\mapsto}{\\mbox{'z'}},\\ \\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 2,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'w'}},\\ \\mbox{'v'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'z'}}\\right\\}:\\ 15,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'w'}},\\ \\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 10\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "simple_cross_union_1 = multiclans.cross_union(mc_1, mc_2)\n", "iprint_latex(\"simple_cross_union_1\", \"mc\\_1 \\\\blacktriangledown mc\\_2\")\n", "iprint_latex(\"simple_cross_union_1\", simple_cross_union_1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`cross_union` like other operations can yield the same result for different inner relation unions. These same results are summed together." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$mc\\_3 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 7,\\\\\n", "\\left\\{\\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 2\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$mc\\_4 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'w'}}\\right\\}:\\ 5,\\\\\n", "\\left\\{\\mbox{'b'}{\\mapsto}{\\mbox{'w'}},\\ \\mbox{'w'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 11\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_cross\\_union\\_2 = mc\\_3 \\blacktriangledown mc\\_4$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_cross\\_union\\_2 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'w'}},\\ \\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 87,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'w'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 35,\\\\\n", "\\left\\{\\mbox{'b'}{\\mapsto}{\\mbox{'w'}},\\ \\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 22\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "iprint_latex(\"mc_3\", mc_3)\n", "iprint_latex(\"mc_4\", mc_4)\n", "iprint_latex(\"simple_cross_union_2\", \"mc\\_3 \\\\blacktriangledown mc\\_4\")\n", "simple_cross_union_2 = multiclans.cross_union(mc_3, mc_4)\n", "iprint_latex(\"simple_cross_union_2\", simple_cross_union_2)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$mc\\_1 = \\left[\\begin{array}{l}\\left\\{\\mbox{'v'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'z'}}\\right\\}:\\ 3,\\\\\n", "\\left\\{\\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 2\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$mc\\_2 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'v'}},\\ \\mbox{'c'}{\\mapsto}{\\mbox{'z'}}\\right\\}:\\ 1,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'w'}}\\right\\}:\\ 5\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_cross\\_intersect\\_1 = mc\\_1 \\blacktriangle mc\\_2$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_cross\\_intersect\\_1 = \\left[\\begin{array}{l}\\left\\{\\right\\}:\\ 30\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "iprint_latex(\"mc_1\", mc_1)\n", "iprint_latex(\"mc_2\", mc_2)\n", "simple_cross_intersect_1 = multiclans.cross_intersect(mc_1, mc_2)\n", "iprint_latex(\"simple_cross_intersect_1\", \"mc\\_1 \\\\blacktriangle mc\\_2\")\n", "iprint_latex(\"simple_cross_intersect_1\", simple_cross_intersect_1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`cross_union` is utilizing the `union` defined on relations. And `'cross_intersection` uses the `intersection` defined on relations." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$mc\\_3 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 7,\\\\\n", "\\left\\{\\mbox{'w'}{\\mapsto}{\\mbox{'y'}},\\ \\mbox{'x'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 2\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$mc\\_4 = \\left[\\begin{array}{l}\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}},\\ \\mbox{'b'}{\\mapsto}{\\mbox{'w'}}\\right\\}:\\ 5,\\\\\n", "\\left\\{\\mbox{'b'}{\\mapsto}{\\mbox{'w'}},\\ \\mbox{'w'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 11\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_cross\\_intersect\\_2 = mc\\_3 \\blacktriangle mc\\_4$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$simple\\_cross\\_intersect\\_2 = \\left[\\begin{array}{l}\\left\\{\\right\\}:\\ 87,\\\\\n", "\\left\\{\\mbox{'a'}{\\mapsto}{\\mbox{'x'}}\\right\\}:\\ 35,\\\\\n", "\\left\\{\\mbox{'w'}{\\mapsto}{\\mbox{'y'}}\\right\\}:\\ 22\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "iprint_latex(\"mc_3\", mc_3)\n", "iprint_latex(\"mc_4\", mc_4)\n", "iprint_latex(\"simple_cross_intersect_2\", \"mc\\_3 \\\\blacktriangle mc\\_4\")\n", "simple_cross_intersect_2 = multiclans.cross_intersect(mc_3, mc_4)\n", "iprint_latex(\"simple_cross_intersect_2\", simple_cross_intersect_2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A Data Algebra Example with Multisets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometimes when importing CSV data, importing the contents into a clan is not the right thing to do. A clan requires each relation be unique, this translates to a requirement that the CSV file does not contain duplicate rows of data, or the user is ok losing that information.\n", "If a user has a CSV file such that there are duplicate rows and this information is important in some way, then importing into a multiclan is a better choice. This is because rather than losing the duplicates, a multiclan will keep track of how many times the relation is present." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can demonstrate the usefulness of the Multiset Object and the Multiclan Algebra when considering the import of CSV data. When employing Data Algebra, each row corresponds to a relation. It is not uncommon for CSV data to have duplicate rows, duplicate relations. In this case the multiplicity is not preserved in a Multiset which makes the import lossy which may not be acceptable. Instead, the multiplicity can be preserved by importing the data into a Multiclan. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Suppose we have a csv data file that records products sold and the cashier that sold them. It is a likely and valid use case that the same product is sold by the same cashier. The results in a datalog where we will have duplicate rows, but each represnt a unique transaction, information that should not be lost. If we have a csv file like this, importing this information as multiclan can help introspect on the data." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Importing data import tools\n", "from io import StringIO\n", "from algebraixlib.io.csv import import_csv\n", "from algebraixlib.io.csv import export_csv" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Example csv data log of cashiers' products sold. Note that the first row contains the colulmn headings.\n", "sales_csv = \"\"\"product,cashier\n", "apple,jane\n", "banana,doug\n", "apple,jane\n", "peach,doug\n", "rice,frank\n", "rice,frank\n", "banana,doug\n", "apple,doug\n", "rice,jane\n", "apple,jane\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$sales\\_multiclan = \\left[\\begin{array}{l}\\left\\{\\mbox{'cashier'}{\\mapsto}{\\mbox{'doug'}},\\ \\mbox{'product'}{\\mapsto}{\\mbox{'apple'}}\\right\\}:\\ 1,\\\\\n", "\\left\\{\\mbox{'cashier'}{\\mapsto}{\\mbox{'doug'}},\\ \\mbox{'product'}{\\mapsto}{\\mbox{'banana'}}\\right\\}:\\ 2,\\\\\n", "\\left\\{\\mbox{'cashier'}{\\mapsto}{\\mbox{'doug'}},\\ \\mbox{'product'}{\\mapsto}{\\mbox{'peach'}}\\right\\}:\\ 1,\\\\\n", "\\left\\{\\mbox{'cashier'}{\\mapsto}{\\mbox{'frank'}},\\ \\mbox{'product'}{\\mapsto}{\\mbox{'rice'}}\\right\\}:\\ 2,\\\\\n", "\\left\\{\\mbox{'cashier'}{\\mapsto}{\\mbox{'jane'}},\\ \\mbox{'product'}{\\mapsto}{\\mbox{'apple'}}\\right\\}:\\ 3,\\\\\n", "\\left\\{\\mbox{'cashier'}{\\mapsto}{\\mbox{'jane'}},\\ \\mbox{'product'}{\\mapsto}{\\mbox{'rice'}}\\right\\}:\\ 1\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Import the data. Note that we are simulating a file to simplify the example.\n", "file = StringIO(sales_csv)\n", "sales_multiclan = import_csv(file, has_dup_rows=True) # note the use of flag to return a multiclan\n", "iprint_latex(\"sales_multiclan\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Frequently CSV data is used for data analysis and mined. Next we will examine how many sales each cashier made and how many of each product was sold using the Multiclan Algebra Compose Operation.\n", "One example of data algebra, is to examine how many sales each cashier had, and examine how many of each product was sold. This information can be computers using the multiclan compose operation." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$cashier\\_diagonal = \\left[\\begin{array}{l}\\left\\{\\mbox{'cashier'}{\\mapsto}{\\mbox{'cashier'}}\\right\\}:\\ 1\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$cashier\\_sales = sales\\_multiclan \\circ cashier\\_diagonal$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$cashier\\_sales = \\left[\\begin{array}{l}\\left\\{\\mbox{'cashier'}{\\mapsto}{\\mbox{'doug'}}\\right\\}:\\ 4,\\\\\n", "\\left\\{\\mbox{'cashier'}{\\mapsto}{\\mbox{'frank'}}\\right\\}:\\ 2,\\\\\n", "\\left\\{\\mbox{'cashier'}{\\mapsto}{\\mbox{'jane'}}\\right\\}:\\ 4\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cashier_diagonal = Multiset({Set(Couplet('cashier', 'cashier')): 1})\n", "cashier_sales = multiclans.compose(sales_multiclan, cashier_diagonal)\n", "\n", "iprint_latex(\"cashier_diagonal\")\n", "iprint_latex(\"cashier_sales\", \"sales\\_multiclan \\circ cashier\\_diagonal\")\n", "iprint_latex(\"cashier_sales\")" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$$product\\_diagonal = \\left[\\begin{array}{l}\\left\\{\\mbox{'product'}{\\mapsto}{\\mbox{'product'}}\\right\\}:\\ 1\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$product\\_sales = sales\\_multiclan \\circ product\\_diagonal$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ "$$product\\_sales = \\left[\\begin{array}{l}\\left\\{\\mbox{'product'}{\\mapsto}{\\mbox{'apple'}}\\right\\}:\\ 4,\\\\\n", "\\left\\{\\mbox{'product'}{\\mapsto}{\\mbox{'banana'}}\\right\\}:\\ 2,\\\\\n", "\\left\\{\\mbox{'product'}{\\mapsto}{\\mbox{'peach'}}\\right\\}:\\ 1,\\\\\n", "\\left\\{\\mbox{'product'}{\\mapsto}{\\mbox{'rice'}}\\right\\}:\\ 3\\end{array}\\right]$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "product_diagonal = Multiset({Set(Couplet('product', 'product')): 1})\n", "product_sales = multiclans.compose(sales_multiclan, product_diagonal)\n", "\n", "iprint_latex(\"product_diagonal\")\n", "iprint_latex(\"product_sales\", \"sales\\_multiclan \\circ product\\_diagonal\")\n", "iprint_latex(\"product_sales\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Converting this data back into an export of csv is also possible." ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cashier,product\r\n", "doug,apple\r\n", "doug,banana\r\n", "doug,banana\r\n", "doug,peach\r\n", "frank,rice\r\n", "frank,rice\r\n", "jane,apple\r\n", "jane,apple\r\n", "jane,apple\r\n", "jane,rice\r\n", "\n", "cashier\r\n", "doug\r\n", "doug\r\n", "doug\r\n", "doug\r\n", "frank\r\n", "frank\r\n", "jane\r\n", "jane\r\n", "jane\r\n", "jane\r\n", "\n", "product\r\n", "apple\r\n", "apple\r\n", "apple\r\n", "apple\r\n", "banana\r\n", "banana\r\n", "peach\r\n", "rice\r\n", "rice\r\n", "rice\r\n", "\n" ] } ], "source": [ "# confirm no data is lost by printing out entire multiclan\n", "sales_csv_out = StringIO()\n", "export_csv(sales_multiclan, sales_csv_out)\n", "csv_str = sales_csv_out.getvalue()\n", "print(csv_str)\n", "\n", "cashier_sales_csv_out = StringIO()\n", "export_csv(cashier_sales, cashier_sales_csv_out)\n", "cashier_sales_csv_str = cashier_sales_csv_out.getvalue()\n", "print(cashier_sales_csv_str)\n", "\n", "product_sales_csv_out = StringIO()\n", "export_csv(product_sales, product_sales_csv_out)\n", "product_sales_csv_str = product_sales_csv_out.getvalue()\n", "print(product_sales_csv_str)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "----\n", "© Copyright Permission.io, Inc. (formerly known as Algebraix Data Corporation), Copyright (c) 2022.\n", "\n", "This file is part of [`algebraixlib`][] .\n", "\n", "[`algebraixlib`][] is free software: you can redistribute it and/or modify it under the terms of [version 3 of the GNU Lesser General Public License][] as published by the [Free Software Foundation][].\n", "\n", "[`algebraixlib`][] is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.\n", "\n", "You should have received a copy of the GNU Lesser General Public License along with [`algebraixlib`][]. If not, see [GNU licenses][].\n", "\n", "[`algebraixlib`]: (A Python library for data algebra)\n", "[Version 3 of the GNU Lesser General Public License]: \n", "[Free Software Foundation]: \n", "[GNU licenses]: " ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.4.3" } }, "nbformat": 4, "nbformat_minor": 0 }