STL analogue in Fortran
There are no templates in Fortran and hence no STL. You can try FLIBS for some generic libraries. It generally uses transfer()
tricks to achieve generic programming.
There is a preprocessor which adds some templates to Fortran and comes with some small STL, you can try that too named PyF95++. If you have access to academic papers through some library, you can read about it here.
I would avoid mixing it with C++ in this specific case although it can be done. You must instantiate each case separately and interface it to Fortran using a wrapper (bind(C)
and iso_c_binding
). Only if you have a very limited number of types you want to use the algorithms for it could be worth it.
You can also try to implement some poor-man's templates using the C-preprocessors in Fortran, For smaller libraries it works, but can become too difficult to maintain or ugly for complex things. As an example you can see my implementation of a linked list https://github.com/LadaF/fortran-list .
Generally, there is no clearly right approach or answer, you always have to choose from more possibilities.
Writing optimal code in FORTRAN using array expressions
I have scanned many sources (~20 books and dozens of web pages). Hard luck I missed something really important. The question I posted is indeed incorrect and comes from my initial high expectation about array operations in fortran.
The answer I would expect is: there are no tools to write short, readable code in fortran with automatic parallelization (to be more precise: there are, but those are proprietary libraries).
The list of intrinsic functions available in fortran is quite short
(link), and consists only of functions easily mapped to SIMD ops.
There are lots of functions that one will be missing.
- while this could be resolved by separate library with separate implementation for each platform, fortran doesn't provide such. There are commercial options (see this thread)
Brief examples of missing functions:
no built-in array
sort
orunique
. The proposed way is to use this library, which provides single-threaded code (forget threads and CUDA)cumulative sum / running sum. One trivially can implement it, but the resulting code will never work fine on threads/CUDA/Xeon Phi/whatever comes next.
bincount, numpy.ufunc.at, numpy.ufunc.reduceat (which is very useful in many applications)
In most cases fortran provides 2x speed up even with simple implementations, but the code written will always be one-threaded, while matlab/numpy functions can be reimplemented for GPU or other parallel platform without any effort from user side (which occasionally happened to MATLAB, also see gnumpy, theano and parakeet)
To conclude, this is bad news for me. Fortran developers really care about having fast programs today, not in the future. I also can't lock my code on proprietary software. And I'm still looking for appropriate tool. (Julia is current candidate)
See also:
STL analogue in fortran
where ready-to-use algorithms are asked.Numerical recipes: the art of parallel programming author implements basic MATLAB-like operations to have more expressive code
I also find useful these notes to see recommended ways of code optimizations (to see there is no place for vector operations)
numpy, fortran, blitz++: a case study
dicussion about implementing unique in fortran, where proprietary tools are recommended.
Fortran: Handling types with different kind in generic procedures
No, it is not possible. Not even with parametrized derived types.
You must manually create each specific procedure. There are many tricks with preprocessors which can assist you to do some poor-man's C++-like tempting. Examples can be found even on StackOverflow. See, among others, STL analogue in Fortran .
Two derived types sharing same subroutine
Error messages are, admittedly, not always helpful. In this case it is a good prompt.
Your derived type Interval
has a type-bound procedure with binding name eptset
and interface the same as the procedure inrval_set
. This is your difficulty.
I imagine you have in mind a call like
type(Interval) range
call range%eptset(1._real32, 15._real32)
which is a reasonable goal.
However, you are relying on a passed-object dummy argument, so that in inrval_set
your first dummy argument t
is of dynamic type range
. This is flawed.
As the error message suggests, the interface for the type-bound procedure in Interval
must, because it doesn't have the NOPASS
attribute, have a dummy argument of type Interval
. A dummy argument of class(*)
is not such a thing.
You don't want to do this approach using NOPASS
.
You could, of course, have
call inrval_set(range, 1._real32, 15._real32)
as one option. But are there type-bound ways?
Yes.
You could consider templating. Or, have an (abstract) parent class. Or provide type-bound procedures with the appropriate interface - one for each type.
Essentially, you're repeating code in the select type
block, so you may as well repeat the code with generic/dynamic resolution instead.
Related Topics
Somehow Register My Classes in a List
How to Optimize Matrix Multiplication (Matmul) Code to Run Fast on a Single Processor Core
Qt3D. Draw Transparent Qspheremesh Over Triangles
Distinguish Between Single and Double Click Events in Qt
"No Appropriate Default Constructor Available"--Why Is the Default Constructor Even Called
Difference Between Cc, Gcc and G++
Embedded C++:To Use Stl or Not
Does 'Auto' Type Assignments of a Pointer in C++11 Require '*'
Detect Gcc Compile-Time Flags of a Binary
Std::Vector to String with Custom Delimiter
How to Use Cin.Fail() in C++ Properly
Why How to Call Base Template Class Method from Derived Class
How to Make Gcc Warn on Passing Too-Wide Types to Functions
What Does "#Define Str(A) #A" Do
Differencebetween Cout, Cerr, Clog of iOStream Header in C++? When to Use Which One