2010-01-05 2 views
2

У меня есть два p * n массива, y и ymiss. y содержит действительные числа и NA. ymiss содержит 1 и 0, так что если y (i, j) == NA, ymiss (i, j) == 0 и 1 в противном случае. У меня также есть 1 * п ydim массив, который говорит, сколько действительных чисел существует при у (1: р, п), так ydim имеет значения от 0 до рКак организовать элементы вектора в Фортране?

В языке R программирования, я могу сделать следующее:

if(ydim!=p && ydim!=0) 
    y(1:ydim(t), t) = y(ymiss(,t), t) 

этот код упорядочивает все действительные числа у (т), в так

первым есть, например у (, т) = (3,1, NA 6,2, NA) после код y (, t) = (3,1,6,2,2, NA)

Теперь я буду o нужны первые первые 1: ydim (t), поэтому не имеет значения, каковы эти остатки.

Вопрос в том, как я могу сделать что-то подобное в Фортране?

Спасибо,

Jouni

ответ

1

В Fortran вы не можете хранить на в массиве действительных чисел, вы можете хранить только действительные числа. Таким образом, вы, вероятно, захотите заменить na на некоторое значение, которое вряд ли будет присутствовать в ваших данных: возможно, будет огромный(). 2D-массивы не являются проблемой для Fortan. Возможно, вы захотите использовать 2D-массив логических элементов для замены ymiss, а не 2D-массив из 1s и 0s.

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

Итак, вот некоторые фрагментарные Fortran код, не тестируются:

! Declarations 
real(8), dimension(m,n) :: y, ynew 
logical, dimension(m,n) :: ymiss 

! Executable 
where (ymiss) ynew = func(y) ! here func() is whatever your function is 
2

«Где оператор» и «слияние» внутренняя функция могущественны, работающих на отдельных позициях в массивах, но они не двигаются элементы перед фронтом массива. С старомодным кодом с явной индексацией (может быть упакована в функцию) например .:

k=1 
do i=1, n 
    if (ymiss (i) == 1) then 
     y(k) = y(i) 
     k = k + 1 
    end if 
end do 

То, что вы хотите, может быть сделаны с встроенными функциями массива, используя «пакет» внутренний. Преобразуйте ymiss в логический массив: 0 -> .false., 1 -> .true .. Затем используйте код (проверенный без второго индекса):

y (1: ydim (t), t) = упаковка (у (:, т), ymiss (:, т))


Изменить, чтобы добавить пример кода, показывающий использование Fortran встроенных функций "где", "подсчет" и "пакет". «где» один не может решить проблему, но «пакет» может. Я использовал «< -90» как NaN для этого примера. Оператор OP не должен выполнять шаг «y (ydim + 1: LEN) = -99.0», которому не нужно использовать эти элементы.

program test1 

integer, parameter :: LEN = 6 
real, dimension (1:LEN) :: y = [3.0, 1.0, -99.0, 6.0, 2.0, -99.0 ] 
real, dimension (1:LEN) :: y2 
logical, dimension (1:LEN) :: ymiss 
integer :: ydim 

y2 = y 
write (*, '(/ "The input array:"/6(F6.1))') y 

where (y < -90.0) 
    ymiss = .false. 
elsewhere 
    ymiss = .true. 
end where 

ydim = count (ymiss) 

where (ymiss) y2 = y 
write (*, '(/ "Masking with where does not rearrange:"/6(F6.1))') y2 

y (1:ydim) = pack (y, ymiss) 
y (ydim+1:LEN) = -99.0 
write (*, '(/ "After using pack, and ""erasing"" the end:"/6(F6.1))') y 


stop 

end program test1 

Выход:

Входной массив: 3,0 1,0 -99,0 6,0 2,0 -99.0

Маскирование с тем, где не переставить: 3,0 1,0 6,0 2,0 -99,0 -99.0

После использования пакета, и «стирание» конец: 3,0 1,0 6,0 2,0 -99,0 -99,0

Смежные вопросы