Attachment 'tutorial-using-free-modules.txt'

Download

   1 Tutorial: Using Free Modules and Vector Spaces
   2 
   3 <span id="tutorial-using-free-modules"></span>
   4 
   5 <p>In this tutorial, we show how to construct and manipulate free modules
   6 and vector spaces and their elements.</p>
   7 <p>Sage currently provides two implementations of free modules:
   8 <a href="#id1"><span class="problematic" id="id2">:class:`FreeModule`</span></a> and <a href="#id3"><span class="problematic" id="id4">:class:`CombinatorialFreeModule`</span></a>. The
   9 distinction between the two is mostly an accident in history. The
  10 later allows for the basis to be indexed by any kind of objects,
  11 instead of just $0,1,2,...$. They also differ by feature set and
  12 efficiency. Eventually, both implementations will be merged under the
  13 name <a href="#id5"><span class="problematic" id="id6">:class:`FreeModule`</span></a>. In the mean time, we focus here on
  14 <a href="#id7"><span class="problematic" id="id8">:class:`CombinatorialFreeModule`</span></a>. We recommend to start by browsing
  15 the documentation.</p>
  16 
  17 {{{id=0|
  18 CombinatorialFreeModule?
  19 ///
  20 }}}
  21 
  22 <p>We begin with a minimal example. What does this give us?</p>
  23 
  24 {{{id=1|
  25 G = Zmod(5)
  26 A = CombinatorialFreeModule(ZZ, G)
  27 A.an_element()
  28 ///
  29 2*B[0] + 2*B[1] + 3*B[2]
  30 }}}
  31 
  32 <p>We can use any set whose elements are immutable to index the
  33 basis. Here are some $ZZ$-free modules; what is the indexing set for
  34 the basis in each case?</p>
  35 <blockquote>
  36 sage: A = CombinatorialFreeModule(ZZ, CC); A.an_element()
  37 B[1.00000000000000*I]
  38 sage: A = CombinatorialFreeModule(ZZ, Partitions(NonNegativeIntegers(), max_part=3)); A.an_element()
  39 B[[]] + 2*B[[1]] + 3*B[[2]]
  40 sage: A = CombinatorialFreeModule(ZZ, ['spam', 'eggs', 42]); A.an_element()
  41 2*B['eggs'] + 2*B['spam'] + 3*B[42]</blockquote>
  42 
  43 {{{id=2|
  44 A = CombinatorialFreeModule(ZZ, ([1],[2],[3])); A.an_element()
  45 ///
  46 Traceback (most recent call last):
  47 TypeError: unhashable type: 'list'
  48 }}}
  49 
  50 <p>We can customize the name of the basis however we want:</p>
  51 
  52 {{{id=3|
  53 A = CombinatorialFreeModule(ZZ, Zmod(5), prefix='a'); A.an_element()
  54 ///
  55 a[0] + 3*a[1] + 3*a[2]
  56 }}}
  57 
  58 <p>Let us do some arithmetic with elements of $A$:</p>
  59 
  60 {{{id=4|
  61 f = A.an_element(); f
  62 ///
  63 a[0] + 3*a[1] + 3*a[2]
  64 }}}
  65 
  66 {{{id=5|
  67 2*f
  68 ///
  69 2*a[0] + 6*a[1] + 6*a[2]
  70 }}}
  71 
  72 {{{id=6|
  73 2*f - f
  74 ///
  75 a[0] + 3*a[1] + 3*a[2]
  76 }}}
  77 
  78 <p>This does not work yet:</p>
  79 
  80 {{{id=7|
  81 a[0] + 3*a[1]
  82 ///
  83 Traceback (most recent call last):
  84 NameError: name 'a' is not defined
  85 }}}
  86 
  87 <p>To construct elements directly, we must first get the basis for the
  88 module:</p>
  89 
  90 {{{id=8|
  91 a = A.basis()
  92 a[0] + 3*a[1]
  93 ///
  94 a[0] + 3*a[1]
  95 }}}
  96 
  97 <p>Copy-pasting works if the prefix matches the name of the basis:</p>
  98 
  99 {{{id=9|
 100 a[0] + 3*a[1] + 3*a[2] == f
 101 ///
 102 True
 103 }}}
 104 
 105 <p>Be careful, that the input is currently <em>not</em> checked:</p>
 106 
 107 {{{id=10|
 108 a['is'] + a['this'] + a['a'] + a['bug']
 109 ///
 110 a['a'] + a['bug'] + a['is'] + a['this']
 111 }}}
 112 
 113 {{{id=11|
 114 a
 115 ///
 116 Lazy family (Term map from Ring of integers modulo 5 to Free module generated by Ring of integers modulo 5 over Integer Ring(i))_{i in Ring of integers modulo 5}
 117 }}}
 118 
 119 <p><tt class="docutils literal"><span class="pre">A.basis()</span></tt> models the family $(B_i)_{i in ZZ_5}$.  See the
 120 documentation for <a href="#id9"><span class="problematic" id="id10">:class:`Family`</span></a> for more information:</p>
 121 
 122 {{{id=12|
 123 Family?
 124 ///
 125 }}}
 126 
 127 <p>The elements of our module come with many methods for
 128 exploring and manipulating them:</p>
 129 <!-- skip: -->
 130 
 131 {{{id=13|
 132 f.
 133 ///
 134 }}}
 135 
 136 <p>Some notation:</p>
 137 <blockquote>
 138 <ul>
 139 <li><p class="first"><em>term</em>: <tt class="docutils literal"><span class="pre">coefficient</span> <span class="pre">*</span> <span class="pre">basis_element</span></tt></p>
 140 </li>
 141 <li><p class="first"><em>monomial</em>: <tt class="docutils literal"><span class="pre">basis_element</span></tt> <em>without</em> a coefficient</p>
 142 </li>
 143 <li><p class="first"><em>support</em>: the index of a <tt class="docutils literal"><span class="pre">basis_element</span></tt></p>
 144 </li>
 145 <li><p class="first"><em>item</em> : a <a href="#id11"><span class="problematic" id="id12">:class:`tuple`</span></a> <tt class="docutils literal"><span class="pre">(index,</span> <span class="pre">coefficient)</span></tt></p>
 146 
 147 </li>
 148 </ul>
 149 </blockquote>
 150 <p>Note that elements are printed starting with the <em>least</em> index (for
 151 lexicographic order by default). Leading/trailing refers to the
 152 greatest/least index, respectively:</p>
 153 
 154 {{{id=14|
 155 f
 156 ///
 157 a[0] + 3*a[1] + 3*a[2]
 158 }}}
 159 
 160 {{{id=15|
 161 &quot;Leading term: &quot;,f.leading_term()
 162 ///
 163 Leading term:  3*a[2]
 164 }}}
 165 
 166 {{{id=16|
 167 print &quot;Leading monomial: &quot;,f.leading_monomial()
 168 ///
 169 Leading monomial:  a[2]
 170 }}}
 171 
 172 {{{id=17|
 173 print &quot;Leading support: &quot;,f.leading_support()
 174 ///
 175 Leading support:  2
 176 }}}
 177 
 178 {{{id=18|
 179 print &quot;Leading coefficient: &quot;,f.leading_coefficient()
 180 ///
 181 Leading coefficient:  3
 182 }}}
 183 
 184 {{{id=19|
 185 print &quot;Leading item: &quot;,f.leading_item()
 186 ///
 187 Leading item:  (2, 3)
 188 }}}
 189 
 190 {{{id=20|
 191 f.leading_term
 192 print &quot;Support: &quot;,f.support()
 193 ///
 194 Support:  [0, 1, 2]
 195 }}}
 196 
 197 {{{id=21|
 198 print &quot;Monomials: &quot;,f.monomials()
 199 ///
 200 Monomials:  [a[0], a[1], a[2]]
 201 }}}
 202 
 203 {{{id=22|
 204 print &quot;Coefficients: &quot;,f.coefficients()
 205 ///
 206 Coefficients:  [1, 3, 3]
 207 }}}
 208 
 209 <p>We can iterate through the items in an element:</p>
 210 
 211 {{{id=23|
 212 for index, coeff in f:
 213        print &quot;The coefficient of a_{%s} is %s&quot;%(index, coeff)
 214 ///
 215 The coefficient of a_{0} is 1The coefficient of a_{1} is 3The coefficient of a_{2} is 3
 216 }}}
 217 
 218 {{{id=24|
 219 # This uses the fact that f can be thought of as a dictionary  index--&gt;coefficient
 220 print f[0], f[1], f[2]
 221 ///
 222 1 3 3
 223 }}}
 224 
 225 {{{id=25|
 226 # This dictionary can be accessed explicitly with the monomial_coefficients method
 227 f.monomial_coefficients()
 228 ///
 229 {0: 1, 1: 3, 2: 3}
 230 }}}
 231 
 232 <p>The parent ($A$ in our example) has several utility methods for
 233 constructing elements:</p>
 234 
 235 {{{id=26|
 236 A.
 237 A.zero()
 238 ///
 239 0
 240 }}}
 241 
 242 {{{id=27|
 243 A.sum_of_monomials(i for i in Zmod(5) if i &gt; 2)
 244 ///
 245 a[3] + a[4]
 246 }}}
 247 
 248 {{{id=28|
 249 A.sum_of_terms((i+1,i) for i in Zmod(5) if i &gt; 2)
 250 ///
 251 4*a[0] + 3*a[4]
 252 }}}
 253 
 254 {{{id=29|
 255 A.sum(ZZ(i)*a[i+1] for i in Zmod(5) if i &gt; 2)  # Note coeff is not (currently) implicitly coerced
 256 ///
 257 4*a[0] + 3*a[4]
 258 }}}
 259 
 260 <p>Note that it is safer to use <tt class="docutils literal"><span class="pre">A.sum()</span></tt> than to use <tt class="docutils literal"><span class="pre">sum()</span></tt>, in
 261 case the input is an empty iterable:</p>
 262 
 263 {{{id=30|
 264 print A.sum([]),':', parent(A.sum([]))
 265 ///
 266 0 : Free module generated by Ring of integers modulo 5 over Integer Ring
 267 }}}
 268 
 269 {{{id=31|
 270 print sum([]),':', parent(sum([]))
 271 ///
 272 0 : <type 'int'>
 273 }}}
 274 
 275 <p>The <tt class="docutils literal"><span class="pre">map</span></tt> methods are useful to transform elements:</p>
 276 
 277 {{{id=32|
 278 f.map_
 279 print f,&quot;--&gt;&quot;, f.map_support     (lambda i  : i+3)
 280 ///
 281 a[0] + 3*a[1] + 3*a[2] --> 3*a[0] + a[3] + 3*a[4]
 282 }}}
 283 
 284 {{{id=33|
 285 print f,&quot;--&gt;&quot;, f.map_coefficients(lambda c  : c-1)
 286 ///
 287 a[0] + 3*a[1] + 3*a[2] --> 2*a[1] + 2*a[2]
 288 }}}
 289 
 290 {{{id=34|
 291 print f,&quot;--&gt;&quot;, f.map_term        (lambda i,c: (i+3,c-1))
 292 ///
 293 a[0] + 3*a[1] + 3*a[2] --> 2*a[0] + 2*a[4]
 294 }}}
 295 
 296 <p><tt class="docutils literal"><span class="pre">f.map_mc</span></tt> is a deprecated synonym for <tt class="docutils literal"><span class="pre">f.map_term</span></tt>.</p>
 297 <p>Note that <tt class="docutils literal"><span class="pre">term</span></tt> and <tt class="docutils literal"><span class="pre">item</span></tt> are not yet used completely consistently.</p>

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.