Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы программирования на FORTRAN (ФОРТРАН)

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330

Открыть новую тему     Написать ответ в эту тему

akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Обсуждаются все вопросы, связанные с программированием на ФОРТРАН, как общего так и конкретного характера.
Постарайтесь дать как можно больше информации о возникшей проблеме -- это в конце концов в ваших же интересах чтобы вам помогли...

прежде чем просить помощи в задании
платное решение задач

ресурсы этого топика
ссылка на подборку ресурсов, собранных посетителями этого форума
 
то, чем мы решили поделиться
ссылка на страничку программ etc собственного изготовления, которыми любезно делятся наши форумчане


если вам вдруг не отвечают или ответ вас не устраивает
и вообще полезно прочитать всем спрашивающим
 
просьба к пишущим и отвечающим все большие листинги оформлять тегом more
и отключать графические смайлики при размещении фортран-кода

Всего записей: 24107 | Зарегистр. 06-12-2002 | Отправлено: 18:11 14-01-2007 | Исправлено: akaGM, 09:47 01-03-2020
akuaku

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Возникла проблема, не могу понять в чём дело. Установил IF 10.1.019, VS 2005 Prof. 64-разрядный процессор, операционная система и компилятор.
Пишу цикл:
    i_Do: do i=0,100000
 
Если omega от 17.78 - 20*0.120, то в цикле к omega прибавляется шаг 0.01
Когда omega увеличится до 17.78 - 4*0.120, то шаг 0.001
когда omega 17.78 - 2*0.120, то шаг 0.0001
и т. д.
потом когда 17.78 + 2*0.120 шаг снова увеличивается 0.001
когда 17.78 + 4*0.120 шаг увелич. 0.01
при omega 17.78 + 20*0.120 выход из цикла.
 
пишу        if(omega.eq. 17.780d0-0.120d0*20) then
                                    write(*,*) "omega=17.78-20Gamma"
                                    pause
                                endif
        if(omega.eq. 17.780d0-0.120d0*4) then
                                    write(*,*) "omega=17.78-4Gamma"
                                    pause
                                endif
 
- это работает, а следующее уже нет:
 
        if(omega .eq. 17.780d0 -0.120d0*2) then
                                    write(*,*) "omega=17.78-2Gamma"
                                    pause
                                endif
если же написать вручную вместо 17.780d0 -0.120d0*2 результат 17.540d0, то всё работает.
Если написать omega.eq.aaa, aaa написать через такую же разность, то тоже не работает.
Наверное где-то в младшем разряде накапливается 1 - ошибка машинной точности (вычисления 64-разрядные), почему в однов случае она есть, а вдругом её нет? Как сделать, чтобы работало?
 
    ..... дальше идут разные write(*,*)
 
    enddo i_Do

Всего записей: 95 | Зарегистр. 09-06-2005 | Отправлено: 13:16 24-03-2008 | Исправлено: akuaku, 13:23 24-03-2008
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akuaku
у меня в таких случаях всегда стандартная рекомендация (что бы не говорили по этому поводу любители возлагать всё это на смарт-компиляторы):

Код:
 
if(omega.eq. 17.780d0-0.120d0*20.d0) then
if(omega.eq. 17.780d0-0.120d0*4.d0) then
if(omega .eq. 17.780d0 -0.120d0*2.d0) then

Всего записей: 24107 | Зарегистр. 06-12-2002 | Отправлено: 14:28 24-03-2008
akuaku

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akaGM
Да нет, это не помогает. В том-то и дело, что написано везде одинаково (*4 и *2), а *4 работает, а *2 - нет.
4.0d0 и 2.0d0 пробовал, изменений по сравнению с предыдущим случаем нет. Вот так.
Что делать?

Всего записей: 95 | Зарегистр. 09-06-2005 | Отправлено: 16:11 24-03-2008 | Исправлено: akuaku, 16:11 24-03-2008
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akuaku
 
omega какого типа?
и объясни мне в чём суть таких констант:
 
17.780d0-0.120d0*4
17.780d0-0.120d0*2
 
почему нельзя одним числом записать?
 

Цитата:
*4 работает, а *2 - нет

а так * (4 / 2)
гы
глюк...

Всего записей: 24107 | Зарегистр. 06-12-2002 | Отправлено: 16:23 24-03-2008
akuaku

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akaGM
omega real*8
 
