Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Q about extended use of operators

WSinc
New Contributor I
12,008 Views

I was told that the standard math operators can be extended to include user defined

variables, such as what one would set up with a TYPE statement.

How does one tell the compiler what to do in those instances?

For instance, I want to use the * to refer to a DOT product of two vectors.

Like :

--------------------------------------------

type(vector)A,B,C

C= A*B

!  where A,B, and C are defined as follows:

type (vector)

integer nx

real(4) x(100)

end type

------------------------------------------

Likewise I would like the + and - operators to take the sum and difference of two vectors.

Or even one could do comparisons of absolute values:

if( A > B) go to 99

I was looking for an article about this topic, but I don't know what "lingo" is used to discuss this.

So I couldn't find it. Any suggestions?

0 Kudos
53 Replies
Simon_Geard
New Contributor I
4,113 Views

An example that does attached. I wanted to include the code but the new spam filters are a tad over enthusiastic.

0 Kudos
Simon_Geard
New Contributor I
4,113 Views

An example that does attached. I wanted to include the code but the new spam filters are a tad over enthusiastic.

0 Kudos
Simon_Geard
New Contributor I
4,113 Views

An example that does attached. I wanted to include the code but the new spam filters are a tad over enthusiastic.

0 Kudos
Simon_Geard
New Contributor I
4,113 Views

