The **Inverse Distance Surrogate** is an interpolating method and in this method the unknown points are calculated with a weighted average of the sampling points. This model uses the inverse distance between the unknown and training points to predict the unknown point. We do not need to fit this model because the response of an unknown point x is computed with respect to the distance between x and the training points.

Let's optimize following function to use Inverse Distance Surrogate:

.

First of all, we have to import these two packages: `Surrogates`

and `Plots`

.

```
using Surrogates
using Plots
default()
```

### Sampling

We choose to sample f in 25 points between 0 and 10 using the `sample`

function. The sampling points are chosen using a Low Discrepancy, this can be done by passing `LowDiscrepancySample()`

to the `sample`

function.

```
f(x) = sin(x) + sin(x)^2 + sin(x)^3
n_samples = 25
lower_bound = 0.0
upper_bound = 10.0
x = sample(n_samples, lower_bound, upper_bound, LowDiscrepancySample(2))
y = f.(x)
scatter(x, y, label="Sampled points", xlims=(lower_bound, upper_bound), legend=:top)
plot!(f, label="True function", xlims=(lower_bound, upper_bound), legend=:top)
```

## Building a Surrogate

```
InverseDistance = InverseDistanceSurrogate(x, y, lower_bound, upper_bound)
add_point!(InverseDistance, 5.0, f(5.0))
add_point!(InverseDistance, [5.1,5.2], [f(5.1),f(5.2)])
prediction = InverseDistance(5.0)
```

`-0.9211536761615453`

Now, we will simply plot `InverseDistance`

:

```
plot(x, y, seriestype=:scatter, label="Sampled points", xlims=(lower_bound, upper_bound), legend=:top)
plot!(f, label="True function", xlims=(lower_bound, upper_bound), legend=:top)
plot!(InverseDistance, label="Surrogate function", xlims=(lower_bound, upper_bound), legend=:top)
```

## Optimizing

Having built a surrogate, we can now use it to search for minimas in our original function `f`

.

To optimize using our surrogate we call `surrogate_optimize`

method. We choose to use Stochastic RBF as optimization technique and again Sobol sampling as sampling technique.

```
@show surrogate_optimize(f, SRBF(), lower_bound, upper_bound, InverseDistance, SobolSample())
scatter(x, y, label="Sampled points", legend=:top)
plot!(f, label="True function", xlims=(lower_bound, upper_bound), legend=:top)
plot!(InverseDistance, label="Surrogate function", xlims=(lower_bound, upper_bound), legend=:top)
```

## Inverse Distance Surrogate Tutorial (ND):

First of all we will define the `Schaffer`

function we are going to build surrogate for. Notice, one how its argument is a vector of numbers, one for each coordinate, and its output is a scalar.

```
function schaffer(x)
x1=x[1]
x2=x[2]
fact1 = (sin(x1^2-x2^2))^2 - 0.5;
fact2 = (1 + 0.001*(x1^2+x2^2))^2;
y = 0.5 + fact1/fact2;
end
```

`schaffer (generic function with 1 method)`

### Sampling

Let's define our bounds, this time we are working in two dimensions. In particular we want our first dimension `x`

to have bounds `-5, 10`

, and `0, 15`

for the second dimension. We are taking 60 samples of the space using Sobol Sequences. We then evaluate our function on all of the sampling points.

```
n_samples = 60
lower_bound = [-5.0, 0.0]
upper_bound = [10.0, 15.0]
xys = sample(n_samples, lower_bound, upper_bound, SobolSample())
zs = schaffer.(xys);
```

```
60-element Array{Float64,1}:
0.5805413942727871
0.8145273099857899
0.08020859455927337
0.19772145405699176
0.8142084947223727
0.5835491982806807
0.1664281216039425
0.5443030417036995
0.8527949936315682
0.7437158136294192
⋮
0.9290960871508356
0.7479664255142824
0.43975577484256423
0.2558930427525836
0.0416027038555522
0.42346068991450914
0.5175383085574314
0.8000176778737265
0.5113242964432465
```

### Building a surrogate

Using the sampled points we build the surrogate, the steps are analogous to the 1-dimensional case.

`InverseDistance = InverseDistanceSurrogate(xys, zs, lower_bound, upper_bound)`

`(::InverseDistanceSurrogate{Array{Tuple{Float64,Float64},1},Array{Float64,1},Array{Float64,1},Array{Float64,1},Float64}) (generic function with 1 method)`

### Optimizing

With our surrogate we can now search for the minimas of the function.

Notice how the new sampled points, which were created during the optimization process, are appended to the `xys`

array. This is why its size changes.

`size(xys)`

`(60,)`

`surrogate_optimize(schaffer, SRBF(), lower_bound, upper_bound, InverseDistance, SobolSample(), maxiters=10)`

`((5.52796935038384, 1.5101935904741073), 0.031300554679043247)`

`size(xys)`

`(137,)`