Nano Hash - криптовалюты, майнинг, программирование

Указатель Fortran на цель массива параметров

У меня есть несколько массивов параметров с разными именами в модуле:

real*8, parameter :: para1(*) = [43.234, 34.0498, ...
real*8, parameter :: para2...

В подпрограмме в этом модуле

subroutine sub(n,...
...
end

Я хочу использовать para1, когда n=1, para2, когда n=2 и т. д. Есть несколько решений для этого, одно из них - создать массив paras=[para1,para2...] и правильно индексировать, что работает нормально. Но я хочу попробовать использовать указатель

real*8, pointer :: ptr(:) 

и назначать его разным массивам параметров в зависимости от n, но проблема в том, что "PARAMETER attribute conflicts with TARGET attribute at (1)". Если я удалю атрибут parameter, процедура станет менее безопасной, и будет использоваться атрибут SAVE.

Я что-то упустил или почему мы не можем объединить parameter и target? И есть ли хороший способ обойти это для этой цели?


  • Да, вы что-то упускаете. Fortran 2018, ограничение C860: Сущность с атрибутом TARGET должна быть переменной. Сущность с атрибутом PARAMETER является именованной константой. Именованная константа не является переменной. 05.06.2019
  • Можете ли вы использовать один 2D-массив для параметров? 06.06.2019
  • @ ja72 Они имеют разную длину, поэтому структурированный массив 2D-параметров построить сложнее. Тогда вам все еще нужно хранить длины. В 1D вы складываете их и сохраняете позиции, так что это намного проще. 07.06.2019
  • Кажется, вам нужен зубчатый массив в Fortran. 07.06.2019
  • @ ja72 Нет, мне это не нужно :) Также это не параметр. См. ответ «roygvib» для 2D-решения. 08.06.2019

Ответы:


1

Атрибуты parameter и target действительно конфликтуют. Объект с атрибутом target должен быть переменной (Fortran 2018 8.5.17, C861); именованная константа (объект с атрибутом parameter) не является переменной (F2018, 8.5.13, C850).

Чтобы использовать целевые массивы, вы должны использовать переменные. Сложно иметь переменную, которая «безопасна» от изменения ее значения из-за ошибки программирования или чего-то подобного. Есть несколько соображений, которые запрещают появление переменной в контексте определения переменной. Если вы можете устроить такое состояние, то у компилятора есть шанс обнаружить вашу ошибку. Может ли это произойти легко?

Вне чистой процедуры и фиктивного аргумента intent(in) наиболее заманчивым запретом является защищенная переменная модуля:

module pars
  real, save, target, protected :: para1(74) = [...]
  real, save, target, protected :: para2(1) = [6]
end module

subroutine sub (...)
  use pars
  real, pointer :: p
  p => para1
end subroutine sub

Будучи защищенными, значения защищены от изменения вне модуля pars? Увы, даже если бы это было правдой, это бесполезно: будучи защищенными, мы не можем даже указать указатель на переменные модуля.

Таким образом, вашему компилятору будет нелегко обнаружить ошибку программирования, которая изменяет целевой массив переменной, поэтому, если вы хотите использовать массив в качестве цели, вам придется быть осторожным.

05.06.2019
  • Последний абзац немного натянут. Тривиально изменить значения этих переменных модуля в процедуре вне модуля. 06.06.2019
  • Это хуже, не так ли? Вся target, protected часть - чепуха. 06.06.2019
  • Знаете ли вы, есть ли конкретная причина, по которой эти цели должны быть переменными? 07.06.2019
  • @Jonatan, я не могу говорить за авторов стандарта, но пара моментов: если указатель может быть переменной, то все, на что он указывает, для простоты должно быть переменной; именованная константа не обязательно должна существовать во время выполнения. 09.06.2019

  • 2

    Следуя предложению @ja72 в комментарии, это попытка использовать один 2D-массив для параметров. Это прекрасно работает с gfortran-8.2 (на MacOS10.11).

    program main
        implicit none
        integer i
        integer, parameter :: para1(*) = [1, 2, 3, 4, 5]
        integer, parameter :: para2(*) = [6, 7]
        integer, parameter :: N1 = size(para1), N2 = size(para2), N = max(N1, N2)
        integer, parameter :: params(N, 2) = &
                reshape( [ para1, (0, i = 1, N - N1), &
                           para2, (0, i = 1, N - N2) ], [N, 2] )
    
        print *, "para1 = ", params( :, 1 )
        print *, "para2 = ", params( :, 2 )
    
        print *, "Input i"
        read *, i
        print *, params( :, i )
    end
    
    $ gfortran-8 test.f90 && ./a.out
    
     para1 =            1           2           3           4           5
     para2 =            6           7           0           0           0
     Input i
    1
               1           2           3           4           5
    

    Однако, поскольку код становится немного сложным (из-за изменения формы) и может не работать со старыми компиляторами, может быть проще просто использовать массивы без параметров...

    06.06.2019
  • Красиво, но 1D действительно проще :) 07.06.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..