Fortran генератор случайных чисел

Последний раз редактировалось Gickle 03.11.2015, 20:01, всего редактировалось 1 раз.

На деле же происходит какая-то чертовщина:
1) Практически (что понимается под практически — см. далее) все элементы получаются одинаковыми. При каждом новом запуске этот одинаковый почти для всех элементов вектор получается при этом различным.
2) Если вывести в конце, например, следующие элементы

85000 в рассматриваемом случае). Причём, что я заметил, у первой пары и последнего первая координата (то есть lattice(. )%coords(1)) отличаются незначительно и всегда почти что на одну величину.
Да и в целом какая-то крайне хреновая случайность получается, что уж. Пытался пользоваться советами выше — не помогло. На всякий случай даже покоординатно вектора задавал — ничего, разумеется, не поменялось.

В чём моя ошибка, не подскажете?

Супермодератор

Я попробовал на всякий случай воспроизвести проблему, дописав недостающие участки кода, и мне это не удалось ни на одном из пяти имеющихся под руками компиляторов. Так что, полагаю, проблема где-то в другом месте.

Судя по проявлениям, у Вас там ошибки при использовании памяти (грубо говоря, Вы почему-то извлекаете данные не оттуда, откуда хотите), но хотелось бы посмотреть на код целиком. Если он небольшой — давайте сюда полностью, если большой — выложите куда-нибудь и давайте ссылку.

Заслуженный участник

program frame
implicit none
integer N, p
integer :: i = 1
real , parameter :: Pi = 3.141593
real ( 8 ) L, phi, R_avg
real ( 8 ) , dimension ( 3 ) :: coord
type pore
real ( 8 ) , dimension ( 3 ) :: coords
real R
end type
type ( pore ) , dimension ( : ) , allocatable :: lattice

print * , ‘L =’
read * , L
print * , ‘phi =’
read * , phi
print * , ‘R_avg =’
read * , R_avg
N = nint ( ( L ** 3 * log ( 1 / ( 1 — phi ) ) ) / ( ( 4 * Pi * ( R_avg ) ** 3 ) / 3 ) )
allocate ( lattice ( N ) )
do while ( i + 1 )
call init_random_seed ( )
call random_number ( coord )
lattice ( i ) % coords = coord * L
i = i + 1
end do
pause
end program frame

Супермодератор

Последний раз редактировалось Pphantom 03.11.2015, 22:52, всего редактировалось 2 раз(а).

Ну что ж, видны как минимум две проблемы:
1) Зачем Вы вызов init_random_seed внутрь цикла вставили? Эту штуку нужно использовать один раз в начале программы.
2) Если N у Вас получается в районе 85000, то в стандартный для Вашего компилятора integer (который может оказаться и integer(2) ) он может просто не влезть. Результаты попыток его туда втиснуть могут быть весьма разнообразны.

Итого, уберите инициализатор датчика случайных чисел в начало программы и смените целые типы на integer(4) . Заодно проверьте результат вычисления N — что он соответствует ожиданиям.

Читайте также: Напряжение генератора ниссан тиида

Кстати, я бы и программу переписал, нынешний вариант жутковат, несмотря на небольшие размеры.

Заслуженный участник
Супермодератор

Второй, менее банальный (хотя и ненамного) совет — не использовать составные типы без явной и сильной необходимости. В данном случае данные проще хранить не в массиве записей, а в одном двумерном массиве, например, таком: real(8),dimension(0:3,1:N) :: lattice (считая, что первый индекс 0 соответствует полю R). Это, в частности, позволило бы вместо всего пресловутого цикла написать просто:

Заслуженный участник
Супермодератор

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

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

Если полей будет больше, то имеет смысл подумать о том, чтобы хранить именно отдельные массивы полей, а не массивы записей. В Фортране идеология сложных типов работает плохо (хотя и поддерживается), куда удобнее разнести по разным массивам разнотипные данные, относящиеся к однотипным физическим объектам, в этом случае выполнение однообразных операций с этими объектами резко упростится.

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей

Fortran генератор случайных чисел

