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

Format numbering

JohnNichols
Valued Contributor III
3,397 Views

I was laughing at myself this morning,  I sometimes hate how you use a nice format numbering system, 100, 110, 120 etc.. , and then you come back and add one, say 115, and it breaks your nice system.  

It would be nice, if IF renumbered your formats for you. 

Of course, that is bizarre request. It clearly shows a brain that has been too long coding Fortran. 

I realize humour is not allowed on this board, we are serious people.  

<I have edited this thrice to correct the English>. 

0 Kudos
23 Replies
AlHill
Super User
3,053 Views

https://ntrs.nasa.gov/citations/19730022396

 

Doc (not an Intel employee or contractor)
[Windows 11 is the new Vista]

0 Kudos
JohnNichols
Valued Contributor III
3,033 Views

Thank you.  I wonder how you get the source code, it would be a useful program.  

0 Kudos
AlHill
Super User
2,940 Views
0 Kudos
mecej4
Honored Contributor III
2,816 Views

A link to the source code for a version of Tidy is available at https://www.pdas.com/tidy.html . Note, however, that Tidy accepts only Fortran 77 (and earlier) source input.

0 Kudos
JohnNichols
Valued Contributor III
2,770 Views

Thank you.  I never knew this program existed, one can live in a world and miss the simplest things.  

The current maintainer is retired from the University.  

0 Kudos
AlHill
Super User
2,754 Views

John, are you having fun yet? <G>

 

Doc

 

0 Kudos
JohnNichols
Valued Contributor III
2,716 Views

Doc:

You kindly asked if I was having fun.  

Actually, yesterday I was thinking about this forum.  It is interesting to think about the statistical properties of a group.  We are a group. I was once asked to explain the Student's t Test in a presentation of the Royal Society of NSW.  I used the example of the age of the officers of the Society and showed that it was improbable that a member of the kindergarten class at Belmont Infants school was an officer based on age difference.  

What got me thinking was the number of views, the problem is there is no way of knowing the distribution of new views to repeat views, so we have an unknown property in the data, so the analysis is restricted. It is philosophically similar to the problem of counting deaths in earthquakes, if a hermit in Papua New Guinea dies alone in a collapsed hut in the highlands, then the count of fatal earthquakes is incorrect and the annual death toll is incorrect. The first is more than interesting as the count is about 20, the second is a blip as the count is about 20,000.   

I can count the number of people that post.  So we know that is two groups, the super users who attempt to solve the unsolvable with limited information, i.e. a Doctor giving a diagnoses.  Some Doctor's are kind, and some are old and gruff, like the nursery tales, but the only thing of real interest is do they make you better or do you die.  The second group here is the people who are flailing around in search of a solution.

The other is the ghosts who just watch, aka the Guinness commercial "I like to watch" . How many ghosts there are, is known only to Intel and God.  I would suspect that on someone's annual report there is a justification for this number of users making their job important.  

My guess as a first shot in setting up a model is 20 permanent, about 300 per month, and maybe 250 to 500 ghosts.

Of course Intel knows the count and really they are probably interested in annual counts.  Intel set up this forum for a few purposes, ... 

But now I have to go and solve another pressing problem. 

  

0 Kudos
JohnNichols
Valued Contributor III
2,674 Views

Doc:

There are a lot of humans watching this forum, in 98 minutes 38 people have viewed this last missive, which is one every 2.5 minutes.  I mean that is a high hit rate for a small forum of limited interest to a very narrow group of elderly Fortran programmers.

Continuing the :: am I  having fun:

Do not steal other people's code unless you are going to check it.  

Case in point, I needed to do a quick linear regression analysis on linear and then log mapped data.  I grabbed this code, 

 

SUBROUTINE MAP_UTIL_ANALY(J8,J9,CONST,SLOPE,CORR,X,Y)
    REAL X(J8),Y(J8),AX,AY,AX2,AY2,AXY
    REAL CONST,SLOPE,CORR
    INTEGER I1,J8,J9,I
    I1=J8
    J8=J8-J9
    AX=0.0D+00
    AY=0.0D+00
    AX2=0.0D+00
    AY2=0.0D+00
    AXY=0.0D+00
    DO 1 I=1,J8
        AX=AX+X(I)
        AY=AY+Y(I)
        AXY=AXY+X(I)*Y(I)
        AX2=AX2+X(I)*X(I)
        AY2=AY2+Y(I)*Y(I)
1   CONTINUE
    CONST=(AY*AX2-AX*AXY)/(J8*AX2-AX*AX)
    SLOPE=((J8*AXY-AX*AY)/(J8*AX2-AX*AX))
    CORR=(J8*AXY-AX*AY)/(SQRT((J8*AX2-AX*AX)*(J8*AY2-AY*AY)))
    J8=I1

    write(*,100)CONST,SLOPE,CORR,CORR*CORR
