Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
6adc171
Initial structure for multiDimensional Array
JeanPierreMR Apr 6, 2020
0147664
git ignore update
JeanPierreMR Apr 7, 2020
41e4126
Update arrays.py
JeanPierreMR Apr 9, 2020
6a51719
Changed MultiDimensionalArray
JeanPierreMR Apr 9, 2020
bf55961
Added Multi-dimensional array
JeanPierreMR Apr 9, 2020
c736ee5
Updated arrays.py
JeanPierreMR Apr 9, 2020
65365ec
Update test_arrays.py
JeanPierreMR Apr 13, 2020
ed73085
Update arrays.py
JeanPierreMR Apr 15, 2020
c84fd4d
Update test_arrays.py
JeanPierreMR Apr 15, 2020
96fe82f
Update arrays.py
JeanPierreMR Apr 15, 2020
464c05f
Merge remote-tracking branch 'upstream/master'
JeanPierreMR Apr 15, 2020
7ea7a43
Update arrays.py
JeanPierreMR Apr 15, 2020
d35900f
Adding Multidimensional array
JeanPierreMR Apr 17, 2020
a8b3340
Update Multidimensional aray
JeanPierreMR Apr 17, 2020
5507c58
Update arrays.py
JeanPierreMR Apr 17, 2020
ecd5d20
Merge branch 'MultiDimensionalArrayPlain'
JeanPierreMR Apr 17, 2020
4b04734
Update arrays.py
JeanPierreMR Apr 17, 2020
7211a98
Update pydatastructs/linear_data_structures/__init__.py
JeanPierreMR Apr 18, 2020
d8db935
Update pydatastructs/linear_data_structures/arrays.py
JeanPierreMR Apr 18, 2020
d6c1f14
Update arrays.py
JeanPierreMR Apr 18, 2020
bcb2ee6
Apply suggestions from code review
JeanPierreMR Apr 18, 2020
8e1b86f
Updated test for multi dimensional array
JeanPierreMR Apr 18, 2020
db6fd14
Update arrays.py
JeanPierreMR Apr 18, 2020
e7a10cb
Update test_arrays.py
JeanPierreMR Apr 18, 2020
0dc9c6c
Minor update
JeanPierreMR Apr 18, 2020
388abf1
Minor changes
JeanPierreMR Apr 20, 2020
f176f46
Apply suggestions from code review
JeanPierreMR Apr 30, 2020
b842d54
Update arrays.py
JeanPierreMR Apr 30, 2020
cce3f28
Update arrays.py
JeanPierreMR Apr 30, 2020
a25e465
Update test_arrays.py
JeanPierreMR May 4, 2020
3427792
Update test_code_quality.py
JeanPierreMR May 4, 2020
427fd5b
Update pydatastructs/linear_data_structures/arrays.py
JeanPierreMR May 4, 2020
c306463
Update pydatastructs/linear_data_structures/arrays.py
JeanPierreMR May 4, 2020
19ceaad
Merge branch 'master' of https://github.com/JeanPierreMR/pydatastructs
JeanPierreMR May 4, 2020
7027671
Merge branch 'master' into master
JeanPierreMR May 4, 2020
e691e93
Apply suggestions from code review
czgdp1807 May 5, 2020
17ee7a9
Apply suggestions from code review
czgdp1807 May 5, 2020
806965e
Apply suggestions from code review
czgdp1807 May 5, 2020
a204a64
Apply suggestions from code review
czgdp1807 May 5, 2020
b8db3e5
Update pydatastructs/linear_data_structures/arrays.py
JeanPierreMR May 5, 2020
7a780c7
Update arrays.py
JeanPierreMR May 5, 2020
9b502d7
Apply suggestions from code review
czgdp1807 May 6, 2020
176afd9
Apply suggestions from code review
czgdp1807 May 6, 2020
8a6bba6
Update arrays.py
JeanPierreMR May 9, 2020
2abae14
Update test_arrays.py
JeanPierreMR May 9, 2020
5145abd
code ready
czgdp1807 May 15, 2020
182f8f7
ready for merge
czgdp1807 May 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pydatastructs/linear_data_structures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from .arrays import (
OneDimensionalArray,
MultiDimensionalArray,
DynamicOneDimensionalArray
)
__all__.extend(arrays.__all__)
Expand Down
120 changes: 109 additions & 11 deletions pydatastructs/linear_data_structures/arrays.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
from pydatastructs.utils.misc_util import _check_type, NoneType

