"""
Project: PolySolvy Version X
Math 351 - Numerical Analysis
Under the instruction of Professor Eric Merchant

Team: Nathan, Jaeger, Ronnie

File Description:

bivariate.py takes a vector of coeffs generated by vmond.py for
a bivariate interpolating polynomial. It implements a naive function Bivariate() which combines the
coefficients contained in the vector with the appropriate (x^n)(y^n) terms to output a z-value
for a given x and y value. Specific procedure is included in function docstring.
"""
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def Bivariate(v_vector: np.array, x: np.double, y: np.double):
    """
    A function that iterates through a vector of polynomial coefficients and multiplies them
    with the corresponding (x^n)(y^n) term. In this case, the index of the vector (as translated from a matrix of r-rows and c-columns)
    corresponds to the powers on x and y.
    
    param: v_vector: a vector of type np.array which contains the coefficients for the interpolating polynomial
    param: x: an x value of type np.double to be used in determining the z value at a point
    param: y: a y value of type np.double to be used in determining the z value at a point
   
   return: None if v_vector is empty, otherwise return the polynomial evaluated at (x) and (y), return type should
            be np.double. This is evaluated as:
            v_matrix[0]*(x^0)*(y^0) + v_matrix[1]*(x^0)*(y^1) + ... + v_matrix[n-1]*(x^(n-1))*(y^(n-1))
                 
    Ex/
    >>> v_vector = np.array([1, 2, 3, 4])  
    >>> Bivariate(v_vector, 1, 1)
    10
    >>> Bivariate(v_vector, 3,4)
    66
    """
    length = len(v_vector)  
    if length == 0:
        return None

    z = np.double(0)

    #initial powers on x and y
    c = 0
    r = 0
    for i in range(length):
        # During iteration through vector (a 1D array) need to increase powers on x as though iterating over rows and columns
        # this can be done by incrementing power on x each time we would have encountered a new row, and resetting powers on y accordingly
        
        #if at a new row index
        if ((i + 1) % math.sqrt(length)) == 0:
            z += v_vector[i]*(x**r)*(y**c)
            r += 1
            c = 0
        else:
            z += v_vector[i]*(x**r)*(y**c)
            c += 1
    return z


