Metadata-Version: 2.5
Name: nateeganmathpackagelinfinnum
Version: 0.2.0
Summary: A collection of undergraduate math functions: Linear Algebra, Number Theory, Mathematical Finance
Project-URL: Homepage, https://github.com/yourusername/mypackage
Project-URL: Documentation, https://github.com/yourusername/mypackage#readme
Project-URL: Repository, https://github.com/yourusername/mypackage.git
Project-URL: Bug Tracker, https://github.com/yourusername/mypackage/issues
Author-email: Nateegan Yopituk <nateegan2205@gmail.com>
License: MIT
License-File: LICENSE
Keywords: finance,linear-algebra,math,number-theory,pep621
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Education
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.8
Requires-Dist: matplotlib
Requires-Dist: networkx
Requires-Dist: numpy
Requires-Dist: scipy
Requires-Dist: seaborn
Requires-Dist: sympy
Provides-Extra: extra
Requires-Dist: gmpy2; extra == 'extra'
Requires-Dist: plotly; extra == 'extra'
Requires-Dist: pyvista; extra == 'extra'
Description-Content-Type: text/markdown

# nateeganmathpackagelinfinnum

`nateeganmathpackagelinfinnum` is a lightweight Python package that provides simple utility functions for **Linear Algebra**, **Number Theory**, and **Mathematical Finance**. It is designed mainly for learning purposes and as an example of Python packaging.

---

## Features

- **Module 1: finance**
  - **present_value / future_value**: convert between present value and future value given an interest rate and number of periods
  - **simple_return**: compute simple return from a starting price and ending price
  - **portfolio_value**: compute total value of a portfolio from asset prices and quantities
  - **call_option_payoff / put_option_payoff**: compute European option payoff at expiry
  - **has_arbitrage_two_state**: check for arbitrage in a simple two-state (binomial) market model
  - **format_currency**: *(String Processing)* format a number as a currency string, e.g. `"฿1,234.50"`
  - **InvalidPortfolioError / safe_portfolio_value**: *(Exception Handling)* a custom exception plus a safe wrapper around `portfolio_value`
  - **portfolio_summary**: *(Data Structures)* summarize holdings from a `dict`, returning a `set` of tickers, total value, and a `list` of `tuple`s
  - **portfolio_returns_numpy**: *(Numpy)* compute period returns using vectorized numpy operations
  - **save_portfolio_report / load_portfolio_report**: *(File I/O)* write and read a formatted portfolio holdings report
  - **plot_portfolio_pie**: *(Matplotlib)* save a pie chart of portfolio composition
  - **plot_price_trend**: *(Seaborn)* save a line chart of a price trend
- **Module 2: linear**
  - **vector_add / scalar_multiply**: basic vector operations
  - **dot_product / vector_norm**: inner product and Euclidean norm of a vector
  - **matrix_rank**: rank of a matrix via Gaussian elimination
  - **is_linearly_independent**: check whether a set of vectors is linearly independent
  - **is_orthogonal**: check whether two vectors are orthogonal
  - **determinant_recursive**: *(Recursive function)* determinant of an n×n matrix via recursive cofactor expansion
  - **Vector / Vector2D / Vector3D / UnitVector2D / Describable / DescribableVector2D / DescribableUnitVector2D**: *(OOP)* a `Vector` class with magic methods (`__add__`, `__sub__`, `__mul__`, `__eq__`, `__len__`, `__getitem__`, `__repr__`) plus a full inheritance hierarchy demonstrating **single**, **hierarchical**, **multilevel**, **multiple**, and **hybrid** inheritance
  - **matrix_multiply_numpy**: *(Numpy)* multiply two matrices with numpy's `@` operator
  - **plot_vector_2d**: *(Matplotlib)* save an arrow plot of a 2D vector
  - **plot_vectors_3d_pyvista**: *(PyVista, optional)* render 3D vectors — requires `pip install pyvista`
