Example #1
0
 def transpose(self):
     from alc.utils import zeros
     new_arr = zeros((self.shape[1], self.shape[0]))
     for i in range(self.shape[1]):
         for j in range(self.shape[0]):
             new_arr[i][j] = self.__iterable[j][i]
     return new_arr
Example #2
0
def forwardsub (L, B):
  # Initialize y
  y = zeros((L.shape[0], B.shape[1]))
  n = L.shape[0]
  # Forward sub
  y[0][0] = B[0][0] / L[0][0]
  for i in range(1, n):
    y[i][0] = B[i][0]
    for j in range(0, i):
      y[i][0] -= L[i][j]*y[j][0]
    y[i][0] /= L[i][i]
  return y
Example #3
0
def retrosub (A, B):
  # Initialize x
  x = zeros((A.shape[0], B.shape[1]))
  n = A.shape[0]
  # Retro-substitution
  x[n-1] = [B[n-1][0]/A[n-1][n-1]]
  for i in range(n-2, -1, -1):
    x[i][0] = B[i][0]
    for j in range(i+1, n):
      x[i][0] -= A[i][j]*x[j][0]
    x[i][0] /= A[i][i]
  return x
Example #4
0
 def __matmul(self, mat1, mat2):
     from alc.utils import zeros
     try:
         assert mat1.shape[1] == mat2.shape[0]
     except AssertionError:
         raise AssertionError(
             "Matrices can't be multiplied with shapes {} and {}".format(
                 mat1.shape, mat2.shape))
     result = zeros((mat1.shape[0], mat2.shape[1]))
     for i in range(mat1.shape[0]):
         for j in range(mat2.shape[1]):
             for k in range(mat2.shape[0]):
                 result[i][j] += mat1[i][k] * mat2[k][j]
             if (abs(result[i][j]) <= constants.epsilon):
                 result[i][j] = 0.0
     return result
Example #5
0
def solve (A, B, method='gauss', threshold=constants.epsilon):
  if method == "gauss":
    # Turn A into an upper triangular matrix
    A, intermediates = gauss_elimination (A, return_intermediates=True, show_steps=False, return_pivots=False)
    # To keep it an equation, apply transformations to B as well
    for m in intermediates:
      B = m * B
    x = retrosub(A, B)
    return x
  elif method == "gauss_jordan":
    # Turn A into an upper triangular matrix
    A, intermediates = gauss_elimination (A, return_intermediates=True, show_steps=False, return_pivots=False)
    # To keep it an equation, apply transformations to B as well
    for m in intermediates:
      B = m * B
    # Turn A into diagonal matrix
    A, intermediates = gauss_jordan_elimination (A, return_intermediates=True, show_steps=False)
    # Apply transformations to B as well
    for m in intermediates:
      B = m * B
    # Initialize x
    x = zeros((A.shape[0], B.shape[1]))
    # Computing x
    for i in range(A.shape[0]):
      x[i][0] = B[i][0]/A[i][i]
    return x
  elif method == "jacobi":
    x = jacobi(A, B, threshold=threshold)
    return x
  elif method == "gauss_seidel":
    x = gauss_seidel(A, B, threshold=threshold)
    return x
  elif method == "lu":
    L, U = lu_decomposition (A, return_det=False)
    y = forwardsub(L, B)
    x = retrosub(U, y)
    return x
  elif method == "cholesky":
    try:
      L, Lt = cholesky_decomposition(A)
      y = forwardsub(L, B)
      x = retrosub(Lt, y)
      return x
    except ValueError as e:
      raise e
  else:
    raise NameError("Solving method not allowed!")
def cholesky_decomposition(arr):
    from alc.utils import is_definite_positive, is_symmetric
    if (not is_definite_positive(arr) or not is_symmetric(arr)):
        raise ValueError(
            "Não é possível realizar a decomposição de Cholesky. A matriz fornecida não é simétrica positiva definida."
        )
    L = zeros(arr.shape)
    for i in range(arr.shape[0]):
        L[i][i] = arr[i][i]
        for k in range(0, i):
            L[i][i] -= (L[i][k]**2)
        L[i][i] = (L[i][i]**(1 / 2))
        for j in range(i + 1, arr.shape[1]):
            L[j][i] = arr[i][j]
            for k in range(0, i):
                L[j][i] -= (L[i][k] * L[j][k])
            L[j][i] /= L[i][i]
    return L, L.t
Example #7
0
def jacobi(A, B, threshold=constants.epsilon):
    if (not is_diagonally_dominant(A)):
        raise ValueError(
            "A matriz \"A\" não é estritamente diagonal dominante e, portanto, o método de Jacobi não irá convergir!"
        )
    prev_x = random_array(B.shape)
    r = 1000
    n = B.shape[0]
    while (r > threshold):
        x = zeros(B.shape)
        for i in range(x.shape[0]):
            x[i][0] = B[i][0]
            for j in range(0, n):
                if (i != j):
                    x[i][0] -= A[i][j] * prev_x[j][0]
            x[i][0] /= A[i][i]
        r = vector_norm(x - prev_x, 2) / vector_norm(x, 2)
        prev_x = deepcopy(x)
    return x
