Skip to content

Commit e9b1c26

Browse files
committed
add elemental matrix operations
1 parent dae5ee0 commit e9b1c26

File tree

1 file changed

+247
-48
lines changed

1 file changed

+247
-48
lines changed

NumpyDeque/NumpyDeque.py

Lines changed: 247 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ def copy(self):
529529
Returns:
530530
NumpyDeque: A new instance of NumpyDeque that is a copy of the current deque.
531531
"""
532-
return NumpyDeque.array(self.deque, None, self.dtype, self._bcap, self._priority)
532+
return NumpyDeque.array(self.deque, None, self.dtype, None, self._priority, _force_buffer_size=self._bcap)
533533

534534
def clear(self):
535535
"""
@@ -561,6 +561,252 @@ def where(self, value):
561561
"""
562562
return np.where(self.deque == value)[0]
563563

564+
def __getitem__(self, index):
565+
return self.queue[index]
566+
567+
def __setitem__(self, index, value):
568+
self.queue[index] = value
569+
570+
def __getattr__(self, name):
571+
"""
572+
Handles unknown attributes by forwarding them to the NumPy.ndarray that holds the deque.
573+
This allows the NumpyDeque to support NumPy attributes such as `shape`, `dtype`, etc.
574+
575+
Parameters:
576+
name (str): The name of the missing attribute.
577+
578+
Returns:
579+
The value of the attribute from `self.deque`.
580+
581+
Raises:
582+
AttributeError: If the attribute does not exist in `self` or `self.deque`.
583+
"""
584+
585+
try:
586+
# Forward any unknown attribute to the NumPy component
587+
attr = getattr(self.deque, name)
588+
if callable(attr):
589+
590+
def method(*args, **kwargs):
591+
return attr(*args, **kwargs)
592+
593+
return method
594+
return attr
595+
except AttributeError:
596+
raise AttributeError(f"'NumpyDeque' object has no attribute '{name}'")
597+
598+
def __len__(self):
599+
return self.size
600+
601+
def __repr__(self):
602+
s = repr(self.deque)
603+
s = s[s.find("(") :] # drop "array" from name
604+
return f"NumpyDeque{s}"
605+
606+
def __str__(self):
607+
s = repr(self.deque)
608+
s = s[s.find("[") : s.find("]") + 1] # get core part of numpy array
609+
return f"NumpyDeque({s})"
610+
611+
def __iter__(self):
612+
return iter(self.deque)
613+
614+
def __copy__(self):
615+
return self.copy()
616+
617+
def __deepcopy__(self, unused=None):
618+
return self.copy()
619+
620+
def __contains__(self, value):
621+
return value in self.deque
622+
623+
def __pos__(self): # +val
624+
return self.copy()
625+
626+
def __neg__(self): # -val
627+
res = self.copy()
628+
res.deque *= -1
629+
return res
630+
631+
def __abs__(self): # abs(val)
632+
res = self.copy()
633+
res.abs()
634+
return res
635+
636+
def __iadd__(self, other): # To get called on addition with assignment e.g. a +=b.
637+
if isinstance(other, NumpyDeque):
638+
other = other.deque
639+
self.deque += other
640+
return self
641+
642+
def __isub__(self, other): # To get called on subtraction with assignment e.g. a -=b.
643+
if isinstance(other, NumpyDeque):
644+
other = other.deque
645+
self.deque -= other
646+
return self
647+
648+
def __imul__(self, other): # To get called on multiplication with assignment e.g. a *=b.
649+
if isinstance(other, NumpyDeque):
650+
other = other.deque
651+
self.deque *= other
652+
return self
653+
654+
def __itruediv__(self, other): # To get called on true division with assignment e.g. a /=b.
655+
if isinstance(other, NumpyDeque):
656+
other = other.deque
657+
self.deque /= other
658+
return self
659+
660+
def __irtruediv__(self, other): # To get called on true division with assignment e.g. a /=b.
661+
if isinstance(other, NumpyDeque):
662+
other = other.deque
663+
self.deque /= other
664+
return self
665+
666+
def __ifloordiv__(self, other): # To get called on integer division with assignment e.g. a //=b.
667+
if isinstance(other, NumpyDeque):
668+
other = other.deque
669+
self.deque //= other
670+
return self
671+
672+
def __irfloordiv__(self, other): # To get called on integer division with assignment e.g. a //=b.
673+
if isinstance(other, NumpyDeque):
674+
other = other.deque
675+
self.deque //= other
676+
return self
677+
678+
def __imod__(self, other): # To get called on modulo with assignment e.g. a%=b.
679+
if isinstance(other, NumpyDeque):
680+
other = other.deque
681+
self.deque %= other
682+
return self
683+
684+
def __irmod__(self, other): # To get called on modulo with assignment e.g. a%=b.
685+
if isinstance(other, NumpyDeque):
686+
other = other.deque
687+
self.deque %= other
688+
return self
689+
690+
def __ipow__(self, other): # To get called on exponents with assignment e.g. a **=b.
691+
if isinstance(other, NumpyDeque):
692+
other = other.deque
693+
self.deque **= other
694+
return self
695+
696+
def __irpow__(self, other): # To get called on exponents with assignment e.g. a **=b.
697+
if isinstance(other, NumpyDeque):
698+
other = other.deque
699+
self.deque **= other
700+
return self
701+
702+
def __int__(self): # To get called by built-int int() method to convert a type to an int.
703+
return NumpyDeque.array(self.deque, self.maxsize, np.int32, None, self.priority, _force_buffer_size=self._bcap)
704+
705+
def __float__(self): # To get called by built-int float() method to convert a type to float.
706+
return NumpyDeque.array(
707+
self.deque, self.maxsize, np.float64, None, self.priority, _force_buffer_size=self._bcap
708+
)
709+
710+
def __add__(self, other): # To get called on add operation using + operator
711+
res = self.copy()
712+
res += other
713+
return res
714+
715+
def __radd__(self, other): # To get called on add operation using + operator
716+
res = self.copy()
717+
res += other
718+
return res
719+
720+
def __sub__(self, other): # To get called on subtraction operation using - operator.
721+
res = self.copy()
722+
res -= other
723+
return res
724+
725+
def __rsub__(self, other): # To get called on subtraction operation using - operator.
726+
res = self.copy()
727+
res -= other
728+
return res
729+
730+
def __mul__(self, other): # To get called on multiplication operation using * operator.
731+
res = self.copy()
732+
res *= other
733+
return res
734+
735+
def __rmul__(self, other): # To get called on multiplication operation using * operator.
736+
res = self.copy()
737+
res *= other
738+
return res
739+
740+
def __floordiv__(self, other): # To get called on floor division operation using // operator.
741+
res = self.copy()
742+
res //= other
743+
return res
744+
745+
def __rfloordiv__(self, other): # To get called on floor division operation using // operator.
746+
res = self.copy()
747+
res //= other
748+
return res
749+
750+
def __truediv__(self, other): # To get called on division operation using / operator.
751+
res = self.copy()
752+
res /= other
753+
return res
754+
755+
def __rtruediv__(self, other): # To get called on division operation using / operator.
756+
res = self.copy()
757+
res /= other
758+
return res
759+
760+
def __mod__(self, other): # To get called on modulo operation using % operator.
761+
res = self.copy()
762+
res %= other
763+
return res
764+
765+
def __rmod__(self, other): # To get called on modulo operation using % operator.
766+
res = self.copy()
767+
res %= other
768+
return res
769+
770+
def __pow__(self, other): # To get called on calculating the power using ** operator.
771+
res = self.copy()
772+
res **= other
773+
return res
774+
775+
def __rpow__(self, other): # To get called on calculating the power using ** operator.
776+
res = self.copy()
777+
res **= other
778+
return res
779+
780+
def __lt__(self, other): # To get called on comparison using < operator.
781+
if isinstance(other, NumpyDeque):
782+
other = other.deque
783+
return self.deque < other
784+
785+
def __le__(self, other): # To get called on comparison using <= operator.
786+
if isinstance(other, NumpyDeque):
787+
other = other.deque
788+
return self.deque <= other
789+
790+
def __gt__(self, other): # To get called on comparison using > operator.
791+
if isinstance(other, NumpyDeque):
792+
other = other.deque
793+
return self.deque > other
794+
795+
def __ge__(self, other): # To get called on comparison using >= operator.
796+
if isinstance(other, NumpyDeque):
797+
other = other.deque
798+
return self.deque >= other
799+
800+
def __eq__(self, other): # To get called on comparison using == operator.
801+
if isinstance(other, NumpyDeque):
802+
other = other.deque
803+
return self.deque == other
804+
805+
def __ne__(self, other): # To get called on comparison using != operator.
806+
if isinstance(other, NumpyDeque):
807+
other = other.deque
808+
return self.deque != other
809+
564810
def _shift_buffer(self):
565811
"""
566812
Internally shift the buffer to accommodate newly added elements and ensure efficient use of buffer space.
@@ -652,53 +898,6 @@ def _reverse_in_place(array):
652898
for i in range(n // 2):
653899
array[i], array[n - i - 1] = array[n - i - 1], array[i]
654900

655-
def __len__(self):
656-
return self.size
657-
658-
def __getitem__(self, index):
659-
return self.queue[index]
660-
661-
def __setitem__(self, index, value):
662-
self.queue[index] = value
663-
664-
def __getattr__(self, name):
665-
"""
666-
Handles unknown attributes by forwarding them to the NumPy.ndarray that holds the deque.
667-
This allows the NumpyDeque to support NumPy attributes such as `shape`, `dtype`, etc.
668-
669-
Parameters:
670-
name (str): The name of the missing attribute.
671-
672-
Returns:
673-
The value of the attribute from `self.deque`.
674-
675-
Raises:
676-
AttributeError: If the attribute does not exist in `self` or `self.deque`.
677-
"""
678-
679-
try:
680-
# Forward any unknown attribute to the NumPy component
681-
attr = getattr(self.deque, name)
682-
if callable(attr):
683-
684-
def method(*args, **kwargs):
685-
return attr(*args, **kwargs)
686-
687-
return method
688-
return attr
689-
except AttributeError:
690-
raise AttributeError(f"'NumpyDeque' object has no attribute '{name}'")
691-
692-
def __repr__(self):
693-
s = repr(self.deque)
694-
s = s[s.find("(") :] # drop "array" from name
695-
return f"NumpyDeque{s}"
696-
697-
def __str__(self):
698-
s = repr(self.deque)
699-
s = s[s.find("[") : s.find("]") + 1] # get core part of numpy array
700-
return f"NumpyDeque({s})"
701-
702901

703902
if __name__ == "__main__":
704903
NumpyDeque(maxsize=5)

0 commit comments

Comments
 (0)