■アリ地獄と化した計算)

 
 マーデルング定数に関しては,このコラムで4作目となる.まず,このシリーズを書くことになった発端の話から振り返ってみたい.
 
 「食塩はNa+とCl-が交互に並んで立方格子というジャングルジムのような構造を形成するイオン結晶である.NaCl結晶の場合,最近接イオン間の距離をrとすると,Na+イオンのまわりには,rだけ離れて6個のCl-イオンがあり,第2近接には√2rだけ離れて12個のNa+イオン,第3近接には√3rだけ離れて8個のCl-イオン,第4近接には2rだけ離れて6個のNa+イオンがある.第5近接には√5rだけ離れて24個のCl-イオン,・・・という具合になる.また,異符号のイオン間には引力が働き,同符号のイオン間には斥力が働くから,NaCl結晶の結合エネルギーは,これらのイオン間のクーロンポテンシャルを加えて,
  U=-e^2/r[6-12/√2+8/√3-6/2+24/√5-・・・]
となる.無限級数で示される括弧のなかの和
  6-12/√2+8/√3-6/2+24/√5-・・・
をマーデルング定数と呼ぶ.」
 
 「CsCl型構造では,1個のCsイオンに最も接近しているのは8個のClイオンである.この最近接距離をrとすると,第2近接は(2/√3)rの距離にある6個のCsイオン,第3近接は(2√2/√3)rの距離にある12個のCsイオン,第4近接は(√11/√3)rの距離にある24個のClイオン,さらに8個のCsイオンが2rの距離(第5近接)に存在する.
 したがって,CsClのマーデルング級数は,
  8-6/(2/√3)-12/(2√2/√3)+24/(√11/√3)-8/4-・・・
になる.」
 
 一般に,無限級数が収束する場合,それぞれの項のなかで絶対値が小さいものほど寄与が小さくなるから,正にせよ負にせよ絶対値の大きいものから足しあげていくのが常套であり,第n近接を求めて,原点からの距離の近い順に足し合わせてみるのは妥当なところであると考えられる.したがって,たいていの物性をテーマとする物理の本には,この無限級数が収束するのは当然のごとく書かれてある.
 
 この記述をみた瞬間,小生はこの無限級数は本当に収束するのかという疑問を持った.たとえば,CsClのマーデルング級数を実際に計算すると
  M=8−5.196−7.348+12.534−4−・・・
になり,はたせるかな,この方法では計算は収束しない.直観は正しかったのである.
 
===================================
 
プログラム(1)
 
