ルジャンドル則係数計算

 投稿者:しばっち  投稿日:2008年12月30日(火)09時40分5秒
  有限区間積分
/1
| f(x)dx
/-1

ガウス・ルジャンドル則の係数(分点、重み)を算出する。
1000桁モードを使用し、ルジャンドル多項式をニュートン法 + 組立除法で解く


OPTION BASE 0
OPTION ARITHMETIC DECIMAL_HIGH
PUBLIC NUMERIC MAXLEVEL,EPS
LET MAXLEVEL=10 !'次数
DIM X(MAXLEVEL),W(MAXLEVEL)
LET KETA=16 !'求める桁数
LET EPS=10^(-KETA)
LET DISPMODE=0 !' 0 or else
LET INTEGRAL=1 !' INTEGRAL >= 1
IF DISPMODE<>0 THEN
   CALL LEGENDREPARA(MAXLEVEL,X,W)
   PRINT "DIM X(";STR$(MAXLEVEL);"),W(";STR$(MAXLEVEL);")"
   FOR I=1 TO INTEGRAL
      PRINT "! INPUT  PROMPT ";CHR$(34);"下限 ";STR$(I);"=";CHR$(34);":A";STR$(I)
      PRINT "! INPUT  PROMPT ";CHR$(34);"上限 ";STR$(I);"=";CHR$(34);":B";STR$(I)
   NEXT I
   FOR I=1 TO INTEGRAL
      PRINT "LET A";STR$(I);"=0"
      PRINT "LET B";STR$(I);"=1"
   NEXT I
   FOR J=1 TO INTEGRAL
      PRINT "LET U";STR$(J);"=(B";STR$(J);"+A";STR$(J);")/2"
      PRINT "LET V";STR$(J);"=(B";STR$(J);"-A";STR$(J);")/2"
   NEXT J
   PRINT "FOR I=1 TO";MAXLEVEL
   PRINT "READ X(I),W(I)"
   PRINT "NEXT"
   PRINT "LET S=0"
   FOR J=1 TO INTEGRAL
      PRINT "FOR K";STR$(J);"=1 TO";MAXLEVEL
   NEXT J
   PRINT "LET  S=S+";
   FOR J=1 TO INTEGRAL
      PRINT "W(K";STR$(J);")*";
   NEXT J
   PRINT "FUNC(";
   FOR I=1 TO INTEGRAL
      PRINT "U";STR$(I);"+V";STR$(I);"*X(K";STR$(I);")";
      IF I < INTEGRAL THEN PRINT ",";
   NEXT I
   PRINT ")";
   FOR J=1 TO INTEGRAL
      PRINT "*V";STR$(J);
   NEXT J
   PRINT
   FOR J=1 TO INTEGRAL
      PRINT "NEXT"
   NEXT J
   PRINT "PRINT S"
   FOR I=1 TO MAXLEVEL
      PRINT "DATA ";
      PRINT USING "#." & REPEAT$("#",KETA):X(I);
      PRINT ",";
      PRINT USING "#." & REPEAT$("#",KETA) & "^^^^":W(I)
   NEXT I
   PRINT "END"
   PRINT
   PRINT "EXTERNAL  FUNCTION FUNC(";
   FOR I=1 TO INTEGRAL
      PRINT "X";STR$(I);
      IF I < INTEGRAL THEN PRINT ",";
   NEXT I
   PRINT ")"
   PRINT "LET S=1";
   FOR I=1 TO INTEGRAL
      PRINT "-X";STR$(I);"*X";STR$(I);
   NEXT I
   PRINT
   PRINT "IF S > 0 THEN"
   PRINT "LET FUNC=SQR(S)"
   PRINT "ELSE"
   PRINT "LET FUNC=0"
   PRINT "END IF"
   PRINT "END FUNCTION"
ELSE
   FOR N=2 TO MAXLEVEL
      PRINT TAB(8+KETA/2);"分点";TAB(8+KETA*1.5);"   重み"
      CALL LEGENDREPARA(N,X,W)
      FOR I=1 TO N
         PRINT "No.";I;":";
         PRINT USING "#." & REPEAT$("#",KETA):X(I);
         PRINT "  ";
         PRINT USING "#." & REPEAT$("#",KETA) & "^^^^":W(I)
      NEXT I
   NEXT N
END IF
END

EXTERNAL  SUB LEGENDREPARA(N,A(),W())
OPTION ARITHMETIC DECIMAL_HIGH
OPTION BASE 0
DIM P(MAXLEVEL),D(MAXLEVEL)
CALL  LEGENDREPOLY(N,P)
FOR I=0 TO N
   LET P(I)=P(I)/P(N)
NEXT I
FOR I=1 TO N
   CALL DERIVATIVE(P,D) !'微分
   LET XX=-1 !'初期値
   DO
      LET X=XX
      LET XX=X-HORNER(N,P,X)/HORNER(N,D,X) !'ニュートン法
   LOOP UNTIL ABS(HORNER(N,P,XX)) < EPS AND ABS(X-XX) < EPS
   LET A(I)=XX !'分点
   LET W(I)=WEIGHT(N,XX) !'重み
   CALL DIV(P,XX) !'組立除法
NEXT I
END SUB

