Compare commits
9 Commits
a35662637b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2244a076a | ||
|
|
a50fc0e90f | ||
|
|
5bbbb4f1da | ||
|
|
b7b584a989 | ||
|
|
b50b42c01b | ||
|
|
201182156f | ||
|
|
bd228e9dca | ||
|
|
846f4e00b7 | ||
|
|
7dedef5665 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
*.pdf
|
*.pdf
|
||||||
latex.out/
|
latex.out/
|
||||||
.direnv
|
.direnv
|
||||||
|
__pycache__/
|
||||||
|
|||||||
268
CS1527/assessment-1/assessment1.py
Normal file
268
CS1527/assessment-1/assessment1.py
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
# The following is a template of the design.
|
||||||
|
# you will need to complete the definition of each class, including class attributes,
|
||||||
|
# instance attributes, and instance methods. However, please do not change the class
|
||||||
|
# names provided below.
|
||||||
|
|
||||||
|
# IMPORTANT: In order to get your program pass the test, make sure your class constructors
|
||||||
|
# use exactly the same parameter names as in the test examples provided at the end of this template.
|
||||||
|
|
||||||
|
# ================Your codes start here=============
|
||||||
|
# Notes:
|
||||||
|
# - Should a motorboat (or eboat) really *be* an engine?
|
||||||
|
# - Why are the keyword arguments abbreviated?
|
||||||
|
|
||||||
|
|
||||||
|
def class_bases(cls):
|
||||||
|
"""Generator of the base classes of a class (including the given class).
|
||||||
|
|
||||||
|
Depth-first, post-order, may yield duplicates
|
||||||
|
"""
|
||||||
|
for cls_ in cls.__bases__:
|
||||||
|
yield from class_bases(cls_)
|
||||||
|
yield cls
|
||||||
|
|
||||||
|
|
||||||
|
def field_repr(obj) -> str:
|
||||||
|
"""String representation of an object
|
||||||
|
|
||||||
|
Lists fields with type annotations in object's class and superclasses"""
|
||||||
|
classes = class_bases(obj.__class__)
|
||||||
|
attrs = (
|
||||||
|
attr for cls in classes for attr in getattr(cls, "__annotations__", {}).keys()
|
||||||
|
)
|
||||||
|
attrs_vals = ",".join(f"{attr}={getattr(obj, attr, None)!r}" for attr in attrs)
|
||||||
|
return f"{obj.__class__.__name__}({attrs_vals})"
|
||||||
|
|
||||||
|
|
||||||
|
class Boat:
|
||||||
|
"""A boat
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
- `color`: color of boat
|
||||||
|
- `brand`: boat brand
|
||||||
|
- `year`: manufacture year
|
||||||
|
|
||||||
|
Class Attributes:
|
||||||
|
- `all_boats`: a list of all boats ever constructed
|
||||||
|
"""
|
||||||
|
|
||||||
|
all_boats = []
|
||||||
|
|
||||||
|
color: str
|
||||||
|
brand: str
|
||||||
|
year: int
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
co: str,
|
||||||
|
br: str,
|
||||||
|
yr: int,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
|
"""Initialize a `Boat`.
|
||||||
|
|
||||||
|
Takes keyword-only arguments `co` (color), `br` (brand), and `yr` (year)
|
||||||
|
as described in class docstring
|
||||||
|
"""
|
||||||
|
Boat.all_boats.append(self)
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
self.color = co
|
||||||
|
self.brand = br
|
||||||
|
self.year = yr
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return field_repr(self)
|
||||||
|
|
||||||
|
def get_boat_age(self, current_year: int) -> int:
|
||||||
|
"""Get the age of this boat given the current year"""
|
||||||
|
return current_year - self.year
|
||||||
|
|
||||||
|
|
||||||
|
class Engine:
|
||||||
|
"""An Engine
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
- `tech`: Technology used by the engine.
|
||||||
|
Either 'gas' or 'electric'
|
||||||
|
- `engine_speed`: maximum speed in miles per hour
|
||||||
|
determined by `tech` - gas engines have speed 80mph, electric 20mph
|
||||||
|
|
||||||
|
Class Attributes:
|
||||||
|
- `speeds`: mapping of engine tech to speed
|
||||||
|
"""
|
||||||
|
|
||||||
|
speeds = {"gas": 80, "electric": 20}
|
||||||
|
|
||||||
|
engine_speed: float
|
||||||
|
tech: str
|
||||||
|
|
||||||
|
def __init__(self, *, tech: str, **kwargs):
|
||||||
|
"""Initialize an `Engine`
|
||||||
|
|
||||||
|
Takes keyword-only argument `tech` (see class docstring)
|
||||||
|
"""
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
self.tech = tech
|
||||||
|
self.engine_speed = Engine.speeds[tech]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return field_repr(self)
|
||||||
|
|
||||||
|
def get_engine_speed(self) -> float:
|
||||||
|
"""Get the engine speed for this engine in miles per hour"""
|
||||||
|
return self.engine_speed
|
||||||
|
|
||||||
|
|
||||||
|
class Motorboat(Boat, Engine):
|
||||||
|
"""A Motorboat
|
||||||
|
|
||||||
|
Always uses 'gas' engine tech
|
||||||
|
Attributes:
|
||||||
|
- `fuel_level`: remaining level of fuel in gallons
|
||||||
|
- `fuel_efficiency`: range with a certain amount of fuel in miles per gallon
|
||||||
|
"""
|
||||||
|
|
||||||
|
fuel_level: float
|
||||||
|
fuel_efficiency: float
|
||||||
|
|
||||||
|
def __init__(self, *, fl: float, fe: float, **kwargs):
|
||||||
|
"""Initialize a `Motorboat`
|
||||||
|
|
||||||
|
Takes keyword-only arguments `fl` (fuel level) and `fe` (fuel efficiency)
|
||||||
|
as described in class docstring, in addition to the arguments described in `Boat`
|
||||||
|
"""
|
||||||
|
super().__init__(**kwargs, tech="gas")
|
||||||
|
|
||||||
|
self.fuel_level = fl
|
||||||
|
self.fuel_efficiency = fe
|
||||||
|
|
||||||
|
def get_max_speed(self) -> float:
|
||||||
|
"""Get the max speed of the motorboat"""
|
||||||
|
return self.engine_speed
|
||||||
|
|
||||||
|
def cal_travel_time(self, distance: float) -> float:
|
||||||
|
"""Calculate the time to travel `distance` miles
|
||||||
|
|
||||||
|
Prints a message and returns max engine runtime
|
||||||
|
if the engine would run out of fuel before the destination
|
||||||
|
"""
|
||||||
|
range = self.fuel_level * self.fuel_efficiency
|
||||||
|
if range < distance:
|
||||||
|
print(
|
||||||
|
f"This motorboat runs out of fuel {distance - range} miles away from the destination."
|
||||||
|
)
|
||||||
|
return min(range, distance) / self.engine_speed
|
||||||
|
|
||||||
|
|
||||||
|
class Pedalboat(Boat):
|
||||||
|
"""A Pedalboat
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
- `pedal_speed`: speed attainable by pedalling in miles per hour
|
||||||
|
Generally in range [10, 20]
|
||||||
|
"""
|
||||||
|
|
||||||
|
pedal_speed: float
|
||||||
|
|
||||||
|
def __init__(self, *, ps: float, **kwargs):
|
||||||
|
"""Initialize a `Pedalboat`
|
||||||
|
|
||||||
|
Clamps `pedal_speed` to `10 <= pedal_speed <= 20`
|
||||||
|
|
||||||
|
Takes keyword-only argument `ps` (pedal speed), as described in the class docstring,
|
||||||
|
in addition to the arguments described in `Boat`
|
||||||
|
"""
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
self.pedal_speed = ps
|
||||||
|
self.check_speed()
|
||||||
|
|
||||||
|
def get_pedal_speed(self) -> float:
|
||||||
|
"""Get the pedalling speed of the boat in miles per hour"""
|
||||||
|
return self.pedal_speed
|
||||||
|
|
||||||
|
def cal_travel_time(self, distance: float) -> float:
|
||||||
|
"""Calculate the time to travel `distance` miles
|
||||||
|
"""
|
||||||
|
return distance / self.pedal_speed
|
||||||
|
|
||||||
|
def check_speed(self):
|
||||||
|
"""Clamps `pedal_speed` to `10 <= pedal_speed <= 20`
|
||||||
|
Returns whether the speed was already in this range
|
||||||
|
"""
|
||||||
|
if 10 <= self.pedal_speed <= 20:
|
||||||
|
return True
|
||||||
|
self.pedal_speed = min(20, max(self.pedal_speed, 10))
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class Eboat(Pedalboat, Engine):
|
||||||
|
"""An `Eboat`
|
||||||
|
|
||||||
|
Always has engine tech 'electric'
|
||||||
|
Attributes:
|
||||||
|
- `battery_time`: remaining battery running time in hours
|
||||||
|
"""
|
||||||
|
|
||||||
|
battery_time: float
|
||||||
|
|
||||||
|
def __init__(self, *, bt: float, **kwargs):
|
||||||
|
"""Initialize an `Eboat`
|
||||||
|
|
||||||
|
Takes keyword-only argument `bt` (battery time), as described in the class docstring,
|
||||||
|
in addition to the arguments described in `Pedalboat`
|
||||||
|
"""
|
||||||
|
super().__init__(**kwargs, tech="electric")
|
||||||
|
|
||||||
|
self.battery_time = bt
|
||||||
|
|
||||||
|
def get_max_speed(self) -> float:
|
||||||
|
"""The maximum speed attainable in this boat by running the engine and pedalling"""
|
||||||
|
return self.pedal_speed + self.engine_speed
|
||||||
|
|
||||||
|
def cal_travel_time(self, distance: float) -> float:
|
||||||
|
"""Calculate the time to travel `distance` miles
|
||||||
|
"""
|
||||||
|
battery_range = self.get_max_speed() * self.battery_time
|
||||||
|
return (
|
||||||
|
min(distance, battery_range) / self.get_max_speed()
|
||||||
|
+ max(distance - battery_range, 0) / self.pedal_speed
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ============ End of your codes here ==================
|
||||||
|
|
||||||
|
|
||||||
|
# ============No modification beyond here =============
|
||||||
|
# the following is a list of test instances, please do not modify them
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# arguments: co - color, br - brand, yr - year, tech - technology used in engine
|
||||||
|
boat1 = Boat(co="Black", br="Trek", yr=2012)
|
||||||
|
engine1 = Engine(tech="gas")
|
||||||
|
print(engine1.get_engine_speed())
|
||||||
|
|
||||||
|
# arguments: co - color, br - brand, yr - year, ps - pedal speed
|
||||||
|
pedalboat1 = Pedalboat(co="Red", br="GIANT", yr=2015, ps=15)
|
||||||
|
pedalboat2 = Pedalboat(co="Red", br="GIANT", yr=2015, ps=30)
|
||||||
|
print(pedalboat1.get_pedal_speed())
|
||||||
|
print(pedalboat2.get_pedal_speed())
|
||||||
|
print(pedalboat1.cal_travel_time(300))
|
||||||
|
|
||||||
|
# arguments: co - color, br - brand, yr - year, ps - pedal speed, bt - battery time
|
||||||
|
eboat1 = Eboat(co="Blue", br="Basis", yr=2018, ps=15, bt=10)
|
||||||
|
print(eboat1.get_max_speed())
|
||||||
|
print(eboat1.cal_travel_time(350))
|
||||||
|
print(eboat1.cal_travel_time(650))
|
||||||
|
|
||||||
|
# arguments: co - color, br - brand, yr - year, fl - fuel level, fe - fuel efficiency
|
||||||
|
motorboat1 = Motorboat(co="Silver", br="YAMAHA", yr=2013, fl=40, fe=12)
|
||||||
|
print(motorboat1.get_max_speed())
|
||||||
|
print(motorboat1.cal_travel_time(300))
|
||||||
|
print(motorboat1.cal_travel_time(600))
|
||||||
|
|
||||||
|
# get the age of all bikes created
|
||||||
|
for b in Boat.all_boats:
|
||||||
|
print(b.get_boat_age(2023))
|
||||||
2
CS1527/assessment-2/.envrc
Normal file
2
CS1527/assessment-2/.envrc
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export NIX_PATH="nixpkgs=flake:nixpkgs"
|
||||||
|
use nix
|
||||||
404
CS1527/assessment-2/assessment2.py
Normal file
404
CS1527/assessment-2/assessment2.py
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""Usage: `python assessment2.py {subcommand} {expressions}`
|
||||||
|
|
||||||
|
If expressions are not provided, they are taken from each line of stdin.
|
||||||
|
Documentation of subcommands is available from `python assessment2.py -h`.
|
||||||
|
|
||||||
|
Examples for marking criteria:
|
||||||
|
1. Eval: `python assessment2.py eval "(((2*(3+2))+5)/2)"`
|
||||||
|
2. Tree: `python assessment2.py render-tree "(((2*(3+2))+5)/2)"`
|
||||||
|
3. Preorder: `python assessment2.py format-prefix "(((2*(3+2))+5)/2)"`
|
||||||
|
In-order: `python assessment2.py format-infix "(((2*(3+2))+5)/2)"`
|
||||||
|
Postorder: `python assessment2.py format-postfix "(((2*(3+2))+5)/2)"`
|
||||||
|
4. Errors: `python assessment2.py eval "(4*3*2)" "(4*(2))" "(4*(3+2)*(2+1))" "(2*4)*(3+2)" "((2+3)*(4*5)" "((2+3)*(4*5)" "(2+5)*(4/(2+2)))" "(2+5)*(4/(2+2)))" "(((2+3)*(4*5))+(1(2+3)))"`
|
||||||
|
5. Tests: `python assessment2.py test`
|
||||||
|
|
||||||
|
Tests can be run with `pytest assessment2.py` or `python assessment2.py test`.
|
||||||
|
|
||||||
|
All of the formatting is implemented with post-order traversals. This is
|
||||||
|
necessary to output parenthesis in the pre- and in-order cases. It could also be
|
||||||
|
done with a buffer and a combined traversal (with callbacks before, between, and
|
||||||
|
after subtree visits), but that requires mutation.
|
||||||
|
|
||||||
|
Note: this program requires Python 3.12 due to the generic syntax used to define
|
||||||
|
`BTree.traverse`. Pytest is also required. These should be installed already
|
||||||
|
on Codio.
|
||||||
|
"""
|
||||||
|
# stdlib
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Literal, Tuple, Callable, cast, override
|
||||||
|
from operator import add, sub, mul, truediv as div
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
from textwrap import dedent
|
||||||
|
|
||||||
|
# pytest, from https://pypi.org/project/pytest/
|
||||||
|
# authors can be found at https://github.com/pytest-dev/pytest/graphs/contributors,
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
OPERATORS: dict[Literal["+", "-", "*", "/"], Callable[[float, float], float]] = {
|
||||||
|
"+": add,
|
||||||
|
"-": sub,
|
||||||
|
"*": mul,
|
||||||
|
"/": div,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BTree:
|
||||||
|
value: float
|
||||||
|
|
||||||
|
def traverse[T](
|
||||||
|
self,
|
||||||
|
value: Callable[["Value", int], T],
|
||||||
|
operator: Callable[["Operator", T, T, int], T],
|
||||||
|
depth: int = 0,
|
||||||
|
) -> T:
|
||||||
|
"""Traverse the binary tree with a post-order traversal
|
||||||
|
|
||||||
|
`value` takes the value node and its depth from the root node
|
||||||
|
`operator` takes the operator node, the results of traversing the left
|
||||||
|
and right subtrees, and the depth of the node
|
||||||
|
|
||||||
|
The tree could, for example, be evaluated with `traverse`:
|
||||||
|
```
|
||||||
|
(...).traverse(
|
||||||
|
lambda node, _: node.value,
|
||||||
|
lambda node, left, right, _: OPERATORS[node.operator](left, right)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def as_preorder_str(self) -> str:
|
||||||
|
"""Format the tree in prefix notation"""
|
||||||
|
return self.traverse(
|
||||||
|
lambda value, _: str(value.value),
|
||||||
|
lambda op, left, right, _: f"({op.operator} {left} {right})",
|
||||||
|
)
|
||||||
|
|
||||||
|
def as_inorder_str(self) -> str:
|
||||||
|
"""Format the tree as a typical parenthesized expression"""
|
||||||
|
return self.traverse(
|
||||||
|
lambda value, _: str(value.value),
|
||||||
|
lambda op, left, right, _: f"({left} {op.operator} {right})",
|
||||||
|
)
|
||||||
|
|
||||||
|
__str__ = as_inorder_str
|
||||||
|
|
||||||
|
def as_inorder_lines(self) -> str:
|
||||||
|
"""Format the tree, visually as a tree"""
|
||||||
|
return self.traverse(
|
||||||
|
lambda value, depth: " " * depth + str(value.value),
|
||||||
|
lambda op, left, right, depth: f"{left}\n{' ' * depth}{op.operator}\n{right}",
|
||||||
|
)
|
||||||
|
|
||||||
|
def as_postorder_str(self) -> str:
|
||||||
|
"""Format the tree in postfix notation (RPN)"""
|
||||||
|
return self.traverse(
|
||||||
|
lambda value, _: str(value.value),
|
||||||
|
lambda op, left, right, _: f"{left} {right} {op.operator}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, slots=True)
|
||||||
|
class Value(BTree):
|
||||||
|
value: float
|
||||||
|
|
||||||
|
@override
|
||||||
|
def traverse[T](
|
||||||
|
self,
|
||||||
|
value: Callable[["Value", int], T],
|
||||||
|
operator: Callable[["Operator", T, T, int], T],
|
||||||
|
depth: int = 0,
|
||||||
|
) -> T:
|
||||||
|
"""Traverse the binary tree with a post-order traversal
|
||||||
|
|
||||||
|
`value` takes the value node and its depth from the root node
|
||||||
|
`operator` takes the operator node, the results of traversing the left
|
||||||
|
and right subtrees, and the depth of the node
|
||||||
|
|
||||||
|
The tree could, for example, be evaluated with `traverse`:
|
||||||
|
```
|
||||||
|
(...).traverse(
|
||||||
|
lambda node, _: node.value,
|
||||||
|
lambda node, left, right, _: OPERATORS[node.operator](left, right)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
return value(self, depth)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, slots=True)
|
||||||
|
class Operator(BTree):
|
||||||
|
operator: Literal["+", "-", "*", "/"]
|
||||||
|
left: BTree
|
||||||
|
right: BTree
|
||||||
|
|
||||||
|
@property
|
||||||
|
def value(self) -> float: # type: ignore - the field should be read-only
|
||||||
|
return OPERATORS[self.operator](self.left.value, self.right.value)
|
||||||
|
|
||||||
|
@override
|
||||||
|
def traverse[T](
|
||||||
|
self,
|
||||||
|
value: Callable[["Value", int], T],
|
||||||
|
operator: Callable[["Operator", T, T, int], T],
|
||||||
|
depth: int = 0,
|
||||||
|
) -> T:
|
||||||
|
"""Traverse the binary tree with a post-order traversal
|
||||||
|
|
||||||
|
`value` takes the value node and its depth from the root node
|
||||||
|
`operator` takes the operator node, the results of traversing the left
|
||||||
|
and right subtrees, and the depth of the node
|
||||||
|
|
||||||
|
The tree could, for example, be evaluated with `traverse`:
|
||||||
|
```
|
||||||
|
(...).traverse(
|
||||||
|
lambda node, _: node.value,
|
||||||
|
lambda node, left, right, _: OPERATORS[node.operator](left, right)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
return operator(
|
||||||
|
self,
|
||||||
|
self.left.traverse(value, operator, depth + 1),
|
||||||
|
self.right.traverse(value, operator, depth + 1),
|
||||||
|
depth,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(expr: str) -> BTree:
|
||||||
|
"""Parse a parenthesized expression as in the spec.
|
||||||
|
|
||||||
|
Requires a single parenthesized string, potentially with whitespace
|
||||||
|
Raises ValueError on parse errors
|
||||||
|
"""
|
||||||
|
|
||||||
|
def number(expr: str) -> Tuple[BTree, str] | None:
|
||||||
|
if not expr[0].isdigit():
|
||||||
|
return None
|
||||||
|
rest = expr.lstrip("0123456789")
|
||||||
|
return Value(int(expr[: len(expr) - len(rest)])), rest.lstrip()
|
||||||
|
|
||||||
|
def parenthesized(expr: str) -> Tuple[BTree, str] | None:
|
||||||
|
if not expr.startswith("("):
|
||||||
|
return None
|
||||||
|
expr = expr[1:].lstrip()
|
||||||
|
|
||||||
|
left, expr = operand(expr)
|
||||||
|
|
||||||
|
operator, expr = expr[0], expr[1:]
|
||||||
|
if operator not in OPERATORS:
|
||||||
|
raise ValueError(f"Unknown operator {operator}")
|
||||||
|
operator = cast(Literal["+", "-", "*", "/"], operator)
|
||||||
|
|
||||||
|
right, expr = operand(expr.lstrip())
|
||||||
|
|
||||||
|
if not expr.startswith(")"):
|
||||||
|
if expr and expr[0] in OPERATORS:
|
||||||
|
raise ValueError("Too many operands in expression")
|
||||||
|
raise ValueError("Expected closing parenthesis")
|
||||||
|
return Operator(operator, left, right), expr[1:].lstrip()
|
||||||
|
|
||||||
|
def operand(expr: str) -> Tuple[BTree, str]:
|
||||||
|
v = number(expr) or parenthesized(expr)
|
||||||
|
if not v:
|
||||||
|
raise ValueError(
|
||||||
|
"Expected a number or the beginning of a parenthesized expression"
|
||||||
|
)
|
||||||
|
return v
|
||||||
|
|
||||||
|
result = parenthesized(expr.lstrip())
|
||||||
|
if not result or result[1]:
|
||||||
|
# If rest is non-empty, then something was after the parenthesis starting the expression
|
||||||
|
# i.e. the full expression was not parenthesized.
|
||||||
|
raise ValueError("Expected parenthesized expression at the top level")
|
||||||
|
|
||||||
|
return result[0]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("expr", "ast"),
|
||||||
|
[
|
||||||
|
("(1 + 1)", Operator("+", Value(1), Value(1))),
|
||||||
|
(
|
||||||
|
"(2*(3+ 2))",
|
||||||
|
Operator("*", Value(2), Operator("+", Value(3), Value(2))),
|
||||||
|
),
|
||||||
|
(" (1 +1) ", Operator("+", Value(1), Value(1))),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_parse(expr: str, ast: BTree):
|
||||||
|
"""Test parsing of expressions"""
|
||||||
|
assert parse(expr) == ast
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("expr", "value"),
|
||||||
|
[
|
||||||
|
("(1 + 2)", 3),
|
||||||
|
("(12 + (((4 / 2) * 3) + (3 * 2)))", 24),
|
||||||
|
("(((2 * (3 + 2)) + 5) / 2)", 7.5),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_eval(expr: str, value: float):
|
||||||
|
"""Test evaluation"""
|
||||||
|
assert parse(expr).value == value
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("expr", "tree"),
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"(1 + 2)",
|
||||||
|
"""
|
||||||
|
1
|
||||||
|
+
|
||||||
|
2
|
||||||
|
""",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(1 + (((4 / 2) * 3) + (3 * 2)))",
|
||||||
|
"""
|
||||||
|
1
|
||||||
|
+
|
||||||
|
4
|
||||||
|
/
|
||||||
|
2
|
||||||
|
*
|
||||||
|
3
|
||||||
|
+
|
||||||
|
3
|
||||||
|
*
|
||||||
|
2
|
||||||
|
""",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"(((2*(3+2))+5)/2)",
|
||||||
|
"""
|
||||||
|
2
|
||||||
|
*
|
||||||
|
3
|
||||||
|
+
|
||||||
|
2
|
||||||
|
+
|
||||||
|
5
|
||||||
|
/
|
||||||
|
2
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_inorder_lines(expr: str, tree: str):
|
||||||
|
"""Test tree rendering"""
|
||||||
|
assert parse(expr).as_inorder_lines() == dedent(tree).strip("\n")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("expr", "prefix"),
|
||||||
|
[
|
||||||
|
("(1 + 2)", "(+ 1 2)"),
|
||||||
|
("(1 + (((4 / 2) * 3) + (3 * 2)))", "(+ 1 (+ (* (/ 4 2) 3) (* 3 2)))"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_prefix(expr: str, prefix: str):
|
||||||
|
"""Test prefix formatting"""
|
||||||
|
assert parse(expr).as_preorder_str() == prefix
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("expr"),
|
||||||
|
[
|
||||||
|
"(1 + 2)",
|
||||||
|
"(1 + (((4 / 2) * 3) + (3 * 2)))",
|
||||||
|
"(((3 + 2) * 2) + (((7 / 3) * 5) - 3))",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_infix_roundtrip(expr: str):
|
||||||
|
"""Test infix formatting roundtrips"""
|
||||||
|
assert str(parse(expr)) == expr
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("expr", "postfix"),
|
||||||
|
[
|
||||||
|
("(1 + 2)", "1 2 +"),
|
||||||
|
("(1 + (((4 / 2) * 3) + (3 * 2)))", "1 4 2 / 3 * 3 2 * + +"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_postfix(expr: str, postfix: str):
|
||||||
|
"""Test postfix formatting"""
|
||||||
|
assert parse(expr).as_postorder_str() == postfix
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("expr", "err"),
|
||||||
|
[
|
||||||
|
("(4 * 3 * 2)", "Too many operands in expression"),
|
||||||
|
("(4 * (2))", "Unknown operator )"),
|
||||||
|
("(4 * (3 + 2) * (2 + 1))", "Too many operands in expression"),
|
||||||
|
("(2 *4)*(3+2)", "Expected parenthesized expression at the top level"),
|
||||||
|
("(2+5)*(4/(2+2))", "Expected parenthesized expression at the top level"),
|
||||||
|
("(((2+3)*(4*5))+(1(2+3)))", "Unknown operator ("),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_error(expr: str, err: str):
|
||||||
|
"""Test error messages"""
|
||||||
|
with pytest.raises(ValueError, match=re.escape(err)):
|
||||||
|
parse(expr)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = ArgumentParser(usage=__doc__)
|
||||||
|
subcommands = parser.add_subparsers(title="Subcommands", required=True)
|
||||||
|
|
||||||
|
def with_expressions(parser):
|
||||||
|
parser.add_argument(
|
||||||
|
"expressions",
|
||||||
|
nargs="*",
|
||||||
|
help="The expressions to operate on. If none are provided, operate on lines of stdin.",
|
||||||
|
)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
with_expressions(
|
||||||
|
subcommands.add_parser("eval", help="Evaluate the expression")
|
||||||
|
).set_defaults(func=lambda expr: expr.value)
|
||||||
|
with_expressions(
|
||||||
|
subcommands.add_parser("render-tree", help="Render the expression as a tree")
|
||||||
|
).set_defaults(func=BTree.as_inorder_lines)
|
||||||
|
with_expressions(
|
||||||
|
subcommands.add_parser(
|
||||||
|
"format-prefix", help="Format the expression in prefix notation"
|
||||||
|
)
|
||||||
|
).set_defaults(func=BTree.as_preorder_str)
|
||||||
|
with_expressions(
|
||||||
|
subcommands.add_parser(
|
||||||
|
"format-infix",
|
||||||
|
help="Format the expression in typical parenthesized infix notation",
|
||||||
|
)
|
||||||
|
).set_defaults(func=BTree.as_inorder_str)
|
||||||
|
with_expressions(
|
||||||
|
subcommands.add_parser(
|
||||||
|
"format-postfix",
|
||||||
|
help="Format the expression in postfix notation, i.e. as RPN",
|
||||||
|
)
|
||||||
|
).set_defaults(func=BTree.as_postorder_str)
|
||||||
|
subcommands.add_parser("test", help="Run tests").set_defaults(
|
||||||
|
func=lambda: pytest.main([__file__])
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
if "expressions" in args:
|
||||||
|
for expression in args.expressions or sys.stdin:
|
||||||
|
if len(args.expressions) > 1:
|
||||||
|
print(expression + ":")
|
||||||
|
try:
|
||||||
|
parsed = parse(expression)
|
||||||
|
except ValueError as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
continue
|
||||||
|
print(args.func(parsed))
|
||||||
|
else:
|
||||||
|
args.func()
|
||||||
3
CS1527/assessment-2/shell.nix
Normal file
3
CS1527/assessment-2/shell.nix
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{ pkgs ? import <nixpkgs> {} }: pkgs.mkShell {
|
||||||
|
packages = [(pkgs.python312.withPackages (p: with p; [ python-lsp-server pytest pytest-watch black ])) pkgs.nodePackages.pyright];
|
||||||
|
}
|
||||||
1
CS1527/notes-2024-02-02.md
Normal file
1
CS1527/notes-2024-02-02.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
CS1527/notes-2024-02-06.md
Normal file
1
CS1527/notes-2024-02-06.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
CS1527/notes-2024-02-13.md
Normal file
1
CS1527/notes-2024-02-13.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
CS1527/notes-2024-02-27.md
Normal file
1
CS1527/notes-2024-02-27.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
CS1534/notes-2024-02-08.md
Normal file
1
CS1534/notes-2024-02-08.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
CS1534/notes-2024-02-13.md
Normal file
1
CS1534/notes-2024-02-13.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
CS1534/notes-2024-02-15.md
Normal file
1
CS1534/notes-2024-02-15.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
\author{}
|
\author{}
|
||||||
|
|
||||||
\newcommand{\paren}[1]{\left(#1\right)}
|
\newcommand{\paren}[1]{\left(#1\right)}
|
||||||
|
\newcommand{\powerset}[1]{\mathcal{P}\paren{#1}}
|
||||||
\renewcommand{\Re}[1]{\operatorname{\mathbb{R}e}\paren{#1}}
|
\renewcommand{\Re}[1]{\operatorname{\mathbb{R}e}\paren{#1}}
|
||||||
\renewcommand{\Im}[1]{\operatorname{\mathbb{{I}}m}\paren{#1}}
|
\renewcommand{\Im}[1]{\operatorname{\mathbb{{I}}m}\paren{#1}}
|
||||||
\newcommand{\C}{\mathbb{C}}
|
\newcommand{\C}{\mathbb{C}}
|
||||||
@@ -21,9 +22,17 @@
|
|||||||
\newcommand{\abs}[1]{\left|#1\right|}
|
\newcommand{\abs}[1]{\left|#1\right|}
|
||||||
\newcommand{\polar}[2]{#1\paren{\cos{\paren{#2}} + i\sin{\paren{#2}}}}
|
\newcommand{\polar}[2]{#1\paren{\cos{\paren{#2}} + i\sin{\paren{#2}}}}
|
||||||
\newcommand{\adj}[1]{\operatorname{adj}#1}
|
\newcommand{\adj}[1]{\operatorname{adj}#1}
|
||||||
|
\newcommand{\card}[1]{\left|#1\right|}
|
||||||
|
\newcommand{\littletaller}{\mathchoice{\vphantom{\big|}}{}{}{}}
|
||||||
|
\newcommand{\restr}[2]{{% we make the whole thing an ordinary symbol
|
||||||
|
\left.\kern-\nulldelimiterspace % automatically resize the bar with \right
|
||||||
|
#1 % the function
|
||||||
|
\littletaller % pretend it's a little taller at normal size
|
||||||
|
\right|_{#2} % this is the delimiter
|
||||||
|
}}
|
||||||
|
|
||||||
\makeatletter
|
\makeatletter
|
||||||
\renewcommand*\env@matrix[1][*\c@MaxMatrixCols c]{%
|
\renewcommand*{\env@matrix}[1][*\c@MaxMatrixCols c]{%
|
||||||
\hskip -\arraycolsep
|
\hskip -\arraycolsep
|
||||||
\let\@ifnextchar\new@ifnextchar
|
\let\@ifnextchar\new@ifnextchar
|
||||||
\array{#1}}
|
\array{#1}}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
\author{}
|
\author{}
|
||||||
|
|
||||||
\newcommand{\paren}[1]{\left(#1\right)}
|
\newcommand{\paren}[1]{\left(#1\right)}
|
||||||
|
\newcommand{\powerset}[1]{\mathcal{P}\paren{#1}}
|
||||||
\renewcommand{\Re}[1]{\operatorname{\mathbb{R}e}\paren{#1}}
|
\renewcommand{\Re}[1]{\operatorname{\mathbb{R}e}\paren{#1}}
|
||||||
\renewcommand{\Im}[1]{\operatorname{\mathbb{{I}}m}\paren{#1}}
|
\renewcommand{\Im}[1]{\operatorname{\mathbb{{I}}m}\paren{#1}}
|
||||||
\newcommand{\C}{\mathbb{C}}
|
\newcommand{\C}{\mathbb{C}}
|
||||||
@@ -21,9 +22,17 @@
|
|||||||
\newcommand{\abs}[1]{\left|#1\right|}
|
\newcommand{\abs}[1]{\left|#1\right|}
|
||||||
\newcommand{\polar}[2]{#1\paren{\cos{\paren{#2}} + i\sin{\paren{#2}}}}
|
\newcommand{\polar}[2]{#1\paren{\cos{\paren{#2}} + i\sin{\paren{#2}}}}
|
||||||
\newcommand{\adj}[1]{\operatorname{adj}#1}
|
\newcommand{\adj}[1]{\operatorname{adj}#1}
|
||||||
|
\newcommand{\card}[1]{\left|#1\right|}
|
||||||
|
\newcommand{\littletaller}{\mathchoice{\vphantom{\big|}}{}{}{}}
|
||||||
|
\newcommand{\restr}[2]{{% we make the whole thing an ordinary symbol
|
||||||
|
\left.\kern-\nulldelimiterspace % automatically resize the bar with \right
|
||||||
|
#1 % the function
|
||||||
|
\littletaller % pretend it's a little taller at normal size
|
||||||
|
\right|_{#2} % this is the delimiter
|
||||||
|
}}
|
||||||
|
|
||||||
\makeatletter
|
\makeatletter
|
||||||
\renewcommand*\env@matrix[1][*\c@MaxMatrixCols c]{%
|
\renewcommand*{\env@matrix}[1][*\c@MaxMatrixCols c]{%
|
||||||
\hskip -\arraycolsep
|
\hskip -\arraycolsep
|
||||||
\let\@ifnextchar\new@ifnextchar
|
\let\@ifnextchar\new@ifnextchar
|
||||||
\array{#1}}
|
\array{#1}}
|
||||||
|
|||||||
347
MA1511/sets.tex
347
MA1511/sets.tex
@@ -2,7 +2,8 @@
|
|||||||
\title{Sets}
|
\title{Sets}
|
||||||
\begin{document}
|
\begin{document}
|
||||||
\maketitle
|
\maketitle
|
||||||
Set comprehensions can be written $\{ x | x \in \N \}$ or $\{ x : x \in \N \}$ - '$:$' or '$|$'
|
Set comprehensions can be written $\{ x | x \in \N \}$ or $\{ x : x \in \N \}$ - '$:$' or '$|$' \\
|
||||||
|
Sets are defined entirely by the values of $x$ for which $x \in A$
|
||||||
\begin{description}
|
\begin{description}
|
||||||
\item[Axiom of Extensionality / Set Equality] $A = B \iff \forall x. (x \in A \iff x \in B)$
|
\item[Axiom of Extensionality / Set Equality] $A = B \iff \forall x. (x \in A \iff x \in B)$
|
||||||
\item[$A \subseteq B$] \quad $\forall x \in A. x \in B$ \\
|
\item[$A \subseteq B$] \quad $\forall x \in A. x \in B$ \\
|
||||||
@@ -13,5 +14,349 @@ Set comprehensions can be written $\{ x | x \in \N \}$ or $\{ x : x \in \N \}$ -
|
|||||||
\item[$\cup$] Union
|
\item[$\cup$] Union
|
||||||
\item[$\cap$] Intersection
|
\item[$\cap$] Intersection
|
||||||
\item[$A \setminus B$] \quad $\{ x \in A : x \not\in B \}$
|
\item[$A \setminus B$] \quad $\{ x \in A : x \not\in B \}$
|
||||||
|
\item[$A^\complement$]\quad $U \setminus A$
|
||||||
|
\item[$[a, b)$] \quad $\{ x \in \R : a \leq x < b \}$
|
||||||
\end{description}
|
\end{description}
|
||||||
|
\begin{align*}
|
||||||
|
C \setminus (A \cup B) \equiv & ~ (C \setminus A) \cap (C \setminus B) \\
|
||||||
|
C \setminus (A \cap B) \equiv & ~ (C \setminus A) \cup (C \setminus B) \\
|
||||||
|
(A^\complement)^\complement \equiv & ~ A \\
|
||||||
|
A^\complement \cup B^\complement \equiv & ~ (A \cap B)^\complement \\
|
||||||
|
A^\complement \cap B^\complement \equiv & ~ (A \cup B)^\complement
|
||||||
|
\end{align*}
|
||||||
|
\section*{Families of Sets}
|
||||||
|
A family of sets indexed by a set $I$ (the indexing set): $A_i ~~\forall~i\in I (\equiv (A_i)_{i\in I})$ \\
|
||||||
|
$A_i$ is a set for every element $i \in I$ \\
|
||||||
|
A family of sets indexed by $\N$ is called a sequence of sets. Also written $(B_i)^{\inf}_{i=0}$ or $(B_i)_{i \geq 0}$
|
||||||
|
\begin{align*}
|
||||||
|
\bigcup_{i \in I}~A_i \equiv \{x | \exists i \in I. x \in A_i \} \\
|
||||||
|
\bigcap_{i \in I}~A_i \equiv \{x | \forall i \in I. x \in A_i \} & \text{ Exists iff } \exists~i\in I
|
||||||
|
\end{align*}
|
||||||
|
\begin{align*}
|
||||||
|
& \forall i \in I. A_i \subseteq \cup_{j \in I}A_j \\
|
||||||
|
& \forall i \in I. A_i \subseteq B \implies \cup_{j \in I}A_j \subseteq B \\
|
||||||
|
& \forall i \in I.\cap_{j \in I}A_j \subseteq A_i \\
|
||||||
|
& \forall i \in I. B \subseteq A_i \implies B \subseteq \cap_{j \in I}A_j \\ \\
|
||||||
|
& B \cup \cap_{i \in I}A_i = \cup_{i \in I}(B \cap A_i) \\
|
||||||
|
& B \cap \cup_{i \in I}A_i = \cap_{i \in I}(B \cup A_i) \\
|
||||||
|
& B \setminus \cup_{i \in I}A_i = \cap_{i\in I}(B\setminus A_i) \\
|
||||||
|
& B \setminus \cap_{i \in I}A_i = \cup_{i\in I}(B \setminus A_i)
|
||||||
|
\end{align*}
|
||||||
|
\section*{Cartesian Products}
|
||||||
|
Ordered pairs can be represented as $(x, y) \equiv \{x, \{x, y\}\}$ \\
|
||||||
|
$X \times Y = \{ (x, y) |~ \forall x, y.~x \in X \land y \in Y\}$ for sets $X$, $Y$ \\
|
||||||
|
$X^n$ is $X\times X^{n-1}$ for set $X$ and natural $n$ \\
|
||||||
|
$\card{X\times Y} = \card{X} \times \card{Y}$ (for finite $X$, $Y$)
|
||||||
|
\section*{Functions}
|
||||||
|
For sets $X$, $Y$:
|
||||||
|
\begin{description}
|
||||||
|
\item[A function $F: X \to Y$] $\subseteq X\times Y$ \text { where } \\
|
||||||
|
$\forall x \in X.~\exists \text{ a unique } F(x) \in Y.~ (x, F(x)) \in F$ \\
|
||||||
|
There exist $\card{Y}^{\card{X}}$ functions $F: X \to Y$
|
||||||
|
\item[$\operatorname{dom}(F)$] The domain of $F$, i.e. $X$
|
||||||
|
\item[$\operatorname{incl}^X_A : A \to X$] $= a \quad \forall A,X. \text{ where } A \subseteq X$
|
||||||
|
\item[Constant function] $\exists y_0 \in Y.~\forall x \in X.~ f(x) = y_0$
|
||||||
|
\item[Characteristic Function of a set $A \subseteq X$: $\chi_A: X \to \{0, 1\}$]
|
||||||
|
\[
|
||||||
|
\chi_A: X \to \{0, 1\} = \left\{\begin{array}{lr}
|
||||||
|
0 & \text{ if } x \not\in A \\
|
||||||
|
1 & \text{ if } x \in A
|
||||||
|
\end{array} \right.
|
||||||
|
\]
|
||||||
|
\item[Restriction of a function $f: X \to Y$] $\restr{f}{A}$ is $f$ specialized contravariantly to $A \subseteq X$
|
||||||
|
\item[$f(A)$: Image of $A$ under $f$] $f$ mapped over $A$ \quad for function $f: X \to Y$, $A \subseteq X$
|
||||||
|
\item[$\operatorname{ran}(f)$ / image of $f$ / range of $f$] $\{ f(x) | x \in X \}$, $f(X)$, i.e. all possible values of $f(x)$
|
||||||
|
\item[Preimage of $B$ under $f$] $\{ x \in X ~|~ f(x) \in B \}$ \\
|
||||||
|
written $f^{-1}(B)$, but is \emph{not} the inverse of f
|
||||||
|
\end{description}
|
||||||
|
For $f: X \to Y$, $A \subseteq A' \subseteq X$, $B \subseteq B' \subseteq Y$:
|
||||||
|
\begin{align*}
|
||||||
|
f(A) \subseteq~ & f(A') \\
|
||||||
|
f^{-1}(B) \subseteq ~ & f^{-1}(B') \\
|
||||||
|
f^{-1}(f(A)) \supseteq ~ & A \\
|
||||||
|
f(f^{-1}(B)) \subseteq ~ & B
|
||||||
|
\end{align*}
|
||||||
|
For set families $(A_i \subseteq X)_{i \in I}, (B_j \subseteq Y)_{j \in J}$:
|
||||||
|
\begin{align*}
|
||||||
|
f(\cup_{i \in I} A_i) = ~ & \cup_{i \in I}f(A_i) \\
|
||||||
|
f(\cap_{i \in I} A_i) \subseteq ~ & \cap_{i \in I}f(A_i) \\
|
||||||
|
f^{-1}(\cup_{j \in J} B_j) = ~ & \cup_{j \in J} f^{-1}(B_j) \\
|
||||||
|
f^{-1}(\cap_{j \in J} B_j) = ~ & \cap_{j \in J} f^{-1}(B_j)
|
||||||
|
\end{align*}
|
||||||
|
\section*{Function Composition}
|
||||||
|
For functions $f: X \to Y$, $g: Y \to Z$:
|
||||||
|
\begin{align*}
|
||||||
|
& (g \circ f): X \to Z \\
|
||||||
|
& (g\circ f)(x) = g(f(x)) & \forall x \in X \\ \\
|
||||||
|
\end{align*}
|
||||||
|
\section*{Surjection and Injection}
|
||||||
|
For $f: X \to Y$, $f$ is
|
||||||
|
\begin{description}
|
||||||
|
\item[surjective] iff $f(X) = Y$, i.e. $\forall y \in Y.~ \exists x \in X.~ f(x) = y$ \\
|
||||||
|
Range is codomain, 'onto'
|
||||||
|
\item[injective] iff $\forall x, x' \in X. ~ f(x) = f(x') \implies x = x'$
|
||||||
|
\item[bijective] iff $f$ is injective and $f$ is surjective \\
|
||||||
|
one-to-one
|
||||||
|
\end{description}
|
||||||
|
Given $f: X \to Y$, $g: Y \to Z$: \\
|
||||||
|
\quad If f and g are injective, so is $g\circ f$ \\
|
||||||
|
\quad If f and g are surjective, so is $g \circ f$ \\
|
||||||
|
\quad If $g \circ f$ is injective, so is $f$ \\
|
||||||
|
\quad If $g \circ f$ is surjective, so is $g$
|
||||||
|
\section*{Inverse Functions}
|
||||||
|
The inverse function $f^{-1}$ of $f: X \to Y$ exists iff $f$ is bijective, and is defined by \[f^{-1}(y) = x \text{ where } \exists! x \in X. f(x) = y \qquad \forall y \in Y\]
|
||||||
|
\begin{align*}
|
||||||
|
(f \circ f^{-1}) = \operatorname{Id} \\
|
||||||
|
(f^{-1} \circ f) = \operatorname{Id}
|
||||||
|
\end{align*}
|
||||||
|
\section*{Power Sets}
|
||||||
|
Powerset of S: $\powerset{S}$ has $2^{\card{S}}$ elements is the set of all subsets of $S$ \\
|
||||||
|
$Fun(X, \{0, 1\})$ is the set of functions $X \to \{0, 1\}$ \\
|
||||||
|
$\Phi: Fun(X, \{0, 1\}) \to \powerset{X}$ \\
|
||||||
|
$\Phi(f) = \{ x \in X | f(x) = 1 \}$ \\
|
||||||
|
$\Phi$ is bijective.
|
||||||
|
\section*{Binary Operators}
|
||||||
|
A binary operator is $X^2 \to X$ \\
|
||||||
|
Union is $\powerset{X}^2 \to \powerset{X}$ \\
|
||||||
|
$\square$ is the unknown or indeterminate binop sigil \\
|
||||||
|
Unital: $\forall x \in X. \exists u \in X. u \square x = x \square u = x$
|
||||||
|
\section*{Construction of the Natural Numbers}
|
||||||
|
\begin{align*}
|
||||||
|
x^{+} & = x \cup \{x\} & \text{successor of $x$}
|
||||||
|
\end{align*}
|
||||||
|
A set $X$ is \emph{inductive} if $\varnothing \in X \land (a \in X \implies a^+ \in X)$ \\
|
||||||
|
Axiom: There exists an inductive set. \\
|
||||||
|
Definition: A natural number is a set that is an element of all inductive sets. \\
|
||||||
|
Theorem: There exists a set whose elements are the natural numbers. \\
|
||||||
|
\begin{align*}
|
||||||
|
& \text{Given an inductive set $A$} \\
|
||||||
|
& \omega = \{ x \in A | x \text{ is a natural number}\} \\
|
||||||
|
& \text{any natural number is in $A$ (since $A$ is inductive), and therefore in $\omega$} \\
|
||||||
|
& \omega \text{ is the natural numbers}
|
||||||
|
\end{align*}
|
||||||
|
\\
|
||||||
|
Define:
|
||||||
|
\begin{align*}
|
||||||
|
0 & = \varnothing \\
|
||||||
|
1 & = 0^+ \\
|
||||||
|
2 & = 1^+ \\
|
||||||
|
\ldots
|
||||||
|
\end{align*}
|
||||||
|
$\in$ is an ordering over $\omega$, as is $\subseteq$ \\
|
||||||
|
$\omega$ is an inductive set. Proof: \\
|
||||||
|
$\varnothing$ is a natural number.
|
||||||
|
$x \in \omega$ implies $x^+ \in \omega$, as $x$ is natural and is therefore in
|
||||||
|
every inductive set, and so $x^+$ is in every inductive set and is therefore a
|
||||||
|
natural number.
|
||||||
|
\subsection*{Principle of Induction}
|
||||||
|
If $A \subseteq \omega$ and $A$ is inductive, $A = \omega$.
|
||||||
|
Since $A$ is inductive, it contains every natural number, so $\omega \subseteq A$. \\
|
||||||
|
Since $A \subseteq \omega \land \omega \subseteq A$, $A = \omega$
|
||||||
|
\section*{Recursion on $\omega$}
|
||||||
|
\subsection*{Principle of Recursion}
|
||||||
|
For a set $X$, $x_0 \in X$, $h: X \to X$, there exists a unique function $f: \omega \to X$ where $f(0) = x_0$, $f(n^+) = h(f(n))$.
|
||||||
|
\section*{Relations}
|
||||||
|
Total order: $(X, \prec)$, requires $\forall x, y, z \in X$: \\
|
||||||
|
\begin{align*}
|
||||||
|
& x \prec y \land y \prec z \implies x \prec z \\
|
||||||
|
& x = y \oplus x \prec y \oplus y \prec x & \text{ (where $\oplus$ denotes XOR) }
|
||||||
|
\end{align*}
|
||||||
|
Lexicographic order $x <_L y$ on $\N\times\N = x_0 < y_0 \lor (x_0 = y_0 \land x_1 < y_1)$ \\
|
||||||
|
For a non-empty subset $A$ of $X$ given a total order $(X, \prec)$, a minimum/least element $a_0 \in A$
|
||||||
|
exists where $\forall a \in A.~a_0 \preceq a$.
|
||||||
|
\section*{Ordering on $\omega$}
|
||||||
|
$(\omega, \in)$ and $(\omega, \subset)$ are both total orderings on $\omega$, such that $\varnothing$ is the minimum and $\forall x \in \omega.~x < x^+$
|
||||||
|
\section*{Strong Induction}
|
||||||
|
Every non-empty subset of $\N$ has a minimum. \\ \\
|
||||||
|
Let $\phi(x)$ be a predicate over $\N$ where $\forall n\in \N.~ (\forall m \in \N.~ m < n \implies \phi(m)) \implies \phi(n)$. \\
|
||||||
|
Then $\phi(0)$ holds, as $\neg\exists n \in \N.~n<0$, $\phi(1)$ holds as $\phi(0)$ holds, etc.
|
||||||
|
\begin{align*}
|
||||||
|
& \neg\exists x \in \N.~\neg\phi(x) \\
|
||||||
|
& \text{Let } A \text{ be a subset of }N\text{ such that }\phi(n)\text{ is false }\forall n \in A \\
|
||||||
|
& \text{If not, $\exists a_0 \in A$} \\
|
||||||
|
& \forall n \in N.~n < a_0 \implies n \not\in A \implies \phi(n) \\
|
||||||
|
& \text{Then $\phi(n)$ holds $\forall n < a_0$, so $\phi(a_0)$, then $a_0 \not\in A$, which is a contradiction, so $A = \varnothing$}
|
||||||
|
\end{align*}
|
||||||
|
\section*{Fibonacci}
|
||||||
|
Fibonacci Sequence: $F_n$ \\
|
||||||
|
Roots of $x^2 - x - 1$ are $\phi = \frac{1 + \sqrt{5}}{2}$ and $\psi = \frac{1 - \sqrt{5}}{2}$ \\
|
||||||
|
$F_n = \frac{\phi^{n+1} - \psi^{n+1}}{\sqrt{5}}$ \\
|
||||||
|
For $n=0$:
|
||||||
|
|
||||||
|
$F_0 = 1 = \frac{\frac{1 + \sqrt{5}}{2} - \frac{1-\sqrt{5}}{2}} = \frac{2\sqrt{5}}{2} = 1$ \\
|
||||||
|
|
||||||
|
For $n=1$: \\
|
||||||
|
|
||||||
|
$F_1 = 1 = \frac{\paren{\frac{1 + \sqrt{5}}{2}}^2 - \paren{\frac{1 - \sqrt{5}}{2}}^2}{\sqrt{5}} = \frac{\phi + 1 - \psi - 1}{\sqrt{5}}$ \\
|
||||||
|
|
||||||
|
For $n\geq 2$:
|
||||||
|
\begin{align*}
|
||||||
|
& F_n = F_{n-1} + F_{n-2} = \frac{\phi^n - \psi^n}{\sqrt{5}} + \frac{\phi^{n-1} - \psi^{n-1}}{\sqrt{5}} \\
|
||||||
|
& = \frac{\phi^{n-1}\paren{\phi + 1} - \psi^{n-1}\paren{\psi + 1}}{\sqrt{5}} \\
|
||||||
|
& = \frac{\phi^{n-1}\phi^2 - \psi^{n-1}\psi^2}{\sqrt{5}} \\
|
||||||
|
& = \frac{\phi^{n+1} - \psi^{n+1}}{\sqrt{5}} & \text{as required}
|
||||||
|
\end{align*}
|
||||||
|
|
||||||
|
\subsection*{Zeckendorff's Theorem}
|
||||||
|
Every natural number can be written as a sum of non-adjacent Fibonacci numbers in a unique way (excluding $F_0$). \\
|
||||||
|
A finite subset $I$ of $\N^+$ is \emph{Zeckendorff} if it contains no adjacent elements ($\forall x \in I.~x^+ \not\in I$) \\
|
||||||
|
Define $\mathcal{Z}$ as the set of all Zeckendorff sets, and $\sigma: \mathcal{Z} \to \N^+$ by $\sigma(I) = \sum_{i \in I}F_i$.
|
||||||
|
The theorem claims $\sigma$ is bijective. \\ \\
|
||||||
|
For nonempty $I \in \mathcal{Z}$ with largest element $k$:
|
||||||
|
\begin{align*}
|
||||||
|
& \text{Let } J = I \setminus \{k\} \\
|
||||||
|
& \sigma(I) = F_k + \sigma(J) \geq F_k \\
|
||||||
|
& \text{If } J = \varnothing\text{, } \sigma(I) = F_k \leq F_{k + 1} \\
|
||||||
|
& \text{Otherwise, we must show } \sigma(I) < F_{k + 1} \\
|
||||||
|
& \equiv F_k + \sigma(J) < F_{k + 1} \\
|
||||||
|
& \equiv \sigma(J) < F_{k + 1} - F_k = F_{k-1} \\
|
||||||
|
& \text{But if $k' = \operatorname{max}(J)$, } \\
|
||||||
|
& \sigma(J) < F_{k' + 1} \land k' < k - 2 \text{ (since $I$ is \emph{Zeckendorff})} \\
|
||||||
|
& \sigma(J) < F_{k - 1} \text{ as required.}
|
||||||
|
\end{align*}
|
||||||
|
|
||||||
|
Proof of theorem: $\forall n \in N.~ \sigma$ is bijective.
|
||||||
|
\begin{align*}
|
||||||
|
n = 0: \quad & I = \varnothing \\
|
||||||
|
n > 0: \quad & \text{Let } F_k \leq n < F_{k + 1},~ m = n - F_k \\
|
||||||
|
& m = \sigma(J) \text{ for some } J \\
|
||||||
|
& \text{If } J = \varnothing, I = \{k\}. \\
|
||||||
|
& \text{Otherwise, } k' = \operatorname{max}(J). \\
|
||||||
|
& \text{If } k' \leq k - 2, I = J \cup \{k\} \\
|
||||||
|
\end{align*}
|
||||||
|
\section*{Equivalence Relations}
|
||||||
|
Reflexive, Symmetric, Transitive \\
|
||||||
|
Equivalence relations are usually called $\sim$ \\
|
||||||
|
In a set $X$,
|
||||||
|
\[ [x] = \{ y \in X | x \sim y \} \]
|
||||||
|
\[ [x] = [y] \equiv x \sim y \]
|
||||||
|
Any two equivalence classes of $X$ are either disjoint or equal. \\
|
||||||
|
\subsection*{Quotient Sets}
|
||||||
|
$X/\sim~ = \{[x] | x \in X \} \subset \powerset{X}$ \\
|
||||||
|
A complete set of representatives is a subset $A$ of $X$ where $\forall x \in X. \exists! a \in A. a \in [x].$ \\
|
||||||
|
I.E. a complete set of representatives contains exactly one element from each element of $X/\sim$ \\
|
||||||
|
$f: A \to X/\sim$ defined by $f(a) = [a]$
|
||||||
|
\\\\\\
|
||||||
|
A function $f: X \to Y$ is \emph{compatible} iff $x \sim y \implies f(x) = f(y)~\forall x, y \in X$ \\
|
||||||
|
For a \emph{compatible} function, $\Bar{f}: X/\sim~\to Y$ exists and is defined by $\Bar{f}([x]) = f(x)$
|
||||||
|
\subsection*{Integers modulo $k$}
|
||||||
|
Fix some $k \in \N^+$ \\
|
||||||
|
Define $\sim$ on $\Z$ by $n \sim m \iff n - m$ is a multiple of $k$ \\
|
||||||
|
$\sim$ is an equivalence relation \\
|
||||||
|
$[0, k)\cap\N$ is a complete set of representatives for $\sim$ \\
|
||||||
|
$Z/k$ is the set of integers modulo $k$, $n \equiv m~(\operatorname{mod} k) \iff n \sim m$ \\
|
||||||
|
\([m] = [m]_k\) \\
|
||||||
|
$+$ and $\times$ on $\Z/k$:
|
||||||
|
\begin{align*}
|
||||||
|
[n] + [m] = [n + m] \\
|
||||||
|
[n][m] = [nm]
|
||||||
|
\end{align*}
|
||||||
|
\section*{Countable Sets}
|
||||||
|
A set $X$ is finite if $\exists n \geq 0. $ a bijection $\{1, ...n\} \to X$ \\
|
||||||
|
Pigeonhole Principle: for finite $X$, any injective $f: X \to X$ is also surjective. \\
|
||||||
|
$\N$ is infinite. Proof: $f: \N \to \N $ defined by $ f(x) = x + 1$ is trivially injective, and $\neg\exists x.~f(x) = 0$, and so not surjective. \\
|
||||||
|
By the inverse of the Pigeonhole Principle, $\N$ is infinite.\\
|
||||||
|
A set $X$ is \emph{countably infinite} iff there exists a bijection $\N \to X$. \\
|
||||||
|
A set is \emph{countable} iff it is finite or countably infinite. \\
|
||||||
|
Any subset of $\N$ is countable. Proof: Let $X \subseteq \N$.\\
|
||||||
|
If $X$ is finite, it's trivially countable.
|
||||||
|
Otherwise, $X$ is infinite and it must be shown that $X$ is countably infinite. \\
|
||||||
|
For $k \in \N$, $X_{>k} = \{ n \in X | n > k \}$. Then $X_{>k} \not= \varnothing$, as $X$ would be a subset of $\{1..k\}$ and would be finite. \\
|
||||||
|
Then $min(X_{>k})$ exists, and $h: X \to X$ can be defined by $h(x) = min(X_{>x})$, and $f: \N \to X$ by recursion on $h$ with $f(0) = min(X)$. \\
|
||||||
|
\\
|
||||||
|
If an injection $f: A \to X$ exists, $A$ is countable if $X$ is. Proof: \\
|
||||||
|
If $A$ is finite, it's countable. Otherwise, \\
|
||||||
|
Since $X$ is countable, there exists a bijection $g: X \to \N$, and $g \circ f: A \to \N$
|
||||||
|
exists and is a composite of 2 injective functions, and therefore is itsself injective. \\
|
||||||
|
\\
|
||||||
|
Any subset of a countable set is countable, by above with the inclusion function.
|
||||||
|
|
||||||
|
$N^2$ is countable. Proof: \\
|
||||||
|
Take $f: \N^2 \to \N$ defined by $f(a, b) = 2^a3^b$. \\
|
||||||
|
$f$ is injective. Proof is simple -- prime factor decompositions are unique. \\
|
||||||
|
|
||||||
|
If a function $f: X \to Y$ exists where $X$ is countable, $f(X)$ is countable. Proof: \\
|
||||||
|
For $y \in f(X)$, \emph{choose} an $x_y \in f^{-1}(\{y\})$ and define $g: f(X) \to X$ by $g(y) = x_y$. \\
|
||||||
|
$g$ is injective, so $f(X)$ injects into the countable set $X$ and is itself countable. \\
|
||||||
|
In particular, for any surjection $f: X \to Y$, $Y$ is countable if $X$ is \\
|
||||||
|
\\
|
||||||
|
The union over a countable set of countable sets is countable. Proof: For family $X_{i \in I}$, $X_i$ countable, $I$ countable \\
|
||||||
|
There is an injection $h: I \to \N$, and $f_i: X_i \to \N \forall i \in I$, as these are countable sets. \\
|
||||||
|
Define $Y = \bigcup_{i \in I}X_i$, and $g: Y \to \N$ by $g(y) = (h(i), f_i(y))$ where $i \in I$ is chosen so that $y \in X_i$.
|
||||||
|
Then $g$ is injective because equality distributes over pairs, and $h$ and $f_i$ are injective.\\
|
||||||
|
|
||||||
|
If $X$ and $Y$ are countable, so is $X\times Y$. Proof: \\
|
||||||
|
Define for $x \in X$ a subset $Y_x = \{(x, y) | y \in Y\}$ of $X \times Y$, then $\{Y_x\}_{x \in X}$ is a countable family of countable sets.
|
||||||
|
\\
|
||||||
|
$\Z$ is countable, as a union of $\N$ and $(\times {-1})(\N^+)$, or $\N \times \{0, 1\}$ \\
|
||||||
|
|
||||||
|
$\Q$ is countable. Proof:
|
||||||
|
\begin{align*}
|
||||||
|
& \text{Define } f: \Z\times (\Z \setminus \{ 0 \}) \text{ by } f(a, b) = \frac{a}{b} \\
|
||||||
|
& f \text{ is surjective, by definition of } \Q. \\
|
||||||
|
& \Z \text{ is countable, as above } \\
|
||||||
|
& \Z \setminus \{ 0 \} \text{ is countable, as a subset of a countable set } \Z \\
|
||||||
|
& \Z\times (\Z \setminus \{ 0 \}) \text{ is countable, as a product of countable sets } \\
|
||||||
|
& \text{Since } f \text{ is surjective with a countable domain, } \Q \text{ is countable }
|
||||||
|
\end{align*}
|
||||||
|
|
||||||
|
For set family $X_{n \in \N^+}$, $\times_{n \in \N^+} X_n$ is countable if $\forall n \in \N.~X_n$ is countable. Proof: \\
|
||||||
|
Base Case: $n = 1$: $X_1$ is countable, since $X_1$ is countable. \\
|
||||||
|
Induction: Assume $\times_{n \in \N^+, \leq k} X_n$ is countable. \\
|
||||||
|
Then the result for $k + 1$ is $\times_{n \in \N^+, \leq k + 1} X_n$, which is $(\times_{n \in \N^+, \leq k} X_n) \times X_{k + 1}$, which is the product of countable sets and is therefore countable. \\
|
||||||
|
By induction, the result holds for $n \in N^+$ \\
|
||||||
|
This generalizes to all countable indexing sets $I$, by constructing an injection $f: I \to \N$.
|
||||||
|
\\ \\
|
||||||
|
Let $X$ be countable. Define $\mathbb{P}_{<\infty}\paren{X}$ as the set of all finite subsets of $X$. $\mathbb{P}_{<\infty}\paren{X}$ is countable. Proof: \\
|
||||||
|
For $n \in \N$, let $\mathbb{P}_{\leq n}(X)$ denote the set of all nonempty subsets of $X$ with $n$ elements or less. \\
|
||||||
|
The function $p_n: X^n \to \mathbb{P}_{\leq n}(X)$ defined by $p_n(x_1, x_2, ... x_n) = \{ x_1, x_2, ... x_n\}$ is surjective. \\
|
||||||
|
Then, since $X$ is countable, so is $\mathbb{P}_{\leq n}(X)$ (as $X^n$ is countable and there exists a surjection $X^n \to \mathbb{P}_{\leq n}(X)$) \\
|
||||||
|
\[\mathbb{P}_{\leq\infty}(X) = \bigcup_{n \in \N^+}\mathbb{P}_{\leq n}(X) \cup \{\varnothing\} \]
|
||||||
|
This is a countably-sized union of countable sets and so is itself countable, as required.
|
||||||
|
|
||||||
|
\subsection*{Cantor's Theorem}
|
||||||
|
Let $X$ be a set. Then there exists no surjective function $f: X \to \powerset{X}$. Proof: \\
|
||||||
|
Let $f: X \to \powerset{X}$ be a function. We will prove that $f$ is not surjective. \\
|
||||||
|
Define $D \subseteq X$ by $\{ x \in X | x \not\in f(x) \}$ \\
|
||||||
|
Then $D \in \powerset{X}$, and we will show that there is no element of $X$ for which $f(x) = D$. \\
|
||||||
|
Suppose there was such an $x$. Either: \\
|
||||||
|
|
||||||
|
$x \in D$. Then $x \in f(x)$, but by definition of $D$, $x \not\in f(x)$, which is a contradiction.
|
||||||
|
|
||||||
|
$x \not\in D$. Then $x \not\in f(x)$, so $x \in D$ by definition of $D$, which is a contradiction. \\\\
|
||||||
|
Since both cases give a contradiction, there exists no such $x$, and $f$ is not surjective. \\
|
||||||
|
This is the less famous diagonal argument. \\
|
||||||
|
\\
|
||||||
|
$\R$ is uncountable. Proof:
|
||||||
|
|
||||||
|
Define $f: \powerset{\N} \to \R$ by $f(A) = \sum_{n \in A} 2(3^{-n}) \quad \forall A \subseteq \N$.
|
||||||
|
Then $f$ is injective: \\
|
||||||
|
|
||||||
|
Take $\alpha, \beta \in \powerset{\N}$, where $\alpha \not = \beta$, and we will show $f(\alpha) \not = f(\beta)$. \\
|
||||||
|
Then, take $k \in \N$ as the smallest natural number in exactly one of $\alpha$, $\beta$, and assume it's in $\beta$ WLOG. \\
|
||||||
|
Then
|
||||||
|
\begin{align*}
|
||||||
|
f(\alpha) & = \sum_{n \in \alpha}\frac{2}{3^n} \\
|
||||||
|
& = \sum_{n \in \alpha, < k} \frac{2}{3^n} + \sum_{n \in \alpha, > k} \frac{2}{3^n} \\
|
||||||
|
& \leq \sum_{n \in \alpha, < k} \frac{2}{3^n} + \sum_{n > k} \frac{2}{3^n} \\
|
||||||
|
& = \sum_{n \in \alpha, < k} \frac{2}{3^n} + \frac{1}{3^k} \\
|
||||||
|
& = \sum_{n \in \beta, < k} \frac{2}{3^n} + \frac{2}{3^k} \\
|
||||||
|
& < \sum_{n \in \beta, < k} \frac{2}{3^n} + \frac{2}{3^k} + \sum_{n \in \beta, > k} \frac{2}{3^n} \\
|
||||||
|
& = f(\beta) \\ \\
|
||||||
|
f(\alpha) < f(\beta) & \implies f(\alpha) \neq f(\beta)
|
||||||
|
\end{align*}
|
||||||
|
Then there is no surjection $\N \to \powerset{\N}$ and so $\powerset{\N}$ is uncountable.
|
||||||
|
Since there's an injection $\powerset{\N} \to \R$, $\R$ is uncountable, as if $\R$ was countable, $\powerset{\N}$ would be countable
|
||||||
|
\\ \\
|
||||||
|
The set of all polynomials with rational coefficients is countable. Proof:
|
||||||
|
|
||||||
|
Let $P$ be the set of all polynomials with rational coefficients, $P_n$ be the set of all polynomials with rational coefficients and degree $\leq$ n.
|
||||||
|
|
||||||
|
Then $P = \bigcup_{n \in \N} P_n$, $\N$ is countable, and $P_n$ is countable as there exists a surjection $\Q^n \to P_n$ by assigning each element of the tuple to a coefficient. \\
|
||||||
|
|
||||||
|
\subsection*{Algebraic Numbers}
|
||||||
|
The algebraic numbers ($\mathcal{A}$) are the real numbers which are roots of polynomials with rational coefficients.
|
||||||
|
|
||||||
|
$\mathcal{A}$ is countable, as \[ \mathcal{A} = \bigcup_{p \in P} \{ x \in \R |~p(x) = 0 \} \] is a countable union of finite sets. \\
|
||||||
|
Then $\R\setminus\mathcal{A}$ is uncountable, as if it were, $\R = (\R \setminus \mathcal{A}) \cup \mathcal{A}$, a union of countable sets.
|
||||||
\end{document}
|
\end{document}
|
||||||
|
|||||||
1
MA2008/2024-09-24
Normal file
1
MA2008/2024-09-24
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
76
MA2008/decls.tex
Normal file
76
MA2008/decls.tex
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
\documentclass[fleqn]{article}
|
||||||
|
\usepackage{amsmath,amssymb,amsthm}
|
||||||
|
\usepackage[margin=0.25in]{geometry}
|
||||||
|
\usepackage{enumitem}
|
||||||
|
\usepackage{systeme}
|
||||||
|
\usepackage{mathtools}
|
||||||
|
|
||||||
|
\date{}
|
||||||
|
\author{}
|
||||||
|
|
||||||
|
\newcommand{\paren}[1]{\left(#1\right)}
|
||||||
|
\newcommand{\powerset}[1]{\mathcal{P}\paren{#1}}
|
||||||
|
\renewcommand{\Re}[1]{\operatorname{\mathbb{R}e}\paren{#1}}
|
||||||
|
\renewcommand{\Im}[1]{\operatorname{\mathbb{{I}}m}\paren{#1}}
|
||||||
|
\newcommand{\C}{\mathbb{C}}
|
||||||
|
\newcommand{\N}{\mathbb{N}}
|
||||||
|
\newcommand{\Z}{\mathbb{Z}}
|
||||||
|
\newcommand{\Q}{\mathbb{Q}}
|
||||||
|
\newcommand{\R}{\mathbb{R}}
|
||||||
|
\newcommand{\conj}[1]{\overline{#1}}
|
||||||
|
\renewcommand{\mod}[1]{\left|#1\right|}
|
||||||
|
\newcommand{\abs}[1]{\left|#1\right|}
|
||||||
|
\newcommand{\polar}[2]{#1\paren{\cos{\paren{#2}} + i\sin{\paren{#2}}}}
|
||||||
|
\newcommand{\adj}[1]{\operatorname{adj}#1}
|
||||||
|
\newcommand{\card}[1]{\left|#1\right|}
|
||||||
|
\newcommand{\littletaller}{\mathchoice{\vphantom{\big|}}{}{}{}}
|
||||||
|
\newcommand{\restr}[2]{{% we make the whole thing an ordinary symbol
|
||||||
|
\left.\kern-\nulldelimiterspace % automatically resize the bar with \right
|
||||||
|
#1 % the function
|
||||||
|
\littletaller % pretend it's a little taller at normal size
|
||||||
|
\right|_{#2} % this is the delimiter
|
||||||
|
}}
|
||||||
|
|
||||||
|
\makeatletter
|
||||||
|
\renewcommand*{\env@matrix}[1][*\c@MaxMatrixCols c]{%
|
||||||
|
\hskip -\arraycolsep
|
||||||
|
\let\@ifnextchar\new@ifnextchar
|
||||||
|
\array{#1}}
|
||||||
|
\makeatother
|
||||||
|
|
||||||
|
|
||||||
|
% https://gitlab.com/jim.hefferon/linear-algebra/-/blob/master/src/sty/linalgjh.sty
|
||||||
|
\newlength{\grsteplength}
|
||||||
|
\setlength{\grsteplength}{1.5ex plus .1ex minus .1ex}
|
||||||
|
|
||||||
|
\newcommand{\grstep}[2][\relax]{%
|
||||||
|
\ensuremath{\mathrel{
|
||||||
|
\hspace{\grsteplength}\mathop{\longrightarrow}\limits^{#2\mathstrut}_{
|
||||||
|
\begin{subarray}{l} #1 \end{subarray}}\hspace{\grsteplength}}}}
|
||||||
|
\newcommand{\repeatedgrstep}[2][\relax]{\hspace{-\grsteplength}\grstep[#1]{#2}}
|
||||||
|
|
||||||
|
\newcommand{\swap}{\leftrightarrow}
|
||||||
|
|
||||||
|
% https://tex.stackexchange.com/a/198806
|
||||||
|
\makeatletter
|
||||||
|
\newcommand{\subalign}[1]{%
|
||||||
|
\vcenter{%
|
||||||
|
\Let@ \restore@math@cr \default@tag
|
||||||
|
\baselineskip\fontdimen10 \scriptfont\tw@
|
||||||
|
\advance\baselineskip\fontdimen12 \scriptfont\tw@
|
||||||
|
\lineskip\thr@@\fontdimen8 \scriptfont\thr@@
|
||||||
|
\lineskiplimit\lineskip
|
||||||
|
\ialign{\hfil$\m@th\scriptstyle##$&$\m@th\scriptstyle{}##$\hfil\crcr
|
||||||
|
#1\crcr
|
||||||
|
}%
|
||||||
|
}%
|
||||||
|
}
|
||||||
|
\makeatother
|
||||||
|
|
||||||
|
\theoremstyle{definition}
|
||||||
|
\newtheorem*{theorem}{Theorem}
|
||||||
|
\newtheorem*{lemma}{Lemma}
|
||||||
|
\newtheorem*{corollary}{Corollary}
|
||||||
|
|
||||||
|
\theoremstyle{remark}
|
||||||
|
\newtheorem*{note}{Note}
|
||||||
27
MA2008/linear-transforms.tex
Normal file
27
MA2008/linear-transforms.tex
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
\input{decls.tex}
|
||||||
|
\title{Vector Spaces and Linear Transformations}
|
||||||
|
\begin{document}
|
||||||
|
\maketitle
|
||||||
|
|
||||||
|
\begin{description}
|
||||||
|
\item[Linear Transformation] A function $\phi: V \to W$ between vector spaces $V$ and $W$ (over some field $K$), such that
|
||||||
|
\begin{align*}
|
||||||
|
\phi(v + w) & \equiv \phi(v) + \phi(w) \\
|
||||||
|
\phi(x \cdot v) & \equiv x \cdot \phi(v) \tag{For $x \in K$}
|
||||||
|
\end{align*}
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
Differentiation is a linear transformation.
|
||||||
|
Solutions to $f'' + f = 0$ for function $f$ are a vector space.
|
||||||
|
|
||||||
|
\begin{theorem}
|
||||||
|
For any scalars $\lambda, \mu \in \R$, there is a unique solution such that $f(0) = \mu$ and $f'(0) = \lambda$
|
||||||
|
\end{theorem}
|
||||||
|
The vector space is then two-dimensional, with basis $sin(x), cos(x)$
|
||||||
|
|
||||||
|
|
||||||
|
\subsection*{}
|
||||||
|
Vector spaces are used over finite fields in \emph{Algebraic Coding Theory}. The field is $\mathbb{F}_2 = \{0, 1\}$ - the integers mod 2.
|
||||||
|
Binary strings of length $n$ are then a vector space over $\mathbb{F}_2^n$.
|
||||||
|
ECC can be based on vector subspaces of $F_2^n$. (Vector subspaces are closed subsets of a vector space).
|
||||||
|
\end{document}
|
||||||
6
MA2008/tmpl.tex
Normal file
6
MA2008/tmpl.tex
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
\input{decls.tex}
|
||||||
|
\title{}
|
||||||
|
\begin{document}
|
||||||
|
\maketitle
|
||||||
|
|
||||||
|
\end{document}
|
||||||
Reference in New Issue
Block a user