1000 '
1010 ' *** Madelung constant ***
1020 '
1030 DEF FNODD(X)=INSTR(STR$((X-1)/2),".")
1040 '
1050 DIMENSION=3
1060 PRINT "dimension=";DIMENSION
1070 INPUT "distance =";D
1080 '
1090 MAX=(2*D+1)*(2*D+1)*(2*D+1)
1100 DIM R(MAX),R$(MAX),RR(MAX)
1110 DIM N(MAX),P(MAX),M(MAX)
1120 DIM SL(MAX),SR(MAX)
1130 D2=D*D
1140 EPS=.00001
1150 '
1160 ' ** MAIN **
1170 '
1180 *MAIN:
1190 'GOSUB *NACL
1200 'GOSUB *NACL2
1210 GOSUB *CSCL
1220 '
1230 GOSUB *SUM
1240 '
1250 GOSUB *QUICK.SORT
1260 GOSUB *TIE.RANK
1270 '
1280 PRINT:PRINT " R^2"," No."," +"," -"," M. const."
1290 SUM=0
1300 FOR I=1 TO NR
1310  SUM=SUM+(P(I)-M(I))/SQR(RR(I))
1320  PRINT RR(I),N(I),P(I),M(I),SUM
1330  IF (I MOD 20)=0 THEN PRINT
1340 NEXT I
1350 '
1360 PRINT:PRINT "Madelung=";SUM
1370 PRINT "N-th neighbor=";NR
1380 END
1390 '
1400 *NACL:
1410 AA=1:BB=1:CC=1
1420 AB=0:BC=0:CA=0
1430 RETURN
1440 '
1450 *NACL2:
1460 AA=SQR(2)/2
1470 BB=AA:CC=AA
1480 AB=1/2
1490 BC=AB:CA=AB
1500 RETURN
1510 '
1520 *CSCL:
1530 AA=1:BB=1:CC=1
1540 AB=-1/3
1550 BC=AB:CA=AB
1560 RETURN
1570 '
1580 *SUM:
1590 NN=0
1600  FOR X=-D TO D
1610   FOR Y=-D TO D
1620    FOR Z=-D TO D
1630     PRINT "*";
1640     GOSUB *SUM3
1650    NEXT Z
1660   NEXT Y
1670  NEXT X
1680 PRINT
1690 RETURN
1700 '
1710 *SUM3:
1720 S1=X*X*AA*AA+Y*Y*BB*BB+Z*Z*CC*CC
1730 S2=2*(X*Y*AA*BB*AB+Y*Z*BB*CC*BC+Z*X*CC*AA*CA)
1740 R2=ABS(S1+S2):R=SQR(R2)
1750 IF R<=0 THEN 1820
1760 '
1770 IF R2>D2 THEN 1820
1780 NN=NN+1
1790 R(NN)=R2
1800 IF FNODD(X+Y+Z)=0 THEN R$(NN)="+" ELSE R$(NN)="-"
1810 '
1820 RETURN
1830 '
1840 ' *** QUICK SORT ***
1850 '
1860 *QUICK.SORT:
1870 PRINT:PRINT "ただいまソート中"
1880 '
1890 S=1:SL(1)=1:SR(1)=NN
1900 WHILE S<>0
1910  L=SL(S):R=SR(S):S=S-1
1920  WHILE L<R
1930   I=L:J=R:X=R((L+R)\2)
1940   WHILE I<=J
1950    WHILE R(I)<X:I=I+1:WEND
1960    WHILE R(J)>X:J=J-1:WEND
1970    IF I<=J THEN SWAP R(I),R(J):SWAP R$(I),R$(J):I=I+1:J=J-1
1980   WEND
1990   IF I<R THEN S=S+1:SL(S)=I:SR(S)=R
2000   R=J
2010  WEND
2020 WEND
2030 RETURN
2040 '
2050 ' *** TIE RANKING ***
2060 '
2070 *TIE.RANK:
2080 NR=0
2090 I=1
2100 WHILE I<=NN
2110  L=1
2120  IL=I+L
2130  WHILE IL<=NN
2140  'IF R(I)<R(IL) THEN 2190
2150   IF ABS((R(I)-R(IL))/R(IL))>EPS THEN 2190
2160   L=L+1
2170   IL=I+L
2180  WEND
2190 '
2200  P=0:M=0
2210  FOR J=I TO I+L-1
2220   IF R$(J)="+" THEN P=P+1
2230   IF R$(J)="-" THEN M=M+1
2240  NEXT J
2250  NR=NR+1:RR(NR)=R(I):N(NR)=L:P(NR)=P:M(NR)=M:I=IL
2260 '
2270 WEND
2280 RETURN
 
 原点からの距離を2乗した値を配列Rに,引力・斥力の別を配列R$に取り込んだ後,各データを原点からの距離の順に並べる.ソートでは最も平均的な効率がよく,最高速だといわれているクイックソートを採用した.
 
 次に,サブルーチン*tie.rankで同一距離のイオン数を計算する.この計算では単調増加数列のプラトー(非増加部分)の長さを求めることになるが,手順を分析しそれを具体的な形に表していくという意味で,プログラム設計者の腕の見せどころとなるステップである.なお,BASICの単精度計算は10進法換算で7桁程度であるが,表示桁数は6桁までであり,表示された数値が同じであっても,内部的には異なる数として認識される.コンピュータを使って計算するとよくこのような誤算の問題に遭遇するが,2140行の代わりに2150行のように相対誤差を計算すれば,これを回避し順位計算を正しく行うことができる.
 
