2013-03-07 4 views
5

Fortran 2003에 스파 스 매트릭스가있는 많은 선형 대수를 수행하는 코드를 작성했습니다. 나는 새로운 표준의 좀 더 추상적 인 기능을 이용하려고 노력하고 있으므로 너무 복잡한 코드가 필요없는 간단한 프로그램을 가지고있다.Fortran 2003의 런타임 다형성

나는 매트릭스, 일부 벡터, 반복 방법에 대한 허용 오차 등을 취하는 절차 solver을 가지고 있습니다. matvec이라는 프로 시저에 대한 포인터를 전달하고 있습니다. matvec은 행렬 - 벡터 곱셈에 사용하는 서브 루틴입니다.

가끔 matvec은이 절차로 보낸 일반적인 것보다 위에 추가 인수 colorlist, color1, color2을 취하는 절차입니다. 나는 이것을 다루는 여러 가지 방법을 생각할 수있다.

첫 번째 아이디어 : 두 개의 다른 추상 인터페이스 matvec1, matvec2 및 서로 다른 두 개의 솔버를 정의하십시오. 이 작동하지만 일부 코드를 복제하는 것을 의미합니다, 그냥 피하려고합니다.

또 다른 아이디어 : 같은 추상적 인 인터페이스 matvec를 유지하고, 여분의 인수는 , color1, color2 선택합니다. 즉, 모든 matvec 루틴에서 옵션을 선택하는 것입니다. 심지어 실제로 선택 사항이 아닌 경우에도 루틴은 전혀 사용되지 않습니다. 내가 이렇게하면 확실히 지옥에 갈거야.

다른 최적의 솔루션보다 많이 생각할 수 있습니다. 나는 이것에 대한 약간의 의견을 원한다. 나는 그것을 할 수있는 우아한 방법이있을 것이라 확신한다. 나는 그것이 무엇인지 모른다.

답변

5

프로 시저가 호출 될 때마다 추가 인수를 전달해야하는지 (실제로 두 호출간에 변경되기 때문에) 인수를 전달해야하는지, 아니면 어떤 시점에서 초기화 한 다음 함수에서 사용하는 것이 문제입니다. 후자의 경우, 필수적인 인수를 가진 서브 루틴 matvec을 정의하는 추상 인터페이스로 클래스를 생성 할 수 있습니다. 그런 다음 추가 옵션을 보유 할 수있는보다 특수화 된 클래스로 클래스를 확장 할 수 있습니다. 그들은 여전히 ​​(동일한 인수 목록을 가진) 부모 클래스와 동일한 matvec 인터페이스를 정의해야하지만, matvec 프로 시저가 호출 될 때 추가 된 값을 사용할 수 있습니다.

비슷한 경우에 대한 자세한 예제는 in this answer입니다 (두 번째 예는 module rechercheRacine입니다).

interface matvec 
    module procedure matvec1, matvec2 
end interface 

이 그런 다음 solver 루틴이 단지 또는 여분의 인수없이 일반 이름을 사용할 수 있습니다 :

2

대신 명시 적 인수로 프로 시저 포인터를 전달, 당신은 일반적인 인터페이스 뒤에 다양한 matvec 루틴을 넣을 수 . 형 바인딩 절차에 파생 형으로 solver을 정의 발린 트의 제안 방법을 사용하면 같은 접근 방식은 물론도 수행 할 수 있습니다

가장 큰 차이점이 올바른 절차를 결정하기 위해 다형성을 사용하지 않는다는 것입니다
type :: solver 
    real, allocatable :: matrix(:,:), v1(:), v2(:) 
contains 
    procedure, pass :: matvec1 
    procedure, pass :: matvec2 
    generic :: matvec => matvec1, matvec2 
end type 

호출하지만 오히려 거짓 인수의 특성.

프로 시저 포인터에 대한 의도가 확실하지 않습니다. 런타임에 타겟을 변경하고 싶다면 (또는 '정의되지 않은'상태에 특별한 의미를 부여하는 경우) 포인터가 유일한 방법이며 모든 타겟이 동일한 추상 인터페이스와 일치해야합니다.대신 인수에 따라 여러 프로 시저 중 하나를 선택하면 인터페이싱 (예제) 또는 오버로드 (Bálint의 예)를 활용할 수 있습니다. 한 유형의 각 확장은 새로운 프로 시저로 상속 된 generic 바인딩을 확장하거나 상속 된 특정 바인딩을 오버로드 할 수 있습니다.