贊助廠商

娛樂城推薦

首頁

電腦與網際網路/其他:電腦列表

Fortran- 輸出值顯示問號

小弟最近在學有限元素法在下面程式中,n<24內都可以正常顯示輸出的值但一旦n超過24時,輸出的值除了原本給定的邊界值計算出來的值均會變成???????????想請問版上的大神們有遇過這種情形嗎? PROGRAM FEM_HW1 IMPLICIT NONE real*8,parameter :: min = 0.d0 !Boundary real*8,parameter :: Max = 1.d0 !Boundary integer,parameter :: n = 24 integer :: i real*8 :: h,a,b,dx,x real*8 :: aa11,aa12,aa22,bb1,bb2 real*8 :: a11,a12,a22,b1,b2 real*8 :: ans real*8 :: gl(0:n) real*8 :: BB(0:n),DD(0:n),AA(0:n),CC(0:n) = 0 real*8 :: y(0:n) aa11(x,b,dx) = x*((b-x)/dx)**2 !Q = x aa22(x,a,dx) = x*((x-a)/dx)**2 !Q = x aa12(x,a,b,dx) = x*(a-x)/dx*(x-b)/dx !Q = x bb1(x,b,dx) = -x*(b-x)/dx !G = -x bb2(x,a,dx) = -x*(x-a)/dx !G = -x open(unit = 9,FILE='FEM_HW1.txt') dx = (Max - min)/dble(n) do i = 0,n gl(i) = dble(i)*dx+min end do do i = 0,n-1 h = (gl(i+1)-gl(i))/3.d0 call simpson(gl(i),gl(i+1),aa11(gl(i),gl(i+1),dx) C,aa11(gl(i)+h,gl(i+1),dx),aa11(gl(i)+h*2,gl(i+1),dx) C,aa11(gl(i)+h*3,gl(i+1),dx),ans) a11 = 1.d0/dx - ans call simpson(gl(i),gl(i+1),aa22(gl(i),gl(i),dx) C,aa22(gl(i)+h,gl(i),dx),aa22(gl(i)+h*2,gl(i),dx) C,aa22(gl(i)+h*3,gl(i),dx),ans) a22 = 1.d0/dx - ans call simpson(gl(i),gl(i+1),aa12(gl(i),gl(i),gl(i+1),dx) C,aa12(gl(i)+h,gl(i),gl(i+1),dx),aa12(gl(i)+h*2,gl(i),gl(i+1),dx) C,aa12(gl(i)+h*3,gl(i),gl(i+1),dx),ans) a12 = -1.d0/dx - ans call simpson(gl(i),gl(i+1),bb1(gl(i),gl(i+1),dx) C,bb1(gl(i)+h,gl(i+1),dx),bb1(gl(i)+h*2,gl(i+1),dx) C,bb1(gl(i)+h*3,gl(i+1),dx),ans) b1 = -ans call simpson(gl(i),gl(i+1),bb2(gl(i),gl(i),dx) C,bb2(gl(i)+h,gl(i),dx),bb2(gl(i)+h*2,gl(i),dx) C,bb2(gl(i)+h*3,gl(i),dx),ans) b2 = -ans BB(i+1) = BB(i+1) + a12 DD( i ) = DD( i ) + a11 AA( i ) = AA( i ) + a12 DD(i+1) = DD(i+1) + a22 CC( i ) = CC( i ) + b1 CC(i+1) = CC(i+1) + b2 end do BB(0) = 0.d0 DD(0) = 1.d0 AA(0) = 0.d0 CC(0) = 0.d0 !B.C. BB(n) = 0.d0 DD(n) = 1.d0 AA(n) = 0.d0 CC(n) = 0.d0 !B.C. CC( 1 ) = CC(1) - BB(1)*CC(0) BB( 1 ) = 0.d0 CC(n-1) = CC(n-1) - AA(n-1)*CC(n) AA(n-1) = 0.d0 call SY(1,n-1,BB(1:n-1),DD(1:n-1),AA(1:n-1),CC(1:n-1)) y = CC do i = 0,n write(*,"((F12.8))")y(i) write(9,"((F12.8))")y(i) end do close(9) STOP END SUBROUTINE simpson(min,Max,a,b,c,d,I) IMPLICIT NONE real*8 :: min,Max,a,b,c,d real*8 :: I I = (Max-min)*(a+b*3+c*3+d)/8 RETURN END SUBROUTINE SY(IL,IU,BB,DD,AA,CC) IMPLICIT DOUBLE PRECISION(A-H,O-Z) DIMENSION AA(1), BB(1), CC(1), DD(1) LP = IL + 1 DO 10 I = LP, IU R = BB(I)/DD(I-1) DD(I) = DD(I) - R*AA(I-1)10 CC(I) = CC(I) - R*CC(I-1) CC(IU) = CC(IU)/DD(IU) DO 20 I = LP,IU J = IU - I + IL20 CC(J) = (CC(J)-AA(J)*CC(J+1))/DD(J) RETURN END--
  • 發問日期:2021-06-03 21:50:08

計算數學 Problem Solving- ZJ-c223: Add All(變異版)

先感謝這兩天 oToToT 和 cutecpu 的指導和討論。概括這題的核心要求:O(1)的操作和CountSort/Radix-Sort是Uva-10954的加強版,原版的作法可以用 PriorityQueue 完成。兩題的差異在於 N=5e3 和 N=1e6 的量級,導致 PriorityQueue 的 log(N)作法會TLE。而觀察過程可以發現一個有趣的規律:每次合併數列中最小的兩個數字,合併後的這個數值是遞增的(廢話)。但原版的作法是放回 PriorityQueue,但這樣就會浪費遞增這個性質,於是改良版就是把合併後的數字用一個 Queue 存起來,每次放回數列的成本就降為O(1)。取最小值時則只要考慮原本數列和現在這個 Queue 最前面的數字即可,所以也是O(1)。詳細的作法請參考inversion文章:https://pse.is/EF4H5但即便達成上述的要求後還是可能會在最後一筆測資吃TLE,這裡就要談到加速讀取。一般加速讀取會談到 cin/cout 和 scanf()/printf() 的說明可以參考這篇:https://pse.is/HMHLT。我自己用getchar()做加速讀取還是不夠的。但這篇的測資輸入最大會 > 50M,以上的作法仍是不夠的,因為IO次數還是太多。於是我們便需要更底層的輸入函數:fread() 或者是 fgets()fread()版本(oToToT撰寫):https://pastebin.com/gdbX9QxX===以下是fread()讀取相關的說明文章,文章解釋得很仔細就不多說僅附上網址https://zhuanlan.zhihu.com/p/55304700===fgets()版本(cutecpu撰寫):https://ideone.com/usX8gE越底層的函數需要越清楚停止條件和讀入緩衝區的大小,這邊我舉fgets()為例,題目的第二行最多會有1e6個數字,每個數字不超過1e6(以字串來看長度不超過7),且數字間用空白隔開,所以緩衝區的大小是1<<23( 7e6 ),停止條件是'\n'。附上兩個函數的使用方式和差異:https://pse.is/HKWJY以及上述讀取函數的時間比較:https://pse.is/J2A5N最後排序的部分:假若採用CountSort約 0.4s 而呼叫內建的Qsort是 0.7s。結論來說 TLE 的主因還是讀取方式,排序方式不是決定的關鍵。如果大家有其他想法歡迎在下面留言,我晚點也會一並整理到內文中。--
  • 發問日期:2021-06-03 21:40:10

友站連結