- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An example that does attached. I wanted to include the code but the new spam filters are a tad over enthusiastic.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An example that does attached. I wanted to include the code but the new spam filters are a tad over enthusiastic.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An example that does attached. I wanted to include the code but the new spam filters are a tad over enthusiastic.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"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....".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I appreciate your discussions about overloaded compilers, and overloaded operators -
What about overloaded computer programmers ?
Maybe I should have been a sheep farmer.
BAAAA !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
billsincl wrote:
What about overloaded computer programmers ?
Cheer up!
Overloaded Programmer + RTFM = Underloaded and Cheerful Fortran Programmer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
RTFM = "really tough for me" ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"Read The Fine Manual"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page