Хорошо, вот зачем
    homega=0.0001d0
    omega_center=17.780d0 ! центр лоренциана
    gamma=0.120d0 ! ширина лоренциана
    omega=omega_center-20*gamma
    i_Do: do i=0,100000
        if(                                      omega .gt. omega_center+20*gamma) exit
        if(omega .ge. omega_center+4*gamma .and. omega .lt. omega_center+20*gamma) then; omega=omegamax3+(i-imaxlev3)*100*homega; imaxlev4=i; omegamax4=omega; endif
        if(omega .ge. omega_center+2*gamma .and. omega .lt. omega_center+4*gamma) then; omega=omegamax2+(i-imaxlev2)*10*homega; imaxlev3=i; omegamax3=omega; endif
        if(omega .ge. omega_center-2*gamma .and. omega .lt. omega_center+2*gamma) then
            omega=omegamax1 +(i-imaxlev1)*homega; imaxlev2=i; omegamax2=omega
        endif
        if(omega .ge. omega_center-4*gamma .and. omega .lt. omega_center-2*gamma) then
            omega=omegamax0 +(i-imaxlev0)*10*homega; imaxlev1=i; omegamax1=omega
        endif
        if(omega .ge. omaga_center-20*gamma .and. omega .lt. omega_center-4*gamma) then
            omega=omega_center-20*gamma+i*100*homega; imaxlev0=i; omegamax0=omega
        endif
 
        write(*,*) omega,i
        if(omega .eq. omega_center-20*gamma) then; write(*,*) "omega=17.78-20Gamma"; pause; endif
        if(omega .eq. omega_center-4*gamma) then; write(*,*) "omega=17.78-4Gamma"; pause; endif
        if(omega .eq. omega_center-2*gamma) then; write(*,*) "omega=17.78-2Gamma"; pause; endif
        if(omega .eq. omega_center+2*gamma) then; write(*,*) "omega=17.78+2Gamma"; pause; endif
        if(omega .eq. omega_center+4*gamma) then; write(*,*) "omega=17.78+4Gamma"; pause; endif
        if(omega .eq. omega_center+20*gamma) then; write(*,*) "omega=17.78+20Gamma"; pause; endif
 
....
 
    enddo i_Do
 
Вот эти if не выполняются
        if(omega .eq. omega_center-2*gamma) then; write(*,*) "omega=17.78-2Gamma"; pause; endif  
        if(omega .eq. omega_center+4*gamma) then; write(*,*) "omega=17.78+4Gamma"; pause; endif  
        if(omega .eq. omega_center+20*gamma) then; write(*,*) "omega=17.78+20Gamma"; pause; endif - даже если подставить численное значение omega_center+20*gamma, - не выполняется.
 
Дело в том, что программа почему-то считает, что в этих if omega .ne. соответствующему выражению с omega_center (-2/+4/+20)*gamma. Хотя смотря значения omega в дебаггере видно, что в цикле omega пробегает в том числе и указанные значения !
 
gamma и omega_center могут меняться.
Мне для начала нужно, чтобы это было вычислением площади под узким лоренцианом.
 
Т. е. просто от omega_center-20gamma до omega_center-4gamma и симметрично с + шаг 0.01
от omega_center-4gamma до omega_center-2gamma и симметрично с + шаг 0.001
от omega_center-2gamma до omega_center+2gamma шаг 0.0001
 
Парадокс в том, почему не работает.
- Что-то в последнем компиляторе не то или изменилось ?
- Виновата 64-битность ?
- ещё ?
...

Всего записей: 95 | Зарегистр. 09-06-2005 | Отправлено: 23:13 24-03-2008 | Исправлено: akuaku, 23:23 24-03-2008
terminat0r



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akuaku

Цитата:
Парадокс в том, почему не работает.  
- Что-то в последнем компиляторе не то или изменилось ?  
- Виновата 64-битность ?  
- ещё ?  
...

а попробуйте при случае другие компилляторы и расскажите нам, что получилось

Всего записей: 2084 | Зарегистр. 31-03-2002 | Отправлено: 00:48 25-03-2008
akuaku

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Вот вам код, попробуйте скомпилить его у себя, если сможете :
xxx.f90
 
