Professor Chambouliard hast just discovered a new type of magnet material. He put particles of this material in a box made of small boxes arranged 
in K rows and N columns as a kind of **2D matrix** `K x N` where `K` and `N` are postive integers.
He thinks that his calculations show that the force exerted by the particle in the small box `(k, n)` is:






The total force exerted by the first row with `k = 1` is:






We can go on with `k = 2` and then `k = 3` etc ... and consider:






## Task: 
To help Professor Chambouliard can we calculate the function `doubles` that will take as parameter `maxk` and `maxn` such that `doubles(maxk, maxn) = S(maxk, maxn)`?
Experiences seems to show that this could be something around `0.7` when `maxk` and `maxn` are big enough.

### Examples:
```
doubles(1, 3)  => 0.4236111111111111
doubles(1, 10) => 0.5580321939764581
doubles(10, 100) => 0.6832948559787737
```

### Notes: 
- In `u(1, N)` the dot is the *multiplication operator*.
- Don't truncate or round: 
Have a look in "RUN EXAMPLES" at "assertFuzzyEquals".

- [link to symbol Sigma](https://en.wikipedia.org/wiki/Summation)

Source: codewars | Difficulty: MEDIUM
Tags: Matrices

Mathematics

Starter code: def doubles(maxk, maxn):
	

Solutions:
def doubles(maxk, maxn):
	return sum([sum([(n + 1) ** (-2 * k) for n in range(1, maxn + 1)]) / k for k in range(1, maxk + 1)])


from scipy.special import zeta, zetac

def doubles(maxk, maxn):
	return sum(((zetac(2 * k) - zeta(2 * k, 2 + maxn)) / k for k in range(1, maxk + 1)))


def v(k, n):
	return 1.0 / k * (n + 1) ** (-2 * k)

def doubles(maxk, maxn):
	total = 0.0
	k = 1.0
	while k <= maxk:
		n = 1.0
		while n <= maxn:
			total += v(k, n)
			n += 1
		k += 1
	return total


def doubles(maxk, maxn):
	res = 0
	for k in range(1, maxk + 1):
		for n in range(1, maxn + 1):
			res += 1 / (k * (n + 1) ** (2 * k))
	return res


import numpy as np

def box_force(k, n):
	return 1 / (k * (n + 1) ** (2 * k))

def doubles(maxk, maxn):
	return np.fromfunction(lambda i, j: box_force(i + 1, j + 1), (maxk, maxn)).sum()


import numpy as np

def get_v(k, n):
	return 1 / (k * np.power((n + 1).reshape(-1, 1), (2 * k).reshape(1, -1)))

def doubles(K, N):
	K = np.arange(1, K + 1, dtype=np.float64)
	N = np.arange(1, N + 1, dtype=np.float64)
	return get_v(K, N).sum()


def v(k, n):
	return 1 / (k * (n + 1) ** (2 * k))

def u(k, N):
	u_res = 0
	for n in range(0, N):
		u_res += v(k, n + 1)
	return u_res

def S(K, N):
	S_res = 0
	for k in range(0, K):
		S_res += u(k + 1, N)
	return S_res

def doubles(maxk, maxn):
	return S(maxk, maxn)


def doubles(k, n):
	s = 0
	for iK in range(1, min(k + 1, 24)):
		for iN in range(2, n + 2):
			s += 1 / (iK * iN ** (2 * iK))
	return s


def doubles(maxk, maxn):
	result = 0
	for k in range(1, maxk + 1):
		curr_sum = 0
		for n in range(1, maxn + 1):
			curr_sum += 1 / (n + 1) ** (2 * k)
		result += 1 / k * curr_sum
	return result