===================================
 
1)NaClの場合
 d=4と入力すると第14近接まで計算され,下のような計算結果が表示される.左のカラムから順に,距離2乗値,イオン数,引力イオン数,斥力イオン数,マーデルング定数の途中経過を表している.
 
 たとえば,第5近接までをとると,
  M=6-12/√2+8/√3-6/2+24/√5=9.867  (第5近接)
 また,最下段には第14近接まで計算したマーデルング定数が表示される.
  M=−4.509  (第14近接)
 
R^2      No.      +       -       M. const.
1       6       6       0       6
2       12      0       12      -2.48528
3       8       8       0       2.13352
4       6       0       6      -.86648
5       24      24      0       9.86665
6       24      0       24      .0686874
8       12      0       12      -4.17395
9       30      30      0       5.82605
10      24      0       24      -1.76342
11      24      24      0       5.47285
12      8       0       8       3.16345
13      24      24      0       9.81985
14      48      0       48      -3.00868
16      6       0       6      -4.50868
 
Madelung=-4.50868
N-th neighbor= 14
 
===================================
 
2)CsClの場合
 同じく,d=4と入力すると第17近接まで計算され,
  M=−2.968  (第17近接)
と表示される.第5近接までをとると,
  M=8-6/(2/√3)-12/(2√2/√3)+24/(√11/√3)-8/4
   =3.989  (第5近接)
 
R^2      No.      +       -       M. const.
1       8       8       0       8
1.33333    6       0       6       2.80385
2.66667    12      0       12      -4.54462
3.66667    24      24      0       7.98897
4       8       0       8       3.98897
5.33333    6       0       6       1.39089
6.33333    24      24      0       10.9275
6.66667    24      0       24      1.63237
8       24      0       24      -6.85292
9       32      32      0       3.81375
10.6667    12      0       12      .139516
11.6667    48      48      0       14.1925
12      30      0       30      5.53222
13.3333    24      0       24      -1.04045
14.3333    24      24      0       5.2988
14.6667    24      0       24      -.967996
16      8       0       8      -2.968
Madelung=-2.968
N-th neighbor= 17
 
===================================
 
 計算結果は,いずれの場合も振動が激しく,正確なマーデルング定数:
  α=1.747565  (NaCl)
  α=1.762675  (CsCl)
とは大きくかけ離れてしまった.
 
 NaClの場合,以下,
  d=5 → M=5.2458  (第22近接)
  d=10 → M=−6.0350 (第85近接)
 CsClの場合,
  d=5 → M=2.0085  (第26近接)
  d=10 → M=3.3978  (第102近接)
と続く.
 
===================================
 
 データ数は(2d+1)^3個あり,dをこれ以上大きくすると,メモリに入りきらないほど巨大なデータを扱うことになる.データを格納する配列の大きさはいくらでも大きくできるわけではなく,1つの配列につき64KBという上限があり,単精度実数型配列の場合は16383が限界値となっている.
 
 作業用配列の使用量を最小にするため,苦肉の策であるが,以下のプログラムでは同じ機能のサブルーチンを2度繰り返して実行している.ダサイし,いやらしいことだが,経済的なメモリ使用の必要上,やむを得まい.このあたりがBASICプログラムの最大の泣きどころになっている.
 
 さらに,クイック・ソートはもっとも有効な内部ソート(オンメモリソート)の1つであるが,ソートする部分の両端をスタックに記憶しておく必要があり,大きな作業用配列が必要となる.そこで,メモリ節約のために,スタックを必要とせず,しかも最高速だといわれるクイックソート並かそれ以上の速度が出せるコムソートを用いることにした.
 
プログラム(2)
 
