Возникли проблемы при чтении текстового файла в массив Fortran - PullRequest
0 голосов
/ 08 мая 2018

Я пишу программу, которая должна прочитать расширенную матрицу (A | B) системы линейных уравнений Ax = B из текстового файла и сохранить ее в матрица, чтобы решить это позже.

Кажется, моя рутина для решения системы уравнений работает, но у меня возникают проблемы с чтением самого файла, что не должно быть слишком сложным, но я запутался в этой точке. Текстовый файл содержит матрицу действительных чисел, которая имеет ширину N+1 записей (матрица коэффициентов плюс соответствующая независимая запись термина в конце) и высоту N записей. Моя попытка (с N=5 системой) была такой:

        OPEN(10,FILE="sistema.txt")
            DO I=1,N
                DO J=1,(N+1)
                    IF(J==(N+1)) THEN
                        READ(10,*) B(I)
                        ELSE
                        READ(10,*) A(I,J)
                    END IF
                END DO
            END DO
    CLOSE(10)

С A(1:N,1:n) реальным массивом и B(1:N) реальным массивом (а N - целое число, введенное пользователем для выбора между двумя стратегиями). Программа возвращает сообщение об ошибке конца файла, и я попытался изменить индексы цикла на I=1,2 и J=1,3, просто чтобы посмотреть, что происходит, но продолжает возвращать ту же ошибку EoF. Только с I=1,2 и J=1,2 он прочитает файл и оставит все записи, кроме четырех, без изменений. Я не понимаю, что происходит.

Содержимое txt файла, если это поможет:

10.0 1.0 2.0 3.0 4.0 12.0
1.0 9.0 -1.0 2.0 -3.0 -27.0
2.0 -1.0 7.0 3.0 -5.0 14.0
3.0 2.0 3.0 12.0 -1.0 -17.0
4.0 -3.0 -5.0 -1.0 15.0 12.0

1 Ответ

0 голосов
/ 08 мая 2018

Команда READ пытается прочитать всю строку, а затем отбросить все, что ей не нужно. Поскольку вы читаете только одно значение на read, вы читаете только первые значения каждой строки и даже не сохраняете их в правильной переменной.

Вот как я это прочитал бы:

do i = 1, N
    read(10, *) A(:, i), B(i)
end do

Я читаю это построчно, сохраняя первые значения в строке A, а затем последнее значение в B(i).

Обновление @agentp отметил, что мое решение выше считывает значения как

A(1,1) A(2,1) A(3,1) A(4,1) A(5,1) B(1)
A(1,2) A(2,2) A(3,2) A(4,2) A(5,2) B(2)
A(1,3) A(2,3) A(3,3) A(4,3) A(5,3) B(3)
A(1,4) A(2,4) A(3,4) A(4,4) A(5,4) B(4)
A(1,5) A(2,5) A(3,5) A(4,5) A(5,5) B(5)

, что отличается от того, что ваш код предлагает вам сделать:

A(1,1) A(1,2) A(1,3) A(1,4) A(1,5) B(1)
A(2,1) A(2,2) A(2,3) ...
...

Чтобы прочитать это в таком порядке, вам нужно изменить строку read на:

read(10, *) A(i, :), B(i)

Что касается вашего последующего вопроса: если у вас есть какой-либо массив A (для простоты 1D), вы можете использовать A(3:7) для доступа только к элементам с 3 по 7 как для чтения, так и для записи. Вы можете опустить любое число для доступа от первого элемента к последнему: A(:7) означает все элементы, вплоть до элемента с индексом 7, включая A(3:) означает все элементы, начиная с индекса 3.

И наоборот, A(:) будет означать, что все элементы A в случае с массивом 1d ничем не отличаются от простого использования A. Но если A многомерно, как здесь, это может быть полезно. В этом случае я использовал A(:,i), что означает все элементы со вторым индексом i.

...