program xxx
 
    implicit real*8(a-h,o-z)
    integer i
 
    homega=0.0001d0
    omega_center=17.780d0
    gamma=0.120d0
    omega=omega_center-20.0d0*gamma
    i_Do: do i=0,100000
        if(omega .gt. omega_center+20.0d0*gamma) exit
        if(omega .ge. omega_center+4.0d0*gamma .and. omega .lt. omega_center+20.0d0*gamma) then; omega=omegamax3+dble(i-imaxlev3)*100.0d0*homega; imaxlev4=i; omegamax4=omega; endif
        if(omega .ge. omega_center+2.0d0*gamma .and. omega .lt. omega_center+4.0d0*gamma) then; omega=omegamax2+dble(i-imaxlev2)*10.0d0*homega; imaxlev3=i; omegamax3=omega; endif
        if(omega .ge. omega_center-2.0d0*gamma .and. omega .lt. omega_center+2.0d0*gamma) then
            omega=omegamax1 +dble(i-imaxlev1)*homega; imaxlev2=i; omegamax2=omega
        endif
        if(omega .ge. omega_center-4.0d0*gamma .and. omega .lt. omega_center-2.0d0*gamma) then
            omega=omegamax0 +dble(i-imaxlev0)*10.0d0*homega; imaxlev1=i; omegamax1=omega
        endif
        if(omega .ge. omega_center-20.0d0*gamma .and. omega .lt. omega_center-4.0d0*gamma) then
            omega=omega_center-20.0d0*gamma+dble(i)*100.0d0*homega; imaxlev0=i; omegamax0=omega
        endif
 
        write(*,*) omega,i
        if(omega .eq. omega_center-20.0d0*gamma) then; write(*,*) "omega=17.78-20Gamma"; pause; endif
        if(omega .eq. omega_center-4.0d0*gamma) then; write(*,*) "omega=17.78-4Gamma"; pause; endif
        if(omega .eq. omega_center-2.0d0*gamma) then; write(*,*) "omega=17.78-2Gamma"; pause; endif
        if(omega .eq. omega_center+2.0d0*gamma) then; write(*,*) "omega=17.78+2Gamma"; pause; endif
        if(omega .eq. omega_center+4.0d0*gamma) then; write(*,*) "omega=17.78+4Gamma"; pause; endif
        if(omega .eq. omega_center+20.0d0*gamma) then; write(*,*) "omega=17.78+20Gamma"; pause; endif
    enddo i_Do
end program xxx
 
Пауза должна появляться 6 раз, у меня только два. А как будет у Вас ??

Всего записей: 95 | Зарегистр. 09-06-2005 | Отправлено: 04:46 25-03-2008 | Исправлено: akuaku, 15:27 25-03-2008
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akuaku
 
а у меня ни разу... потому что я не смог скомпилировать...
 
выкинул на фиг все твои имлиситы, написал (_как это дОлжно_ implicit none)
и наткнулся на твою
omaga_center
 
и ошибка у тебя в логике, а не в компиляторе,
разбирайся...

Всего записей: 24107 | Зарегистр. 06-12-2002 | Отправлено: 15:05 25-03-2008 | Исправлено: akaGM, 19:48 25-03-2008
akuaku

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akaGM
omega_center
Одна опечатка, исправил, но на суть вопроса она не повлияла.
 
implicit-ы тоже на суть вопроса не влияют, проверил это. Но согласен, что по-правильному надо писать implicit none.
 
Короче сей глюк остался не понятым, инетересно понимать, что происходит в "мозгах" у компилятора, и почему из двух, казалось бы, одинаковых примеров один не работает !!
 
Я конечно могу написать
real(8) :: diff
real(8) :: tolerance      ! set to some appropriate acceptable value
 
diff = omega - (omega_center-4.0d0*gamma)
 
if ( abs(diff) <= tolerance ) then
       ! the two numbers are considered to be equal
 
и вопрос будет решён, просто столкнулся с интересным случаем - "глюком".

Всего записей: 95 | Зарегистр. 09-06-2005 | Отправлено: 15:26 25-03-2008
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akuaku
да нет там, скорее всего, никаких глюков...
 
ты уверен, что все твои imaxlev'елы и omegamax'ы правильно иницилизируются перед использованием? т.е. попадают в нужную ветку if раньше чем...
 
ну дай исправленный код?

Всего записей: 24107 | Зарегистр. 06-12-2002 | Отправлено: 15:41 25-03-2008
akuaku

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Попробуйте
так и так
 
Разница заметна...

Всего записей: 95 | Зарегистр. 09-06-2005 | Отправлено: 15:45 25-03-2008 | Исправлено: akuaku, 15:46 25-03-2008
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akuaku
вот смотри...
 
судя по твоему (первоначальному) коду -- в цикле 6 ифов, в 5-ти из которых последней инструкцией стоит
omegamax# = omega
 
беру и ставлю перед write()
omegamax0 = omega
omegamax1 = omega
omegamax2 = omega
omegamax3 = omega
omegamax4 = omega
 
я полагаю, ничего не должно измениться, я прав?
 
фиг вам -- меняется, так что это, я думаю, ошибка в логике и советую пересмотреть/упростить задачу...
 
-----
наверное, всё же я не прав...
сам запутался...

Всего записей: 24107 | Зарегистр. 06-12-2002 | Отправлено: 16:04 25-03-2008 | Исправлено: akaGM, 16:07 25-03-2008
XPEHOMETP

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akuaku

Цитата:
if(omega .eq. omega_center-2.0d0*gamma) then; write(*,*) "omega=17.78-2Gamma"; pause; endif  

