diff --git a/README.md b/README.md
index 254cada..01c5a2b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,19 @@
-# unipy
-A unified module for doing undergrad-grad level coding in physics using python.
+# **[unipy](https://github.com/mandal-anik10/unipy)**
+___________________________________________________________
+A unified module for numerical calculations in physics using python.
+
+I have a dream of making a numerical universe where I can simulate nature and physical phenomena just by incorporating the most fundamental law/infromation `(if, we will find the one most fundamental theroy of the universe)` of physics. Thhis module is in developement for that purpose. If you want to contribute, please send a mail. you can find contact information [here](https://mandal-anik10.github.io).
+
+Checkout the [documantation](https://mandal-anik10.github.io/unipy/) for more information about this module.
+___________________________________________________________
+## Installation:
+- Clone the repository in your computer and move to the repository:
+ ```
+ $ git clone https://github.com/mandal-anik10/unipy.git
+ $ cd unipy
+ ```
+- Now you should have a shell prompt ready in the `unipy` folder, and by running `$ ls` you should see a folder again called `unipy`. You can then install `unipy` with:
+ ```
+ $ python setup.py install
+ ```
+___________________________________________________________
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..2f41441
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,38 @@
+import setuptools
+
+with open("README.md", "r", encoding="utf-8") as fh:
+ long_description = fh.read()
+
+setuptools.setup(
+ name="unipy",
+ version="2023.10.1",
+ author="Anik Mandal",
+ author_email="mandal.anik10@gmail.com",
+ description="A unified module for physics",
+ long_description=long_description,
+ long_description_content_type="text/markdown",
+ url="https://github.com/mandal-anik10/unipy",
+ project_urls={
+ "Unipy webpage": "https://mandal-anik10.github.io/unipy/",
+ },
+ classifiers=[
+ "Programming Language :: Python :: 3",
+ "License :: OSI Approved :: MIT License",
+ "Operating System :: OS Independent",
+ ],
+ install_requires=[
+ "numpy",
+ "sklearn"
+ ],
+ package_dir={},
+ packages=setuptools.find_packages(where="src"),
+ python_requires=">=3.6"
+)
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/unipy/.idea/.gitignore b/unipy/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/unipy/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/unipy/.idea/LocalModule.iml b/unipy/.idea/LocalModule.iml
new file mode 100644
index 0000000..698ce9f
--- /dev/null
+++ b/unipy/.idea/LocalModule.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/unipy/.idea/inspectionProfiles/profiles_settings.xml b/unipy/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/unipy/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/unipy/.idea/misc.xml b/unipy/.idea/misc.xml
new file mode 100644
index 0000000..a4652f3
--- /dev/null
+++ b/unipy/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/unipy/.idea/modules.xml b/unipy/.idea/modules.xml
new file mode 100644
index 0000000..af1927a
--- /dev/null
+++ b/unipy/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/unipy/BasicOp.py b/unipy/BasicOp.py
new file mode 100644
index 0000000..b6f8520
--- /dev/null
+++ b/unipy/BasicOp.py
@@ -0,0 +1,169 @@
+"""
+Module for basic mathematical operations and physical quantities.
+
+Mandal, Anik | 2023-10-03
+"""
+
+
+from numpy import *
+
+# Mathematical Operations----------
+
+# Summation:
+def Sum(arr, step = 1):
+ '''
+ Returns sum of the elements in a input list
+
+ -----Inputs----------
+ arr : list : list of integers/float
+ step : int : increment in the index value
+ -----Output----------
+ s : int/float : sum of the elements of list
+
+ * Equivalant to numpy.sum()
+ '''
+ s = 0
+ for i in range(0, len(arr), step):
+ s = s + arr[i]
+ return s
+
+
+# Factorial:
+def Fact(n, step=1):
+ '''
+ Returns factorial of a number
+
+ -----Inputs----------
+ n : int : Input number
+ step : int : difference between two successive numbers
+ -----Output----------
+ f : int : factorial of the number
+ '''
+ f = 1
+ for i in range(1, n+1, step):
+ f = f * i
+ return f
+
+# Integration:
+def Integrate(y_data, x_data, spacing='linear'):
+ '''
+ Function for performing integration using trapizoidal method.
+
+ -----Inputs----------
+ y_data : list : a list of numbers defing the y values of the function
+ x_data : list : a list of numbers defing the x values of the function
+ spacing : string : specification of increment vector/scaler
+ - default :'linear'
+ -----Output----------
+ s : float : value of the integration
+ '''
+ if len(y_data) != len(x_data) or len(x_data) <= 1 or len(y_data) <= 1:
+ raise ValueError("x and y data are not consistant for trapizoidal integration")
+ else:
+ if spacing == 'linear':
+ h = x_data[1] - x_data[0]
+ s = Sum(y_data[1:len(x_data)-1])
+ s = (y_data[0] + y_data[-1] + 2 * s) * h / 2
+ else:
+ s = 0
+ for i in range(len(x_data)-1):
+ h = x_data[i+1] - x_data[i]
+ s = s + h * (y_data[i] + y_data[i+1]) / 2
+ return s
+
+def Integrate_simp(y_data, x_data, spacing='linear'):
+ '''
+ Function for performing integration using Simpson's 1/3 method.
+
+ -----Inputs----------
+ y_data : list : a list of numbers defing the y values of the function
+ x_data : list : a list of numbers defing the x values of the function
+ spacing : string : specification of increment vector/scaler
+ - default :'linear'
+ -----Output----------
+ s : float : value of the integration
+ '''
+ if len(y_data) != len(y_data) or len(x_data) <= 2 or len(y_data) <= 2:
+ raise ValueError("x and y data are not consistant for simpson integration")
+ else:
+ if spacing == 'linear':
+ h = x_data[1] - x_data[0]
+ s = 4 * Sum(y_data[1, len(x_data)-1], 2)
+ s = s + 2 * Sum(y_data[2, len(x_data)-1], 2)
+ s = (y_data[0] + s + y_data[-1]) * h / 3
+ else:
+ raise NotImplementedError('Simpson\'s 1/3 integration is not implemented yet'+\
+ 'in nonlinear scale; use tapizoidal integration.')
+
+# Fourier Series:
+def FourierSeries(y_data, x_data, nc=10):
+ '''
+ Returns Fouries Series of a function
+
+ -----Inputs----------
+ y_data : list : a list of numbers defing the y values of the function
+ x_data : list : a list of numbers defing the x values of the function
+ nc : int : number of coefficents of sin and cos series
+ - default :10
+ -----Outputs----------
+ cc : list : coeff. of cosine series
+ cs : list : coeff. of sin series
+ y_new : list : fourier function
+ '''
+ cc, cs, y_new = [], [], []
+
+ for i in range(nc):
+ yc = y_data * cos(pi * i * x_data)
+ ys = y_data * sin(pi * i * x_data)
+
+ sc = Integrate(yc, x_data)
+ ss = Integrate(ys, x_data)
+
+ cc.append(sc)
+ cs.append(ss)
+
+ cc[0] = cc[0]/2
+
+ for i in range(len(x_data)):
+ s = 0
+ for j in range(nc):
+ s = s + cc[j] * cos(pi * j *x_data[i]) + cs[j] * sin(pi * j * x_data[i])
+
+ y_new.append(s)
+ return cc, cs, y_new
+
+
+# Physical Quantities----------
+
+# Inertia Tensor:
+def Inertia_T(Mass_List, Pos_Tensor):
+ '''
+ Returns Inertia Tensor of discrete masses
+
+ -----Inputs----------
+ arr : list : list of integers/float
+ -----Output----------
+ s : int/float : sum of the elements of list
+ '''
+ I = np.zeros((3, 3))
+
+ for m in range(3):
+ for n in range(3):
+
+ if m == n:
+ for k in range(len(Mass_List)):
+ s = 0
+ for i in range(3):
+ if i != m:
+ s = s + Mass_List[k]*Pos_Tensor[k][i]**2
+
+ I[m][n] = I[m][n] + s
+
+ else:
+ for k in range(len(Mass_List)):
+ s = - Mass_List[k]*Pos_Tensor[k][m]*Pos_Tensor[k][n]
+
+ I[m][n] = I[m][n] + s
+ return I
+
+
diff --git a/unipy/CurveFit.py b/unipy/CurveFit.py
new file mode 100644
index 0000000..04bbf55
--- /dev/null
+++ b/unipy/CurveFit.py
@@ -0,0 +1,75 @@
+"""
+Module for curve fitting.
+
+Mandal, Anik | 2023-10-03
+"""
+
+import numpy as np
+from sklearn.linear_model import Lasso
+from sklearn.preprocessing import PolynomialFeatures
+
+
+# Linear Fit Module:
+def LinearFit(x_data, y_Data):
+ '''
+ Returns slope and y-intersect of the best linear fit using least
+ square fit
+
+ -----Inputs----------
+ x_data : list : x coordinate of the input values
+ y_data : list : y coordinate of the input values
+ -----Outputs----------
+ m : float : slope of the best fit line
+ c : float : y-intersect of the best fit line.
+ '''
+ (sx, sy, p1, p2) = (0, 0, 0, 0)
+ for i in range(len(x_data)):
+ sx = sx + x_data[i]
+ sy = sy + y_Data[i]
+ xb = sx/len(x_data)
+ yb = sy/len(y_Data)
+ for i in range(len(x_data)):
+ p1 = p1 + (x_data[i]-xb)*(y_Data[i]-yb)
+ p2 = p2 + (x_data[i]-xb)**2
+ m = p1/p2
+ c = yb - m*xb
+ return m, c
+
+
+# Nolinear Fit Module:
+def LassoRegression(x_data, y_data, max_degrees=10, alpha_value=0.2, num_points=int(1e5)):
+ '''
+ Returns data set of best fit curve using sklearn Lasso Regression
+
+ -----Inputs----------
+ x_data : list : x coordinates of the input values
+ y_data : list : y coordinates of the input values
+ max_degree : int : maximum degree for interpolation
+ - default : 10
+ alpha_value : float : defines alpha parameter for Lasso regression
+ - default : 0.2
+ num_points : int : number of point for interpolation
+ - default : 1e5
+ -----Outputs----------
+ x_new : list : x coordinates of the fitted curve
+ y_new : list : y coordinates of the fitted curve
+ '''
+ d = max_degrees
+ poly = PolynomialFeatures(degree=d, include_bias=False)
+ x_new = poly.fit_transform(x_data)
+
+ alp = alpha_value
+ sl = Lasso(alpha=alp).fit(x_new, y_data)
+
+ m = sl.coef_
+ c = sl.intercept_
+ s = sl.score(x_new, y_data)
+
+ x_new = np.linspace(min(x_data), max(x_data), num_points)
+ y_new = []
+ for i in range(len(x_new)):
+ a = 0
+ for j in range(len(m)):
+ a = a + m[j] * x_new[i] ** (j + 1)
+ y_new.append(a + c[0])
+ return x_new, y_new
diff --git a/unipy/GraphPlot.py b/unipy/GraphPlot.py
new file mode 100644
index 0000000..b3129ad
--- /dev/null
+++ b/unipy/GraphPlot.py
@@ -0,0 +1,22 @@
+"""
+Module for graph plotting.
+
+Mandal, Anik | 2023-10-03
+"""
+
+def ExpData2GraphData(x_data, y_data, small_x, small_y):
+ '''
+ Returns sum of the elements in a input list
+
+ -----Inputs----------
+ arr : list : list of integers/float
+ step : int : increment in the index value
+ -----Output----------
+ s : int/float : sum of the elements of list
+ '''
+ x_new = []
+ y_new = []
+ for i in range(len(x_data)):
+ x_new.append(x_data[i]/small_x)
+ y_new.append(y_data[i]/small_y)
+ return x_new, y_new
diff --git a/unipy/MatOp.py b/unipy/MatOp.py
new file mode 100644
index 0000000..c29ced7
--- /dev/null
+++ b/unipy/MatOp.py
@@ -0,0 +1,72 @@
+"""
+Module for matrix operations.
+
+Mandal, Anik | 2023-10-03
+"""
+
+import numpy as np
+
+# Matrix Order:
+def M_Order(arr_x):
+ '''
+ Returns order of the input matrix
+
+ -----Inputs----------
+ arr_x : array-like : input array
+ -----Output----------
+ o : list : order of the matrix
+ '''
+ r = len(arr_x)
+ c = len(arr_x[0])
+ o = [r, c]
+ return o
+
+
+# Matrix Sum:
+def M_Sum(arr_x, arr_y):
+ '''
+ Returns sum of two matrices
+
+ -----Inputs----------
+ arr_x : array-like : first input matrix
+ arr_y : array-like : second input matrix
+ -----Output----------
+ arr_z : array-like : output matrix as the sum of input matrices
+ '''
+ if M_Order(arr_x) == M_Order(arr_y):
+ Order = M_Order(arr_x)
+ arr_z = np.zeros(Order)
+ for i in range(Order[0]):
+ for j in range(Order[1]):
+ arr_z[i][j] = arr_x[i][j] + arr_y[i][j]
+ return arr_z
+ else:
+ raise ValueError('Order of the matrices doesn\'t match')
+
+
+# Matrix Multiplication:
+def M_Multiplication(arr_x, arr_y):
+ '''
+ Returns multiplication of two matrices
+
+ -----Inputs----------
+ arr_x : array-like : first input matrix
+ arr_y : array-like : second input matrix
+ -----Output----------
+ arr_z : array-like : output matrix as the multiplication of input matrices
+ '''
+ Ox = M_Order(arr_x)
+ Oy = M_Order(arr_y)
+ arr_z = np.zeros((Ox[0],Oy[1]))
+ if Ox[1] == Oy[0]:
+ for i in range(0,Ox[0]):
+ for j in range(0,Oy[1]):
+ for k in range(0,Ox[1]):
+ arr_z[i][j] = arr_z[i][j] + arr_x[i][k] * arr_y[k][j]
+ return arr_z
+ else:
+ raise ValueError('order of the matrices are incompatable for matrix multiplication'+\
+ 'number of column of the fist matrix must be equal to the number of row of second matrix')
+
+
+
diff --git a/unipy/VecOp.py b/unipy/VecOp.py
new file mode 100644
index 0000000..572de26
--- /dev/null
+++ b/unipy/VecOp.py
@@ -0,0 +1,197 @@
+"""
+Module for vector operations.
+
+Mandal, Anik | 2023-10-03
+"""
+
+import numpy as np
+from unipy.MatOp import *
+
+
+# Vector Dimension:
+def V_Dim(v1):
+ '''
+ Returns the dimension of the vector
+
+ -----Inputs----------
+ v1 : array-like : input vector
+ -----Output----------
+ D : int : dimension of the input vector
+ '''
+ D = M_Order(v1)[0]
+ return D
+
+# Vector Sum:
+def V_Sum(v1, v2):
+ '''
+ Returns sum of two vectors
+
+ -----Inputs----------
+ v1 : array-like : first vector
+ v2 : array-like : second vector
+ -----Output----------
+ vs : array-like : sum of the two vectors
+ '''
+ if V_Dim(v1) == V_Dim(v2):
+ vs = M_Sum(v1, v2)
+ return vs
+ else:
+ raise ValueError('Dimension of the vectors doesn\'t match')
+
+
+# Vector Negative:
+def V_Neg(v1):
+ '''
+ Returns neg vector of a vector
+
+ -----Inputs----------
+ v1 : array-like : input vector
+ -----Output----------
+ vn : array-like : neg vector of the input vector
+ '''
+
+ vn = np.zeros((V_Dim(v1), 1))
+ for i in range(V_Dim(v1)):
+ vn[i][0] = -v1[i][0]
+ return vn
+
+
+# Vector Substraction:
+def V_Subtract(v1, v2):
+ '''
+ Returns subtraction of two vectors
+
+ -----Inputs----------
+ v1 : array-like : first vector
+ v2 : array-like : second vector
+ -----Output----------
+ vs : array-like : subtraction of the two vectors
+ '''
+ vn = V_Sum(v1, V_Neg(v2))
+ return vn
+
+
+# Vector Dot Product:
+def V_Dot(v1, v2):
+ '''
+ Returns scaler product of two vectors
+
+ -----Inputs----------
+ v1 : array-like : first vector
+ v2 : array-like : second vector
+ -----Output----------
+ vs : array-like : scaler product of the two vectors
+ '''
+ if V_Dim(v1) == V_Dim(v2):
+ vs = 0
+ for i in range(V_Dim(v1)):
+ vs = vs + v1[i][0] * v2[i][0]
+ return vs
+ else:
+ raise ValueError('Dimension of the vectors doesn\'t match')
+
+
+# Vector Scaler Product:
+def V_Scale(v1, f):
+ '''
+ Returns scaled vector of a vector
+
+ -----Inputs----------
+ v1 : array-like : input vector
+ f: floar : scaling factor
+ -----Output----------
+ vs : array-like : scaled vector of the input vector
+ '''
+ vs = np.zeros((V_Dim(v1), 1))
+ for i in range(V_Dim(v1)):
+ vs[i][0] = vs[i][0] + f * v1[i][0]
+ return vs
+
+
+# Vector Mod:
+def V_Mod(v1):
+ '''
+ Returns length/modulus of a vector
+
+ -----Inputs----------
+ v1 : array-like : input vector
+ -----Output----------
+ vm : float : length of the vector
+ '''
+ vm = (V_Dot(v1, v1))**0.5
+ return vm
+
+
+# Unit Vector:
+def V_Unit(v1):
+ '''
+ Returns unit vector of a vector
+
+ -----Inputs----------
+ v1 : array-like : input vector
+ -----Output----------
+ vu : array-like : unit vector of the input vector
+ '''
+ vm = V_Mod(v1)
+ if vm > 0:
+ vu = np.zeros((V_Dim(v1), 1))
+ for i in range(v1):
+ vu[i][0] = v1[i][0] / vm
+ return vu
+ else:
+ raise ZeroDivisionError('Length of the vector found to be zero!')
+
+
+# Vector Cross Product:
+def V_Cross(v1, v2):
+ '''
+ Returns cross product of two vectors
+
+ -----Inputs----------
+ v1 : array-like : first input vector
+ v2 : array-like : second input vector
+ -----Output----------
+ vc : array-like : cross product of the input vectors
+ '''
+ if V_Dim(v1) == V_Dim(v2) == 3:
+ vcx = v1[1][0] * v2[2][0] - v1[2][0] * v2[1][0]
+ vcy = v1[2][0] * v2[0][0] - v1[0][0] * v2[2][0]
+ vcz = v1[0][0] * v2[1][0] - v1[1][0] * v2[0][0]
+ vc = [vcx, vcy, vcz]
+
+ return vc
+ else:
+ raise ValueError('Dimension of the vectors are not compatible for cross product')
+
+
+
+
+# Gram-Schimdt Orthogonalization:
+def GSOrtho(list_v):
+ '''
+ Returns vectors which are normal with each other using
+ Gram-Schimdt orthogonalization method
+
+ -----Inputs----------
+ list_v : list : list of vectors
+ -----Output----------
+ list_n : list : mutually normal vectors
+ '''
+ dim_vs = [V_Dim(v) for v in list_v]
+ if len(set(dim_vs)) == 1 and len(list_v) == dim_vs[0]:
+
+ list_n = np.zeros((len(list_v)))
+ list_n[0] = list_v[0]
+
+ for i in range(1, len(list_n)):
+ s = list_v[i]
+ for j in range(0, i):
+ s = s - (V_Dot(list_n[j], list_v[i]) / V_Mod(list_v[i])) * V_Unit(list_n[j])
+
+ list_n[i] = s
+
+ return list_n
+ else:
+ raise ValueError('Set of given vector are not compatible for Gram-Schimdt orthogonalization')
+
+
diff --git a/unipy/__init__.py b/unipy/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/unipy/__pycache__/Content.cpython-310.pyc b/unipy/__pycache__/Content.cpython-310.pyc
new file mode 100644
index 0000000..21dad8a
Binary files /dev/null and b/unipy/__pycache__/Content.cpython-310.pyc differ
diff --git a/unipy/__pycache__/__init__.cpython-310.pyc b/unipy/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..d00dc5f
Binary files /dev/null and b/unipy/__pycache__/__init__.cpython-310.pyc differ