100 Format("                      Constant     m  :: ",F20.15,/,&
           "                      Slope       m/m :: ",F20.15,/,&
           "                      Correlation R   :: ",F10.5,/,&
           "                      Correlation RSq :: ",F10.5,/)
    RETURN
    END

 

 

I added the write statement. 

I am at the stage of checking the answer, so I use the tried and true EXCEL for simple data set. 

Screenshot 2021-09-29 114537.png

The code gives me R as a return value.  One is so used to the traditional Rsquared being returned and this is a single independent variable  model that is all you want.  I would never expect the R instead of the Rsquared.   

So I grabbed this code to check the map code. 

 

!****************************************************
! 相関係数計算
!
!   date          name            version
!   2018.12.18    mk-mode.com     1.00 新規作成
!
! Copyright(C) 2018 mk-mode.com All Rights Reserved.
!****************************************************
!
module const
  ! SP: 単精度(4), DP: 倍精度(8)
  integer,     parameter :: SP = kind(1.0)
  integer(SP), parameter :: DP = selected_real_kind(2 * precision(1.0_SP))
end module const

module comp
  use const
  implicit none
  private
  public :: calc_r

contains
  ! 相関係数計算
  !
  ! :param(in) real(8) x(:): X 値配列
  ! :param(in) real(8) y(:): Y 値配列
  ! :return    real(8)    r: 相関係数
  function calc_r(x, y) result(r)
    implicit none
    real(DP), intent(in) :: x(:), y(:)
    real(DP)    :: r
    integer(SP) :: size_x, size_y, i
    real(DP)    :: mean_x, mean_y, cov, var_x, var_y

    size_x = size(x)
    size_y = size(y)
    if (size_x == 0 .or. size_y == 0) then
      print *, "[ERROR] array size == 0"
      stop
    end if
    if (size_x /= size_y) then
      print *, "[ERROR] size(X) != size(Y)"
      stop
    end if

    r = 0.0_DP
    mean_x = sum(x) / size_x
    mean_y = sum(y) / size_y
    cov = sum((x(1:size_x) - mean_x) * (y(1:size_x) - mean_y))
    var_x = sum((x(1:size_x) - mean_x) * (x(1:size_x) - mean_x))
    var_y = sum((y(1:size_x) - mean_y) * (y(1:size_x) - mean_y))
    r = (cov / sqrt(var_x)) / sqrt(var_y)
  end function calc_r
end module comp

program correlation_coefficient
  use const
  use comp
  implicit none
  real(DP)    :: x(10), y(10), r
  integer(SP) :: i

  x = (/(i, i=1,10)/)

  y = (/(i, i=1,10)/)
  r = calc_r(x, y)
  print '("X = (", 10F6.2, ")")', x
  print '("Y = (", 10F6.2, ")")', y
  print '("r = ", F11.8)', r
  print *

  y = (/2, 3, 3, 4, 6, 7, 8, 9, 10, 11/)
  r = calc_r(x, y)
  print '("X = (", 10F6.2, ")")', x
  print '("Y = (", 10F6.2, ")")', y
  print '("r = ", F11.8)', r
  print *

  y = (/15, 13, 12, 12, 10, 10, 8, 7, 4, 3/)
  r = calc_r(x, y)
  print '("X = (", 10F6.2, ")")', x
  print '("Y = (", 10F6.2, ")")', y
  print '("r = ", F11.8)', r
end program correlation_coefficient

 

The Chinese comment says Pearson coefficient, so this is also R as one observes by looking at the equations.  

As some one observed to me yesterday, how do you know the code is correct?  I looked and said, you check against known data and methods and you look at the graphs and say - does it look ok.  

Fun - yes a pleasant interlude, like reading a murder mystery.  

of course I should not have been lazy and use the NR in Fortran. 

 

0 Kudos
AlHill
Super User
2,648 Views

Looks like you are having fun.   When you get Tidy running, post the before and after on a piece of code.

 

Doc

0 Kudos
JohnNichols
Valued Contributor III
2,623 Views

Doc:

TIDY is designed to be run on LAHEY's Fortran - the Uni guy must have used that compiler.  

I have loaded it as a VS sln with Intel Fortran, I have added a very old F77 file hagar.for to the debug directory as a test case. 

This program generates kerb return profiles, I think.  

I fixed the getcommand arguments so it runs, but I do know how to pass a cmd line argument in Fortran in VS.  

The program crashed on the IF cmd window at line 1689 or there abouts.  

Much easier to debug in VS than as a command line.  <personal opinion only.>

Anyone know how to put a cmd line argument in VS.  I can do it for C# but IF is different and I have to pick up a child from school, so I cannot do it right now.  

JMN

0 Kudos
MWind2
New Contributor III
2,618 Views
0 Kudos
jimdempseyatthecove
Honored Contributor III
2,611 Views