- **Module 3: numtheory**
  - **is_prime**: check whether a number is prime
  - **prime_factorization**: factor a number into its prime factors
  - **mod_pow**: fast modular exponentiation
  - **extended_gcd / modular_inverse**: extended Euclidean algorithm and modular multiplicative inverse
  - **euler_totient**: compute Euler's totient function φ(n)
  - **factorial_recursive**: *(Recursive function)* factorial via simple recursion
  - **fibonacci_memo**: *(Recursion + Memoization)* Fibonacci numbers cached in a `dict` for speed
  - **prime_set_up_to**: *(Data Structures)* Sieve of Eratosthenes, returns a `set` of primes
  - **binomial_coefficient_scipy**: *(SciPy)* compute the binomial coefficient (n choose r) using `scipy.special.comb`
  - **factor_symbolic**: *(Sympy)* symbolic prime factorization using `sympy.factorint`
  - **is_prime_fast**: *(GMPY2 / PARI-GP / SageMath)* fast primality test using `gmpy2` when available, falling back to `is_prime` otherwise
  - **divisor_graph**: *(NetworkX)* build a directed graph of divisibility relations
  - **plot_primes_plotly**: *(Plotly, optional)* interactive scatter plot of primes — requires `pip install plotly`

---

## Installation

You can install the package directly from PyPI:

```bash
pip install nateeganmathpackagelinfinnum
```

This installs the required dependencies automatically: `numpy`, `matplotlib`, `seaborn`, `scipy`, `sympy`, `networkx`.

A few features are optional and not installed by default (`plotly`, `pyvista`, `gmpy2`). If you want those too:

```bash
pip install nateeganmathpackagelinfinnum[extra]
```

---

## Examples

