Smoothing Data and Identifying Hot and Cold Spots in Fortran 90

I_MAX * J_MAX!FIND THE HOT AND COLD SPOTS AND AVERAGE THE CELLS TO REPLACE THEIR VALUES!PSEUDOCODEDO I = 2, 299 DO J = 2, 399 IF ((DATA_ARRAY(I, J) .EQ. 0.0) .OR. (DATA_ARRAY(I, J) .GT. 1000.0)) THEN IF (DATA_ARRAY(I, J) .EQ. 0.0) THEN NUM_OF_HOTSPOTS = NUM_OF_HOTSPOTS + 1 DATA_ARRAY_AVERAGED(I, J) = (DATA_ARRAY(I-1, J) +
  • #1
isuckathw
5
0

Homework Statement



Write a program that that prompts the user for a filename of data, reads the data from the input file, smooths the data using the average value of the cell value and all of the nearest neighbors

-9 cell average for interior cells
-6 cell average for edge cells
-4 cell average for corner cells

However

-Any value of 0.0 is a cold spot. Do not include in averaging but replace with average of neighbors

-any value >= 1000 is a hot spot, replace with average of neighbors as well

Write the output to 2 files, one formatted and one unformatted, and tell user how many hot and cold spots there are.

Here is my attempt so far. I just have no idea where to start with the 9 cell averaging. I mean NO CLUE. Please,
Code:
PROGRAM FILE_CHECKER
IMPLICIT NONE

REAL :: I, J, I_MAX, J_MAX, PERCENT_OF_TOT_COLD, PERCENT_OF_TOT_HOT
CHARACTER(LEN=30) :: INPUT_FILE_1
REAL, DIMENSION(300:400):: DATA_ARRAY, DATA_ARRAY_AFTER_REPLACEMENT
INTEGER :: NUM_OF_ELEMENTS, NUM_OF_HOTSPOTS, NUM_OF_COLDSPOTS!PROMPT THE USER FOR THE FILE 
PRINT *, "Enter the full name of the image file you wish to check for errors"
!READ THE FILE
READ *, INPUT_FILE_1
!PRINT THE FILE TO MAKE SURE THIS THE ONE THE WISH TO USE
PRINT *, "The file to be checked is ", INPUT_FILE_1
!OPEN THE FILE
OPEN(1, FILE=INPUT_FILE_1, ACTION="READ", FORM='UNFORMATTED')
!READ THE FILE TO GET DIMENSIONS 
READ(1) I_MAX, J_MAX
READ(1) DATA_ARRAY
!FIND THE NUMBER OF TOTAL ELEMENTS
NUM_OF_ELEMENTS = I_MAX*J_MAX
!PRINT THE # OF ROWS AND COLUMNS AND THE # OF ELEMENTS IN THE ARRAY AND THE ARRAY     
PRINT *, "The number of rows is", I_MAX, "The number of columns is", J_MAX
PRINT *, "The number of elements in the array is", NUM_OF_ELEMENTS
PRINT *, "HERE IS THE ARRAY ", DATA_ARRAY
!FIND THE HOT AND COLD SPOTS AND AVERAGE THE CELLS TO REPLACE THEIR VALUES
!HERE IS WHERE I HAVE NO IDEA WHAT TO DO. <---------------------------------------------------------
!CLOSE THE FILE
CLOSE(1)

!WE WRITE A FORMATTED FILE OF THE OUTPUT
OPEN(2, FILE="FORMATTED_FORTRAN_OUTPUT_1.DAT", ACTION="WRITE", FORM="FORMATTED")
WRITE(2) DATA_ARRAY_AFTER_REPLACEMENT
CLOSE(2)

!WE WRITE AN UNFORMATTED FILE OF THE OUTPUT
OPEN(3, FILE="UNFORMATTED_FORTRAN_OUTPUT_1.DAT", ACTION="WRITE", FORM="UNFORMATTED")
WRITE(3) DATA_ARRAY_AFTER_REPLACEMENT
CLOSE(3)

!PRINT THE NUMBER OF HOT AND COLD SPOTS
PRINT *, "THE NUMBER OF HOTSPOTS IS ", NUM_OF_HOTSPOTS
PRINT *, "THE NUMBER OF COLDSPOTS IS ". NUM_OF_COLDSPOTS
!PRINT THE PERCENTAGE OF THE WHOLE OF HOTSPOTS AND COLDSPOTS
PERCENT_OF_TOT_HOT = (NUM_OF_HOTSPOTS / NUM_OF_ELEMENTS) * 100
PRINT *, "THE PERCENTAGE OF HOTSPOTS TO THE TOTAL NUMBER OF PIXELS IS: ", PERCENT_OF_TOT_HOT
PERCENT_OF_TOT_COLD = (NUM_OF_COLDSPOTS / NUM_OF_ELEMENTS) * 100
PRINT *, "THE PERCENTAGE OF COLDSPOTS TO THE TOTAL NUMBER OF PIXELS IS: ", PERCENT_OF_TOT_COLD

!WE ARE DONE, END THE PROGRAM

END PROGRAM FILE_CHECKER

Please help, thank you
 
Last edited:
Physics news on Phys.org
  • #2
I, J, I_MAX, J_MAX should be INTEGER, not REAL. Also, NUM_OF_HOTSPOTS and NUM_OF_COLDSPOTS have to be initialized to 0.

You need a DO loop nested within another DO loop to cycle through DATA_ARRAY, looking for hot spots.
Code:
DO I=1, 300 
  DO J=1, 400
    IF ((DATA_ARRAY(I, J) .EQ. 0.0) .OR. (DATA_ARRAY(I, J) .GT. 1000.0)) THEN
      IF (DATA_ARRAY(I, J) .EQ. 0.0) NUM_OF_HOTSPOTS= NUM_OF_HOTSPOTS+ 1
      IF (DATA_ARRAY(I, J) .GT. 1000.0) NUM_OF_COLDSPOTS= NUM_OF_COLDSPOTS+ 1

       ! pseudocode
       if it's a corner, calculate average of its three neighbors
       if it's an edge, calculate average of its five neighbors
       otherwise calculate average of its eight neighbors
       store calculated average in DATA_ARRAY(I, J)
       store calculated average in DATA_ARRAY_AFTER_REPLACEMENT(I, J)
    ELSE
      store value in DATA_ARRAY_AFTER_REPLACEMENT(I, J)
    ENDIF
  END DO
END DO

There are only four corner points: at DATA_ARRAY(1, 1), DATA_ARRAY(300, 1), DATA_ARRAY(1, 400), and DATA_ARRAY(300, 400). Handle each case separately, adding the three neighboring values together, and divide the total by 4.

There are a lot more edge cases: when the row number is 1 or 300, or when the column number is 1 or 400. It probably makes more sense to handle these as four separate cases. In each case add up the values of the surrounding five neighbor values, and divide the total by 6.

Interior hot/cold spots. Add up the values of the eight neighbor cells and divide the total by 9.
 
  • #3
Mark44 said:
I, J, I_MAX, J_MAX should be INTEGER, not REAL. Also, NUM_OF_HOTSPOTS and NUM_OF_COLDSPOTS have to be initialized to 0.

You need a DO loop nested within another DO loop to cycle through DATA_ARRAY, looking for hot spots.

There are only four corner points: at DATA_ARRAY(1, 1), DATA_ARRAY(300, 1), DATA_ARRAY(1, 400), and DATA_ARRAY(300, 400). Handle each case separately, adding the three neighboring values together, and divide the total by 4.

There are a lot more edge cases: when the row number is 1 or 300, or when the column number is 1 or 400. It probably makes more sense to handle these as four separate cases. In each case add up the values of the surrounding five neighbor values, and divide the total by 6.

Interior hot/cold spots. Add up the values of the eight neighbor cells and divide the total by 9.

Thank you so much, that helped out tremendously!
 
  • #4
If you know how to write subroutines, you could write one to handle corner cells, another to handle edge cells, and one more to handle interior cells. Each subroutine would have three parameters: the row, the column, and the array itself.
 
  • #5
Mark44 said:
If you know how to write subroutines, you could write one to handle corner cells, another to handle edge cells, and one more to handle interior cells. Each subroutine would have three parameters: the row, the column, and the array itself.

I keep getting stupid numbers for my hot and cold spots, along with the percentage

Here's what I have

Code:
PROGRAM FILE_CHECKER
IMPLICIT NONE
REAL :: PERCENT_OF_TOT_COLD, PERCENT_OF_TOT_HOT
CHARACTER(LEN=30) :: INPUT_FILE, ANSWER
REAL, DIMENSION(300,400):: DATA_ARRAY, DATA_ARRAY_AVERAGED
INTEGER :: I, J, I_MAX, J_MAX, NUM_OF_ELEMENTS, NUM_OF_HOTSPOTS, NUM_OF_COLDSPOTS


!PROMPT THE USER FOR THE FILE 
PRINT *, "ENTER THE FULL NAME OF THE IMAGE FILE YOU WISH TO CHECK FOR ERRORS"
!READ THE FILE
READ *, INPUT_FILE
!PRINT THE FILE TO MAKE SURE THIS THE ONE THE WISH TO USE
PRINT *, "THE FILE TO BE CHECKED IS ", INPUT_FILE
!OPEN THE FILE
OPEN(1, FILE=INPUT_FILE, ACTION="READ", FORM='UNFORMATTED')
READ(1) I_MAX, J_MAX
READ(1) DATA_ARRAY
!FIND THE NUMBER OF TOTAL ELEMENTS
NUM_OF_ELEMENTS = I_MAX*J_MAX
!PRINT THE # OF ROWS AND COLUMNS AND THE # OF ELEMENTS IN THE ARRAY AND THE ARRAY     
PRINT *, "THE NUMBER OF ROWS IS ",I_MAX  , "THE NUMBER OF COLUMNS IS ",J_MAX
PRINT *, "THE NUMBER OF ELEMENTS IN THE ARRAY IS ", NUM_OF_ELEMENTS
PRINT *, "WOULD YOU LIKE TO PRINT THE ARRAY? (Y OR N)"
READ *, ANSWER
SELECT CASE(ANSWER)
    CASE ('Y')
        PRINT *, DATA_ARRAY, "NOW CHECKING FOR HOT AND COLD SPOTS..."
    CASE ('N')
        PRINT *, "NOW CHECKING FOR HOT AND COLD SPOTS..."
    CASE ('y')
       	PRINT *, DATA_ARRAY, "NOW CHECKING FOR HOT AND COLD SPOTS..."
    CASE ('n')
        PRINT *, "NOW CHECKING FOR HOT AND COLD SPOTS..."
END SELECT
!THE INTERIOR

DO I = 1, I_MAX
  DO J = 1, J_MAX
       IF (DATA_ARRAY(I, J) .EQ. 0) NUM_OF_COLDSPOTS = NUM_OF_COLDSPOTS + 1
       IF (DATA_ARRAY(I, J) .GT. 1000) NUM_OF_HOTSPOTS = NUM_OF_HOTSPOTS +1
  END DO
END DO

PRINT *, "THIS IS A CHECK. INTERIOR BEING RAN NOW"

DO I=2, I_MAX-1
  DO J=2, J_MAX-1
      IF (DATA_ARRAY(I,J) .EQ. 0) DATA_ARRAY(I,J) = (DATA_ARRAY(I-1,J-1)+DATA_ARRAY(I,J-1)+DATA_ARRAY(I-1,J)+ &
DATA_ARRAY(I+1,J-1)+DATA_ARRAY(I-1,J+1)+DATA_ARRAY(I+1,J)+DATA_ARRAY(I,J+1)+DATA_ARRAY(I+1,J+1))/9
      IF (DATA_ARRAY(I,J) .GT. 1000) DATA_ARRAY(I,J) = (DATA_ARRAY(I-1,J-1)+DATA_ARRAY(I,J-1)+DATA_ARRAY(I-1,J)+&
DATA_ARRAY(I+1,J-1)+DATA_ARRAY(I-1,J+1)+DATA_ARRAY(I+1,J)+DATA_ARRAY(I,J+1)+DATA_ARRAY(I+1,J+1))/9
END DO 
END DO


PRINT *, "THIS IS A CHECK. LEFT SIDE BEING RAN NOW"

!LEFT SIDE
DO I=2, I_MAX-1
 DO J=0,1
  IF (DATA_ARRAY(I,J) .EQ. 0) DATA_ARRAY(I,J) = (DATA_ARRAY(I-1,J)+DATA_ARRAY(I-1,J+1)+DATA_ARRAY(I+1,J)+&
DATA_ARRAY(I,J+1)+DATA_ARRAY(I+1,J+1))/6
  IF (DATA_ARRAY(I,J) .GT. 1000) DATA_ARRAY(I,J) = (DATA_ARRAY(I-1,J)+DATA_ARRAY(I-1,J+1)+&
DATA_ARRAY(I+1,J)+DATA_ARRAY(I,J+1)+DATA_ARRAY(I+1,J+1))/6
END DO
END DO

PRINT *, "THIS IS A CHECK, TOP SIDE BEING RAN NOW"

!TOP SIDE
DO J=2, J_MAX-1
 DO I=0,1
  IF (DATA_ARRAY(I,J) .EQ. 0) DATA_ARRAY(I,J) = (DATA_ARRAY(I,J-1)+DATA_ARRAY(I-1,J-1)+DATA_ARRAY(I-1,J)+&
DATA_ARRAY(I-1,J+1)+DATA_ARRAY(I,J+1))/6
  IF (DATA_ARRAY(I,J) .GT. 1000) DATA_ARRAY(I,J) = (DATA_ARRAY(I,J-1)+DATA_ARRAY(I-1,J-1)+&
DATA_ARRAY(I-1,J)+DATA_ARRAY(I-1,J+1)+DATA_ARRAY(I,J+1))/6
END DO
END DO

PRINT *, "THIS IS A CHECK, RIGHT SIDE BEING RAN NOW"

!RIGHT SIDE
DO I=2, I_MAX-1
 DO J=J_MAX-1, J_MAX
  IF (DATA_ARRAY(I,J) .EQ. 0) DATA_ARRAY(I,J) = (DATA_ARRAY(I-1,J)+DATA_ARRAY(I-1,J-1)+DATA_ARRAY(I+1,J)+&
DATA_ARRAY(I,J-1)+DATA_ARRAY(I+1,J-1))/6
  IF (DATA_ARRAY(I,J) .GT. 1000) DATA_ARRAY(I,J) = (DATA_ARRAY(I-1,J)+DATA_ARRAY(I-1,J-1)+DATA_ARRAY(I+1,J)+&
DATA_ARRAY(I,J-1)+DATA_ARRAY(I+1,J-1))/6   
END DO
END DO

PRINT *, "THIS IS A CHECK, BOTTOM SIDE BEING RAN NOW"

!BOTTOM SIDE
 DO J=2, J_MAX-1
  DO I=I_MAX-1, I_MAX
  IF (DATA_ARRAY(I,J) .EQ. 0) DATA_ARRAY(I,J) = (DATA_ARRAY(I-1,J-1)+DATA_ARRAY(I,J-1)+DATA_ARRAY(I-1,J)+&
DATA_ARRAY(I-1,J+1)+DATA_ARRAY(I,J+1))/6
  IF (DATA_ARRAY(I,J) .GT. 1000) DATA_ARRAY(I,J) = (DATA_ARRAY(I-1,J-1)+DATA_ARRAY(I,J-1)+&
DATA_ARRAY(I-1,J)+DATA_ARRAY(I-1,J+1)+DATA_ARRAY(I,J+1))/6
END DO 
END DO

PRINT *, "THIS IS A CHECK, TOP LEFT CORNER BEING RAN NOW"

!TOP LEFT CORNER
IF ((DATA_ARRAY(1,1) .EQ. 0) .OR. (DATA_ARRAY(1,1) .GT. 1000)) DATA_ARRAY(1,1) = (DATA_ARRAY(1,2) + DATA_ARRAY(2,2) + DATA_ARRAY(2,1))/4

PRINT *, "THIS IS A CHECK, TOP RIGHT CORNER BEING RAN NOW"

!TOP RIGHT CORNER
IF ((DATA_ARRAY(1,J_MAX) .EQ. 0) .OR. (DATA_ARRAY(1, J_MAX) .GT. 1000)) DATA_ARRAY(1, J_MAX) = (DATA_ARRAY(1, J_MAX-1) +&
 DATA_ARRAY(2, J_MAX-1) + DATA_ARRAY(2, J_MAX))/4

PRINT *, "THIS IS A CHECK, BOTTOM RIGHT CORNER BEING RAN NOW"

!BOTTOM RIGHT CORNER
IF ((DATA_ARRAY(I_MAX, J_MAX) .EQ. 0) .OR. (DATA_ARRAY(I_MAX,J_MAX) .GT. 1000)) DATA_ARRAY(I_MAX, J_MAX) = (DATA_ARRAY(I_MAX, J_MAX -1)&
 + DATA_ARRAY(I_MAX-1, J_MAX-1) + DATA_ARRAY(I_MAX, J_MAX-1))/4

PRINT *, "THIS IS A CHECK, BOTTOM LEFT CORNER BEING RAN NOW"

!BOTTOM LEFT CORNER 
IF ((DATA_ARRAY(I_MAX, 1) .EQ. 0) .OR. (DATA_ARRAY(I_MAX,1) .GT. 1000)) DATA_ARRAY(I_MAX, 1) = (DATA_ARRAY(I_MAX-1, 1) +&
 DATA_ARRAY(I_MAX-1, 2) + DATA_ARRAY(I_MAX,2 ))/4

!WE WRITE A FORMATTED FILE OF THE OUTPUT OF THE SMOOTHED ARRAY

!PRINT THE NUMBER OF HOT AND COLD SPOTS
PRINT *, "THE NUMBER OF HOTSPOTS IS ", NUM_OF_HOTSPOTS
PRINT *, "THE NUMBER OF COLDSPOTS IS ", NUM_OF_COLDSPOTS

!PRINT THE PERCENTAGE OF THE WHOLE OF HOTSPOTS AND COLDSPOTS
PERCENT_OF_TOT_HOT = (NUM_OF_HOTSPOTS / NUM_OF_ELEMENTS) * 100
PRINT *, "THE PERCENTAGE OF HOTSPOTS TO THE TOTAL NUMBER OF PIXELS IS: ",PERCENT_OF_TOT_HOT
PERCENT_OF_TOT_COLD = (NUM_OF_COLDSPOTS / NUM_OF_ELEMENTS) * 100
PRINT *, "THE PERCENTAGE OF COLDSPOTS TO THE TOTAL NUMBER OF PIXELS IS: ",PERCENT_OF_TOT_COLD

CLOSE(1)

!WE WRITE AN UNFORMATTED FILE OF THE OUTPUT OF THE SMOOTHED ARRAY
OPEN(20, FILE="UNFORMATTED_FORTRAN_OUTPUT_ARRAY.dat", ACTION="WRITE", FORM="UNFORMATTED")
WRITE(20) DATA_ARRAY
CLOSE(20)
PRINT *, "FILE 'UNFORMATTED_FORTRAN_OUTPUT_ARRAY.dat' HAS BEEN CREATED..."

!WE WRITE A FORMATTED FILE OF THE OUTPUT OF THE SMOOTHED ARRAY
OPEN(10, FILE="FORMATTED_FORTRAN_OUTPUT_ARRAY.dat", ACTION="WRITE", FORM="FORMATTED")
WRITE(10) DATA_ARRAY
10 FORMAT(F6.3)
CLOSE(10)
PRINT *, "FILE 'FORMATTED_FORTRAN_OUTPUT_ARRAY.dat' HAS BEEN CREATED..."


END PROGRAM FILE_CHECKER

Any ideas?
 
  • #6
You have a string similar to this in a number of places - "THIS IS A CHECK. LEFT SIDE BEING RAN NOW" - should be "being run now".

In the code I supplied I have one nested loop, not the six that you have. All of the logic for hot spots, cold spots at corners, along the top, bottom, left and right edges, and interior cells can be put in a single nested loop with several IF ELSE statements. The way you did it could be made to work, but is less efficient because it repeatedly cycles through your array instead of going through it once.

Inside my nested loop and surrounded by a pair if nested IF statements I had this pseudocode:
Code:
      ! pseudocode
       if it's a corner, calculate average of its three neighbors
       if it's an edge, calculate average of its five neighbors
       otherwise calculate average of its eight neighbors
       store calculated average in DATA_ARRAY(I, J)
       store calculated average in DATA_ARRAY_AFTER_REPLACEMENT(I, J)
It's easy enough to determine that you're at a corner points. The array indexes will be (1,1), (I_MAX,1), (J_MAX,1) or (I_MAX,J_MAX).
It's a little harder to determine when the element is on an edge of the array. For elements on the left edge, the row will be larger than 1 and smaller than I_MAX, and the column will be 1. Elements on the right edge will be similar, but the column will be J_MAX.
Checking that the element is in the top row is similar, but the row index will be 1. For elements on the bottom edge, the row index will be I_MAX.

You should do all of these as a bunch of IF...ELSEIF ... statements, with one each for corner elements, one each for left/right/top/bottom elements, and the final ELSE statement for interior elements.

When you say you are getting stupid numbers for hot spots/cold spots, what do you mean? Are your counts of them wrong, or or the massaged values wrong? If you are not clear in what you're saying, I can't diagnose the problem as well.

Similarly, if you are not clear in your programming, the code that is generated won't be what you meant it to be. Computers are pretty fast, but they are very stupid and very literal. The computer will do exactly what you tell it to do, whether that's what you want it to do or not.
 
  • #7
Mark44 said:
You have a string similar to this in a number of places - "THIS IS A CHECK. LEFT SIDE BEING RAN NOW" - should be "being run now".

In the code I supplied I have one nested loop, not the six that you have. All of the logic for hot spots, cold spots at corners, along the top, bottom, left and right edges, and interior cells can be put in a single nested loop with several IF ELSE statements. The way you did it could be made to work, but is less efficient because it repeatedly cycles through your array instead of going through it once.

Inside my nested loop and surrounded by a pair if nested IF statements I had this pseudocode:
Code:
      ! pseudocode
       if it's a corner, calculate average of its three neighbors
       if it's an edge, calculate average of its five neighbors
       otherwise calculate average of its eight neighbors
       store calculated average in DATA_ARRAY(I, J)
       store calculated average in DATA_ARRAY_AFTER_REPLACEMENT(I, J)
It's easy enough to determine that you're at a corner points. The array indexes will be (1,1), (I_MAX,1), (J_MAX,1) or (I_MAX,J_MAX).
It's a little harder to determine when the element is on an edge of the array. For elements on the left edge, the row will be larger than 1 and smaller than I_MAX, and the column will be 1. Elements on the right edge will be similar, but the column will be J_MAX.
Checking that the element is in the top row is similar, but the row index will be 1. For elements on the bottom edge, the row index will be I_MAX.

You should do all of these as a bunch of IF...ELSEIF ... statements, with one each for corner elements, one each for left/right/top/bottom elements, and the final ELSE statement for interior elements.

When you say you are getting stupid numbers for hot spots/cold spots, what do you mean? Are your counts of them wrong, or or the massaged values wrong? If you are not clear in what you're saying, I can't diagnose the problem as well.

Similarly, if you are not clear in your programming, the code that is generated won't be what you meant it to be. Computers are pretty fast, but they are very stupid and very literal. The computer will do exactly what you tell it to do, whether that's what you want it to do or not.

OK, I will give the elseif approach a try,

When I say I am getting stupid numbers, I get numbers that are in the millions and negative for the hot/coldspots along with the percentage. Not really sure why. I will try your approach though.
 
  • #8
You're still not being clear. Are the numbers in the millions and negative part of the data or are they the counts of the hot/cold spots?

Assuming that you are talking about the counts, whenever you use a counting variable, you ALWAYS have to initialize it to 0.
 
  • #9
Mark44 said:
You're still not being clear. Are the numbers in the millions and negative part of the data or are they the counts of the hot/cold spots?

Assuming that you are talking about the counts, whenever you use a counting variable, you ALWAYS have to initialize it to 0.

No, the data file itself consists of 120,000 data points the are numbers, most of which are in between 0 and 1000. The program is designed to find those points which are not in between 0 and 1000. The number of hotspots and coldspots the code outputs is in the range of ~-10,000,000 or something. Obviously that can't be right b/c first of all its negative and secondly because there aren't even that many data points. That's why I said they were "stupid" numbers, although I apologize for my lack of clarity.
 
  • #10
NUM_OF_HOTSPOTS and NUM_OF_COLDSPOTS are counter variables. You have to initialize them to 0 before using them.
 

Related to Smoothing Data and Identifying Hot and Cold Spots in Fortran 90

1. What is Fortran 90 and why is it important in the scientific community?

Fortran 90 is a programming language specifically designed for scientific computing. It is important because it allows for efficient and accurate implementation of mathematical and scientific algorithms, making it a powerful tool for scientists to solve complex problems and analyze large data sets.

2. What are the key features of Fortran 90?

Some key features of Fortran 90 include its support for array operations, modular programming, and dynamic memory allocation. It also has improved data handling capabilities, such as the ability to work with strings and structures.

3. How is Fortran 90 different from previous versions of Fortran?

Fortran 90 introduced many significant changes and improvements over its predecessor, Fortran 77. Some of these include new data types, improved control structures, and the ability to create user-defined functions and subroutines. It also has a more modern and structured syntax.

4. What resources are available for learning Fortran 90?

There are many online tutorials, books, and courses available for learning Fortran 90. Some popular resources include "Fortran 90/95 for Scientists and Engineers" by Stephen Chapman and "Introduction to Programming with Fortran" by Ian Chivers and Jane Sleightholme. Many universities also offer courses and workshops on Fortran programming.

5. Can you provide Fortran 90 assignment help or tutoring?

As a scientist, my expertise lies in using Fortran 90 for scientific computing rather than providing assignment help or tutoring. However, there are many online forums and communities dedicated to Fortran where you can seek help from experienced programmers.

Back
Top