>>but I do know how to pass a cmd line argument in Fortran in VS. 

Select Release or Debug build as current solution | Right click on project in solution explorer | Properties | Debugging | Arguments | place your arguments there.

Jim Dempsey

0 Kudos
andrew_4619
Honored Contributor III
2,995 Views

I never create numbered formats any more I created them as parameter with character strings. You can call them what you want then, descriptive name  etc.  Numbered formats and numbered lines seem like constructs from the last century to my eyes.

0 Kudos
JohnNichols
Valued Contributor III
2,939 Views

       INTEGER(1) int1
       INTEGER    int2, int3, array(3)
       LOGICAL(1) log1
       LOGICAL log2, log3
       REAL    real1
       REAL(8) real2
       COMPLEX z1, z2
       CHARACTER(1)  char1
       CHARACTER(10) char2

       NAMELIST /example/ int1, int2, int3, log1, log2, log3,       &
      &          real1, real2, z1, z2, char1, char2, array

       int1     = 11
       int2     = 12
       int3     = 14
       log1     = .TRUE.
       log2     = .TRUE.
       log3     = .TRUE.
       real1    = 24.0
       real2    = 28.0d0
       z1       = (38.0,0.0)
       z2       = (316.0d0,0.0d0)
       char1    = 'A'
       char2    = '0123456789'
       array(1) = 41
       array(2) = 42
       array(3) = 43
       WRITE (*, example)

There are sometimes many ways to achieve the same end.  

Both achieve the same thing, communication. 

 

0 Kudos
andrew_4619
Honored Contributor III
2,912 Views
     character(*), parameter :: fmt_nodal_times = '(I0,*(1x,f0.6))'
1234 format(i0,*(1x,f0.6))
     write(unit, fmt_nodal_times) j, t(:)
     write(unit, 1234) j, t(:)

Not really, giving something a name can give much more meaning than giving something an arbitrary unique  number. 

0 Kudos
JohnNichols
Valued Contributor III
2,592 Views

We are lucky we can do it two ways.  

The TIDY has a lot of stuff like you show and I am finding it interesting to navigate.  

20       IF (I.EQ.0.OR.LDEF(I).GE.0) THEN
              LDEF(I+1)=L15
              LOCDEF(I+1)=NREC
              NNMKLS(I+1)=5
              GO TO 90
          END IF

 

IFORT Is crashing on LINE 20 when I = 0.  I know why, but why would it not have been caught in other compilers.  Technically it should not crash if the compiler is optimized.  <personal viewpoint> 

 

0 Kudos
JohnNichols
Valued Contributor III
2,589 Views

it is now running, HAGAR.FOR has become HAGAR.TID  and is about 100 lines shorter and the format numbers adjusted.  

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,522 Views

>>IF (I.EQ.0.OR.LDEF(I).GE.0) THEN

With Fortran "LDEF(I).GE.0" can (not necessarily is) evaluated before "I.EQ.0"

IOW both sides of the .OR. are evaluated. This is different from C where left-to-right evaluations can preempt further evaluations.

Therefore the statement could execute an index out of range.

Technically the program produces undefined behavior.

Jim Dempsey

0 Kudos
JohnNichols
Valued Contributor III
2,487 Views

Yes, clearly this is a logic error in the algorithm, but one can assume that it has been there for a very long time.  I think this program started in 1966.  

The statement will work if the Fortran compiler, tests i == 0, it is true and falls out of the if statement. 

I mean it is almost like a Pavlovian response, one codes and it works, and most people learn the basic rules quickly and then try it.  

If something works we continue to use it.  

Then we are surprised when a later compiler tags it as an error or has a fatal error in what ever form.  

I mean how often does one see someone ask about a command, and mecej4, or you or FF or Steve explain the true intent of Fortran.  

Ajit J. Thakkar from Canada has maintained the program, although he is now retired.  He was running the program on Laheys' Fortran I believe,  I wonder why it did not trip on the older compilers. 

Anyway, it is a question for the Gods.   But I will send him an email and ask.  

Of course one is mindful of the dreadful experiences with old code and Powerstation Fortran. 

 

0 Kudos
mecej4
Honored Contributor III
2,442 Views

JohnNichols said :

"Technically it should not crash if the compiler is optimized.  <personal viewpoint> "

It is not the optimization of the compiler that is at issue, it is the optimization of the compiled version of your code that the compiler produces.

When the code has bugs, they are more likely to be exposed when higher optimization levels are used.

Some programming languages use short circuit evaluation. Fortran does not prohibit it, but code that requires it is not standard-conforming. A Fortran program that was developed and debugged only on processors that employed short circuit evaluation is at risk of failing when used on a system where short circuit evaluation is not assured. There have been many proposals, such as for adding logical operators .COR. and .CAND. for adding short circuit evaluation to Fortran. See the second page of EWD1009 for a discussion from 1987.

0 Kudos
Reply