```python
import nateeganmathpackagelinfinnum as pkg

# Module 1: finance

print(pkg.present_value(1000, 0.05, 2))                          # output: 907.0294784580499
print(pkg.future_value(1000, 0.05, 2))                           # output: 1102.5
print(pkg.simple_return(100, 110))                               # output: 0.1
print(pkg.portfolio_value([50, 100, 20], [10, 2, 5]))            # output: 800
print(pkg.call_option_payoff(120, 100))                          # output: 20
print(pkg.put_option_payoff(80, 100))                            # output: 20
print(pkg.has_arbitrage_two_state(0, 5, 0))                      # output: True

# --- String Processing ---
print(pkg.format_currency(1234.5))                               # output: ฿1,234.50

# --- Exception Handling ---
try:
    raise pkg.InvalidPortfolioError("ราคาสินทรัพย์ต้องไม่ติดลบ")
except pkg.InvalidPortfolioError as e:
    print(e)                                                      # output: ราคาสินทรัพย์ต้องไม่ติดลบ

print(pkg.safe_portfolio_value([-100, 200], [1, 2]))              # prints an error message, output: None

# --- Data Structures: dict, tuple, set, list ---
holdings = {"AAPL": (150, 10), "GOOG": (2800, 2)}
tickers, total, breakdown = pkg.portfolio_summary(holdings)
print(tickers, total, breakdown)
# output: {'AAPL', 'GOOG'} 7100 [('AAPL', 1500), ('GOOG', 5600)]

# --- Numpy ---
print(pkg.portfolio_returns_numpy([100, 110, 105]))

# --- File I/O ---
holdings = {"AAPL": (150, 10), "GOOG": (2800, 2)}
pkg.save_portfolio_report("portfolio_report.txt", holdings)
print(pkg.load_portfolio_report("portfolio_report.txt"))
# output: ['AAPL: 10 หน่วย x ฿150.00 = ฿1,500.00', 'GOOG: 2 หน่วย x ฿2,800.00 = ฿5,600.00']

# --- Data Visualization: Matplotlib, Seaborn ---
pkg.plot_portfolio_pie(["AAPL", "GOOG"], [1500, 5600], "pie.png")
pkg.plot_price_trend([100, 105, 102, 110], "trend.png")

# ============================================================

# Module 2: linear

print(pkg.vector_add([1, 2], [3, 4]))                             # output: [4, 6]
print(pkg.scalar_multiply(2, [1, 2, 3]))                          # output: [2, 4, 6]
print(pkg.dot_product([1, 2, 3], [4, 5, 6]))                      # output: 32
print(pkg.vector_norm([3, 4]))                                    # output: 5.0
print(pkg.matrix_rank([[1, 2], [2, 4]]))                          # output: 1
print(pkg.is_linearly_independent([[1, 0], [0, 1]]))              # output: True
print(pkg.is_orthogonal([1, 0], [0, 1]))                          # output: True

# --- Recursive function ---
print(pkg.determinant_recursive([[6, 1, 1], [4, -2, 5], [2, 8, 7]]))  # output: -306

# --- OOP: Class, Magic methods, Inheritance ---
v1, v2 = pkg.Vector([1, 2, 3]), pkg.Vector([4, 5, 6])
print(v1 + v2)                                                    # output: Vector([5, 7, 9])

v2d = pkg.Vector2D(3, 4)                                          # single inheritance
print(v2d.norm())                                                 # output: 5.0

v3d = pkg.Vector3D(1, 2, 3)                                       # hierarchical inheritance
print(v3d)                                                        # output: Vector([1, 2, 3])

uv = pkg.UnitVector2D(3, 4)                                       # multilevel inheritance
print(uv.is_unit())                                               # output: True

dv = pkg.DescribableVector2D(1, 1)                                # multiple inheritance
print(dv.describe())                                              # output: เวกเตอร์ 2 มิติ: [1, 1]

duv = pkg.DescribableUnitVector2D(3, 4)                           # hybrid inheritance
print(duv.is_unit(), duv.describe())

# pkg.Describable is a mixin, meant to be combined with another class:
class MyVector(pkg.Vector, pkg.Describable):
    pass
mv = MyVector([1, 2])
print(mv.describe())                                              # output: เวกเตอร์ 2 มิติ: [1, 2]

# --- Numpy ---
print(pkg.matrix_multiply_numpy([[1, 2], [3, 4]], [[5, 6], [7, 8]]))  # output: [[19, 22], [43, 50]]

# --- Data Visualization: Matplotlib, PyVista ---
pkg.plot_vector_2d([3, 4], "vector.png")
pkg.plot_vectors_3d_pyvista([[1, 0, 0], [0, 1, 0]], "vectors3d.png")  # needs pyvista installed

# ============================================================

# Module 3: numtheory

print(pkg.is_prime(29))                                           # output: True
print(pkg.prime_factorization(60))                                # output: {2: 2, 3: 1, 5: 1}
print(pkg.mod_pow(3, 13, 7))                                      # output: 3
print(pkg.extended_gcd(30, 18))                                   # output: (6, -1, 2)
print(pkg.modular_inverse(3, 11))                                 # output: 4
print(pkg.euler_totient(36))                                      # output: 12

# --- Recursive function ---
print(pkg.factorial_recursive(5))                                 # output: 120

# --- Recursive function with memoization ---
print(pkg.fibonacci_memo(30))                                     # output: 832040

# --- Data Structures: set, list ---
print(pkg.prime_set_up_to(30))
# output: {2, 3, 5, 7, 11, 13, 17, 19, 23, 29}

# --- SciPy ---
print(pkg.binomial_coefficient_scipy(5, 2))                       # output: 10

# --- Sympy ---
print(pkg.factor_symbolic(360))                                   # output: {2: 3, 3: 2, 5: 1}

# --- GMPY2 / PARI-GP / SageMath (falls back to pure Python if gmpy2 isn't installed) ---
print(pkg.is_prime_fast(97))                                      # output: True

# --- NetworkX ---
g = pkg.divisor_graph(10)
print(list(g.successors(2)))                                      # output: [4, 6, 8, 10]

# --- Plotly ---
pkg.plot_primes_plotly(30, "primes.html")                         # needs plotly installed
```
