Skip to content

Commit

Permalink
Merge branch 'notes' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Zune-Ahmed authored Sep 25, 2024
2 parents 99e9906 + 5bb1ccb commit e5dad72
Show file tree
Hide file tree
Showing 14 changed files with 215 additions and 88 deletions.
12 changes: 9 additions & 3 deletions source/combinatorics/sec-combinatorics.ptx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<aside>
<title>Notes</title>
<p>
Factorials are widely used in probability problems, such as determining the number of possible ways a set of items can be arranged.
Factorials are super important in machine learning, especially in models like Naive Bayes and Hidden Markov Models. These models rely on probabilities, and when working with big datasets, factorials help figure out how different sequences of events could happen. This is especially useful when you’re looking at all the possible ways things can unfold over time, like predicting future outcomes based on past events.
</p>
</aside>
<p>
Expand All @@ -33,7 +33,7 @@
<aside>
<title>Notes</title>
<p>
Combinations are useful in scenarios like determining the number of possible committees that can be formed from a larger group.
Combinations come in handy in genetics, helping scientists figure out how traits get passed down from parents to kids. When you have a set of genes, combinations allow you to calculate how many different ways certain traits can be inherited. This is really useful for predicting the chances of diseases or genetic conditions showing up in a family.
</p>
</aside>
<p>
Expand Down Expand Up @@ -74,7 +74,7 @@
<aside>
<title>Notes</title>
<p>
Understanding permutations can help solve problems like scheduling where the order of tasks or events matters.
In cryptography, permutations are key to making strong passwords or encryption systems. The order of characters or keys makes all the difference. By understanding how many different ways a set of characters can be arranged, cryptographers can measure how tough it would be for someone to crack the code using methods like brute force. The more permutations, the harder it is to break in, which keeps systems more secure.
</p>
</aside>
<p>
Expand Down Expand Up @@ -141,3 +141,9 @@
</subsection>

</section>






7 changes: 7 additions & 0 deletions source/functions/sec-recursion.ptx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
<p>
A recursive sequence is defined by one or more base cases and a recursive step that relates each term to its predecessors.
</p>
<aside>
<title>Notes</title>
<p>
Recursion is widely used in everyday tech, like navigating a website or solving puzzles. For example, think about how file systems on your computer are organized into folders and subfolders—finding a file often involves recursively searching through each folder. Recursion is also used in video game development, where actions like rendering objects on the screen or generating game worlds are done by breaking them into smaller, manageable tasks. Students can relate to recursion when they use apps that require repeated tasks, like solving a math problem step-by-step or generating suggestions in a chatbot.
</p>
</aside>
<p>
Given a sequence defined by a recursive formula, we can ask Sage to find its closed form. Here, <c>s</c> is a function representing the sequence defined by recursion. The equation <c>eqn</c> defines the recursive relation <m>s_n = s_{n-1} + 2\cdot s_{n-2}</m>. The <c>rsolve()</c> function is then used to find a closed-form solution to this recurrence, given the initial conditions <m>s_0 = 2</m> and <m>s_1 = 7</m>. At last, we use the <c>SR()</c> function to convert from Python notation to mathematical notation.
</p>
Expand Down Expand Up @@ -116,3 +122,4 @@
</subsection>

</section>

