<jupyter_start><jupyter_text>Vector Spaces & Modules Vector Spaces and Modules are defined using Groups, Rings, and Fields.  Vector Space A **Vector Space**, $\mathscr{V} = \langle G, F, \circ \rangle$, consists of the following:* an **abelian Group**, $G = \langle V, \oplus \rangle$ (i.e., the *"vectors"*)* a **field**, $F = \langle S, +, \cdot \rangle$ (i.e., the *"scalars"*)* and a **binary operator**, $\circ : S \times V \to V$where the following conditions hold:1. Scaled Vectors: For all $s \in S$ and $v \in V \Rightarrow s \circ v \in V$1. Scaling by One: If $1 \in S$ is the multiplicative identity element of $F$, then $1 \circ v = v$1. Distributivity of Scalars Over Vector Addition: $s \circ (v_1 \oplus v_2) = (s \circ v_1) \oplus (s \circ v_2)$1. Distributivity of Vectors Over Scalar Addition: $(s_1 + s_2) \circ v = (s_1 \circ v) \oplus (s_2 \circ v)$1. Scalar-Vector Associativity: $s_1 \circ (s_2 \circ v) = (s_1 \cdot s_2) \circ v$ A **Module**, $\mathscr{M} = \langle G, R, \circ \rangle$, has the same conditions as a Vector Space, except that the Field is replaced by a **Ring**, $R$.  Internal Representation of Vector Spaces & ModulesUnlike Groups, Rings, Fields, and such, Vector Spaces and Modules have more than one set of elements and more than one or two binary operations.  Within the ``finite_algebra`` implementation, the internal representation is as shown below. The five elements listed must be input to the function, ``make_finite_algebra``, in the order shown, to construct a Module or VectorSpace.* **name**: (``str``) A short name for the algebra;* **description**: (``str``) Any additional, useful information about the algebra;* **scalars**: A ``Ring`` or a ``Field``. The Ring or Field elements are called *scalars* and the scalar addition and multiplication operations are those of the Ring or Field;* **vectors**: An abelian ``Group``. Its elements are *vectors* and its operation is *vector addition*;* **sv_op**: A scalar-vector binary operation, $\circ : S \times V \to V$, for "scaling vectors"If the scalars are a Field, then ``make_finite_algebra`` will construct a VectorSpace. Otherwise, if the scalars are a Ring, then a Module will be constructed.  Examples  $\mathbb{R}^n$ Perhaps the most well-known example of a vector space is $\mathbb{R}^n$, the n-dimensional vector space over the real numbers.  Of course, $\mathbb{R}^n$ satisfies all of the conditions listed in the definition above.  The scalar field of $\mathbb{R}^n$ is $\mathbb{R}$ itself, and the abelian group of $\mathbb{R}^n$ is the direct product, $\mathscr{G} = \mathbb{R} \times \dots \times \mathbb{R} \equiv \times^n \mathbb{R}$, where the group's binary operation is component-wise addition in $\mathbb{R}$, its identity element is $0_n = (0, \dots, 0)$, commonly called *the origin*, and the scalar-vector binary operation is defined as $s \circ v \equiv (s \circ v_1, \dots, s \circ v_n)$, where $v = (v_1, \dots, v_n)$.In the section to follow, this type of Vector Space (or Module), where the Group is created from the n-fold direct product of the Field, will be created using a finite Field or Ring.  A Finite, n-Dimensional Vector Space (similar to $\mathbb{R}^n$) Given a finite Field (or finite Ring) and a positive integer dimension, the function, ``generate_n_dim_module``, constructs an n-dimensional Vector Space (or Module) similar to how $\mathbb{R}^n$ is constructed.This will be demonstrated using the following ["field with 4 elements" (see Wikipedia)](https://en.wikipedia.org/wiki/Finite_fieldField_with_four_elements):<jupyter_code>>>> from finite_algebras import make_finite_algebra
>>> f4 = make_finite_algebra('F4',
                             'Field with 4 elements (from Wikipedia)',
                             ['0', '1', 'a', '1+a'],
                             [['0', '1', 'a', '1+a'],
                              ['1', '0', '1+a', 'a'],
                              ['a', '1+a', '0', '1'],
                              ['1+a', 'a', '1', '0']],
                             [['0', '0', '0', '0'],
                              ['0', '1', 'a', '1+a'],
                              ['0', 'a', '1+a', '1'],
                              ['0', '1+a', '1', 'a']]
                            )

