1import c3py # import the python interface to the c3 library 2import numpy as np 3import matplotlib.pyplot as plt 4 5## Define two functions 6def func1(x,param=None): 7 return np.sum(x,axis=1) 8 9def func1_grad(x,param=None): 10 return np.ones(x.shape[1]) 11 12def func2(x,param=None): 13 return np.sin(np.sum(x,axis=1)) 14 15def func2_grad(x): 16 return np.cos(np.sum(x,axis=1)) 17 18dim = 2 # number of features 19ndata = 100 # number of data points 20x = np.random.rand(ndata,dim)*2.0-1.0 # training samples 21y1 = func1(x) # function values 22y2 = func2(x) # ditto 23 24lb = -1 # lower bounds of features 25ub = 1 # upper bounds of features 26nparam = 2 # number of parameters per univariate function 27 28 29## Run a rank-adaptive regression routine to approximate the first function 30ft = c3py.FunctionTrain(dim) 31for ii in range(dim): 32 ft.set_dim_opts(ii,"legendre",lb,ub,nparam) 33ft.build_data_model(ndata, x, y1, alg="AIO", obj="LS", adaptrank=1, 34 kickrank=1, roundtol=1e-10, verbose=0, store_opt_info=False) 35 36 37## Run a fixed-rank regression routine to approximate the second function with stochastic gradient descent 38ft_sgd = c3py.FunctionTrain(dim) 39ranks = [2]*(dim+1) 40ranks[0] = 1 41ranks[dim] = 1 42ft_sgd.set_ranks(ranks) 43for ii in range(dim): 44 ft_sgd.set_dim_opts(ii,"legendre",lb,ub,nparam) 45ft_sgd.build_data_model(ndata,x,y2,alg="AIO",obj="LS",opt_type="SGD",verbose=0) 46 47## Run a fixed-rank regression routine to approximate the second function 48ft2 = c3py.FunctionTrain(dim) 49ranks = [2]*(dim+1) 50ranks[0] = 1 51ranks[dim] = 1 52ft2.set_ranks(ranks) 53for ii in range(dim): 54 ft2.set_dim_opts(ii,"legendre",lb,ub,nparam) 55ft2.build_data_model(ndata,x,y2,alg="AIO",obj="LS",verbose=0) 56 57# ## Select number of parameters through cross validation 58# # ftcv = c3py.FunctionTrain(dim) 59# # ranks = [4]*(dim+1) 60# # ranks[0] = 1 61# # ranks[dim] = 1 62# # ftcv.set_ranks(ranks) 63# # for ii in range(dim): 64# # ftcv.set_dim_opts(ii,"legendre",lb,ub,nparam) 65# # ftcv.build_data_model(ndata,x,y2,alg="AIO",obj="LS_SPARSECORE",\ 66# # cvregweight=[1e-10,1e-8,1e-6,1e-4],kfold=3,verbose=0,cvverbose=2) 67 68 69ft3 = ft + ft2 # add two function-trains 70ft4 = ft * ft2 # multiply to function-trains 71 72## Run adaptive sampling scheme 73ft_adapt = c3py.FunctionTrain(dim) 74for ii in range(dim): 75 ft_adapt.set_dim_opts(ii,"legendre",lb,ub,nparam) 76verbose=0 77init_rank=2 78adapt=1 79ft_adapt.build_approximation(func2,None,init_rank,verbose,adapt) 80 81ft_lin_adapt = c3py.FunctionTrain(dim) 82for ii in range(dim): 83 ft_lin_adapt.set_dim_opts(ii,"linelm",lb,ub,80) 84verbose=0 85init_rank=2 86adapt=1 87ft_lin_adapt.build_approximation(func2,None,init_rank,verbose,adapt) 88 89 90 91ft.save("saving.c3") 92ft_load = c3py.FunctionTrain(0) 93ft_load.load("saving.c3") 94## Generate test point 95test_pt = np.random.rand(dim)*2.0-1.0 96 97 98print("\n\n\n") 99 100print("test_pt = ", test_pt) 101grad = ft.grad_eval(test_pt) 102grad_should = func1_grad(test_pt.reshape((1,dim))) 103print("Grad = ", grad) 104print("should be = ",grad_should) 105 106print("\n\n\n") 107 108 109ft1eval = ft.eval(test_pt) # evaluate the function train 110floadeval = ft_load.eval(test_pt) # evaluate the function train 111ft2eval = ft2.eval(test_pt) 112ft_sgd_eval = ft_sgd.eval(test_pt) 113# ftcveval = ftcv.eval(test_pt) 114ft3eval = ft3.eval(test_pt) 115ft4eval = ft4.eval(test_pt) 116ft_adapt_eval = ft_adapt.eval(test_pt) 117ft_lin_adapt_eval = ft_lin_adapt.eval(test_pt) 118 119eval1s = func1(test_pt.reshape((1,dim))) 120eval2s = func2(test_pt.reshape((1,dim))) 121eval3s = eval1s + eval2s 122eval4s = eval1s * eval2s 123 124 125print("Fteval =",ft1eval, "Should be =",eval1s) 126print("Ft_loadeval =",floadeval, "Should be =",eval1s) 127print("Second function with BFGS: Fteval =",ft2eval, "Should be =",eval2s) 128print("Second function with SGD: Fteval =",ft_sgd_eval, "Should be =",eval2s) 129print("Second function with CrossApproximation: Fteval =",ft_adapt_eval, "Should be =",eval2s) 130print("Second function with CrossApproximation and linear elements: Fteval =",ft_lin_adapt_eval, "Should be =",eval2s) 131# print("Second function with CV: Fteval =",ftcveval, "Should be =",eval2s) 132print("Fteval =",ft3eval, "Should be =",eval3s) 133print("Fteval =",ft4eval, "Should be =",eval4s) 134 135 136print("\n\n\n") 137print("Now getting optimization trajectories, run interactively and then type plt.show()") 138 139dim = 5 # number of features 140ndata = 10000 # number of data points 141x = np.random.rand(ndata,dim)*2.0-1.0 # training samples 142y1 = func2(x) + np.random.randn(ndata)*0.01 # function values 143 144lb = -1 # lower bounds of features 145ub = 1 # upper bounds of features 146nparam = 10 # number of parameters per univariate function 147 148ranks = [2]*(dim+1) 149ranks[0] = 1 150ranks[dim] = 1 151 152ft = c3py.FunctionTrain(dim) 153ft.set_ranks(ranks) 154for ii in range(dim): 155 ft.set_dim_opts(ii,"legendre",lb,ub,nparam) 156opt_ft = ft.build_data_model(ndata, x, y1, alg="AIO", obj="LS", adaptrank=0, verbose=0, store_opt_info=True) 157 158ft_sgd = c3py.FunctionTrain(dim) 159ft_sgd.set_ranks(ranks) 160for ii in range(dim): 161 ft_sgd.set_dim_opts(ii,"legendre",lb,ub,nparam) 162opt_sgd = ft_sgd.build_data_model(ndata, x, y1, alg="AIO", obj="LS", 163 opt_type="SGD", opt_sgd_learn_rate=1e-4, 164 adaptrank=0, verbose=0, opt_maxiter=100, store_opt_info=True) 165 166ft_als = c3py.FunctionTrain(dim) 167ft_als.set_ranks(ranks) 168for ii in range(dim): 169 ft_als.set_dim_opts(ii,"legendre",lb,ub,nparam) 170opt_als = ft_als.build_data_model(ndata, x, y1, alg="ALS", obj="LS", 171 adaptrank=0, verbose=0, store_opt_info=True) 172 173 174plt.figure() 175plt.plot(np.log10(opt_ft), label='AIO') 176plt.plot(np.log10(opt_sgd), label='SGD') 177plt.plot(np.log10(opt_als), label='ALS') 178# plt.semilogy(opt_als, label='ALS') 179plt.legend() 180 181 182# Test serialization 183 184 185# clean up memory for each function train 186# ft.close() 187# ft2.close() 188# ft_sgd.close() 189# ft3.close() 190# ft4.close() 191 192 193