- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
module vector_ implicit none private public:: vector integer,parameter:: rp=8,ip=4 !types !----------------------- type:: vector private real(rp),allocatable,dimension(:):: vc contains generic:: init => init_vector procedure,private:: init_vector generic:: operator(*) => vsMultiply,svMultiply procedure,pass(lhs),private:: vsMultiply procedure,pass(rhs),private:: svMultiply end type vector !----- contains !&& pure subroutine init_vector(this,v) class(vector),intent(out):: this class(vector),intent(in):: v allocate( this%vc( size(v%vc) ) ) this%vc = v%vc end subroutine init_vector elemental function svMultiply(lhs,rhs) result(vr) real(rp),intent(in):: lhs class(vector),intent(in):: rhs type(vector):: vr allocate( vr%vc( size(rhs%vc) ) ) vr%vc = lhs * rhs%vc end function svMultiply !-- elemental function vsMultiply(lhs,rhs) result(vr) class(vector),intent(in):: lhs real(rp),intent(in):: rhs type(vector):: vr call vr%init( rhs * lhs ) end function vsMultiply !-- end module vector_ module polynomial_ use vector_ implicit none private public:: polynomial integer,parameter:: rp=8,ip=4 !----------------------------------------- type,extends(vector):: polynomial contains !the below p1=> error #5286: Ambiguous generic interface OPERATOR(*): previously declared specific procedure VECTOR_::SVMULTIPLY is not distinguishable from this declaration. [SPMULTIPLY] generic:: operator(*) => spmultiply procedure,pass(rhs),private:: spMultiply !the below p2=>error #8280: An overriding binding and its corresponding overridden binding must both be either subroutines or functions with the same result type, kind, and shape. [SVMULTIPLY] !procedure,pass(rhs),private:: svMultiply => spMultiply end type polynomial !----------------------------------------- contains !-- elemental function spMultiply(lhs,rhs) result(p) real(rp),intent(in):: lhs class(polynomial),intent(in):: rhs type(polynomial):: p call p%init(rhs) end function spMultiply end module polynomial_ program test use vector_ use polynomial_ implicit none print*, 'ok' end program test
here I meet some problems.
I have two types: one is <vector>, and another one is <polynomial> which is the subclass of <vector>
I want to override the operator(*) of <vector> in <polynomial> which makes the result follow the type of input
Method1: I tried to add <spMultiply> into the generic binding procedure, it leads problem1
Method2: I tried to override the <svMultiply>, it leads problem2
So is there anyone can help me solve this overriding procedure and realize my thought. I ever tried to change the class of output in <svMultiply> to <class(vector),allocatable::>, but <elemental> attribution refuse the declaration of <allocatable> for function output.
!!!the real problem!!!
Actually another worse problem is that I successfully override the operator<*> by method1 in a big code. Then a type(polynomial) can produce a type(polynomial) when multiplying REAL. But I can’t reproduce this successful compilation in this simplified version.
the f90 attached is a version can override operator<*>. it can run directly.
i want to know whether method1 is an legal overriding procedure for operator?
i use the VS2013+intelfortran2017
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
i find the reason which leads to this strange compiling behavior
once the operator(*) of <vector> is not the first overriden generic operator, method1 can be passed through the compiler check
like:
generic:: operator(+)=> <someproc>
added in line 16
but this compiling will still fails if the other overriden operator added behind the operator(*)
for now, i still want an legal and robust way to override the operator which can produce the different type output
<class,allocatable> is not a preferred way because <elemental> attribution is quite convenient for coding
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Li L. wrote:
.. for now, i still want an legal and robust way to override the operator which can produce the different type output ..
@Li L,
What are all your use cases with the extended operator(*) in the child derived type? Note for situations that are like or similar to this:
z = x * y
where z is the child type and either x or y is the child type while the other is a real scalar of kind rp, all you would need is to introduce a defined assignment in the child type which has a second dummy argument of the parent type.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan wrote:for example p1 = r * p2 *p3 if i don't override operator of polynomial r*p2=vector, rather than polynomial vector*p3 is wrong and nonsense as you say, a split step seems work. but it definitely confusing me in the future when i check the code with the literature. a compact expression, totally the same as the paper can help me work better
Quote:
Li L. wrote:.. for now, i still want an legal and robust way to override the operator which can produce the different type output ..
@Li L,
What are all your use cases with the extended operator(*) in the child derived type? Note for situations that are like or similar to this:
z = x * y
where z is the child type and either x or y is the child type while the other is a real scalar of kind rp, all you would need is to introduce a defined assignment in the child type which has a second dummy argument of the parent type.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Li L. wrote:
.. for example
p1 = r * p2 *p3
if i don't override operator of polynomial
r*p2=vector, rather than polynomial
vector*p3 is wrong and nonsense.. when i check the code with the literature. a compact expression, totally the same as the paper can help me work better
Why is it nonsense? Based on what you show, a polynomial is effectively the same as vector; in fact, one can ask why even extend vector to make it a polynomial!
Also, what literature are you referring to? Which paper, and what is the "compact expression"? Does it have a design pattern in some other language you're trying to mimic with Fortran?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Li L. wrote:
..
for example
p1 = r * p2 *p3
..
Keep in mind you don't need necessarily work with type-bound generic operators; in fact, case can be made that abstraction for multiplications, etc. be achieved via module procedures rather than TBPs - many will find them clearer to understand and easier to implement, as aspect in which you express an interest. Moreover there may be some performance benefit given the fact the code can then work with explicit derived types rather than the polymorphic instances.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan wrote:module procedures is a good choice
Quote:
Li L. wrote:
..
for example
p1 = r * p2 *p3
..
Keep in mind you don't need necessarily work with type-bound generic operators; in fact, case can be made that abstraction for multiplications, etc. be achieved via module procedures rather than TBPs - many will find them clearer to understand and easier to implement, as aspect in which you express an interest. Moreover there may be some performance benefit given the fact the code can then work with explicit derived types rather than the polymorphic instances.
explicit derived type increase the code lines. but if you are definitely sure about the benefit of performance, no matter how much, i will try
anymore, can you reproduce the strange compiling. that method1: i can override the second or later generic operator by adding function in generic binding, but compiling fails when doing that for the first generic operator.
is that a compiler debug? this generic binding add is permitted or not?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Li L. wrote:
.. p1 = r * p1 * p2 ..
Upon further thought, you don't really need to override the scalar * vector and the vector * scalar operator in the polynomial type. You should be able to work by simply extending the generic operator(*) with 2 more procedures, a) with your ppMultiply where lhs -> class(polynomial) and rhs -> type(polynomial) and b) with, say, a vpMultiply where lhs -> type(vector) and rhs -> class(polynomial).
But you can also try the module procedure option and do performance comparisons.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan wrote:
Quote:
Li L. wrote:
.. p1 = r * p1 * p2 ..
Upon further thought, you don't really need to override the scalar * vector and the vector * scalar operator in the polynomial type. You should be able to work by simply extending the generic operator(*) with 2 more procedures, a) with your ppMultiply where lhs -> class(polynomial) and rhs -> type(polynomial) and b) with, say, a vpMultiply where lhs -> type(vector) and rhs -> class(polynomial).
But you can also try the module procedure option and do performance comparisons.
permitting the vector*polynomial is a dangerous logic for the program, as i think.
like if you considering the superclass as <2 dimensional vector>, and subclass as <3 dimensional vector>, which is a very nature inheritance
and in superclass we define real*2dvector = 2dvector
due to the lack of an effective overriding method
we have to admit the existence of real*3dvector = 2dvector, and then for correcting this logic, define an operation of <2dvector .op. 3dvector>
in mathematics, this operator definition breaks the completeness of 3d space. in code, this expression losses <z>
<class(2dvector),allocatable> as the output may help, but <elemental> is also a fundamental attribution for operator procedure
after a long time for considering this questions, i think a module interface is a safer way to override the intrinsic operator.
type binding operator is not suitable for extended type
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page