## Packages
using Combinatorics
using LinearAlgebra
using Statistics
using Plots
using Surrogates
using AbstractGPs
using SurrogatesAbstractGPs
## Samples & Simulation Values
samples = [(0.0069279,3125.3376),(0.007217,2822.4),(0.0066381,3103.6992),(0.0068796,3449.6),(0.0075551,3298.1312),(0.0076034,2995.5072),(0.0063966,3211.5776),(0.0071204,3038.784 ),(0.0065415,2973.8688),(0.0069762,3254.8544),(0.0075068,2865.6768),(0.0064932,2844.0384),(0.0068313,3017.1456),(0.0077,3146.6624),(0.0071687,3168.3008),(0.0063,2930.592),(0.0063483,3060.4224),(0.0076517,3406.3232),(0.0066864,3233.216),(0.006783,3341.408),(0.0070721,3363.0464),(0.0073619,3384.6848),(0.0065898,3427.9616),(0.0064449,3319.7696),(0.0074102,3082.0608),(0.0073136,2952.2304),(0.0067347,2887.3152),(0.0070238,2908.9536),(0.0072653,3276.4928),(0.0074585,3189.9392)]
pemag = [0.0345961,0.030084187,0.035679352,0.037666891,0.034359619,0.029923033,0.03636267,0.032476597,0.034182258,0.036440253,0.028273117,0.032135811,0.033565659,0.032167263,0.034371812,0.034238148,0.03568152,0.035676125,0.036677513,0.036585461,0.036987271,0.036416266,0.038416255,0.037919082,0.0323768,0.031139335,0.031703983,0.031259604,0.035165709,0.033306386]
torchspeed = map(x->x[1],samples)
torchheat = map(x->x[2],samples)
lb = [minimum(torchspeed),minimum(torchheat)]
ub = [maximum(torchspeed),maximum(torchheat)]
## Create Validation & Training Sets
vsets = collect(combinations(1:30, 5))
tsets = map(x->setdiff(1:30, x), vsets)
### Counter
x = collect(1:142506)
## Radial Basis Function
RBF_linear = map(i-> RadialBasis(samples[tsets[i]], z[i], lb, ub), collect(1:length(x)))
RBF_cubic = map(i-> RadialBasis(samples[tsets[i]], z[i], lb, ub, rad = cubicRadial()), collect(1:length(x)))
RBF_multiq = map(i-> RadialBasis(samples[tsets[i]], z[i], lb, ub, rad = multiquadricRadial()), collect(1:length(x)))
RBF_thinpl = map(i-> RadialBasis(samples[tsets[i]], z[i], lb, ub, rad = thinplateRadial()), collect(1:length(x)))
## Gaussian Process Regression (Kriging)
GPR = map(i-> Kriging(samples[tsets[i]], z[i], lb, ub, p=[2.0, 2.0]), collect(1:length(x)))
## Gaussian Process (General)
GPs = map(i-> AbstractGPSurrogate(samples[tsets[i]], z[i]), collect(1:length(x)))
xs = range(lb[1], ub[1]; length=100)
ys = range(lb[2], ub[2]; length=100)
surface(xs, ys, (x1,x2) -> RBF_multiq[1]((x1,x2)))