EXTERNAL  SUB LEGENDREPOLY(KK,NEWP()) !'ルジャンドル多項式(係数)
OPTION ARITHMETIC DECIMAL_HIGH
OPTION BASE 0
DIM P(KK+1),OLDP(KK),PP(KK)
LET  OLDP(0)=1
LET  P(1)=1
FOR I=0 TO KK
   LET NEWP(I)=0
NEXT I
FOR K=2 TO KK
   FOR J=1 TO K
      LET  NEWP(J)=NEWP(J)+(2*K-1)/K*P(J-1)
      LET  NEWP(J-1)=NEWP(J-1)-(K-1)/K*OLDP(J-1)
   NEXT J
   IF K < KK THEN
      FOR I=0 TO K
         LET  OLDP(I)=P(I)
         LET  P(I)=NEWP(I)
         LET  NEWP(I)=0
      NEXT I
   END IF
NEXT K
END SUB

EXTERNAL  FUNCTION LEGENDRE(K,X) !'ルジャンドル多項式(値)
OPTION ARITHMETIC DECIMAL_HIGH
OPTION BASE 0
DIM PP(K+1)
LET  PP(0)=1
LET  PP(1)=X
FOR N=1 TO K-1
   LET  PP(N+1)=((2*N+1)*X*PP(N)-N*PP(N-1))/(N+1)
NEXT N
LET  LEGENDRE=PP(K)
END FUNCTION

EXTERNAL  FUNCTION WEIGHT(N,X) !'重み
OPTION ARITHMETIC DECIMAL_HIGH
LET WEIGHT=2*(1-X^2)/(N*LEGENDRE(N-1,X))^2
END FUNCTION

EXTERNAL  FUNCTION HORNER(N,A(),X)
OPTION ARITHMETIC DECIMAL_HIGH
LET  Y=A(N)
FOR I=N-1 TO 0 STEP -1
   LET  Y=Y*X+A(I)
NEXT I
LET  HORNER=Y
END FUNCTION

EXTERNAL  SUB DERIVATIVE(A(),B()) !'微分
OPTION ARITHMETIC DECIMAL_HIGH
FOR I=MAXLEVEL TO 1 STEP -1
   LET  B(I-1)=I*A(I)
NEXT I
LET B(MAXLEVEL)=0
END SUB

EXTERNAL  SUB DIV(A(),P) !'組立除法
!'A(N)*X^N+A(N-1)*X^(N-1)+...+A(2)*X^2+A(1)*X+A(0)=(X-P)(C(N-1)*X^(N-1)+...+C(2)*X^2+C(1)*X+C(0))
OPTION BASE 0
OPTION ARITHMETIC DECIMAL_HIGH
DIM C(MAXLEVEL)
FOR I=MAXLEVEL TO 1 STEP -1
   LET  C(I-1)=A(I)+C(I)*P
NEXT I
CALL COPY(A,C)
END SUB

EXTERNAL  SUB COPY(X(),Y())
OPTION ARITHMETIC DECIMAL_HIGH
FOR I=0 TO MAXLEVEL
   LET  X(I)=Y(I)
NEXT I
END SUB
---------------------------------------------------
ルジャンドル多項式表示
有理数モードでお試しください

OPTION BASE 0
PUBLIC NUMERIC MAXLEVEL
LET  MAXLEVEL=20 !'次数
DIM P(MAXLEVEL)
PRINT "P(0)=1"
PRINT "P(1)=X"
FOR K=2 TO MAXLEVEL
   CALL LEGENDREPOLY(K,P) !'上記参照(OPTION ARITHMETIC DECIMAL_HIGHを外す)
   PRINT "P(";STR$(K);")=";
   CALL DISPLAY(P)
NEXT K
END

EXTERNAL  SUB DISPLAY(A())
FOR N=MAXLEVEL TO 0 STEP -1
   IF A(N)<>0 THEN EXIT FOR
NEXT N
IF N > 1 THEN
   IF A(N) < 0 THEN PRINT "-";
   IF ABS(A(N))<>1 THEN
      PRINT STR$(ABS(A(N)));"*X^";STR$(N);
   ELSE
      PRINT "X^";STR$(N);
   END IF
END IF
FOR I=N-1 TO 2 STEP -1
   IF A(I)<>0 THEN
      IF A(I) < 0 THEN PRINT "-"; ELSE PRINT "+";
      IF ABS(A(I))<>1 THEN
         PRINT STR$(ABS(A(I)));"*X^";STR$(I);
      ELSEIF ABS(A(I))=1 THEN
         PRINT "X^";STR$(I);
      END IF
   END IF
NEXT I
IF A(1)<>0 THEN
   IF N > 1 THEN
      IF A(1) < 0 THEN PRINT "-"; ELSE PRINT "+";
   END IF
   IF ABS(A(1))<>1 THEN
      PRINT STR$(ABS(A(1)));"*X";
   ELSEIF ABS(A(1))=1 THEN
      PRINT "X";
   END IF
END IF
IF A(0)<>0 THEN
   IF A(0) < 0 THEN PRINT "-"; ELSE PRINT "+";
   PRINT STR$(ABS(A(0)));
END IF
PRINT
END SUB
 

戻る