1000 '
1010 ' *** Madelung constant ***
1020 '
1030 DEF FNODD(X)=INSTR(STR$((X-1)/2),".")
1040 '
1050 DIMENSION=3
1060 PRINT "dimension=";DIMENSION
1070 INPUT "distance =";D
1080 '
1090 D2=D*D
1100 EPS=.00001
1110 '
1120 ' ** MAIN **
1130 '
1140 *MAIN:
1150 'GOSUB *NACL
1160 'GOSUB *NACL2
1170 GOSUB *CSCL
1180 '
1190 GOSUB *DIM1
1200 DIM R(NN),R$(NN)
1210 GOSUB *SUM
1220 'GOSUB *QUICK.SORT
1230 GOSUB *COMB.SORT
1240 '
1250 GOSUB *DIM2
1260 DIM RR(NR)
1270 DIM N(NR),P(NR),M(NR)
1280 GOSUB *TIE.RANK
1290 '
1300 PRINT:PRINT " R^2"," No."," +"," -"," M. const."
1310 SUM=0
1320 FOR I=1 TO NR
1330  SUM=SUM+(P(I)-M(I))/SQR(RR(I))
1340  PRINT RR(I),N(I),P(I),M(I),SUM
1350  IF (I MOD 20)=0 THEN PRINT
1360 NEXT I
1370 '
1380 PRINT:PRINT "Madelung=";SUM
1390 PRINT "N-th neighbor=";NR
1400 END
1410 '
1420 *NACL:
1430 AA=1:BB=1:CC=1
1440 AB=0:BC=0:CA=0
1450 RETURN
1460 '
1470 *NACL2:
1480 AA=SQR(2)/2
1490 BB=AA:CC=AA
1500 AB=1/2
1510 BC=AB:CA=AB
1520 RETURN
1530 '
1540 *CSCL:
1550 AA=1:BB=1:CC=1
1560 AB=-1/3
1570 BC=AB:CA=AB
1580 RETURN
1590 '
1600 *SUM:
1610 NN=0
1620  FOR X=-D TO D
1630   FOR Y=-D TO D
1640    FOR Z=-D TO D
1650     PRINT "*";
1660     GOSUB *SUM3
1670    NEXT Z
1680   NEXT Y
1690  NEXT X
1700 PRINT
1710 RETURN
1720 '
1730 *SUM3:
1740 S1=X*X*AA*AA+Y*Y*BB*BB+Z*Z*CC*CC
1750 S2=2*(X*Y*AA*BB*AB+Y*Z*BB*CC*BC+Z*X*CC*AA*CA)
1760 R2=ABS(S1+S2):R=SQR(R2)
1770 IF R<=0 THEN 1840
1780 '
1790 IF R2>D2 THEN 1840
1800 NN=NN+1
1810 R(NN)=R2
1820 IF FNODD(X+Y+Z)=0 THEN R$(NN)="+" ELSE R$(NN)="-"
1830 '
1840 RETURN
1850 '
1860 ' *** QUICK SORT ***
1870 '
1880 *QUICK.SORT:
1890 PRINT:PRINT "ただいまソート中"
1900 '
1910 S=1:SL(1)=1:SR(1)=NN
1920 WHILE S<>0
1930  L=SL(S):R=SR(S):S=S-1
1940  WHILE L<R
1950   I=L:J=R:X=R((L+R)\2)
1960   WHILE I<=J
1970    WHILE R(I)<X:I=I+1:WEND
1980    WHILE R(J)>X:J=J-1:WEND
1990    IF I<=J THEN SWAP R(I),R(J):SWAP R$(I),R$(J):I=I+1:J=J-1
2000   WEND
2010   IF I<R THEN S=S+1:SL(S)=I:SR(S)=R
2020   R=J
2030  WEND
2040 WEND
2050 RETURN
2060 '
2070 ' *** TIE RANKING ***
2080 '
2090 *TIE.RANK:
2100 NR=0
2110 I=1
2120 WHILE I<=NN
2130  L=1
2140  IL=I+L
2150  WHILE IL<=NN
2160   IF ABS((R(I)-R(IL))/R(IL))>EPS THEN 2200
2170   L=L+1
2180   IL=I+L
2190  WEND
2200 '
2210  P=0:M=0
2220  FOR J=I TO I+L-1
2230   IF R$(J)="+" THEN P=P+1
2240   IF R$(J)="-" THEN M=M+1
2250  NEXT J
2260  NR=NR+1:RR(NR)=R(I):N(NR)=L:P(NR)=P:M(NR)=M:I=IL
2270 '
2280 WEND
2290 RETURN
2300 '
2310 ' *** dimension-1 ***
2320 '
2330 *DIM1:
2340 NN=0
2350  FOR X=-D TO D
2360   FOR Y=-D TO D
2370    FOR Z=-D TO D
2380     PRINT "*";
2390     GOSUB *DIM3
2400    NEXT Z
2410   NEXT Y
2420  NEXT X
2430 PRINT
2440 RETURN
2450 '
2460 *DIM3:
2470 S1=X*X*AA*AA+Y*Y*BB*BB+Z*Z*CC*CC
2480 S2=2*(X*Y*AA*BB*AB+Y*Z*BB*CC*BC+Z*X*CC*AA*CA)
2490 R2=ABS(S1+S2):R=SQR(R2)
2500 IF R<=0 THEN 2530
2510 IF R2>D2 THEN 2530
2520 NN=NN+1
2530 RETURN
2540 '
2550 ' *** dimension-2 ***
2560 '
2570 *DIM2:
2580 NR=0
2590 I=1
2600 WHILE I<=NN
2610  L=1
2620  IL=I+L
2630  WHILE IL<=NN
2640   IF ABS((R(I)-R(IL))/R(IL))>EPS THEN 2680
2650   L=L+1
2660   IL=I+L
2670  WEND
2680 '
2690  NR=NR+1:I=IL
2700 '
2710 WEND
2720 RETURN
2730 '
2740 ' *** COMB SORT-11 ***
2750 '
2760 *COMB.SORT:
2770 PRINT:PRINT "ただいまソート中"
2780 '
2790 SF=1.3
2800 GAP=NN
2810 SW=1
2820 WHILE SW=1 OR GAP>1
2830  IF INT(GAP/SF)>1 THEN GAP=INT(GAP/SF) ELSE GAP=1
2840  IF GAP=9 OR GAP=10 THEN GAP=11
2850  SW=0
2860  FOR I=1 TO NN-GAP
2870   J=I+GAP
2880   IF R(I)>R(J) THEN SWAP R(I),R(J):SWAP R$(I),R$(J):SW=1
2890  NEXT I
2900 WEND
2910 RETURN
 
 しかし,このプログラムを用いても,