Example #8
0
def gauss_seidel(A, B, threshold=constants.epsilon):
    if (not is_diagonally_dominant(A)):
        if (not is_definite_positive(A)):
            raise ValueError(
                "A matriz \"A\" não é estritamente diagonal dominante nem positiva definida e, portanto, o método de Gauss-Seidel não irá convergir!"
            )
    prev_x = random_array(B.shape)
    r = 1000
    n = B.shape[0]
    while (r > threshold):
        x = zeros(B.shape)
        for i in range(x.shape[0]):
            x[i][0] = B[i][0]
            for j in range(0, i):
                x[i][0] -= A[i][j] * x[j][0]
            for j in range(i + 1, n):
                x[i][0] -= A[i][j] * prev_x[j][0]
            x[i][0] /= A[i][i]
        r = vector_norm(x - prev_x, 2) / vector_norm(x, 2)
        prev_x = deepcopy(x)
    return x
Example #9
0
def least_squares(x, y):
    # Length of X and Y samples must be the same
    try:
        if (len(x) != len(y)):
            raise ValueError("Length of X and Y samples must be the same!")
    except Exception as e:
        print("Failure while comparing X and Y length")
        raise e
    # Start with ones matrix and then just replace with X values on first column
    P = ones((len(x), 2))
    for i, val in enumerate(x):
        P[i][0] = val
    # Then, turn y samples into an array
    Y = zeros((len(y), 1))
    for i, val in enumerate(y):
        Y[i][0] = val
    # Next, do A = P^T * P, C = P^T * Y
    A = P.t * P
    C = P.t * Y
    # Finally, find B = A^(-1) * C
    B = ~A * C
    # a, b are first and second values of B
    return B[0][0], B[1][0]
Example #10
0
def integrate(function, a, b, n_points=10, method='polynomial'):

    if ((n_points < 1) or (n_points > 10)):
        raise ValueError("n_points must be between 1 and 10")
    x = Symbol('x')
    try:
        f = lambdify(x, eval(function))
    except:
        raise ExpressionError(
            "Falhou ao executar a seguinte função: {}. Favor verificar a expressão."
            .format(function))
    if (n_points == 1):
        return f(abs(a + b) / 2) * (abs(b - a))

    def laguerre_function(x):
        return f(x) / math.exp(-x)

    def hermite_function(x):
        return f(x) / math.exp(-x**2)

    # Getting hermite sum
    sum_hermite = 0
    points = constants.hermite[n_points]['points']
    weights = constants.hermite[n_points]['weights']
    for i in range(n_points):
        sum_hermite += hermite_function(points[i]) * weights[i]

    # Getting laguerre sum
    sum_laguerre = 0
    points = constants.laguerre[n_points]['points']
    weights = constants.laguerre[n_points]['weights']
    for i in range(n_points):
        sum_laguerre += laguerre_function(points[i]) * weights[i]

    if (a == float("-inf")):

        # B is positive infinite
        if (b == float("inf")):
            return sum_hermite

        # B is positive
        elif (b >= 0):
            return sum_hermite - sum_laguerre + integrate(
                function, 0, b, n_points, method='gauss_quadrature')

        # B is negative
        else:
            return sum_hermite - sum_laguerre - integrate(
                function, b, 0, n_points, method='gauss_quadrature')

    elif (b == float("inf")):

        if (a == 0):
            return sum_laguerre

        elif (a > 0):
            return sum_laguerre - integrate(
                function, 0, a, n_points, method='gauss_quadrature')

        else:
            return sum_hermite - sum_laguerre - integrate(
                function, a, 0, n_points, method='gauss_quadrature')

    if (method == 'polynomial'):
        delta_x = abs(b - a) / (n_points - 1)
        B = []
        integration_points = []
        res = 0

        for i in range(1, n_points + 1):
            integration_points.append(a + (i - 1) * delta_x)
            B.append((b**i - a**i) / i)

        vandermonde = zeros((n_points, n_points))
        B = Array([[b] for b in B])

        for i in range(n_points):
            for j in range(n_points):
                vandermonde[i][j] = integration_points[j]**i

        x = solve(vandermonde, B)

        for i in range(n_points):
            res += x[i][0] * f(integration_points[i])

        return res

    elif (method == 'gauss_quadrature'):
        weights = constants.legendre[n_points]['weights']
        points = constants.legendre[n_points]['points']
        L = b - a
        res = 0
        integration_points = []

        for i in range(n_points):
            integration_points.append((a + b + points[i] * L) / 2)

        for i in range(n_points):
            res += f(integration_points[i]) * weights[i]

        return res * L / 2

    else:
        raise NameError("Method {} not allowed.".format(method))