22 changes: 22 additions & 0 deletions source/lattices/sec-definition.ptx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
<p>
A <term>lattice</term> is a partially ordered set (<term>poset</term>) in which any two elements have a least upper bound (also known as join) and greatest lower bound (also known as meet).
</p>
<aside>
<title>notes</title>
<p>
Lattices is used in access control for a company’s security system. Think of it like this: a lattice can map out who has access to what, making sure that a manager can see everything their team does, but the team members only get what they need. This kind of setup keeps things organized and avoids confusion.
</p>
</aside>
<p>
In Sage, a lattice can be represented as a poset using the <c>Poset()</c> function. This function takes a tuple as its argument, where the first element is the set of elements in the poset, and the second element is a list of ordered pairs representing the partial order relations between those elements.
</p>
Expand Down Expand Up @@ -63,6 +69,12 @@
<p>
The join of two elements in a lattice is the least upper bound of those elements.
</p>
<aside>
<title>notes</title>
<p>
The "join" operation helps find the least upper bound between two elements. For example, in a security system, if someone holds two roles—say, as a manager and a team leader—the join helps figure out the highest level of access they should have. It’s a way to combine different permissions and make sure nothing important is left out.
</p>
</aside>
<p>
To check if a poset is a join semi-lattice (every pair of elements has a least upper bound), we use <c>is_join_semilattice()</c> function.
</p>
Expand All @@ -86,6 +98,12 @@
<p>
The meet of two elements in a lattice is their greatest lower bound.
</p>
<aside>
<title>notes</title>
<p>
The "meet" operation is about finding the greatest lower bound. It’s useful when you need to figure out what the most restrictive level is between two things. For example, if two people have different roles with different permissions, the meet will show the most limited access they share. It’s helpful for making sure sensitive information is kept secure and that people only have the access they truly need.
</p>
</aside>
<p>
To check if a poset is a meet semi-lattice (every pair of elements has a greatest lower bound), we use <c>is_meet_semilattice()</c> function.
</p>
Expand All @@ -104,3 +122,7 @@
</sage>
</subsection>
</section>




137 changes: 97 additions & 40 deletions source/lattices/sec-tables-of-operations.ptx
Original file line number Diff line number Diff line change
Expand Up @@ -2,96 +2,153 @@
<title>Tables of Operations</title>
<introduction>
<p>
This section examines the representation of meet <m>(∧)</m> and join <m>(∨)</m> operations within lattices using operation tables.
This section delves into the representation of meet <m>(∧)</m> and join <m>(∨)</m> operations within lattices using operation tables. Such tables are pivotal for visualizing the algebraic structure of lattices and understanding how elements combine under each operation.
</p>
</introduction>

<subsection xml:id="meet-operation-table">
<title>Meet Operation Table</title><idx><h>meet matrix</h></idx>
<p>
The meet operation table illustrates the greatest lower bound, or meet, for every pair of elements in the lattice.
The meet operation table illustrates the greatest lower bound, or meet, for every pair of elements in the lattice.
</p>
<aside>
<title>notes</title>
<p>
The meet operation table shows how elements share a common "lowest" value. Think of it like comparing two sets of preferences between friends—what’s the most basic thing they agree on? The meet operation helps find that shared agreement. For students, it’s similar to when you and a group of friends all like different things, but you find one thing everyone’s okay with. This makes it easier to visualize how different choices or elements overlap in a structured way.
</p>
</aside>
<p>
To output the table as a matrix, we need to specify that the poset is indeed a lattice, thus requiring us to use the function <c>LatticePoset()</c>. Then, we can use the function <c>meet_matrix()</c> to process the table.
For outputting the table as a matrix, we need to specify that the poset is indeed a lattice, thus requiring us to use the function <c>LatticePoset()</c>. Then we can use the function <c>meet_matrix()</c> to process the table.
</p>
<sage>
<input>
elements = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

relations = [
['a', 'b'], ['a', 'c'], ['b', 'd'], ['c', 'd'],
['c', 'e'], ['d', 'f'], ['e', 'f'], ['f', 'g']
]

L = LatticePoset((elements, relations))
M = L.meet_matrix()
show(M)
L = LatticePoset((['a', 'b', 'c', 'd', 'e', 'f', 'g'],
[['a', 'b'], ['a', 'c'], ['b', 'd'], ['c', 'd'],
['c', 'e'], ['d', 'f'], ['e', 'f'], ['f', 'g']]))
P = L.meet_matrix(); L
show(P)
</input>
<output>
# Displays the meet operation table as a matrix.
</output>
</sage>
<p>
From the output matrix, we can see that each entry <m>a_{ij}</m> is not the actual value of the meet of the elements <m>a_{i}</m> and <m>a_{j}</m> but just its position in the lattice. Let's show the values:
From the output matrix, we can see that each entry <m>a_{ij}</m> is not the actual value of the meet of the elements <m>a_{i}</m> and <m>a_{j}</m> but just its position in the lattice. Sage does not have a specific function to output the exact meet, but we can define our own function for this purpose.
</p>
<sage>
<input>
linear_extension = L.linear_extension()