1)NaClの場合
  d=15 → M=10.0539 (第189近接)
2)CsClの場合
  d=14 → M=5.5929  (第198近接)
まで計算するのが限界であった.
 
===================================
 
 さらに,以下のプログラムでは,メモリの節約効果を高めるように工夫してある.10カ所の変更箇所には*マークをつけておいた.
 
 主たる変更点を述べると,サブルーチン*SUMでは,データの取り込み範囲をx≧0とし,サブルーチン*SUM3の因子MをM=2としている.1820行でこの値を配列Lに取り込むが,これによって取り込みに要する時間もメモリ使用量も約1/2に節減される.
 
プログラム(3)
 
1000 '
1010 ' *** Madelung constant ***
1020 '
1030 DEF FNODD(X)=INSTR(STR$((X-1)/2),".")
1040 '
1050 DIMENSION=3
1060 PRINT "dimension=";DIMENSION
1070 INPUT "distance =";D
1080 '
1090 D2=D*D
1100 EPS=.00001
1110 '
1120 ' ** MAIN **
1130 '
1140 *MAIN:
1150 'GOSUB *NACL
1160 'GOSUB *NACL2
1170 GOSUB *CSCL
1180 '
1190 GOSUB *DIM1
1200 DIM R(NN),R$(NN),L(NN)   *
1210 GOSUB *SUM
1220 'GOSUB *QUICK.SORT
1230 GOSUB *COMB.SORT
1240 '
1250 GOSUB *DIM2
1260 DIM RR(NR)
1270 DIM N(NR),P(NR),M(NR)
1280 GOSUB *TIE.RANK
1290 '
1300 PRINT:PRINT " R^2"," No."," +"," -"," M. const."
1310 SUM=0
1320 FOR I=1 TO NR
1330  SUM=SUM+(P(I)-M(I))/SQR(RR(I))
1340  PRINT RR(I),N(I),P(I),M(I),SUM
1350  IF (I MOD 20)=0 THEN PRINT
1360 NEXT I
1370 '
1380 PRINT:PRINT "Madelung=";SUM
1390 PRINT "N-th neighbor=";NR
1400 END
1410 '
1420 *NACL:
1430 AA=1:BB=1:CC=1
1440 AB=0:BC=0:CA=0
1450 RETURN
1460 '
1470 *NACL2:
1480 AA=SQR(2)/2
1490 BB=AA:CC=AA
1500 AB=1/2
1510 BC=AB:CA=AB
1520 RETURN
1530 '
1540 *CSCL:
1550 AA=1:BB=1:CC=1
1560 AB=-1/3
1570 BC=AB:CA=AB
1580 RETURN
1590 '
1600 *SUM:
1610 NN=0
1620  FOR X=0 TO D   *
1630   FOR Y=-D TO D
1640    FOR Z=-D TO D
1650     PRINT "*";
1660     GOSUB *SUM3
1670    NEXT Z
1680   NEXT Y
1690  NEXT X
1700 PRINT
1710 RETURN
1720 '
1730 *SUM3:
1740 S1=X*X*AA*AA+Y*Y*BB*BB+Z*Z*CC*CC
1750 S2=2*(X*Y*AA*BB*AB+Y*Z*BB*CC*BC+Z*X*CC*AA*CA)
1760 R2=ABS(S1+S2):R=SQR(R2)
1770 IF R<=0 THEN 1850
1780 '
1790 IF R2>D2 THEN 1850
1800 M=2:IF X=0 THEN M=1   *
1810 NN=NN+1
1820 R(NN)=R2:L(NN)=M   *
1830 IF FNODD(X+Y+Z)=0 THEN R$(NN)="+" ELSE R$(NN)="-"
1840 '
1850 RETURN
1860 '
1870 ' *** QUICK SORT ***
1880 '
1890 *QUICK.SORT:
1900 PRINT:PRINT "ただいまソート中"
1910 '
1920 S=1:SL(1)=1:SR(1)=NN
1930 WHILE S<>0
1940  L=SL(S):R=SR(S):S=S-1
1950  WHILE L<R
1960   I=L:J=R:X=R((L+R)\2)
1970   WHILE I<=J
1980    WHILE R(I)<X:I=I+1:WEND
1990    WHILE R(J)>X:J=J-1:WEND
2000    IF I<=J THEN SWAP R(I),R(J):SWAP R$(I),R$(J)                        :SWAP L(I),L(J):I=I+1:J=J-1   *
2010   WEND
2020   IF I<R THEN S=S+1:SL(S)=I:SR(S)=R
2030   R=J
2040  WEND
2050 WEND
2060 RETURN
2070 '
2080 ' *** TIE RANKING ***
2090 '
2100 *TIE.RANK:
2110 NR=0
2120 I=1
2130 WHILE I<=NN
2140  L=1
2150  IL=I+L
2160  WHILE IL<=NN
2170   IF ABS((R(I)-R(IL))/R(IL))>EPS THEN 2210
2180   L=L+1
2190   IL=I+L
2200  WEND
2210 '
2220  P=0:M=0
2230  FOR J=I TO I+L-1
2240   IF R$(J)="+" THEN P=P+L(J)   *
2250   IF R$(J)="-" THEN M=M+L(J)   *
2260  NEXT J
2270  NR=NR+1:RR(NR)=R(I):N(NR)=P+M:P(NR)=P:M(NR)=M:I=IL   *
2280 '
2290 WEND
2300 RETURN
2310 '
2320 ' *** dimension-1 ***
2330 '
2340 *DIM1:
2350 NN=0
2360  FOR X=0 TO D   *
2370   FOR Y=-D TO D
2380    FOR Z=-D TO D
2390     PRINT "*";
2400     GOSUB *DIM3
2410    NEXT Z
2420   NEXT Y
2430  NEXT X
2440 PRINT
2450 RETURN
2460 '
2470 *DIM3:
2480 S1=X*X*AA*AA+Y*Y*BB*BB+Z*Z*CC*CC
2490 S2=2*(X*Y*AA*BB*AB+Y*Z*BB*CC*BC+Z*X*CC*AA*CA)
2500 R2=ABS(S1+S2):R=SQR(R2)
2510 IF R<=0 THEN 2540
2520 IF R2>D2 THEN 2540
2530 NN=NN+1
2540 RETURN
2550 '
2560 ' *** dimension-2 ***
2570 '
2580 *DIM2:
2590 NR=0
2600 I=1
2610 WHILE I<=NN
2620  L=1
2630  IL=I+L
2640  WHILE IL<=NN
2650   IF ABS((R(I)-R(IL))/R(IL))>EPS THEN 2690
2660   L=L+1
2670   IL=I+L
2680  WEND
2690 '
2700  NR=NR+1:I=IL
2710 '
2720 WEND
2730 RETURN
2740 '
2750 ' *** COMB SORT-11 ***
2760 '
2770 *COMB.SORT:
2780 PRINT:PRINT "ただいまソート中"
2790 '
2800 SF=1.3
2810 GAP=NN
2820 SW=1
2830 WHILE SW=1 OR GAP>1
2840  IF INT(GAP/SF)>1 THEN GAP=INT(GAP/SF) ELSE GAP=1
2850  IF GAP=9 OR GAP=10 THEN GAP=11
2860  SW=0
2870  FOR I=1 TO NN-GAP
2880   J=I+GAP
2890   IF R(I)>R(J) THEN SWAP R(I),R(J):SWAP R$(I),R$(J)                        :SWAP L(I),L(J):SW=1   *
2900  NEXT I
2910 WEND
2920 RETURN
 
 これにより,