__all__ = [
'OneDimensionalArray',
'DynamicOneDimensionalArray'
'OneDimensionalArray',
'MultiDimensionalArray',
'DynamicOneDimensionalArray'
]


class Array(object):
'''
Abstract class for arrays in pydatastructs.
'''
pass


class OneDimensionalArray(Array):
'''
Represents one dimensional arrays.
Expand Down Expand Up @@ -68,18 +71,18 @@ class OneDimensionalArray(Array):
def __new__(cls, dtype=NoneType, *args, **kwargs):
if dtype is NoneType or len(args) not in (1, 2):
raise ValueError("1D array cannot be created due to incorrect"
" information.")
" information.")
obj = Array.__new__(cls)
obj._dtype = dtype
if len(args) == 2:
if _check_type(args[0], list) and \
_check_type(args[1], int):
_check_type(args[1], int):
for i in range(len(args[0])):
if _check_type(args[0][i], dtype) is False:
args[0][i] = dtype(args[0][i])
size, data = args[1], [arg for arg in args[0]]
elif _check_type(args[1], list) and \
_check_type(args[0], int):
_check_type(args[0], int):
for i in range(len(args[1])):
if _check_type(args[1][i], dtype) is False:
args[1][i] = dtype(args[1][i])
Expand All @@ -89,7 +92,7 @@ def __new__(cls, dtype=NoneType, *args, **kwargs):
"expected type of data is list/tuple.")
if size != len(data):
raise ValueError("Conflict in the size %s and length of data %s"
%(size, len(data)))
% (size, len(data)))
obj._size, obj._data = size, data

elif len(args) == 1:
Expand All @@ -102,7 +105,7 @@ def __new__(cls, dtype=NoneType, *args, **kwargs):
if _check_type(args[0][i], dtype) is False:
args[0][i] = dtype(args[0][i])
obj._size, obj._data = len(args[0]), \
[arg for arg in args[0]]
[arg for arg in args[0]]
else:
raise TypeError("Expected type of size is int and "
"expected type of data is list/tuple.")
Expand Down Expand Up @@ -133,13 +136,108 @@ def __len__(self):
def __str__(self):
return str(self._data)

class MultiDimensionalArray(Array):
'''
Represents a multi-dimensional array.

Parameters
==========

dtype: type
A valid object type.
size: int
The number of elements in the array.

Raises
======
IndexError
Index goes out of boundaries
ValueError
When there's no dimensions or the dimension size is 0
TypeError
An argument is not what expected

Examples
========
>>> from pydatastructs import MultiDimensionalArray as MDA
>>> arr = MDA(int, 5, 6, 9)
>>> arr.fill(32)
>>> arr[3][0][0]
32
>>> arr[3][0][0] = 7.2
>>> arr[3][0][0]
7

References
==========