values_meet_matrix = [[linear_extension[M[i, j]] for j in range(len(elements))] for i in range(len(elements))]

values_meet_matrix
L = LatticePoset((['a', 'b', 'c', 'd', 'e', 'f', 'g'],
[['a', 'b'], ['a', 'c'], ['b', 'd'], ['c', 'd'],
['c', 'e'], ['d', 'f'], ['e', 'f'], ['f', 'g']]))
P = L.meet_matrix()
elements = L.list()
K = [['' for _ in range(P.ncols())] for _ in range(P.nrows())]
for i in range(P.nrows()):
for j in range(P.ncols()):
K[i][j] = elements[P[i,j]]
for row in K:
print(row)
</input>
<output>
</output>
</sage>
<p>
Show the output as a table:
We can further improve our function to show the output as a table instead of a matrix.
</p>
<sage>
<input>
import pandas as pd

df = pd.DataFrame(values_meet_matrix)

df
L = LatticePoset((['a', 'b', 'c', 'd', 'e', 'f', 'g'],
[['a', 'b'], ['a', 'c'], ['b', 'd'], ['c', 'd'],
['c', 'e'], ['d', 'f'], ['e', 'f'], ['f', 'g']]))
P = L.meet_matrix()
elements = L.list()
def create_table(elements, P):
column_widths = max(len(element) for element in elements) + 2
header = " " * column_widths + "| " + " ".join(f"{elem:>{column_widths}}" for elem in elements)
divider = "-" * len(header)
table = [header, divider]
for i, row_label in enumerate(elements):
row = f"{row_label:>{column_widths}} | " + " ".join(f"{elements[P[i,j]]:>{column_widths}}" for j in range(len(elements)))
table.append(row)
return "\n".join(table)
print(create_table(elements, P))
</input>
<output>
</output>
</sage>

</subsection>

<subsection xml:id="join-operation-table">
<title>Join Operation Table</title><idx><h>join matrix</h></idx>
<p>
Conversely, the join operation table presents the least upper bound, or join, for each pair of lattice elements.
Conversely, the join operation table presents the least upper bound, or join, for each pair of lattice elements.
</p>
<aside>
<title>notes</title>
<p>
The join operation table is about finding the "highest" shared element between different parts. Imagine you’re working on a group project, and you need to combine ideas from different people. The join helps figure out the most complete version of your ideas without missing anything important. It’s like taking the best suggestions from each person and merging them to create the ultimate solution that works for everyone.
</p>
</aside>
<p>
Similarly, we can use the function <c>join_matrix()</c> to process the table.
</p>
<sage>
<input>
J = L.join_matrix()

show(J)
L = LatticePoset((['a', 'b', 'c', 'd', 'e', 'f', 'g'],
[['a', 'b'], ['a', 'c'], ['b', 'd'], ['c', 'd'],
['c', 'e'], ['d', 'f'], ['e', 'f'], ['f', 'g']]))
P = L.join_matrix(); L
show(P)
</input>
<output>
# Displays the join operation table as a matrix.
</output>
</sage>
<p>
Output the elements of the poset:
We can also output the elements of the poset by slightly changing the function we previously defined.
</p>
<sage>
<input>
linear_extension = L.linear_extension()

values_join_matrix = [[linear_extension[J[i, j]] for j in range(len(elements))] for i in range(len(elements))]
L = LatticePoset((['a', 'b', 'c', 'd', 'e', 'f', 'g'],
[['a', 'b'], ['a', 'c'], ['b', 'd'], ['c', 'd'],
['c', 'e'], ['d', 'f'], ['e', 'f'], ['f', 'g']]))
P = L.join_matrix()
elements = L.list()
K = [['' for _ in range(P.ncols())] for _ in range(P.nrows())]
for i in range(P.nrows()):
for j in range(P.ncols()):
K[i][j] = elements[P[i,j]]

values_join_matrix
for row in K:
print(row)
</input>
<output>
</output>
</sage>
<p>
Show the output as a table instead of a matrix.
We can also output the join table just as shown above for meet.
</p>
<sage>
<input>
import pandas as pd