>>> f4<jupyter_output><empty_output><jupyter_text>f4 is used, below, to create a finite, n-dimensional VectorSpace.NOTE: ``generate_n_dim_module`` is a convenience function.  Within it, the requisite Field (or Ring), Group, and scalar-vector operation are constructed and then fed to the all-purpose algebra construction function, ``make_finite_algebra``, to create a VectorSpace or Module.  The five conditions, listed in the definition above, are also checked.  If any of them fail, then an exception will be raised.<jupyter_code>>>> from finite_algebras import generate_n_dim_module

>>> n = 2  # We're using a small number of dimensions to limit the amount of printout below

>>> vs = generate_n_dim_module(f4, n)

>>> vs.about(max_size=16)<jupyter_output>VectorSpace: VS2-F4
Instance ID: 140359803734416
Description: 2-dimensional Vector Space over F4

SCALARS:

** Field **
Name: F4
Instance ID: 140361151253456
Description: Field with 4 elements (from Wikipedia)
Order: 4
Identity: 0
Associative? Yes
Commutative? Yes
Cyclic?: Yes
  Generators: ['1+a', 'a']
Elements:
   Index   Name   Inverse  Order
      0       0       0       1
      1       1       1       2
      2       a       a       2
      3     1+a     1+a       2
Cayley Table (showing indices):
[[0, 1, 2, 3], [1, 0, 3, 2], [2, 3, 0, 1], [3, 2, 1, 0]]
Mult. Identity: 1
Mult. Commutative? Yes
Zero Divisors: None
Multiplicative Cayley Table (showing indices):
[[0, 0, 0, 0], [0, 1, 2, 3], [0, 2, 3, 1], [0, 3, 1, 2]]

VECTORS:

** Group **
Name: F4_x_F4
Instance ID: 140361149519888
Description: Direct product of F4 & F4
Order: 16
Identity: 0:0
Associative? Yes
Commutative? Yes
Cyclic?: No
Elements:
   Index   Name   Inverse  Order
      0     0:0     0:0       1
      1     0:1    [...]<jupyter_text>The scalar and vector elements of the VectorSpace can be obtained as follows:<jupyter_code>>>> vs.scalar.elements
>>> vs.vector.elements<jupyter_output><empty_output><jupyter_text>Scalar addition and multiplication is just the addition and multiplication operations of the Field (Scalars) used to create the VectorSpace (or Module)<jupyter_code>>>> vs.scalar.add('1', 'a')
>>> vs.scalar.mult('a', 'a')<jupyter_output><empty_output><jupyter_text>Vector addition is just the binary operation of the Group (Vectors) used to create the Vector Space (or Module)<jupyter_code>>>> vs.vector_add('1+a:1', '1:a')  # Same as vs.vector.op('1+a:1', '1:a')<jupyter_output><empty_output><jupyter_text>And, since the *scalar* part of a VectorSpace is a Field, we can obtain it's identity elements as follows:<jupyter_code>>>> vs.scalar.zero
>>> vs.scalar.one<jupyter_output><empty_output><jupyter_text>The scalar-vector operation for scaling Vectors (or Modules) is the VectorSpace method, ``sv_op``, and takes two inputs: a scalar and vector, resp.<jupyter_code>vs.sv_op('a', '1+a:1')<jupyter_output><empty_output><jupyter_text>Checking the VectorSpace/Module Conditions The following are four examples that illustrate the method calls required to check the requirements of a Vector Space or Module.  During VectorSpace or Module construction, function ``make_finite_algebra`` automatically calls the function ``check_module_conditions`` to make sure that the requirements for a Vector Space or Module are met. **Scaling by 1** If $\mathscr{1} \in S$ is the multiplicative identity element of $\mathscr{F}$, then $\mathscr{1} \circ v = v$<jupyter_code>>>> print(vs.sv_op(vs.scalar.one, 'a:1+a'))<jupyter_output>a:1+a<jupyter_text>**Distributivity of scalars over vector addition** $s \circ (v_1 \oplus v_2) = (s \circ v_1) \oplus (s \circ v_2)$<jupyter_code>>>> s = 'a'
>>> v1 = 'a:1+a'
>>> v2 = 'a:1'<jupyter_output><empty_output><jupyter_text>$s \circ (v_1 \oplus v_2)$<jupyter_code>>>> print(vs.sv_op(s, vs.vector_add(v1, v2)))<jupyter_output>0:1+a<jupyter_text>$(s \circ v_1) \oplus (s \circ v_2)$<jupyter_code>>>> print(vs.vector_add(vs.sv_op(s, v1), vs.sv_op(s, v2)))<jupyter_output>0:1+a<jupyter_text>**Distributivity of vectors over scalar addition** $(s_1 + s_2) \circ v = (s_1 \circ v) \oplus (s_2 \circ v)$<jupyter_code>>>> s1 = 'a'
>>> s2 = '1+a'
>>> v = 'a:1'<jupyter_output><empty_output><jupyter_text>$(s_1 + s_2) \circ v$<jupyter_code>>>> print(vs.sv_op(vs.scalar.add(s1, s2), v))<jupyter_output>a:1<jupyter_text>$(s_1 \circ v) \oplus (s_2 \circ v)$<jupyter_code>>>> print(vs.vector_add(vs.sv_op(s1, v), vs.sv_op(s2, v)))<jupyter_output>a:1<jupyter_text>**Associativity** $s_1 \circ (s_2 \circ v) = (s_1 \times s_2) \circ v$<jupyter_code>>>> s1 = 'a'
>>> s2 = '1+a'
>>> v = 'a:1'<jupyter_output><empty_output><jupyter_text>$s_1 \circ (s_2 \circ v)$<jupyter_code>>>> print(vs.sv_op(s1, vs.sv_op(s2, v)))<jupyter_output>a:1<jupyter_text>$(s_1 \times s_2) \circ v$<jupyter_code>>>> print(vs.sv_op(vs.scalar.mult(s1, s2), v))<jupyter_output>a:1<jupyter_text>Module based on a Ring Another example, using the technique presented above, but this time with a Ring, instead of a Field.Here's the Ring:<jupyter_code>>>> from finite_algebras import generate_powerset_ring
>>> psr2 = generate_powerset_ring(2)
>>> psr2.about()<jupyter_output>** Ring **
Name: PSRing2
Instance ID: 140361151198992
Description: Autogenerated Ring on powerset of {0, 1} w/ symm. diff. (add) & intersection (mult)
Order: 4
Identity: {}
Associative? Yes
Commutative? Yes
Cyclic?: No
Elements:
   Index   Name   Inverse  Order
      0      {}      {}       1
      1     {0}     {0}       2
      2     {1}     {1}       2
      3  {0, 1}  {0, 1}       2
