import numpy as np import os from S_polyfit_utils import getBest from S_polyfit_utils import basis_vector import itertools import sys import csv import sympy from sympy import symbols, Add, Mul, S, simplify from scipy.linalg import fractional_matrix_power def mk_sympy_function(coeffs, num_covariates, deg): generators = [basis_vector(num_covariates+1, i) for i in range(num_covariates+1)] powers = map(sum, itertools.combinations_with_replacement(generators, deg)) coeffs = np.round(coeffs,2) xs = (S.One,) + symbols('z0:%d'%num_covariates) if len(coeffs)>1: return Add(*[coeff * Mul(*[x**deg for x, deg in zip(xs, power)]) for power, coeff in zip(powers, coeffs)]) else: return coeffs[0] def polyfit(maxdeg, filename): n_variables = np.loadtxt(filename, dtype='str').shape[1]-1 variables = np.loadtxt(filename, usecols=(0,)) means = [np.mean(variables)] for j in range(1,n_variables): v = np.loadtxt(filename, usecols=(j,)) means = means + [np.mean(v)] variables = np.column_stack((variables,v)) f_dependent = np.loadtxt(filename, usecols=(n_variables,)) if n_variables>1: C_1_2 = fractional_matrix_power(np.cov(variables.T),-1/2) x = [] z = [] for ii in range(len(variables[0])): variables[:,ii] = variables[:,ii] - np.mean(variables[:,ii]) x = x + ["x"+str(ii)] z = z + ["z"+str(ii)] if np.isnan(C_1_2).any()==False: variables = np.matmul(C_1_2,variables.T).T res = getBest(variables,f_dependent,maxdeg) parameters = res[0] params_error = res[1] deg = res[2] x = sympy.Matrix(x) M = sympy.Matrix(C_1_2) b = sympy.Matrix(means) M_x = M*(x-b) eq = mk_sympy_function(parameters,n_variables,deg) symb = sympy.Matrix(z) for i in range(len(symb)): eq = eq.subs(symb[i],M_x[i]) eq = simplify(eq) else: res = getBest(variables,f_dependent,maxdeg) parameters = res[0] params_error = res[1] deg = res[2] eq = mk_sympy_function(parameters,n_variables,deg) for i in range(len(x)): eq = eq.subs(z[i],x[i]) eq = simplify(eq) else: res = getBest(variables,f_dependent,maxdeg) parameters = res[0] params_error = res[1] deg = res[2] eq = mk_sympy_function(parameters,n_variables,deg) try: eq = eq.subs("z0","x0") except: pass return (eq, params_error)