Проблема в том, что представление нецелых чисел в памяти компьютера является приближенным. Т.е. неточным. Поскольку бесконечное множество действительных чисел, с которыми оперирует математика, проэцируется на конечное множество дробных чисел, которыми оперирует компьютер. И эта "приближенность" может иногда малость подрасти из-за использования оптимизации. Соответственно, при проверке, не является ли omega в точности равной omega_center-2.0d0*gamma, можно получить совсем не то, что ожидалось, поскольку и то, и другое число представлены в памяти компьютера приближенно. Короче, надо обязательно учитывать, что есть некоторая погрешность в компьютерном представлении действительных чисел, и так вот в лоб сравнивать их опасно. И это не глюк, это просто издержки двоичного исчисления.

Всего записей: 2485 | Зарегистр. 21-06-2005 | Отправлено: 16:17 25-03-2008 | Исправлено: XPEHOMETP, 16:20 25-03-2008
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akuaku
гы
 
всё работает с сингловой точностью...
все константы --> .e0
real(8) --> real*4
dble() --> real()
 
-----
а в общем-то, XPEHOMETP прав...
сравнивать (и именно на равенство) две плавающие точки -- засада...

Всего записей: 24107 | Зарегистр. 06-12-2002 | Отправлено: 16:39 25-03-2008 | Исправлено: akaGM, 21:11 25-03-2008
akuaku

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akaGM
Принципиально интересно как с .e0 работает, а с .d0 - нет!
 
Я пересмотрел свои реализацию этого дела так, чтобы не сталкиваться с этой проблемой (теперь делаю по второму варианту). На досуге ещё поковыряюсь ...

Всего записей: 95 | Зарегистр. 09-06-2005 | Отправлено: 14:16 26-03-2008 | Исправлено: akuaku, 14:22 26-03-2008
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
akuaku
маленький отчёт:
 
-- Лахей 5.0 отработал твой код точно так же как Интел...
 
-- во блин! gfortran вообще не лезет ни в один if () !
 

Цитата:
Я пересмотрел свои реализацию этого дела так, чтобы не сталкиваться с этой проблемой (теперь делаю по второму варианту)
а ты пересмотри свою задачу на предмет перенормировки... если там дальше у тебя нет никаких других тонкостей/точностей, то этот твой кусок вообще можно в целых числах решать...

Всего записей: 24107 | Зарегистр. 06-12-2002 | Отправлено: 14:44 26-03-2008 | Исправлено: akaGM, 14:46 26-03-2008
Spartach01

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Братцы,кто может,помогите пожалуйста.Не могу создать программу(массивы) для лабораторки.
 
"Дана последовательность из N целых чисел.Получить новую последователльность,которая отличается от исходной тем,что все четные члены заменены суммой предыдущих"
 

Всего записей: 12 | Зарегистр. 27-03-2008 | Отправлено: 19:26 28-03-2008
Spartach01

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Помогите пожалуйста,надо сдавать работу,а я не знаю,как ее делать.

Всего записей: 12 | Зарегистр. 27-03-2008 | Отправлено: 15:29 31-03-2008
terminat0r



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Spartach01
Ну, скажем так, за те три дня что Вы ждали на лабораторку, я написал и отладил программку на 1500 строк.
Может все-таки попробуете тоже что-то написать? Больше пользы будет. Покажете нам свои усилия, вот тогда и поговорим.

Всего записей: 2084 | Зарегистр. 31-03-2002 | Отправлено: 15:54 31-03-2008
pir0texnik2



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
И снова мои мучения с OpenMP...
Хочу сделать выход из параллельно цикла при условии, что  
m>M_max и  
zabs(ye_circ_out-Y_old) > errrel
Это цирк какой-то...
пишу...
 

Код:
 
USE OMP_LIB
INTEGER THREADS, M_up/0/
     ye_circ_out = 10000.0d0
     Y_old          = 0.0
     call OMP_SET_NUM_THREADS(2)
     THREADS = OMP_GET_NUM_THREADS( )
 
do while (((zabs(ye_circ_out-Y_old)) > errrel).OR.(M_up<=M_max))
    Y_old=ye_circ_out
    M_up = M_up + THREADS
!$OMP PARALLEL
!$OMP DO SCHEDULE (STATIC, THREADS)
do m=M_up-THREADS,M_up,1
....
ЦЫКЛ ...чего-то считаем...
....
end do
!$OMP END PARALLEL  

 
компилируем......
иии....

Код:
1>Compiling with Intel(R) Fortran Compiler 10.1.019 [IA-32]...
1>ye_circ.f90
1>fortcom: Fatal: There has been an internal compiler error (C0000005).
1>compilation aborted for C:\_user\Visual Studio 2005\Projects\ye_circ\ye_circ\ye_circ.f90 (code 1)
1>

 
неизменный результат...  
неглючит только если отключить OpenMP, но кому оно тогда надо...
как бы вывести....

Всего записей: 173 | Зарегистр. 27-02-2008 | Отправлено: 16:30 31-03-2008
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы программирования на FORTRAN (ФОРТРАН)


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru