1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Fortran 90 assignment help

  1. Nov 24, 2009 #1
    1. The problem statement, all variables and given/known data

    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 (Text):

    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: Nov 24, 2009
  2. jcsd
  3. Nov 24, 2009 #2

    Mark44

    Staff: Mentor

    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 (Text):

    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.
     
  4. Nov 25, 2009 #3
    Thank you so much, that helped out tremendously!
     
  5. Nov 25, 2009 #4

    Mark44

    Staff: Mentor

    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.
     
  6. Nov 27, 2009 #5
    I keep getting stupid numbers for my hot and cold spots, along with the percentage

    Here's what I have

    Code (Text):

    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?
     
  7. Nov 27, 2009 #6

    Mark44

    Staff: Mentor

    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 (Text):
          ! 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.
     
  8. Nov 27, 2009 #7
    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.
     
  9. Nov 27, 2009 #8

    Mark44

    Staff: Mentor

    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.
     
  10. Nov 27, 2009 #9
    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.
     
  11. Nov 27, 2009 #10

    Mark44

    Staff: Mentor

    NUM_OF_HOTSPOTS and NUM_OF_COLDSPOTS are counter variables. You have to initialize them to 0 before using them.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Fortran 90 assignment help
  1. Fortran 90 Question (Replies: 1)

  2. FOrtran 90 stucked (Replies: 4)

  3. Fortran 90 (Replies: 1)

Loading...