Отметим, что случайные величины (или «случайно выбранные» числа) оказываются полезными не только для статистического моделирования, но и в численном анализе. Для решения различных задач были предложены так называемые методы Монте-Карло [ Кнудт Д. Искуссиво программирования для ЭВМ. Т. 2 ]. Случайные числа используются также для формирования случайных выборок, необходимых при проведении различных социологических исследований. Случайность, кроме того, есть существенная часть оптимальных стратегий в теории игр. Генерирование случайных чисел в Фортране 90 выполняется подпрограммой RANDOM_NUMBER . Обращение к подпрограмме генерирования случайного числа имеет вид

Методы Монте-Карло (ММК) – это численные методы решения математических задач с помощью моделирования случайных величин. ММК позволяют успешно решать математические задачи, обусловленные вероятностными процессами. Более того, при решении задач, не связанных с какими-либо вероятностями, можно искусственно придумать вероятностную модель (и даже не одну), позволяющую решать эти задачи. Рассмотрим вычисление определенного интеграла

При вычислении этого интеграла по формуле прямоугольников интервал [a,b] разбиваем на N одинаковых интервалов, в серединах которых вычислялись значения подынтегральной функции. Вычисляя значения функции в случайных узлах, можно получить более точный результат:

Здесь γi – случайное число, равномерно распределенное на интервале [0, 1). Погрешность вычисления интеграла ММК

, что значительно больше, чем у ранее изученных детерминированных методов.

CALL RANDOM_NUMBER( имя переменной >),

Кроме встроенной функции RANDOM _ NUMBER во входных языках имеются дополнительные подпрограммы, реализующие генерирование случайных чисел,

RANDOM и RAN , а также встроенные подпрограммы функции DRAND , DRANDM , IRAND , RAN и RAND . Все эти подпрограммы используют один и тот же алгоритм получения псевдослучайных чисел.

В CVF можно подключить библиотеку IMSLF 90 , и тогда будет доступна функция RAND , которая позволяет осуществлять заполнение случайными числами массива любой размерности. При этом инициировать датчик нет необходимости ( см. пример ). Программа, показанная в примере, демонстрирует использование функции CONST ( ) , которая позволяет вычислять значение некоторых констант . Здесь – переменная строкового типа. Проверить работу программы , осуществив несколько запусков программы, задавая различные значения K.

Читайте также: Ремонт бензиновых генераторов в калининграде

Fortran генератор случайных чисел

Fortran 90 introduced a pseudo-random number generator (PRNG) to the language standard. The routine random_number() returns a single number or an array of numbers from the uniform distribution over the range 0 ≤ x srand() , rand() and irand() for backwards compatibility with g77. These routines access an independent PRNG. Additionally, several implementations of the Mersenne Twister (MT19937) have been written in Fortran that return random 32-bit or 64-bit values.

Fortran 90 also added the random_seed() routine that initialises the PRNG. Without seeding, random_number() will always return the same sequence of numbers.

call random_seed([size][, put][, get])
Argument Type Description
size integer The returned minimum size of the array used with put and get (optional).
put integer, dimension(*) The array with seed values to use (optional).
get integer, dimension(*) The used array with seed values (optional).

The GNU Fortran implementation uses the Xoshiro256** pseudo-random number generator, with a period of 2 256 – 1. Threads defined by OpenMP directives have their own random number state. The routine random_number() returns either a random real number or an array of random numbers.

call random_number(harvest)
Argument Type Description
harvest real[, dimension(*)] Returned scalar or array with random number(s).

The example initialises the PRNG and fills and array with random numbers:

Compile and run the example with:

Fortran 2018

In Fortran 2018, the routine random_init() has been added to initialise the state of the PRNG with respect to Co-Arrays.

call random_init(repeatable, image_distinct)
Argument Type Description
repeatable logical If .true. , the seed is set to a processor-dependent value that is the same each time random_init() is called from the same instance of program execution. If .false. , the seed is set to a processor-dependent value.
image_distinct logical If .true. , the seed is set to a processor-dependent value that is distinct from the seed set by a call to random_init() in another process. If .false. , the seed depends on which image called random_init() .

The routine random_init() allows us to generate the very same random numbers on each initialisation:

The array is filled with the same random numbers despite re-initialisation:

Seeding

For higher entropy, we can feed a custom seed array to random_seed() , with data obtained from /dev/urandom :

The example outputs ten random integers:

OpenSSL

The RAND_bytes() function of OpenSSL returns cryptographically strong pseudo-random bytes. We first need to implement an appropriate ISO C binding interface to the C function. A character array can then be passed to the function interface to be filled with random values:

