2012-06-04 2 views
2

Мне нужно работать с некоторыми устаревшими Fortran, хотя я могу использовать последние компиляторы.Создать обертку Объекты для де-convolute ужасного кода Fortran?

В коде хранится огромное количество данных в одномерных массивах.

Например,

PROGRAM horrible_coding 
IMPLICIT EVERYTHING ! Sarcasm 

REAL, DIMENSION(1000) :: data 
INTEGER, DIMENSION(50) :: info_location 

! Somewhere, info is read in and stored temporarily as info_1, info_2, etc. 

data(1:3) = info_1 
data(4:9) = info_2 
... 
data(134:192) = info_n 

ассоциация между которыми элементы в массиве DATA пойти с, какие части info хранятся во втором массиве. Что-то вроде:

info_location(1) = 1 
info_location(2) = 4 
info_location(n) = 134 

Это верно. Значение каждого элемента массива info_location относится к первому элементу массива данных, где вы можете найти соответствующую информацию.

Так, например, если вы хотите получить данные для info_7, вы должны сделать следующее:

size_of_info_7 = info_location(8) - info_location(7) 
ALLOCATE(data_for_info_7(size_of_info_7)) 
data_for_info_7 = data(info_location(7) : info_location(7) + size_of_info_7 - 1) 

В настоящем время, вид этого безумия мог вызвать кровь, чтобы начать стрельбу из ваши глаза, поэтому я приношу свои извинения.

Я хотел бы создать экземпляры объектов и сохранить все соответствующие данные для каждой части информации как данные экземпляра. И пока я привожу вещи в 2003 году, я бы создал методы экземпляра для получения и установки данных экземпляра.

Я не хочу переписывать код, но хочу поставить эту модернизацию поверх того, что уже есть.

Я считаю, что могу сделать это, сделав данные экземпляра объекта просто указателями, указывающими на фактические элементы массива data, который содержит соответствующую информацию.

Это разумная вещь?

Могу ли я создавать объекты в Фортране, чьи данные экземпляра являются преимущественно указателями?

Я не решаюсь приступить к этой задаче, не отбросив идею до stackoverflow.

+0

Так, очевидно, из редактирования pst я спрашиваю об объектах-оболочках. Уже чувствую себя лучше, зная, что есть имя того, что я пытаюсь сделать. – EMiller

+2

Я не касался fortran в течение многих лет, поэтому не знаю о каких-либо расширениях объектов. Однако я бы рекомендовал, чтобы перед тем, как вы реорганизовали код, вы должны провести несколько проверочных тестов, которые гарантируют, что вы не сломаете какой-либо архановый фрагмент логики. –

ответ

3

Могу ли я создавать объекты в Фортране, чьи данные экземпляра являются преимущественно указателями?

Я не уверен, что вы имели в виду, но вы определенно можете сделать что-то как:

type data_ptr 
    real,dimension(:),pointer :: data 
end type 

И вы можете также сделать массивы этих типов:

type(data_ptr),dimension(:),allocatable :: some_name 

(может быть также указателем или статиком, как вы пожелаете.)

Тогда, если исходные данные имеют атрибут TARGET, вы можете использовать:

some_name(i)%data => data(lower:upper) 

Вы также можете переназначить указатель на различные нижние границы, процесс выше дает ему нижнюю границу 1.

3

Я нахожу «код», который вы опубликовали немного запутанным. Я ожидаю, что вы знаете, что линии

data(1:3) :: info_1 
data(4:9) :: info_2 
... 
data(134:192) :: info_n 

не являются синтаксически действительными Fortran (любого поколения). Я думаю, что я могу интерпретировать то, что вы пытаетесь нам рассказать, но скорее не предлагать советы, основанные на (неверной) интерпретации. Кроме того, вы перемещаете объекты, такие как info_1, info_2, в состав, не уточняя их определения и декларации. Я не уверен, что info_1 - это то же самое, что и info_location(1).

Если я понимаю, что вы опубликовали, у вас есть довольно распространенная (в старом коде Fortran) конструкция, в которой массив данных фиксированного размера (здесь полезно называется data), который используется для хранения коллекции элементов. Затем у вас есть индексный массив (называемый info_location), который содержит индексы в данных в начале каждого элемента. Это очень странно, что этот индекс массива имеет тип REAL, я бы ожидать, что это будет INTEGER, так что вы могли бы написать такие утверждения, как:

data(info(3):info(4)-1)) 

Это, конечно, не делает мои глазные яблоки кровоточить, возможно, я имею запрограммированный в Фортране слишком долго, но для меня это выглядит очень разумно! Один из вариантов, который вы должны рассмотреть, - это сделать info_location INTEGER и использовать его как индексный массив. Или вы могли бы сделать эти слепки, как и в случае необходимости, написания линий, такие как:

data(int(info(3)):int(info(4))-1)) 

Лично я хотел бы сделать массив целочисленного индекса, REALS имеет неправильный тип для индексов массива.

Затем вы пишете

Так, например, если вы хотите получить данные для info_7, вы должны сделать следующее:

size_of_info_7 = info_location(8) - info_location(7) 
ALLOCATE(data_for_info_7(size_of_info_7)) 
data_for_info_7 = data(info_location(7) : info_location(7) + size_of_info_7 - 1) 

Так как вы убежище» t уточнил, что именно info_7 или data_for_info_7 Я немного смущен этим. Если вы используете неявное впечатывание, тогда size_of_info_7 будет REAL, и ваш оператор ALLOCATE завершится с ошибкой, требуя INTEGER для размера выделенного объекта.

Я полагаю, что data_for_info_7, вероятно, является выделяемым массивом REAL. Если info_location были типа INTEGER вы могли бы просто написать:

ALLOCATE(data_for_info_7, source = data(info_location(7) : info_location(8) - 1)) 

Владимир F уже предоставил рекомендации по использованию указателей, чтобы очистить ваш код. Другой подход - использовать конструкцию ASSOCIATE. Вы могли бы написать, в соответствующей точке (ы) в вашем коде, что-то вроде:

ASSOCIATE(data_for_info_7 => data(info_location(7) : info_location(8) - 1)) 

сопрягая это с END ASSOCIATE заявление в нужном месте. Это эффективно определяет псевдоним для секции массива в конструкции ASSOCIATE.

Таким образом, чтобы округлить:

  1. Типом info_location массива неправильно.
  2. Оставляя это в стороне от оригинального дизайна, с массивом данных и другим массивом индексов в нем, (безусловно, было) вполне разумно.
  3. У вас есть несколько вариантов обновления кода, включая указатели и ассоциацию.
+0

Да, info_location должен быть целым. Это теперь исправлено в примере кода. – EMiller