def reshape(Fn, A, B): """ implement dyadic ⍴ """ assertNotArray(A) if A.isScalarLike(): Apy = confirmInteger(A.scalarToPy()) assertTrue(Apy >= 0, "DOMAIN ERROR") if Apy == 0: return makeEmptyVector(B.prototype()) Bpy = B.castToVectorPy() return makeVector(Fn(Apy, Bpy), Apy, B.prototype()) if A.isEmptyVector(): Bpy = B.castToVectorPy() return makeVector(Fn(1, Bpy), 1, B.prototype()) Apy = tuple([confirmInteger(I) for I in A.vectorToPy()]) assertTrue(Apy == (2, 2), "WIP - MATRIX ERROR") for I in Apy: assertTrue(I >= 0, "DOMAIN ERROR") Bpy = B.castToVectorPy() return makeArray(Fn(Apy, Bpy), Apy, 2 * B.prototype())
def take(Fn, A, B): """ implement dyadic ↑ """ assertNotArray(A) if B.isScalar() or B.isEmptyVector(): if A.isEmptyVector(): return B if B.isVectorLike(): assertScalarLike(A) Apy = confirmInteger(A.scalarToPy()) if Apy == 0: return makeEmptyVector(B.prototype()) Rpy = Fn(Apy, B.vectorToPy(), B.padFill()) return makeVector(Rpy, abs(Apy), B.prototype()) Apy = [confirmInteger(I) for I in A.vectorToPy()] assertTrue(B.dimension() == (2, 2), "WIP - MATRIX ERROR") assertTrue(len(Apy) == B.rank(), "LENGTH ERROR") Rpy = [] for Bit in Fn(Apy[0], B.arrayByLastAxis(), B.padFill()): Rpy += Fn(Apy[1], Bit.vectorToPy(), Bit.padFill()) return makeArray(Rpy, [abs(I) for I in Apy], B.prototype())
def deal(A, B): """ A ? B """ A = confirmInteger(A) B = confirmInteger(B) try: return tuple(random.sample(range(1, B + 1), A)) except ValueError: assertError("DOMAIN ERROR")
def transpose(_, A, B): """ implement dyadic ⍉ """ assertNotArray(A) if B.isArray(): assertTrue(A.tally() == B.rank(), "LENGTH ERROR") IO = indexOrigin() Apy = [confirmInteger(I) - IO for I in A.vectorToPy()] high = B.rank() + 1 assertTrue(all(x >= 0 and x <= high for x in Apy), "DOMAIN ERROR") assertTrue(sum(Apy) <= sum(range(B.rank())), "DOMAIN ERROR") Rpy = dyadicTranspose(B.arrayToPy(), Apy, B.dimension()) def newDimensions(A, B): """ determine dimensions of the transposed result """ R = list(range(len(A))) for I in R: H = [B[X] for X in R if A[X] == I] if H: yield min(H) Dpy = tuple(newDimensions(Apy, B.dimension())) if len(Dpy) == 1: return makeVector(Rpy, Dpy[0], None) return makeArray(Rpy, Dpy, None) if B.isVector(): assertScalarLike(A) Apy = confirmInteger(A.scalarToPy()) assertTrue(Apy == 1, "DOMAIN ERROR") return B assertEmptyVector(A) return B
def expandFirst(Fn, A, B): """ implement dyadic ⍀ """ assertNotArray(A) if B.isScalar() and A.isEmptyVector(): return makeEmptyVector(B.prototype()) if B.isVectorLike(): if A.isScalar(): Apy = confirmInteger(A.scalarToPy()) assertTrue(Apy >= 0, "LENGTH ERROR") if Apy == 0: return makeVector(B.prototype(), 1, B.prototype()) Rpy = Fn(A.promoteScalarToVectorPy(), B.vectorToPy(), B.padFill()) return makeVector(Rpy, -1, B.prototype()) if B.isArray(): assertTrue(B.dimension() == (2, 2), "WIP - MATRIX ERROR") Apy = [confirmInteger(I) for I in A.vectorToPy()] if A.isScalarLike(): if Apy[0] < B.dimension()[0]: assertError("LENGTH ERROR") else: assertError("DOMAIN ERROR") else: Lpy = sum(abs(I) if I != 0 else 1 for I in Apy) Dpy = list(B.dimension()) Dpy[-1] = Lpy assertTrue(tuple(Dpy) == (2, 2), "WIP - MATRIX ERROR") Rpy = [] for Bit in B.arrayByFirstAxis(): Rpy += Fn(A.promoteScalarToVectorPy(), Bit.vectorToPy(), B.padFill()[-1]) Rpy = monadicTranspose(Rpy, Dpy) Dpy[0], Dpy[-1] = Dpy[-1], Dpy[0] return makeArray(Rpy, Dpy, B.prototype())
def drop(Fn, A, B): """ implement dyadic ↓ """ assertNotArray(A) if B.isScalar(): if A.isEmptyVector(): return B assertScalarLike(A) Apy = confirmInteger(A.scalarToPy()) if Apy == 0: return makeVector(B.vectorToPy(), 1, B.prototype()) return makeEmptyVector(B.prototype()) if B.isVector(): if A.isEmptyVector(): Apy = 1 else: assertScalarLike(A) Apy = confirmInteger(A.scalarToPy()) if Apy == 0: return B Rpy = Fn(Apy, B.vectorToPy()) return makeVector(Rpy, -1, B.prototype()) Apy = [confirmInteger(I) for I in A.vectorToPy()] assertTrue(B.dimension() == (2, 2), "WIP - MATRIX ERROR") assertTrue(len(Apy) == B.rank(), "LENGTH ERROR") Rpy = [] for Bit in Fn(Apy[0], B.arrayByLastAxis()): Rpy += Fn(Apy[1], Bit.vectorToPy()) Dpy = [max(0, I[1] - abs(I[0])) for I in zip(Apy, B.dimension())] return makeArray(Rpy, Dpy, B.prototype())
def _nextPairWithInteger(A, B): """ utility routine to fetch the next pair of values from the iterators The first of the pair must be an integer """ OK = 0 try: X = confirmInteger(A.__next__()) OK += 1 except StopIteration: if isinstance(B, aplIterator): raise StopIteration try: Y = B.__next__() OK += 1 except StopIteration: if isinstance(A, aplIterator): raise StopIteration if OK == 2: return X, Y if OK == 0: raise StopIteration assertError("LENGTH ERROR")
def circular(A, B): """ A ○ B A is valid in the range [-12, +12]. The following are implemented: ¯7 atanh(B) ¯6 acosh(B) ¯5 asinh(B) ¯4 sqrt(B**2-1) ¯3 atan(B) ¯2 acos(B) ¯1 asin(B) 0 sqrt(1-B**2) 1 sin(B) 2 cos(B) 3 tan(B) 4 sqrt(B**2+1) 5 sinh(B) 6 cosh(B) 7 tanh(B) """ A = confirmInteger(A) if A <= -12 or A >= 12: assertError("DOMAIN ERROR") function = _CircularFunctions[A + 12] if function is None: assertError("FUNCTION NOT YET IMPLEMENTED") try: return function(B) except ValueError: assertError("DOMAIN ERROR")
def pick(_, A, B): """ implement dyadic ⊃ """ assertNotArray(A) assertNotArray(B) if A.isEmptyVector(): return B assertNotScalar(B) if B.isVector(): IO = indexOrigin() try: for X in A.vectorToPy(): X = confirmInteger(X) assertTrue(X >= IO, "INDEX ERROR") if isinstance(B, aplQuantity): B = B.vectorToPy()[X - IO] else: assertError("RANK ERROR") except IndexError: assertError("INDEX ERROR") if isinstance(B, aplQuantity): return B return makeScalar((B, ), None)
def deal(Fn, A, B): """ implement deal (dyadic ?) """ assertScalarLike(A, "RANK ERROR") assertScalarLike(B, "RANK ERROR") Apy = confirmInteger(A.scalarToPy()) return makeVector(Fn(Apy, B.scalarToPy()), Apy)
def rotateFirst(Fn, A, B): """ implement dyadic ⌽ """ assertNotArray(A) if B.isArray(): if not A.isScalarLike(): assertTrue(A.tally() == B.rank(), "LENGTH ERROR") assertTrue(B.tally() != 0, "WIP - LENGTH ERROR") Apy = [ operator.mod(confirmInteger(I), B.tally()) for I in A.vectorToPy() ] if A.isScalarLike(): Apy = Apy * B.rank() Rpy = [] for Apy, Bit in zip(Apy, B.arrayByFirstAxis()): Rpy += Fn(Apy, Bit.vectorToPy()) Rpy = monadicTranspose(Rpy, B.dimension()) return makeArray(Rpy, B.dimension(), None) assertScalarLike(A, "RANK ERROR") Apy = confirmInteger(A.scalarToPy()) if B.isEmptyVector(): return B Apy = operator.mod(Apy, B.tally()) if Apy == 0: return B return makeVector(Fn(Apy, B.vectorToPy()), B.dimension(), None)
def iota(Fn, B): """ implement monadic ⍳ the operand is scalar: there is no map as such """ if B.isScalar(): Bpy = confirmInteger(B.scalarToPy()) assertTrue(Bpy >= 0, "DOMAIN ERROR") return makeVector(Fn(Bpy), Bpy) assertNotVector(B, "WIP - LENGTH ERROR") assertNotArray(B)
def compressFirst(Fn, A, B): """ implement dyadic ⌿ """ assertNotArray(A) if B.isScalar() and A.isEmptyVector(): return makeEmptyVector(B.prototype()) if B.isVectorLike(): Rpy = Fn(A.promoteScalarToVectorPy(), B.vectorToPy(), B.padFill()) return makeVector(Rpy, -1, B.prototype()) if B.isArray(): assertTrue(B.dimension() == (2, 2), "WIP - MATRIX ERROR") Apy = [confirmInteger(I) for I in A.vectorToPy()] if A.isScalarLike(): Lpy = abs(Apy[0]) * B.dimension()[0] else: Lpy = sum(abs(I) for I in Apy) Dpy = list(B.dimension()) Dpy[0] = Lpy Dpy[0], Dpy[-1] = Dpy[-1], Dpy[0] if Lpy == 0: return makeArray(B.padFill(), Dpy, B.prototype()) assertTrue(tuple(Dpy) == (2, 2), "WIP - MATRIX ERROR") Rpy = [] for Bit in B.arrayByFirstAxis(): Rpy += Fn(A.promoteScalarToVectorPy(), Bit.vectorToPy(), B.padFill()[-1]) Rpy = monadicTranspose(Rpy, B.dimension()) return makeArray(Rpy, Dpy, B.prototype())
def _nextPair(self): """ fetch the next pair of values from the iterators """ OK = 0 try: self._X = confirmInteger(self._A.__next__()) if self._X > 0: self._T += 1 if self._T == 0: return elif self._X == 0: self._X -= 1 OK += 1 except StopIteration: pass if self._X < 0 and self._T < 0: return try: self._Y = self._B.__next__() self._T -= 1 OK += 1 except StopIteration: pass if self._X < 0 and self._T == 0: return if OK != 2: if isinstance(self._A, aplIterator): assertTrue(self._T == 1, "LENGTH ERROR") else: assertTrue(self._T == 0, "LENGTH ERROR") raise StopIteration
def partition(Fn, A, B): """ implement dyadic ⊂ """ assertNotArray(A) assertNotTrue(B.isScalar(), "RANK ERROR") if A.isEmptyVector() and B.isEmptyVector(): return B if A.isScalar(): Apy = confirmInteger(A.scalarToPy()) if Apy == 0: return makeEmptyVector() return makeScalar((B, ), B.prototype()) if B.isArray(): assertTrue(B.dimension() == (2, 2), "WIP - MATRIX ERROR") Apy = A.vectorToPy() assertTrue(len(Apy) == B.rank(), "LENGTH ERROR") Rpy = [] for Bit in B.arrayByLastAxis(): Rpy += makeScalar((Fn( A.vectorToPy(), Bit.vectorToPy(), ), B.prototype())) Dpy = list(B.dimension()) Dpy[-1] = 1 return makeArray(Rpy, Dpy, None) return makeVector(Fn(A.vectorToPy(), B.vectorToPy()), -1, B.prototype())