df = pd.DataFrame(values_join_matrix)

df
L = LatticePoset((['a', 'b', 'c', 'd', 'e', 'f', 'g'],
[['a', 'b'], ['a', 'c'], ['b', 'd'], ['c', 'd'],
['c', 'e'], ['d', 'f'], ['e', 'f'], ['f', 'g']]))
P = L.join_matrix()
elements = L.list()
def create_table(elements, P):
column_widths = max(len(element) for element in elements) + 2
header = " " * column_widths + "| " + " ".join(f"{elem:>{column_widths}}" for elem in elements)
divider = "-" * len(header)
table = [header, divider]
for i, row_label in enumerate(elements):
row = f"{row_label:>{column_widths}} | " + " ".join(f"{elements[P[i,j]]:>{column_widths}}" for j in range(len(elements)))
table.append(row)
return "\n".join(table)
print(create_table(elements, P))
</input>
<output>
</output>
</sage>
</subsection>
</section>
26 changes: 15 additions & 11 deletions source/logic/sec-logical-operation.ptx
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,52 @@
<idx><h>logical operators</h><h>biconditional</h></idx>
<introduction>
<p>
In Sage, the logical operators are AND <c>&amp;</c>, OR <c>|</c>, NOT <c>~</c>, conditional <c>-&gt;</c>, and biconditional <c>&lt;-&gt;</c>.
In Sage, logical operations such as AND <c>&amp;</c>, OR <c>|</c>, NOT <c>~</c>, conditional <c>-&gt;</c>, and biconditional <c>&lt;-&gt;</c> play crucial roles in constructing and evaluating logical expressions.
</p>
<tabular>
<row>
<cell>Name</cell>
<cell>Sage Operator</cell>
<cell>Operator</cell>
<cell>Symbol</cell>
<cell>Mathematical Notation</cell>
</row>
<row>
<cell>AND</cell>
<cell><c>&amp;</c></cell>
<cell>&amp;</cell>
<cell><m>\land</m></cell>
</row>
<row>
<cell>OR</cell>
<cell><c>|</c></cell>
<cell>|</cell>
<cell><m>\lor</m></cell>
</row>
<row>
<cell>NOT</cell>
<cell><c>~</c></cell>
<cell>~</cell>
<cell><m>\lnot</m></cell>
</row>
<row>
<cell>Conditional</cell>
<cell><c>-&gt;</c></cell>
<cell>-&gt;</cell>
<cell><m>\rightarrow</m></cell>
</row>
<row>
<cell>Biconditional</cell>
<cell><c>&lt;-&gt;</c></cell>
<cell>&lt;-&gt;</cell>
<cell><m>\leftrightarrow</m></cell>
</row>
</tabular>
<aside>
<title>Notes</title>
<p>
Logical operators are fundamental in digital circuit design. They are used to create complex circuits like ALUs (Arithmetic Logic Units) in computer processors, where operations such as addition, subtraction, and bit shifting rely on combinations of AND, OR, and NOT gates. Understanding these basics is essential for designing efficient electronic and software solutions.
Logical operators like AND, OR, and NOT are at the heart of decision-making in AI and machine learning systems. Take an autonomous vehicle, for instance. The car uses these operators to process inputs from different sensors—such as speed, distance from obstacles, and road conditions—to make decisions. Whether it should brake, accelerate, or steer depends on how these inputs combine. These logical operations allow the vehicle to quickly analyze real-time data and make safe, efficient decisions on the fly.
</p>
</aside>

</introduction>
<!-- Logical Operations in Sage -->
<subsection>
<title>Boolean Formula</title>

<p>
Sage's <c>propcalc.formula()</c> function allows for the creation of Boolean formulas using variables and logical operators. We can then use <c>show</c> function to display the mathematical notations.
</p>
Expand All @@ -61,7 +61,11 @@
A = propcalc.formula('(p &amp; q) | (~p)')
show(A)
</input>
<output>
# Displays the Boolean formula (p AND q) OR (NOT p) in mathematical notation.
</output>
</sage>
</subsection>

</section>

Loading

0 comments on commit e5dad72

Please sign in to comment.