1)NaClの場合
  d=19 → M=−1.1299 (第303近接)
2)CsClの場合
  d=15 → M=12.624  (第226近接)
  d=18 → M=2.6754  (第326近接)
まで計算範囲が拡大している.配列の64KBの制約の中では,これが限界であろう.
 
===================================
 
 今回のコラムでは,なかなか収束しない計算を展望してみた.途中,MSDOS/N88BASICによる制約のために,本題から一時脱線して,メモリ節減というアリ地獄にはまってしまった.確かにメモリの節減は大切なことであるが,いまはその辺はOSが面倒をみてくれて,プログラマはメモリサイズを気にしなくてもよい時代になっている.
 
 マーデルング級数の困難な点は,級数のなかの陽イオンの項と陰イオンの項が別々に発散することである.すなわち,∞−∞の不定形であり,条件つき収束のため,マーデルング級数の収束はきわめて遅く,プログラム的には収束しないという結論になってしまうことである.
 
 マーデルング定数の計算法に関しては,固体物理の教科書(例えば,キッテル「固体物理学入門」丸善・・・現在,第7版が出版されている)を参考にしたが,そこには,フーリエ変換を用いて計算する方法が紹介されている.特異点を打ち消し無限大になるのを抑えながら計算する非常に巧みな方法なのであろうが,小生にとってはまるでトリックでも見せられている感じで,あまり感心しなかった.結晶の規則的な配列は,そのような難解な方法を使わなくても,初等的な方法で十分計算可能と思われたからである.
 
 たとえ収束は遅くとも,いろいろな結晶構造のマーデルング定数を求めるプログラムを組み立ててみたい.おぼろげな概念であるが,これがこのシリーズを書くことになった動機であり,目的となっている.
 
===================================