Skip to content

Commit

Permalink
Fixed issues Berat-O#8 and Berat-O#9: improve readability and error h…
Browse files Browse the repository at this point in the history
…andling
  • Loading branch information
Lucin-ee committed Nov 12, 2024
1 parent 0279618 commit 280e4e3
Show file tree
Hide file tree
Showing 15 changed files with 834 additions and 599 deletions.
39 changes: 36 additions & 3 deletions Algebra/Cholesky.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
import numpy as np
from math import sqrt

def is_symmetric(A):
"""Check if a matrix A is symmetric."""
return np.allclose(A, A.T)

def is_positive_definite(A):
"""Check if a matrix A is positive definite by testing eigenvalues."""
return np.all(np.linalg.eigvals(A) > 0)

def cholesky_decomposition(A):
"""
Perform Cholesky decomposition on a matrix A.
A must be a symmetric, positive-definite matrix.
Perform Cholesky decomposition on a symmetric, positive-definite matrix A.
Parameters:
A (ndarray): Symmetric, positive-definite matrix of size (n, n).
Returns the lower triangular matrix L such that A = L * L^T.
Returns:
ndarray: Lower triangular matrix L such that A = L * L.T.
"""
# Validate the input matrix
if not is_symmetric(A):
raise ValueError("Matrix must be symmetric.")
if not is_positive_definite(A):
raise ValueError("Matrix must be positive-definite.")

n = len(A)
L = np.zeros((n, n)) # Initialize L with zeros

# Perform Cholesky decomposition
for k in range(n):
# Calculate the diagonal element L[k][k]
sum_squares = sum(L[k][j] ** 2 for j in range(k))
Expand All @@ -22,3 +40,18 @@ def cholesky_decomposition(A):
L[i][k] = (A[i][k] - sum_products) / L[k][k]

return L

# Example usage
if __name__ == "__main__":
A = np.array([
[4, 12, -16],
[12, 37, -43],
[-16, -43, 98]
])

try:
L = cholesky_decomposition(A)
print("Cholesky Decomposition (Lower triangular matrix L):")
print(L)
except ValueError as e:
print(f"Error: {e}")
115 changes: 66 additions & 49 deletions Algebra/Gauss.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,74 @@
from numpy import zeros,array, eye, copy, dot
import numpy as np

def Gauss(A,b):
def gaussian_elimination_with_pivoting(A, b):
"""Perform Gaussian elimination with partial pivoting on matrix A and vector b."""
size = len(A)
A = array(A)
P = eye(size)
for i in range(size-1):
maxRow = i
for j in range(i+1,size):
if abs(A[j][i]) > abs(A[maxRow][i]):
maxRow = j
if maxRow != i:
#### Swap
P[[maxRow,i]] = P[[i, maxRow]]
A[[maxRow,i]] = A[[i, maxRow]]
for k in range(i+1, size):
A[k][i] /= A[i][i]
for j in range(i+1, size):
A[k][j] -= A[k][i]*A[i][j]

L = eye(size)
A = np.array(A, dtype=float) # Ensure A is a float array
b = np.array(b, dtype=float) # Ensure b is a float array
P = np.eye(size) # Initialize the permutation matrix

# Partial Pivoting and Elimination
for i in range(size - 1):
# Find the pivot row
max_row = max(range(i, size), key=lambda k: abs(A[k][i]))
if max_row != i:
# Swap rows in both A and P for pivoting
A[[i, max_row]] = A[[max_row, i]]
P[[i, max_row]] = P[[max_row, i]]
b[i], b[max_row] = b[max_row], b[i] # Also swap entries in b

# Perform elimination
for k in range(i + 1, size):
factor = A[k][i] / A[i][i]
A[k, i:] -= factor * A[i, i:] # Update only remaining elements in row
b[k] -= factor * b[i] # Update b vector accordingly

# Extract L and U matrices from A
L = np.eye(size)
U = np.zeros((size, size))
for i in range(size):
for j in range(i):
L[i][j] = A[i][j]
for j in range(size):
if i > j:
L[i][j] = A[i][j]
else:
U[i][j] = A[i][j]

U = zeros((size,size))
return P, L, U, b

def forward_substitution(L, Pb):
"""Solve the equation Ly = Pb using forward substitution."""
size = len(L)
y = np.zeros(size)
for i in range(size):
for j in range(i,size):
U[i][j] = A[i][j]
y[i] = (Pb[i] - np.dot(L[i, :i], y[:i])) / L[i][i]
return y

