From e444e2e7edfa2c82ad6cb006e06aad8f372a3b33 Mon Sep 17 00:00:00 2001 From: Hideyoshi Date: Sat, 16 May 2020 15:38:24 -0300 Subject: [PATCH] v1.0 v1.0 v1.0 v1.0 v1.0 v1.0 v1.0 v1.0 v1.0 v1.0 v1.0 v1.0 v1.0 --- Otter/Otter.py | 191 ++++----- Otter/__init__.py | 4 +- README.md | 78 ++-- build/lib/Otter/Otter.py | 480 ++++++++++++++++++++++ build/lib/Otter/__init__.py | 2 + dist/yoshi-otter-1.1.tar.gz | Bin 0 -> 4975 bytes dist/yoshi_otter-1.1-py3-none-any.whl | Bin 0 -> 12205 bytes setup.py | 7 +- yoshi_otter.egg-info/PKG-INFO | 91 ++++ yoshi_otter.egg-info/SOURCES.txt | 9 + yoshi_otter.egg-info/dependency_links.txt | 1 + yoshi_otter.egg-info/requires.txt | 3 + yoshi_otter.egg-info/top_level.txt | 1 + 13 files changed, 730 insertions(+), 137 deletions(-) create mode 100644 build/lib/Otter/Otter.py create mode 100644 build/lib/Otter/__init__.py create mode 100644 dist/yoshi-otter-1.1.tar.gz create mode 100644 dist/yoshi_otter-1.1-py3-none-any.whl create mode 100644 yoshi_otter.egg-info/PKG-INFO create mode 100644 yoshi_otter.egg-info/SOURCES.txt create mode 100644 yoshi_otter.egg-info/dependency_links.txt create mode 100644 yoshi_otter.egg-info/requires.txt create mode 100644 yoshi_otter.egg-info/top_level.txt diff --git a/Otter/Otter.py b/Otter/Otter.py index acbb30f..c2ec3b7 100755 --- a/Otter/Otter.py +++ b/Otter/Otter.py @@ -26,11 +26,10 @@ class Algebra: def __init__(self, function): self.f = function - def riemann(self,interval): + def riemann(self,a,b,n=None): - a = interval[0] - b = interval[1] - n = interval[2] + if n is None: + n = 10**6 delta = (b-a)/n @@ -46,15 +45,14 @@ class Algebra: return integral - def simpson(self, interval): + def simpson(self,a,b,n=None): + + if n is None: + n = 10**6 def x(i): return a + i*h - a = interval[0] - b = interval[1] - n = interval[2] - h = (b-a)/n eta = 0 @@ -81,15 +79,13 @@ class Algebra: def __init__(self,function): self.f = function - def riemann(self,x_interval,y_interval): + def riemann(self,a,b,c,d,n=None,m=None): + + if n is None: + n = 10**4 - a = x_interval[0] - b = x_interval[1] - n = x_interval[2] - - c = y_interval[0] - d = y_interval[1] - m = y_interval[2] + if m is None: + m = n dx = (b-a)/n dy = (d-c)/m @@ -109,15 +105,13 @@ class Algebra: return theta*(dx)*(dy) - def simpson(self,x_interval,y_interval): + def simpson(self,a,b,c,d,n=None,m=None): + + if n is None: + n = 10**4 - a = x_interval[0] - b = x_interval[1] - n = x_interval[2] - - c = y_interval[0] - d = y_interval[1] - m = y_interval[2] + if m is None: + m = n dx = (b-a)/n dy = (d-c)/m @@ -178,12 +172,10 @@ class Algebra: if function is not None: self.f = function - def bissec(self, interval): - """ invertal = [a,b,e] ; with 'a' being the first value of the interval, 'b' the last value of the interval and 'e' the precision of the procedure. """ - - a = interval[0] - b = interval[1] - e = interval[2] + def bissec(self,a,b,e=None): + + if e is None: + e = 10**(-6) fa = self.f(a) @@ -208,10 +200,10 @@ class Algebra: def d(self, x, e): return (self.f(x + e) - self.f(x - e))/(2*e) - def newton(self, interval): + def newton(self,a,e=None): - a = interval[0] - e = interval[1] + if e is None: + e = 10**(-6) fa = self.f(a) da = self.d(a,e) @@ -227,11 +219,10 @@ class Algebra: return a - def bissec_newton(self, interval): + def bissec_newton(self,a,b,e=None): - a = interval[0] - b = interval[1] - e = interval[2] + if e is None: + e = 10**(-6) fa = self.f(a) @@ -271,12 +262,10 @@ class Algebra: def __init__(self, function): self.f = function - def euler(self, interval): + def euler(self,a,y,b,n=None): - a = interval[0] - b = interval[1] - y = interval[2] - n = int(interval[3]) + if n is None: + n = 10**7 dx = (b-a)/n @@ -289,12 +278,10 @@ class Algebra: return y - def runge(self, interval): + def runge(self,a,y,b,n=None): - a = interval[0] - b = interval[1] - y = interval[2] - n = int(interval[3]) + if n is None: + n = 10**7 dx = (b-a)/n @@ -315,6 +302,59 @@ class Interpolation: self.data = data self.polinomial = self.Polinomial(self.data) + def minimus(self,x): + + theta = 0 + # somatorio de x + for i in range(self.data.shape[0]): + + theta += self.data[i][0] + + eta = 0 + #somatorio de y + for i in range(self.data.shape[0]): + + eta += self.data[i][1] + + sigma = 0 + #somatorio de xy + for i in range(self.data.shape[0]): + + sigma += self.data[i][0]*self.data[i][1] + + omega = 0 + #somatorio de x^2 + for i in range(self.data.shape[0]): + + omega += self.data[i][0]**2 + + + self.a = (self.data.shape[0]*sigma - theta*eta)/(self.data.shape[0]*omega - (theta**2)) + + self.b = (theta*sigma - eta*omega)/((theta**2) - self.data.shape[0]*omega) + + ym = 0 + + for i in range(self.data.shape[0]): + + ym += self.data[i][1]/self.data.shape[0] + + sqreq = 0 + + for i in range(self.data.shape[0]): + + sqreq += ((self.a*self.data[i][0] + self.b) - ym)**2 + + sqtot = 0 + + for i in range(self.data.shape[0]): + + sqtot += (self.data[i][1] - ym)**2 + + self.r2 = sqreq/sqtot + + return self.a*x + self.b + class Polinomial: def __init__(self, data): @@ -437,57 +477,4 @@ class Interpolation: y += d[i+1][0]*mult i += 1 - return y - - def minimus(self,x): - - theta = 0 - # somatorio de x - for i in range(self.data.shape[0]): - - theta += self.data[i][0] - - eta = 0 - #somatorio de y - for i in range(self.data.shape[0]): - - eta += self.data[i][1] - - sigma = 0 - #somatorio de xy - for i in range(self.data.shape[0]): - - sigma += self.data[i][0]*self.data[i][1] - - omega = 0 - #somatorio de x^2 - for i in range(self.data.shape[0]): - - omega += self.data[i][0]**2 - - - self.a = (self.data.shape[0]*sigma - theta*eta)/(self.data.shape[0]*omega - (theta**2)) - - self.b = (theta*sigma - eta*omega)/((theta**2) - self.data.shape[0]*omega) - - ym = 0 - - for i in range(self.data.shape[0]): - - ym += self.data[i][1]/self.data.shape[0] - - sqreq = 0 - - for i in range(self.data.shape[0]): - - sqreq += ((self.a*self.data[i][0] + self.b) - ym)**2 - - sqtot = 0 - - for i in range(self.data.shape[0]): - - sqtot += (self.data[i][1] - ym)**2 - - self.r2 = sqreq/sqtot - - return self.a*x + self.b \ No newline at end of file + return y \ No newline at end of file diff --git a/Otter/__init__.py b/Otter/__init__.py index 80edee6..4132067 100644 --- a/Otter/__init__.py +++ b/Otter/__init__.py @@ -1,2 +1,2 @@ -from .Otter import Algebra -from .Otter import Interpolation \ No newline at end of file +from .Otter import Algebra as algebra +from .Otter import Interpolation as interpolation \ No newline at end of file diff --git a/README.md b/README.md index 808a0d7..05245f1 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,68 @@ -# Numeric Calculus +# Otter - Numeric Calculus -This is a Repository of Python Packages for Numeric Calculus. It contains two packages: Seals and Otter. +This python package is made for applied Numeric Calculus of Algebra Functions. It is made with the following objectives in mind: -## Seals +* Receive one variable function from user input + +* Receive two variable function from user input -The package Seals is made for Linear Algebra. It's able to: +* Performe derivatives with one variable functions -* Scan *csv* files to make a numpy matrix. - -* Write a matrix into a *csv* file - -* Insert user input into a matrix or a vector. +* Performe integral with received functions * Use methods to proccess the matrices. - * Identity Matrix - * Gauss Elimination - * Inverse Matrix - * Cholesky Decomposition - * LU Decomposition - * Cramer -### Syntax +* Find root of functions throw method of bissection and method of newton -The function *scan* has the following syntax `scan(path)`, where `path` is the path to your directory. +* Solve Diferential Equations throw method of euler and runge -The function *solution* has the following syntax `write(array,path)`, where `array` is the matrix that you desire to output and `path` is the path to your directory. +* Performe Minimus Interpolation and Polinomial Interpolation -The python class *Insert* has a method for *matrix* and another for *vector*, and it has the following syntax `Insert.method(array)`, where `Insert` is the *Python Class* and `method` is either a `matrix` or a `vector` and `array` is either a *matrix* or a *vector*. +## Syntax -### Processes +To initialize a Otter instance linked to functions use the following syntax `otr = Otter.algebra(f)`, where `otr` will be a arbitrary name for the instance and `f` is a function of *one variable*. -The python class *process* has all the methods described in the first session. +To initialize a Otter instance linked to data and interpolation use the following syntax `otr = Otter.interpolation(data)`, where `otr` will be a arbitrary name for the instance and data will be a *numpy* matrix where the first columns has to contain the values for `x` and the second column contains the values for `y`. -To call the method use a syntax like `sl = Seals.process()`, where `sl` is an instance and to use a method you have to append the method in front of the instance like: `sl.identity(array)`. +### Algebra -* The method *identity* returns a *numpy* identity matrix of the order of the matrix passed into to it, and it has the following syntax `sl.identity(array)`, which `array` is a square matrix. +Algebra is a Python Class where some of the features described previously are defined as Classes as well, like: `Integral`, `Roots`, `EDO` (diferential equations). -* The method *gauss* returns a *numpy* vector containing the vector of variables from the augmented matrix. `sl.gauss(matrix)`, which `matrix` is the augmented matrix. +#### Integral -* The method *inverse* returns a *numpy* inverse matrix of the matrix passed into to it, and it has the following syntax `sl.inverse(matrix)`, which `matrix` is a square matrix. +To call the class *Integral* append the sufix with lower case in front of the instance like: `otr.integral`. The Integral class has two other class defined inside, `Simple` and `Double`, to call them append the sufix with lower case in front as `otr.integral.simple` or `otr.integral.double`. Then pick between Riemann's Method or Simpson's Method by appending the sufix `riemann` or `simpson` as well. -* The method *cholesky* returns a *numpy* vector containing the vector of variables from the coefficient matrix and the constants vector, and it has the following syntax `sl.cholesky(A,b)`, which `A` is the coefficient matrix and `b` is the constants vector. - -* The method *decomposition* returns a *numpy* vector containing the vector of variables from the coefficient matrix and the constants vector, and it has the following syntax `sl.cholesky(A,b)`, which `A` is the coefficient matrix and `b` is the constants vector. +After that the syntax will be something like `otr.integral.double.riemann(a,b,c,d,n,m)`, where `a` and `c` will be the first value of the interval of integration respectively in x and y, `b` and `d` will be the last, `n` and `m` will be the number of partitions. -* The method *cramer* returns a *numpy* vector containing the vector of variables from the coefficient matrix and the constants vector, and it has the following syntax `sl.cholesky(A,b)`, which `A` is the coefficient matrix and `b` is the constants vector. +The syntax for one variable integrations will be `otr.integral.simple.riemann(a,b,n)`. + +If `n` is not defined the standart value in 10^6 partitions for one variable and 10^4 for double. And if `m` is not defined the standart value will be equal to `n`. + +#### Roots + +To call the class *Root* append the sufix with lower case in front of the instance like: `otr.roots`. The Roots class has three methods defined inside, `bissec`, `newton` and `bissec_newton`, to call them append the sufix with lower case in front as `otr.roots.bissec` or `otr.roots.newton` or even `otr.roots.bissecnewton`. + +The syntax for the bissection method and bissec_newton is equal to `otr.roots.bissec(a,b,e)` and `otr.roots.bissec_newton(a,b,e)`, where `a` is the first element of the interval containing the root and `b` is the last, `e` being the precision. + +The syntax for the newton method is equal to `otr.roots.newton(a,e)`, where `a` is the element closest to the root and `e` is the precision. + +If `e` is not defined the standart value is 10^(-6). + +#### Diferential Equations + +To call the class *EDO* (*E*quações *D*iferenciais *O*rdinárias) append the sufix with lower case in front of the instance like: `otr.edo`. The *EDO* class has two methods defined inside: `euler` and `runge`, to call them append the sufix with lower case in front as `otr.edo.euler` or `otr.edo.runge`. + +The syntax for the diferential equations method is equal to `otr.edo.euler(a,y,b,n)` or `otr.edo.runge(a,y,b,n)`, where `a` and `y` will be the inintial point and `b` is the value in *x* which you want to know the corresponding value in *y* and `n` is the number of operations. + +If `n` is not defined the standart value is 10^7. + +### Interpolation + +The python class *Interpolation* is divided in one method, minimus interpolation, and one class, polinomial interpolation. + +To call the method *minimus* use a syntax like `otr = Otter.interpolation(data)`, where `otr` is an instance and append the method in front of the instance like: `otr.minimus(x)`, where *x* is value of *f(x)* you want to estimate. + +To call the class *Polinomial* append the sufix with lower case in front of the instance like: `otr.polinomial`. The *Polinomial* class has four methods defined inside: `vandermonde`, `lagrange`, `newton` and `gregory`, to call them append the sufix with lower case in front like `otr.edo.gregory(x)` where *x* is value of *f(x)* you want to estimate. ## Installation @@ -54,4 +72,4 @@ To install the package from source `cd` into the directory and run: or run -`pip install Numeric-Calculus_HideyoshiNakazone` \ No newline at end of file +`pip install yoshi-otter` diff --git a/build/lib/Otter/Otter.py b/build/lib/Otter/Otter.py new file mode 100644 index 0000000..c2ec3b7 --- /dev/null +++ b/build/lib/Otter/Otter.py @@ -0,0 +1,480 @@ +import math +import numpy as np +import Seals + +sl = Seals.method() + +class Algebra: + + def __init__(self, function): + self.f = function + self.integral = self.Integral(self.f) + self.roots = self.Roots(self.f) + self.edo = self.Edo(self.f) + + def d(self, x, e): + return (self.f(x + e) - self.f(x - e))/(2*e) + + class Integral: + + def __init__(self,function): + self.f = function + self.simple = self.Simple(function) + self.double = self.Double(function) + + class Simple: + def __init__(self, function): + self.f = function + + def riemann(self,a,b,n=None): + + if n is None: + n = 10**6 + + delta = (b-a)/n + + psi = a + theta = 0 + + while((psi+delta) <= b): + + theta += (self.f(psi) + self.f(psi + delta))/2 + psi += delta + + integral = delta*theta + + return integral + + def simpson(self,a,b,n=None): + + if n is None: + n = 10**6 + + def x(i): + return a + i*h + + h = (b-a)/n + + eta = 0 + theta = 0 + + psi = 1 + kappa = 1 + + while(psi <= (n/2)): + + eta = eta + self.f(x(2*psi - 1)) + psi = psi + 1 + + while(kappa <= ((n/2)-1)): + + theta = theta + self.f(x(2*kappa)) + kappa = kappa + 1 + + return (h/3)*( self.f(x(0)) + self.f(x(n)) + 4*eta + 2*theta) + + + class Double: + + def __init__(self,function): + self.f = function + + def riemann(self,a,b,c,d,n=None,m=None): + + if n is None: + n = 10**4 + + if m is None: + m = n + + dx = (b-a)/n + dy = (d-c)/m + kappa = a + psi = c + theta = 0 + + while((psi + dy) < d): + + while((kappa + dx) < b): + + theta = theta + self.f(kappa, psi) + kappa = kappa + dx + + psi = psi + dy + kappa = a + + return theta*(dx)*(dy) + + def simpson(self,a,b,c,d,n=None,m=None): + + if n is None: + n = 10**4 + + if m is None: + m = n + + dx = (b-a)/n + dy = (d-c)/m + + def x(i): + + x = a + i*dx + + return x + + def y(i): + + y = c + i*dy + + return y + + def g(i): + + sigma = 0 + upsilon = 0 + + zeta = 1 + csi = 1 + + while(zeta <= (m/2)): + + sigma += self.f(x(i),y(2*zeta - 1)) + zeta += 1 + + while(csi <= ((m/2)-1)): + + upsilon += self.f(x(i),y(2*csi)) + csi += 1 + + return (dy/3)*( self.f(x(i),y(0)) + self.f(x(i),y(m)) + 4*sigma + 2*upsilon ) + + eta = 0 + theta = 0 + + psi = 1 + kappa = 1 + + while(psi <= (n/2)): + + eta += g(2*psi - 1) + psi += 1 + + while(kappa <= ((n/2)-1)): + + theta += g(2*kappa) + kappa += 1 + + return (dx/3)*( g(0) + g(n) + 4*eta + 2*theta) + + class Roots: + + def __init__(self, function=None): + if function is not None: + self.f = function + + def bissec(self,a,b,e=None): + + if e is None: + e = 10**(-6) + + fa = self.f(a) + + while abs(a-b) > e: + + c = (a+b)/2 + fc = self.f(c) + + if (fa*fc) < 0: + + b = c + + else: + + a = c + fa = fc + + c = (a+b)/2 + + return c + + def d(self, x, e): + return (self.f(x + e) - self.f(x - e))/(2*e) + + def newton(self,a,e=None): + + if e is None: + e = 10**(-6) + + fa = self.f(a) + da = self.d(a,e) + b = a - fa/da + + + while abs(a-b) > e: + + b = a + a -= (fa/da) + fa = self.f(a) + da = self.d(a,e) + + return a + + def bissec_newton(self,a,b,e=None): + + if e is None: + e = 10**(-6) + + fa = self.f(a) + + c = (a+b)/2 # 'c' é a raiz calculada + + while abs(a-b) > 0.1: + + fc = self.f(c) + + if fa*fc < 0: + + b = c + + else: + + a = c + fa = self.f(a) + + c = (a+b)/2 + + fc = self.f(c) + dc = self.d(c,e) + h = c - fc/dc # 'h' é uma variável de controle + + while abs(c-h) > e: + + h = c + c -= (fc/dc) + fc = self.f(c) + dc = self.d(c,e) + + return (c) + + + class Edo: + + def __init__(self, function): + self.f = function + + def euler(self,a,y,b,n=None): + + if n is None: + n = 10**7 + + dx = (b-a)/n + + def x(i): + return a + i*dx + + for i in range(n): + + y = y + (self.f(x(i),y))*dx + + return y + + def runge(self,a,y,b,n=None): + + if n is None: + n = 10**7 + + dx = (b-a)/n + + def x(i): + return (a + i*dx) + + for i in range(n): + + y = y + (dx/2)*(self.f(x(i),y)+self.f(x(i+1),(y+(dx*self.f(x(i),y))))) + + return y + +class Interpolation: + """ Data should be organized in two columns: X and Y""" + + def __init__(self, data): + + self.data = data + self.polinomial = self.Polinomial(self.data) + + def minimus(self,x): + + theta = 0 + # somatorio de x + for i in range(self.data.shape[0]): + + theta += self.data[i][0] + + eta = 0 + #somatorio de y + for i in range(self.data.shape[0]): + + eta += self.data[i][1] + + sigma = 0 + #somatorio de xy + for i in range(self.data.shape[0]): + + sigma += self.data[i][0]*self.data[i][1] + + omega = 0 + #somatorio de x^2 + for i in range(self.data.shape[0]): + + omega += self.data[i][0]**2 + + + self.a = (self.data.shape[0]*sigma - theta*eta)/(self.data.shape[0]*omega - (theta**2)) + + self.b = (theta*sigma - eta*omega)/((theta**2) - self.data.shape[0]*omega) + + ym = 0 + + for i in range(self.data.shape[0]): + + ym += self.data[i][1]/self.data.shape[0] + + sqreq = 0 + + for i in range(self.data.shape[0]): + + sqreq += ((self.a*self.data[i][0] + self.b) - ym)**2 + + sqtot = 0 + + for i in range(self.data.shape[0]): + + sqtot += (self.data[i][1] - ym)**2 + + self.r2 = sqreq/sqtot + + return self.a*x + self.b + + class Polinomial: + + def __init__(self, data): + self.data = data + + def vandermonde(self, x): + + matrix = np.zeros((self.data.shape[0],self.data.shape[0])) + + for k in range(0, self.data.shape[0]): + + matrix[:,k] = self.data[:,0]**k + + self.A = sl.gauss(np.c_[matrix,self.data[:,1]]) + + y = 0 + + for i in range(0,self.A.shape[0]): + + y += self.A[i]*(x**i) + + return float(y) + + def lagrange(self, x): + + data_x = self.data[:,0] + data_y = self.data[:,1] + + def L(k,x): + + up = down = 1 + + for i in [x for x in range(data_x.shape[0]) if x != k]: + up = up*(x - data_x[i]) + + for i in [x for x in range(data_x.shape[0]) if x != k]: + down = down*(data_x[k] - data_x[i]) + + return up/down + + y = 0 + + for i in range(data_x.shape[0]): + + y += data_y[i]*L(i,x) + + return y + + def newton(self,x): + + d = np.array(np.zeros((self.data.shape[0],self.data.shape[0]))) + + d[0] = self.data[:,1] + + i = j = 0 + + while (i < self.data.shape[0]): + + while (j < (self.data.shape[0]-(i+1))): + + d[i+1][j] = (d[i][j+1] - d[i][j])/(self.data[(i+1)+j][0]-self.data[j][0]) + j += 1 + + i += 1 + j = 0 + + def f(x): + + y = d[0][0] + i = 0 + + while ((i+1) < self.data.shape[0]): + + mult = 1 + k = 0 + while (k <= i): + mult = mult*(x - self.data[k][0]) + k += 1 + + y += d[i+1][0]*mult + i += 1 + + return y + + self.f = f + + return f(x) + + def gregory(self,x): + + h = self.data[0][0] - self.data[1][0] + + d = np.array(np.zeros((self.data.shape[0],self.data.shape[0]))) + + d[0] = self.data[:,1] + + i = j = 0 + + while (i < self.data.shape[0]): + + while (j < (self.data.shape[0]-(i+1))): + + d[i+1][j] = (d[i][j+1] - d[i][j])/((i+1)*h) + j += 1 + + i += 1 + j = 0 + + y = d[0][0] + i = 0 + + while ((i+1) < self.data.shape[0]): + + mult = 1 + k = 0 + while (k <= i): + mult = mult*(x - self.data[k][0]) + k += 1 + + y += d[i+1][0]*mult + i += 1 + + return y \ No newline at end of file diff --git a/build/lib/Otter/__init__.py b/build/lib/Otter/__init__.py new file mode 100644 index 0000000..4132067 --- /dev/null +++ b/build/lib/Otter/__init__.py @@ -0,0 +1,2 @@ +from .Otter import Algebra as algebra +from .Otter import Interpolation as interpolation \ No newline at end of file diff --git a/dist/yoshi-otter-1.1.tar.gz b/dist/yoshi-otter-1.1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8d832a9809ae951ec127976b8c73fe3e465ee99f GIT binary patch literal 4975 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 literal 0 HcmV?d00001 diff --git a/setup.py b/setup.py index bedab02..6da5b64 100644 --- a/setup.py +++ b/setup.py @@ -4,11 +4,11 @@ with open("README.md", "r") as fh: long_description = fh.read() setuptools.setup( - name="Otter", # Replace with your own username - version="1.0", + name="yoshi-otter", # Replace with your own username + version="1.1", author="Vitor Hideyoshi", author_email="vitor.h.n.batista@gmail.com", - description="Algebra Functions Python Module for Numeric Calculus", + description="Numeric Calculus python module in the topic of Algebra Functions", long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/HideyoshiNakazone/Otter-NumericCalculus.git", @@ -23,5 +23,6 @@ setuptools.setup( install_requires=[ 'numpy', 'pandas', + 'yoshi-seals' ], ) \ No newline at end of file diff --git a/yoshi_otter.egg-info/PKG-INFO b/yoshi_otter.egg-info/PKG-INFO new file mode 100644 index 0000000..b2d399e --- /dev/null +++ b/yoshi_otter.egg-info/PKG-INFO @@ -0,0 +1,91 @@ +Metadata-Version: 2.1 +Name: yoshi-otter +Version: 1.1 +Summary: Numeric Calculus python module in the topic of Algebra Functions +Home-page: https://github.com/HideyoshiNakazone/Otter-NumericCalculus.git +Author: Vitor Hideyoshi +Author-email: vitor.h.n.batista@gmail.com +License: UNKNOWN +Description: # Otter - Numeric Calculus + + This python package is made for applied Numeric Calculus of Algebra Functions. It is made with the following objectives in mind: + + * Receive one variable function from user input + + * Receive two variable function from user input + + * Performe derivatives with one variable functions + + * Performe integral with received functions + + * Use methods to proccess the matrices. + + * Find root of functions throw method of bissection and method of newton + + * Solve Diferential Equations throw method of euler and runge + + * Performe Minimus Interpolation and Polinomial Interpolation + + ## Syntax + + To initialize a Otter instance linked to functions use the following syntax `otr = Otter.algebra(f)`, where `otr` will be a arbitrary name for the instance and `f` is a function of *one variable*. + + To initialize a Otter instance linked to data and interpolation use the following syntax `otr = Otter.interpolation(data)`, where `otr` will be a arbitrary name for the instance and data will be a *numpy* matrix where the first columns has to contain the values for `x` and the second column contains the values for `y`. + + ### Algebra + + Algebra is a Python Class where some of the features described previously are defined as Classes as well, like: `Integral`, `Roots`, `EDO` (diferential equations). + + #### Integral + + To call the class *Integral* append the sufix with lower case in front of the instance like: `otr.integral`. The Integral class has two other class defined inside, `Simple` and `Double`, to call them append the sufix with lower case in front as `otr.integral.simple` or `otr.integral.double`. Then pick between Riemann's Method or Simpson's Method by appending the sufix `riemann` or `simpson` as well. + + After that the syntax will be something like `otr.integral.double.riemann(a,b,c,d,n,m)`, where `a` and `c` will be the first value of the interval of integration respectively in x and y, `b` and `d` will be the last, `n` and `m` will be the number of partitions. + + The syntax for one variable integrations will be `otr.integral.simple.riemann(a,b,n)`. + + If `n` is not defined the standart value in 10^6 partitions for one variable and 10^4 for double. And if `m` is not defined the standart value will be equal to `n`. + + #### Roots + + To call the class *Root* append the sufix with lower case in front of the instance like: `otr.roots`. The Roots class has three methods defined inside, `bissec`, `newton` and `bissec_newton`, to call them append the sufix with lower case in front as `otr.roots.bissec` or `otr.roots.newton` or even `otr.roots.bissecnewton`. + + The syntax for the bissection method and bissec_newton is equal to `otr.roots.bissec(a,b,e)` and `otr.roots.bissec_newton(a,b,e)`, where `a` is the first element of the interval containing the root and `b` is the last, `e` being the precision. + + The syntax for the newton method is equal to `otr.roots.newton(a,e)`, where `a` is the element closest to the root and `e` is the precision. + + If `e` is not defined the standart value is 10^(-6). + + #### Diferential Equations + + To call the class *EDO* (*E*quações *D*iferenciais *O*rdinárias) append the sufix with lower case in front of the instance like: `otr.edo`. The *EDO* class has two methods defined inside: `euler` and `runge`, to call them append the sufix with lower case in front as `otr.edo.euler` or `otr.edo.runge`. + + The syntax for the diferential equations method is equal to `otr.edo.euler(a,y,b,n)` or `otr.edo.runge(a,y,b,n)`, where `a` and `y` will be the inintial point and `b` is the value in *x* which you want to know the corresponding value in *y* and `n` is the number of operations. + + If `n` is not defined the standart value is 10^7. + + ### Interpolation + + The python class *Interpolation* is divided in one method, minimus interpolation, and one class, polinomial interpolation. + + To call the method *minimus* use a syntax like `otr = Otter.interpolation(data)`, where `otr` is an instance and append the method in front of the instance like: `otr.minimus(x)`, where *x* is value of *f(x)* you want to estimate. + + To call the class *Polinomial* append the sufix with lower case in front of the instance like: `otr.polinomial`. The *Polinomial* class has four methods defined inside: `vandermonde`, `lagrange`, `newton` and `gregory`, to call them append the sufix with lower case in front like `otr.edo.gregory(x)` where *x* is value of *f(x)* you want to estimate. + + ## Installation + + To install the package from source `cd` into the directory and run: + + `pip install .` + + or run + + `pip install otter` + +Platform: UNKNOWN +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2) +Classifier: Operating System :: OS Independent +Classifier: Development Status :: 2 - Pre-Alpha +Requires-Python: >=3.6 +Description-Content-Type: text/markdown diff --git a/yoshi_otter.egg-info/SOURCES.txt b/yoshi_otter.egg-info/SOURCES.txt new file mode 100644 index 0000000..5dc205c --- /dev/null +++ b/yoshi_otter.egg-info/SOURCES.txt @@ -0,0 +1,9 @@ +README.md +setup.py +Otter/Otter.py +Otter/__init__.py +yoshi_otter.egg-info/PKG-INFO +yoshi_otter.egg-info/SOURCES.txt +yoshi_otter.egg-info/dependency_links.txt +yoshi_otter.egg-info/requires.txt +yoshi_otter.egg-info/top_level.txt \ No newline at end of file diff --git a/yoshi_otter.egg-info/dependency_links.txt b/yoshi_otter.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/yoshi_otter.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/yoshi_otter.egg-info/requires.txt b/yoshi_otter.egg-info/requires.txt new file mode 100644 index 0000000..11c1c26 --- /dev/null +++ b/yoshi_otter.egg-info/requires.txt @@ -0,0 +1,3 @@ +numpy +pandas +yoshi-seals diff --git a/yoshi_otter.egg-info/top_level.txt b/yoshi_otter.egg-info/top_level.txt new file mode 100644 index 0000000..ccaaf54 --- /dev/null +++ b/yoshi_otter.egg-info/top_level.txt @@ -0,0 +1 @@ +Otter