.. [1] https://en.wikipedia.org/wiki/Array_data_structure#Multidimensional_arrays
'''
__slots__ = ['_size', '_data', '_dtype']

def __new__(cls, dtype=NoneType, *args, **kwargs):
if dtype is NoneType or len(args) == (0):
raise ValueError("array cannot be created due to incorrect"
" information.")
dimensions = list(args)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this variable for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable is to store the sizes of the different dimensions, and used to set the size of the dimension
lets say you want to create an array of three dimensions, each dimension with its own size like 4 3 2
So,
MultiDimensionalArray(int, 4, 3, 5)
then
dimensions == [4, 3, 5]

I used it mostly for convenience since i use pop and I wanted to have an easier name, but if you want me to only use args, i can change it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it appears to me that this uses recursive solution i.e., array of arrays of arrays for three dimensions. What we want is, an internal 1D layout with size as product of dimensions with RMO being used to convert queries like, M[i, j, k] to M[l], where l = RMO(i, j, k).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, i did it again, this time it only uses a one dimensional array, calculating the position with the size of each dimension

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dimensions = list(args)
dimensions = args

if dimensions[0] <= 0:
raise ValueError("array cannot be created due to incorrect"
" number of dimensions.")
if len(dimensions) == 2:
obj = Array.__new__(cls)
obj._dtype = OneDimensionalArray
obj._size = dimensions.pop(0)
obj._data = [None] * obj._size
for i in range(obj._size):
obj._data[i] = MultiDimensionalArray(dtype, *dimensions)
return obj
elif len(dimensions) == 1:
return OneDimensionalArray(dtype, dimensions[0])
else:
obj = Array.__new__(cls)
obj._dtype = MultiDimensionalArray
obj._size = dimensions.pop(0)
obj._data = [None] * obj._size
for i in range(obj._size):
obj._data[i] = MultiDimensionalArray(dtype, *dimensions)
return obj

def __getitem__(self, idx):
if idx >= self._size or idx < 0:
raise IndexError("Index out of range.")
return self._data.__getitem__(idx)

def __setitem__(self, idx, element):
if idx >= self._size or idx < 0:
raise IndexError("Index out of range.")
if type(element) != self._data[0]._dtype:
raise TypeError("Unexpected item type.")
# Check the size of the element if it is, set it
if self.compare_size(element):
self._data[idx] = element
else:
raise TypeError("Unexpected item type.")

def compare_size(self, array):
if self._data[0]._size == array._size:
if array._dtype == MultiDimensionalArray:
return self._data[0].compare_size(array)
elif array._dtype == OneDimensionalArray:
if array[0]._dtype == self._data[0][0]._dtype:
return True
return False

def fill(self, element):
for i in range(self._size):
self._data[i].fill(element)

class DynamicArray(Array):
"""
Abstract class for dynamic arrays.
"""
pass


class DynamicOneDimensionalArray(DynamicArray, OneDimensionalArray):
"""
Represents dynamic one dimensional arrays.
Expand Down Expand Up @@ -252,7 +350,7 @@ def append(self, el):

def delete(self, idx):
if idx <= self._last_pos_filled and idx >= 0 and \
self[idx] is not None:
self[idx] is not None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Irrelevant change.

self[idx] = None
self._num -= 1
if self._last_pos_filled == idx:
Expand All @@ -262,7 +360,6 @@ def delete(self, idx):
@property
def size(self):
return self._size

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

def __str__(self):
to_be_printed = ['' for i in range(self._last_pos_filled + 1)]
for i in range(self._last_pos_filled + 1):
Expand All @@ -283,10 +380,11 @@ class ArrayForTrees(DynamicOneDimensionalArray):

pydatastructs.linear_data_structures.arrays.DynamicOneDimensionalArray
"""

def _modify(self):
if self._num/self._size < self._load_factor:
if self._num / self._size < self._load_factor:
new_indices = dict()
arr_new = OneDimensionalArray(self._dtype, 2*self._num + 1)
arr_new = OneDimensionalArray(self._dtype, 2 * self._num + 1)
j = 0
for i in range(self._last_pos_filled + 1):
if self[i] is not None:
Expand Down
20 changes: 19 additions & 1 deletion pydatastructs/linear_data_structures/tests/test_arrays.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pydatastructs.linear_data_structures import (
OneDimensionalArray, DynamicOneDimensionalArray)
OneDimensionalArray, DynamicOneDimensionalArray, MultiDimensionalArray)
from pydatastructs.utils.raises_util import raises


Expand All @@ -21,6 +21,24 @@ def test_OneDimensionalArray():
assert raises(TypeError, lambda: ODA(int, set([1, 2, 3])))
assert raises(ValueError, lambda: ODA(int, 3, [1]))

def test_MultiDimensionalArray():
MDA = MultiDimensionalArray
A = MDA(int, 5, 9, 3, 8)
A.fill(5)
A[1][3][2][5] = 2.0
assert A
assert A[1][3][2][5] == 2.0
assert A[1][3][1][5] == 5
assert A[0][3][2][5] == 5
assert A[1][3][2][0] == 5
assert raises(IndexError, lambda: A[5])
assert raises(IndexError, lambda: A[4][10])
assert raises(IndexError, lambda: A[-1])
assert raises(ValueError, lambda: MDA())
assert raises(ValueError, lambda: MDA(int))
assert raises(ValueError, lambda: MDA(int, 0))
assert raises(TypeError, lambda: MDA(int, 5, 6, ""))

def test_DynamicOneDimensionalArray():
DODA = DynamicOneDimensionalArray
A = DODA(int, 0)
Expand Down