Question: I'm looking to plot the Alpine1 function using Python. The function looks like this:

Alp(x\_1,…,x\_n )= ∑\_(i=1)^n〖|x\_i \* sin(x\_i )+1.01x\_i |〗

[![ALpine1](https://i.stack.imgur.com/fnKr2.png)](https://i.stack.imgur.com/fnKr2.png)

So the function sums (`from i=1 to n`) the absulute of `xi*sin(xi) +1.01xi`. Without the summation the function in Python looks like this: 

```
def f(x):
   return (abs(x * np.sin(x) + 1.01 * x))

```

However, here I used x instead of xi and the summation is left out. How do I correctly implement the summation `from i=1 to n`? Simply using sum() gives just one value, while I require an array. 

I think I need to look in the direction of a `for i in range(1,...)` type of thing but I haven't been able to figure it out. 

Thanks in advance for the one that can help me!

Answer: 
You can use `np.sum` to take the sum of an array. Numpy's [broadcasting](https://realpython.com/numpy-array-programming/) and vectorization take care that all elements are calculated separately and then summed.

Here is an example:

```
import numpy as np

def alpine1(xis):
    return np.sum(np.abs(xis * np.sin(xis) + 1.01 * xis))

xis = np.array([1, 2, 3])
print(alpine1(xis)) # 9.143425862638862

```

As your post mentions plotting, here is how a heatmap of the Alpine1 function would look like applied to two values:

```
import numpy as np
import matplotlib.pyplot as plt

def alpine1(xis):
    return np.sum(np.abs(xis * np.sin(xis) + 1.01 * xis))

x1, x2 = np.meshgrid(np.linspace(-10, 10, 500), np.linspace(-10, 10, 500))
z = np.apply_along_axis(alpine1, -1, np.dstack([x1, x2]))
plt.pcolormesh(x1, x2, z, cmap='inferno')
plt.colorbar()
plt.show()

```

[![example plot](https://i.stack.imgur.com/PuL64.jpg)](https://i.stack.imgur.com/PuL64.jpg)

This is how a 3D surface (`z = Alpine1(x1, x2)`) would look like:

```py
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def alpine1(xis):
    return np.sum(np.abs(xis * np.sin(xis) + 1.01 * xis))

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x1, x2 = np.meshgrid(np.linspace(-10, 10, 500), np.linspace(-10, 10, 500))
z = np.apply_along_axis(alpine1, -1, np.dstack([x1, x2]))

surf = ax.plot_surface(x1, x2, z, cmap='inferno', edgecolor='none')
fig.colorbar(surf)
plt.show()

```

[![3D surface plot](https://i.stack.imgur.com/7Kwsd.jpg)](https://i.stack.imgur.com/7Kwsd.jpg)
Thanks I think I understand a lot better already!

I was wondering another thing actually. Alpine1 is a n-dimensional function, so suppose I want to take the "2D version" the function would directly result in:

```
def Alpine(x1, x2): 
return (np.abs(x1 * np.sin(x1) + 1.01 * x1)+ np.abs(x2 * np.sin(x2) + 1.01 * x2))

```

How do I plot it now? Still two variables (arrays actually) are required (x1 and x2) but `np.apply_along_axis` only works for 1d I think. How should I handle this?

*Maybe using x for x1 and y for x2 makes it easier to understand*