The program has to be linked against OpenSSL’s crypto library, using flag -lcrypto :

The example application just prints the random bytes [0 … 255] to console:

Создание случайного числа в заданном диапазоне в Fortran 77

Я начинаю пытаться сделать некоторые инженерные эксперименты, используя fortran 77. Я использую компилятор и редактор Force 2.0. У меня есть следующие запросы:

    Как я могу создать случайное число между указанным диапазоном, например. если мне нужно создать одно случайное число между 3.0 и 10.0, как я могу это сделать?
    Как я могу использовать данные из текстового файла для вызова в вычислениях в моей программе. например, у меня есть значения температуры, давления и влажности (почасовые значения за день, поэтому в каждом текстовом файле всего 24 значения).
    Нужно ли мне также определять в программе количество значений в текстовом файле?

Knuth имеет выпущенный в источники общедоступного домена как в C, так и в FORTRAN для генератора псевдослучайных чисел, описанного в разделе 3.6 The Art компьютерного программирования.

В стандарте Fortran 77 не указывается генератор случайных чисел, но вы можете использовать любой из бесчисленных источников, свободно предоставляемых для этой цели; http://www.cisl.ucar.edu/zine/96/spring/articles/3.random-6.html, например, имеет хорошую, полезную подпрограмму f77 SRAND , готовую для копирования и вставки.

Если ваш файл, например, выглядит так:

эта простая программа будет читать:

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

Мой совет: прочитайте типы данных (INTEGER, REAL, CHARACTER), массивы (DIMENSION), ввод/вывод (READ, WRITE, OPEN, CLOSE, REWIND) и циклы (DO, FOR) я буду делать полезные вещи в кратчайшие сроки.

Я никогда ничего не делал со случайными числами, поэтому я не могу вам помочь, но я думаю, что в fortran есть некоторые встроенные функции. Я проверю это и отчитаюсь завтра. Что касается третьего вопроса, я не уверен, что вы думаете (вы не знаете, сколько строк данных у вас будет в файле? Или?)

Эта подпрограмма генерирует случайное число в фортране 77 между 0 и ifin, где я — начальное число; какое-то большое число, такое как 746397923

Вы можете изменить, чтобы взять определенный диапазон.

Вы хотите проверить свое руководство для компилятора для конкретной функции генератора случайных чисел, но, скорее всего, он генерирует случайные числа от 0 до 1. Это легко обрабатывать — вы просто масштабируете интервал, чтобы быть надлежащей шириной, затем сдвиньте его, чтобы он соответствовал правильной начальной точке: т.е. чтобы отобразить r в [0, 1] до s в [a, b] , используйте s = r*(b-a) + a , где r — это значение, полученное вами от генератора случайных чисел, и s является случайным значением в диапазоне, который вы хотите.

Ответ на Идигас хорошо освещает ваш второй вопрос — читайте данные с использованием форматированного ввода, а затем используйте их так же, как и любую другую переменную.

Для вашего третьего вопроса вам нужно будет определить, сколько строк есть в текстовом файле, только если вы хотите что-то сделать со всеми из них — если вы смотрите на чтение строки, обрабатываете ее, а затем двигаетесь дальше, вы можете обойтись, не зная количества строк раньше времени. Однако, если вы хотите сохранить все значения в файле (например, с массивами температуры, влажности и давления, чтобы вы могли вычислять статистику давления пара), вам нужно как-то настроить хранилище. Как правило, в FORTRAN 77 это делается путем предварительного выделения массива большего размера, чем вы считаете нужным, но это может быстро стать проблематичным. Есть ли шанс перейти на Fortran 90? Обновленная версия имеет гораздо лучшие возможности для работы со стандартизированным распределением динамической памяти, не говоря уже о многих других преимуществах. Я бы настоятельно рекомендовал использовать F90, если это вообще возможно — вы значительно облегчите свою жизнь.

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

  • Свежие записи
    • Как я ремонтировала свой автомобиль
    • Автомобильные зеркала
    • Ностальгия по «бугатти»
    • Тест драйв. OPEL MOKKA – лучший полноприводный кроссовер в своем классе
    • McFarlan — от рассвета до заката


    источники:

    https://dmsht.ru/fortran-generator-sluchaynyh-chisel