And now it seems I've made three posts and not attached anything. What is going on with this forum????? I wrote 1 file called v3.f90 but it seems to be being renamed v3_0.f90 ... v3_3.f90. No idea why and no idea why it wasn't added to one of my previous posts, or even why those posts were made (since I didn't press submit). The preview says that the file is attached (with no name) so hopefully you'll be able to see it.

0 Kudos
lklawrie
Beginner
4,113 Views

Coming into this a bit late so sorry if this has been covered.

An example for vectors is shown in Fortran 90/95 for Scientists and Engineers, by Stephen Chapman, page 505ff.

0 Kudos
John_Campbell
New Contributor II
4,113 Views

The following also works:

[fortran]

program utest
  implicit none

  integer, dimension(3):: u, v, w

  u = (/ 1, 2, 3 /)
  v = (/ 4, 5, 6 /)
  w = 3*u + 5*v
  write(*,*) '3*',u,' + 5*',v,' = ',w
end program utest[/fortran]

I am not convinced that the new way is such a step forward.

John

0 Kudos
geard__simon
Beginner
4,113 Views

The point of the example was to show how to do what the OP was asking rather than comment on whether or not it was a good idea.

Personally I think the new way is an enormous step forward and that your code supports my view. The old way only works for POA (plain old arrays), even then it is limited. For example, if vector has all its components mod(.,7) then the new constructs allow that property to be separated from the application code whereas in the old world you have to add a call to mod(.,7) in the application code. And what of composite objects? I could have defined vector3_t  as

[fortran]

type vector3_t

  character(len=:), allocatable :: name

  integer :: values(3)

contains

   ...

end type vector3_t

[/fortran]

In some applications operator overloading is pretty much the only way to do it, automatic differentiation being one example, quaternions possibly another.

This new way is something I really like (along with associate), I'm now looking forward to parameterized derived types and the block construct.

0 Kudos
andrew_4619
Honored Contributor III
4,113 Views

@Simong #28.

The examples have been interesting however from a personal standpoint the functionality is not particularly useful to me. I concede we all have personal preferences in how we like to do things. Standard Vector operations are not really a suitable example, plain old arrays can be manipulated very efficiently and clearly as #27 and #14 demonstrate.

The use of derived types in this application adds additional overheads and makes vectorisation and other optimisations less likely. Making extra code to do something in a more complicated way does not seem like a good idea to me. Using standard array operations the code will always be 'inline' rather than potentially thrashing about in memory

Personally I think overloading standard mathematical operators is an exceptionally bad idea and hides what the code is actually doing. W=3*U+5*V is converted from what looks like standard Fortran into what happens in some hidden user code with some additional potential for bugs. 

Stylistically we might prefer A .cross. B to cross(A,B) but at the end of the day the former is just an alias for the latter and does not confer any other advantage than the style.

0 Kudos
IanH
Honored Contributor III
4,113 Views

sgeard@cad-schroer.co.uk wrote:
And now it seems I've made three posts and not attached anything...

I find it easiest to upload the files, submit the post, wait and see if the attachment has worked (you will get an indication whether it is going to work based on the state of the attachments area prior to hitting the final post submit button), then after the post has appeared - edit it, and use the MyFiles tab on the Select Media "dialog" to select the file that was uploaded but not attached, then resubmit the edited post.

0 Kudos
John_Campbell
New Contributor II
4,113 Views

I don't disagree that it's an enormous step forward for the compiler, although ifort ver 12.1 (XE 2011) did not recognise :
generic                        :: write(formatted) => write_v
I have never seen or was aware of the syntax to define a write format for a derived type.

The question I have is how many users of Fortran use or are aware of this language structure and is it good for the language to provide, what I am assuming, such a rarely used syntax. Given the changes that have taken place from F1995 to F2003 and to F2008, I wonder what F2020 might contain and how many compliant compilers will be available.

There is the discussion about overloaded operators, what about overloaded compilers.

John

0 Kudos
IanH
Honored Contributor III
4,113 Views

The examples that use a derived type to encapsulate the vector (particularly sgeard's in #25) offer expressive potential well beyond that available using an intrinsic array.

If you'll never need that potential, then - yes - there's little point using that style.  But that kind of misses the point.

For a simple example - consider what the code looks like if you have some vectors of vectors and you want to do some operations on them.  Consider if you want to customize the formatted output in some way.  Consider if you want to insert some validation or error checking code into the operations themselves.  Consider if the vector is really the internal implementation of some higher level concept as intimated in #28.  Etc.

I accept that inappropriate definition of the existing operators could create confusion.  But I could also write a procedure called Add that doesn't do what it says on the label, and merrily confuse all future readers of my code.  (In fact, the results of recent debugging indicate that is more or less what I have [inadvertently] done.)

I also accept with current compiler capability you may not get the fastest code.  But compiler capability is also constantly improving, and the ability to transform these higher level coding structures into efficient machine code is something that I regard as an important feature.

(On that topic - when the otherwise private procedures are accessed via bindings is the compiler able to see the "leaf" nature of the procedures and avoid the overhead associated with the use of a descriptor for the polymorphic argument?  If not, is that capability being considered?)

0 Kudos
IanH
Honored Contributor III
4,113 Views

Restriction the discussion to language evolution (rather than compiler support of that evolution, which has an unfortunate but unavoidable lag) then the following two papers might be of interest.

The New Features of Fortran 2003.

The New Features of Fortran 2008.

There's always going to be tension between the level of use and familiarity with a language feature and the compiler support of that feature.

Where practical, you are better off pushing management of complexity and tedium up the chain to compilers and libraries (write once, test a lot, use many, many times) and free up the human programmers to do more abstract thinking type work (write once, test... maybe, use once).

0 Kudos
FortranFan
Honored Contributor III
4,113 Views

"To each their own" - the standards extensions since Fortran 90 have been designed well to make this idiom quite applicable to Fortran developers - kudos to standards creators!  Hence those who wish not to make use of many of the new language features and enhancements are under no pressure to change.  But there is no need to question the march forward.  I wish the compilers would keep up with the change, or rather lead the change (as it used to be until F90).

I, for one, am finding great value in most of the new features of Fortran 2003 and 2008.  In applications involving numerical quadrature including ODEs and PDEs, I find my code written with OOP constructs, derived types with bound procedures, overloaded operators, generic programming, etc. to yield high-quality data abstraction and encapsulation while achieving better or similar performance compared to code written in FORTRAN 77 style, array-based, procedural paradigms.  In addition, I find it much easier to achieve thread-safety in the newer code, it is highly amenable to parallel computing, and increasingly scalable with multi-processor architecture.  For me, there is no looking back.

Another great benefit I am finding with all the new features is in being able to communicate with my colleagues in what is effectively the same "code design language" that they use with highly modern programming styles in C++, Python, C#, etc.  I can now illustrate my Fortran code design using similar unified modeling language (UML) constructs that they all can understand, I can implement various design patterns that they do as well.  In my world, gone are the days of "FORTRAN.. YUCK....". 

 

0 Kudos
WSinc
New Contributor I
4,113 Views

I appreciate your discussions about overloaded compilers, and overloaded operators -

 

What about overloaded computer programmers ?

 

Maybe I should have been a sheep farmer.

BAAAA !

0 Kudos
mecej4
Honored Contributor III
4,113 Views

billsincl wrote:

What about overloaded computer programmers ?

Cheer up!

Overloaded Programmer + RTFM = Underloaded and Cheerful Fortran Programmer

0 Kudos
WSinc
New Contributor I
4,113 Views

RTFM = "really tough for me" ?

0 Kudos
Steven_L_Intel1
Employee
4,113 Views

"Read The Fine Manual"

0 Kudos
Craig_Dedo
New Contributor I
4,113 Views

I goofed in one of the source code examples that I posted on Tuesday.  In the add and subtract functions in the Demo_Vector_3D_M module, I mistakenly used:

[fortran]

C = A + B

[/fortran]

Instead, I should have used:

[fortran]

C%X = A%X + B%X

C%Y = A%Y + B%Y

C%Z = A%Z + B%Z

[/fortran]

I.e., I should have written component-by-component definitions.  I am attaching a corrected copy of Demo_Vector_3D_M.f90 to this posting.

0 Kudos
mecej4
Honored Contributor III
4,113 Views

Craig Dedo wrote:

... I should have written component-by-component definitions.  I am attaching a corrected copy of Demo_Vector_3D_M.f90 to this posting.

And, in those functions which have return values of type Vector_3D_DP_T, you need to declare the dummy arguments to be of type Vector_3D_DP_T instead of Vector_3D_SP_T (probably casualties of copy/paste?).

0 Kudos
Craig_Dedo
New Contributor I
4,077 Views

mecej4 wrote:

Quote:

Craig Dedo wrote:

... I should have written component-by-component definitions.  I am attaching a corrected copy of Demo_Vector_3D_M.f90 to this posting.

 

And, in those functions which have return values of type Vector_3D_DP_T, you need to declare the dummy arguments to be of type Vector_3D_DP_T instead of Vector_3D_SP_T (probably casualties of copy/paste?).

Yes, you are correct.  Thank you very much for pointing out the mistake.  Yes, they were casualties of copy/paste.  Here is a second corrected copy of Demo_Vector_3D_M.f90.

 

0 Kudos
Craig_Dedo
New Contributor I
4,077 Views

John Campbell wrote:

Thanks Craig and app4619 for your examples of the coding for .cross. They give me a good indication of what is required.

<snip>

I have always used a subroutine dcross (a, b, c) where C = A x B, rather than using a vector function. I'm not sure if I will adopt the use of .cross.  Given my recent interest in AVX performance, I wonder if adopting .cross. would have any benefit ?

Yes, adopting .Cross. instead of using a procedure reference would have significant benefit.  In a word:  readability.  It allows you to write your code in a more natural, straightforward style, just like you would write your problem on a piece of paper or on the blackboard.  It also allows someone else to much more quickly understand what your source code is doing.  The same expression using operators is much easier to read and understand than the equivalent expression using procedure calls.

Please keep in mind that using operators is in the original spirit of Fortran:  making life as easy as possible for the non-expert application developer to write correct, robust, and understandable programs.

 

0 Kudos
Reply