# Rasters and arrays:  backgrounder on shapes and dimensions

Blog Post created by Dan_Patterson on Jan 20, 2016

Introduction

This blog post is for the two other people in the world that might be remotely interested in rasters/arrays and dimensionality as it can be applied to reshaping for subsequent analysis.  The topic was introduced in my previous blog about block statistics.  I am gently warming the readers (both of you) to moving/sliding window functions and how they work on a mechanical level.

The code below is for the record.  This is one incarnation of what is out there on the web.  Most of the comments and posts deal with the 'speed' and efficacy of determining what you will see.  In my opinion, those discussions don't matter... I have only needed primes and combinations and permutations once outside of an academic environment.  I will rely on this code should the need arise again.  So here it is with an output example.

Nerd Note:

As of worlds largest prime as of this date,   , the worlds largest prime is ... 274207281-1 .... or 22,338,618 digits the number is called M74207281

which is the 49th Mersenne Prime discovered.     http://www.mersenne.org/primes/?press=M74207281

In the next post, I will use this foundation to provide more background on working with block and moving window operations.

```"""
Script:  primes_combos_demo.py
Author:  Dan.Patterson@carleton.ca
Purpose: Long forgotten, but it is done.
"""
import numpy as np
import itertools

def primes(n):
"""Returns a array of primes, p < n
http://stackoverflow.com/questions/2068372/fastest-way-to-list-
all primes-below-n-in-python/3035188#3035188
"""
assert n>=2
sieve = np.ones(n/2, dtype=np.bool)
for i in range(3,int(n**0.5)+1,2):
if sieve[i/2]:
sieve[i*i/2::i] = False
p_num = np.r_[2, 2*np.nonzero(sieve)[1::]+1]
return p_num

def divisor(n, prn=False):
"""Determine the divisors, products, cumulative products and
divisors given a set of primes < n
"""
p_vals = primes(n)
divs = [p for p in p_vals if (n % p == 0)]
cump = np.cumproduct(divs).tolist()
divs = divs + cump
prods = list(set(i*j for i in divs for j in divs))
all_div = list(set(divs+prods))
all_div.sort()
if prn:
print("all",all_div)
return all_div

def perm_sums(n,max_dim=3):
"""Determine the permutations that sum to n for an array of given size.
A verbose workflow follows...   """
##divs, subs, prods = divisor(n)
perms = divisor(n)
p =[]
for i in range(1,max_dim+1):
p.append(list(itertools.product(perms, repeat=i)))
combos = []
for i in range(len(p)):
vals = [v for v in p[i] if np.product(v)==n ]
combos.extend(vals) #.append(vals)
perms = np.array(perms)
ppp = np.product(perms,axis=-1)
wh = np.where(ppp == n)
perm_vals = perms[wh]
return combos

def demo(n=36, prn=True):
""" demo perm_sums"""
p = primes(n)
print("\nPrimes:...{}".format(p))
all_div = divisor(n)
print("Number:...{}\nAll:...{}".format(n, all_div))
ndim = 4
combos = perm_sums(n, max_dim=ndim)
if prn:
print("\nProducts for... {} - max_dim = {}".format(n, ndim))
for i in combos:
print(i)
return combos

if __name__=="__main__":
"""primes demo"""
n = 36
combos = demo(n, prn=True)

```

For the example in my last post for a 6x6 array for 36 unique numbers, these list the possible ways that that data can be reconfigure.

Primes:...[ 2  3  5  7 11 13 17 19 23 29 31]
Number:...36
All:...[2, 3, 4, 6, 9, 12, 18, 36]

Products for... 36 - max_dim = 4

2D3D4D

(36,)

(2, 18)

(3, 12)

(4, 9)

(6, 6)

(9, 4)

(12, 3)

(18, 2)

(2, 2, 9)

(2, 3, 6)

(2, 6, 3)

(2, 9, 2)

(3, 2, 6)

(3, 3, 4)

(3, 4, 3)

(3, 6, 2)

(4, 3, 3)

(6, 2, 3)

(6, 3, 2)

(9, 2, 2)

(2, 2, 3, 3)

(2, 3, 2, 3)

(2, 3, 3, 2)

(3, 2, 2, 3)

(3, 2, 3, 2)

(3, 3, 2, 2)

If you specify a minimum window size you can get possible combinations.

Minimum window...[3, 3]

[(3, 12), (4, 9), (6, 6), (9, 4), (12, 3), (2, 3, 6), (2, 6, 3), (3, 3, 4), (3, 4, 3), (4, 3, 3), (2, 2, 3, 3)]

That's all for now.  The cases of being able to reshape a raster in 1, 2, 3 or 4 dimensions are given above.