12,545,876 members (59,730 online)
Article
alternative version

15.1K views
5 bookmarked
Posted

# Multi-dimensional Array Implementation in Python 3.2 besides with the coincidence of C#

, 8 Mar 2012 GPL3
 Rate this:
A multi dimensional array class with the advance of negative indexes. Used like a[-2, -5, 3] with any dimensions.

## Introduction

You can easily make use of `Multiray` class for issues regarding multidimensional arrays. Now you can download `C# version `of multiray completely with the same structure as python version.

## Using the Code

The usage is simple:
1. Initialize `Multiray` object with predefined dimensions:
Python
```a = Multiray(2, 5, 20, 6);
```
C#
```using multiray;
MultiRay a = new MultiRay(2, 5, 20, 6);
```
2. Assign your data values to multi-index specified cells:
Python
```#a[1, 4, 21, 1] will assert an overflow.
a[1, 2, 18, 5] = "Any Object";
```
C#
```//a[1, 4, 21, 1] will raise an exception.
a[1, 2, 18, 5] = "Any Object";
```
3. Looping is somewhat like jagged arrays. Use `GetLength(d)` for any dimension with index d.
Python
```for i in range(a.GetLength(0)):
for j in range(a.GetLength(1)):
for k in range(a.GetLength(2)):
for l in range(a.GetLength(3)):
#do anything you want with
#a[i, j, k, l];
print("a[{1:3}]={0}".format(a[i, j, k, l], a.Position));
```
C#
```for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
for (int k = 0; k < a.GetLength(2); k++)
for (int l = 0; l < a.GetLength(3); l++)
{
a[i, j, k, l] = "Hello World";
Console.WriteLine("a[{0},{1},{2},{3}] = {4}"
, i, j, k, l, a[i, j, k, l]);
}
```

`_EvaluateIndex` gets real index of given indexes-tuple with this principle:

• if a is a (I x J x K) three dimensional array; let a[i][j][k] nth item in a array. In `Multiray` implementation, n is evaluated by `_EvaluateIndex`() method call.
• for D = 3, n is thus:
• `n = i*J*K + j*K + k;`
• for D = 4(I x J x K x T :: i, j, k, t) n is thus:
• `n = i*J*K*T + j*K*T + k*K + t;`
• We multiply the first key with J, K and T; second key with K and T; third with T and fourth with 1
• So we need to multiply first index with keys[1]*keys[2]*keys[3] second key with keys[2]*keys[3] and so on...
• `_EvaluateIndex` definitely do this:
Python
```def _EvaluateIndex(self, keys, k):
dLen = len(self.Dimensions);
#attention!
if k == dLen: return keys[-1];
t = 1; #accumulator
#multiply t with the given dimensions k to dLen
for i in range(k, dLen):
t *= self.Dimensions[i]
t *= keys[k - 1];
return t + self._EvaluateIndex(keys, k=k+1);```
C#
```private int _EvaluateIndex(int[] keyTuple, int k)
{
int dLen = this.Dimensions.Length;
if (k == dLen)
return keyTuple[keyTuple.Length - 1];
int t = 1;
for (int i = k; i < dLen; i++)
{
t *= this.Dimensions[i];
}
t *= keyTuple[k - 1];
return t + this._EvaluateIndex(keyTuple, k + 1);
}
```

## How is it possible using Multiray object with an indexer?

• Solution is implementing `__getitem__` and `__setitem__`:
Python
```def __getitem__(self, keyTuple):
keys = self._CheckKeys(keyTuple);
self.Position = self._EvaluateIndex(keys, k=1);
return self._Arr2D[self.Position];```
• `self._CheckKeys` makes checks and conversion of minus indexes(a[2,3,-2]); then `self.Position `is evaluated and is given as index to the `self._Arr2D `array.
Python
```def __setitem__(self, keyTuple, item):
keys = self._CheckKeys(keyTuple);
self.Position = self._EvaluateIndex(keys, k=1);
self._Arr2D[self.Position] = item```
C#
```public object this[params int[] keyTuple]
{
get
{
int[] keys = this._CheckKeys(keyTuple);
this.Position = this._EvaluateIndex(keys, 1);
return this._Arr2D[this.Position];
}
set
{
int[] keys = this._CheckKeys(keyTuple);
this.Position = this._EvaluateIndex(keys, 1);
this._Arr2D[this.Position] = value;
}
}
```
• Again `self._CheckKeys()` makes checks and manipulations:
Python
```def _CheckKeys(self, keyTuple):
assert(len(keyTuple) == len(self.Dimensions));
keyList = list(keyTuple);
limit = len(keyList);
for i in range(limit):
assert(keyList[i] < self.Dimensions[i] \
and keyList[i] >= -self.Dimensions[i]);
#for minus indexes:
#like a[1,-2]
if keyList[i] < 0:
keyList[i] += self.Dimensions[i];
return keyList;
```
C#
```private int[] _CheckKeys(int[] keyTuple)
{
Debug.Assert(keyTuple.Length == this.Dimensions.Length);
int limit = keyTuple.Length;
int[] keyList = new int[limit];
for (int i = 0; i < limit; i++)
{
Debug.Assert(keyList[i] < this.Dimensions[i]
&& keyList[i] >= -this.Dimensions[i]);
keyList[i] = keyTuple[i];
//for negative indexes
//like a[1,-2]
if (keyList[i] < 0)
keyList[i] += this.Dimensions[i];
}
return keyList;
}
```

## Last word

• I found out that "," delimeted indexes are passed in tuples. So when I use a[1,2,3] __getitem__ takes (1,2,3) tuple.
• So positional arguments not needed for now.

## Points of Interest

I suffered from invalid mathematical evaluations. By the help of induction, I could eventually implement the right way of function.

## History

The previous version lacked c sharp in advance.

## Share

 Software Developer Turkey
I am a software developer emphasizing algorithm side of development.

## You may also be interested in...

 Pro Pro