def Orinignal_fun(matrix1, matrix2, matrix3, matrix4):
    solve3 = []
    for i in range(t + k + 1):
        solve3.append(matrix_x[((t + 2 * k + 1) - 1) - i][0])
    solve4 = list(P(np.array(solve3)) // P(np.array(matrix4)))
    solve5 = np.poly1d(np.round(solve4))
    return solve5
Beispiel #2
0
def polynomial_div_modN(dividend, divisor, N):
    #print("dividend:",dividend)
    #print("divisor :",divisor)
    acc = P(0)
    while True:
        dividend = poly_modN(dividend, N)
        divisor = poly_modN(divisor, N)
        deg_diff = dividend.degree() - divisor.degree()
        if (deg_diff < 0 or dividend == P(0)):
            return acc, dividend
        else:
            if inv_mod_N(divisor.coef[-1], N) == N:  # No Inverse Flag
                coef = dividend.coef[-1] / divisor.coef[-1]
            else:  # coef must be coprime to N
                coef = dividend.coef[-1] * inv_mod_N(divisor.coef[-1], N)
#            print('inverse  of',divisor.coef[-1],':',coef)

            mult = [0] * (deg_diff + 1)  # from x^deg_diff to x^0
            mult[-1] = coef
            poly_mult = P(mult)
            acc += poly_mult
            #acc = poly_modN(acc,N)
            #print(" A  ",dividend.coef)
            #print("-B: ",poly_modN(poly_mult*divisor,N).coef,'=',poly_mult.coef,'x',divisor.coef)
            dividend = dividend - poly_mult * divisor
def P_n(n):
    P0 = P([1])
    P1 = P([0, 2])
    Pnm1, Pn = P0, P1
    for i in range(n):
        Pnext = (2 * X * Pn) - Pnm1
        Pnm1, Pn = Pn, Pnext
    return Pnm1
def Orinignal_fun(matrix1, matrix2, matrix3, matrix4):
    for i in range(t + k + 1):
        solve3.append(matrix_x[((t + 2 * k + 1) - 1) - i][0])
    solve4 = list(P(np.array(solve3)) // P(np.array(matrix4)))
    solve5 = np.poly1d(solve4)
    for i in range(num_e):
        matrix3[matrix2[i] - 1] = int(round(solve5(matrix2[i])))
    return matrix3, solve5
Beispiel #5
0
def main():
    N = 11
    q = 32
    irr_l    =  [-1,0,0,0,0,0,0,0,0,0,0,1]
    f_inv_q  =  [5,9,6,16,4,15,16,22,20,18,30]
    f        =  [-1,1,1,0,-1,0,1,0,0,1,-1]
    check    =  poly_ring_mult_over_q_with_irr(P(f),P(f_inv_q),P(irr_l),q)
    print("check:", check)
Beispiel #6
0
def diceMath(x):
  diceSize = 6
  diceQuantity = x
  dropLowest = False
  diceTotal = diceSize**diceQuantity
  diceRange = diceSize*x
  a = diceSize + 1

  if(dropLowest == True):
    diceMin = (diceSize - diceSize +1)*(diceQuantity-1)
    diceMax = (diceQuantity-1)*diceSize
    
  if(dropLowest == False):
    diceMin = (diceSize - diceSize +1)*(diceQuantity)
    diceMax = (diceQuantity)*diceSize 

  refList = [[0]*a for i in range(a)]
  masterList = [[0]] * a
  powerList = [[]] * a
  diffList = [[]] * a
  sumList = 0
  oddsList = [0] * (diceRange+1)

  for x in range(0, a-1):
    refList[x][x+1] = 1
    refList[x] = P(refList[x])

  for x in range(0, a):
    tempList = [0] * (x +1)
    tempListOne = [1] * (a - x - 1)
    masterList[x] = tempList + tempListOne

  for x in range(0, a):
    powerList[x] = (P(masterList[x]))**diceQuantity


  if(dropLowest == True):
    for x in range(0, a-1):
      diffList[x] = ((powerList[x] - powerList[x+1])//refList[x])

    for x in range(0, a-1):
      sumList += diffList[x]

  if(dropLowest == False):
    sumList = powerList[0]


  for x in range(diceMin, diceMax+1):
    #  oddsList[x] = round(sumList.coef[x]/diceTotal, 4)*100
    oddsList[x] = round(sumList.coef[x])

  
  return(oddsList)
def BellC(x, j):
    """ Defines the complete ordinary Bell polynomial recursively. """
    indices = [i for i in x.j() if F(i) <= j]
    indices = [(p, q) for p, q in nloop(indices, 2) if p != 0 and p + q == j]
    if indices:
        s = sum(p / j * BellC(x, q) * x[p] for p, q in indices if x[p] != P(0))
        if s == 0:
            return P(0.)
        else:
            return s
    else:
        return P(1)
Beispiel #8
0
 def F(self, y, j):
     N, phi, h, v = y
     indices = v.j()
     return numpy.array([
         P(0),
         P(0),
         self.V(phi, j) / 3. -
         sum(h[p] * h[q] + v[p] * v[q] / 3.
             for p, q in nloop(indices, 2) if p != j != q and p + q == j),
         -self.dVdphi(phi, j) - 3 *
         sum(h[p] * v[q]
             for p, q in nloop(indices, 2) if p != j != q and p + q == j),
     ])
Beispiel #9
0
def background_polynomials(x, list_coefficients=0.0):
    r"""
    Polynomials of variable `w` and with coefficients contained in
    'list_coefficients'

    Parameters
    ----------

    x: list or :class:`~numpy:numpy.ndarray`
        domain of the function

    list_coefficients: list or float
        list of coefficients for the polynomials in ascending order, i.e.
        the first element is the coefficient for the constant term.
        Default to 0 (no background).

    Return
    ------
    `numpy.float64` or :class:`~numpy:numpy.ndarray`
        output number or array

    Examples
    --------
    >>> background_polynomials(5, 1)
    1.0

    >>> background_polynomials(5, [1, 2])
    11.0

    >>> background_polynomials([1,2,3], [1,2,3])
    array([ 6., 17., 34.])


    Mathematically, `background_polynomials(x, [1,2,3])` corresponds to
    :math: 1 + 2x + 3x^2.
    """

    x = np.asarray(x)

    # check that list_coeff is a list and all elements are numbers
    if isinstance(list_coefficients, list) and \
            all(isinstance(w, (int, float)) for w in list_coefficients):

        return P(list_coefficients)(x)

    elif isinstance(list_coefficients, (int, float)):

        return P(list_coefficients)(x)

    else:
        raise ValueError('problem with input')
def parse(rpn):
  """
  Parses a string of RPN.
  
  :param rpn: The RPN formatted string.
  :type rpn: str
  
  :return: A :class:`numpy.polynomial.Polynomial` object.
  :rtype: :class:`numpy.polynomial.Polynomial`
  """
  # Initialise stack
  stack = []
  # Set default pronumeral as x
  pronumeral = 'x'
  
  # Loop through each character
  for character in rpn.split():
    # Check if character is an operator
    if character in OPERATORS:
      # Pop last two items off stack
      term1 = stack.pop(-2)
      term2 = stack.pop(-1)
      
      # Apply operations as needed and append result to stack
      if character == OPERATORS[0]:
        stack.append(term1 + term2)
        
      elif character == OPERATORS[1]:
        stack.append(term1 - term2)
        
      elif character == OPERATORS[2]:
        stack.append(term1 * term2)
        
      elif character == OPERATORS[3]:
        # Here a Polynomial can only be raised to a power of an integer
        stack.append(term1 ** term2.coef[0])
    
    else:
      # If not an operator, try as an integer
      try:
        # Append polynomial as integer to stack
        stack.append(P([int(character)]))
      except:
        # Append polynomial as just pronumeral to stack and set pronumeral
        pronumeral = character
        stack.append(P([0, 1]))
  
  # Return stack and pronumeral
  return stack, pronumeral
Beispiel #11
0
def irr(CashFlow, all=False):
    """
    irr - Internal Rate of Return
    
    :param CashFlow: A list with the cash flow stream
    :return: A list containing the internal rate of return 
    
    Example:
    
        >>> irr([-100000, 10000, 20000, 30000, 40000, 50000])
        [0.12005761954196337]
    
    From: http://www.mathworks.com/help/finance/irr.html
    """
    from numpy.polynomial import Polynomial as P
    from numpy import isreal

    roots = P(CashFlow).roots()
    # roots = [float(r) for r in roots if isreal(r)]

    if not all:
        roots = [r for r in roots if isreal(r) and r > 0]
        roots = list(map(float, roots))

    r2i = lambda r: 1 / r - 1

    i = list(map(r2i, roots))

    return i
Beispiel #12
0
def data_discrete(x_values, y_values, n):
    coeficients = []
    b_matrix = np.ndarray(shape=(n + 1, n + 1), dtype='float')
    c_matrix = np.ndarray(shape=(n + 1, 1), dtype='float')
    i = 0
    while i <= n:
        j = 0
        c_value = 0
        while j <= n:
            b_value = 0
            for m in range(len(x_values)):
                b_value += (x_values[m])**(i + j)
            b_matrix[i][j] = b_value
            j += 1
        for a in range(len(y_values)):
            c_value += (x_values[a])**i * y_values[a]
        c_matrix[i][0] = c_value
        i += 1
    #print(b_matrix)
    #print(c_matrix)
    a_values = la.solve(b_matrix, c_matrix)
    for p in range(len(a_values)):
        coeficients.append(a_values[p][0])
    p_f = P(coeficients)
    return p_f
Beispiel #13
0
def graficoLagrange(pontos, valor):
    Pn = 0
    for i in range(len(pontos)):
        mult = 1
        div = 1
        for j in range(len(pontos)):
            if i == j: continue
            mult *= P([-pontos[j][0], 1])
            div *= pontos[i][0] - pontos[j][0]
        Pn = Pn + pontos[i][1] * (mult // div)
    
    fig, ax = plt.subplots()
    z = np.arange(-4,4,0.01)
    
    y = []
    for i in range(len(z)):
        y.append(Pn(z[i]))

    a = []
    w = []
    for i in range(len(pontos)):
        a.append(pontos[i][0])
        w.append(pontos[i][1])

    ax.plot(z,y, label='Polinômio Interpolador P(x)')
    ax.plot(a,w, "r*", markersize=6, label="Pontos da tabela")
    ax.plot(valor,Pn(valor), "g*", markersize=6, label="Estimativa")
    ax.legend()
    ax.grid()
    plt.show()
Beispiel #14
0
def extract_coefficients_algebraically(regex, what = None, threshold = 1e-3):
    ast = transfer(regex, what)
    # rationalize(regex) = overflow(z) + top(z)/bottom(z), where the quotient is irreducible.
    overflow, (top, bottom) = simplify(*rationalize(ast))
    pow, _ = leading_term(bottom)
    # Express our bottom polynomial as a numpy polynomial-vector.
    polynomial = P([bottom[k] if k in bottom else 0 for k in range(pow + 1)])

    # Compute, refine, and custer the roots
    roots = polynomial.roots()
    roots = newton(polynomial, roots)
    roots = closed_form(polynomial, roots)
    clusters = cluster_roots(polynomial, roots, threshold=threshold)

    # roots of multiplicity k has expanded form binom[n+k-1,k-1] * (r)**(-n - k) * (-1)**k
    if len(roots):
        degree = len(roots)
        # This is the generator for the extended Vandermonde matrix augmented with the multiplicity of a root
        basis = lambda n: array(
            [comb(n + k - 1, k - 1) * (-1)**k * (root)**(-n - k) for (root, k) in collate(clusters)])
        vandermonde_matrix = array([basis(n) for n in range(degree)])
        target = array([exact(regex, n, what=what, use_overflow=False) for n in range(degree)])
        partial_coefficients = solve(vandermonde_matrix, target)

        return (
            # A function that computes the coefficient for n
            (lambda n: abs(basis(n).dot(partial_coefficients)) + (overflow[n] if n in overflow else 0)),
            # internal states to reconstruct the closed form enumeration
            (dict(clusters), basis, partial_coefficients, polynomial, (overflow, (top, bottom)))
        )
    else:
        return (
            (lambda n: overflow[n] if n in overflow else 0),
            (dict(clusters), (lambda n: []), array([]), polynomial, (overflow, (top, bottom)))
        )
Beispiel #15
0
 def dVdphi(self, phi, j):
     ans = P(0)
     if j >= 2:
         ans = ans + self.m**2 * phi[j - 2]
         ans = ans + self.l / 6. * sum(phi[p] * phi[q] * phi[r]
                                       for p, q, r in nloop(indices, 3)
                                       if p + q == j - 2)
     return ans
Beispiel #16
0
 def V(self, phi, j):
     indices = phi.j()
     ans = P(0)
     if j >= 2:
         ans = ans + 1. / 2 * self.m**2 * sum(phi[p] * phi[q]
                                              for p, q in nloop(indices, 2)
                                              if p + q == j - 2)
     return ans
Beispiel #17
0
def LinearRegressionTraining(
    path,
    alpha=ALPHA_LinearRegressionTraining,
    n_iterations=MAX_ITER_LinearRegressionTraining,
    output_name=OUTPUT_PREFIX_0,
    feature_type=NO_FEATURE_TYPE,
    feature_val=1.0,
):
    (x, orig_x), y, (X_train, orig_x_train), (
        X_test,
        orig_x_test,
    ), y_train, y_test = matrix_to_train_test(path=path,
                                              feature_type=feature_type,
                                              feature_val=feature_val)

    # Model initialization
    regression_model = LinearRegressionGD(alpha, n_iterations)
    regression_model.fit(X_train, y_train)

    # Predict
    y_predicted = regression_model.predict(x)
    y_predicted_train = regression_model.predict(X_train)
    y_predicted_test = regression_model.predict(X_test)

    # Model evaluation training data
    rmse = mean_squared_error(y_train, y_predicted_train)
    r2 = r2_score(y_train, y_predicted_train)
    print("[Training Set] Root mean squared error: ", rmse)
    print("[Training Set] R2 score: ", r2)

    # Model evaluation test data
    rmse = mean_squared_error(y_test, y_predicted_test)
    r2 = r2_score(y_test, y_predicted_test)
    print("[Test Set] Root mean squared error: ", rmse)
    print("[Test Set] R2 score: ", r2)

    orig_y_train = y_train.flatten()
    orig_y_test = y_test.flatten()

    # Data points
    plt.scatter(orig_x_train, orig_y_train, s=20, color="b")
    plt.scatter(orig_x_test, orig_y_test, s=40, color="r")
    plt.xlabel("Input size")
    plt.ylabel("Time (seconds)")

    # Plotting predicted values
    orig_x = orig_x.flatten()

    # Predicted values
    y_predicted = y_predicted.flatten()
    plt.plot(orig_x, y_predicted, color="g")
    plt.legend(["Regression line", "Train data", "Test data"])
    plt.title(polynomial_to_LaTeX(P(regression_model.w_.flatten())))

    # Return figure
    plt.savefig(output_name)

    plt.close()
Beispiel #18
0
 def find_roots(self, numpol):
     print " i am numpol\n", numpol
     p = P(numpol)
     z = p.roots()
     self.zreal = z.real
     self.zimag = z.imag
     del self.rev[:]
     print "i am real root\n", self.zreal
     print " i am imaginary root\n", self.zimag
Beispiel #19
0
def polynomial_div_modN(dividend, divisor, N):
    acc = P(0)
    while True:
        dividend = poly_modN(dividend, N)
        divisor = poly_modN(divisor, N)
        deg_diff = dividend.degree() - divisor.degree()
        if (deg_diff < 0 or dividend == P(0)):
            return acc, dividend
        else:
            coef = dividend.coef[-1] * inv_mod_N(divisor.coef[-1], N)
            mult = [0] * (deg_diff + 1)
            mult[-1] = coef
            poly_mult = P(mult)
            acc += poly_mult
            acc = poly_modN(acc, N)
            print(" A  ", dividend.coef)
            print("-B: ", (poly_mult * divisor).coef)
            dividend = dividend - poly_mult * divisor
Beispiel #20
0
def applyginv(pointlist, vars, coef):
    if vars == 1:
        p = P(coef)
        for term in pointlist:
            term[2] = term[2] - p(term[0])
    if vars == 2:
        for term in pointlist:
            term[2] = term[2] - p2d(term[0], term[1], coef)

    return pointlist
Beispiel #21
0
def g(word, rc, s_box):
    # This function implements the g-box which is in the key schedules for all key sizes
    # Input: 32-bit Word in polynomial format, current round coefficient ,SBox
    # Output: Result of the h-box operation (32-bit Word in polynomial format)
    first_byte = ''.join([str(int(elem)) for elem in word.coef[0:8][::-1]])
    second_byte = ''.join([str(int(elem)) for elem in word.coef[8:16][::-1]])
    third_byte = ''.join([str(int(elem)) for elem in word.coef[16:24][::-1]])
    fourth_byte = ''.join([str(int(elem)) for elem in word.coef[24:32][::-1]])
    (first_byte, second_byte, third_byte, fourth_byte) = \
        (s_box[second_byte], s_box[third_byte], s_box[fourth_byte], s_box[first_byte])
    new_word = P([int(bit) for bit in first_byte[::-1]] +
                 [int(bit) for bit in second_byte[::-1]] +
                 [int(bit) for bit in third_byte[::-1]] +
                 [int(bit) for bit in fourth_byte[::-1]])
    temp = P(new_word.coef[0:8]) + rc
    temp = reduce_galois(temp.coef)
    for i in range(8 - len(temp)):
        temp.append(0)
    new_word.coef[0:8] = temp
    return new_word
Beispiel #22
0
 def dVdphi(self, phi, j):
     ans = P(0)
     Phi_p = numpy.exp(-phi[0].coef[0] * sqrt(2. / 3))
     s = F(2 * int(numpy.sign(phi[0].coef[1])), 3)
     if j >= 2 - s:
         ans = ans + 2 * sqrt(2. / 3) * Phi_p * BellC(
             -sqrt(2. / 3) * phi, j - (2 - s))
     if j >= 2 - 2 * s:
         ans = ans - 2 * sqrt(2. / 3) * Phi_p**2 * BellC(
             -2 * sqrt(2. / 3) * phi, j - (2 - 2 * s))
     return ans * self.L**4
Beispiel #23
0
 def V(self, phi, j):
     indices = phi.j()
     ans = P(0)
     if j == 2:
         ans = ans + self.L
     if j >= 2:
         ans = ans + 1. / 2 * self.m**2 * sum(phi[p] * phi[q]
                                              for p, q in nloop(indices, 2)
                                              if p + q == j - 2)
         ans = ans + 1. / 24 * self.l * sum(
             phi[p] * phi[q] * phi[r] * phi[s]
             for p, q, r, s in nloop(indices, 4) if p + q == j - 2)
     return ans
Beispiel #24
0
    def CalculateRoots(self):
        A = self.A
        B = self.B
        C = self.C

        from numpy.polynomial import Polynomial as P
        x0 = B
        x1 = 1.j * C * math.sqrt(math.pi)
        x2 = A
        x3 = -C * math.sqrt(math.pi)
        x4 = 1.0
        p = P([x0, x1, x2, x3, x4])

        self.roots = p.roots()
Beispiel #25
0
    def fit(self, data, centers):
        X = np.empty((len(data), self.deg + 1))
        X[:, 0] = 1
        for p in range(1, self.deg + 1):
            X[:, p] = np.power(centers, p)
        self.results = sm.OLS(data, X).fit()
        self.poly = P(self.results.params)

        # copy the fit parameters to a dictionary where the
        # coefficients are labeled a0, a1...
        self.params = {}
        for i in range(self.deg + 1):
            param_name = 'a%d' % i
            self.params[param_name] = self.results.params[i]
Beispiel #26
0
def h(word, s_box):
    # This function implements the h-box which is in the key schedule of the AES-256
    # Input: 32-bit Word in polynomial format, SBox
    # Output: Result of the h-box operation (32-bit Word in polynomial format)
    first_byte = ''.join([str(int(elem)) for elem in word.coef[0:8][::-1]])
    second_byte = ''.join([str(int(elem)) for elem in word.coef[8:16][::-1]])
    third_byte = ''.join([str(int(elem)) for elem in word.coef[16:24][::-1]])
    fourth_byte = ''.join([str(int(elem)) for elem in word.coef[24:32][::-1]])
    (first_byte, second_byte, third_byte, fourth_byte) = \
        (s_box[first_byte], s_box[second_byte], s_box[third_byte], s_box[fourth_byte])
    new_word = P([int(bit) for bit in first_byte[::-1]] +
                 [int(bit) for bit in second_byte[::-1]] +
                 [int(bit) for bit in third_byte[::-1]] +
                 [int(bit) for bit in fourth_byte[::-1]])
    return new_word
Beispiel #27
0
def get_poly_baseline(mspec, k_est, debug=True, **kwargs):
    """
    Fit for the best polynomial baseline according to BIC
    
    Search polynomial fits from order 0 to order 7 and
    use the BIC to select the best fit. This fit should 
    also have an rms error within a factor of two of 
    the estimated noise (k_est). If this is not the case
    then the baseline fit is most likely bad. 
    """
    d = np.arange(0, 7)
    rms_err = np.zeros(d.shape)
    all_polys = []
    #k_est = 0.2/np.sqrt(7)
    xx = np.arange(mspec.size)
    yy = mspec

    for i in range(len(d)):
        p = ma.polyfit(xx, yy, d[i])
        basepoly = P(p[::-1])
        all_polys.append(basepoly)
        rms_err[i] = np.sqrt(np.sum((basepoly(xx) - yy)**2) / len(yy))
    BIC = np.sqrt(len(yy)) * rms_err / k_est + 1 * d * np.log(len(yy))
    AIC = np.sqrt(len(yy)) * rms_err / k_est + 2 * d + 2 * d * (d + 1) / (
        len(yy) - d - 1)

    if debug:
        fig = plt.figure(figsize=(12, 5))
        ax = fig.add_subplot(311)
        ax.plot(d, rms_err, '-k', label='rms-err')
        ax.legend(loc=2)
        ax.axhline(k_est * 2., ls=":", color='r')
        ax.axhline(k_est, color='red')
        ax.axhline(k_est / 2., ls=':', color='r')

        ax = fig.add_subplot(312)
        ax.plot(d, BIC, '-k', label='BIC')
        ax.legend(loc=2)
        ax = fig.add_subplot(313)
        ax.plot(d, AIC, '-r', label='AIC')
        ax.legend(loc=2)

        plt.savefig(kwargs["outdir"] + "/debugplot.png")

        plt.close(fig)
    best_poly_order = np.argmin(AIC)
    best_poly = all_polys[best_poly_order]
    return (best_poly(xx))
Beispiel #28
0
def pwc_function_approximation(linear_piece: P, left_bound, right_bound,
                               error_tolerance):
    if linear_piece.degree() <= 0:
        return [linear_piece], [left_bound, right_bound]
    elif linear_piece.degree() >= 2:
        print(linear_piece)
        raise ValueError('The function must be constant or linear.')
    a = linear_piece.coef[-1]
    piece_num = math.ceil(
        (math.fabs(a) * (right_bound - left_bound)) / (2 * error_tolerance))
    delta_x = (right_bound - left_bound) / piece_num
    pwc_result = []
    bounds_result = [left_bound]
    for i in range(0, piece_num):
        pwc_result.append(P([linear_piece(left_bound + (i - 0.5) * delta_x)]))
        bounds_result.append(left_bound + (i + 1) * delta_x)
    return pwc_result, bounds_result
Beispiel #29
0
def read_key(key_string):
    # This function reads a binary key in string format and it is out is a polynomial
    # split into words if size 32 bits
    # Input: Key in string format Output: Key in Polynomial format split into words
    key = []
    if len(key_string) == 128:
        ind_array = [0, 4, 8, 12]
    elif len(key_string) == 192:
        ind_array = [0, 4, 8, 12, 16, 20]
    elif len(key_string) == 256:
        ind_array = [0, 4, 8, 12, 16, 20, 24, 28]
    for j in ind_array:
        key.append(
            P([
                int(bit) for i in range(j, j + 4)
                for bit in key_string[i * 8:(i + 1) * 8][::-1]
            ]))
    return key
Beispiel #30
0
def getNumInvSubs(matrix):
    """
	:mat : Matrix - Matrix representation of a linear transformation on Complex Vector Space V -> V.
	
	Takes the Matrix representation of a linear transformation T on an n-dimensional Vector Space V to V and returns an integer representing the number of T-invariant subspaces that exist on that Vector Space. If the characteristic polynomial of T splits, the result is the sum of combinations of all distinct eigenvalues (n k) for all 0 <= k <= n, which is 2 ** n, 2 if the characteristic polynomial does not split (which should never happen in a complex vector space), or 1 if V is the 0 vector space.
	"""
    if matrix.n == 0:
        return 1
    cp = matrix.charPoly()
    factorDict = linearFactor(cp)
    print(factorDict)
    if factorDict["r_"] == P([complex(0, 0)]):
        numESpaces = 0
        keys = list(factorDict.keys())
        keys.remove("r_")
        for eval in keys:
            numESpaces += getDimESpace(matrix, eval)
        return 2**numESpaces
    return 2