python 파이썬 행렬식 - 다른 선형 대수 백엔드를 제공하기위한 아키텍처




1 Answers

왜 당신의 예제에서 Vector와 같은 "가상"클래스 ( AbstractVector )를 만들지 않고 각 구현에 대해 다른 하위 클래스를 만드는 것이 좋을까요?

Vector = NumPyVector 또는 그런 식으로 엔진을 선택할 수 있습니다.

행렬의 외적 numpy

파이썬에서 새로운 시스템을 프로토 타이핑하고있다. 기능은 대부분 숫자입니다.

중요한 요구 사항은 각각의 사용자 구현에서 Numpy와 같은 일반 라이브러리에 이르기까지 다양한 선형 대수학 백엔드를 사용할 수 있다는 것입니다. 선형 대수학 구현 (즉, 백엔드)은 인터페이스와 독립적이어야합니다.

나의 초기 건축 시도는 다음과 같다 :

(1) 시스템 인터페이스 정의

>>> v1 = Vector([1,2,3])
>>> v2 = Vector([4,5,6])
>>> print v1 * v2
>>> # prints "Vector([4, 10, 18])"

(2) 백엔드와 독립적으로 해당 인터페이스를 사용할 수 있도록 코드를 구현하십시오

# this example uses numpy as the back-end, but I mean
# to do this for a general back-end
import numpy 
def numpy_array(*args): # creates a numpy array from the arguments
    return numpy.array(*args)

class VectorBase(type):
    def __init__(cls, name, bases, attrs):
        engine = attrs.pop("engine", None)
        if not engine:
            raise RuntimeError("you need to specify an engine")
        # this implementation would change depending on `engine`
        def new(cls, *args):
            return numpy_array(*args)   
        setattr(cls, "new", classmethod(new))

class Vector(object):   
    __metaclass__ = VectorBase        
    # I could change this at run time
    # and offer alternative back-ends
    engine = "numpy"  
    @classmethod
    def create(cls, v):
        nv = cls()
        nv._v = v
        return nv    
    def __init__(self, *args):  
        self._v = None
        if args:
            self._v = self.new(*args)
    def __repr__(self):
        l = [item for item in self._v]
        return "Vector(%s)" % repr(l)
    def __mul__(self, other):
        try:
            return Vector.create(self._v * other._v)
        except AttributeError:
            return Vector.create(self._v * other)
    def __rmul__(self, other):
        return self.__mul__(other)

이 간단한 예제는 다음과 같이 작동합니다. Vector 클래스는 백엔드에서 만든 벡터 인스턴스에 대한 참조를 유지합니다 (이 예에서 numpy.ndarray ). 모든 산술 호출은 인터페이스에 의해 구현되지만 평가는 백엔드로 연기됩니다.

실제로이 인터페이스는 모든 적절한 연산자와 방어기를 백엔드로 오버로드합니다 (이 예에서는 __mul____rmul__ 만 보여 주지만 각 작업마다 동일하게 수행 할 수 있음).

나는 customizability의 교환에 약간의 성과를 풀어 기꺼이한다. 예제가 작동하는 동안에도 제대로 작동하지 않습니다. 많은 생성자 호출로 백 엔드를 손상시킬 수 있습니다! 이것은 다른 metaclass 구현을 요구하며 더 나은 호출 지연을 허용합니다.

그렇다면이 기능을 구현하는 것이 어떻습니까? 시스템의 모든 Vector 인스턴스를 선형 대수학 백엔드와 동질적이고 독립적으로 유지하는 것이 중요하다는 것을 강조 할 필요가 있습니다.




Related