Cayley Table (showing indices):
[[0, 1, 2, 3], [1, 0, 3, 2], [2, 3, 0, 1], [3, 2, 1, 0]]
Mult. Identity: {0, 1}
Mult. Commutative? Yes
Zero Divisors: ['{0}', '{1}']
Multiplicative Cayley Table (showing indices):
[[0, 0, 0, 0], [0, 1, 0, 1], [0, 0, 2, 2], [0, 1, 2, 3]]<jupyter_text>And here's the finite, n-dimensional Module based on the Ring, above:<jupyter_code>>>> n = 2
>>> psr_mod = generate_n_dim_module(psr2, n)
>>> psr_mod.about(max_size=16)<jupyter_output>Module: Mod2-PSRing2
Instance ID: 140359532443536
Description: 2-dimensional Module over PSRing2

SCALARS:

** Ring **
Name: PSRing2
Instance ID: 140361151198992
Description: Autogenerated Ring on powerset of {0, 1} w/ symm. diff. (add) & intersection (mult)
Order: 4
Identity: {}
Associative? Yes
Commutative? Yes
Cyclic?: No
Elements:
   Index   Name   Inverse  Order
      0      {}      {}       1
      1     {0}     {0}       2
      2     {1}     {1}       2
      3  {0, 1}  {0, 1}       2
Cayley Table (showing indices):
[[0, 1, 2, 3], [1, 0, 3, 2], [2, 3, 0, 1], [3, 2, 1, 0]]
Mult. Identity: {0, 1}
Mult. Commutative? Yes
Zero Divisors: ['{0}', '{1}']
Multiplicative Cayley Table (showing indices):
[[0, 0, 0, 0], [0, 1, 0, 1], [0, 0, 2, 2], [0, 1, 2, 3]]

VECTORS:

** Group **
Name: PSRing2_x_PSRing2
Instance ID: 140361151371344
Description: Direct product of PSRing2 & PSRing2
Order: 16
Identity: {}:{}
Associative? Yes
Commutative? Yes
Cyclic?: No
Elements:
   Index   Name   Inverse[...]
{'fraction_non_alphanumeric': 0.1452877249242829, 'fraction_numerical': 0.039105647603776945, 'mean_word_length': 3.824666953158573, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 175, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '19', 'dir': 'jupyter-structured-clean-dedup', 'id': '610254', 'license': 'MIT', 'n_tokens_mistral': 4117, 'n_tokens_neox': 3853, 'n_words': 1371, 'path': 'notebooks/vectors.ipynb', 'repo_name': 'alreich/abstract_algebra', 'size': '11226'}