b = array(b)
def backward_substitution(U, y):
"""Solve the equation Ux = y using backward substitution."""
size = len(U)
x = np.zeros(size)
for i in range(size - 1, -1, -1):
x[i] = (y[i] - np.dot(U[i, i + 1:], x[i + 1:])) / U[i][i]
return x

y = copy(dot(P,b))
def solve_gaussian(A, b):
"""Main function to solve the system Ax = b using Gaussian elimination with pivoting."""
# Step 1: Gaussian Elimination with Partial Pivoting to get P, L, U
P, L, U, Pb = gaussian_elimination_with_pivoting(A, b)

# forwards
for i in range(size):
if L[i][i] == 0: #Division by 0
y[i] = 0
continue
for j in range(i):
y[i] = (y[i] - L[i][j]*y[j])/L[i][i]


x = zeros((size,1))
x[size-1] = y[size-1]/U[size-1][size-1]

for i in range(size-1,-1,-1):
if U[i][i] == 0: #Division by 0
x[i] = 0
continue
xv = y[i]
for j in range(i+1,size):
xv -= U[i][j]*x[j]
xv /= U[i][i]
x[i] = xv

return x
# Step 2: Forward substitution to solve Ly = Pb
y = forward_substitution(L, Pb)

# Step 3: Backward substitution to solve Ux = y
x = backward_substitution(U, y)

return x

# Example usage:
A = [[2, -1, 1],
[3, 3, 9],
[3, 3, 5]]
b = [2, -1, 4]

x = solve_gaussian(A, b)
print("Solution x:", x)
88 changes: 50 additions & 38 deletions Algebra/function_to_graph.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,53 @@
import matplotlib.pyplot as plt
import numpy as np


xmin = -100
xmax = 100
ymin = -100
ymax = 100
points = xmax - xmin
x = np.linspace(xmin, xmax, points)


while True:
eq = input("Enter the equation for y in terms of x: ")

# Use eval() to evaluate the user's input as a mathematical expression
import sympy as sp

def get_user_equation():
"""Prompts the user to input an equation for y in terms of x."""
while True:
eq = input("Enter the equation for y in terms of x: ")
try:
x = sp.symbols('x')
y_expr = sp.sympify(eq)
y_func = sp.lambdify(x, y_expr, 'numpy')
return y_func, eq
except (sp.SympifyError, TypeError):
print("Invalid equation. Please enter a valid mathematical expression.")

def plot_graph(y_func, equation_str):
"""Plots the graph of the equation y = y_func(x)."""
# Set the graph limits and generate x values
xmin, xmax = -100, 100
ymin, ymax = -100, 100
x = np.linspace(xmin, xmax, 500)

# Calculate y values safely, handling any runtime issues
try:
y = eval(eq) # Evaluate the expression with x as a variable
break
except:
print("Invalid input equation.")


fig, ax = plt.subplots()
plt.axis([xmin, xmax, ymin, ymax])
plt.plot([xmin, xmax], [0, 0], "b")
plt.plot([0, 0], [ymin, ymax], "b")

ax.set_xlabel("x values")
ax.set_ylabel("y values")
ax.set_title("Equation Graph")
ax.grid(True)

ax.set_xticks(np.arange(xmin, xmax, 20))
ax.set_yticks(np.arange(ymin, ymax, 20))


plt.plot(x, y, label=f"y= {eq}")

plt.legend()
plt.show()
y = y_func(x)
except Exception as e:
print(f"Error evaluating the equation over the range: {e}")
return

# Initialize plot
fig, ax = plt.subplots()
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
ax.plot([xmin, xmax], [0, 0], "b") # x-axis
ax.plot([0, 0], [ymin, ymax], "b") # y-axis

# Plot settings
ax.set_xlabel("x values")
ax.set_ylabel("y values")
ax.set_title(f"Graph of y = {equation_str}")
ax.grid(True)
ax.set_xticks(np.arange(xmin, xmax + 1, 20))
ax.set_yticks(np.arange(ymin, ymax + 1, 20))

# Plot the equation
ax.plot(x, y, label=f"y = {equation_str}", color='red')
ax.legend()
plt.show()

if __name__ == "__main__":
y_function, equation_text = get_user_equation()
plot_graph(y_function, equation_text)
Loading

0 comments on commit 280e4e3

Please sign in to comment.