十進BASIC 第2掲示板 過去ログ 1-1000




新掲示板開設

 投稿者:白石 和夫  投稿日:2008年 7月21日(月)09時38分46秒
返信・引用  編集済
  十進BASIC第2掲示板を開設しました。
メインの掲示板が不調のとき,こちらをご利用ください。
なお,最大500行まで書き込めることになっていますが,
実験的には251行までしか書き込めないようです。
Internet Explorerでもインデントを保持したまま表示されること,
同一人による連続書き込みに規制がかかること(スパム対策)
など,利点も多いので,将来的には本格的な移転もありえます。
 

第2掲示板に感謝

 投稿者:北摂三太郎  投稿日:2008年 7月23日(水)10時27分59秒
返信・引用
  私の県の学校ネットでは、旧十進BASIC掲示板は、なぜか「有害情報」として扱われ学校からは閲覧することができません。(フィルターにひっかかるようです。)
この第2掲示板は今のところ閲覧できてますので、こちらに移転していただけるとありがたいです。
 

【質問】chr$での文字表示について

 投稿者:Bear  投稿日:2008年 9月 2日(火)04時49分9秒
返信・引用
  ※現在の住まいの関係上、無料メールしか利用できないため
※こちらの掲示板に書かせていただきます。

当方、WindowsXp + 十進BASIC 7.2.7という環境です。
前に十進BASICとUltraBASICの違いを質問した者です、よろしくお願いします。

 print chr$(...)

て具合に番地指定で文字表示させる際に
WindowsのIMEパッドで見える範囲を指定してるのにちょくちょく例外が発生します。

=ここから=
option character kanji
input prompt "全角で1文字入力してください:":a$
let b=ord(a$)
let b$=str$(b)
let c$=bstr$(ord(a$),16)
let d$=right$(c$,2)&left$(c$,2)
print
print chr$(bval(c$,16))&"(JIS:"&c$&")"&" -> "&chr$(bval(d$,16))&"(JIS:"&d$&")"
end
=ここまで=

例として、上記プログラムでa$に「日」と入力した場合に出力される文字を
テキストウィンドウ内でコピーしてからプログラムを再実行して
2回目のa$入力でペーストすれば「裏の裏は表」となり、今度は「日」が出力されるはずだと思うのですが
なぜかここで例外4002が発生してしまいます。

当方の記述にまずい点があればご教示いただけませんでしょうか。
それともFull Basicの規格に準拠する仕様上、当然の結果なのでしょうか?
 

Re: 【質問】chr$での文字表示について

 投稿者:SECOND  投稿日:2008年 9月 2日(火)22時32分26秒
返信・引用  編集済
  > No.3[元記事へ]

削除編集できません。→ 投稿者:SECOND  投稿日:2008年 9月 2日(火)21時28分28秒
削除して下さい。


win98SE + ver7.2.7 では、例外が発生せず、以下の様に
期待どうりになります。
しかし、byte 反転した word は、漢字コードの許される範囲を、
いつ飛出すか不明です。時折、不正コードは、発生しているはずです。
又、7C46 は、第1第2水準以外の、拡張文字コードです。
  (金+帝 の字、※この掲示板は、表示出来ないようです。)
IMEパッドも、アテニ出来ません。
この字を、IMEパッドで拾うと何故か、BSTR$( ORD("金+帝"),16 ) →"1662" になる?不正コードです。
しかし、w$=CHR$( BVAL("7C46",16) ) →BSTR$( ORD(w$),16 ) →"7C46" になりますので、
十進BASIC の方は、正常です。


全角で1文字入力してください:日

日(JIS:467C) -> (JIS:7C46)

  (copy & paste)

全角で1文字入力してください:

(JIS:7C46) -> 日(JIS:467C)
 

Re: 【質問】chr$での文字表示について

 投稿者:Bear  投稿日:2008年 9月 3日(水)21時10分48秒
返信・引用
  > No.5[元記事へ]

ありがとうございます。
IMEパッドもあてにできないんですね、今後は注意するようにします。

>win98SE + ver7.2.7 では、例外が発生せず、以下の様に
>期待どうりになります。
やっぱりそうですか。
自分も前に 98SE + 5.0.8 の組合せで同じ事を試した時は
第1水準、第2水準から外れる文字番地をかすめても特に支障なかったので
これはありなんだと思ってたら今回 Xp + 7.2.7 で例外を回避できませんでした。

猶、例外が出る文字番地を一覧するもの書いてみました。
=ここから=
rem -- 全角文字の始点:8481 (2121) / 終端:38700 (972C) --
rem -- 結果出力は画面表示よりファイルに書き出した方が早いかも --
option arithmetic decimal
option character kanji
do
input prompt "どこから見る?(半角始点=1,全角始点=2)":start
if start=1 or start=2 then
exit do
elseif start=0 then
stop
else
end if
loop
select case start
case is =2
let start=8481
case else
end select
for count=start to 38700 step 1
let hcount$=bstr$(count,16)
let strcount$=str$(count)
when exception in
print chr$(39)+chr$(count)+chr$(39)+" chr$("+strcount$+") <-> JIS ["+hcount$+"]"
use
print chr$(7)+"例外"+str$(extype)+chr$(7)+" chr$("+strcount$+") <-> JIS ["+hcount$+"]"
end when
next count
end
=ここまで=
 

Re: 【質問】chr$での文字表示について

 投稿者:白石 和夫  投稿日:2008年 9月 5日(金)20時59分34秒
返信・引用
  > No.6[元記事へ]

Windows XP (Windows2000) は文字コードがユニコードに変更されています。
シフトJISの文字はユニコードに変換されて表示されます。
シフトJISとJISの対応は,一応,一対一とみなせますが,
ユニコードとJIS(あるいはシフトJIS)との対応は一対一ではありません。
シフトJIS→ユニコード→シフトJISと変換すると元に戻らないことがあります。
十進BASICの場合,ファイル入出力はシフトJISなので,
画面に表示した文字をクリップボード経由で取り出すのでなく,
ファイルに書き出した文字を対象にすれば,問題は起こりにくくなると思います。


100 OPTION CHARACTER KANJI
110 INPUT PROMPT "全角で1文字入力してください:":a$
120 LET b=ORD(a$)
130 LET b$=STR$(b)
140 LET c$=BSTR$(ORD(a$),16)
150 LET d$=right$(c$,2)&left$(c$,2)
160 PRINT
170 PRINT CHR$(BVAL(c$,16))&"(JIS:"&c$&")"&" -> "&CHR$(BVAL(d$,16))&"(JIS:"&d$&")"
180 OPEN #1:NAME "A:TEST.TXT"
190 ERASE #1
200 PRINT #1:CHR$(BVAL(d$,16))
210 CLOSE #1
220 OPEN #2:NAME "A:TEST.TXT"
230 INPUT #2:s$
240 CLOSE #2
250 PRINT BSTR$(ORD(s$),16)
260 END

180行以降を追加しています。
 

Re: 【質問】chr$での文字表示について

 投稿者:白石 和夫  投稿日:2008年 9月 6日(土)10時09分11秒
返信・引用
  > No.6[元記事へ]

JIS文字コードは,第2バイト(下位バイト)が16進で21から7Eの間でのみ定義されています。
なので,文字を順に生成するプログラムは,下位バイトが21から7Eの間になるように記述しなければなりません。


100 OPTION ARITHMETIC DECIMAL
110 OPTION CHARACTER KANJI
120 FOR hi=BVAL("21",16) TO BVAL("73",16)
130    FOR lo=BVAL("21",16) TO BVAL("7E",16)
140       LET count=hi*256+lo
150       LET hcount$=BSTR$(count,16)
160       LET strcount$=STR$(count)
170       WHEN EXCEPTION IN
180          PRINT CHR$(39)&CHR$(count)&CHR$(39)&" chr$("&strcount$&") <-> JIS ["&hcount$&"]"
190       USE
200          PRINT CHR$(7)&"例外"&STR$(EXTYPE)&CHR$(7)&" chr$("&strcount$&") <-> JIS ["&hcount$&"]"
210       END WHEN
220    NEXT lo
230 NEXT hi
240 END
 

Re: 【質問】chr$での文字表示について

 投稿者:Bear  投稿日:2008年 9月 7日(日)22時07分8秒
返信・引用
  白石先生、ありがとうございます。

提示いただいたソース拝見しました、自分でも動かしてみました。
なるほど、こうすればいいんですね。
今後の参考にさせていただき、もっと勉強しようと思います。

>シフトJIS→ユニコード→シフトJISと変換すると元に戻らないことがあります。

文字の割当てがない番地(「・」と表示されるところ)を
WindowsXp上でコピーしてからペースト(クリップボード経由)すると
本来の番地に関係なくJIS 2126番地にされてしまいます。
この現象はWindows98SEでは見られないものでしたが、これで疑問が晴れました。

ありがとうございました。
 

第1掲示板が開けない

 投稿者:島村1243  投稿日:2008年10月 9日(木)10時11分32秒
返信・引用
  第1掲示板を読ませて頂いておりますが、先日からアクセス出来なくなっています。閉止でしょうか、或いは不具合発生対処中でしょうか?  

Re: 第1掲示板が開けない

 投稿者:白石 和夫  投稿日:2008年10月 9日(木)20時18分21秒
返信・引用
  > No.12[元記事へ]

around.ne.jp全体がアクセス不能になっています。
こちらの掲示板は,今回のような事態に備えて開設したものです。
もうしばらく様子を見て,復活しないようであれば,こちらを正の掲示板にしたいと思います。
 

Re: 第1掲示板が開けない

 投稿者:島村1243  投稿日:2008年10月10日(金)10時07分10秒
返信・引用
  > No.13[元記事へ]

白石先生、ご回答有り難うございます。もうしばらく復旧されるか待ってみます。

山中様が最近第1掲示板に掲載されたクウォータニアンのプログラムを見たい(コピー損ねた)
のですが、どうしても第1掲示板が復旧出来なかった場合は第2掲示板への転載はされるでし
ょうか。
 

Re: 第1掲示板が開けない

 投稿者:白石 和夫  投稿日:2008年10月10日(金)16時52分13秒
返信・引用
  > No.14[元記事へ]

掲示板自体が復旧しないかぎり,書き込み内容はアクセス不能です。
 

Re: 第1掲示板が開けない

 投稿者:白石 和夫  投稿日:2008年10月11日(土)09時27分55秒
返信・引用
  > No.15[元記事へ]

http://freebbs.around.ne.jp/
が不通になって3日たちました。
当面,こちらの掲示板をメインに使っていくことにしたいと思います。
旧掲示板の101ページから110ページのログは,旧掲示板が復活しない限り取り出せません。

101ページ以降に書き込まれた方は,再書き込みなど,ご協力をお願いします。
なお,旧掲示板過去ログ 12-100 は,
http://www.geocities.jp/thinking_math_education/log/logs.html
にあります。
 

Re: 第1掲示板が開けない

 投稿者:山中和義  投稿日:2008年10月11日(土)10時56分27秒
返信・引用
  > No.14[元記事へ]

島村1243さんへのお返事です。

> 山中様が最近第1掲示板に掲載されたクウォータニアンのプログラムを見たい(コピー損ねた)
> のですが、どうしても第1掲示板が復旧出来なかった場合は第2掲示板への転載はされるでし
> ょうか。


行列表現による複素数、クォータニオン(四元数)の計算
 http://www.urban.ne.jp/home/kz4ymnk/seminar/basic/mat.lzh

でダウンロードしてください。



また、掲示板で発表したプログラムのメンテナンス(デバッグ、バージョンアップなど)はこちらです。

 http://www.urban.ne.jp/home/kz4ymnk/seminar/basic/

1〜2週間後に掲載しています。リンク集にも掲載されています。
 

Re: 第1掲示板が開けない

 投稿者:島村1243  投稿日:2008年10月11日(土)11時27分14秒
返信・引用
  > No.17[元記事へ]

山中和義さん、有難う御座いました。早速ダウンロード完了致しました。
楽しみに読ませて頂きます。

> 行列表現による複素数、クォータニオン(四元数)の計算
>  http://www.urban.ne.jp/home/kz4ymnk/seminar/basic/mat.lzh
>
> でダウンロードしてください。
>
>
>
> また、掲示板で発表したプログラムのメンテナンス(デバッグ、バージョンアップなど)はこちらです。
>
>  http://www.urban.ne.jp/home/kz4ymnk/seminar/basic/
>
> 1〜2週間後に掲載しています。リンク集にも掲載されています。
 

スピログラフ(幾何学アート)

 投稿者:山中和義  投稿日:2008年10月13日(月)22時35分55秒
返信・引用
  !参考. リンク集より
! 彷徨の神殿 http://stillbe.web.fc2.com/compendium/basic/index.html

FUNCTION GCD(a,b) !最大公約数
   IF b=0 THEN LET GCD=a ELSE LET GCD=GCD(b, MOD(a,b))
END FUNCTION


LET r1=8 !固定円の半径
LET r2=5 !動く円の半径 ※r1*r2>0なら内側、r1*r2<0なら外側
LET r3=4 !点Pの位置(動く円の中心から) ※r3=r2ならサイクロイド、r3≠r2ならトロコイド

IF r1*r2>0 THEN
   LET sz=ABS(r1)+ABS(r3)+1
ELSE
   LET sz=ABS(r1)+ABS(r2)+ABS(r3)+1
END IF
SET WINDOW -sz,sz,-sz,sz !表示領域

DRAW grid !座標
DRAW circle WITH SCALE(r1) !大きな円

LET iter=r2/GCD(r1,r2) !周回数

FOR th=0 TO 360*iter !STEP 0.2 !※疎になるなら調整
   DRAW p WITH ROTATE(r1/r2*RAD(th))*SHIFT(r1-r2,0)*ROTATE(-RAD(th)) !点P
NEXT th


PICTURE p !原点(動く円の中心)を基準に点Pを描く
   DRAW disk WITH SCALE(0.1)*SHIFT(r3,0) !点P
END PICTURE

END
 

Re: スピログラフ(幾何学アート)

 投稿者:山中和義  投稿日:2008年10月14日(火)07時54分28秒
返信・引用  編集済
  > No.19[元記事へ]

作画の様子をアニメーションさせてみました。


FUNCTION GCD(a,b) !最大公約数
   IF b=0 THEN LET GCD=a ELSE LET GCD=GCD(b, MOD(a,b))
END FUNCTION


LET r1=8 !固定円の半径
LET r2=5 !動く円の半径 ※r1*r2>0なら内側、r1*r2<0なら外側
LET r3=4 !点Pの位置(動く円の中心から) ※r3=r2ならサイクロイド、r3≠r2ならトロコイド

!LET r1=8 !固定円の直径 r1:r2=2:1
!LET r2=4
!LET r3=r2

!LET r1=12 !アステロイド 4:1
!LET r2=3
!LET r3=r2

!LET r1=5 !カージオイド 1:1
!LET r2=-5
!LET r3=ABS(r2)

!LET r1=4 !ネフロイド 2:1
!LET r2=-2
!LET r3=ABS(r2)


IF r1*r2>0 THEN
   IF ABS(r1)>ABS(r2) THEN
      LET sz=MAX(ABS(r1),ABS(r1-r2)+ABS(r3))+1
   ELSE
      LET sz=ABS(r1)+ABS(r3)+1
   END IF
ELSE
   LET sz=ABS(r1)+ABS(r2)+ABS(r3)+1
END IF
SET WINDOW -sz,sz,-sz,sz !表示領域

DRAW grid !座標
DRAW circle WITH SCALE(r1) !大きな円

LET iter=r2/GCD(r1,r2) !周回数

SET DRAW MODE NOTXOR

DIM w(4,4) !ローカル座標をワールド座標に変換する
MAT w=SHIFT(r1-r2,0) !1つ前
DRAW p(0) WITH w

FOR th=0 TO 360*iter !STEP 0.2 !※疎になるなら調整
   DRAW p(0) WITH w !1つ前を消す

   MAT w=ROTATE(-r1/r2*RAD(th)) * SHIFT(r1-r2,0)*ROTATE(RAD(th)) !姿勢と位置
   DRAW p(1) WITH w !ワールド座標に、動く円と点Pを描く

   WAIT DELAY 0.02
NEXT th


PICTURE p(f) !ローカル座標の原点を基準に、動く円と点Pを描く
   IF f=1 THEN !描画順を考慮して、先に点Pを描く
      SET DRAW MODE OVERWRITE !描画diskにNOTXORを反映させない
      DRAW disk WITH SCALE(0.2)*SHIFT(r3,0)
      SET DRAW MODE NOTXOR
   END IF
   DRAW circle WITH SCALE(r2) !動く円
   PLOT LINES: 0,0; r3,0
END PICTURE

END
 

画像縮小補正プログラム

 投稿者:荒田浩二  投稿日:2008年10月15日(水)19時32分55秒
返信・引用  編集済
  第2掲示板では画像のアップもできるようなので、試しに画像縮小の補正プログラムを投稿します。
MAT PLOT CELLSで画像を縮小して描画したときに生じるジャギー(ギザギザ)を補正するものです。
縮小により欠損する画素の色情報を周囲の画素と加重平均しました。
補正できる縮小率は次の2通りです。
 1/2,1/3,1/4,...といった 1/n のタイプ。
 2/3,3/4,4/5,...といった (n-1)/n のタイプ。
縮小率を入力すると、まず画面右下に補正なしの画像が描画されます。
ビープ音の後、何かキーを押すと左下に補正した画像が描画されます。
プログラムで読み込んでいる画像は十進BASIC添付ファイルですが、サイズが小さいためか補正の効果をあまり確認できません。
ぜひ、アップした写真をデスクトップにでもコピー&ペーストして試してみてください。
この写真は個人が撮影したもので著作権に問題はありません。

(JPEG形式でUpしたので画質が落ちてますが、DownLoadするとBMP形式で保存されます。)
(掲示されているサイズは400×300、拡大すると元のサイズ800×600になります。どちらのサイズもダウンロードできます)


REM ** 画像縮小補正プログラム **
OPTION ARITHMETIC NATIVE
DECLARE EXTERNAL SUB revision1,revision2
GLOAD "C:\Program Files\Decimal BASIC\BASICw32\SAMPLE\ZENKOUJI.JPG"
LET px0=PIXELX(1)
LET py0=PIXELY(1)
SET WINDOW 0,px0,0,py0
DIM pict0(0 TO px0,0 TO py0)    ! 元画像(配列の下限は0以外も可)
SET COLOR MODE "NATIVE"
ASK PIXEL ARRAY (0,py0) pict0   ! 元画像の色指標
DO
   LET err=0
   INPUT PROMPT "[縮小率入力] 分子,分母 (分子=1 or 分子=分母-1)" : num,denom
   IF num<1 OR INT(num)<>num THEN LET err=1
   IF denom<2 OR INT(denom)<>denom THEN LET err=1
   IF num<>1 AND num<>denom-1 THEN LET err=1
LOOP UNTIL err=0
LET t0=TIME
LET kk=num/denom   ! 縮小率
MAT PLOT CELLS, IN px0-px0*kk,py0*kk ; px0,0 : pict0  !! 補正なし
!
LET px9=INT(SIZE(pict0,1)*kk+0.00001)-1  ! k=1/3,3*k<>1に対応
LET py9=INT(SIZE(pict0,2)*kk+0.00001)-1
DIM pict9(0 TO px9,0 TO py9)    ! 縮小補正画像(配列の下限は0)
IF num=1 THEN
   CALL revision1(pict0,pict9,denom)   ! 縮小率=1/n
ELSE
   CALL revision2(pict0,pict9,denom)   ! 縮小率=(n-1)/n
END IF
IF TIME-t0<0.2 THEN WAIT DELAY 0.2
BEEP
SET TEXT COLOR "RED"
SET TEXT HEIGHT py0/30
PLOT TEXT ,AT 1,1 : "PUSH ANY KEY"
DO
   FOR i=8 TO 239
      IF GetKeyState(i)<0 THEN EXIT DO
   NEXT i
LOOP
MAT PLOT CELLS, IN 0,py9 ; px9,0 : pict9  !! 補正あり
BEEP
END


REM  縮小率=1/n (1/2,1/3,1/4,...)
EXTERNAL SUB revision1(sp0(,),sp9(,),k)
OPTION ARITHMETIC NATIVE
LET kk=1/k
DIM c9(3)
LET lx0=LBOUND(sp0,1)
LET ly0=LBOUND(sp0,2)
LET ux0=UBOUND(sp0,1)
LET uy0=UBOUND(sp0,2)
LET ux9=UBOUND(sp9,1)
LET uy9=UBOUND(sp9,2)
FOR i=lx0 TO ux0-(k-1) STEP k
   FOR j=ly0 TO uy0-(k-1) STEP k
      MAT c9=ZER
      FOR ii=0 TO k-1
         FOR jj=0 TO k-1
            CALL acm(i+ii,j+jj)
         NEXT jj
      NEXT ii
      LET sp9((i-lx0)*kk,(j-ly0)*kk)=COLORINDEX(c9(1)/k^2,c9(2)/k^2,c9(3)/k^2)
   NEXT j
NEXT i
LET rm2=MOD(uy0,k)  ! 縁(横)の処理
IF rm2<>k-1 THEN
   FOR i=lx0 TO ux0-(k-1) STEP k
      MAT c9=ZER
      FOR j=0 TO rm2
         CALL acm(i,uy0-j)
      NEXT j
      LET sp9((i-lx0)*kk,uy9)=COLORINDEX(c9(1)/(rm2+1),c9(2)/(rm2+1),c9(3)/(rm2+1))
   NEXT i
END IF
LET rm1=MOD(ux0,k)  ! 縁(縦)の処理
IF rm1<>k-1 THEN
   FOR j=ly0 TO uy0-(k-1) STEP k
      MAT c9=ZER
      FOR i=0 TO rm1
         CALL acm(ux0-i,j)
      NEXT i
      LET sp9(ux9,(j-ly0)*kk)=COLORINDEX(c9(1)/(rm1+1),c9(2)/(rm1+1),c9(3)/(rm1+1))
   NEXT j
END IF
IF rm1<>k-1 OR rm2<>k-1 THEN  ! 角の処理
   MAT c9=ZER
   FOR i=0 TO rm1
      FOR j=0 TO rm2
         CALL acm(ux0-i,uy0-j)
      NEXT j
   NEXT i
   LET rm12=(rm1+1)*(rm2+1)
   LET sp9(ux9,uy9)=COLORINDEX(c9(1)/rm12,c9(2)/rm12,c9(3)/rm12)
END IF
SUB acm(x0,y0)
   ASK COLOR MIX(sp0(x0,y0)) b,g,r
   LET c9(1)=c9(1)+b
   LET c9(2)=c9(2)+g
   LET c9(3)=c9(3)+r
END SUB
END SUB

REM  縮小率=(n-1)/n (2/3,3/4,4/5,...)
EXTERNAL SUB revision2(sp0(,),sp9(,),k)
OPTION ARITHMETIC NATIVE
DECLARE FUNCTION c_ave
LET kk=(k-1)/k
LET num1=(k-1)-1
LET lx0=LBOUND(sp0,1)
LET ly0=LBOUND(sp0,2)
LET ux0=UBOUND(sp0,1)
LET uy0=UBOUND(sp0,2)
LET ux9=UBOUND(sp9,1)
LET uy9=UBOUND(sp9,2)
FOR i=lx0 TO ux0-k STEP k
   FOR j=ly0 TO uy0-k STEP k
      CALL center
      CALL side1(i,j,1,0)
      CALL side1(i+k,j,-1,num1)
      CALL side2(i,j,1,0)
      CALL side2(i,j+k,-1,num1)
      CALL corner(i,j,1,1,0,0)
      CALL corner(i,j+k,1,-1,0,num1)
      CALL corner(i+k,j,-1,1,num1,0)
      CALL corner(i+k,j+k,-1,-1,num1,num1)
   NEXT j
NEXT i
LET x8=(i-lx0-k)*kk+num1
LET y8=(j-ly0-k)*kk+num1
IF uy9<>y8 THEN CALL edge1
IF ux9<>x8 THEN CALL edge2
IF ux9<>x8 AND uy9<>y8 THEN CALL edge_corner
FUNCTION c_ave(c1,c2)   ! 色強度加重平均
   ASK COLOR MIX(c1) b1,g1,r1
   ASK COLOR MIX(c2) b2,g2,r2
   LET c_ave=COLORINDEX((b1+2*b2)/3,(g1+2*g2)/3,(r1+2*r2)/3)
END FUNCTION
SUB center
   FOR ii=2 TO num1
      FOR jj=2 TO num1
         LET sp9((i-lx0)*kk+ii-1,(j-ly0)*kk+jj-1)=sp0(i+ii,j+jj)
      NEXT jj
   NEXT ii
END SUB
SUB side1(x,y,ii,m)
   FOR jj=2 TO num1
      LET sp9((i-lx0)*kk+m,(j-ly0)*kk+jj-1)=c_ave(sp0(x,y+jj),sp0(x+ii,y+jj))
   NEXT jj
END SUB
SUB side2(x,y,jj,n)
   FOR ii=2 TO num1
      LET sp9((i-lx0)*kk+ii-1,(j-ly0)*kk+n)=c_ave(sp0(x+ii,y),sp0(x+ii,y+jj))
   NEXT ii
END SUB
SUB corner(x,y,ii,jj,m,n)
   ASK COLOR MIX(sp0(x,y)) b1,g1,r1
   ASK COLOR MIX(sp0(x,y+jj)) b2,g2,r2
   ASK COLOR MIX(sp0(x+ii,y)) b3,g3,r3
   ASK COLOR MIX(sp0(x+ii,y+jj)) b4,g4,r4
   LET bb=(b1+2*b2+2*b3+4*b4)/9
   LET gg=(g1+2*g2+2*g3+4*g4)/9
   LET rr=(r1+2*r2+2*r3+4*r4)/9
   LET sp9((i-lx0)*kk+m,(j-ly0)*kk+n)=COLORINDEX(bb,gg,rr)
END SUB
SUB edge1
   FOR i=lx0 TO ux0-k STEP k  ! 下辺の処理
      FOR ii=0 TO num1
         FOR jj=0 TO uy9-y8-2
            LET sp9((i-lx0)*kk+ii,uy9-jj)=sp0(i+ii+1,uy0-jj)
         NEXT jj
         LET sp9((i-lx0)*kk+ii,uy9-jj)=c_ave(sp0(i+ii+1,uy0-(jj+1)),sp0(i+ii+1,uy0-jj))
      NEXT ii
   NEXT i
END SUB
SUB edge2
   FOR j=ly0 TO uy0-k STEP k  ! 右辺の処理
      FOR jj=0 TO num1
         FOR ii=0 TO ux9-x8-2
            LET sp9(ux9-ii,(j-ly0)*kk+jj)=sp0(ux0-ii,j+jj+1)
         NEXT ii
         LET sp9(ux9-ii,(j-ly0)*kk+jj)=c_ave(sp0(ux0-(ii+1),j+jj+1),sp0(ux0-ii,j+jj+1))
      NEXT jj
   NEXT j
END SUB
SUB edge_corner
   FOR ii=ux9 TO x8+1 STEP-1
      FOR jj=uy9 TO y8+1 STEP-1
         LET sp9(ii,jj)=sp0(ux0-(ux9-ii),uy0-(uy9-jj))
      NEXT jj
   NEXT ii
END SUB
END SUB
 

Re: 画像縮小補正プログラム

 投稿者:山中和義  投稿日:2008年10月18日(土)20時06分51秒
返信・引用  編集済
  > No.21[元記事へ]

バイリニア法では、画像を縮小すればエッジ部分が強調される傾向があります。

一般的な縮小率の場合、画像処理アプリケーションでの操作のように
縮小率に応じて平滑化(ぼかす)して、バイリニア法で縮小すればよいかと思います。


別解 ※MAT文を使って処理が速くなりました。


!離散コサイン変換(DCT:Discrete Cosine Transform)による拡大縮小

OPTION ARITHMETIC NATIVE

LET N=8 !ブロックサイズ

FUNCTION phi(k,i,N) !基底関数φk(i)
   IF k=0 THEN
      LET phi=1/SQR(N)
   ELSE
      LET phi=SQR(2/N)*COS((2*i+1)*k*PI/(2*N))
   END IF
END FUNCTION

SUB DCT(f(,),TBL(,),iTBL(,), FF(,)) !DCT変換
   MAT FF=TBL*f
   MAT FF=FF*iTBL !F(k,l)=Σ[j=0,N-1]Σ[i=0,N-1]f(i,j)*φk(i)*φl(j)
END SUB
SUB iDCT(FF(,),TBL(,),iTBL(,), f(,)) !DCT逆変換
   MAT f=iTBL*FF
   MAT f=f*TBL !f(i,j)=Σ[l=0,N-1]Σ[k=0,N-1]F(k,l)*φk(i)*φl(j)
END SUB

DIM TBLn(0 TO N-1,0 TO N-1) !変換行列 T
MAT TBLn=ZER
FOR k=0 TO N-1 !N×Nブロックのφk(i)のテーブルをつくる
   FOR i=0 TO N-1
      LET TBLn(k,i)=phi(k,i,N)
   NEXT i
NEXT k
!!!MAT PRINT TBLn;
DIM iTBLn(N,N) !※T^-1=T^t、∵ユニタリー行列
MAT iTBLn=TRN(TBLn)
!-------------------- ここまでがサブルーチン


SET COLOR MODE "NATIVE"
!GLOAD "c:\BASICw32\SAMPLE\ZENKOUJI.JPG" !画像を読み込む
GLOAD "c:\My Documents\test2.bmp" !画像を読み込む
ASK PIXEL SIZE (0,0; 1,1) w,h !画像の縦横の大きさ(ピクセル単位)を調べる
DIM p(w,h) !画像の大きさに対応する配列要素を用意する
ASK PIXEL ARRAY (0,1) p !画像の各点の色情報を配列に格納する
PRINT "画像の大きさ 縦:";h;" 横:";w
!SET BITMAP SIZE w,h !ウィンドウの大きさを画像に合わせる


LET A=5 !拡大縮小率 A/N
!LET A=11 !拡大縮小率

LET ww=INT(w*A/N+0.5) !変換後の画像の大きさ
LET hh=INT(h*A/N+0.5)
PRINT A;"/";N;"倍(縦横比は固定) 縦:";hh;" 横:";ww
IF ww<=0 OR hh<=0 THEN
   PRINT "画像の大きさが0または負になります。"
   STOP
END IF
DIM q(ww,hh) !変換後の画像を格納する配列


LET t0=TIME


DIM TBLa(0 TO A-1,0 TO A-1)
MAT TBLa=ZER
FOR k=0 TO A-1 !A×Aブロックのφk(i)のテーブルをつくる
   FOR i=0 TO A-1
      LET TBLa(k,i)=phi(k,i,A)
   NEXT i
NEXT k
DIM iTBLa(0 TO A-1,0 TO A-1)
MAT iTBLa=TRN(TBLa)

FOR by=0 TO INT((h-1)/N) !ブロック単位に分割する
   FOR bx=0 TO INT((w-1)/N)

      FOR j=1 TO N !ブロック内の画像
         LET y=by*N+j
         IF y>h THEN EXIT FOR !下端なら
         FOR i=1 TO N
            LET x=bx*N+i
            IF x>w THEN EXIT FOR !右端なら
            !!!PRINT x;y,i;j

            LET c=p(x,y)
            ASK COLOR MIX(c) r,g,b !RGBを取得する

            DIM Br(N,N),Bg(N,N),Bb(N,N) !画素の色濃度 ※画像信号 f(i,j)
            LET Br(i,j)=r
            LET Bg(i,j)=g
            LET Bb(i,j)=b
         NEXT i
      NEXT j

      DIM BVr(N,N),BVg(N,N),BVb(N,N) !DCT係数 F(k,l)
      CALL DCT(Br,TBLn,iTBLn, BVr)
      CALL DCT(Bg,TBLn,iTBLn, BVg)
      CALL DCT(Bb,TBLn,iTBLn, BVb)

      !※縮小なら高周波成分の行と列を除く、拡大なら不足部分は0を補う
      DIM Tr(A,A),Tg(A,A),Tb(A,A)
      IF A>N THEN !拡大なら
         MAT Tr=ZER(A,A)
         MAT Tg=ZER(A,A)
         MAT Tb=ZER(A,A)
      END IF
      FOR j=1 TO MIN(N,A) !copy it
         FOR i=1 TO MIN(N,A)
            LET Tr(i,j)=BVr(i,j)
            LET Tg(i,j)=BVg(i,j)
            LET Tb(i,j)=BVb(i,j)
         NEXT i
      NEXT j

      DIM iBr(A,A),iBg(A,A),iBb(A,A) !画素の色濃度 ※画像信号 f(i,j)
      CALL iDCT(Tr,TBLa,iTBLa, iBr)
      CALL iDCT(Tg,TBLa,iTBLa, iBg)
      CALL iDCT(Tb,TBLa,iTBLa, iBb)

      FOR j=1 TO A !画像に割当てる
         LET yy=by*A+j
         IF yy>hh THEN EXIT FOR !下端なら
         FOR i=1 TO A
            LET xx=bx*A+i
            IF xx>ww THEN EXIT FOR !右端なら

            LET r=MIN(iBr(i,j)*A/N,1) !輝度調整
            LET g=MIN(iBg(i,j)*A/N,1)
            LET b=MIN(iBb(i,j)*A/N,1)

            LET q(xx,yy)=colorindex(r,g,b) !指定位置の画素に書き込む
         NEXT i
      NEXT j

   NEXT bx
NEXT by


SET BITMAP SIZE ww,hh !ウィンドウの大きさを画像に合わせる
MAT PLOT CELLS, IN 0,1; 1,0 :q !画像を表示する


PRINT
PRINT "計算時間=";TIME-t0

END
 

質問

 投稿者:ゆう  投稿日:2008年10月19日(日)09時43分19秒
返信・引用
  グラフを描いています。
2つの関数f(x)とg(x)によって囲まれた図形を塗りつぶしたいのですが、どうやってやったら出来ますか?回答お願いします。
 

Re: 質問

 投稿者:山中和義  投稿日:2008年10月19日(日)11時51分12秒
返信・引用  編集済
  > No.23[元記事へ]

ゆうさんへのお返事です。


!連立不等式f(x)>0、g(x,y)<0の領域

DEF f(x)=x^2-3*x-1 !関数の定義 y=f(x)
DEF g(x,y)=5*x^2-6*x*y+5*y^2-25 !関数の定義 f(x,y)=0

LET a=-5 !x=[a,b] ※xy座標の表示領域
LET b=5
LET c=a !y=[c,d]
LET d=b


SET WINDOW a,b,c,d !表示領域を設定する
DRAW grid(1,1) !座標を描く
ASK PIXEL SIZE (a,c; b,d) w,h !画像の縦横の大きさ(ドット単位)を調べる
PRINT w;h

LET cEps=(b-a)/(w-1) !座標間隔
PRINT cEps

DEF ha(f)=MOD(f,cEps*10) !評価関数
SUB hatch(t, x,y,c) !ハッチ形状なら点(x,y)を描く
   LET flg=0
   IF (t=1 OR t=5) AND ha(y)<cEps THEN LET flg=1 !横
   IF (t=2 OR t=5) AND ha(x)<cEps THEN LET flg=1 !縦
   IF (t=3 OR t=6) AND ha(x+y)<cEps THEN LET flg=1 !左斜め
   IF (t=4 OR t=6) AND ha(x-y)<cEps THEN LET flg=1 !右斜め
   IF t=0 OR flg=1 THEN !t=0はベタ塗り
      SET POINT COLOR c
      PLOT POINTS: x,y
   END IF
END SUB


!条件を満たす領域を描く
SET POINT STYLE 1 !ドット形式
FOR j=1 TO h !画面全体を走査する
   LET y=WORLDY(j) !ドットをxy座標に変換する
   FOR i=1 TO w
      LET x=WORLDX(i)

      WHEN EXCEPTION IN
      !不等式が示す領域 ※y>f(x)はf(x)>0、y<f(x)はf(x)<0を意味する
         IF y>f(x) THEN CALL hatch(4, x,y,4) !条件を満たすなら
         IF g(x,y)<0 THEN CALL hatch(3, x,y,2)

         !連立不等式が示す領域
         !IF y>f(x) AND g(x,y)<0 THEN CALL hatch(5, x,y,2) !条件を満たすなら
      USE
      END WHEN

   NEXT i
NEXT j



!曲線を描く ※y=f(x)
FOR x=a TO b STEP cEps
   WHEN EXCEPTION IN
      PLOT LINES: x,f(x); !折れ線で近似する
   USE
      PLOT LINES
   END WHEN
NEXT x
PLOT LINES
PLOT TEXT ,AT -2,4: "f(x)"


!曲線を描く ※連続なf(x,y)=0
SET POINT COLOR 1
FOR y=c TO d STEP cEps
   LET x=a
   LET z=g(x,y)
   FOR x=a TO b STEP cEps
      LET z0=z
      LET z=g(x,y)
      IF z0*z<0 THEN  PLOT POINTS: x,y !符号が変われば
   NEXT x
NEXT y
PLOT TEXT ,AT -3,-3: "g(x)"


END
 

(無題)

 投稿者:だい  投稿日:2008年10月21日(火)13時50分23秒
返信・引用
  十進basicをダウンロードしたいんですが、どうしたらいいか教えてください。  

Re: (無題)

 投稿者:白石 和夫  投稿日:2008年10月21日(火)17時56分20秒
返信・引用
  > No.25[元記事へ]

だいさんへのお返事です。

> 十進basicをダウンロードしたいんですが、どうしたらいいか教えてください。

この頁の一番下のほうにある「十進BASICのホームページ」へのリンクをクリックし,
十進BASICのホームページでOS別に用意されたダウンロードの頁に進んでください。
 

Re: 画像縮小補正プログラム

 投稿者:荒田浩二  投稿日:2008年10月26日(日)12時08分13秒
返信・引用
  > No.22[元記事へ]

山中和義さんへのお返事です。

アドバイスありがとうございます。
画像処理に対しての知識もなく思いつきで作ったプログラムです。
離散コサイン変換なる用語も初めて目にするもので、ネット等で自分なりに調べましたが残念ながら硬くなった頭では原理を理解するまではいたりませんでした。

画像関係ではないですが、いくつか投稿しようかと思案しているものがあります。
またアドバイスお願いします。
 

不等号をタグと誤認識

 投稿者:荒田浩二  投稿日:2008年10月27日(月)08時31分49秒
返信・引用  編集済
  第2掲示板ではHTMLタグを使えますが、不等号をタグと誤認識することがあるようなので報告します。
「右開き不等号(<)+タグ用語+空白」でタグと認識し、次の左開き不等号(>)までの間にある文字が表示されません。
(元の文として表示しているのは不等号を全角にしています。)
投稿する際は、変数名をタグ用語と変えるか、j<p+0 の様にして不等号に続く変数の後ろを空白にしない、または不等号の向きを変えるといった工夫が必要になります。
参考までに1文字のタグは、a,b,i,p,q,s,u。h1〜h6も見出しと認識されます。(訂正;掲示板内では見出しタグは使えないようです)

この問題の原因はレンタル掲示板にあるのでどうしようもないですよね?



例1 : フォント(font)
10 IF ac THEN LET font=1

元1 :
10 IF a<font AND b>c THEN LET font=1


例2 : 改行(br)
20 IF x
z THEN LET br=2

元2 :
20 IF x<br OR y>z THEN LET br=2


例3 : ハイパーリンク(a)
30 IF di THEN LET h=5

元3 :
30 IF d<a THEN LET d=3
40 LET e=e+1
50 IF f<g THEN LET f=4
60 IF h>i THEN LET h=5


例4 : 段落(p)
70 IF j

l THEN LET j=6

元4 :
70 IF j<p OR k>l THEN LET j=6


例5 : ボールド体(b)
80 IF mo THEN LET m=7

元5 :
80 IF m<b AND n>o THEN LET m=7


問題なし :
10 a<fontx AND b>c THEN LET fontx=1
70 IF j<p+0 OR k>l THEN LET j=6
80 IF b>m AND n>o THEN LET m=7


(<b で太字になってしまったので</b>
と記述されるまで直りません。)

 

Re: 不等号をタグと誤認識

 投稿者:山中和義  投稿日:2008年10月27日(月)12時59分39秒
返信・引用  編集済
  > No.28[元記事へ]

気になる特殊文字の書き込み試験です。

PRINT "&LT;"
PRINT "&lt;"
PRINT "123"&lt$
PRINT "123"&ltuvw$
IF a<font AND b>c THEN LET font=1

と記述したプログラムを投稿したとする。



PRINT "<"
PRINT "<"
PRINT "123"<$
PRINT "123"&ltuvw$
IF ac THEN LET font=1



PREタグを指定してみる
PRINT "<"
PRINT "<"
PRINT "123"<$
PRINT "123"&ltuvw$
IF ac THEN LET font=1


ということは、<と&を&lt;,&amp;に変換しておけばいいのでしょうか!?
 

Re: 不等号をタグと誤認識

 投稿者:白石 和夫  投稿日:2008年10月28日(火)08時04分13秒
返信・引用  編集済
  > No.29[元記事へ]

十進BASIC FAQ 掲示板の使い方に & ,< の置換手順を追加しました。
なお,ほかにお気づきの点があればお知らせください。
 

モンテカルロ法による数値積分

 投稿者:山中和義  投稿日:2008年10月28日(火)11時14分32秒
返信・引用  編集済
  !モンテカルロ法(Monte Carlo Method)による数値積分

DEF f(x)=1/(1+x) !被積分関数

!●入門的モンテカルロ法
! ∫[0,1]f(x)dx=Σ[i=1,N]f(i/N)/N=1/N*Σ[i=1,N]f(xi)
!
! x=[a,b]範囲で一様乱数で点(x,y)をN個発生させると
! ∫[a,b]f(x)dx=(b-a)/N*Σ[i=1,N]f(xi)

LET N=500000 !乱数の発生個数

LET a=0
LET b=1

LET ba=b-a
LET h=0
FOR i=1 TO N
   LET x=RND*ba+a !N個の一様乱数
   LET h=h+f(x) !Σf
NEXT i
LET S=h*ba/N

PRINT S, LOG(2)



!●「あたりはずれ」のモンテカルロ法
! x=[a,b]、y=[0,c]、0<f(x)<cの範囲で
! 一様乱数で点(x,y)をN個発生させて、y<f(x)の数をnとすると
! ∫[a,b]f(x)dx=c*(b-a)*n/N

LET N=500000 !乱数の発生個数

LET a=0
LET b=1
LET c=1

LET ba=b-a
LET hit=0
FOR i=1 TO N
   LET x=RND*ba+a !N個の一様乱数
   LET y=RND*c
   IF y<f(x) THEN LET hit=hit+1 !fより下の領域
NEXT i
LET S=c*ba * hit/N !長方形との面積比

PRINT S, LOG(2)


END
 

< & の直後には、半角スペースを必ず置く。

 投稿者:SECOND  投稿日:2008年10月28日(火)13時02分40秒
返信・引用  編集済
  1)<の直後には、半角スペースを置く。( 不等号<>は、そのままで良いようです。)
2)&の直後には、半角スペースを置く。

の様にすると、
タグと、文字参照、のシーケンスが止められます。掲示用のリストで「実行」も兼用。

スペース挿入効果の試験です。

PRINT "& LT;"
PRINT "& lt;"
PRINT "123"& lt$
PRINT "123"& ltuvw$
IF a< font AND b>c THEN LET font=1
IF a<>b THEN LET font=2

と記述したプログラムを投稿したとする。

PRINT "& LT;"
PRINT "& lt;"
PRINT "123"& lt$
PRINT "123"& ltuvw$
IF a< font AND b>c THEN LET font=1
IF a<>b THEN LET font=2

文字参照 の試験を、もう少し追加。(右側は、スペース無しの同文)

print "& #34; & quot;"    ! print "" ""
print "& #38; & amp;"     ! print "& &"
print "& #60; & lt;"      ! print "< <"
print "& #62; & gt;"      ! print "> >"
print "& #160; & nbsp;"   ! print "   "
print "& #161; & iexcl;"  ! print "クA憎クA蔵
print "& #162; & cent;"   ! print "¢ ¢"
print "& #163; & pound;"  ! print "£ £"
print "& #164; & curren;" ! print "クA陞クA陟
print "& #165; & yen;"    ! print "\ \"
print "& #166; & brvbar;" ! print "�� ��"
print "& #167; & sect;"   ! print "§ §"
print "& #168; & uml;"    ! print "¨ ¨"
print "& #169; & copy;"   ! print "クA迸クA蹉

--------------------------------------------------
&& の試験。

LET copy$="&& を使用して1行に"

PRINT "1行に書き切れなくて、改行してしまったが、"&
&クA蹐 & "つないで、この行を、改行していない1行の文字列にした。"

PRINT "1行に書き切れなくて、改行してしまったが、"&
&& copy$ & "つないで、この行を、改行していない1行の文字列にした。"
  ↑
このスペースが無い場合(上)と、有る場合(下)。

--------------------------------------------------
<の試験 を追加。(半角スペース後付けの出来ないケース)

IF X <= 10 THEN PRINT USING "<###" : 123
IF X <> 10 THEN PRINT USING "<%%%" : 123
IF X<=10 THEN PRINT USING "<###":123
IF X<>10 THEN PRINT USING "<%%%":123
PRINT USING "#<" : w10, w1
PRINT USING "#<":w10, w1

 と書いたとする。

IF X <= 10 THEN PRINT USING "<###" : 123
IF X <> 10 THEN PRINT USING "<%%%" : 123
IF X<=10 THEN PRINT USING "<###":123
IF X<>10 THEN PRINT USING "<%%%":123
PRINT USING "#<" : w10, w1
PRINT USING "#<":w10, w1
 

世界のナベアツにBASICで挑戦! おもろ〜

 投稿者:山中和義  投稿日:2008年10月29日(水)11時14分24秒
返信・引用  編集済
  以前、プログラミングの練習に「3の倍数」と「3の付く数」の判定方法を検討してみました。
今回は、数を多項式やベクトルや行列で表現して、その演算で判定してみます。


!自然数nの各位の値が係数となる多項式p(x)=k1+k2*x+k3*x^2+ …で表す。
!21の場合
! p(x)=1+2*x+0*x^2+0*x^3+ …
!元のnに戻すには、x=10として関数値を計算すればよい。
! p(10)=1*1+2*10+0*100+0*1000+ … =21

DEF p(x)=k1+k2*x+k3*x^2+k4*x^3 !多項式

FOR k2=0 TO 9 !十の位
   FOR k1=0 TO 9 !一の位

      IF MOD(p(1),3)=0 THEN !各桁の和が3の倍数なら
         PRINT p(10) !x=k1+k2*10+k3*100+ …
      ELSEIF k1=3 OR k2=3 THEN !いずれかが3となる
         PRINT p(10) !x=k1+k2*10+k3*100+ …
      END IF

   NEXT k1
NEXT k2





!自然数nの各位の値が成分となるベクトルで表す。
!21の場合
! (1 2)
!元のnに戻すには、10のべき乗を成分とするベクトルと内積をとればよい。
! (1 2)・(1 10)=1*1+2*10=21

LET K=4 !桁数

DIM CC(K) !定数 (1 1 1 …)
MAT CC=CON
DIM BB(K) !定数 (1 10 100 …)
FOR i=1 TO K
   LET BB(i)=10^(i-1) !位
NEXT i
DIM V(K) !ベクトル
FOR k2=0 TO 9 !十の位
   LET V(2)=k2
   FOR k1=0 TO 9 !一の位
      LET V(1)=k1

      IF MOD(DOT(V,CC),3)=0 THEN !各桁の和が3の倍数なら
         PRINT DOT(V,BB) !x=k1+k2*10+k3*100+ …
      ELSEIF V(1)=3 OR V(2)=3 THEN !いずれかが3となる
         PRINT DOT(V,BB) !x=k1+k2*10+k3*100+ …
      END IF

   NEXT k1
NEXT k2





!自然数nの各位の値が要素となる対角行列で表す。
!21の場合
! ┌ 1 0 ┐
! └ 0 2 ┘
!元のnに戻すには、10のべき乗を要素とする行列をかければよい。
! ┌ 1 0 ┐┌ 1 ┐
! └ 0 2 ┘└ 10 ┘
! =┌ 1 ┐
!  └ 20 ┘
!さらに、すべての要素が1の行列をかければよい。
! [1 1]┌ 1 ┐=[21]
!    └ 20 ┘

FUNCTION tr(A(,)) !行列Aのトレース
   LET t=0 !対角成分の和
   FOR m=1 TO MIN(UBOUND(A,1),UBOUND(A,2))
      LET t=t+A(m,m)
   NEXT m
   LET tr=t
END FUNCTION


LET K=4 !桁数

DIM B(K,1) !定数 t[1 10 100 …]
FOR i=1 TO K
   LET B(i,1)=10^(i-1) !位
NEXT i

DIM C(1,K) !定数 [1 1 1 …]
MAT C=CON

DIM TT(K,1),X(1,1) !作業用

DIM A(K,K) !対角行列
MAT A=ZER
FOR k2=0 TO 9 !十の位
   LET A(2,2)=k2
   FOR k1=0 TO 9 !一の位
      LET A(1,1)=k1

      IF MOD(tr(A),3)=0 THEN !各桁の和が3の倍数なら
         MAT TT=A*B !x=k1+k2*10+k3*100+ …
         MAT X=C*TT
         MAT PRINT X; !PRINT X(1,1)
      ELSEIF A(1,1)=3 OR A(2,2)=3 THEN !いずれかが3となる
         MAT TT=A*B !x=k1+k2*10+k3*100+ …
         MAT X=C*TT
         MAT PRINT X;
      END IF

   NEXT k1
NEXT k2


END
 

旧掲示板の投稿をキャッシュからサルベージ

 投稿者:荒田浩二  投稿日:2008年10月30日(木)08時04分4秒
返信・引用
  十進BASICの旧掲示板が10月上旬から運営会社aroundの活動停止により事実上閉鎖されました。
「掲示板過去ログ」に保管されていなかった101〜110ページの投稿を検索サイトのキャッシュから拾い出す方法を紹介します。
ただしキャッシュですから、すべてのページが保存されているわけではありません。
分割して投稿されたプログラムなどは、部分的にしか拾えないかもしれません。
また、キャッシュは日々更新されますのであと1,2ヶ月もしたらほとんどのページが削除されると思います。
数日前と比較してもヒット数が減っています。
必要な投稿は早めにパソコンに保存しておくことをお勧めします。


1.検索サイトGoogleで "十進BASIC掲示板" を検索します。
  (余計な情報を排除するためダブルクォテーション(")で囲みましょう)

2.検索結果の最後に、
    最も的確な結果を表示するために、上の○○件と似たページは除外されています。
    検索結果をすべて表示するには、ここから再検索してください。

  とあるのでクリックして下さい。

3.検索結果のうち、URLが freebbs.around.ne.jp で始まるものが旧掲示板の投稿です。
  /basic/ または &pg= の後ろにある数字が旧掲示板のページ番号です。
  (URLが www.geocities.jp とあるのは「掲示板過去ログ」にあるのでそちらをご覧ください)

4.内容を見るには必ずキャッシュをクリックして下さい。
  (見出しをクリックすると接続エラーになります)

5.下の語句からも検索できます。他の検索サイトからも検索してみて下さい。
    "freebbs.around.ne.jp/article/b/basic/"

    "freebbs.around.ne.jp/kyview","basic"
 

Re: 旧掲示板の投稿をキャッシュからサルベージ

 投稿者:SECOND  投稿日:2008年10月31日(金)18時20分1秒
返信・引用
  > No.34[元記事へ]

目次だけで、直接に中味は見れませんが、個別検索のキーワードに。

Page : 101~110 全ページ(ツリー表示)のキャッシュが、ありました。
Live Search で、下のキーワード

"初心者歓迎! 十進BASIC掲示板" "Page : 110"
  (
   )
"初心者歓迎! 十進BASIC掲示板" "Page : 101"

(すでに消去されている場合、保存してありますので御要望があればココに掲示します。)
 

Re: 旧掲示板の投稿をキャッシュからサルベージ

 投稿者:白石 和夫  投稿日:2008年10月31日(金)18時36分7秒
返信・引用
  > No.35[元記事へ]

メール等でデータをいただければ,十進BASIC過去ログの頁に掲載します。
 

プログラムのお願い

 投稿者:GAI  投稿日:2008年11月 1日(土)10時51分27秒
返信・引用
  オイラー方陣が6次では構成不可能であることを、しらみつぶしにより
確認することをやってみたいのです。
どなたか十進BASICにてプログラムを組んでいただけないでしょうか?
オイラー方陣とは5次なら(2次と6次以外は構成可能と証明されている。)
12 23 34 45 51
53 14 25 31 42
44 55 11 22 33
35 41 52 13 24
21 32 43 54 15
のように、十位と一位にくる数(1〜5)が
各行、各列に重複することが起きない。
(ただし25個の数字は全て異なるものとする。)
自分でやっていて、なかなか進展しないものですのでよろしくお願いします。
 

Re: プログラムのお願い

 投稿者:白石 和夫  投稿日:2008年11月 1日(土)20時58分48秒
返信・引用
  > No.37[元記事へ]

1〜6の数字で作られる2桁の数は全部で36個あります。
なので,これら36個の数の順列すべてについて条件を満たすかどうか調べればよいはずです。
ただし,
36!=371993326789901217467999448150835200000000 ≒3.7E41
なので,1秒に1万件テストしたとしても3.7E37秒≒1.12E30年かかります。
 

Re: プログラムのお願い

 投稿者:GAI  投稿日:2008年11月 1日(土)22時13分32秒
返信・引用
  > No.38[元記事へ]

白石 和夫さんへのお返事です。
/* 6次のオイラー方陣が存在しないことを確認する. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N 6

char lb[9408][N][N];
/* N=1〜7: 1,1,1,4,56,9408,16942080 N=7は非現実的 */

int lbs;
char wb[N][N];
int p, q;
char xidx[N], yidx[N];

void check1(int n);

void makelb(int x, int y)
{
int i, j;

for(i = 0; i < N; ++i){
for(j = 0; j < x; ++j)
if((char)i == wb[y][j])
break;
if(j >= x){
for(j = 0; j < y; ++j)
if((char)i == wb[j][x])
break;
if(j >= y){
wb[y][x] = (char)i;
if(y == N - 1 && x == N - 1){
memcpy(lb[lbs++], wb, sizeof(wb));
return;
}
if(y == N - 1)
makelb(x + 1, 1);
else
makelb(x, y + 1);
}
}
}
}

void echk(void)
{
static char fb[N][N];
int i, j;

memset(fb, 0, sizeof(fb));
for(i = 0; i < N; ++i)
for(j = 0; j < N; ++j){
if(fb[lb[p][i][j]][lb[q][yidx[i]][xidx[j]]])
return;
fb[lb[p][i][j]][lb[q][yidx[i]][xidx[j]]] = 1;
}
for(i = 0; i < N; ++i)
for(j = 0; j < N; ++j)
printf("%c%c%c", lb[p][i][j] + '0', lb[q][yidx[i]][xidx[j]] + '0',
j == N - 1 ? '\n' : ' ');
exit(0);
}

void check2(int n)
{
int i;
char c;

for(i = n; i < N; ++i){
c = yidx[i];
yidx[i] = yidx[n];
yidx[n] = c;
if(yidx[n] != xidx[n] && (n != 1 || yidx[n] < xidx[n]))
if(n == N - 1)
echk();
else
check1(n + 1);
c = yidx[i];
yidx[i] = yidx[n];
yidx[n] = c;
}
}

void check1(int n)
{
int i;
char c;

for(i = n; i < N; ++i){
c = xidx[i];
xidx[i] = xidx[n];
xidx[n] = c;
check2(n);
c = xidx[i];
xidx[i] = xidx[n];
xidx[n] = c;
}
}

int main(void)
{
int i, count;

for(i = 0; i < N; ++i)
wb[0][i] = wb[i][0] = (char)i;
lbs = 0;
makelb(1, 1);

count = 0;
for(p = 0; p < lbs; ++p)
for(q = p; q < lbs; ++q){
if(++count % 1000 == 0)
printf("%d\r", count);
for(i = 0; i < N; ++i)
xidx[i] = yidx[i] = (char)i;
check1(1);
}
printf("解は見つかりませんでした.\n");
return 0;
}
がc言語でのプログラムでの解決法(5時間ほどでOK!)です。
これをBASICで書き直せないでしょうか。(自分はC言語に不勉強なので)
 

Re: プログラムのお願い

 投稿者:山中和義  投稿日:2008年11月 2日(日)08時22分9秒
返信・引用
  > No.38[元記事へ]

総当りの王道としてバックトラック法があります。
ただし、不適以降は無視(枝刈り)するので検証する場合の数がいくらか減ります。

う〜ん、現実的ではない!
掲載されたC言語のように標準形のラテン方陣からのアプローチを検討してほしい。


LET N=5 !大きさ N×N

PUBLIC NUMERIC ANSWER_COUNT !解答数
LET ANSWER_COUNT=0

PUBLIC STRING num$
LET num$="0123456789ABCDEF" !N進法の数字

DIM M(0 TO N-1,0 TO N-1) !平方の方陣
MAT M=(-1)*CON

SET WINDOW -1,N+1,N+1,-1
DRAW grid

LET t0=TIME
CALL BackTrack(N,M,0) !左上から
PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB BackTrack(N,M(,),p) !(左上からの連番)位置pを調査する
IF p<N*N THEN !すべてが埋まるまで
   LET row=INT(p/N) !行と列に換算する
   LET col=MOD(p,N)

   FOR k=0 TO N*N-1 !0〜N*N-1範囲の数字を
      CALL CheckRule(N,M, row,col,k, rc)!矛盾なく置ければ
      IF rc=1 THEN
         SET TEXT COLOR 1
         PLOT TEXT ,AT col+0.5,row+0.5: STR$(k)

         LET M(row,col)=k !ここに置いてみる
         CALL BackTrack(N,M,p+1) !次へ
         LET M(row,col)=-1 !取り消す

         SET TEXT COLOR 0
         PLOT TEXT ,AT col+0.5,row+0.5: STR$(k)
      END IF
   NEXT k

ELSE !すべて埋まったら
   LET ANSWER_COUNT=ANSWER_COUNT+1 !解答数
   PRINT ANSWER_COUNT

   FOR i=0 TO N-1
      FOR j=0 TO N-1
         LET t=M(i,j)
         LET k1=MOD(t,N)+2 !N進法での各桁の値(文字位置を加味)
         LET k2=INT(t/N)+2
         PRINT num$(k2:k2); num$(k1:k1); " "; !解を表示する
      NEXT j
      PRINT
   NEXT i
   PRINT

END IF
END SUB


EXTERNAL SUB CheckRule(N,M(,), row,col,K, rc) !同じ数があるかどうか確認する
LET rc=0

FOR y=0 TO N-1 !埋まっている範囲で未使用の数字か
   FOR x=0 TO N-1
      IF y>=row AND x>=col THEN EXIT FOR
      IF M(y,x)=K THEN EXIT SUB !見つかったので、NG!
   NEXT x
NEXT y

LET k1=MOD(K,N) !N進法での1桁目
LET k2=INT(K/N) !N進法での2桁目
FOR y=0 TO row-1 !列
   LET t=M(y,col)
   IF MOD(t,N)=k1 THEN EXIT SUB
   IF INT(t/N)=k2 THEN EXIT SUB
NEXT y

FOR x=0 TO col-1 !行
   LET t=M(row,x)
   IF MOD(t,N)=k1 THEN EXIT SUB
   IF INT(t/N)=k2 THEN EXIT SUB
NEXT x

LET rc=1 !見つからないので、OK!
END SUB
 

Re: プログラムのお願い

 投稿者:GAI  投稿日:2008年11月 2日(日)13時12分5秒
返信・引用
  > No.40[元記事へ]

山中和義さんへのお返事です。

まさにこんなことができるプログラムを構成したかったのです。
自分だけであくせく路頭に迷うより、誰かに尋ねると世の中
才能ある人が必ずいるもので、こちらが1ヶ月かかってもできない
ことでも、1時間もあれば見通せる人がいるなんて感動です。
プログラムをコピーさせてもらい、中身の仕組みを分析していきます。
どうも自分はコンピューターに使われている感覚ですが、
山中さんのような人はまさにコンピューターをこき使っている雰囲気です。
私も、コンピューターを思いのまま動かすことが出来るプログラム構成の
力を向上できるよう精進していきたいです。
山中さんは趣味でやられてきたのですか?
それともお仕事で必要でマスターされてきたのですか?
できたらコンピューター歴をお聞かせください。
 

Re: プログラムのお願い

 投稿者:山中和義  投稿日:2008年11月 2日(日)20時25分34秒
返信・引用  編集済
  > No.41[元記事へ]

GAIさんへのお返事です。

仕事と趣味でコンピュータは扱っています。
このBASICは高校数学、工業を題材にプログラミングを楽しんでいます。


●掲載のC言語プログラムの説明
ラテン方陣からのアプローチ
作業手順
Step1. 標準形ラテン方陣を求める。
 例. 3×3の場合
  1 2 3
  2 3 1
  3 1 2
Step2. 2つのラテン方陣の組合せる。
 標準形ラテン方陣から対称、回転を含んですべてのラテン方陣を求める。
 オイラー方陣が成立するものを採用する。
 例. 3×3の場合
  1 2 3  3 1 2  13 21 32
  2 3 1  2 3 1  22 33 11
  3 1 2  1 2 3  31 12 23
 オイラー方陣が成立するので、採用。

たとえば、3×3の場合は標準形が1通り、その展開が12通りあるから
1H2×12通りを検証する必要がある。

 N=1、1=1!×0!×1
 N=2、2=2!×1!×1
 N=3、12=3!×2!×1
 N=4、576=4!×3!×4
 N=5、161,280=5!×4!×56
 N=6、812,851,200=6!×5!×9,408
 N=7、6,147,941,990,400=7!×6!×16,942,080

 ※標準形ラテン方陣(1行目と1列目が整列しているもの)は
  N=1,2,3,4,5,6,7,…なら、1,1,1,4,56,9408,16942080,…となる。

方陣が大きくなればそれに伴い増大して容量、計算量が増える。


インタプリタ系言語BASICで処理を考えると、
容量の問題から掲載されたC言語の手順のように組合せごとに標準形ラテン方陣を展開したい。
でも、検証する「場合の数」が多いため、処理時間の問題から、ラテン方陣をそのまま記録したい。

これは悩ましい問題である。



!(標準形)ラテン方陣を求める

LET N=5 !大きさ N×N

PUBLIC NUMERIC CntOfLM !その数
LET CntOfLM=0

PUBLIC STRING num$
LET num$="0123456789ABCDEF" !N進法の数字

DIM M(0 TO N*N-1) !平方の方陣
MAT M=(-1)*CON

FOR i=0 TO N-1 !標準形の場合 ※1行目と1列目が整列している
   LET M(i*N+0)=i
   LET M(0*N+i)=i
NEXT i

LET t0=TIME
CALL BackTrack(N,M,0) !左上から
PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB BackTrack(N,M(),p) !(左上からの連番)位置pを調査する
IF p<N*N THEN !すべてが埋まるまで
   IF M(p)>=0 THEN !既に置いてあれば
      CALL BackTrack(N,M,p+1) !次へ
   ELSE
      FOR k=0 TO N-1 !数字0〜N-1を
         CALL CheckRule(N,M, p,k, rc)!矛盾なく置ければ
         IF rc=1 THEN
            LET M(p)=k !ここに置いてみる
            CALL BackTrack(N,M,p+1) !次へ
            LET M(p)=-1 !取り消す
         END IF
      NEXT k
   END IF

ELSE !すべて埋まったら
   LET CntOfLM=CntOfLM+1 !解答数
   PRINT CntOfLM

   FOR i=0 TO N-1
      FOR j=0 TO N-1
         LET t=M(i*N+j)+1
         PRINT num$(t+1:t+1); " "; !解を表示する
      NEXT j
      PRINT
   NEXT i
   PRINT

END IF
END SUB


EXTERNAL SUB CheckRule(N,M(), p,K, rc) !同じ数があるかどうか確認する
LET rc=0

LET row=INT(p/N) !行と列に換算する
LET col=MOD(p,N)

FOR i=0 TO row-1 !列
   IF M(i*N+col)=K THEN EXIT SUB
NEXT i

FOR i=0 TO col-1 !行
   IF M(row*N+i)=K THEN EXIT SUB
NEXT i

LET rc=1 !見つからないので、OK!
END SUB
 

山中さんへお礼と感想

 投稿者:GAI  投稿日:2008年11月 2日(日)23時33分46秒
返信・引用
  再度の掲載ありがとうございます。
例の数字:1,1,1,4,56,9408・・・とはどうやって決まっているんだろう?
なにか公式でもあるのかしら、と疑問に思っていましたがつまりこれは実際に構成
したときに、この数しか作れないというものなのですね。
これは計算から求まる値ではないですよね。
このプログラムではっきりとその数の意味するものを理解できました。
 N=1、1=1!×0!×1
 N=2、2=2!×1!×1
 N=3、12=3!×2!×1
 N=4、576=4!×3!×4
 N=5、161,280=5!×4!×56
 N=6、812,851,200=6!×5!×9,408
 N=7、6,147,941,990,400=7!×6!×16,942,080
の計算からN=6では8億以上の組み合わせを調査せねばならないということに
なるわけですか?
本によると、6次のオイラー方陣が不可能であることを理論ではなく、場合列挙の
方法で証明した(1900年頃G.TARRYという人物)と書かれていました。
当時高速コンピューターもない時代にこんなことができるんでしょうか?
もしこんなに可能性が大量に発生する問題に計算機無しに決着をつけたとしたら
その根性はとんでもないものだと驚愕します。
先人の知恵や執念を垣間見た感慨です。
それにしてもオイラーという人物は、さらに怪物に見えます。
 

Re: 山中さんへお礼と感想

 投稿者:山中和義  投稿日:2008年11月 4日(火)13時38分41秒
返信・引用
  > No.43[元記事へ]

GAIさんへのお返事です。

C言語版を移植してみました。ただし、直訳ではありません。
全解求めるようになっていますので、C言語版のように最初の解のみは、
プログラムの最後のSTOP文を有効にしてください。

N=5がすでに厳しいようです。100倍!?ぐらいの速さの差を感じます。
前回紹介したバックトラック法よりは良好です。


!オイラー方陣を求める

LET N=5 !大きさ N×N

!※N=1,2,3,4,5,6,7,…なら、1,1,1,4,56,9408,16942080,…となる。
PUBLIC NUMERIC LM(9408,0 TO 35) !標準形ラテン方陣 N=6

PUBLIC NUMERIC CntOfLM !その数
LET CntOfLM=0

DIM M(0 TO N*N-1) !平方の方陣
MAT M=(-1)*CON
FOR i=0 TO N-1 !標準形 ※1行目と1列目が整列している
   LET M(i*N+0)=i
   LET M(0*N+i)=i
NEXT i

LET t0=TIME
CALL BackTrack(N,M,0) !左上から
PRINT CntOfLM
PRINT "計算時間=";TIME-t0



LET t0=TIME

PUBLIC NUMERIC ANSWER_COUNT !解答数
LET ANSWER_COUNT=0

LET cnt=0 !検証回数
LET cc=comb(CntOfLM+2-1,2)

DIM A(0 TO N-1,0 TO N-1),B(0 TO N-1,0 TO N-1)
FOR i=1 TO CntOfLM !標準形Aと標準形Bの展開との重複組合せ 56H2
   FOR y=0 TO N-1 !Aを指定する
      FOR x=0 TO N-1
         LET A(y,x)=LM(i,y*N+x)
      NEXT x
   NEXT y

   FOR j=i TO CntOfLM

      LET cnt=cnt+1 !進捗
      PRINT cnt;"/";cc

      FOR y=0 TO N-1 !Bを指定する
         FOR x=0 TO N-1
            LET B(y,x)=LM(j,y*N+x)
         NEXT x
      NEXT y

      DIM R(N) !順列の初期値
      FOR k=1 TO N
         LET R(k)=k
      NEXT k
      CALL RPerm(N,A,B, R,2) !まず行順を指定する ※1行目は固定
   NEXT j
NEXT i
IF ANSWER_COUNT=0 THEN PRINT "解なし"

PRINT "計算時間=";TIME-t0


END


EXTERNAL SUB BackTrack(N,M(),p) !(左上からの連番)位置pを調査する
IF p<N*N THEN !すべてが埋まるまで
   IF M(p)>=0 THEN !既に置いてあれば
      CALL BackTrack(N,M,p+1) !次へ
   ELSE
      FOR k=0 TO N-1 !数字0〜N-1を
         CALL CheckRule(N,M, p,k, rc)!矛盾なく置ければ
         IF rc=1 THEN
            LET M(p)=k !ここに置いてみる
            CALL BackTrack(N,M,p+1) !次へ
            LET M(p)=-1 !取り消す
         END IF
      NEXT k
   END IF

ELSE !すべて埋まったら
   LET CntOfLM=CntOfLM+1 !数と配置を記録する
   FOR i=0 TO N*N-1
      LET LM(CntOfLM,i)=M(i)
   NEXT i

END IF
END SUB


EXTERNAL SUB CheckRule(N,M(), p,K, rc) !同じ数があるかどうか確認する
LET rc=0

LET row=INT(p/N) !行と列に換算する
LET col=MOD(p,N)

FOR i=0 TO row-1 !列
   IF M(i*N+col)=K THEN EXIT SUB
NEXT i

FOR i=0 TO col-1 !行
   IF M(row*N+i)=K THEN EXIT SUB
NEXT i

LET rc=1 !見つからないので、OK!
END SUB


EXTERNAL SUB RPerm(N,A(,),B(,), P(),i) !順列を生成して行の並び替え ※辞書式順ではない
IF I<N THEN
   FOR j=i TO N
      LET t=P(i) !i番目とj番目を交換する
      LET P(i)=P(j)
      LET P(j)=t
      CALL RPerm(N,A,B, P,i+1) !再帰呼出し
      LET t=P(i) !元に戻す
      LET P(i)=P(j)
      LET P(j)=t
   NEXT j

ELSE !完了なら
   DIM C(N) !順列の初期値
   FOR j=1 TO N
      LET C(j)=j
   NEXT j
   CALL CPerm(N,A,B,P,C,1) !今度は列順を指定する

END IF
END SUB


EXTERNAL SUB CPerm(N,A(,),B(,),R(), P(),i) !順列を生成して列の並び替え ※辞書式順ではない
IF I<N THEN
   FOR j=i TO N
      LET t=P(i) !i番目とj番目を交換する
      LET P(i)=P(j)
      LET P(j)=t
      CALL CPerm(N,A,B,R, P,i+1) !再帰呼出し
      LET t=P(i) !元に戻す
      LET P(i)=P(j)
      LET P(j)=t
   NEXT j

ELSE !オイラー方陣をつくって検証する

   DIM EM(N,N) !使用できる数字の組と使用状況
   MAT EM=ZER

   !※ラテン方陣の組合せなので、行と列の重複はない。
   FOR i=0 TO N-1 !方陣全体で同じ数があるかどうか確認する
      FOR j=0 TO N-1
         LET rr=A(i,j)+1 !オイラー方陣をつくる
         LET cc=B(R(i+1)-1,P(j+1)-1)+1
         IF EM(rr,cc)=1 THEN EXIT SUB !その数字は使用中なのでNG!
         LET EM(rr,cc)=1
      NEXT j
   NEXT i


   LET ANSWER_COUNT=ANSWER_COUNT+1 !解答数
   PRINT ANSWER_COUNT

   FOR i=0 TO N-1 !答えを表示する
      FOR j=0 TO N-1
         PRINT (A(i,j)+1)*10 + B(R(i+1)-1,P(j+1)-1)+1 ;
      NEXT j
      PRINT
   NEXT i

   !!!STOP !最初に見つけた答え

END IF
END SUB
 

Re: プログラムのお願い

 投稿者:SECOND  投稿日:2008年11月 4日(火)14時32分41秒
返信・引用  編集済
  > No.39[元記事へ]

!掲示のC言語のリストを、十進BASIC版に書き直したもので、何も変わっていません。
!全く同じものだと、思います。違っていたら御免なさい。

!check1、check2 の交番する再帰コールは、見ずらいので、
!check1 1本の中に統合したが、内容は同じです。

OPTION BASE 0
LET N= 3 ! 2,3,4,5,6
DIM lb(9408,N,N) ! N=1〜7: 1,1,1,4,56,9408,16942080 N=7は非現実的
DIM wb(N,N), xidx(N), yidx(N), fb(N,N)
!
CALL main

SUB makelb(x, y)
   local i,j
   FOR i=0 TO N-1
      FOR j=0 TO x-1
         IF i=wb(y,j) THEN EXIT FOR ! break;
      NEXT j
      IF j>x-1 THEN
         FOR j=0 TO y-1
            IF i=wb(j,x) THEN EXIT FOR ! break;
         NEXT j
         IF j>y-1 THEN
            LET wb(y,x)= i
            IF y=N-1 AND x=N-1 THEN
            !----memcpy(lb[lbs++], wb, sizeof(wb));
               FOR a=0 TO N
                  FOR b=0 TO N
                     LET lb(lbs,a,b)=wb(a,b)
                  NEXT b
               NEXT a
               LET lbs=lbs+1
               !---------------
               EXIT SUB ! return;
            END IF
            IF y=N-1 THEN CALL makelb(x+1, 1) ELSE CALL makelb((x),y+1)
         END IF
      END IF
   NEXT i
END SUB


SUB echk
   local i,j
   MAT fb=ZER ! memset(fb, 0, sizeof(fb));
   FOR i= 0 TO N-1
      FOR j= 0 TO N-1
         IF fb( lb(p,i,j), lb(q,yidx(i),xidx(j)) )>0 THEN EXIT SUB ! return;
         LET fb( lb(p,i,j), lb(q,yidx(i),xidx(j)) )=1
      NEXT j
   NEXT i
   FOR i= 0 TO N-1
      FOR j= 0 TO N-1
         PRINT USING "%#": lb(p,i,j)+1, lb(q,yidx(i),xidx(j))+1;
         IF j=N-1 THEN PRINT ELSE PRINT " ";
      NEXT j
   NEXT i
   STOP ! exit(0);
END SUB


SUB check1(n_)
   local i
   FOR i=n_ TO N-1
      swap xidx(i),xidx(n_)
      !-----check2(n_)
      local i_
      FOR i_= n_ TO N-1
         swap yidx(i_),yidx(n_)
         IF ( yidx(n_)<>xidx(n_)) AND (n_<>1 OR yidx(n_)< xidx(n_) ) THEN
            IF n_=N-1 THEN CALL echk ELSE CALL check1(n_+1)
         END IF
         swap yidx(i_),yidx(n_)
      NEXT i_
      !------
      swap xidx(i),xidx(n_)
   NEXT i
END SUB


SUB main
   FOR i= 0 TO N-1
      LET wb(i,0)= i
      LET wb(0,i)= i
   NEXT i
   LET lbs = 0
   PRINT "N=";N; ! 追加した表示
   CALL makelb(1,1)
   PRINT "lbs=";lbs !追加
   MAT PRINT wb !  追加
   LET count= 0
   FOR p=0 TO lbs-1
      FOR q=p TO lbs-1
         LET count=count+1
         IF MOD(count,1000)=0 THEN PRINT count
         FOR i= 0 TO N-1
            LET yidx(i)= i
            LET xidx(i)= i
         NEXT i
         CALL check1(1)
      NEXT q
   NEXT p
   PRINT "解は見つかりませんでした."
END SUB

END

!注意:このリストは、for~nextの中から再帰コールをしているので、十進BASICの
!   Ver7.2.0 以降 のバージョンが必要です。
 

Re: プログラムのお願い

 投稿者:山中和義  投稿日:2008年11月 4日(火)16時27分16秒
返信・引用
  > No.45[元記事へ]

SECONDさんへのお返事です。

SECONDさん、お久しぶりです。

C言語版のコードをみて思ったのですが

・N=1が求まらない
・順列の生成がおかしい(行や列の交換が不十分)
 →標準形からすべて展開されていない
 →exitの箇所をコメント(無効)にしても全解が得られない
 →N=6で検証していない箇所がある
の疑問があります。

GAIさんを経由してC言語版の作者に聞くのが筋と思いますが、
SECONDさんは、どのように感じていますか?
 

Re: プログラムのお願い

 投稿者:SECOND  投稿日:2008年11月 4日(火)17時00分31秒
返信・引用
  > No.46[元記事へ]

山中和義さんへのお返事です。

全く同感です。その様にして頂ければと、思います。
 

カードマジックで出会った現象

 投稿者:GAI  投稿日:2008年11月 4日(火)22時52分56秒
返信・引用
  お二人の強力なプログラマーの出現により、C言語とBASIC言語との比較をしながらとってもいい勉強ができています。
Cのスピードは魅力的ですが、どうも約束事が多くて馴染み難いのです。
その点BASICの記述では何をしたいのかがCに較べると読み取り易い気がします。
C言語でプログラムを書いていただいた方には後ほど質問をしておきます。
話は変わりますが・・・
この場を借りて日頃疑問に感じていることを解析してほしいんですが実は自分はカードマジックが大好きでそれに関連した本を読んでいて出会った記述でして、次のような事が起きます。
ぜひ、トランプで確認を!
ハートとスペードを順にA、2、3・・・Qと重ねる。
ハートパケットはテーブルに裏向き(Aが上)で置く。
観客に1〜12までの好きな数字を決め手もらう。
スペードパケットを手に裏向き(Aが上)に持ち、上から表向きにしながらテーブルへ左、右、左、・・・と2つの山を作りながらカードを重ねていく。
客が決めた数字の枚数目の時、このカードはテーブルの別の場所に捨てられた札として、表向きのまま除く。その代わりとして、ハートパケットの一番上のカードをこのカードの置くべきだった山へ表向きにのせる。後続けていき手持ちのカードが無くなるまで進む。
左の山を持ち上げ、右の山へ重ね、一つになったパケットを手にとり、裏向きで持つ。
同じことをくり返し、最終的に手にはハート、捨て場にはスペードが集まる。
この二つの山をテーブルに並べて置く。
観客にハートまたはスペードから好きなカード(A〜Qまでの中から)の名前を言ってもらう。(例ハートの8を観客が選んだとして説明します。)
客がハートを選択したのなら、まずスペードの山から、上より8枚目のカードを引き出す。
(もし客がスペードの選択をしたのならハートの山からカードを引き出すことになる。)
引き出したカードの数字に従い、今度はハートパケットの上からその数字の枚数目のカードを表向きにする。
ここから客が指定しておいたハートの8が出現する。
<わかり難いでしょうか?>
この客に任意で選択させている事(1〜12を選ばせたり、好きなカードを指定させたり)をやっておきながら、的確に客のカードを当ててしまう仕組みはとっても数学的に巧く計算されていると思われます。
12という数字が何かキーになる性質を有しているからだろうと予感されます。
このことをプログラムで解明して欲しいんですが・・・
 

Re: カードマジックで出会った現象

 投稿者:山中和義  投稿日:2008年11月 5日(水)16時23分20秒
返信・引用  編集済
  > No.48[元記事へ]

GAIさんへのお返事です。

たぶんこれで大丈夫でしょう。
剰余(mod)が関係しているのでしょうか?(一種のシャッフルですから)


LET mk$="SCHD" !マーク

SUB dec(C(),p, w) !パケット内上からp位置のカードを削除する
   LET w=C(p)
   FOR i=p TO C(0)-1 !前に詰める
      LET C(i)=C(i+1)
   NEXT i
   LET C(0)=C(0)-1
END SUB
SUB inc(C(),p,w) !パケット内上からp位置にカードを追加する
   IF p<=C(0) THEN
      FOR i=C(0) TO p STEP -1 !後ろにずらす
         LET C(i+1)=C(i)
      NEXT i
   ELSE
      LET p=C(0)+1 !最後
   END IF
   LET C(p)=w
   LET C(0)=C(0)+1
END SUB
DIM TT(0 TO 13*4+1)
SUB add(C1(),C2(), C()) !C1を上、C2を下にパケットを重ねる
   FOR i=1 TO C1(0)
      LET TT(i)=C1(i)
   NEXT i
   FOR i=1 TO C2(0) !続けて
      LET TT(C1(0)+i)=C2(i)
   NEXT i
   LET C(0)=C1(0)+C2(0)
   FOR i=1 TO C(0)
      LET C(i)=TT(i)
   NEXT i
END SUB
SUB clr(C()) !パケットをクリアする
   LET C(0)=0
END SUB
SUB rev(C()) !パケットを裏返す
   FOR i=1 TO INT(C(0)/2)
      swap C(i),C(C(0)-i+1)
   NEXT i
END SUB
SUB disp(C(),m$) !パケットを上から順に表示する
   PRINT m$;"(";C(0);"枚)";
   FOR i=1 TO C(0)
      PRINT C(i);
   NEXT i
   PRINT
END SUB
!-------------------- ここまでがサブルーチン


LET N=12 !枚数

DIM S(0 TO N),H(0 TO N) !スペード、ハートパケットの初期化
FOR i=1 TO N !整列
   LET S(i)=i !スペード 1〜13
   LET H(i)=i+13*2 !ハート 27〜39
NEXT i
LET H(0)=N !枚数
LET S(0)=N

!テーブルの初期化
DIM Y1(0 TO N),Y2(0 TO N),Y3(0 TO N) !山1、山2、捨て場
CALL clr(Y1) !山のクリア
CALL clr(Y2)
CALL clr(Y3)

CALL dump !内容を確認する

SUB dump
   CALL disp(S,"スペード") !トレース
   CALL disp(H,"ハート")
   CALL disp(Y1,"山1")
   CALL disp(Y2,"山2")
   CALL disp(Y3,"捨て場")
   PRINT
END SUB


!1回目
INPUT PROMPT "好きな数字(2〜N)?": K !好きな数字 1〜N

CALL routine

SUB routine !作業の定義
   FOR x=1 TO N !手持ちのカードがなくなるまで
      PRINT x;"枚目をテーブルへ"
      CALL dec(S,1,w) !削除する
      IF x=K THEN !一致する枚数目なら捨て場へ
      !IF MOD(x,K)=0 THEN !一致する枚数目なら捨て場へ
         CALL inc(Y3,1,w)
         CALL dec(H,1,w) !代替として場から
      END IF

      IF MOD(x,2)=0 THEN !左右交互で山に置く
         CALL inc(Y2,1,w)
      ELSE
         CALL inc(Y1,1,w)
      END IF

      CALL dump !内容を確認する
   NEXT x
   PRINT
END SUB




!2回目以降
DO
   CALL add(Y1,Y2, S) !山を重ねて手に持つ
   CALL rev(S)
   CALL disp(S,"スペード")
   PRINT

   IF H(0)=0 THEN EXIT DO !ハートパケットがなくなるまで

   CALL clr(Y1) !山のクリア
   CALL clr(Y2)

   CALL routine
LOOP


MAT H=Y3
CALL rev(H)
CALL disp(H,"ハート")


INPUT PROMPT "カードのマーク?": c$
INPUT PROMPT "数字(1〜N)?": K

IF UCASE$(c$)="H" THEN
   LET w=H(K) !スペードの列になっている
   LET w=S(w)
ELSE
   LET w=MOD(S(K),13) !ハートの列になっている
   LET w=H(w)
END IF
PRINT mid$(mk$,INT(w/13)+1,1); MOD(w,13)


END
 

Re: カードマジックで出会った現象

 投稿者:SECOND  投稿日:2008年11月 5日(水)17時59分39秒
返信・引用
  > No.48[元記事へ]

!トランプ は、どの数を選んでも、
!互いに インデックスに なってしまうようです。難解。

DIM s(12),h(12),w(12),t(12)

PRINT "----- 最初の状態 -----"
CALL ready
CALL printa(s) ! スペード
CALL printa(h) ! ハート
PRINT
!
FOR R=1 TO 12
   PRINT "----- Request";R;"の場合-----"
   CALL ready
   LET k=1
   DO WHILE k< 13
      FOR i=1 TO 12
         LET j=MOD(i,2)*7+INT(i/2) ! 分けた2つを重ねた時の位置。
         IF i=R THEN
            LET t(j)=h(k) ! ハートをテーブルへ
            LET w(k)=s(i) ! 手元(最初スペード)を「捨て」へ
            LET k=k+1
         ELSE
            LET t(j)=s(i) ! 手元(最初スペード)をテーブルへ
         END IF
      NEXT i
      MAT s=t ! テーブルを手元(最初スペード)へ
   LOOP
   CALL printa(s) ! 比較・・・手元(最初スペード)
   CALL printa(w) ! 比較・・・「捨て」の重なり
   PRINT
NEXT R

SUB printa(a())
   FOR n=1 TO 12
      PRINT USING "## ":a(n);
   NEXT n
   PRINT " …互いに Index."
END SUB

SUB ready
   FOR i=1 TO 12
      LET s(i)=i
      LET h(i)=i
   NEXT i
END SUB

END
 

Re: カードマジックで出会った現象

 投稿者:山中和義  投稿日:2008年11月 5日(水)21時53分27秒
返信・引用
  > No.49[元記事へ]

リフルシャッフルの性質を利用していると思います。

プログラムを実行して表示されるKは、
「手持ちのカードを左右の山に分けて、左右と重ね1つの山にする」の操作に該当します。
一番上の索引番号が最初に聞いた好きな番号です。どの列でも構いませんが、
その列を上から順に見ていくと、捨て場に積まれる(スペードの)カードの順になります。

ところで置き換えたハートのカードは、この番号位置に置き換わりますが、
最終的に、12回の操作でスペードのカードに対応した位置に整列されることになります。

これで参照位置とその配置位置をうまく絡ませることができます。

ちょうどN回目でもとに戻る場合、たとえばN=2,4,10,12がこの問題を満たすと思います。



!置換(Permutation)の計算

!補助ルーチン
SUB PermPrintOut(A()) !表示する ※標準形(2行n列の行列表記する)
!PRINT "┌";
!FOR i=1 TO UBOUND(A)
!   PRINT USING "###": i;
!NEXT i
!PRINT " ┐"
!PRINT "└";
   FOR i=1 TO UBOUND(A)
      PRINT USING "###": A(i);
   NEXT i
   !PRINT " ┘";
   PRINT
END SUB

!置換
SUB PermIdentity(A()) !恒等置換
   FOR i=1 TO UBOUND(A)
      LET  A(i)=i
   NEXT i
END SUB
SUB PermMultiply(A(),B(), AB()) !積AB ※AB≠BA、A(BC)=(AB)C
   LET  ua=UBOUND(A)
   LET  ub=UBOUND(B)
   IF ua=ub THEN
      FOR i=1 TO ua
         LET  AB(i)=A(B(i)) !※合成写像(AB)(i)=A(B(i))
      NEXT i
   ELSE
      PRINT "次元が違います。A=";ua;" B=";ub
      STOP
   END IF
END SUB
!-------------------- ここまでがサブルーチン


!main

LET N=12 !※2,4,10,12

!A=┌ 1 2 3 4 ┐=(1 2 4 3) ※1行目の順番は固定とする
! └ 2 4 1 3 ┘
DATA 2,4,6,8,10,12,1,3,5,7,9,11 !配列変数の「添え字と値」に対応させる
!DATA 2,4,6,8,10,1,3,5,7,9 !N=10
!DATA 2,4,1,3 !N=4
!DATA 2,1 !N=2
DIM A(N)
MAT READ A

FOR i=1 TO N
   PRINT USING "###": i;
NEXT i
PRINT

DIM B(N)
CALL PermIdentity(B) !初期値

DIM c(N)
FOR k=1 TO N !回数
   CALL PermMultiply(B,A,c) !シャッフル
   PRINT "K=";k
   CALL PermPrintOut(c) !何回か実行すると元に戻る
   MAT B=c
NEXT k


END
 

Re: プログラムのお願い

 投稿者:GAI  投稿日:2008年11月 5日(水)22時07分8秒
返信・引用
  > No.46[元記事へ]

山中和義さんへのお返事です。

> C言語版のコードをみて思ったのですが
>
> ・N=1が求まらない
> ・順列の生成がおかしい(行や列の交換が不十分)
>  →標準形からすべて展開されていない
>  →exitの箇所をコメント(無効)にしても全解が得られない
>  →N=6で検証していない箇所がある
> の疑問があります。


このことを製作者の方にお尋ねしましたところ、次のようなメールを頂きました。

・N=1が求まらない

  N=1に対処するとプログラムが面倒になるだけですので
無視しています(手間をかけてN=1にわざわざ対処しても、
まったく無意味ですよね?)。

> ・順列の生成がおかしい(行や列の交換が不十分)
>  →標準形からすべて展開されていない
>  →exitの箇所をコメント(無効)にしても全解が得られない
>  →N=6で検証していない箇所がある

  おかしくないはずです。
  すべてを検証すると非常に長い時間がかかりますので、
数学的に考えて検証が必要ないものは省いています。
(省かないと、現実的な時間で求まりません。)

との回答でした。連絡まで
 

Re: プログラムのお願い

 投稿者:山中和義  投稿日:2008年11月 6日(木)07時10分30秒
返信・引用
  > No.52[元記事へ]

GAIさんへのお返事です。

お手数おかけしました。ありがとうございます。
 

カードマジックの続き

 投稿者:GAI  投稿日:2008年11月 6日(木)10時47分33秒
返信・引用
  ということは、12枚ずつ計24枚のカードでなくても、
2,4,10,12,18,36,52,58,60,66,82,100,・・・
枚ずつの場合でも同様な現象が起こせるということなんでしょうか?

この手品には続きがありまして、一度この現象を見せても客はたまたま当たったとしか感じてくれないので、次のようにさらにカードを混ぜたように見せていく。
まず、一方のパケット(例としてハートの方を選ぶ)にK(13)カードを一枚をボトムに
付け加える。(パケットは裏向き状態)
これを数回カット(任意の場所から分け、上、下の位置関係を逆にする。)した後、
客に2〜12の中から好きな数字を言ってもらう。(例:9を言ったとして以下説明)
パケットを表向きにして上から一枚ずつテーブルへ9つの山を作っていく。(左から右へ)
残りのカードは始めの山に戻り、2枚目として重ねていく。(左より4つ目の山で終る)
この最後に置いたカードが一番右の山から数えて何番目の場所で終わったのかを密かに覚える。
(9の場合は右回りにカウントすると4番目、左回りにカウントすると5番目ということになる。)
左か右回りは関係せず、少ない方の数をキー数字(9なら4となる。)とする。
ここで、客に9つの山の一つを任意に選ばせる。
演者はこの山から取り上げ、右へ(右回りにカウントして得た数字だから)4ずつ進んで
行った山の上に重ねる。
同じく重なった山を持ち上げ、次の4右へ進んだ山の上に重ねる。(一番右まできたら、一番左の山へ進んでカウントする。)
これを続けていく。(ただし重ねる山は、最初に置いていた山の位置でカウントすること。 従ってもうカードを取り去った位置もカウントの対象になる。)
<客からはカードの集め方がランダムに集めているように感じる。>
一つにまとまったパケット(表向き)を数回カットするが、最後のカットでK(13)カードがボトムに(表向きなら一番上)なるように、調節し裏向きでテーブルに置く。
このとき、一番下(裏向きの状態なら一番上)にくるカードを盗み見して(数字)覚えておく。
次にスペードのパケット(こちらは12枚)を取り上げ、エースカードが盗み見をした数に上から数えての枚数目になるように、位置を調節して一度カットをする。
裏向き状態でテーブルに置く。(これで、全てのカード位置と指示位置が対応している)

この作業は気が済むまで、くり返して行ってよい。
(だれでもハートのカードはがっかりするくらいよく混ぜられたと感じるだろう。)

再び、客のリクエストに相当するカードを探しだすことができる。
(またまた、分かり難いでしょうか?)
 

Re: カードマジックの続き

 投稿者:山中和義  投稿日:2008年11月 7日(金)07時31分4秒
返信・引用
  > No.54[元記事へ]

GAIさんへのお返事です。

>2,4,10,12,18,36,52,58,60,66,82,100,・・・

たぶんOKだと思います。


>続きのマジックについて

プログラムミスと思いますが、一致するときと一致しないときがあります。
後でプログラムを掲載します。(長編です)


>続きのマジックのテーブルでのハートパケットのシャッフルについて

シャッフルによって元の数字がどこに移動するか確認してみました。
1回目(作る山の数)の好きな数字によって、次のプログラムで表示される表の数字列(横にみる)のいずれかになるようです。
2回目(山の選択)は、13を底に移動させる調整カットで無効になります。

1  2  3  4  5  6  7  8  9 10 11 12 13
2  4  6  8 10 12  1  3  5  7  9 11 13
3  6  9 12  2  5  8 11  1  4  7 10 13
4  8 12  3  7 11  2  6 10  1  5  9 13
5 10  2  7 12  4  9  1  6 11  3  8 13
6 12  5 11  4 10  3  9  2  8  1  7 13
7  1  8  2  9  3 10  4 11  5 12  6 13
8  3 11  6  1  9  4 12  7  2 10  5 13
9  5  1 10  6  2 11  7  3 12  8  4 13
10  7  4  1 11  8  5  2 12  9  6  3 13
11  9  7  5  3  1 12 10  8  6  4  2 13
12 11 10  9  8  7  6  5  4  3  2  1 13

たとえば、好きな数字に3を指定すると13-3=10番目になります。
10  7  4  1 11  8  5  2 12  9  6  3 13 … (1)


これがスペードパケットの調整カットとの関係が見えません。(調査中)
1列目の数字(10)か、1の位置(4番目)か、何か、、、



●プログラム

!13以外の数Nに、自分自身Nを加えて新しい数を作る。
!その数が13より大きいときは、13を引く。
DIM A(13),B(13)
FOR k=1 TO 12
   LET A(k)=k
   LET B(k)=0
NEXT k
FOR i=1 TO 12
   FOR k=1 TO 12
      LET B(k)=MOD(B(k)+A(k),13)
   NEXT k
   LET B(13)=13
   MAT PRINT B;
NEXT i
END
 

Re: カードマジックの続き

 投稿者:GAI  投稿日:2008年11月 7日(金)09時24分8秒
返信・引用
  > No.55[元記事へ]

山中和義さんへのお返事です。

> プログラムミスと思いますが、一致するときと一致しないときがあります。

続いて手品を行うということは、最初のマジックを終了したもののパケットをそのまま
の順序で利用するということになります。
(関係ないですかね?)
なお、客が指定する山の数に対応してカードを集める向きとずらし数は
2:右へ1
3:右へ1
4:右へ1
5:左へ2
6:右へ1
7:左へ1
8:左へ3
9:右へ4
10:右へ3
11:右へ2
12:右へ1
となります。
(まさにこれは、13が素数であることを上手に利用した方法ですね。)
 

Re: カードマジックの続き

 投稿者:山中和義  投稿日:2008年11月 7日(金)09時25分35秒
返信・引用  編集済
  > No.55[元記事へ]

GAIさんへのお返事です。

動作不良です。間違った操作を指摘してください。
1000 !トランプのマジック
1010
1020 !パケット操作のシミュレーション
1030
1040 SUB dec(C(),p, w) !上からp位置のカードを削除する ※1≦p
1050    LET w=C(p)
1060    FOR i=p TO C(0)-1 !前に詰める
1070       LET C(i)=C(i+1)
1080    NEXT i
1090    LET C(0)=C(0)-1 !枚数
1100 END SUB
1110 SUB inc(C(),p,w) !上からp位置にカードを追加する
1120    IF p<=C(0) THEN
1130       FOR i=C(0) TO p STEP -1 !後ろにずらす
1140          LET C(i+1)=C(i)
1150       NEXT i
1160    ELSE
1170       LET p=C(0)+1 !最後へ
1180    END IF
1190    LET C(p)=w
1200    LET C(0)=C(0)+1 !枚数
1210 END SUB
1220 DIM TT(0 TO 13*4+1) !作業用 ※1デッキ分
1230 SUB add(C1(),C2(), C()) !C1を上、C2を下に重ねる
1240    FOR i=1 TO C1(0) !C1
1250       LET TT(i)=C1(i)
1260    NEXT i
1270    FOR i=1 TO C2(0) !続けてC2
1280       LET TT(C1(0)+i)=C2(i)
1290    NEXT i
1300    LET TT(0)=C1(0)+C2(0) !枚数
1310    CALL copy(TT,TT(0), C)
1320 END SUB
1330 SUB clr(C()) !空にする
1340    LET C(0)=0
1350 END SUB
1360 SUB rev(C()) !裏返す
1370    FOR i=1 TO INT(C(0)/2)
1380       swap C(i),C(C(0)-i+1) !上下を入れ替える
1390    NEXT i
1400 END SUB
1410 SUB del(C(),p,q) !p位置からq位置までのカードを削除する ※1≦p≦q
1420    IF p>C(0) THEN
1430       PRINT "無効です。";p;q
1440    ELSE
1450       IF p>q THEN
1460          PRINT "p>qで無効です。";p;q
1470       ELSE
1480          LET q=MIN(q,C(0))
1490          FOR i=q+1 TO C(0) !残りを繋げる
1500             LET C(p+i-q-1)=C(i)
1510          NEXT i
1520          LET C(0)=C(0)-(q-p+1) !枚数
1530       END IF
1540    END IF
1550 END SUB
1560 SUB shuffle(C()) !リフルシャッフルを行う ※後半、前半の順に重ねる
1570    FOR i=1 TO C(0)
1580       LET TT(i)=C(INT(i/2)+MOD(i,2)*(INT(C(0)/2)+1))
1590       !LET TT(i)=C(INT((i-1)/2)+MOD(i-1,2)*INT(C(0)/2)+1) !※前半、後半の順
1600    NEXT i
1610    LET TT(0)=C(0) !枚数
1620    CALL copy(TT,TT(0), C)
1630 END SUB
1640 SUB cut(C(),p) !カットする ※p位置以降が上になる
1650    LET p=MIN(p,C(0))
1660    FOR i=1 TO p-1 !前半部分を後へ
1670       LET TT(C(0)+i-p+1)=C(i)
1680    NEXT i
1690    FOR i=p TO C(0) !後半部分を前へ
1700       LET TT(i-p+1)=C(i)
1710    NEXT i
1720    LET TT(0)=C(0) !枚数
1730    CALL copy(TT,TT(0), C)
1740 END SUB
1750 SUB copy(C1(),p, C()) !上からp位置までをコピーする
1760    LET p=MIN(p,C1(0))
1770    FOR i=1 TO p !copy it
1780       LET C(i)=C1(i)
1790    NEXT i
1800    LET C(0)=p !枚数
1810 END SUB
1820 SUB move(C1(),p, C()) !上からp位置までを移動する
1830    CALL copy(C1,p,C)
1840    CALL del(C1,1,p)
1850 END SUB
1860 SUB disp(C(),m$) !上から順に表示する
1870    PRINT m$;"(";C(0);"枚)";
1880    FOR i=1 TO C(0)
1890       PRINT C(i);
1900    NEXT i
1910    PRINT
1920 END SUB
1930
1940
1950 DEF MarkOfCard$(w)=mid$(mk$,INT(w/13)+1,1) !カードを表示する
1960 DEF NumOfCard(w)=MOD(w,13)
1970 DEF CntOfPacket(C())=C(0) !パケット内のカードの枚数
1980
1990 LET mk$="SCHD" !マーク
2000 LET nm$=" A 1 2 3 4 5 6 7 8 910 J Q K" !※2文字ずつ
2010
2020 !スペード、クラブ、ハート、ダイヤパケットを初期化する
2030 DIM cS(0 TO 13),cC(0 TO 13),cH(0 TO 13),cD(0 TO 13)
2040 FOR i=1 TO 13 !整列
2050    LET cS(i)=i !スペード 1〜13
2060    LET cC(i)=i+13 !クラブ 14〜16
2070    LET cH(i)=i+13*2 !ハート 27〜39
2080    LET cD(i)=i+13*3 !ダイヤ 40〜52
2090 NEXT i
2100 LET cS(0)=13 !枚数
2110 LET cC(0)=13
2120 LET cH(0)=13
2130 LET cD(0)=13
2140 !-------------------- ここまでがサブルーチン
2150
2160
2170 LET N=12 !枚数
2180
2190 DIM Y1(0 TO N+1),Y2(0 TO N+1),Y3(0 TO N+1),Y4(0 TO N+1) !山1〜12
2200 DIM Y5(0 TO N+1),Y6(0 TO N+1),Y7(0 TO N+1),Y8(0 TO N+1)
2210 DIM Y9(0 TO N+1),Y0(0 TO N+1),Yj(0 TO N+1),Yq(0 TO N+1)
2220
2230 DIM S(0 TO N+1),H(0 TO N+1) !スペード、ハートパケットの初期化
2240 CALL copy(cS,N, S)
2250 CALL copy(cH,N, H)
2260
2270 CALL dump !内容を確認する
2280 SUB dump
2290    CALL disp(S,"スペード") !トレース
2300    CALL disp(H,"ハート")
2310    CALL disp(Y1,"山1")
2320    CALL disp(Y2,"山2")
2330    CALL disp(Y3,"捨て場")
2340    PRINT
2350 END SUB
2360
2370
2380 !1回目
2390 INPUT PROMPT "好きな数字(1〜N)?": K !好きな数字 1〜N
2400
2410 CALL routine
2420 SUB routine !作業の定義
2430    FOR x=1 TO N !手持ちのカードがなくなるまで
2440    !!!PRINT x;"枚目をテーブルへ"
2450       CALL dec(S,1,w) !削除する
2460       IF x=K THEN !一致する枚数目なら捨て場へ
2470          CALL inc(Y3,1,w)
2480          CALL dec(H,1,w) !代替として場から
2490       END IF
2500
2510       IF MOD(x,2)=0 THEN !左右交互で山に置く
2520          CALL inc(Y2,1,w)
2530       ELSE
2540          CALL inc(Y1,1,w)
2550       END IF
2560
2570       !!!CALL dump !内容を確認する
2580    NEXT x
2590    !!!PRINT
2600 END SUB
2610
2620
2630 !2回〜N回まで
2640 DO
2650    CALL add(Y1,Y2, S) !山を重ねて手に持つ
2660    CALL rev(S)
2670
2680    CALL clr(Y1) !山のクリア
2690    CALL clr(Y2)
2700
2710    IF CntOfPacket(H)=0 THEN EXIT DO !テーブル上のハートパケットがなくなるまで
2720
2730    CALL routine
2740 LOOP
2750
2760
2770 CALL move(Y3,99, H) !最終の状態
2780 CALL rev(H)
2790
2800 PRINT
2810 CALL dump !内容を確認する
2820
2830
2840 CALL surprise
2850 SUB surprise
2860    INPUT PROMPT "カードのマーク(S,H)?": c$
2870    INPUT PROMPT "数字(1〜N)?": K
2880
2890    IF UCASE$(c$)="H" THEN
2900       LET w=H(K) !スペードの列になっている
2910       LET w=S(w)
2920    ELSE
2930       LET w=MOD(S(K),13) !ハートの列になっている
2940       LET w=H(w)
2950    END IF
2960    PRINT MarkOfCard$(w); NumOfCard(w) !カードを表示する
2970 END SUB
2980
2990 !---------- ↑↑↑↑↑ ---------- 前半のマジック
3000
3010
ここまでが前半のマジックです。(続く)
 

Re: カードマジックの続き

 投稿者:山中和義  投稿日:2008年11月 7日(金)09時28分59秒
返信・引用  編集済
  > No.55[元記事へ]

GAIさんへのお返事です。

(続き)2回目のマジック部分 ※N0.56記事を反映、行番号の付加
3020
3030
3040
3050 !CALL copy(cS,12, S) !!!!!移動先の調査 <-----ここ
3060 !CALL copy(cS,12, H) !!!!! <-----ここ
3070 PRINT
3080
3090 CALL inc(H,99, 13) !K(キング)を底に追加する
3100
3110
3120 PRINT "(ハートパケットを)数回カットする。"
3130 FOR x=1 TO 5
3140    CALL cut(H,INT(RND*(N+1))+1)
3150 NEXT x
3160
3170 CALL dump2 !内容を確認する
3180 SUB dump2
3190    CALL disp(S,"スペード") !トレース
3200    CALL disp(H,"ハート")
3210    CALL disp(Y1,"山1")
3220    CALL disp(Y2,"山2")
3230    CALL disp(Y3,"山3")
3240    CALL disp(Y4,"山4")
3250    CALL disp(Y5,"山5")
3260    CALL disp(Y6,"山6")
3270    CALL disp(Y7,"山7")
3280    CALL disp(Y8,"山8")
3290    CALL disp(Y9,"山9")
3300    CALL disp(Y0,"山10")
3310    CALL disp(Yj,"山11")
3320    CALL disp(Yq,"山12")
3330    PRINT
3340 END SUB
3350
3360
3370
3380 INPUT PROMPT "好きな数字(2〜12)": K
3390
3400 CALL routine2_1(H) !各山へ分配する
3410 SUB routine2_1(C())
3420    FOR x=1 TO N+1
3430       CALL dec(C,1,w) !1枚ずつ
3440       !SELECT CASE K-MOD(x-1,K) !それぞれの山へ
3450       SELECT CASE MOD(x-1,K)+1 !それぞれの山へ
3460       CASE 1
3470          CALL inc(Y1,1,w)
3480       CASE 2
3490          CALL inc(Y2,1,w)
3500       CASE 3
3510          CALL inc(Y3,1,w)
3520       CASE 4
3530          CALL inc(Y4,1,w)
3540       CASE 5
3550          CALL inc(Y5,1,w)
3560       CASE 6
3570          CALL inc(Y6,1,w)
3580       CASE 7
3590          CALL inc(Y7,1,w)
3600       CASE 8
3610          CALL inc(Y8,1,w)
3620       CASE 9
3630          CALL inc(Y9,1,w)
3640       CASE 10
3650          CALL inc(Y0,1,w)
3660       CASE 11
3670          CALL inc(Yj,1,w)
3680       CASE 12
3690          CALL inc(Yq,1,w)
3700       CASE ELSE
3710          PRINT "置く山がありません。"
3720          STOP
3730       END SELECT
3740    NEXT x
3750    CALL dump2 !内容を確認する
3760 END SUB
3770
3780
3790 PRINT "右から";MOD(N+1,K);"番目に最後のカードを置きました。"
3800 PRINT
3810
3820
3830
3840 INPUT PROMPT "好きな山を選ぶ(1〜K)": x
3850
3860 DIM dx(N)
3870 DATA 1,1,1,1,-2,1,-1,-3,4,3,2,1 !回収方法 ※1なら右へ1、−2なら左へ2の意
3880 MAT READ dx
3890
3900 DIM yy(0 TO N+1)
3910 CALL routine2_2 !各山から回収する
3920 SUB routine2_2
3930    DO
3940       SELECT CASE MOD(x-1,K)+1
3950       CASE 1
3960          CALL move(Y1,99, yy)
3970       CASE 2
3980          CALL move(Y2,99, yy)
3990       CASE 3
4000          CALL move(Y3,99, yy)
4010       CASE 4
4020          CALL move(Y4,99, yy)
4030       CASE 5
4040          CALL move(Y5,99, yy)
4050       CASE 6
4060          CALL move(Y6,99, yy)
4070       CASE 7
4080          CALL move(Y7,99, yy)
4090       CASE 8
4100          CALL move(Y8,99, yy)
4110       CASE 9
4120          CALL move(Y9,99, yy)
4130       CASE 10
4140          CALL move(Y0,99, yy)
4150       CASE 11
4160          CALL move(Yj,99, yy)
4170       CASE 12
4180          CALL move(Yq,99, yy)
4190       CASE ELSE
4200          PRINT "置く山がありません。"
4210          STOP
4220       END SELECT
4230
4240       IF CntOfPacket(yy)=13 THEN EXIT SUB !1つにまとまるまで
4250
4260       PRINT "山";x;"から";
4270       CALL disp(yy,"回収したカード")
4280       LET x=x+dx(K) !右または左へ移動させて該当する山へ重ねる
4290       PRINT "山";x;"に重ねます。"
4300       SELECT CASE MOD(x-1,K)+1
4310       CASE 1
4320          CALL add(yy,Y1, Y1)
4330       CASE 2
4340          CALL add(yy,Y2, Y2)
4350       CASE 3
4360          CALL add(yy,Y3, Y3)
4370       CASE 4
4380          CALL add(yy,Y4, Y4)
4390       CASE 5
4400          CALL add(yy,Y5, Y5)
4410       CASE 6
4420          CALL add(yy,Y6, Y6)
4430       CASE 7
4440          CALL add(yy,Y7, Y7)
4450       CASE 8
4460          CALL add(yy,Y8, Y8)
4470       CASE 9
4480          CALL add(yy,Y9, Y9)
4490       CASE 10
4500          CALL add(yy,Y0, Y0)
4510       CASE 11
4520          CALL add(yy,Yj, Yj)
4530       CASE 12
4540          CALL add(yy,Yq, Yq)
4550       CASE ELSE
4560       END SELECT
4570
4580       CALL dump2 !内容を確認する
4590    LOOP
4600 END SUB
4610
4620
4630 PRINT "(回収したハートパケットを)数回カットする。"
4640 FOR x=1 TO 5 !数回カットする
4650    CALL cut(yy,INT(RND*(N+1))+1)
4660 NEXT x
4670 CALL disp(yy,"")
4680
4690
4700 PRINT "K(キング)を底へ移動させるために調整カットする。"
4710 FOR x=1 TO N !位置を探す
4720    IF MOD(yy(x),N+1)=0 THEN EXIT FOR
4730 NEXT x
4740 IF x=13 THEN !既に底の場合は何もしない
4750 ELSE
4760    CALL cut(yy,x+1) !差分をカットする
4770 END IF
4780 CALL disp(yy,"")
4790
4800
4810 CALL move(yy,99, H) !最終の状態
4820
4830 LET KEY2=MOD(H(1),N+1) !一番上の数字を記憶する
4840
4850 CALL dump2 !内容を確認する
4860
4870
4880
4890
4900 PRINT KEY2;"の位置に「1」のカードがくるように(スペードパケットを)カットする。"
4910 FOR x=1 TO N !位置を探す
4920    IF MOD(S(x),N+1)=1 THEN EXIT FOR
4930 NEXT x
4940 PRINT "現在の位置";x
4950 IF x>KEY2 THEN !差分をカットする
4960    CALL cut(S,x-KEY2+1)
4970 ELSEIF x<KEY2 THEN
4980    CALL cut(S,N-(KEY2-x)+1)
4990 END IF
5000
5010 CALL dump2 !内容を確認する
5020
5030
5040 CALL surprise
5050
5060 !---------- ↑↑↑↑↑ ---------- 後半のマジック
5070
5080
5090 END
以上、長編力作?
 

感想

 投稿者:GAI  投稿日:2008年11月 7日(金)19時00分44秒
返信・引用
  私はよくプログラムが作れないんですが、感覚としてずれを生じている箇所として
山を作らせる数字は2〜12の範囲でしかないから、下記の辺りの調整か

”
INPUT PROMPT "好きな数字(2〜N:N<=12)": K
2450
2460 CALL routine2_1(H) !各山へ分配する
2470 SUB routine2_1(C())
2480    FOR x=1 TO N+1
2490       CALL dec(C,1,w) !1枚ずつ
2500       SELECT CASE MOD(x-1,K)+1 !それぞれの山へ
”
好きな山を選択するときは、1なら動きはないからDATA の最初は0?
あと2920行では wlk(K)→wlk(x)?


2870 INPUT PROMPT "好きな山を選ぶ(1〜K:K<=N,ただし0は終了)": x
2880
2890 DIM wlk(N)
2900 DATA 1,1,1,1,-2,1,-1,-3,4,3,2,1 !回収方法 ※1なら右へ1、−2なら左へ2の意
2910 MAT READ wlk
2920 LET KEY1=wlk(K) !終端位置を記憶する
2930
2940 DIM yy(0 TO N+1)
2950 CALL routine2_2 !各山から回収する

のような気がします。
でもどこがどう直すかはまったくわかりません。
 

Re: 感想

 投稿者:山中和義  投稿日:2008年11月 7日(金)19時21分52秒
返信・引用
  > No.59[元記事へ]

GAIさんへのお返事です。

2回目のマジック部分(No.58記事)の先頭箇所のコメントを削除して実行してください。
スペード、ハートとも、1,2,3,4,5,6,7,8,9,10,11,12でカードの動きがわかります。
これが実際の動きと同じでない箇所がプログラムミスとなります。

お手数ですが、確認してみてください。



!CALL copy(cS,12,S) !!!!!移動先の調査 <----- ここ
!CALL copy(cS,12,H) !!!!! <----- ここ
PRINT

CALL inc(H,99, N+1) !K(キング)を底に追加する


PRINT "(ハートパケットを)数回カットする。"
FOR x=1 TO 5
   CALL cut(H,INT(RND*(N+1))+1)
NEXT x

(以下略)
 

18次のオイラー方陣

 投稿者:GAI  投稿日:2008年11月 7日(金)19時31分26秒
返信・引用
              18次のオイラー直交方陣

0X AB T9 W7 Z5 BT 8W 5C 2A Y8 X6 6Z 3Y 92 C3 11 40 74
BY 8X 56 T4 W2 Z0 6T 3W 07 A5 Y3 X1 1Z 4A 7B 99 C8 2C
9Z 6Y 3X 01 TC WA Z8 1T BW 82 50 YB X9 C5 26 44 73 A7
X4 4Z 1Y BX 89 T7 W5 Z3 9T 6W 3A 08 Y6 70 A1 CC 2B 52
Y1 XC CZ 9Y 6X 34 T2 W0 ZB 4T 1W B5 83 28 59 77 A6 0A
3B Y9 X7 7Z 4Y 1X BC TA W8 Z6 CT 9W 60 A3 04 22 51 85
18 B6 Y4 X2 2Z CY 9X 67 T5 W3 Z1 7T 4W 5B 8C AA 09 30
CW 93 61 YC XA AZ 7Y 4X 12 T0 WB Z9 2T 06 37 55 84 B8
AT 7W 4B 19 Y7 X5 5Z 2Y CX 9A T8 W6 Z4 81 B2 00 3C 63
ZC 5T 2W C6 94 Y2 X0 0Z AY 7X 45 T3 W1 39 6A 88 B7 1B
W9 Z7 0T AW 71 4C YA X8 8Z 5Y 2X C0 TB B4 15 33 62 96
T6 W4 Z2 8T 5W 29 C7 Y5 X3 3Z 0Y AX 78 6C 90 BB 1A 41
23 T1 WC ZA 3T 0W A4 72 Y0 XB BZ 8Y 5X 17 48 66 95 C9
80 38 B3 6B 16 91 49 C4 7C 27 A2 5A 05 XX YY ZZ WW TT
7A 25 A0 58 03 8B 36 B1 69 14 9C 47 C2 YT ZX WY TZ XW
57 02 8A 35 B0 68 13 9B 46 C1 79 24 AC ZW WT TX XY YZ
65 10 98 43 CB 76 21 A9 54 0C 87 32 BA WZ TW XT YX ZY
42 CA 75 20 A8 53 0B 86 31 B9 64 1C 97 TY XZ YW ZT WX

6次では構成不可能であるのに対し、18次もの大きさでは
このようにできてしまうことに6の不思議さを感じます。
2次と6次だけは作れず、それ以外では可能であることが
さらに不思議です。
 

Re: 感想

 投稿者:GAI  投稿日:2008年11月 7日(金)20時14分51秒
返信・引用
  > No.60[元記事へ]

山中和義さんへのお返事です。

> 2回目のマジック部分(No.58記事)の先頭箇所のコメントを削除して実行してください。
> スペード、ハートとも、1,2,3,4,5,6,7,8,9,10,11,12でカードの動きがわかります。
> これが実際の動きと同じでない箇所がプログラムミスとなります。



スペード札とハート札が逆になった状態にあるような気がします。
ハートのK(13)を付け加えるときに、なにかスペード札の方に加わっているように
感じます。
最初の札の交換のとき、元々手にしていたスペードパケットが、結果的にハートカード
の集まりに変化してしまうことが影響しているのでしょうか?
 

追加

 投稿者:GAI  投稿日:2008年11月 7日(金)20時37分36秒
返信・引用
  > No.62[元記事へ]

ハートカードとして処理されているものをスペードに読み替えてカードの並びをみてみますと、最後 のKを加え山を構成して、集めて一つにしたパケットでKを一番下にコントロールしたカットの後の数の並びが、Kだけは13番目で正しいですが、1〜12番 目にあるカード位置がまったく逆で1番が12番目、2番目が11番目、3番が10番目、・・・
となってしまっているようです。
 

Re: 追加

 投稿者:山中和義  投稿日:2008年11月 7日(金)20時53分27秒
返信・引用  編集済
  > No.63[元記事へ]

GAIさんへのお返事です。

> スペード札とハート札が逆になった状態にあるような気がします。
> ハートのK(13)を付け加えるときに、なにかスペード札の方に加わっているように
> 感じます。
> 最初の札の交換のとき、元々手にしていたスペードパケットが、結果的にハートカード

はい、そうです。
スペード、ハートパケットは論理的な名まえとして扱ってください。
(別にどちらそうだと言う必要はないはずです。互いに参照され合っていますから)
実際の操作は、カードでのマークで処理するのですね?
開始する前にSWAPされればいいだけですので、プログラムは直します。


> ハートカードとして処理されているものをスペードに読み替えてカードの並びをみてみますと、最後のKを加え山を構成して、集めて一つにしたパケットでKを 一番下にコントロールしたカットの後の数の並びが、Kだけは13番目で正しいですが、1〜12番目にあるカード位置がまったく逆で1番が12番目、2番目 が11番目、3番が10番目、・・・
> となってしまっているようです。


具体的に「好きな数」「選択した山の番号」などを教えてください。
前出の「13のテーブル」の数だけ並び替えが起こりますので、区別するために。

それが実際のカードでの動きと違いがありますか?
 

点検

 投稿者:GAI  投稿日:2008年11月 7日(金)22時18分20秒
返信・引用
  最初の段階の客の選んだ数を5
後半での好きな数を3
としてカードが配られていく山の順序を見たら、1,2,3,1,2,3とカードを配らねばならぬところを、1,3,2,1,3,2・・・と配られていっているような様子です。
たぶんこの順序はカードを配り終わったとき、山を回収していく順序と思われます。
 

追加

 投稿者:GAI  投稿日:2008年11月 7日(金)22時47分46秒
返信・引用
  そして山になったカードを重ねるとき、山のカードをずらした位置の山の上に重ねるところが、山の下になって重なっていく順序に見えます。(画面でカードの数字の並びを左から順に見るとき、裏向きにして上になる順番として解釈して見ています。)  

Re: 点検

 投稿者:山中和義  投稿日:2008年11月 7日(金)22時53分41秒
返信・引用  編集済
  > No.65[元記事へ]

GAIさんへのお返事です。

> 最初の段階の客の選んだ数を5
> 後半での好きな数を3


コメントは無効して、今掲載しているプログラムで実行してみました。
 3050 CALL copy(cS,12, S) !!!!!移動先の調査 <-----ここ
 3060 CALL copy(cS,12, H) !!!!! <-----ここ

トレースのどこか具体的に指摘してください。
スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
ハート( 12 枚) 27  28  29  30  31  32  33  34  35  36  37  38
山1( 0 枚)
山2( 0 枚)
捨て場( 0 枚)

好きな数字(1〜N)?5 <-----※

スペード( 12 枚) 30  31  34  32  27  35  29  33  38  28  37  36
ハート( 12 枚) 5  10  7  1  2  4  8  3  6  12  11  9
山1( 0 枚)
山2( 0 枚)
捨て場( 0 枚)

カードのマーク(S,H)?s <-----※
数字(1〜N)?3 <-----※
S 3

(ハートパケットを)数回カットする。
スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
ハート( 13 枚) 8  9  10  11  12  13  1  2  3  4  5  6  7
山1( 0 枚)
山2( 0 枚)
山3( 0 枚)
山4( 0 枚)
山5( 0 枚)
山6( 0 枚)
山7( 0 枚)
山8( 0 枚)
山9( 0 枚)
山10( 0 枚)
山11( 0 枚)
山12( 0 枚)

好きな数字(2〜12)3 <-----※
スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
ハート( 0 枚)
山1( 5 枚) 7  4  1  11  8  <-----※ここがおかしいのですか!?
山2( 4 枚) 5  2  12  9
山3( 4 枚) 6  3  13  10
山4( 0 枚)
山5( 0 枚)
山6( 0 枚)
山7( 0 枚)
山8( 0 枚)
山9( 0 枚)
山10( 0 枚)
山11( 0 枚)
山12( 0 枚)

右から 1 番目に最後のカードを置きました。

好きな山を選ぶ(1〜K)2
山 2 から回収したカード( 4 枚) 5  2  12  9
山 3 に重ねます。
スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
ハート( 0 枚)
山1( 5 枚) 7  4  1  11  8
山2( 0 枚)
山3( 8 枚) 5  2  12  9  6  3  13  10
山4( 0 枚)
山5( 0 枚)
山6( 0 枚)
山7( 0 枚)
山8( 0 枚)
山9( 0 枚)
山10( 0 枚)
山11( 0 枚)
山12( 0 枚)

山 3 から回収したカード( 8 枚) 5  2  12  9  6  3  13  10
山 4 に重ねます。
スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
ハート( 0 枚)
山1( 13 枚) 5  2  12  9  6  3  13  10  7  4  1  11  8
山2( 0 枚)
山3( 0 枚)
山4( 0 枚)
山5( 0 枚)
山6( 0 枚)
山7( 0 枚)
山8( 0 枚)
山9( 0 枚)
山10( 0 枚)
山11( 0 枚)
山12( 0 枚)

(回収したハートパケットを)数回カットする。
( 13 枚) 8  5  2  12  9  6  3  13  10  7  4  1  11
K(キング)を底へ移動させるために調整カットする。
( 13 枚) 10  7  4  1  11  8  5  2  12  9  6  3  13
スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
ハート( 13 枚) 10  7  4  1  11  8  5  2  12  9  6  3  13
山1( 0 枚)
山2( 0 枚)
山3( 0 枚)
山4( 0 枚)
山5( 0 枚)
山6( 0 枚)
山7( 0 枚)
山8( 0 枚)
山9( 0 枚)
山10( 0 枚)
山11( 0 枚)
山12( 0 枚)

 10 の位置に「1」のカードがくるように(スペードパケットを)カットする。
現在の位置 1
スペード( 12 枚) 4  5  6  7  8  9  10  11  12  1  2  3
ハート( 13 枚) 10  7  4  1  11  8  5  2  12  9  6  3  13
山1( 0 枚)
山2( 0 枚)
山3( 0 枚)
山4( 0 枚)
山5( 0 枚)
山6( 0 枚)
山7( 0 枚)
山8( 0 枚)
山9( 0 枚)
山10( 0 枚)
山11( 0 枚)
山12( 0 枚)

カードのマーク(S,H)?s
数字(1〜N)?5
S 2
 

新発見

 投稿者:GAI  投稿日:2008年11月 7日(金)23時35分17秒
返信・引用
  最初の段階の客の数字を5として、ハートとスペードのパケットの構成をしてみると
ハート:4,5,8,6,1,9,3,7,12,2,11,10
スペード:5,10,7,1,2,4,8,3,6,12,11,9
となります。(数字は左より裏向きで重ねたとき上からの順番です。)
ここで面白いことに気がつきました。
ハートのボトムにKを追加して、適当に数回カット後
客の数字を3として、3つの山に配り(パケットは表向きに持って配ることになる)
指定する山を2として、回収して、最後のカットでKをボトムに配置すると
ハート:2,3,6,4,11,7,1,5,10,12,9,8,13
Aの調整でスペードパケットのカット(Aを2枚目に持って来る)後は
スペード:7,1,2,4,8,3,6,12,11,9,5,10
の配列をなして、お互いインデックスが対応する。
しかし、
スペードの配列の最後にKを加え、同じ様に数度のカット後
3つの山をつくり、2の山から回収を始め一つにまとめ、Kをボトムでカットすると
スペード:12,8,1,5,11,3,2,10,9,6,4,7,13
これに合わせてハートパケットをAが12枚目になるようにカットしてやると
ハート:9,3,7,12,2,11,10,4,5,8,6,1
でこれはインデックスにはなんの関係も保存されていません。(不思議!!!)

すなわち、相互同値に見えて実はまったく異なる構造であることになります。
追加すべきはハートのKであり、このことが混乱している原因と思います。
 

Re: 点検

 投稿者:GAI  投稿日:2008年11月 8日(土)00時14分26秒
返信・引用
  > No.67[元記事へ]

山中和義さんへのお返事です。

> GAIさんへのお返事です。
>
> > 最初の段階の客の選んだ数を5
> > 後半での好きな数を3
>
>
> コメントは無効して、今掲載しているプログラムで実行してみました。
>  3050 CALL copy(cS,12, S) !!!!!移動先の調査 <-----ここ
>  3060 CALL copy(cS,12, H) !!!!! <-----ここ
>
> トレースのどこか具体的に指摘してください。
>
> <PRE>
> スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
> ハート( 12 枚) 27  28  29  30  31  32  33  34  35  36  37  38
> 山1( 0 枚)
> 山2( 0 枚)
> 捨て場( 0 枚)
>
> 好きな数字(1〜N)?5 <-----※
>
> スペード( 12 枚) 30  31  34  32  27  35  29  33  38  28  37  36
> ハート( 12 枚) 5  10  7  1  2  4  8  3  6  12  11  9
> 山1( 0 枚)
> 山2( 0 枚)              *ハートパケットの数字の並び
> 捨て場( 0 枚)                  4,5,8,6,1,9,3,7,12,2,11,10
>                                       ここではスペードの30,31,34,・・でトレース
> カードのマーク(S,H)?s <-----※    *スペードパケットの数字の並び
> 数字(1〜N)?3 <-----※         5,10,7,1,2,4,8,3,6,12,11,9
> S 3                                 ここではハートの列としてトレースされている
>
> (ハートパケットを)数回カットする。
> スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
> ハート( 13 枚) 8  9  10  11  12  13  1  2  3  4  5  6  7
> 山1( 0 枚)          *ここはカードが1,2,3,・・と順序よくなっていま
> 山2( 0 枚)           すが、さきのカードの順番で続きをやることに
> 山3( 0 枚)           なります。
> 山4( 0 枚)
> 山5( 0 枚)
> 山6( 0 枚)
> 山7( 0 枚)
> 山8( 0 枚)
> 山9( 0 枚)
> 山10( 0 枚)
> 山11( 0 枚)
> 山12( 0 枚)
>
> 好きな数字(2〜12)3 <-----※
> スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
> ハート( 0 枚)
> 山1( 5 枚) 7  4  1  11  8  <-----※ここがおかしいのですか!?
> 山2( 4 枚) 5  2  12  9     表向きで配りますから、山1,2,3には
> 山3( 4 枚) 6  3  13  10     7,6,5,・・・とカードが入ると思います。
> 山4( 0 枚)
> 山5( 0 枚)
> 山6( 0 枚)
> 山7( 0 枚)
> 山8( 0 枚)
> 山9( 0 枚)
> 山10( 0 枚)
> 山11( 0 枚)
> 山12( 0 枚)
>
> 右から 1 番目に最後のカードを置きました。
>
> 好きな山を選ぶ(1〜K)2
> 山 2 から回収したカード( 4 枚) 5  2  12  9
> 山 3 に重ねます。
> スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
> ハート( 0 枚)
> 山1( 5 枚) 7  4  1  11  8
> 山2( 0 枚)
> 山3( 8 枚) 5  2  12  9  6  3  13  10   *山を上に重ねますからここは
> 山4( 0 枚)                6,3,13,10,5,2,12,9
> 山5( 0 枚)                                 の順序になると思います。
> 山6( 0 枚)
> 山7( 0 枚)
> 山8( 0 枚)
> 山9( 0 枚)
> 山10( 0 枚)
> 山11( 0 枚)
> 山12( 0 枚)
>
> 山 3 から回収したカード( 8 枚) 5  2  12  9  6  3  13  10
> 山 4 に重ねます。
> スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
> ハート( 0 枚)
> 山1( 13 枚) 5  2  12  9  6  3  13  10  7  4  1  11  8  *同様にここもそうです
> 山2( 0 枚)
> 山3( 0 枚)
> 山4( 0 枚)
> 山5( 0 枚)
> 山6( 0 枚)
> 山7( 0 枚)
> 山8( 0 枚)
> 山9( 0 枚)
> 山10( 0 枚)
> 山11( 0 枚)
> 山12( 0 枚)
>
> (回収したハートパケットを)数回カットする。
> ( 13 枚) 8  5  2  12  9  6  3  13  10  7  4  1  11
> K(キング)を底へ移動させるために調整カットする。
> ( 13 枚) 10  7  4  1  11  8  5  2  12  9  6  3  13
> スペード( 12 枚) 1  2  3  4  5  6  7  8  9  10  11  12
> ハート( 13 枚) 10  7  4  1  11  8  5  2  12  9  6  3  13
> 山1( 0 枚)
> 山2( 0 枚)
> 山3( 0 枚)
> 山4( 0 枚)
> 山5( 0 枚)
> 山6( 0 枚)
> 山7( 0 枚)
> 山8( 0 枚)
> 山9( 0 枚)
> 山10( 0 枚)
> 山11( 0 枚)
> 山12( 0 枚)
>
>  10 の位置に「1」のカードがくるように(スペードパケットを)カットする。
> 現在の位置 1
> スペード( 12 枚) 4  5  6  7  8  9  10  11  12  1  2  3
> ハート( 13 枚) 10  7  4  1  11  8  5  2  12  9  6  3  13
> 山1( 0 枚)
> 山2( 0 枚)
> 山3( 0 枚)
> 山4( 0 枚)
> 山5( 0 枚)
> 山6( 0 枚)
> 山7( 0 枚)
> 山8( 0 枚)
> 山9( 0 枚)
> 山10( 0 枚)
> 山11( 0 枚)
> 山12( 0 枚)
>
> カードのマーク(S,H)?s
> 数字(1〜N)?5
> S 2
> </PRE>
 

Re: 点検

 投稿者:山中和義  投稿日:2008年11月 8日(土)08時04分0秒
返信・引用
  > No.69[元記事へ]

GAIさんへのお返事です。

お手数おかけしました。ありがとうございます。
 

Re: 新発見

 投稿者:山中和義  投稿日:2008年11月 8日(土)11時49分44秒
返信・引用  編集済
  > No.68[元記事へ]

GAIさんへのお返事です。

ハートのK(キング)によるシャッフルをすべて調べて見ました。
すべて関係性は保たれるようです。

結果から「13でのシャッフル」と「そのカット」(そう呼ぶことにします)の関係性は
確認できますが、数理的にはうまく説明できません。(合同式かな?)

またスペードの方も確認はできます。

!置換(Permutation)の計算
!※技術メモ
! A=┌ 1 2 3 4 ┐=(1 2 4 3) ※1行目の順番は固定とする
!  └ 2 4 1 3 ┘
!の場合、
! DATA 2,4,1,3 !配列変数の「添え字と値」に対応させる
! MAT READ A
!とプログラムでは記述する。

SUB PermPrintOut(A()) !表示する ※標準形(2行n列の行列表記する)
   MAT PRINT USING(REPEAT$(" ##",UBOUND(A))): A;
   PRINT
END SUB
SUB PermIdentity(A()) !恒等置換
   FOR i=1 TO UBOUND(A)
      LET  A(i)=i
   NEXT i
END SUB
SUB PermInverse(A(), iA()) !逆置換 ※iAはA以外の配列を指定すること
   FOR i=1 TO UBOUND(A)
      LET  iA(A(i))=i
   NEXT i
END SUB
SUB PermMultiply(A(),B(), AB()) !積AB ※ABはAかつB以外の配列を指定すること
   LET  ua=UBOUND(A)
   LET  ub=UBOUND(B)
   IF ua=ub THEN
      FOR i=1 TO ua
         LET  AB(i)=A(B(i)) !※合成写像(AB)(i)=A(B(i))
      NEXT i
   ELSE
      PRINT "次元が違います。A=";ua;" B=";ub
      STOP
   END IF
END SUB

SUB PermReverse(A()) !並び順を反転させる
   LET  ua=UBOUND(A)
   FOR i=1 TO INT(ua/2)
      swap A(i),A(ua-i+1)
   NEXT i
END SUB
!-------------------- ここまでがサブルーチン



!main

LET N=12 !※固定

DIM cc(N)
SUB check(SS(),HH()) !参照を確認する ※共に連番で表示されればOK
   PRINT "check!"
   CALL PermMultiply(HH,SS,cc) !AB=BA=I ※恒等置換
   CALL PermPrintOut(cc)

   CALL PermMultiply(SS,HH,cc)
   CALL PermPrintOut(cc)
END SUB


DIM Rev(N) !反転に相当する置換
CALL PermIdentity(Rev)
CALL PermReverse(Rev)

DIM shuffle(N) !リフルシャッフルに相当する置換
DATA 2,4,6,8,10,12,1,3,5,7,9,11
MAT READ shuffle


DIM H(N),S(N) !ハート、スペードの束

FOR R1=1 TO N !前半のマジックでの「好きな数」

   PRINT "----- Request";R1;"の場合-----"

   !●スペードをシャッフルする
   DIM B(N),c(N)
   CALL PermIdentity(B) !初期値
   FOR k=1 TO 12 !回数 ※何回か実行すると元に戻る
      LET S(k)=B(R1)
      CALL PermMultiply(B,shuffle,c)
      MAT B=c
   NEXT k
   CALL PermInverse(S,H) !SH=HS=Iより

   DIM RH(N)
   CALL PermMultiply(H,Rev,RH) !ハートをK(キング)でシャッフルする場合
   !!!CALL PermMultiply(S,Rev,RH) !スペードをK(キング)でシャッフルする場合
   !!!MAT S=H


   FOR R2=1 TO N
      PRINT "表";R2;"の場合"

      !●ハートをシャッフルする
      DIM M(N) !後半のマジックでの「好きな数」「山の選択」
      MAT M=ZER
      FOR i=1 TO R2 !R番目
         FOR k=1 TO 12
            LET M(k)=MOD(M(k)+k,13)
         NEXT k
      NEXT i
      !※「山の選択」は、13を底に移動させる調整カットで無効になるので、このいずれかになる。

      DIM c1(N)
      CALL PermMultiply(RH,M,c1)
      CALL PermPrintOut(c1)

      !●スペードをカットする
      LET KEY2=c1(1) !移動先
      FOR x=1 TO N !現在位置を探す
         IF S(x)=1 THEN EXIT FOR
      NEXT x
      PRINT x;"から";KEY2;"へ"
      DIM cut(N) !カットに相当する置換
      FOR i=1 TO N
         LET cut(i)=MOD(i+(x-KEY2)-1,12)+1
      NEXT i
      !!!MAT PRINT cut;
      DIM c2(N)
      CALL PermMultiply(S,cut,c2)
      CALL PermPrintOut(c2)

      CALL check(c1,c2)
   NEXT R2

NEXT R1

END



!-----前半のマジックでの「好きな数」が 1 の場合のシャッフル結果-----
!DATA 1, 2, 5, 3,10, 6,12, 4, 9,11, 8, 7 !ハート
!DATA 1, 2, 4, 8, 3, 6,12,11, 9, 5,10, 7 !スペード
!----- 2 の場合-----
!DATA 12, 1, 4, 2, 9, 5,11, 3, 8,10, 7, 6
!DATA  2, 4, 8, 3, 6,12,11, 9, 5,10, 7, 1
!----- 3 の場合-----
!DATA 9,10, 1,11, 6, 2, 8,12, 5, 7, 4, 3
!DATA 3, 6,12,11, 9, 5,10, 7, 1, 2, 4, 8
!----- 4 の場合-----
!DATA 11,12, 3, 1, 8, 4,10, 2, 7, 9, 6, 5
!DATA  4, 8, 3, 6,12,11, 9, 5,10, 7, 1, 2
!----- 5 の場合-----
!DATA 4, 5, 8, 6, 1, 9, 3, 7,12, 2,11,10 !※代替として混ざられる位置
!DATA 5,10, 7, 1, 2, 4, 8, 3, 6,12,11, 9 !※捨て場へ移される順
!----- 6 の場合-----
!DATA 8, 9,12,10, 5, 1, 7,11, 4, 6, 3, 2
!DATA 6,12,11, 9, 5,10, 7, 1, 2, 4, 8, 3
!----- 7 の場合-----
!DATA 2, 3, 6, 4,11, 7, 1, 5,10,12, 9, 8
!DATA 7, 1, 2, 4, 8, 3, 6,12,11, 9, 5,10
!----- 8 の場合-----
!DATA 10,11, 2,12, 7, 3, 9, 1, 6, 8, 5, 4
!DATA  8, 3, 6,12,11, 9, 5,10, 7, 1, 2, 4
!----- 9 の場合-----
!DATA 5, 6, 9, 7, 2,10, 4, 8, 1, 3, 12,11
!DATA 9, 5,10, 7, 1, 2, 4, 8, 3, 6, 12,11
!----- 10 の場合-----
!DATA  3, 4, 7, 5,12, 8, 2, 6,11, 1,10, 9
!DATA 10, 7, 1, 2, 4, 8, 3, 6,12,11, 9, 5
!----- 11 の場合-----
!DATA  6, 7,10, 8, 3,11, 5, 9, 2, 4, 1,12
!DATA 11, 9, 5,10, 7, 1, 2, 4, 8, 3, 6,12
!----- 12 の場合-----
!DATA  7, 8,11, 9, 4,12, 6,10, 3, 5, 2, 1
!DATA 12,11, 9, 5,10, 7, 1, 2, 4, 8, 3, 6




!後半のマジックでのシャッフルに相当する置換
!DATA  1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12 !「13でのシャッフル」
!DATA  2, 4, 6, 8,10,12, 1, 3, 5, 7, 9,11
!DATA  3, 6, 9,12, 2, 5, 8,11, 1, 4, 7,10
!DATA  4, 8,12, 3, 7,11, 2, 6,10, 1, 5, 9
!DATA  5,10, 2, 7,12, 4, 9, 1, 6,11, 3, 8
!DATA  6,12, 5,11, 4,10, 3, 9, 2, 8, 1, 7
!DATA  7, 1, 8, 2, 9, 3,10, 4,11, 5,12, 6
!DATA  8, 3,11, 6, 1, 9, 4,12, 7, 2,10, 5
!DATA  9, 5, 1,10, 6, 2,11, 7, 3,12, 8, 4
!DATA 10, 7, 4, 1,11, 8, 5, 2,12, 9, 6, 3
!DATA 11, 9, 7, 5, 3, 1,12,10, 8, 6, 4, 2
!DATA 12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1

 

Re: 新発見

 投稿者:GAI  投稿日:2008年11月 8日(土)12時24分29秒
返信・引用
  > No.71[元記事へ]

山中和義さんへのお返事です。


 確認作業御疲れさんでした。

> またスペードの方も確認はできます。   *エー!!スペードでも可能ですか?
>
>
>
> !置換(Permutation)の計算
> !※技術メモ
> ! A=┌ 1 2 3 4 ┐=(1 2 4 3) ※1行目の順番は固定とする
> !  └ 2 4 1 3 ┘
> !の場合、
> ! DATA 2,4,1,3 !配列変数の「添え字と値」に対応させる
> ! MAT READ A
> !とプログラムでは記述する。
>
> SUB PermPrintOut(A()) !表示する ※標準形(2行n列の行列表記する)
>    MAT PRINT USING(REPEAT$(" ##",UBOUND(A))): A;
> END SUB
>
> SUB PermMultiply(A(),B(), AB()) !積AB ※AB≠BA、A(BC)=(AB)C
>    LET  ua=UBOUND(A)
>    LET  ub=UBOUND(B)
>    IF ua=ub THEN
>       FOR i=1 TO ua
>          LET  AB(i)=A(B(i)) !※合成写像(AB)(i)=A(B(i))
>       NEXT i
>    ELSE
>       PRINT "次元が違います。A=";ua;" B=";ub
>       STOP
>    END IF
> END SUB
> !-------------------- ここまでがサブルーチン
>
>
>
> !main
>
> LET N=12 !※固定
>
> DIM TT(N)
> SUB cut(C(),p) !カットする ※p位置以降が上になる
>    FOR i=1 TO p-1 !前半部分を後へ
>       LET TT(N+i-p+1)=C(i)
>    NEXT i
>    FOR i=p TO N !後半部分を前へ
>       LET TT(i-p+1)=C(i)
>    NEXT i
>    FOR i=1 TO N !copy it
>       LET C(i)=TT(i)
>    NEXT i
> END SUB
>
>
> !----- 前半のマジックでの「好きな数」が 1 の場合-----
> DATA 1, 2, 5, 3,10, 6,12, 4, 9,11, 8, 7 !ハート
> DATA 1, 2, 4, 8, 3, 6,12,11, 9, 5,10, 7 !スペード
>
> !----- 2 の場合-----
> DATA 12, 1, 4, 2, 9, 5,11, 3, 8,10, 7, 6
> DATA  2, 4, 8, 3, 6,12,11, 9, 5,10, 7, 1
>
> !----- 3 の場合-----
> DATA 9,10, 1,11, 6, 2, 8,12, 5, 7, 4, 3
> DATA 3, 6,12,11, 9, 5,10, 7, 1, 2, 4, 8
>
> !----- 4 の場合-----
> DATA 11,12, 3, 1, 8, 4,10, 2, 7, 9, 6, 5
> DATA  4, 8, 3, 6,12,11, 9, 5,10, 7, 1, 2
>
> !----- 5 の場合-----
> DATA 4, 5, 8, 6, 1, 9, 3, 7,12, 2,11,10 !※代替として混ざられるスペードパケットの位置
> DATA 5,10, 7, 1, 2, 4, 8, 3, 6,12,11, 9 !※捨て場へ移される順
>
> !----- 6 の場合-----
> DATA 8, 9,12,10, 5, 1, 7,11, 4, 6, 3, 2
> DATA 6,12,11, 9, 5,10, 7, 1, 2, 4, 8, 3
>
> !----- 7 の場合-----
> DATA 2, 3, 6, 4,11, 7, 1, 5,10,12, 9, 8
> DATA 7, 1, 2, 4, 8, 3, 6,12,11, 9, 5,10
>
> !----- 8 の場合-----
> DATA 10,11, 2,12, 7, 3, 9, 1, 6, 8, 5, 4
> DATA  8, 3, 6,12,11, 9, 5,10, 7, 1, 2, 4
>
> !----- 9 の場合-----
> DATA 5, 6, 9, 7, 2,10, 4, 8, 1, 3, 12,11
> DATA 9, 5,10, 7, 1, 2, 4, 8, 3, 6, 12,11
>
> !----- 10 の場合-----
> DATA  3, 4, 7, 5,12, 8, 2, 6,11, 1,10, 9
> DATA 10, 7, 1, 2, 4, 8, 3, 6,12,11, 9, 5
>
> !----- 11 の場合-----
> DATA  6, 7,10, 8, 3,11, 5, 9, 2, 4, 1,12
> DATA 11, 9, 5,10, 7, 1, 2, 4, 8, 3, 6,12
>
> !----- 12 の場合-----
> DATA  7, 8,11, 9, 4,12, 6,10, 3, 5, 2, 1
> DATA 12,11, 9, 5,10, 7, 1, 2, 4, 8, 3, 6
>


この前半のパターンの表はなんとか手にしました。

後半の完成されたプログラムの全体が見たいです。
例のカードシュミレーションの(前半も含む)リストを送ってください。
 

質問

 投稿者:GAI  投稿日:2008年11月 8日(土)15時32分9秒
返信・引用
  > No.71[元記事へ]

山中和義さんへのお返事です。


request2での表2の場合の最終パケットの配列が
トランプで実験してみると(左より裏向きにした場合に上から並ぶ順で読む。)
ハ ー ト:7,8,11,9,4,12,6,10,3,5,2,1,(13)
スペード:12,11,9,5,10,7,1,2,4,8,3,6
であったのに対し
置換のプログラムで表示された結果の表では
ハ ー ト:1,2,5,3,10,6,12,4,9,11,8,7,(13)
スペード:2,4,8,3,6,12,11,9,5,10,7,1
となりました。
でもチェックではOKで合ってはいるのですが・・・

他にも
request5,
表5の場合で
実験では
ハ ー ト:7,8,11,9,4,12,6,10,3,5,2,1,(13)
スペード:12,11,9,5,10,7,1,2,4,8,3,6
出力の表では
----- Request 5 の場合-----

表 4 の場合
  6  7 10  8  3 11  5  9  2  4  1 12
11  9  5 10  7  1  2  4  8  3  6 12
check!
1  2  3  4  5  6  7  8  9  10  11  12
1  2  3  4  5  6  7  8  9  10  11  12
表 5 の場合
  1  2  5  3 10  6 12  4  9 11  8  7  (ハート列)
  1  2  4  8  3  6 12 11  9  5 10  7  (スペード列)
check!
1  2  3  4  5  6  7  8  9  10  11  12
1  2  3  4  5  6  7  8  9  10  11  12

と最終結果と微妙にずれています。
 

Re: 質問

 投稿者:山中和義  投稿日:2008年11月 8日(土)17時27分15秒
返信・引用
  > No.73[元記事へ]

GAIさんへのお返事です。


> request2での表2の場合の最終パケットの配列が
> トランプで実験してみると(左より裏向きにした場合に上から並ぶ順で読む。)
> ハ ー ト:7,8,11,9,4,12,6,10,3,5,2,1,(13)
> スペード:12,11,9,5,10,7,1,2,4,8,3,6
> であったのに対し
> 置換のプログラムで表示された結果の表では
> ハ ー ト:1,2,5,3,10,6,12,4,9,11,8,7,(13)
> スペード:2,4,8,3,6,12,11,9,5,10,7,1
> となりました。

失礼しました。ここでも並び順の判断ミスでした。
プログラムを修正しておきました。
 

Re: 新発見

 投稿者:山中和義  投稿日:2008年11月 9日(日)11時52分0秒
返信・引用  編集済
  > No.72[元記事へ]

GAIさんへのお返事です。

> 後半の完成されたプログラムの全体が見たいです。
> 例のカードシュミレーションの(前半も含む)リストを送ってください。

遅くなりました。
現状のプログラムはここからダウンロードしてください。

また数理的な説明としては、置換で表現(プログラム No.71記事)したことをもって代えさせていただきます。

数学的に1つのことを、たとえば
手の中でシャッフルしたり、場でシャッフルしたり
目先を変えてあたかも違ったことやっているように見せるのがマジックの1つの常套手段ですね。
 

お礼

 投稿者:GAI  投稿日:2008年11月 9日(日)13時12分40秒
返信・引用
  すごい!
トランプをいちいち操作することなく、現象を追跡できるなんて・・・
こんなに自由にコンピューターを使いこなせたら楽しいだろうなー(私も頑張ろう!)
ひょんな質問からここまでプログラムを組んでくれたことに感謝いたします。
このソフトは私の宝物になります。
いろいろな質問にお答え頂き、誠にありがとうございました。
 

質問です・・・

 投稿者:NINA  投稿日:2008年11月 9日(日)22時54分19秒
返信・引用
  大学の数学の課題で、

「1,2,3,…,n の順に並んでいる数列のなかで、“+”と“=”を入れて式を完成させよ。」

というような、課題がでました。問題の答えの例としては

1+2=3
1+2+3+…+14=15+16+17+…+20 (=105)

という様な感じです。


これを十進BASICで1,000,000桁までくらいの等式をつくれ ということ言われ、やってみたのですが、
BASICを使うのは初めてなので、どんな風にプログラムを作ればいいのかわかりません。

どなたかご指導いただければと思い、投稿させていただきました。
わかるかた、ぜひよろしくお願いします!!
 

Re: 質問です・・・

 投稿者:荒田浩二  投稿日:2008年11月10日(月)14時45分25秒
返信・引用  編集済
  > No.77[元記事へ]

NINAさんへのお返事です。

まず、1,000,000桁ではなくn=1,000,000までの間違いですよね。

等式

  1+2+…+(k-1)+k=(k+1)+(k+2)+…+(n-1)+n

を、次のようにnについての2次方程式と考えれば

  (k^2+k)/2=(n^2+n)/2-(k^2+k)/2

nが整数解を持てば等式は成り立ちます。

  FOR k=1 TO 1000000 〜 NEXT k

として、nが整数解を持つか調べればよいのでは。
(1,000,000までに8個ありました)
 

Re: 質問です・・・

 投稿者:NINA  投稿日:2008年11月10日(月)23時39分46秒
返信・引用
  > No.78[元記事へ]

荒田浩二さんへのお返事です。



> NINAさんへのお返事です。
>
> まず、1,000,000桁ではなくn=1,000,000までの間違いですよね。

そうでした。ご指摘ありがとうございます。


> 等式
>
>   1+2+…+(k-1)+k=(k+1)+(k+2)+…+(n-1)+n
>
> を、次のようにnについての2次方程式と考えれば
>
>   (k^2+k)/2=(n^2+n)/2-(k^2+k)/2
>
> nが整数解を持てば等式は成り立ちます。
>
>   FOR k=1 TO 1000000 〜 NEXT k
>
> として、nが整数解を持つか調べればよいのでは。
> (1,000,000までに8個ありました)


とてもわかりやすい解説ありがとうございました!求め方、式の書き方は理解できました。

さっそくやってみたのですが、 (k^2+k)/2=(n^2+n)/2-(k^2+k)/2 と打ったところ、エラーの表示がでてしまいました。
そのまま入力したのがいけなかったのでしょうか??

また、整数解をもつか調べるのはIF文で良いのでしょうか??

教えていただけますでしょうか??
 

Re: 質問です・・・

 投稿者:山中和義  投稿日:2008年11月11日(火)11時10分6秒
返信・引用  編集済
  > No.77[元記事へ]

NINAさんへのお返事です。

> 大学の数学の課題で、
> 「1,2,3,…,n の順に並んでいる数列のなかで、“+”と“=”を入れて式を完成させよ。」

別解を紹介しておきます。

●解き方
たとえばN=10の場合、1○2○3○4○5○6○7○8○9○10 と数列ができる。
○(演算記号=を入る場所)の数は、10-1=9個あるから場所の可能性は1〜9である。

次に条件を満たす判断方法は、たとえば、3番目とすると
 1○2○3=4○5○6○7○8○9○10
となるから、=で元の数列は「左辺」と「右辺」に2分割される。
したがって、1○2○3 と 4○5○6○7○8○9○10 の2つの等差数列の和を求めて「左辺=右辺」で判断すればよい。
ここでは左辺と右辺の和を求めるのではなく「左辺が全体の和の半分に等しい」ということで条件を満たすと判断する。
Σk=n*(n+2)/2の公式を使ってそれぞれ求める。

ここで、S1=1、S2=1+2、S3=1+2+3、… 、Sn=1+2+3+ … +n、すなわちデータ列{Sn}を考える。
これは左辺の和が順に並んだものである。
したがって、「左辺が全体の和の半分に等しい」は
 この1〜n個のデータ列から、Sn/2の値を見つける「探索」の問題
に置き換えることができる。
逐次探索すると毎回の走査が必要で時間がかかる。
S1,S2,…,Snは整列された(小さい順)データ列だから、2分探索が可能である。

●「基本アルゴリズムの課題」としてのサンプル
!OPTION ARITHMETIC decimal_high

LET t0=TIME

DIM S(1000000) !S1,S2,…,Sn
LET S(1)=1
FOR k=2 TO 1000000
   LET S(k)=S(k-1)+k !左辺 1+ … +(k-1)+k の値
NEXT k


LET c=0 !個数
FOR n=1 TO 1000000

   LET key=S(n)/2 !「全体の半分の値」を見つける

   LET L=1 !下限
   LET H=n !上限
   DO WHILE L<=H !逆転したら終了
      LET M=INT((L+H)/2) !中央
      IF S(M)<=key THEN LET L=M+1 !絞り込む
      IF S(M)>=key THEN LET H=M-1
   LOOP
   !!!PRINT n;L;H

   IF L=H+2 THEN !見つかったら
      LET c=c+1
      PRINT c;"個目"

      PRINT "1 + … +";M;"=";M+1; !左辺と=
      IF M<n-1 THEN !整形のため
         PRINT "+ … +";n; !右辺
      END IF
      PRINT "(=";S(M);")" !和
   END IF

NEXT n


PRINT "計算時間=";TIME-t0

END

(実行結果)
 1 個目
1 + … + 2 = 3 (= 3 )
 2 個目
1 + … + 14 = 15 + … + 20 (= 105 )
 3 個目
1 + … + 84 = 85 + … + 119 (= 3570 )
 4 個目
1 + … + 492 = 493 + … + 696 (= 121278 )
 5 個目
1 + … + 2870 = 2871 + … + 4059 (= 4119885 )
 6 個目
1 + … + 16730 = 16731 + … + 23660 (= 139954815 )
 7 個目
1 + … + 97512 = 97513 + … + 137903 (= 4754343828 )
 8 個目
1 + … + 568344 = 568345 + … + 803760 (= 161507735340 )


●「2次方程式を解く」の別解としてのサンプル
FOR k=1 TO 1000000
 nについての2次方程式 n^2+n-2*(k^2+k)=0 を解いて正の整数解を得る
NEXT k
これは、数列{Sk,Sk+1,…}の中から、2*Skを探すことです。
無限個の中を探索できないので、(実際は小さい順に整列しているので途中で中止する)

 Sk,Sk+1,…,Sn-1,Sn,Sn+1,…
         ↑
         2*Sk?
この矢印のの位置を2次方程式を解くことで推定している。


実際どこにデータがあるかは、S=Σk=n*(n+2)/2よりSQR(S)の位置と推定されるので、
上記サンプル同様に数列{S1,S2,…,Sn}でSn/2を探すアプローチは以下のようになる。
!OPTION ARITHMETIC decimal_high

LET t0=TIME


LET c=0 !個数
FOR N=2 TO 1000000

   LET S=N*(N+1)/2 !全部の和

   LET a=INT(SQR(S)) !=が入る箇所の可能性
   FOR k=a TO a+1
      LET L=k*(k+1)/2 !左辺の和

      IF 2*L=S THEN !2*左辺=全部の和なら、条件をみたす
         LET c=c+1
         PRINT c;"個目"

         PRINT "1 + … +";k;"="; !左辺と=
         IF i=N-1 THEN !整形のため
            PRINT k+1;"(=";L;")" !右辺と和
         ELSE
            PRINT k+1;"+ … +";N;"(=";L;")"
         END IF
      END IF
   NEXT k

NEXT N


PRINT "計算時間=";TIME-t0

END
 

Re: 質問です・・・

 投稿者:荒田浩二  投稿日:2008年11月11日(火)18時32分18秒
返信・引用  編集済
  > No.79[元記事へ]

NINAさんへのお返事です。


> さっそくやってみたのですが、 (k^2+k)/2=(n^2+n)/2-(k^2+k)/2 と打ったところ、エラーの表示がでてしまいました。


 BASICでは、等号は変数に数値を与えるときに使います(代入文)。

たとえば「LET a=b+3」という文は、変数aに数値式b+3の値を代入するという意味です。(変数bが4ならばaの値は7になります)

左辺は一つの変数でなければいけません。「LET b+3=a」と記述すると文法エラーになります。
(十進BASICのヘルプの[入門][変数][let文]を参照して下さい)


  また、BASICは式の変形や方程式を解くといった数式処理には対応していません。
その部分は自分で解くか、解くためのプログラムを作らなければなりません。

前出の問題で言えば、

  (k^2+k)/2=(n^2+n)/2-(k^2+k)/2

を下のように変形することはBASICはしてくれません。

  n^2+n-2*(k^2+k)=0

この解を求めるのも、そのためのプログラムを作る必要があります。


 下は、2次方程式 a*x^2+b*x+c=0 の解の一つを求め整数性を判定するプログラムです。参考にしてください。

  10 LET a=1
  20 LET b=3
  30 LET c=-4
  40 LET D=b^2-4*a*c  ! 判別式
  50 LET x=(-b+SQR(D))/(2*a)  ! 解の公式
  60 PRINT x
  70 IF INT(x)=x THEN PRINT "整数"
  80 END

*70行のIF文で整数の判定をしています。(IF文での等号は両辺が等しいかの判定に使われるので左辺が変数である必要はありません)
*INT(x)やSQR(D)は組込み関数です。(ヘルプ[数値][組込み関数][数値関数]参照)
*40行と50行の「!」は注釈記号です。この記号以降は何を書いてもプログラムの実行に影響を与えません。
 

確認

 投稿者:小塚貞典  投稿日:2008年11月12日(水)14時25分6秒
返信・引用
  GMO(グローバルメデイアオンライン)は外税です。  

Re: 質問です・・・

 投稿者:山中和義  投稿日:2008年11月13日(木)15時53分38秒
返信・引用  編集済
  > No.77[元記事へ]

NINAさんへのお返事です。

> 大学の数学の課題で、
>
> 「1,2,3,…,nの順に並んでいる数列のなかで、“+”と“=”を入れて式を完成させよ。」

データ列の処理として、もう1つ別解を紹介しておきます。


●「基本アルゴリズムの課題」としてのサンプル(その2)

方程式 n*(n+1)/2=2*k*(k+1)/2 より
2つの数列
 数列 S1={1,3,6,10,15,21,…,n*(n+1)/2,…}、n=1〜1000000
 数列 S2={2,6,12,20,30,42,…,2*k*(k+1)/2,…}、k=1〜1000000-1
を考える。
この2つの数列(データ列)は小さい順に整列されているので、
1つの整列されたデータ列に併合(マージ)することに着目する。
!OPTION ARITHMETIC decimal_high

LET t0=TIME

LET a=1000000

LET n=1 !先頭から
LET k=1

LET c=0 !個数
DO UNTIL n>a OR k>a-1 !どちらかのデータ列が終わるまで
   LET s1=n*(n+1)/2 !データ列を得る
   LET s2=2*k*(k+1)/2

   IF s1=s2 THEN !マージする
      LET c=c+1
      PRINT c;"個目"

      PRINT "1 + … +";k;"=";k+1; !左辺と=
      IF k<n-1 THEN !整形のため
         PRINT "+ … +";n; !右辺
      END IF
      PRINT "(=";s1/2;")" !和

      LET k=k+1
      LET n=n+1
   ELSEIF s1>s2 THEN
      LET k=k+1
   ELSE
      LET n=n+1
   END IF
LOOP

PRINT "計算時間=";TIME-t0

END

 

疑問

 投稿者:GAI  投稿日:2008年11月16日(日)07時09分52秒
返信・引用
  1から3を   1 3
         2
と配列すれば、上の段の2数の差が(ただし大きい方から小さい方を引く。3−1)
下の数となる。
この規則を敷衍し
1から6までの数字を一度だけ使用して
       ● ● ●
        ● ●
         ●
の位置に入れたい。
試行錯誤の後、6 2 5
        4 3
         1
なる配列が(もちろん他のパターンも存在すると思う。)求められる。
しかし、
次からが人間には限界が出てきて、
では、1〜10の数字を一度だけ使用して
      ● ● ● ●
       ● ● ●
        ● ●
         ●
の配列を構成
さらに、1〜15の数字で
     ● ● ● ● ●
      ● ● ● ●
       ● ● ●
        ● ●
         ●
1〜21で
    ● ● ● ● ● ●
     ● ● ● ● ●
      ● ● ● ●
       ● ● ●
        ● ●
         ●
・・・・
・・・・
は構成可能なのだろうか?
この問題を解決してもらいたい。
 

Re: 疑問

 投稿者:荒田浩二  投稿日:2008年11月16日(日)12時05分29秒
返信・引用
  > No.84[元記事へ]

GAIさんへのお返事です。

n=10では存在しました。

  9  10   3   8
    1   7   5
      6   2
        4

次のプログラムで発見しましたが、少し工夫すれば全数調査も可能ではないかと思います。

LET k=4  ! 4行
LET n=k*(k+1)/2  ! n=10
DIM a(k,k),check(n)
FOR maxn=1 TO CEIL(k/2)
   FOR r=1 TO n^(n/2)
      MAT check=ZER
      LET a(1,maxn)=n
      LET check(n)=1
      FOR i=1 TO k
         FOR j=1 TO k+1-i
            IF NOT (i=1 AND j=maxn) THEN
               DO
                  LET num=INT((n-1)*RND)+1
               LOOP UNTIL check(num)=0
               LET a(i,j)=num
               LET check(num)=1
            END IF
         NEXT j
      NEXT i
      !MAT PRINT a
      CALL diff
      IF p=0 THEN MAT PRINT a
      LET p=0
   NEXT r
NEXT maxn
SUB diff
   FOR i=1 TO k-1
      FOR j=1 TO k-i
         IF ABS(a(i,j)-a(i,j+1))<>a(i+1,j) THEN
            LET p=1
            EXIT SUB
         END IF
      NEXT j
   NEXT i
END SUB
END
 

助けて下さい。

 投稿者:GAI  投稿日:2008年11月16日(日)20時54分54秒
返信・引用
  早速リストをコピーして動かしてみたら、OKでした。
k=5 でやっていますが、朝から動かしていますがまだ終わりません。(12時間近く。)
せめて、1時間位で調査できないものでしょうか?
どこをどう改良したらよいのか・・・、誰か助け舟が欲しい!!!
 

Re: 助けて下さい。

 投稿者:荒田浩二  投稿日:2008年11月16日(日)22時07分56秒
返信・引用  編集済
  > No.86[元記事へ]

GAIさんへのお返事です。


ごめんなさい。
あれは20分くらいで取り合えず作ったもので、作りながらも「無駄が多い」と考えてはいました。
ランダム調査で試行回数がCEIL(k/2)*SQR(n^n)ですから、n=15ではなかなか終わらないと思います。

さっそく改良版を作ります。
明日までにはできるかと思います。
 

Re: 疑問

 投稿者:山中和義  投稿日:2008年11月17日(月)09時14分59秒
返信・引用
  > No.84[元記事へ]

GAIさんへのお返事です。

●サンプル その1
前回紹介したバックトラック法による総当りです。
K段の場合、K*(K+1)/2の階乗になります。(K=5、15!=1,307,674,368,000)

この手のパズルはバックトラック法で解けます(時間はかかる)ので、ぜひマスターしてみてください。
PUBLIC NUMERIC ANSWER_COUNT !解答数
LET ANSWER_COUNT=0

LET K=5 !段数 ※1〜

LET N=K*(K+1)/2 !1〜Kまでの数字
DIM A(N)
MAT A=ZER

LET t0=TIME
PRINT K;"段"
PRINT "1 〜";N;"までの数字"
CALL backtrack(1,K,N,A)
IF ANSWER_COUNT=0 THEN PRINT "解なし"
PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB backtrack(p,K,N,A())
FOR nm=1 TO N
   LET A(p)=nm !仮に設定してみる

   CALL checkrule(p,nm,N,A, rc) !条件を満たすなら
   IF rc=1 THEN

      IF p=N THEN !すべて埋まったら
         LET ANSWER_COUNT=ANSWER_COUNT+1
         PRINT ANSWER_COUNT;"個目"

         FOR i=K TO 1 STEP -1 !上段から
            PRINT REPEAT$(" ",K-i); !右へシフト
            FOR j=1 TO i !この段の数字の数
               PRINT USING "###": A((i-1)*i/2+j);
            NEXT j
            PRINT
         NEXT i
         !!!MAT PRINT A;

      ELSE
         CALL backtrack(p+1,K,N,A) !次へ

      END IF

   END IF
   LET A(p)=0 !元に戻す
NEXT nm
END SUB


EXTERNAL SUB checkrule(p,nm,N,M() ,rc) !条件が満たすかどうか確認する
LET rc=0

!●数字は重複していないか?
FOR i=1 TO p-1
   IF nm=M(i) THEN EXIT SUB !見つかったのでNG!
NEXT i

!●上段の2数の差?
!M(p)の添え字番号と配置
!11 12 …   5段目 s=11
! 7 8 9 10  4段目 s=7
!  4 5 6   3段目 s=4
!  2 3    2段目 s=2
!   1    1段目 s=1
!
!M(p-1) M(p)  x段目
!  M(p-x)

LET a=1/2 !段数を得る ※xの2次方程式(x-1)*x/2+1-p=0の解
LET b=-1/2
LET c=1-p
LET D=b^2-4*a*c !判別式 ※この解は実数のみ
LET x=INT((-b+SQR(D))/(2*a))

IF x>1 THEN !2段目以降なら
   IF p>(x-1)*x/2+1 THEN !この段の2列目以降なら
      IF ABS(M(p-1)-M(p))<>M(p-x) THEN EXIT SUB !不成立なのでNG!
   END IF
END IF

!●左右対称
IF p=N AND M(p)<M(p-x+1) THEN EXIT SUB !上段の左端と右端

LET rc=1 !OK!
END SUB
(実行結果)
 5 段
1 〜 15 までの数字
 1 個目
  6 14 15  3 13
   8  1 12 10
    7 11  2
     4  9
      5
計算時間= 36.36
※WindowsME、CPU Pentium��700MHzにて
 

Re: 疑問

 投稿者:山中和義  投稿日:2008年11月17日(月)10時46分44秒
返信・引用  編集済
  > No.88[元記事へ]

GAIさんへのお返事です。

●サンプル その2
K段の場合、使用する数字は1〜N=K*(K+1)/2となる。
上段の数字のみが自由に設定できる。ただし、重複はしない。
この上段の数字列は、順列P(N,K)で決めることができる。
それによって、下段は階差として順に決まる。
このとき、数字の重複がないか確認する。

K=3なら、N=3*(3+1)/2=6。
上段 2 4 5 とすると

 2 4 5
  2 1 ←上段2つの差
  1 ←上段2つの差

たとえば、2段目1番目の2が重複しているため、NGとなる。

2段 3P2=          6
3段 6P3=        120
4段 10P4=     5,040
5段 15P5=   360,360
6段 21P6=39,070,080 ←かなりキツイ
 :
の数を確認する。
PUBLIC NUMERIC ANSWER_COUNT !解答数
LET ANSWER_COUNT=0

LET K=5 !段数 ※1〜

LET N=K*(K+1)/2 !1〜Nまでの数字
DIM F(N),FF(N),B(K),BB(K)
MAT F=ZER
MAT B=ZER

LET t0=TIME

PRINT K;"段"
PRINT "1 〜";N;"までの数字"
CALL perm(1,N,K, F,B,FF,BB)
IF ANSWER_COUNT=0 THEN PRINT "解なし"

PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB perm(p,N,R, F(),B(),FF(),BB()) !順列nPrを生成する
FOR nm=1 TO N !上段のK個の数を決める

   IF F(nm)=0 THEN !数字は重複なしに埋める

      LET F(nm)=1 !使用中とする
      LET B(p)=nm !仮に設定してみる

      IF p=R THEN !すべて埋まったら
         CALL checkrule(R,F,B,FF,BB, rc) !条件を満たすなら
         IF rc=1 THEN

            LET ANSWER_COUNT=ANSWER_COUNT+1
            PRINT ANSWER_COUNT;"個目"

            MAT BB=B
            FOR j=1 TO R !上段
               PRINT USING "###": BB(j);
            NEXT j
            PRINT
            FOR i=R-1 TO 1 STEP -1 !下段へ
               PRINT REPEAT$(" ",R-i); !右へシフト
               FOR j=1 TO i !この段の数字の数
                  LET BB(j)=ABS(BB(j)-BB(j+1))
                  PRINT USING "###": BB(j);
               NEXT j
               PRINT
            NEXT i

         END IF
      ELSE
         CALL perm(p+1,N,R, F,B,FF,BB) !次へ
      END IF

      LET B(p)=0 !元に戻す
      LET F(nm)=0

   END IF

NEXT nm
END SUB


EXTERNAL SUB checkrule(K,F(),B(),FF(),BB(), rc) !条件が満たすかどうか確認する
LET rc=0

!●左右対称
IF B(1)>B(K) THEN EXIT SUB !上段の左端と右端

!●上段の2数の差?
MAT BB=B !作業配列へ
MAT FF=F
FOR x=K-1 TO 1 STEP -1 !x段目
   FOR j=1 TO x !1つ下の段
      LET p=ABS(BB(j)-BB(j+1))
      IF FF(p)=1 THEN EXIT SUB !数字が重複していないか
      LET BB(j)=p
      LET FF(p)=1 !使用中とする
   NEXT j
NEXT x

LET rc=1 !OK!
END SUB

(実行結果)
●  5 段
1 〜 15 までの数字
 1 個目
  6 14 15  3 13
   8  1 12 10
    7 11  2
     4  9
      5
計算時間= 23.13  ←多少早くなった


●  6 段
1 〜 21 までの数字
解なし
計算時間= 2978.17
※WindowsME、CPU Pentium��700MHzにて



●改良案
数字Nは必ず上段に存在する。この配置はK通り。
残りK-1箇所に残りの数字を埋める順列はP(N-1,K-1)となる。
これによって、

2段 2×2P1=             4
3段 3×5P2=            30
4段 4×9P3=         2,016
5段 5×14P4=      120,120
6段 6×20P5=   11,162,880
7段 7×27P6=1,491,890,400 ←かなりキツイ

となり、7段の求解が現実となる?!
 

お礼

 投稿者:GAI  投稿日:2008年11月17日(月)15時17分47秒
返信・引用
  色々調べましたら5段までは構成できるが、6段以降は不可能(証明はどうやるのだろうか?)とのことでした。
結果をみるとなーんだ!なんですがこれを試行錯誤だけでやってみると、最初の5つの数字を微妙に変化させながらいくらやっても、数段後には重複する数字が出現してくるのです。
まさに成功するには根性の何者でもありません。(私も3日ほど取り組みましたがどうしても5段を発見することができませんでした。トホホ・・・)
このパズルは誰にでもでき、あきらめない気持ちと多少の幸運というギャンブル的要素を含んだとってもいいパズルだと思いました。
だれがこんな発見をして世の中に紹介しているんでしょうか?
またこれが5段で終わりということもありがたいです。
もうこれ以上考えたくもありませんもの・・・
しかし
証明されたとはホントはウソで、余りにもパターン数が多く6,7,8・・・まで構成できないから以降もあり得ないだろうとの感覚だけからそう結論を出しているかもしれません。
ある思いがけない段において構成可能ではなかろうかという思いもどこかに残ります。
どなたか数学的な証明を出して下さい。
 

Re: 助けて下さい。

 投稿者:荒田浩二  投稿日:2008年11月17日(月)23時52分29秒
返信・引用  編集済
  > No.86[元記事へ]

GAIさんへのお返事です。


全数調査用プログラム完成しました。

まず1行目を決めて、差を取っていき数字の重複がないか調査します。

k行でn個の数字とすると、(n-1)個から(k-1)個を取り出した順列pの前半部分にnを挿入して1行目を構成します。

調査回数を減らすために、対称的な数列はキャンセルするようにしました。

たとえば、k=5,n=15で配列pが 7,11,6,9 だとします。

調査するのは、

  15,7,11,6,9
  7,15,11,6,9
  7,11,15,6,9

この3通りとします。

7,11,6,15,9 と 7,11,6,9,15 は、配列pが 9,6,11,7 のときに調査します。

また、このときは 9,6,15,11,7 は調査しません。


  行数     実行時間   調査回数     解
  k=2 --->   0.03 秒         2 回   2個
  k=3 --->   0.08 秒        30 回   4個
  k=4 --->   0.14 秒      1008 回   4個
  k=5 --->   2.05 秒     60060 回   1個
  k=6 ---> 192.16 秒   5581440 回   0個 (2進モードで100.20秒)
  k=7 ---> 未調査    745945200 回   ?個 (2進モードでも4時間近くか?)
  k=8 ---> 未調査 135566323200 回   ?個


DECLARE EXTERNAL SUB combi
PUBLIC NUMERIC k,n,h,pt,count
LET t0=TIME
LET k=5         ! 行数
LET n=k*(k+1)/2 ! 最大値
LET h=INT(k/2)  ! 半分
LET pt=MOD(k,2) ! 奇偶
DIM nn(n-1),c(k-1)
MAT nn=ZER
LET count=0
LET j=0
CALL combi(nn,1,k-1,j,c)
PRINT TIME-t0;"秒",count;"回"
END

EXTERNAL SUB differ(p()) !注意:一部改良しました
DIM a(k,k),ck(n-1)
LET a(1,1)=n
FOR j=2 TO k
   LET a(1,j)=p(j-1)
NEXT j
CALL check
FOR j=2 TO h
   SWAP a(1,j-1),a(1,j)
   CALL check
NEXT j
IF pt=1 AND p(1)<p(k-1) THEN ! nが中央のとき
   SWAP a(1,h),a(1,h+1)
   CALL check
END IF
SUB check
   LET count=count+1
   MAT ck=ZER
   FOR r=1 TO k-1
      LET ck(p(r))=1
   NEXT r
   FOR ii=1 TO k-1
      FOR jj=1 TO k-ii
         LET d=ABS(a(ii,jj)-a(ii,jj+1))
         IF ck(d)=1 THEN EXIT SUB ! 数値重複
         LET ck(d)=1
         LET a(ii+1,jj)=d
      NEXT jj
   NEXT ii
   MAT PRINT a;  ! 解あり
END SUB
END SUB

REM 十進BASIC添付"\BASICw32\SAMPLE\COMBINAT.BAS"より
REM 1〜n-1の集合からr個を選ぶ組合せを生成する。
EXTERNAL SUB combi(nn(),kk,r,j,c())
DECLARE EXTERNAL SUB permu
! kk以降の数からr個を選択する
IF r=0 THEN
   FOR i=1 TO n-1
      IF nn(i)=1 THEN
         LET j=j+1
         LET c(j)=i
      END IF
   NEXT i
   !MAT PRINT c;
   CALL permu(c,1)
   LET j=0
ELSE
   FOR i=kk TO n-r
      LET nn(i)=1
      CALL combi(nn,i+1,r-1,j,c)
      LET nn(i)=0
   NEXT i
END IF
END SUB

REM 十進BASIC添付"\BASICw32\SAMPLE\PERMUTAT.BAS"より
REM (k-1)個の数値の順列を辞書式順序で生成する。
EXTERNAL SUB permu(p(),r)
DECLARE EXTERNAL SUB differ
IF r=k-1 THEN
!MAT PRINT p;
   CALL differ(p)
ELSE
   FOR i=r TO k-1
      LET t=p(i)
      FOR j=i-1 TO r STEP -1
         LET p(j+1)=p(j)
      NEXT j
      LET p(r)=t
      CALL permu(p,r+1)
      LET t=p(r)
      FOR j=r TO i-1
         LET p(j)=p(j+1)
      NEXT j
      LET p(i)=t
   NEXT i
END IF
END SUB
 

機械語で速度を上げたが

 投稿者:SECOND  投稿日:2008年11月18日(火)04時24分8秒
返信・引用
  > No.39[元記事へ]

!遅い方の check1,check2,echk ルーチン だけ、機械語で速度を上げたが、
!1.7GHz Pentium-4 128MB で8時間もかかる。C言語より速いはずなのだが、
!私の書き方が不味いのか?
! http://homepage2.nifty.com/neutro/asm/hojin_43.dll   ...同じフォルダに置く。
! http://homepage2.nifty.com/neutro/asm/hojin_43.asm   ...ソース
!----------------------------------------------------------------------------
!/* 6次のオイラー方陣が存在しないことを確認する. */

OPTION CHARACTER byte
SET TEXT BACKGROUND "opaque"
SET TEXT font"",14
OPTION BASE 0
DIM wb(8,8)
!
LET lb$=REPEAT$( CHR$(0),10000*8*8) !  N=1〜7: 1,1,1,4,56,9408,16942080
LET N= 6 !  2,3,4,5,6
LET cp= 1000 ! カウンターの表示間隔(1~20000)、小さいと速度低下。大きいと中止が困難。
!
CALL main

SUB makelb(x,y)
   local element
   FOR element=0 TO N-1
      FOR i=0 TO x-1
         IF element=wb(y,i) THEN EXIT FOR ! break;
      NEXT i
      IF i>x-1 THEN
         FOR i=0 TO y-1
            IF element=wb(i,x) THEN EXIT FOR ! break;
         NEXT i
         IF i>y-1 THEN
            LET wb(y,x)=element
            IF y=N-1 AND x=N-1 THEN
            !----memcpy(lb[lbs++], wb, sizeof(wb));
               LET w=1+64*lbs
               FOR i=0 TO N-1
                  FOR j=0 TO N-1
                     LET lb$(w+j:w+j)=CHR$(wb(i,j))
                  NEXT j
                  LET w=w+8
               NEXT i
               !--------モニター
               IF MOD(lbs,1000)=0 THEN PRINT "作成中。N=";N;"lbs=";lbs
               !--------
               LET lbs=lbs+1
               EXIT SUB ! return;
            END IF
            IF y=N-1 THEN CALL makelb(x+1,1) ELSE CALL makelb((x),y+1)
         END IF
      END IF
   NEXT element
END SUB

SUB main
   FOR i=0 TO N-1
      LET wb(i,0)=i ! =element
      LET wb(0,i)=i ! =element
   NEXT i
   !------
   PRINT "標準のラテン方陣の作成。"
   LET lbs=0
   CALL makelb(1,1)
   PRINT "作成終了。"
   PRINT
   PRINT "次数 N=";N;"lbs=";lbs;"個"
   PRINT "標準のラテン方陣 2つで、"
   PRINT "  オイラー方陣を構成可?"
   LET w$=STR$(lbs)
   IF lbs>2 THEN LET w$=w$& "+"& STR$(lbs-1)
   IF lbs>3 THEN LET w$=w$& "+"& STR$(lbs-2)
   IF lbs>4 THEN LET w$=w$& "+..."
   IF lbs>1 THEN LET w$=w$& "+1"
   PLOT TEXT,AT 0.1,0.9 :w$& " が検査回数です。"
   PLOT TEXT,AT 0.1,0.8 :"("& STR$(lbs) &"+1)*"& STR$(lbs)& "/2= "& STR$((lbs+1)*lbs/2)& "回まで、何時間?"
   PRINT "機械語実行中"
   IF check1( CallBackAdr(9), N+16*cp, lbs, lb$)=0 THEN PRINT "解は、有りませんでした。"
   PRINT "終了しました。"
END SUB

!-------------------------------------
FUNCTION check1( moniのアドレス, Ncp, lbs, lb$ )
   ASSIGN "hojin_43.dll","start00"
END FUNCTION

!-------------------------------------
!  hojin.dll が使用する文で、状態表示用。
SUB moni(message$,count), callback 9
   PRINT message$;
   PLOT TEXT,AT 0.1, 0.7 :"count= "&STR$(count)
END SUB

END

!注意:十進BASICの Ver7.2.0 以降 のバージョンが必要です。
 

Re: 助けて下さい。

 投稿者:GAI  投稿日:2008年11月18日(火)10時38分17秒
返信・引用
  > No.91[元記事へ]

荒田浩二さんへのお返事です。

>
>   行数     実行時間   調査回数     解
>   k=2 --->   0.03 秒         2 回   2個
>   k=3 --->   0.08 秒        30 回   4個
>   k=4 --->   0.14 秒      1008 回   4個
>   k=5 --->   2.05 秒     60060 回   1個
>   k=6 ---> 192.16 秒   5581440 回   0個 (2進モードで100.20秒)
>   k=7 ---> 未調査    745945200 回   ?個 (2進モードでも4時間近くか?)
>   k=8 ---> 未調査 135566323200 回   ?個

前回k=5で丸一日でも計算途中と終了せずになっていたものが、
今回のプログラムで4.28秒(なんという短時間)で結果が出てきました。
6万回以上のチェックがこんな短時間になされているなんて、おいらの頭はなんなんだ!
プログラム一つでこうも違うことになるとは、プログラムの世界も奥深いですね。
 

Re: 機械語で速度を上げたが

 投稿者:GAI  投稿日:2008年11月18日(火)10時44分11秒
返信・引用
  > No.92[元記事へ]

SECONDさんへのお返事です。

機械語???
私には、このプログラムをどう使ったらよいのか検討もつきません。
一応コピーをしてBASIC上で走らせましたが、何かのファイルが読めませんと返事が返ってきました。
これを使うにはどうしたらよいか教えて下さい。
 

mat命令と複素数表示

 投稿者:大熊 正  投稿日:2008年11月18日(火)11時28分38秒
返信・引用
  最近10進BASICのブルーバックスの本を購入、その虜になってます。
所で、電気関係では、4端子網をマトリクス[A,B,C,D]表示します。10進BASICのMAT文に複素表示の値を入れて計算させるには、どうしたら よいでしょうか。A=5+3i B=4-6i C=7+2i D=2-3iなどと入れたら[実数でないと駄目]と拒否されました。また複素数表示のMATの積や逆行列、等もどうするのでしょうか。
 

Re: 助けて下さい。

 投稿者:山中和義  投稿日:2008年11月18日(火)11時41分45秒
返信・引用
  > No.93[元記事へ]

GAIさんへのお返事です。

> プログラム一つでこうも違うことになるとは、プログラムの世界も奥深いですね。


今回紹介されたプログラムは以下の手法を用いています。

・モンテカルロ法
 ランダムに数字を埋めて条件に合うか確認する。
 確率ですから、「偶然にみつかる」を期待する。
 →荒田浩二さんの1回目

・バックトラック法
 順列や組合せによる数字を発生して、条件に合うように順に数字を埋めていく。(今回は下から)
 枝刈り効果(矛盾発生以降は対象外とする処理)を期待する。(検証回数が減る)
 →私の1回目

・「場合の数」法
 問題に応じた「場合の数」を、順列や組合せを考えて最小回数の検証を行う。
 →荒田浩二さんの2回目
 →私の2回目


プログラミングは、コーディング(言語による表現)より、
アルゴリズム(解き方)を検討するのが主だと思います。
 

Re: mat命令と複素数表示

 投稿者:山中和義  投稿日:2008年11月18日(火)11時55分10秒
返信・引用  編集済
  > No.95[元記事へ]

大熊 正さんへのお返事です。


BASICの編集画面に「複素数」ボタンがあります。オンの状態で複素数の計算が可能です。
通常は、下記のようにプログラムに記述します。

2×2正方行列の各要素に値を設定するプログラム

●例1

OPTION ARITHMETIC COMPLEX !複素数を扱う

LET j=SQR(-1) !虚数単位 ※電気系はjを使う

!M=(a b)
!  (c d)
DIM M(2,2) !2×2の正方行列

LET M(1,1)=5+3*j !a
LET M(1,2)=4-6*j !b
LET M(2,1)=7+2*j !c
LET M(2,2)=2-3*j !d

MAT PRINT M;

END


●例2 ※この場合はjは必要ない

OPTION ARITHMETIC COMPLEX !複素数を扱う

!M=(a b)
!  (c d)
DIM M(2,2) !2×2の正方行列

LET M(1,1)=COMPLEX(5,3) !a
LET M(1,2)=COMPLEX(4,-6) !b
LET M(2,1)=COMPLEX(7,2) !c
LET M(2,2)=COMPLEX(2,-3) !d

MAT PRINT M;

END

複素数は、括弧付きの数字の組(実部、虚部)で表示されます。


掛け算は
  DIM A(2,2),B(2,2),C(2,2),T(2,2)
  MAT T=A*B !T=AB

  MAT T=A*B !T=ABC
  MAT T=T*C
と記述します。
加減乗は2項の演算のみですから、3項以上は2項ずつに分解した記述してください。


定数倍は、MAT T=(2)*A !T=2A
逆行列は、MAT T=INV(A) !T=A^-1
転置行列は、MAT T=TRN(A) !T=tA
行列式は、LET p=DET(A) !p=|A|
これらは1項のみです。

行列の計算には実行列と複素行列の区別はありません。
 

Re: 機械語で速度を上げたが

 投稿者:SECOND  投稿日:2008年11月18日(火)14時14分21秒
返信・引用  編集済
  > No.94[元記事へ]

GAIさんへのお返事です。

> SECONDさんへのお返事です。
>
> 機械語???
> 私には、このプログラムをどう使ったらよいのか検討もつきません。
> 一応コピーをしてBASIC上で走らせましたが、何かのファイルが読めませんと返事が返ってきました。
> これを使うにはどうしたらよいか教えて下さい。

  http://homepage2.nifty.com/neutro/asm/hojin_43.dll

この機械語ファイルを、ダウンロードして、掲示のプログラムと同じフォルダーに置くと
走ります。

※「機械語は、命令語自体を、プログラムして速度を探す世界で、
  書き方(アルゴリズム)によって、10倍もの速さが、同じソースで、
  同じ数学アルゴリズムでも、違ったりもします。
 

さいころを転がす

 投稿者:山中和義  投稿日:2008年11月18日(火)18時56分39秒
返信・引用  編集済
  私からも1つパズルを紹介します。

●問題
4×4の格子がある。左上をスタート、右下をゴールの位置とする。
さいころの目「1」を上にしてスタートに置き、ゴールに向けて転がす。
このとき、ゴールでの目の数が1〜6になる転がし方(経路)を求める。

経路の決め方に、重複通過、迂回、通過点などの制限を設けてもよい。


シミュレータをつくって確認してみました。他にもあると思います。

!「さいころの回転」のシミュレーション

!置換(Permutation)の計算
SUB PermPrintOut(A()) !表示する
   MAT PRINT USING(REPEAT$(" ##",UBOUND(A))): A;
   PRINT
END SUB
SUB PermIdentity(A()) !恒等置換
   FOR i=1 TO UBOUND(A)
      LET A(i)=i
   NEXT i
END SUB
SUB PermInverse(A(), iA()) !逆置換 ※iAはA以外の配列を指定すること
   FOR i=1 TO UBOUND(A)
      LET iA(A(i))=i
   NEXT i
END SUB
SUB PermMultiply(A(),B(), AB()) !積AB ※ABはAかつB以外の配列を指定すること
   LET ua=UBOUND(A)
   LET ub=UBOUND(B)
   IF ua=ub THEN
      FOR i=1 TO ua
         LET AB(i)=A(B(i)) !※合成写像(AB)(i)=A(B(i))
      NEXT i
   ELSE
      PRINT "次元が違います。A=";ua;" B=";ub
      STOP
   END IF
END SUB
!-------------------- ここまでがサブルーチン


LET N=6

!展開図の配置と面番号(配列の添え字)との関係
! □    後    1
!□□□□ 左上右下 2345
! □    正    6

!---------- ↓↓↓↓↓ ----------
DIM A(N)
DATA 5,4,1,3,6,2 !目の配置 ※展開図参照
MAT READ A

!LET s$="DRDRDR" !手順 1
!LET s$="RRRDDD" !手順 2
!LET s$="RRDDDR" !手順 3
!LET s$="RRDRDD" !手順 4
!LET s$="RDDDRR" !手順 5
LET s$="RDLDRRRD" !手順 6
!---------- ↑↑↑↑↑ ----------


DIM U(N),D(N),L(N),R(N) !置換
!    1,2,3,4,5,6
DATA 3,2,6,4,1,5 !上 ※正面を上面にするの(図での水平軸)回転
!!!DATA 5,2,1,4,6,3 !下
DATA 1,3,4,5,2,6 !左
!!!DATA 1,5,2,3,4,6 !右

MAT READ U
CALL PermInverse(U,D)
!!!MAT READ D
MAT READ L
CALL PermInverse(L,R)
!!!MAT READ R


SET WINDOW -1,5,5,-1 !表示領域
DRAW grid !格子

DIM T(N),TT(N) !作業配列
LET x=0.5 !左上
LET y=0.5

MAT T=A !初期状態を表示する
CALL disp(T)

FOR k=1 TO LEN(s$) !スクリプトを実行する

   PLOT LINES: x,y; !経路の結線 始点

   SELECT CASE UCASE$(s$(k:k)) !各方向へ
   CASE "U","N"
      CALL PermMultiply(T,U,TT)
      LET y=y-1
   CASE "D","S"
      CALL PermMultiply(T,D,TT)
      LET y=y+1
   CASE "L","W"
      CALL PermMultiply(T,L,TT)
      LET x=x-1
   CASE "R","E"
      CALL PermMultiply(T,R,TT)
      LET x=x+1
   CASE ELSE
   END SELECT
   MAT T=TT !次へ

   PLOT LINES: x,y; !終点

   CALL disp(T)

NEXT k

SUB disp(T()) !現在の状態を表示する
   CALL PermPrintOut(T)

   LET nm=T(3) !グラフィックスによる
   IF nm=1 THEN !中央
      DRAW eye(4) WITH SHIFT(x,y)
   END IF
   IF nm=3 OR nm=5 THEN
      DRAW eye(1) WITH SHIFT(x,y)
   END IF
   IF nm=2 OR nm=4 OR nm=5 OR nm=6 THEN !左斜め
      DRAW eye(1) WITH SHIFT(x+0.25,y+0.25)
      DRAW eye(1) WITH SHIFT(x-0.25,y-0.25)
   END IF
   IF nm=3 OR nm=4 OR nm=5 OR nm=6 THEN !右斜め
      DRAW eye(1) WITH SHIFT(x+0.25,y-0.25)
      DRAW eye(1) WITH SHIFT(x-0.25,y+0.25)
   END IF
   IF nm=6 THEN !中段
      DRAW eye(1) WITH SHIFT(x+0.25,y)
      DRAW eye(1) WITH SHIFT(x-0.25,y)
   END IF

   !!!SET TEXT JUSTIFY "center","half"
   !!!PLOT TEXT ,AT x,y: STR$(T(3))
END SUB

PICTURE eye(c) !目の1つを表示する
   SET AREA COLOR c
   DRAW disk WITH SCALE(0.1)
END PICTURE

END
 

> No.95[元記事へ]

 投稿者:大熊 正  投稿日:2008年11月18日(火)19時03分13秒
返信・引用
  早速の御回答有難うございます。
早速明日から、色々やって見ます。
こんなに簡単に複素数のMATガできるなら、ますます10進BASICにはまりそうです。
中山様 有難うございました。
 

動きました。

 投稿者:GAI  投稿日:2008年11月19日(水)06時55分25秒
返信・引用
  > No.98[元記事へ]

SECONDさんへのお返事です。

言われたように、ダウンロードし同じフォルダーに入れたら走りだしました。
だいたい3時間程度で全パターンの組み合わせの調査を済ませ、どの組み合わせも
オイラー方陣の用件を満たさない報告がなされました。
調査総数が4千万を超えるものがあるのを、最初に証明した人はコンピューターの
道具がない時代にいったいどうやって調べたというのでしょうか?
最初オイラーさんも1万通り位は挑戦したでしょうがとても全パターンまではやってみようとは思わなかったでしょうね。
そこで、一般には4k+2 (k=0,1,2,3,・・・)
の場合には存在しないだろうと予想を立てたのでしょう。(1782年)
それから、約200年オイラーさんの言葉が信じられていた。
しかし、k=2(10次のオイラー方陣)が

00 47 18 76 29 93 85 34 61 52
86 11 57 28 70 39 94 45 02 63
95 80 22 67 38 71 49 56 13 04
59 96 81 33 07 48 72 60 24 15
73 69 90 82 44 17 58 01 35 26
68 74 09 91 83 55 27 12 46 30
37 08 75 19 92 84 66 23 50 41
14 25 36 40 51 62 03 77 88 99
21 32 43 54 65 06 10 89 97 78
42 53 64 05 16 20 31 98 79 87


00 17 28 39 94 85 76 61 52 43
71 22 37 48 59 96 80 13 04 65
82 73 44 57 68 09 91 35 26 10
93 84 75 66 07 18 29 50 41 32
49 95 86 70 11 27 38 02 63 54
58 69 90 81 72 33 47 24 15 06
67 08 19 92 83 74 55 46 30 21
16 31 53 05 20 42 64 77 88 99
25 40 62 14 36 51 03 89 97 78
34 56 01 23 45 60 12 98 79 87


46 57 68 70 81 02 13 24 35 99
71 94 37 65 12 40 29 06 88 53
93 26 54 01 38 19 85 77 60 42
15 43 80 27 09 74 66 58 92 31
32 78 16 89 63 55 47 91 04 20
67 05 79 52 44 36 90 83 21 18
84 69 41 33 25 98 72 10 56 07
59 30 22 14 97 61 08 45 73 86
28 11 03 96 50 87 34 62 49 75
00 82 95 48 76 23 51 39 17 64

のように構成可能であることが示され、オイラーの予想が覆されました。
またk=4(18次のオイラー方陣)も


0X AB T9 W7 Z5 BT 8W 5C 2A Y8 X6 6Z 3Y 92 C3 11 40 74

BY 8X 56 T4 W2 Z0 6T 3W 07 A5 Y3 X1 1Z 4A 7B 99 C8 2C

9Z 6Y 3X 01 TC WA Z8 1T BW 82 50 YB X9 C5 26 44 73 A7

X4 4Z 1Y BX 89 T7 W5 Z3 9T 6W 3A 08 Y6 70 A1 CC 2B 52

Y1 XC CZ 9Y 6X 34 T2 W0 ZB 4T 1W B5 83 28 59 77 A6 0A

3B Y9 X7 7Z 4Y 1X BC TA W8 Z6 CT 9W 60 A3 04 22 51 85

18 B6 Y4 X2 2Z CY 9X 67 T5 W3 Z1 7T 4W 5B 8C AA 09 30

CW 93 61 YC XA AZ 7Y 4X 12 T0 WB Z9 2T 06 37 55 84 B8

AT 7W 4B 19 Y7 X5 5Z 2Y CX 9A T8 W6 Z4 81 B2 00 3C 63

ZC 5T 2W C6 94 Y2 X0 0Z AY 7X 45 T3 W1 39 6A 88 B7 1B

W9 Z7 0T AW 71 4C YA X8 8Z 5Y 2X C0 TB B4 15 33 62 96

T6 W4 Z2 8T 5W 29 C7 Y5 X3 3Z 0Y AX 78 6C 90 BB 1A 41

23 T1 WC ZA 3T 0W A4 72 Y0 XB BZ 8Y 5X 17 48 66 95 C9

80 38 B3 6B 16 91 49 C4 7C 27 A2 5A 05 XX YY ZZ WW TT

7A 25 A0 58 03 8B 36 B1 69 14 9C 47 C2 YT ZX WY TZ XW

57 02 8A 35 B0 68 13 9B 46 C1 79 24 AC ZW WT TX XY YZ

65 10 98 43 CB 76 21 A9 54 0C 87 32 BA WZ TW XT YX ZY

42 CA 75 20 A8 53 0B 86 31 B9 64 1C 97 TY XZ YW ZT WX

の様に出来ちゃいます。(こんな配列は神様しかできない。)

いやー人間の脳の力(数学の凄さ)を思い知ります。
 

Re: 動きました。

 投稿者:SECOND  投稿日:2008年11月19日(水)17時06分33秒
返信・引用  編集済
  > No.101[元記事へ]

GAIさんへのお返事です。

ご報告ありがとうございます。”C”より遅かったらどうしようかと思っていました。
私のパソコンで8時間かかりますので、どうなのかが、わかりませんでした。
もっと、速い速度を研究してみます。

※2008.11.21 hojin_45.dll に取替えると、3時間→2時間20分ぐらいになります。
  http://homepage2.nifty.com/neutro/asm/hojin_45.dll    ・・・変更した機械語ファイル
  http://homepage2.nifty.com/neutro/asm/hojin_45.asm    ・・・上のソース・リスト
  http://homepage2.nifty.com/neutro/asm/HOJIN_45.BAS    ・・・assign修正、十進BASICファイル
 .asm や.BASファイルは、
 ダウン・ロード窓が出ず、化け文字で開くことが有ります。その場合は、
 「表示」→「エンコード」→「日本語(シフトJIS)」にして、
 「すべて選択」コピー・ペーストして下さい。(メモ帳などに)
 

2端子対定数(4端子定数)の計算

 投稿者:山中和義  投稿日:2008年11月20日(木)13時40分22秒
返信・引用
  電気回路計算の演習問題を解いています。
電卓による筆算の検算としてのプログラムをつくってみました。

以前苦労したラダー回路の合成抵抗値が「F行列の積」と「Zへの変換」で算出できます。
!2端子対回路(4端子回路)
! i1→┌──┐i2→
! a ─┤A B├─ b
!E1↑ │  │ ↑E2
! a'─┤C D├─ b'
!   └──┘
!基本行列Fを用いて
! (E1)=(A B)(E2)
! (i1) (C D)(i2)

OPTION ARITHMETIC COMPLEX !複素数を扱う

LET j=SQR(-1) !虚数単位 ※電気系はjを使う

!●交流回路

LET f=60 !周波数[Hz]
LET w=2*PI*f !角周波数ω

DEF H2Ohm(L)=j*w*L ![H]を[Ω]へ
DEF F2Ohm(C)=1/(j*w*C) ![F]を[Ω]へ
DEF xL(L)=w*L !誘導リアクタンス
DEF xC(C)=1/(w*C) !容量リアクタンス

SUB DispS(z) !複素数をS表示する ※スタインメッツ(Steinmetz)
   PRINT ABS(z);
   IF ABS(z)<>0 THEN
      IF arg(z)<>0 THEN PRINT "∠";DEG(arg(z));"°";
   END IF
   PRINT
END SUB

FUNCTION S2COMPLEX(l,th) !S表示(極座標形式)を複素数へ
   LET S2COMPLEX=COMPLEX(l*COS(RAD(th)),l*SIN(RAD(th)))
END FUNCTION


!●2端子インピーダンス回路行列
! ─Z─ の場合 F=(1 Z)
! ─-─      (0 1)
SUB seriesF(Z,F(,))
   LET F(1,1)=1
   LET F(1,2)=Z
   LET F(2,1)=0
   LET F(2,2)=1
END SUB
! ─┬─ の場合 F=(1  0)
!  Z        (1/Z 1)
! ─┴─
SUB shuntF(Z,F(,))
   WHEN EXCEPTION IN
      LET F(1,1)=1
      LET F(1,2)=0
      LET F(2,1)=1/Z
      LET F(2,2)=1
   USE
      PRINT "0で割れません。"
      STOP
   END WHEN
END SUB

!●パラメータの相互変換 ※一部
SUB F2Z(F(,), Z(,)) !FパラメータをZパラメータへ
   LET Z(1,1)=F(1,1) !A
   LET Z(1,2)=DET(F) !AD-BC
   LET Z(2,1)=1
   LET Z(2,2)=F(2,2) !D
   WHEN EXCEPTION IN
      MAT Z=(1/F(2,1))*Z !(1/C)倍
   USE
      PRINT "Zパラメータは存在しません。"
      STOP
   END WHEN
END SUB
SUB F2Y(F(,),Y(,)) !FパラメータをYパラメータへ
   LET Y(1,1)=F(2,2) !D
   LET Y(1,2)=-DET(F) !BC-AD
   LET Y(2,1)=-1
   LET Y(2,2)=F(1,1) !A
   WHEN EXCEPTION IN
      MAT Y=(1/F(1,2))*Y !(1/B)倍
   USE
      PRINT "Yパラメータは存在しません。"
      STOP
   END WHEN
END SUB

SUB Z2Y(Z(,),Y(,)) !ZパラメータをYパラメータへ
   WHEN EXCEPTION IN
      MAT Y=INV(Z) !Y=Z^-1
   USE
      PRINT "Yパラメータは存在しません。"
      STOP
   END WHEN
END SUB
!-------------------- ここまでがサブルーチン


DIM mF(2,2),mZ(2,2),mY(2,2) !F,Z,Yパラメータ
DIM T1(2,2),T2(2,2) !作業用

!●はしご回路の合成抵抗 a-b端子間

!a─R1┬R3┬R5┬ … ┬Rn┬─┬ …
!   R2 R4 R6  Rn-1 Rn+1
!b──┴─┴─┴   ┴─┴─┴
!
LET R1=1 !1,2,1,2,…,1,2,1
LET R2=2

CALL seriesF(R1,T1) !─R1┬
CALL shuntF(R2,T2)  !  R2

MAT mF=IDN !単位行列
FOR i=1 TO 5 !段数
   MAT mF=mF*T1 !─R1┬R1┬ … ┬R1┬
   MAT mF=mF*T2 !  R2 R2   R2 R2
NEXT i
MAT mF=mF*T1 !─R1┐

CALL F2Z(mF,mZ) !要素a
MAT PRINT mZ;



!●T型LC回路
! ─L─┬─L─
!    C
! ─-─┴─-─
!ω=1[rad/sec]、L=2[H]、C=1[F]
LET L=2
LET C=1
LET w=1 !問題に合わせる


!●Fパラメータ、基本行列
MAT mF=IDN !単位行列

CALL seriesF(H2Ohm(L),T1)
MAT mF=mF*T1

CALL shuntF(F2Ohm(C),T2)
MAT mF=mF*T2

MAT mF=mF*T1

PRINT "Fパラメータ"
MAT PRINT mF;


!●Zパラメータ、インピーダンス行列 V=Z*I
CALL F2Z(mF,mZ)
PRINT "Zパラメータ"
MAT PRINT mZ;


!●Yパラメータ、アドミタンス行列 I=Y*V
CALL F2Y(mF,mY)
PRINT "Yパラメータ"
MAT PRINT mY;


!●Yパラメータ(別解)Y=Z^-1
CALL Z2Y(mZ,mY)
PRINT "Yパラメータ"
MAT PRINT mY;


END
 

mat命令と複素数計算

 投稿者:大熊 正  投稿日:2008年11月21日(金)15時11分26秒
返信・引用
  大熊 です。

前回 NO95 NOの御回答有難うございました。山中さんを中山さんと間違えて投稿しました。失礼を御許しください。
その後だいぶ10進BASICを進めてますが、下記の不具合でストップしてます。
MAT T=INV(A) が出来ないのです。


OPTION ARITHMETIC COMPLEX
LET j=SQR(-1)
LET R1=5000
LET R2=5000
LET C1=0.1*10^( -6 )
LET C2=0.1*10^( -6 )
LET F=100
LET SZ=0.001
LET NP=4
LET ZC1=1/(2*PI*F*C1)
LET ZC2=1/(2*PI*F*C2)
OPTION BASE 1
PRINT "ZCI=";ZC1

DIM A(NP,NP),B(NP,NP),T(NP,NP),E1(NP)

LET A(1,2)=1/R1+SZ*j
LET A(2,3)=1/R2+SZ*j
LET A(2,4)=SZ+1/ZC1*j
LET A(3,4)=SZ+1/ZC2*j
MAT PRINT A

LET E1(1)=1
LET E1(4)=0
PRINT"下記のごとくMAT PRINT E1とやると横に一文字になる。"
MAT PRINT E1
PRINT"下記のごとくMAT PRINT USING REPEAT$RIで縦に一文字並び良

好。"
MAT PRINT USING REPEAT$(" #.#### ",1):E1
MAT T=INV(A)


STOP

早速ですが、上記の文を作り、マトリクス[A]を作り実行すると、最後の MAT T=INV(A)で
「EXTYPE 3009 引数が定義外の値」となり、ストップします。
どこが不良の原因でしょうか。
また、一列のE(5)などを作り、PRINT E  をやると、横一列に表示します。
四端子網の A*E 等は大丈夫でしょうか。縦に変更してT=TRAN(E) そしてA*T でしょうか。
 

Re: mat命令と複素数計算

 投稿者:山中和義  投稿日:2008年11月21日(金)16時36分32秒
返信・引用  編集済
  > No.104[元記事へ]

大熊 正さんへのお返事です。

> 早速ですが、上記の文を作り、マトリクス[A]を作り実行すると、最後の MAT T=INV(A)で
> 「EXTYPE 3009 引数が定義外の値」となり、ストップします。
> どこが不良の原因でしょうか。

行列Aが、逆行列を持たない行列だからです。
Aは筆算で逆行列は存在しますか?


> また、一列のE(5)などを作り、PRINT E  をやると、横一列に表示します。
> 四端子網の A*E 等は大丈夫でしょうか。縦に変更してT=TRAN(E) そしてA*T でしょうか。

DIM A(3,3)
DIM X(3),B(3)
MAT B=A*X !(3行,3列)(3行,1列)=(3行,1列)として計算される
MAT PRINT B !横へ
MAT B=X*A !(1行,3列)(3行,3列)=(1行,3列)として計算される
MAT PRINT B !横へ
END
この場合、X,Bはベクトル扱いになります。
X,Bを行列として扱う場合は、(X,Bに対してTRNを適用する場合)
行または列のみの行列は、たとえば
 3行1列なら DIM B(3,1)
 1行3列なら DIM B(1,3)
としてください。
 

Re: 旧掲示板の投稿をキャッシュからサルベージ

 投稿者:teriam  投稿日:2008年11月21日(金)20時03分4秒
返信・引用
  > No.34[元記事へ]

大事な情報だと思うのでご本人の了解は得てませんが再掲します。

> 十進BASICの旧掲示板が10月上旬から運営会社aroundの活動停止により事実上閉鎖されました。
> 「掲示板過去ログ」に保管されていなかった101〜110ページの投稿を検索サイトのキャッシュから拾い出す方法を紹介します。
> ただしキャッシュですから、すべてのページが保存されているわけではありません。
> 分割して投稿されたプログラムなどは、部分的にしか拾えないかもしれません。
> また、キャッシュは日々更新されますのであと1,2ヶ月もしたらほとんどのページが削除されると思います。
> 数日前と比較してもヒット数が減っています。
> 必要な投稿は早めにパソコンに保存しておくことをお勧めします。
>
>
> 1.検索サイトGoogleで "十進BASIC掲示板" を検索します。
>   (余計な情報を排除するためダブルクォテーション(")で囲みましょう)
>
> 2.検索結果の最後に、
>     最も的確な結果を表示するために、上の○○件と似たページは除外されています。
>     検索結果をすべて表示するには、ここから再検索してください。

>   とあるのでクリックして下さい。
>
> 3.検索結果のうち、URLが freebbs.around.ne.jp で始まるものが旧掲示板の投稿です。
>   /basic/ または &pg= の後ろにある数字が旧掲示板のページ番号です。
>   (URLが www.geocities.jp とあるのは「掲示板過去ログ」にあるのでそちらをご覧ください)
>
> 4.内容を見るには必ずキャッシュをクリックして下さい。
>   (見出しをクリックすると接続エラーになります)
>
> 5.下の語句からも検索できます。他の検索サイトからも検索してみて下さい。
>     "freebbs.around.ne.jp/article/b/basic/"
>
>     "freebbs.around.ne.jp/kyview","basic"
 

Re: mat命令と複素数計算

 投稿者:SECOND  投稿日:2008年11月23日(日)07時44分19秒
返信・引用  編集済
  > No.104[元記事へ]

大熊 正さんへのお返事です。

> MAT T=INV(A) が出来ないのです。

IF DET(A)<>0 THEN ! 行列式|A|の値
   MAT T=INV(A)
ELSE
   PRINT "A は、逆行列を持たない"
END IF


※十進BASIC の、1次元配列、行ベクトルと列ベクトル

行列 (a)
┌              ┐
│ 1.000   2.000│
│ 3.000   4.000│
└              ┘
ベクトル (v1)
(  1.000   2.000 ) ・・・この状態は、行か、列かが、不定になっている。

MAT v2=a*v1 ・・・右へ書けば、列ベクトル v1 として計算される。
┌              ┐┌      ┐
│ 1.000   2.000││ 1.000│
│ 3.000   4.000││ 2.000│
└              ┘└      ┘
v2=(  5.000  11.000 )

MAT v2=v1*a ・・・左へ書けば、行ベクトル v1 として計算される。
┌              ┐┌              ┐
│ 1.000   2.000││ 1.000   2.000│
└              ┘│ 3.000   4.000│
                  └              ┘
v2=(  7.000  10.000 )
 

Re: mat命令と複素数計算

 投稿者:島村1243  投稿日:2008年11月23日(日)10時38分16秒
返信・引用
  > No.104[元記事へ]

大熊 正さんへのお返事です。

> 大熊 です。
> ***中略***
> その後だいぶ10進BASICを進めてますが、下記の不具合でストップしてます。
> MAT T=INV(A) が出来ないのです。
> ***中略***
> LET A(1,2)=1/R1+SZ*j
> LET A(2,3)=1/R2+SZ*j
> LET A(2,4)=SZ+1/ZC1*j
> LET A(3,4)=SZ+1/ZC2*j
> MAT PRINT A
> ***中略***
> 早速ですが、上記の文を作り、マトリクス[A]を作り実行すると、最後の MAT T=INV(A)で
> 「EXTYPE 3009 引数が定義外の値」となり、ストップします。
> どこが不良の原因でしょうか。

アドミタンス行列[A]と節点法を使って、電気回路網の電流[I]=[A][E]、インピーダンス[Z]=INV(A)を計算するプログラムを作成するつもりの様ですね。
プログラム原稿を見ると、下記節点間アドミタンスが未設定であることがエラーの原因です。

未設定の節点間アドミタンス
A(2,1)!=A(1,2)
A(3,2)!=A(2,3)
A(4,3)!=A(3,4)

したがって「INV(A)」よりも前に
A(2,1)=A(1,2)
A(3,2)=A(2,3)
A(4,3)=A(3,4)

を追記すればエラーは出ません。
なお、本来は対地間アドミタンス{A(1,1),A(2,2),A(3,3),A(4,4)}や、アドミタンスが接続されない節点間のアドミタンスは0と 設定すべきです(本件ではBASICアプリケーションが未指定の節点間アドミタンス=0と自動初期値設定をしてしまうのでトラブルにはなりませんが注意が 必要です)。
 

あるシャッフル方法の規則性

 投稿者:GAI  投稿日:2008年11月23日(日)12時46分19秒
返信・引用
  例:1から18の番号順にカードが並んでいるとする。(裏向きトップが1)
このカード群を裏向きに持ち、上から1枚ずつ裏向きのままテーブルへ左から右へ3枚並べ
たら、元に戻って2枚目をまた左から右の山へ配る。
これを繰り返しそれぞれの山の枚数が6枚ずつになり、手持ちのカードが無くなる。
次に左の山を持ち上げ、隣の山に重ね、重なった山を持ち上げ、右の山へ重ね一つにする。
このシャッフルを繰り返すと9回繰り返した時点で、カードの順番が元に戻る。
このシャッフルの規則を調べたい(元の状態にどの条件で戻るのか)のですが、
一般にカードがn枚あり
山をp個(p<=nとする)作って、このシャッフルをしていく場合、何回繰り返せば元に戻るのでしょうか?
(n=7,p=3なら3回で元に戻りました。)

これを知るためのプログラムを作って貰えないでしょうか?
これを使って新作のカードマジックを作りたいのでよろしくお願いします。
ちなみに、トランプ全部52枚の場合2山、3山、4山、・・・、13山
での復元回数も知りたいのですが・・・
 

!万華鏡

 投稿者:SECOND  投稿日:2008年11月23日(日)16時05分47秒
返信・引用
  !万華鏡

OPTION ARITHMETIC NATIVE
DIM px(12),py(12)

MAT READ px
DATA 0.20, 0.40, 0.60, 0.80, 0.70, 0.60, 0.50, 0.40, 0.30, 0.20, 0.40, 0.60
MAT READ py
DATA 0.11, 0.11, 0.11, 0.11, 0.29, 0.47, 0.65, 0.47, 0.29, 0.11, 0.11, 0.11

SET WINDOW -1/4,1/4, -1/4,1/4
!----------
LET N=3
DO
   LET s=MOD(s,36)+1
   LET s2=INT((s-1)/4)+1
   SET DRAW mode hidden
   CLEAR
   DRAW D4(N) WITH SHIFT(-0.5,-0.5/SQR(3))*ROTATE(PI*2/36*s+PI)
   SET DRAW mode explicit
   WAIT DELAY 0.2
LOOP

!------
PICTURE D4(k)
   IF 0< k THEN
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*SHIFT(1/4,SQR(3)/4) ! 上
      DRAW D4(k-1) WITH SCALE(1/2,-1/2)*SHIFT(1/4,SQR(3)/4) ! 中
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(-PI*2/3)*SHIFT(1/4,SQR(3)/4) ! 左
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(PI*2/3)*SHIFT(1,0) ! 右
   ELSE
      DRAW Set01
   END IF
END PICTURE

!------ 種の三角図
PICTURE Set01
   PLOT LINES: 0,0; 1,0 ;0.5,SQR(3)/2 ;0,0
   SET AREA COLOR 5 !2
   DRAW disk WITH SCALE(0.1)*SHIFT(px(s2),py(s2)) ! 飾り1
   SET AREA COLOR 6 !3
   DRAW disk WITH SCALE(0.1)*SHIFT(px(s2+1),py(s2+1)) ! 飾り2
   SET AREA COLOR 7 !4
   DRAW disk WITH SCALE(0.1)*SHIFT(px(s2+2),py(s2+2)) ! 飾り3
   SET AREA COLOR 1
   DRAW disk WITH SCALE(0.1)*SHIFT(px(s2+3),py(s2+3)) ! 飾り4
END PICTURE

END
 

Re: あるシャッフル方法の規則性

 投稿者:GAI  投稿日:2008年11月24日(月)08時50分50秒
返信・引用
  > No.109[元記事へ]

GAIさんへのお返事です。
自分へ返事を出すのも変ですが、私なりのプログラムを作って調べてみました。

!4山でのシャッフル調査
100 OPTION BASE 1
110 INPUT  PROMPT "カードの枚数は?":n
120 INPUT  PROMPT "山の数は?:4を入力しておいて下さい。":p
130 INPUT  PROMPT "シャッフル回数?":t
140
150 DIM a(n)
160 DIM b(n)
170 DIM c(n)
180 DIM d(n)
190 DIM e(n)
200 DIM f(n)
210
220 FOR i=1 TO n
230    LET a(i)=i
240 NEXT i
250
260 FOR q=1 TO t
270    FOR k=1 TO INT(n/p)
280       LET b(k)=a(p*(k-1)+1)
290       LET c(k)=a(p*(k-1)+2)
300       LET d(k)=a(p*(k-1)+3)
310       LET e(k)=a(p*(k-1)+4)
320       PRINT USING "####":b(k);
330       PRINT USING "####":c(k);
340       PRINT USING "####":d(k);
350       PRINT USING "####":e(k);
360       PRINT
370    NEXT k
380
390    FOR i=1 TO n/p
400       LET f(i)=b(n/p-i+1)
410       LET f(n/p+i)=c(n/p-i+1)
420       LET f(2*n/p+i)=d(n/p-i+1)
430       LET f(3*n/p+i)=e(n/p-i+1)
440    NEXT i
450
460    FOR i=1 TO n
470       LET a(i)=f(i)
480       PRINT ;q;"回";
490       PRINT USING "####":a(i);
500       PRINT
510    NEXT i
520
530 NEXT q
540 END
550

!3山でのシャッフル調査
100 OPTION BASE 1
110 INPUT  PROMPT "カードの枚数は?":n
120 INPUT  PROMPT "山の数は?:3を入力しておいて下さい。":p
130 INPUT  PROMPT "シャッフル回数?":t
140
150 DIM a(n)
160 DIM b(n)
170 DIM c(n)
180 DIM d(n)
190!DIM e(n)
200 DIM f(n)
210
220 FOR i=1 TO n
230    LET a(i)=i
240 NEXT i
250
260 FOR q=1 TO t
270    FOR k=1 TO INT(n/p)
280       LET b(k)=a(p*(k-1)+1)
290       LET c(k)=a(p*(k-1)+2)
300       LET d(k)=a(p*(k-1)+3)
310       !    LET e(k)=a(p*(k-1)+4)
320       PRINT USING "####":b(k);
330       PRINT USING "####":c(k);
340       PRINT USING "####":d(k);
350       !   PRINT USING "####":e(k);
360       PRINT
370    NEXT k
380
390    FOR i=1 TO n/p
400       LET f(i)=b(n/p-i+1)
410       LET f(n/p+i)=c(n/p-i+1)
420       LET f(2*n/p+i)=d(n/p-i+1)
430       !  LET f(3*n/p+i)=e(n/p-i+1)
440    NEXT i
450
460    FOR i=1 TO n
470       LET a(i)=f(i)
480       PRINT ;q;"回";
490       PRINT USING "####":a(i);
500       PRINT
510    NEXT i
520
530 NEXT q
540 END
550

カードマジックをやる上では、これ位が妥当であろう。

こうやって調べましたら次の様な結果を得ました。
             <3山でのシャッフル>
トランプ枚数     正順復元回数         逆順復元回数
     6                3
      9                4                   2
      12               6                   3
     15               4
     18               9
      21              10                   5
      24              20                  10
     27               3
     30              15
      33              16                   8
     36               9
     39               4
     42              21
      45              22                  11
     48              21
     51               6


              <4山でのシャッフル>
トランプ枚数      正順復元回数       逆順復元回数
      8                6                  3
     12               3
      16               4                  2
      20               6                  3
     24               5
     28               7
      32              10                  5
     36               9
     40               5
     44               6
     48              21
     52              13


これを眺めると以外にも混ぜているように見せかけて、元に戻すことが起こる
現象をつくることが可能であることがわかりました。
27枚での3山か、20枚での4山あたりが使えそうです。
 

Re: あるシャッフル方法の規則性

 投稿者:山中和義  投稿日:2008年11月24日(月)17時07分13秒
返信・引用  編集済
  > No.111[元記事へ]

GAIさんへのお返事です。

> これを眺めると以外にも混ぜているように見せかけて、元に戻すことが起こる
> 現象をつくることが可能であることがわかりました。


逆置換で元に戻すことを考える。

n枚p山のとき、n=k*pならn枚k山に分配・収集が考えられる。

たとえば
18枚3山の場合、各山6枚ずつ
 16,13,10,7,4,1 !山1 ※上から順に
 17,14,11,8,5,2 !山2
 18,15,12,9,6,3 !山3
となる置換になる。(出題の参考例のシャッフル)
これに対して、18枚6山、各山3枚ずつ
 6,12,18 !山1
 5,11,17 !山2
 4,10,16 !山3
 3, 9,15 !山4
 2, 8,14 !山5
 1, 7,13 !山6
となる逆置換である。

この置換は、上記の置換の後に適用すると計2回で元に戻る。
カード操作は、ほぼ同じ操作で実現できる。「カードを下から順に」とか、、、


。。。と言う具合に、私も少し考えてみました。
また、逆順のときに1回で逆順させるシャッフルを行う(途中で枚数を数える振りをして、1山にカードを置いていくなど)
などの組合せで、回数とかを減らすことができますね。
 

シャッフル法則合点!!!

 投稿者:GAI  投稿日:2008年11月24日(月)18時41分33秒
返信・引用
  オッー!!! ワンダフル
n×m枚のカードをまずn山に分けるシャッフルを行なった後
次はm山でのシャッフルをしたら、最後に枚数を確認する操作に紛れて順番を逆転してやればどの枚数でも3回の操作でフォールスシャッフルが可能という訳ですね。
これなら、枚数での正順復元回数をいちいち覚えておかなくても大丈夫だ!
4×5=20枚程度がいいかも!(任意の枚数でも2つ数の掛け算さえやれば済むんだ。)
数学が得意な方はどうしてこうも頭が柔軟なんだろう。
自分はある山だけに限定して思考をしてしまう・・・
たいへん参考になるアドバイスありがとうございました。
 

mat命令と複素数計算

 投稿者:大熊 正  投稿日:2008年11月24日(月)18時50分22秒
返信・引用
  大熊 です。
山中様、島村様、そしてSECOND様
色いろの御教授 本当に有難うございました。

その総てが、現在の私に理解できたとは、到底思ってませんが、
10進BASICが更に好きになったことは確かです。「持つべきは、
先達なり」・・・と感謝いたしております。

そこで、電気回路{A}では、コンデンサーなどのアドミッタンス
が周波数(F)特性を持ちます、更に電源[B}も同様です。

(1)マトリクス[A]の中にコンデンサーなどのアドミッタンス
   をスマートに入れる方法。
(2)同じく 電源のマトリクス[B}に、SIN(F,T)表示等で
   スマートに入れる方法。
(3)電源の周波数と大きさ、出力の関係、将来のグラフ化に
   備え、INV(A)*B 等とした上で更に、全体を
     FOR F=100 TO 10000 STEP 100・・「INB (A)*B」・
     ・・・NEXT F
       等とやるのでしょうか、全体の方法が私にはまだ見え
    てません。
(4)最終的には、片対数表のグラフ表示に成るのでしょうが、
   これを   やった、参考資料や、文献などがありまし
   たら御教えください。
   CR 一段の回路でも現在の私には、大変参考になります。
(5)実は、最終的には「有限要素法」にまでたどり着きた
   いのですが、   10進BASICでこれをやった、先達の文献
   などありましたら御教えください。従来の [N88 BASIC ??]
   でやった参考書はあるのですが、真似してプログラムすると
   「文法の相違か、あちこちでつっかえ全く動かず」
   現在は、諦めている状況です。

「もっと、自分で苦労し、真面目にやれ」とのお叱りの言葉も
 きこえますが、なるべく早く「初歩の段階」を済ませ先に
 行きたいので よろしく御願いします。

敬具
 

古代生物

 投稿者:SECOND  投稿日:2008年11月25日(火)03時38分43秒
返信・引用
  !古代生物( 再投稿コンパクト)

SET TEXT FONT "MS 明朝",12
SET TEXT BACKGROUND "OPAQUE"
SET POINT STYLE 1
!----------------
LET t$="アンモナイト"
LET N=101
LET xm=-0.63
LET ym=0.5
LET h=1.5
RANDOMIZE 19650218
SET WINDOW xm-h,xm+h, ym-h,ym+h
PLOT TEXT,AT xm+h*0.1,ym+h*0.85:t$& "    N="& USING$("###",N)
SET POINT COLOR 44
CALL fa(N, 0.4, 0.2)
beep
!----------------
LET t$="シダの葉"
LET N=19
LET xm=0.32
LET ym=0.5
LET h=0.6
RANDOMIZE 19650218
SET WINDOW xm-h,xm+h, ym-h,ym+h
DRAW axes
PLOT TEXT,AT xm+h*0.1,ym+h*0.7:t$& "    N="& USING$("###",N)
PLOT TEXT,AT xm-h*0.75, ym+h*0.85:"しばらく御待ち下さい。"
SET POINT COLOR 10
CALL fs(N, 0,0)
CALL fs(N, 0,0)
beep
PLOT TEXT,AT xm-h*0.75, ym+h*0.85:" 描画の終了     "

!------------------------------------------------------------
! 複数の縮小アファイン変換 (アンモナイト)
DEF A1x(x,y)=-0.289993*x-0.001347*y+0.593333
DEF A1y(x,y)= 0.001986*x-0.196662*y-0.32 ! p1=0.06124
DEF A2x(x,y)=-0.073058*x-0.024834*y+0.793333
DEF A2y(x,y)=-0.006353*x+0.285589*y-0.056667 ! p2=0.022236
DEF A3x(x,y)= 0.939186*x-0.218787*y-0.046667
DEF A3y(x,y)= 0.214337*x+0.958685*y+0.01 ! p3=0.916524
!------------------------------------------------------------
SUB fa(k, x,y)
   IF 0< k THEN
      CALL fa(k-1, A3x(x,y),A3y(x,y))
      IF RND< 0.0668176 THEN CALL fa(k-1, A1x(x,y),A1y(x,y))
      IF RND< 0.024261 THEN CALL fa(k-1, A2x(x,y),A2y(x,y))
   END IF
   PLOT POINTS: x,y
END SUB

!------------------------------------------------------------
! 複数の縮小アファイン変換 (シダの葉)
DEF W1x(x,y)= 0.836*x+0.044*y
DEF W1y(x,y)=-0.044*x+0.836*y+0.169 ! p1=0.4
DEF W2x(x,y)=-0.141*x+0.302*y
DEF W2y(x,y)= 0.302*x+0.141*y+0.127 ! p2=0.2
DEF W3x(x,y)= 0.141*x-0.302*y
DEF W3y(x,y)= 0.302*x+0.141*y+0.169 ! p3=0.2
DEF W4x(x,y)= 0
DEF W4y(x,y)= 0.175337*y ! p4=0.2
!------------------------------------------------------------
!確率的プロット(p1~p4)は、変形されています。
SUB fs(k, x,y)
   IF 0< k THEN
      CALL fs(k-1, W1x(x,y),W1y(x,y))
      IF RND< 0.3 THEN CALL fs(k-1, W2x(x,y),W2y(x,y))
      IF RND< 0.3 THEN CALL fs(k-1, W3x(x,y),W3y(x,y))
      IF RND< 0.3 THEN CALL fs(k-1, W4x(x,y),W4y(x,y))
   END IF
   PLOT POINTS: x,y
END SUB

END
 

Re: mat命令と複素数計算

 投稿者:山中和義  投稿日:2008年11月25日(火)11時29分9秒
返信・引用
  > No.114[元記事へ]

大熊 正さんへのお返事です。

> (1)マトリクス[A]の中にコンデンサーなどのアドミッタンスをスマートに入れる方法。
> (2)同じく 電源のマトリクス[B}に、SIN(F,T)表示等でスマートに入れる方法。

1要素ずつ代入文で設定するのが基本になります。
サブルーチンや関数を使って、最小限の要素を指示することも可能です。(サンプル参照)

RC回路、これでいいのでしょうか? 具体的に提示した方が問題解決が早いと思います。


> (4)最終的には、片対数表のグラフ表示に成るのでしょうが、

周波数特性のグラフですか?


> (5)実は、最終的には「有限要素法」にまでたどり着きたいのですが、

tについての微分方程式を解くということですか?


2端子対回路(4端子回路)として処理したサンプル
1000 !2端子対回路(4端子回路)
1010 ! i1→┌──┐i2→
1020 ! a ─┤A B├─ b
1030 !E1↑ │  │ ↑E2
1040 ! a'─┤C D├─ b'
1050 !   └──┘
1060 !基本行列Fを用いて
1070 ! (E1)=(A B)(E2)
1080 ! (i1) (C D)(i2)
1090
1100 OPTION ARITHMETIC COMPLEX !複素数を扱う
1110
1120 LET j=SQR(-1) !虚数単位 ※電気系はjを使う
1130
1140 !●交流回路
1150
1160 LET f=60 !周波数[Hz]
1170 DEF w=2*PI*f !角周波数ω
1180 DEF w2f=w/(2*PI) !ωからfを求める
1190
1200 DEF H2Ohm(L)=j*w*L ![H]を[Ω]へ
1210 DEF F2Ohm(C)=1/(j*w*C) ![F]を[Ω]へ
1220 DEF xL(L)=w*L !誘導リアクタンス
1230 DEF xC(C)=1/(w*C) !容量リアクタンス
1240
1250 SUB DispS(z) !複素数をS表示する ※スタインメッツ(Steinmetz)
1260    PRINT ABS(z);
1270    IF ABS(z)<>0 THEN
1280       IF arg(z)<>0 THEN PRINT "∠";DEG(arg(z));"°";
1290    END IF
1300    PRINT
1310 END SUB
1320
1330 FUNCTION S2COMPLEX(l,th) !S表示(極座標形式)を複素数へ
1340    LET S2COMPLEX=COMPLEX(l*COS(RAD(th)),l*SIN(RAD(th)))
1350 END FUNCTION
1360 FUNCTION i2COMPLEX(im,th) !瞬時値式を複素数へ ※最大値、初期位相
1370    LET i2COMPLEX=S2COMPLEX(im/SQR(2),th) !実効値、初期位相
1380 END FUNCTION
1390
1400
1410 !●基本2端子対回路
1420 ! ─Z─ の場合 F=(1 Z)
1430 ! ─-─      (0 1)
1440 SUB seriesF(Z,F(,)) !直列挿入
1450    MAT F=IDN
1460    LET F(1,2)=Z !インピーダンス
1470 END SUB
1480 ! ─┬─ の場合 F=(1  0)
1490 !  Z        (1/Z 1)
1500 ! ─┴─
1510 SUB shuntF(Z,F(,)) !並列挿入
1520    WHEN EXCEPTION IN
1530       MAT F=IDN
1540       LET F(2,1)=1/Z !アドミタンス
1550    USE
1560       PRINT "0では割れません。"
1570       STOP
1580    END WHEN
1590 END SUB
1600
1610 !●パラメータの相互変換 ※一部
1620 SUB F2Z(F(,), Z(,)) !FパラメータをZパラメータへ
1630    LET Z(1,1)=F(1,1) !A
1640    LET Z(1,2)=DET(F) !AD-BC
1650    LET Z(2,1)=1
1660    LET Z(2,2)=F(2,2) !D
1670    WHEN EXCEPTION IN
1680       MAT Z=(1/F(2,1))*Z !(1/C)倍
1690    USE
1700       PRINT "Zパラメータは存在しません。"
1710       STOP
1720    END WHEN
1730 END SUB
1740 SUB F2Y(F(,),Y(,)) !FパラメータをYパラメータへ
1750    LET Y(1,1)=F(2,2) !D
1760    LET Y(1,2)=-DET(F) !BC-AD
1770    LET Y(2,1)=-1
1780    LET Y(2,2)=F(1,1) !A
1790    WHEN EXCEPTION IN
1800       MAT Y=(1/F(1,2))*Y !(1/B)倍
1810    USE
1820       PRINT "Yパラメータは存在しません。"
1830       STOP
1840    END WHEN
1850 END SUB
1860 !-------------------- ここまでがサブルーチン
1870
1880
1890 DIM mF(2,2),mZ(2,2),mY(2,2) !F,Z,Yパラメータ
1900 DIM vi(2),vo(2) !電流や電圧のベクトル
1910 DIM T1(2,2),T2(2,2) !作業用
1920
1930
1940 !●1次RC回路、直列RC回路、ローパスフィルタ
1950 !i1→   i2→
1960 ! ─R─┬─
1970 !E1↑  C ↑E2
1980 ! ─-─┴─
1990 !i1=3*SQR(2)*SIN(377*t)[A]、R=30[Ω]、C=66.3[μF]
2000
2010 LET R=30
2020 LET C=66.3e-6
2030
2040
2050 !●Fパラメータ、基本行列
2060 MAT mF=IDN !単位行列
2070
2080 CALL seriesF(R,T1)
2090 MAT mF=mF*T1 !縦続接続
2100
2110 CALL shuntF(F2Ohm(C),T2)
2120 MAT mF=mF*T2
2130
2140 PRINT "Fパラメータ"
2150 MAT PRINT mF;
2160
2170
2180 !●Zパラメータ、インピーダンス行列 V=Z*I
2190 CALL F2Z(mF,mZ)
2200 PRINT "Zパラメータ"
2210 MAT PRINT mZ;
2220
2230
2240 !●(E1)=[F](E2)より
2250 ! (i1)  (i2)
2260 LET vi(2)=i2COMPLEX(3*SQR(2),0) !3[A}
2270 PRINT "i1=";
2280 CALL DispS(vi(2))
2290 LET vi(1)=mZ(1,1)*vi(2) !E=R*i、150∠-53.1°[V]
2300 PRINT "E1=";
2310 CALL DispS(vi(1))
2320 PRINT
2330
2340 MAT T1=INV(mF) !出力側を算出する
2350 MAT vo=T1*vi
2360
2370 PRINT "E2=";
2380 CALL DispS(vo(1))
2390 PRINT "i2=";
2400 CALL DispS(vo(2))
2410 PRINT
2420
2430
2440 !●Yパラメータ、アドミタンス行列 I=Y*V
2450 CALL F2Y(mF,mY)
2460 PRINT "Yパラメータ"
2470 MAT PRINT mY;
2480
2490
2500 END
 

レス、遅くなりました。

 投稿者:NINA  投稿日:2008年11月25日(火)23時07分41秒
返信・引用
  荒田様、山中様、親切なご説明ありがとうございました!!

お二人のおかげで、十進BASICのすごさがわかったような気がします。
そして、自分の勉強不足も…。
これを機に、十進BASICを少しでも使えるように勉強したいと思います。


返事が遅くなったこと、連名でのお返事本当に申し訳ありません。
ありがとうございました。
 

Re: mat命令と複素数計算

 投稿者:山中和義  投稿日:2008年11月26日(水)08時19分38秒
返信・引用  編集済
  > No.114[元記事へ]

大熊 正さんへのお返事です。
> (1)マトリクス[A]の中にコンデンサーなどのアドミッタンスをスマートに入れる方法。
> (2)同じく 電源のマトリクス[B}に、SIN(F,T)表示等でスマートに入れる方法。

節点電位法によるサンプルです。
以前第1掲示板に投稿した直流回路の改修版になります。
1000 !電気回路シミュレーション(節点電位法) 交流回路
1010
1020 !・各節点の電位を表示する
1030 !・各素子への電流、電位を表示する
1040
1050 OPTION ARITHMETIC COMPLEX
1060
1070 LET j=SQR(-1) !虚数単位 ※電気系はjを使う
1080
1090 LET f=60 !周波数[Hz]
1100 DEF w=2*PI*f !角周波数ω
1110
1120 DEF H2Ohm(L)=j*w*L ![H]を[Ω]へ
1130 DEF F2Ohm(C)=1/(j*w*C) ![F]を[Ω]へ
1140 DEF xL(L)=w*L !誘導リアクタンス
1150 DEF xC(C)=1/(w*C) !容量リアクタンス
1160
1170 SUB DispS(z) !複素数をS表示する ※スタインメッツ(Steinmetz)
1180    PRINT ABS(z);
1190    IF ABS(z)<>0 THEN
1200       IF arg(z)<>0 THEN PRINT "∠";DEG(arg(z));"°";
1210    END IF
1220    !PRINT
1230 END SUB
1240
1250 FUNCTION S2COMPLEX(l,th) !S表示(極座標形式)を複素数へ
1260    LET S2COMPLEX=COMPLEX(l*COS(RAD(th)),l*SIN(RAD(th)))
1270 END FUNCTION
1280 FUNCTION i2COMPLEX(im,th) !瞬時値式を複素数へ ※最大値、初期位相
1290    LET i2COMPLEX=S2COMPLEX(im/SQR(2),th) !実効値、初期位相
1300 END FUNCTION
1310 !-------------------- ここまでがサブルーチン
1320
1330 !---------- ↓↓↓↓↓ ----------
1340 LET Ns=0 !電圧源の数
1350 LET Nd=3 !節点の数
1360 !---------- ↑↑↑↑↑ ----------
1370
1380 LET N=Nd+Ns
1390
1400 !●キルヒホッフの電流則より、節点方程式を組み立てる
1410 DIM A(N,N),x(N),b(N) !連立方程式 Ax=b
1420 MAT A=ZER
1430 MAT b=ZER
1440
1450
1460 DIM el_tmp$(100),ev_tmp(100),nd1_tmp(100),nd2_tmp(100) !素子の属性
1470 LET K=0
1480
1490 SUB AddElements(el$,ev,nd1,nd2) !回路を記録する
1500    LET K=K+1 !連番で回路を記録する ※注意. 方程式の成分番号と一致しない
1510    LET el_tmp$(K)=el$
1520    LET ev_tmp(K)=ev
1530    LET nd1_tmp(K)=nd1
1540    LET nd2_tmp(K)=nd2
1550
1560
1570    !連立方程式を組み立てる
1580    ! ┌  │  ┐┌ ┐ ┌ ┐
1590    ! │G │±1││V │=│I │
1600    !───┼─────────
1610    ! │±1│-Zp││Ip│ │Ep│
1620    ! └  │  ┘└ ┘ └ ┘
1630
1640    SELECT CASE UCASE$(el$(1:1)) !素子に応じて
1650    CASE "V" !電圧源なら
1660       LET p=VAL(el$(2:LEN(el$)))+Nd !番号を得る
1670       LET A(nd1,p)=A(nd1,p)-1 !電流Ipが節点iから節点jへ流れたとして、(Vi-Vj)-Ip*Zp=Ep
1680       LET A(p,nd1)=A(p,nd1)-1
1690       LET A(nd2,p)=A(nd2,p)+1
1700       LET A(p,nd2)=A(p,nd2)+1
1710       LET A(p,p)=A(p,p)+0 !内部抵抗Zpは0とする
1720       LET b(p)=b(p)+ev !起電力
1730
1740    CASE "I" !電流源なら
1750       LET b(nd1)=b(nd1)-ev
1760       LET b(nd2)=b(nd2)+ev
1770
1780    CASE ELSE !素子なら
1790       LET Gij=1/ev
1800       !対角成分 ※節点に接続された素子(アドミタンス)の和
1810       LET A(nd1,nd1)=A(nd1,nd1)+Gij
1820       LET A(nd2,nd2)=A(nd2,nd2)+Gij
1830       !その他の成分 ※節点に接続された素子(アドミタンス)に-1をかけたものの和
1840       LET A(nd1,nd2)=A(nd1,nd2)-Gij
1850       LET A(nd2,nd1)=A(nd2,nd1)-Gij
1860
1870    END SELECT
1880 END SUB
1890 !-------------------- ここまでがサブルーチン
1900
1910 !---------- ↓↓↓↓↓ ----------
1920
1930 !●回路図 ※1次RC回路、直列RC回路、ローパスフィルタ
1940 ! ─2─R1─3─
1950 !  │   │
1960 !  i3   C2
1970 !  │   │
1980 ! ─1───┴─
1990 !  │
2000 !  ≡アース
2010 ! i3=3*SQR(2)*SIN(377*t)[A]、R1=30[Ω]、C2=66.3[μF]
2020
2030 !素子: Rn,Vn,In、n:番号(連番) ※2文字目以降は番号
2040 !値:
2050 !端子番号(起点): 1以上の値 ※節点
2060 !端子番号: 1以上の値 ※節点
2070
2080 CALL AddElements("R1",30,2,3) !30[Ω]、枝路電流は2→3と仮定する
2090 CALL AddElements("C2",F2Ohm(66.3e-6),3,1) !C=66.3[μF]
2100 CALL AddElements("i3",i2COMPLEX(3*SQR(2),0),1,2) !3[A]
2110
2120 !※電圧源の番号は1からの連番 例. CALL AddElements("V1",?,?,?) !?[V]
2130 !なし
2140
2150 LET GND=1 !※アース
2160
2170 !---------- ↑↑↑↑↑ ----------
2180
2190
2200 FOR i=1 TO Nd !結線されていない節点 1*Vi=0
2210    IF A(i,i)=0 THEN LET A(i,i)=1
2220 NEXT i
2230 LET A(GND,GND)=0 !電位を0とする
2240
2250 MAT PRINT A;
2260 MAT PRINT b;
2270
2280
2290 DIM Ai(N,N) !連立方程式を解く
2300 MAT Ai=INV(A)
2310 MAT x=Ai*b
2320
2330
2340 FOR i=1 TO Nd !各節点の電位、流れ込む電流を表示する
2350    PRINT "節点";STR$(i);":";
2360    CALL DispS(x(i))
2370    PRINT "[V] ,";
2380    CALL DispS(b(i))
2390    PRINT "[A]"
2400 NEXT i
2410 PRINT
2420
2430 FOR i=1 TO K-Ns !各素子に流れる電流、電位を表示する
2440    PRINT el_tmp$(i);":";
2450    LET t$=el_tmp$(i)(1:1)
2460    IF UCASE$(t$)="I" THEN !電流源なら
2470       CALL DispS(ev_tmp(i))
2480       PRINT "[A]",
2490       CALL DispS(x(nd2_tmp(i))-x(nd1_tmp(i)))
2500       PRINT "[V]"
2510    ELSE
2520       CALL DispS((x(nd1_tmp(i))-x(nd2_tmp(i)))/ev_tmp(i))
2530       PRINT "[A]",
2540       CALL DispS(x(nd1_tmp(i))-x(nd2_tmp(i)))
2550       PRINT "[V]"
2560    END IF
2570 NEXT i
2580 PRINT
2590
2600 FOR i=1 TO Ns !電圧源に流れる電流、電位を表示する
2610    PRINT el_tmp$(K-Ns+i);":";
2620    CALL DispS(x(Nd+i))
2630    PRINT "[A]",
2640    CALL DispS(ev_tmp(K-Ns+i))
2650    PRINT "[V]"
2660 NEXT i
2670
2680
2690 END
 

(無題)

 投稿者:大熊 正  投稿日:2008年11月26日(水)12時16分55秒
返信・引用
  山中様
大熊です。毎回、御丁寧な回答を有難うございます。
総てをまだ理解できないでいますが、SUB命令のスタイルなどを
一辺に覚えました。

所で、御回答で気になることがあるので質問いたします。

(1) 電流でやってますが、そのため E1に位相が付いています。
    周波数特性(ボード線図)などでは、
        E1 100Vで位相0度を加えると E2 I2 、そして最後にI1
    はどうか・・・・。
    のように逆に成ると思います。電圧と電流の比例関係から
    E1の結果を単純に逆計算、E1を100Vに直し、E1の位相を
    E2に加減するという事になるのでしょうか。

(2) 1090 LET f=60 !周波数
    となってますが、周波数特性(ボード線図)などでは、
    周波数 f=10 から 10000まで
    等と成ります。
    下に DATA 文を付け、READ DATA 等とやるのでしょうか。
    周波数を DIM FF(fの指定,1)
        出力も  DIM EE2(出力の格納,1)
    等とやると、可能とおもいますが、いかがでしょうか。


(3) 例えば、このローパスフィルターが5段つずいたら、
    F行列を5乗するのですか、
    其の時 (A)^5 でしょうか。または、FOR --NEXTですか。


(4) 私の「有限要素法」とは、・・・熱とか、磁気や電位の表示で
    たとえば、楕円形の板が在ったとき、その形状を小さな三角▽に
    分割し、連立方程式を立てる。・・・時間tにも関係します。
    楕円の板のA(X,Y)に100度を加えると他の部分A(P,Q)の温度は
        どうなるか,・・・また、それを色で表示せよ・・・。
    時間的にはどうか・・・・と言ったような問題です。
    実は、無料のソフトがあるようなのですが、「リナックス」とか
    で作られ、総ての問題に対しまだ今は、完全には完成出来てない
    と聞きました。N88でのソフトに,近い問題のソフト例があり
    また昔ですが、本(¥2,300)も出ています。
    「BASICによる 有限要素法の基礎」戸川 隼人 サイエンス社
    これは、マトリクスで解いていません。従ってソフトの見通し
    が悪く、この部分は一体何をしてるのか良く分らない・・・
    という欠点があります。マトリクスと複素数の両方ができる
    10進BASICなら、それが可能で、あるいはもう既に出来てる
    のかと思い質問・投稿しました。

(5) 脱線ですが、この投稿欄に機械語のことがありました。SECOND様
    このソフトは万能で、たとえば、今回のローパスフィルタでも
    其のソフトのある同じホルダーにおけば、動作可能なのですか。
 

Re: (無題)

 投稿者:山中和義  投稿日:2008年11月26日(水)13時42分16秒
返信・引用  編集済
  > No.119[元記事へ]

大熊 正さんへのお返事です。


>(1) 電流でやってますが、そのため E1に位相が付いています。
>
>(2) 1090 LET f=60 !周波数
>    となってますが、周波数特性(ボード線図)などでは、
>    周波数 f=10 から 10000まで 等と成ります。

fのFOR 〜NEXT文で毎回計算し直せばいいかと思います。
繰り返し部分をサブルーチン化するとプログラムの見通しが良くなると思います。


例.

※サブルーチン部分は省略
DIM mF(2,2),mZ(2,2) !F,Zパラメータ
DIM vi(2),vo(2) !電流や電圧のベクトル
DIM T1(2,2),T2(2,2) !作業用

!●1次RC回路、直列RC回路、ローパスフィルタ、積分回路
!i1→   i2→
! ─R─┬─
!E1↑  C ↑E2
! ─-─┴─
!E1=5[V]、R=1k[Ω]、C=0.1[μF]

LET R=1e3
LET C=0.1e-6

SUB routine
!※Fパラメータ、基本行列
   MAT mF=IDN !単位行列
   CALL seriesF(R,T1) !縦続接続
   MAT mF=mF*T1
   CALL shuntF(F2Ohm(C),T2)
   MAT mF=mF*T2


   !※Zパラメータ、インピーダンス行列 V=Z*I
   CALL F2Z(mF,mZ)


   !※(E1)=[F](E2)より
   ! (i1)  (i2)
   LET vi(1)=5 !5[V]
   LET vi(2)=vi(1)/mZ(1,1) !i=V/R、?[A]

   MAT T1=INV(mF) !出力側を算出する
   MAT vo=T1*vi
END SUB


SET bitmap SIZE 800,400 !画面を横長へ
!※2SET bitmap SIZE 300,600 !画面を横長へ
SET WINDOW -1,6, -1,2 !表示領域
!※2SET WINDOW -1,6, -91,1 !表示領域
!※3SET WINDOW -1,6, -20,1 !表示領域
DRAW grid !目盛り

FOR f=1 TO 6 !x軸が対数
   PLOT TEXT ,AT f-0.3,-0.15: mid$("10  100 1k  10k 100k1M  ",4*(f-1)+1,4)
NEXT f
FOR f=10 TO 100000 STEP 100 !周波数[Hz]
   CALL routine

   LET vv=vo(1)/vi(1)
   PLOT LINES: LOG10(f),ABS(vv); !振幅特性
   !※2PLOT LINES: LOG10(f),DEG(ATN(Im(vv)/Re(vv))); !位相θ
   !※3PLOT LINES: LOG10(f),20*LOG10(ABS(vv)); !利得[dB]
NEXT f


END



>(3) 例えば、このローパスフィルターが5段つずいたら、

行列のべき乗はMAT文では記述できませんので、FOR〜NEXT文で乗算を繰り返します。


例.
!●はしご回路の合成抵抗 a-b端子間

!a─R1┬R3┬R5┬ … ┬Rn┬ …
!   R2 R4 R6  Rn-1 Rn+1
!b──┴─┴─┴   ┴─┴
!
LET R1=1 !1,2,1,2,…,1,2,1
LET R2=2

CALL seriesF(R1,T1) !─R1┬
CALL shuntF(R2,T2)  !  R2

MAT mF=IDN !単位行列
FOR i=1 TO 5 !段数
   MAT mF=mF*T1 !─R1┬R1┬ … ┬R1┬
   MAT mF=mF*T2 !  R2 R2   R2 R2
NEXT i
MAT mF=mF*T1 !─R1┐

PRINT "Fパラメータ"
MAT PRINT mF;
 

Re: (無題)

 投稿者:SECOND  投稿日:2008年11月26日(水)18時25分24秒
返信・引用
  > No.119[元記事へ]

大熊 正さんへのお返事です。

> (5) 脱線ですが、この投稿欄に機械語のことがありました。SECOND様
>     このソフトは万能で、たとえば、今回のローパスフィルタでも
>     其のソフトのある同じホルダーにおけば、動作可能なのですか。


機械語について、あやまった御理解が、見受けられますが、私のカン違いかも知れません。
その場合は、以下、聞き流してください。

機械語は、アセンブラー(Assembler) とも呼ばれ、その昔、BASIC も C言語も無かった時代に、
最初に有った言語、即ち、CPU、プロセッサが、直接認識できる、唯一の言語です。

機械語は16進コードそのもので見づらい。
そこで、mov ax,1234h とか、push ax などの、シンボルを、1対1で機械語に、対応させて、
見やすくしたものを、アセンブラー言語 と呼んでいます。

十進 BASIC.EXE 本体は、その記述を、機械語に翻訳するための「システム言語プログラム」
という事です。その他の方面の言語なども全て、同様です。

最終的に、機械語にならないと、CPUは、認識、実行できません。

-------------------------------------------------------------------
投稿した機械語は、本来、BASIC.EXE が、翻訳する文の一部を、
手で、直接に翻訳代行したものと言えます。

なぜ、そんな事をしたのかと、いうのは、
翻訳の冗長性を外したり、高速のための書き方、追求でした。
ご質問の件は、ご推察されるとおりで、専用に書き直さないと、使用できません。
 

周波数プログラム

 投稿者:大熊 正  投稿日:2008年11月27日(木)15時48分15秒
返信・引用
  山中様   大熊です。
周波数のプログラムを有難うございました。
サブルーチンにつなげたら直ぐ軽快に動きました。

(1)最後のDB表示の#3と位相表示の#2のグラフ
   を一緒に表示したいのですが、
   今のままで、「!」マークを外し、そのまま
   つなげても動きませんでした。
   DBの縦目盛りは左側に、位相の0−90度目盛りは
   右側にといった具合です。
   こうすると、本にある「ボード線図」ずばりに
   なります。


(2)位相表示は、なにか周波数の文字の上が表示されて
   ません。
   私の バージョンは、VER 5.02 ですが、
   最新はVER 7.2.8 のようです。
   これが原因でしょうか。
   私は、ハードデスクの「D」に本「ブルーバックス」
   に添付のCD ROM を指示に従い展開したのですが、
   インターネット上の「(仮称)10進BASIC」にある
   VER 7.2.8 のを、そのまま同じ「フォルダー」に
   コピー「展開?}したら駄目でしょうか。
   前のVER 5.02 は、この本のサンプルも一緒に
   入ってるのでどこまでがVER 5.02 本体なのか
   分らずVER 5.02 だけ消すのは困難なのです。

   VER 5.02をVER 7.2.8 で上書きするのはどう
   するのですか。

(3)突然ですが、同じ行数と列数のMATには、
       固有値成るものが、あるそうですが、
   この
 

周波数特性 続き 大熊

 投稿者:大熊 正  投稿日:2008年11月27日(木)15時55分50秒
返信・引用
  山中 様  大熊です。
確認のつもりが間違って投稿を押してしまいました。



(3)突然ですが、同じ行数と列数のMATには、
       固有値なるものが、あるそうですが、
    この命令語は単独で在るのでしょうか。
   または、此れを解いて表示するプログラム
   があれば御教えください。



 敬具
 

リラックス

 投稿者:SECOND  投稿日:2008年11月27日(木)19時09分8秒
返信・引用  編集済
  !4つの振り子(再投稿 失われたログ)

!2重振子Chaos
LET g= 9.8 !m/s^2
LET m1=0.1 !kg
LET m2=0.1 !kg
LET L1= 5 !m
LET L2= 5 !m
!
LET dt=0.05 !sec. 演算ピッチ。
!
LET μ2=m2/(m1+m2)
LET L21=L2/L1
DEF ss1(w2,θ1,θ2)=-g/L1*SIN(θ1) -μ2*L21*w2^2*SIN(θ1-θ2)
DEF ss2(w1,θ1,θ2)=-g/L2*SIN(θ2) +w1^2*SIN(θ1-θ2)/L21
DEF D(θ1,θ2)=1-μ2*COS(θ1-θ2)^2
DEF α1(w1,w2,θ1,θ2)=( ss1(w2,θ1,θ2) -L21*μ2*COS(θ1-θ2)*ss2(w1,θ1,θ2) )/D(θ1,θ2)
DEF α2(w1,w2,θ1,θ2)=(-ss1(w2,θ1,θ2)*COS(θ1-θ2)/L21 +ss2(w1,θ1,θ2) )/D(θ1,θ2)

SUB RK(θ1,θ2,w1,w2)
   LET w11=w1
   LET w12=w2
   LET α11=α1(w1,w2,θ1,θ2)
   LET α12=α2(w1,w2,θ1,θ2)
   !
   LET w21=w1+α11*dt/2
   LET w22=w2+α12*dt/2
   LET α21=α1(w21,w22,θ1+w11*dt/2,θ2+w12*dt/2)
   LET α22=α2(w21,w22,θ1+w11*dt/2,θ2+w12*dt/2)
   !
   LET w31=w1+α21*dt/2
   LET w32=w2+α22*dt/2
   LET α31=α1(w31,w32,θ1+w21*dt/2,θ2+w22*dt/2)
   LET α32=α2(w31,w32,θ1+w21*dt/2,θ2+w22*dt/2)
   !
   LET w41=w1+α31*dt
   LET w42=w2+α32*dt
   LET α41=α1(w41,w42,θ1+w31*dt,θ2+w32*dt)
   LET α42=α2(w41,w42,θ1+w31*dt,θ2+w32*dt)
   !
   LET θ1=θ1+(w11+2*w21+2*w31+w41)*dt/6
   LET θ2=θ2+(w12+2*w22+2*w32+w42)*dt/6
   LET w1=w1+(α11+2*α21+2*α31+α41)*dt/6
   LET w2=w2+(α12+2*α22+2*α32+α42)*dt/6
END SUB

!----init.
LET a_1=PI*0.8 !初期角度1
LET a_2=PI*0.9 !  〜 2
LET a_3=0 ! 初期角速度1
LET a_4=0 !    〜 2
!
LET b_1=-a_1+0.001
LET b_2=-a_2
LET b_3=0
LET b_4=0
!
LET c_1=a_1
LET c_2=a_2+0.002
LET c_3=0
LET c_4=0
!
LET d_1=-a_1
LET d_2=-a_2+0.003
LET d_3=0
LET d_4=0
!
!----run
LET w=14
SET WINDOW -w,w,-w,w
SET LINE width 2 !4
SET LINE COLOR 2 !43
LET r1=SQR(m1)
LET r2=SQR(m2)
LET t0=TIME
DO
   LET t=TIME
   IF dt=< ABS(t-t0) THEN
      SET DRAW mode hidden
      CLEAR
      PLOT TEXT,AT 0.25*w,0.9*w:"マウス 右ボタンで、終了。"
      PLOT TEXT,AT -0.98*w,0.93*w,USING"演算ピッチ=#.### 秒":dt
      PLOT TEXT,AT -0.98*w,0.87*w,USING"描画ピッチ=#.### 秒":t-t0
      LET t0=t
      SET AREA COLOR 15
      DRAW disk WITH SCALE(3.86,4.67)
      SET AREA COLOR 1
      DRAW PDL1X2(a_1,a_2) WITH ROTATE(a_1)*SHIFT(-3,3)
      DRAW PDL1X2(b_1,b_2) WITH ROTATE(b_1)*SHIFT(3,3)
      DRAW PDL1X2(c_1,c_2) WITH ROTATE(c_1)*SHIFT(-3,-3)
      DRAW PDL1X2(d_1,d_2) WITH ROTATE(d_1)*SHIFT(3,-3)
      CALL RK(a_1,a_2,a_3,a_4)
      CALL RK(b_1,b_2,b_3,b_4)
      CALL RK(c_1,c_2,c_3,c_4)
      CALL RK(d_1,d_2,d_3,d_4)
      SET DRAW mode explicit
   END IF
   WAIT DELAY 0 !ノートパソコン等の消費電力を押える。
   MOUSE POLL mx,my,mlb,mrb
LOOP UNTIL mrb=1

PICTURE PDL1X2(θ1,θ2)
   DRAW circle WITH SCALE(0.3)
   DRAW PDLM(L1,r1)
   DRAW PDLM(L2,r2) WITH ROTATE(θ2-θ1)*SHIFT(0,-L1)
END PICTURE

PICTURE PDLM(L,r)
   PLOT LINES: 0,0;0,-L
   DRAW disk WITH SCALE(r)*SHIFT(0,-L)
END PICTURE

END
 

Re: リラックス

 投稿者:GAI  投稿日:2008年11月27日(木)19時35分53秒
返信・引用
  > No.125[元記事へ]

SECONDさんへのお返事です。

前回の古代生物といい、今回のものといい大変面白く遊び心満載です。
SECONDさんが作られた作品をどんどんアップして紹介してください。
こんなことがプログラムを組むことで可能なんだといつも驚かされます。
お仕事はプログラマーなんですか?
 

Re: 周波数プログラム

 投稿者:山中和義  投稿日:2008年11月27日(木)19時37分25秒
返信・引用  編集済
  > No.123[元記事へ]

大熊 正さんへのお返事です。


> (1)最後のDB表示の#3と位相表示の#2のグラフを一緒に表示したいのですが、


縦軸の目盛りが違うので、調整が必要かと思います。半固定で表示するようにしてみました。

例.

後半のグラフ描画の部分
!SET bitmap SIZE 600,600 !画面を大きくする
SET WINDOW -0.5,6.5, -50,5 !表示領域
DRAW grid(1,5) !左端の目盛り

FOR f=1 TO 6 !x軸が対数
   PLOT TEXT ,AT f-0.3,-0.15: mid$("10  100 1k  10k 100k1M  ",4*(f-1)+1,4)
NEXT f

FOR f=10 TO 100000 STEP 100 !周波数[Hz]
   CALL routine
   LET vv=vo(1)/vi(1)
   PLOT LINES: LOG10(f),20*LOG10(ABS(vv)); !利得[dB]
NEXT f
PLOT LINES


SET TEXT COLOR 2
FOR i=5 TO -45 STEP -5 !右端の縦軸目盛り
   PLOT TEXT ,AT 6,i: STR$(i*2)&"°"
NEXT i

SET LINE COLOR 2
FOR f=10 TO 100000 STEP 100 !周波数[Hz]
   CALL routine
   LET vv=vo(1)/vi(1)
   PLOT LINES: LOG10(f),DEG(ATN(Im(vv)/Re(vv)))/2; !位相θ ※1/2倍
NEXT f
PLOT LINES


END


> (2)位相表示は、なにか周波数の文字の上が表示されてません。


周波数のグラフは、目盛りが1度ずつ狭いところに重ね書きされて解読できない状態になります。
たとえば、30度ずつ間隔の指定もできますが、今回はしていません。(手抜きです)


>    VER 5.02をVER 7.2.8 で上書きするのはどうするのですか。


・BASIC本体のフォルダ D:\BASIC32w 全体です。これをエクスプローラで削除してください。
・その後、ダウンロードした新しいBASICをこのフォルダにインストールします。
・本のサンプルプログラム、たぶん別のフォルダにまとめられていると思いますので、
 BASIC本体をインストールした後、(BASIC本体とは別のフォルダに)コピーすればいいと思います。
 ※BASIC本体にもかなりのサンプルが添付されています。


> (3)突然ですが、同じ行数と列数のMATには、固有値なるものが、あるそうですが、
>    この命令語は単独で在るのでしょうか。
>    または、此れを解いて表示するプログラムがあれば御教えください。


命令語はありません。プログラムをつくって求める必要があります。


BASIC VER5.02本体
 

Re: リラックス

 投稿者:SECOND  投稿日:2008年11月27日(木)20時05分43秒
返信・引用
  > No.126[元記事へ]

GAIさんへのお返事です。

ごめんなさい.もう種切れです。(^ ^; プログラマーでもなんでもありません。

これらは、全て、数学の先人たちが、残してくれた遺産です。
ねむくなるような数理的な世界を、楽しくできれば、なによりです。
 

困惑?

 投稿者:GAI  投稿日:2008年11月28日(金)10時18分16秒
返信・引用
  今まで何事もなく立ち上がっていた十進BASICの画面が、突然下のタスクバーには入り込むのですが、プログラムを貼り付ける画面が広がらず(テキスト画面とグラフィック画面は広がる。)コピーしたプログラムを動かそうとしても動かせない状態になってしまいました。
どうやって元の状態に出来るのか解らずにいます。
ちなみに一度全てを削除して、もう一度インストゥールを繰り返しましたが、結果は同じでした。
解決方法がありましたらよろしくご教授下さい。
なおosはWINDOW xp です。
 

Re: 困惑?

 投稿者:山中和義  投稿日:2008年11月28日(金)10時56分15秒
返信・引用  編集済
  > No.129[元記事へ]

GAIさんへのお返事です。

Windows Meでの話ですが、
・他のアプリケーションと併用(同時、その後も含む)するとこの現象(同じ?)が起こります。
 十進BASICでプログラムを実行するとリソースメモリ(実装メモリとは違う)を消費しているみたいです。
 このリソース不足状態で発生しやすいです。また、起動もできない場合があります。
 例. インターネットエクスプローラでPDFファイルを閲覧しながら、プログラムする。

対処
・OS(パソコン)を再起動して、併用しない。
 

周波数プログラム その他

 投稿者:大熊 正  投稿日:2008年11月28日(金)13時40分34秒
返信・引用
  山中 様   大熊です。

(1)振幅と位相の同時表示の追加プログラムを有難うございました。
   直ぐ実施したら、上手く動きました。
(2)ver の変更の件ですが、

   BASIC VER5.02本体
  とある35のファイル総てを、一つづつ消すのでしょうか、

   消す場合「ごみ箱」は駄目ときいていましたが、
   「エクスプローラー」はどこにあるのでしょうか。

(3)ver5.02のある、ファイルホルダーから
   「エクスプローラー」で一つづつ35個のファイル
   を消して、インターネットにある ver7.2.8を
   指定、展開先が、元のver5.02のある、
   ファイルホルダーと理解して宜しいですか。
(4)インターネットの「仮称10進basic]では、
   2つのプログラムが「・・・の場合は、こちら・・」
   と書いてありますが、ハードデスクの「D」では、
   下の二番目でしょうか。

敬具。
 

Re: 周波数プログラム その他

 投稿者:山中和義  投稿日:2008年11月28日(金)14時40分32秒
返信・引用  編集済
  > No.131[元記事へ]

大熊 正さんへのお返事です。

>    BASIC VER5.02本体
>    とある35のファイル総てを、一つづつ消すのでしょうか、
>


1つずつ削除していくのが無難でしょう。
まとめてのファイル削除はいろいろなやり方があります。
たとえば、ドラグ、ShiftやCtrlキー押しながらをクリックでの範囲指定など。

5.02が入っているフォルダに、自作などのファイルがなければ、そのフォルダをまるごと削除しても良いです。
(入っている場合はバックアップして後で元にもどせば良いだけですが、、、)


>    消す場合「ごみ箱」は駄目ときいていましたが、
>

削除されたファイルなどは一端ごみ箱に入ると思いますが、後でごみ箱を空にしてください。


>    「エクスプローラー」はどこにあるのでしょうか。
>

デストップ上の「マイコンピュータ」(コンピュータのアイコン)を右クリックして表示されるメニューにあります。
エクスプローラの画面は、マイコンピュータをダブルクリック(シングルクリック設定されている場合もある)
して表示される画面(ファイル、フォルダなどの一覧を見る画面)のことです。


> (3)ver5.02のある、ファイルホルダーから
>    「エクスプローラー」で一つづつ35個のファイル
>    を消して、インターネットにある ver7.2.8を
>    指定、展開先が、元のver5.02のある、
>    ファイルホルダーと理解して宜しいですか。

はい。


> (4)インターネットの「仮称10進basic]では、
>    2つのプログラムが「・・・の場合は、こちら・・」
>    と書いてありますが、ハードデスクの「D」では、
>    下の二番目でしょうか。
>


上の「Windows95/98/Me/NT4.0/2000/XP/Vista インストーラ版」の方が良いと思います。

ZIPファイルの解凍が可能なら、下の「Windows95/98/Me/NT4.0/2000/XP/Vista アーカイブ版」でも大丈夫です。
 

Re: 周波数特性 続き 大熊

 投稿者:山中和義  投稿日:2008年11月28日(金)20時05分5秒
返信・引用  編集済
  > No.124[元記事へ]

大熊 正さんへのお返事です。

> (3)突然ですが、同じ行数と列数のMATには、固有値なるものが、あるそうですが、
>    略
>    または、此れを解いて表示するプログラムがあれば御教えください。

!直接法による行列の固有値を求める

OPTION ARITHMETIC COMPLEX

LET i=SQR(-1) !虚数単位

LET cEps=1e-8 !誤差 ※単精度


LET N=3 !N次正方行列

FUNCTION tr(A(,)) !行列Aのトレース
   LET t=0
   FOR j=1 TO N
      LET t=t+A(j,j)
   NEXT j
   LET tr=t
END FUNCTION


DIM c(N) !多項式 X^N+c(1)*X^(N-1)+c(2)*X^(N-2)+ … +c(N-1)*X+c(N) の係数
SUB DKA_00(A(),Xr()) !DKA法(Durand Kerner Aberth)
   LET r=1 !初期値を仮定する
   FOR j=2 TO N
      LET rn=ABS(A(j))^(1/j)
      if r<rn then LET r=rn
   NEXT j
   FOR j=1 TO N !半径rの円に等間隔に配置する
      LET Xr(j)=-A(1)/N+r*EXP( 2*PI*i/N *(j-3/4) ) !アーバスの初期値
   NEXT j

   FOR m=0 TO 100 !反復 ※調整要
      LET mfx=0
      LET maj=0
      FOR j=1 TO N
         LET Xk=1
         LET fx=1
         FOR w=1 TO N
            LET fx=fx*Xr(j)+A(w)
            IF w<>j THEN LET Xk=Xk*(Xr(j)-Xr(w))
         NEXT w
         LET Xr(j)=Xr(j)-fx/Xk
         IF mfx<ABS(fx) THEN LET mfx=ABS(fx)
         IF maj<ABS(fx/Xk) THEN LET maj=ABS(fx/Xk)
      NEXT j
      IF mfx<cEps AND maj<cEps THEN EXIT FOR !収束したら
   NEXT m
END SUB
!-------------------- ここまでがサブルーチン


DIM A(N,N) !行列A
!DATA 1,0,0 !λ=1(3重根)
!DATA 0,1,1
!DATA 0,0,1

!DATA 0,1,1 !λ=2,-1(重根)
!DATA 1,0,1
!DATA 1,1,0

!DATA 3,0,0 !λ=3,±i
!DATA 0,2,-5
!DATA 0,1,-2

DATA 2,1,-1 !λ=3,2,1
DATA 0,3,0
DATA 0,2,1

MAT READ A

MAT PRINT A;


!n次正方行列Aの固有多項式 det(tE-A)=t^n+c1*t^(n-1)+ … + cn を求める。
DIM X(N,N),cE(N,N)
MAT X=IDN !frame法
FOR k=1 TO N
   MAT X=A*X
   LET c(k)=-tr(X)/k
   MAT cE=(c(k))*IDN
   MAT X=X+cE
NEXT k
MAT PRINT c;

!ニュートン法などで解く。解が固有値になる。
DIM lmd(N)
CALL DKA_00(c,lmd)

FOR k=1 TO N
   PRINT "固有値=";lmd(k)
NEXT k



!※N個求まった場合の検算
LET s=1
FOR k=1 TO N
   LET s=s*lmd(k)
NEXT k
PRINT s, DET(A) !固有値の積=行列の行列式 Πλi=|A|

LET s=0
FOR k=1 TO N
   LET s=s+lmd(k)
NEXT k
PRINT s, tr(A) !固有値の和=行列のトレース Σλi=trA


END
 

バージョンアップの件

 投稿者:大熊 正  投稿日:2008年11月29日(土)12時45分44秒
返信・引用
  (1)山中様 大熊です。
   バージョンアップは、お蔭様で上手く行きました。
   固有値も含め今までのソフトも順調に動きました。
      有難うございます。

(2)SECOND様 しだとアンモナイトの画も綺麗に出ま
      した。
 

トランプマジックの創作

 投稿者:GAI  投稿日:2008年11月29日(土)19時30分52秒
返信・引用
  十進BASICとは何の関係もありませんが、
今日一日、数学的構造を活かせるマジックができないかと挑戦してみて、次の手順を考えましたので、是非一度トランプを手にしてやってみて下さい。

*デックのセット方法(裏向きトップよりの順)
赤カード:3,4,8, J , K (マークはなんでもよい。)
黒カード:2,3, 4,6,8, K(同じくマークはなんでもよい。)
4枚のAをまず抜き出しておき、トップからの枚数目に次のカードを配置してください。

(裏向きトップからの枚数目のカードの配置:●カードはなんでもよい。)
1●    11●    21ハートA  31●     41赤4    51赤J

2●    12●    22●     32クラブA  42●      52●

3●    13黒4   23●     33黒3     43●

4●      14ダイアA   24●      34●      44●

5赤K     15●      25黒2     35●      45黒6

6●     16●      26●       36●      46●

7●     17黒K     27●       37黒8     47●

8●     18●      28●       38●       48●

9赤8    19●     29赤3    39●       49スペードA

10●    20●      30●      40●       50●

(やり方)
このようにセットしたパケットをなにげにテーブルに表向きにリボンスプレッドして
普通のカードであることを示す。
順番が狂わぬように集め、裏向きに手に持つ。
ここで一度フォールスカット(順番は元の状態に戻るようにする、偽のカット)をする。
奇数番目のカードをアップする(1,3,5・・・枚目のカードを上に少しずらす。)
これを最後までカードが互い違いになるまで繰り返し、上に上げたカードを全て抜き出し
テーブルに裏向きのまま置く。(順番が崩れないように注意。)<リバースフェローシャッフルと呼ぶ。>
手に残ったパケットで再び同じようにリバースフェローシャッフルをする。
抜き出したカード群は前の取り出してテーブルに置いている上に重ねておく。
これを繰り返すと手元には一枚のカードが残る。
これをテーブルに表向きに出すとクラブのAが現れる。
次に、テーブルに重ねていたパケットを大体半分になるように客に分けてもらう。
(正確に半分でなくてよく、上半分24枚〜27枚まで許される。)
上半分を演者がもらい、客のパケットの下半分の枚数を数える振りをしてパケットの上から一枚ずつテーブルにカウントしながら順序を逆転させる。
下半分の枚数が27枚〜24枚に入らない時は(枚数がオーバーする時)、カウントし終わった客のパケットのボトムから、演者のパケットのボトムへ数枚を何 気に移動させる。あるいはその逆に少ない場合は演者のパケットのボトムから数枚抜き出し、それの順序を逆転した数枚のカードを客のパケットのボトムに追加 しておく。
いずれにしても、客のパケットの枚数を27枚〜24枚の範囲に調節しておく。
調整したパケットを客に渡す。
演者と客はお互いのパケットを前の操作と同様にリバースフェローシャッフルをしていく。
それぞれ一枚ずつのカードが残るので、それをテーブルに表向きにする。
演者はダイアのA、客はハートのAが出現する。
これでテーブルには3枚のAが揃ったので、残りがスペードのA
ここで客に2つのパケットのうち、演者が捨てて重ねているパケットか、客が捨てた方のパケットかを選択させる。(ここは少し賭けであるが、客が自分の方のパケットを選ぶと心理的にみて構成している。)
こちらの思惑どうりに客が自分のパケットを選んだら(マジシャンズチョイスで客のパケットの方を選んだように見せかけるとよいだろう。)、パケットを受け取りテーブルに
時計の文字盤の様に1,2,3、・・・12時の位置にカードを上から裏向きのまま配置していく。
残ったカードは中央の針の位置に表向きにして置く。演者の方のパケットも表向きで重ねておく。
ここで客に12時の位置に置いたカード以外が選ばれるように誘導しながら、文字盤の位置にあるカードを一つを選ばせる。(12時を選ばせていい時は、客のパケット枚数が24枚または25枚の時に限る。)
(もし、客が6時の位置を選んだら貴方の勘はすばらしいと褒めてそのカードをめくって、最後のスペードのAを出して終了する。)
客が選んだカードを表向きにして、そのカードの数字が
黒ならそのカードの次から数えて時計回りの向きにその数だけ進み、そこのカードをめくって取り除いていく。(めくったカードは中央に表向きで重ねていく。)
また客が指定したカードが赤のカードなら反時計回りに進んでめくり、取り除いていく。
これを繰り返していく(取り除いたカードの次からまた進んで<最初の客が選んだカードの数ぶん>次のカードをめくる。)と最後に6時の位置にあったカードが一枚だけ残る。
このカードを思わせぶりに焦らせて表にすると、まさに最後のスペードのAが出現する。
他のカードに2枚として同じカードが含まれていないことを、中央にある表向きに重なっているパケットをテーブルにリボンスプレッドして演技を終わる。

原理的には二進法の利用と、継子立ての遊びを組み合わせた様な手順になります。
朝から取り組み、今ようやくどうにかまとめました。
何か手違いが生じたら、お教えください。
更に改良部分がありましたらヒントをお願いします。
 

「古代生物」について。

 投稿者:SECOND  投稿日:2008年11月29日(土)20時07分15秒
返信・引用  編集済
  V7.2.1 までは、乱数が異なり、動作できません、以降のバージョンが必要です。

※あやまって、cookie を、消してしまい、修正できなくなりました、すみません。
 無理に動かすと、図が汚くなると思います。
 

Re: トランプマジックの創作

 投稿者:山中和義  投稿日:2008年11月30日(日)17時53分57秒
返信・引用  編集済
  > No.135[元記事へ]

GAIさんへのお返事です。

> ここで客に12時の位置に置いたカード以外が選ばれるように誘導しながら、文字盤の位置にあるカードを一つを選ばせる。(12時を選ばせていい時は、客のパケット枚数が24枚または25枚の時に限る。)


時計状に配置するときのパケットの内容
元のカードの配置位置なら
26の場合
  37  5  45  29  13  49  41  33  25  17  9  1  51  47  43  39  35  31  27  23  19  15  11  7  3
27の場合
  37  5  45  29  13  49  41  33  25  17  9  1  51  47  43  39  35  31  27  23  19  15  11  7  3  50

実際のカードでは、黒は正、赤は負とすると
  8 -13  6 -3  4 sA -4  3  2  13 -8  ? -11  ?  ? …
となる。

1番目のカードがこの位置にくるので、もう1つの「赤J」にすればよいと思います。



> 原理的には二進法の利用と、継子立ての遊びを組み合わせた様な手順になります。


解りづらかったので、シミュレータをつくってみました。
継子立てにはいろいろな手法があるので、少しプログラムを修正すると対応できると思います。
!継子立て(ヨセフスの問題)をシミュレートする

LET N=12 !石の数 ※
LET P=-3 !除いていく位置 ※<----------
LET a=4 !開始位置 ※<----------


!●数理的

IF P>0 THEN !時計まわりなら
   PRINT MOD(a-1+f(N,P),N)+1
ELSE !反時計まわりなら
   PRINT MOD((N-a)-1+f(N,ABS(P)),N)+1 !左右反転して時計まわりにする
END IF
PRINT
FUNCTION f(n,p) !1番から時計まわりにp番目を取り除く
   IF n=1 THEN LET f=1 ELSE LET f=MOD(p-1+f(n-1,p),n)+1
END FUNCTION



!●シミュレータ

DIM s(N) !石の状態
FOR i=1 TO N !連番をつける
   LET s(i)=i
NEXT i

SET WINDOW -2,2,-2,2 !表示画面
LET r=1.5 !石の位置
SET TEXT JUSTIFY "center","half" !文字の位置
LET r2=1.8

CALL disp_stone !初期状態

PRINT "開始位置=";a
PRINT "除いていく位置=";P

!LET s(a)=0
!CALL disp_stone
LET k=N !残りの個数

DO UNTIL k=1 !残りの石が1つになるまで
   LET c=0 !カウンタ
   DO UNTIL c=ABS(P) !該当位置を見つける
      LET a=a+SGN(P) !±1 ※正の場合、時計まわり
      LET b=MOD(a-1,N)+1 !配置位置を換算する
      IF s(b)>0 THEN LET c=c+1 !石がある場合のみカウントする
   LOOP
   PRINT b !取り除く
   LET s(b)=-1
   LET k=k-1

   CALL disp_stone !現在の状態
LOOP


SUB disp_stone !環状に並べる
   SET DRAW mode hidden !ちらつきを抑える(開始)
   CLEAR
   FOR i=1 TO N
      LET th=RAD(90-i/N*360) !Y軸から時計まわり
      LET x=COS(th) !位置
      LET y=SIN(th)
      PLOT TEXT ,AT r2*x,r2*y: STR$(i) !番号
      IF s(i)>=0 THEN DRAW disk WITH SCALE(0.1)*SHIFT(r*x,r*y) !石
   NEXT i
   SET DRAW mode explicit !ちらつきを抑える(終了)
   WAIT DELAY 0.5
END SUB

END
 

そうだ!

 投稿者:GAI  投稿日:2008年11月30日(日)22時29分22秒
返信・引用
  そうだ!!!
1枚目と51枚目を共に赤のJであれば24〜27枚のいずれでも対応できるんですね。
(1枚目には気付いてはいるのだが、どうして共にセットしておけばいいと思いつかないんだろう、情けない。)
いつも急所を押さえるヒントを与えてもらい、ありがとうございます。
ほんとに助かります。
 

再度トランプで

 投稿者:GAI  投稿日:2008年12月 1日(月)22時44分34秒
返信・引用
  トランプが続いてすみませんが、次の手順を再現できるプログラムができないでしょうか?
1.一組のカード(52枚)をまずよくシャッフルする。
2.デックを表向きに持ち、奇数のカードをアップジョグ(上にすこしずらす)していき
  これらのカード全てを抜き取り(順番を変えないで)、ボトム側へ回す。
3.上半分(偶数群)から4,8,Q のカードを、
  下半分(奇数群)から3,7,J のカードをアップジョグしていき、これらを抜き取り、ボトムへ
4.上三分の一位から2,10のカード
  中三分の一位からA,9のカード
  下三分の一位から7,8のカードをアップジョグして、これを抜き取りボトムへ
5.上から順に、6,5,4,3,2,Aのカードをアップジョグして抜き取りボトムへ
6.赤カードをアップジョグしてボトムへ
7.上半分(黒カード群)からクラブ、下半分(赤カード群)からダイアカードをアップジョグしてボトムへ
以上の手順を行なうと、デックは裏向きトップから
ダイア、クラブ、ハート、スペードの順に
A,2,3,・・・J,Q,k と揃う。(原理は2進法の応用)
これをどのカードを選びますか?
の質問を受けながら入力待ちとして(2番では奇数、6番では赤、7番ではマーク、他は数字)進行していけるようにしたい。
他の任意のカードの配列もこの方法を使って調べたいので、数字と色とマークが独立に選択できていけるよであればうれしいのですが...
 

Re: 再度トランプで

 投稿者:山中和義  投稿日:2008年12月 3日(水)11時06分36秒
返信・引用
  > No.139[元記事へ]

GAIさんへのお返事です。

> トランプが続いてすみませんが、次の手順を再現できるプログラムができないでしょうか?

> これをどのカードを選びますか?
> の質問を受けながら入力待ちとして(2番では奇数、6番では赤、7番ではマーク、他は数字)進行していけるようにしたい。


メニュー形式ではありませんが、再現するプログラムを試作してみました。
コーディング形式がマンネリなので、今回は「文字列操作」でカードの動きを実現しています。
また、ビジュアル表示も追加していますが、必要に応じてその部分を削除してください。
十進BASICは、ビットマップ画像の処理が苦手ですから処理速度は期待できません。

ここからダウンロード

(実行画面)
 

カードが並んでいます

 投稿者:GAI  投稿日:2008年12月 3日(水)19時28分13秒
返信・引用
  おおおおーワンダフル。
トランプが実際に並んでいます。(どこから現れたのか?)
いちいち手作業でやっていた操作が一瞬で終了します。
しかも毎回カードは見事にばらばらでスタートできます。
中の構造はおぼろげながら読み解けますが、細部はまだ解読する力が私にはありません。
こんな長い過程のプログラムがよくこんな短時間にできますね。
問題を見た瞬間、だいたいこうプログラムを組めばいいんだとわかるもんなんですか?
プログラムを恐る恐る一部手直しをして、例えばダイアの2,4,5のカードだけをアウトジョグしてボトムへ回そうとあれこれ挑戦したのですが、いずれも機械がいうことを聞いてくれません。
ダイアと他のマークを含めた2,4,5のカードがアウトジョグされたりします。
AND で繋ごうと試みても、”ここにはANDは入れられません”などのコメントを受けます。
プログラムで特定のカード(マークと数字の指定)を、アウトジョグするにはどのように
記述したらよいか教えてください。
 

Re: カードが並んでいます

 投稿者:山中和義  投稿日:2008年12月 3日(水)20時09分59秒
返信・引用
  > No.141[元記事へ]

GAIさんへのお返事です。

> 例えばダイアの2,4,5のカードだけをアウトジョグしてボトムへ回そう

> プログラムで特定のカード(マークと数字の指定)を、アウトジョグするにはどのように記述したらよいか教えてください。


FOR i=1 TO N !該当するカード ※マークと数字
   k=CNum(c$,i)
   IF CMark$(c$,i)="D" AND ( k=2 OR k=4 OR k=5 ) THEN LET flg(i)=1
NEXT i
CALL shuffle(c$,flg)


または

FOR i=1 TO N !該当するカード ※カード
   SELECT CASE CGet$(c$,i)
   CASE "D2","D4","D5"
      LET flg(i)=1
   CASE ELSE
   END SELECT
NEXT i
CALL shuffle(c$,flg)
 

旧掲示板

 投稿者:白石 和夫  投稿日:2008年12月 4日(木)20時48分13秒
返信・引用
  旧掲示板が復活しています。
フリーソフトWeBoxを利用してWeb全体を取り込んで過去ログのページにアップしました。

http://www.geocities.jp/thinking_math_education/log/logs.html

 

グラフィックでお願いします。

 投稿者:GAI  投稿日:2008年12月 5日(金)07時34分7秒
返信・引用
  カードでのグラフィックが可能なことを利用して、次の現象を再現したいのですが
絵札(J,Q,K)とAの16枚を使う。
このカードを裏向きに4×4の行列形式に並べ(下の番号順に並べる)
カードの位置を(演者側から見た番号)
1  2  3  4
5  6  7  8
9  10 11 12
13 14 15 16
とする。
これ全体を一枚の紙と見立てて一枚のカードの大きさに折る操作を行なう。
<折り方の方法>
何処の位置(カードとカードの間の縦または横線)
でもかまわない部分を指定してもらい
例えば 1  2  3  4
     --------------
    5  6  7  8
の間の線ならば、1  2  3  4
のカードをひっくり返して
        5  6  7  8
のカードの上に重ねる。
また 2 |  3
      6 |  7
     10 | 11
     14 | 15
の線なら右半分(または左半分でもよい。)
を全て折り返して(カードはひっくり返ることになる。)

3 →  2
4 →  1
7 →  6
8 →  5
11 → 10
12 →  9
15 → 14
16 → 13
と重ねることとする。

これを客にその都度線を指定させ、16枚のカードが一つに重なるまで続ける。
(パケットは表向き、裏向きが混ざった状態にある。)
このパケットにおまじないをかけ、テーブルにリボンスプレッドしてみる。
(このとき、パケット全体をひっくり返しておく必要がある時が起きることもある。)

(パターンK)
仕込み:16枚のパケットの上から3,4,9,12枚目にKを配置しておく。
スタート:4×4に並べたカードの
     1,4,6,8,11,12,14,16番を表向きにする。(これは客から見てKに見える。)

(パターンA)
仕込み:16枚のパケットの上から5,7,8,16枚目にAを配置しておく。
スタート:4×4に並べたカードの
     1,3,5,6,7,9,11,14番を表向きにする。(これは客から見てAに見える。)

(パターンJ)
仕込み:16枚のパケットの上から4,9,10,15枚目にJを配置しておく。
スタート:4×4に並べたカードの
     2,5,7,9,12,13番を表向きにする。(これは客から見てJに見える。)

(パターンQ)
仕込み:16枚のパケットの上から1,4,14,16枚目にQを配置しておく。
スタート:4×4に並べたカードの
     3,4,6,8,9,11番を表向きにする。(これは客から見てQに見える。これは少し苦しい)

これらの仕込みと最初の初期設定からの折り返しを繰り返して、最後のパケットでの
スプレッドをするとそれぞれのパターンでの4枚だけのカードが 表向きで出現し、
他のカードは裏向きになっている。

というものです。(すみません、説明が長すぎて・・・)
 

Re: グラフィックでお願いします。

 投稿者:山中和義  投稿日:2008年12月 5日(金)19時39分34秒
返信・引用  編集済
  > No.144[元記事へ]

GAIさんへのお返事です。

> (パターンK)
> 仕込み:16枚のパケットの上から3,4,9,12枚目にKを配置しておく。
> スタート:4×4に並べたカードの
>      1,4,6,8,11,12,14,16番を表向きにする。(これは客から見てKに見える。)


折り紙の数理ですね。

●解析結果
向きが不動な箇所は、1,3,6,8,9,11,14,16である。 2,4,5,7,10,12,13,15は、反転する。
4×4配置なら
1  *  3  *
*  6  *  8
9  * 11  *
* 14  * 16
となる。

ところで、各カードの配置場所は、

  1  *  *  4  *  6  *  8  *  * 11 12  * 14  * 16 <-- Kのパターン
  ↓   ↓ ↓   ↓     ↓   ↓ ↓   ↓
  1  2  *  *  5  6  7  8  * 10 11  * 13 14 15 16 <-- シャッフル後
したがって、3,4,9,12にKを配置しておけばよい。

  1  *  3  *  5  6  7  *  9  * 11  *  * 14  *  * <-- Aのパターン
  ↓   ↓ ↓   ↓     ↓   ↓ ↓   ↓
  1  2  3  4  *  6  *  *  9 10 11 12 13 14 15  * <-- シャッフル後
したがって、5,7,8,16にAを配置しておけばよい。

  *  2  *  *  5  *  7  *  9  *  * 12 13  *  *  * <-- Jのパターン
  ↓   ↓ ↓   ↓     ↓   ↓ ↓   ↓
  *  *  *  4  *  *  *  *  9 10  *  *  *  * 15  * <-- シャッフル後
したがって、4,9,10,15にJを配置しておけばよい。

  *  2  3  *  *  6  *  8  9  * 11  * 13 14  *  * <-- Qのパターン
  ↓   ↓ ↓   ↓     ↓   ↓ ↓   ↓
  *  *  3  4  5  6  7  8  9 10 11 12  * 14 15  * <-- シャッフル後
したがって、1,2,13,16にQを配置しておけばよい。(訂正を反映)


次のプログラムで確認できます。どちらを折りたたむかで位置(a,b)は変わります。
LET N=4 !N行N列
LET a=-2 !折りたたむ位置(a,b)
LET b=2
DATA 0,1,1,0 !Qパターン ※1:表、0:裏
DATA 0,1,0,1
DATA 1,0,1,0
DATA 1,1,0,0
DIM M(N,N)
MAT READ M
FOR y=1 TO N !行
   FOR x=1 TO N !列
      IF MOD(ABS(x-a)+ABS(y-b),2)=1 THEN !格子上での距離 ※1:反転、0:そのまま
         LET M(y,x)=1-M(y,x) !論理否定
      END IF
      PRINT M(y,x); !「0が4つ」または「1が4つ」の位置
   NEXT x
   PRINT
NEXT y
END


シミュレータによるプログラムはこちらからダウンロード(前回と同じ、前回分も同梱)
 

御礼

 投稿者:GAI  投稿日:2008年12月 5日(金)20時33分6秒
返信・引用
  さっそく製作して頂いて貰ってありがとうございます。
楽しく使わせていただいております。
日頃カードでやっているマジックをプログラムにすると、こんな風に構成していくのかと
BASICを勉強するのにとっても役に立ちますし、その意味を掴むのに好都合です。
自分はたかがトランプですが、そこにいろいろな数理や法則、組み合わせの妙などの技巧が構成していける点に興味があり、新しい作品を創造していくことが楽しみです。
これをコンピュータでシュミレートできれば試行錯誤を厭わない強みが手に入ります。
部分的に書き換えて現象がどう変化していくのかを知ることができ、改良や改善点の発見に大いに役立ちます。
これからも何かとお願いするかと思いますのでお助け下さい。
次から次への製作依頼に応じて下さいまして、重ね重ねありがとうございました。
 

訂正

 投稿者:GAI  投稿日:2008年12月 5日(金)22時58分14秒
返信・引用
  アップした後、数値の間違いに気付き訂正をしておいて下さい。
(パターンQ)で
仕込み:1,2,13,16枚目とし
スタート:2,3,6,8,9,11,13,14番
への変更をお願いします。
 

さいころ賭博

 投稿者:GAI  投稿日:2008年12月 7日(日)20時46分54秒
返信・引用
  <パターン�機�
4つのさいころがあり
A={2,3,3,9,10,11}、B={0,1,7,8,8,8}、C={5,5,6,6,6,6}、D={4,4,4,4,12,12}
の目が各面に印字されているとします。
あなたと私はこの中からそれぞれ一つのさいころを選んでさいころを振ります。
出た目が大きいほうが相手から千円を受け取ることができます。
でも少なくとも100回は勝負することにします。(選んださいころは変えない。)
さて貴方はどのさいころを選びますか?


<パターン�供�
同じく4つのさいころが
X={5,5,6,6,7,7}、Y={1,2,3,9,10,11}、Z={0,1,7,8,8,9}、W={3,4,4,5,11,12}
の目でできています。
同じく勝負しますが(これも100回は戦う条件つき)同じ目が出ればアイコでやり直しをします。
さてあなたが選ぶさいころはどれ?
 

Re: さいころ賭博

 投稿者:荒田浩二  投稿日:2008年12月 8日(月)09時22分26秒
返信・引用
  > No.148[元記事へ]

GAIさんへのお返事です。

10万回の実験ではDとWがわずかに有利とでました。
期待値の1.324とは、1回に1000円かけると平均1324円戻ってくるという意味です。
下のプログラムでは対戦人数を2〜4人に指定できます。
ただし全員違うサイコロを選択するとします。
3人、4人ではAとYが有利とでました。
理論値を求めるのもそれほど難しくはないと思いますが、どうでしょう?


DECLARE EXTERNAL SUB combination
LET k=100000 ! 対戦回数
LET p=2 ! パターン
LET n=4 ! サイコロの種類
LET f=6 ! サイコロの面数
INPUT PROMPT "対戦人数は? " : r
IF r<2 OR r>n THEN STOP
DIM code$(p,n),dice(p,n,f),d(r),win(r),sumwin(p,n),a(n),com(COMB(n,r),r)
MAT READ code$,dice
MAT a=ZER(n)
MAT sumwin=ZER
LET total=(COMB(n,r)-COMB(n-1,r))*k
LET count=0 ! COMB(n,r)
CALL combination(a,n,1,r,com,count)
FOR pp=1 TO p
   FOR i=1 TO count
      MAT win=ZER
      FOR j=1 TO k
         LET maxd=-1
         FOR ri=1 TO r
            LET d(ri)=dice(pp,com(i,ri),INT(f*RND)+1)
            IF d(ri)>maxd THEN
               LET maxd=d(ri)
               LET w=ri
            ELSEIF d(ri)=maxd THEN ! 引き分け
               LET w=0
            END IF
         NEXT ri
         IF w=0 THEN LET j=j-1 ELSE LET win(w)=win(w)+1
      NEXT j
      LET maxw=0
      FOR ri=1 TO r
         LET sumwin(pp,com(i,ri))=sumwin(pp,com(i,ri))+win(ri)
         PRINT code$(pp,com(i,ri));win(ri);"  ";
         IF win(ri)>maxw THEN
            LET w=ri
            LET maxw=win(ri)
         END IF
      NEXT ri
      PRINT "勝者 ";code$(pp,com(i,w));win(w);"勝";k-win(w);"敗";
      PRINT USING " 期待値 #.####":r*win(w)/k
   NEXT i
   PRINT "総合勝敗"
   FOR ni=1 TO n
      PRINT code$(pp,ni);sumwin(pp,ni);"勝";total-sumwin(pp,ni);"敗";
      PRINT USING " 期待値 #.####":r*sumwin(pp,ni)/total
   NEXT ni
   PRINT
NEXT pp
DATA A,B,C,D,X,Y,Z,W
DATA 2,3,3,9,10,11  ! A
DATA 0,1,7,8,8,8    ! B
DATA 5,5,6,6,6,6    ! C
DATA 4,4,4,4,12,12  ! D
DATA 5,5,6,6,7,7    ! X
DATA 1,2,3,9,10,11  ! Y
DATA 0,1,7,8,8,9    ! Z
DATA 3,4,4,5,11,12  ! W
END

REM 十進BASIC添付"\BASICw32\SAMPLE\COMBINAT.BAS"より
REM 1〜nの集合からr個を選ぶ組合せを生成する。配列com(,)
EXTERNAL SUB combination(a(),n,k,r,com(,),count)
! k以降の数からr個を選択する
IF r=0 THEN
   LET count=count+1
   LET ri=1
   FOR i=1 TO n
      IF a(i)=1 THEN
         LET com(count,ri)=i
         LET ri=ri+1
      END IF
   NEXT i
ELSE
   FOR i=k TO n-r+1
      LET a(i)=1
      CALL combination(a,n,i+1,r-1,com,count)
      LET a(i)=0
   NEXT i
END IF
END SUB
 

Re: さいころ賭博

 投稿者:GAI  投稿日:2008年12月 8日(月)11時26分21秒
返信・引用
  > No.149[元記事へ]

荒田浩二さんへのお返事です。

10万回の勝負とはすごい。
2人でやる場合しか考慮していなかったので、3,4人でのプログラムまで構成されているのに驚きました。
自分で組んだプログラムに較べ、なんと効率よく組まれているかと感心いたしました。
さてここは賭博です。
当然胴元が有利になるような戦略を立てて下さい。
例の計算結果を眺め、期待値が高くなる組み合わせで作戦を練ります。
<ヒント>:二人で同時に選ぶように見せかけ、客が先にさいころを選ばせます。
 

ファイルの開き方

 投稿者:初心者A  投稿日:2008年12月 8日(月)12時05分31秒
返信・引用
  十進Basicで保存したファイルをダブルクリックしても開きません。
どうしたらダブルクリックで開けるのですか?
プログラムを起動してから、ファイルを開くのは実施できます。
初心者なのでよろしくお願いします。
 

Re: ファイルの開き方

 投稿者:白石 和夫  投稿日:2008年12月 8日(月)14時37分17秒
返信・引用  編集済
  > No.151[元記事へ]

いくつか方法があります。
1つめは,インストーラ版ダウンロードのページからBASIC728setup.exeをダウンロードして実行することです。これが一番簡単です。
2つめ2は,BASICのフォルダにある,SETUP.BATを実行することです。なお,エクスプローラで拡張子を表示する設定になっていないと“.BAT”の部分は表示されません。
3つめは,FAQのページのBASファイルの関連付けの修正にあります。
 

Re: ファイルの開き方

 投稿者:初心者A  投稿日:2008年12月 8日(月)15時38分6秒
返信・引用
  > No.152[元記事へ]

白石 和夫先生へ

十進BASICの開発者である白石和夫先生から、早速回答をいただき、恐縮しております。
高校教師をしているので、日常の授業教材として活用させていただきたいと思います。

指示された2つめの方法で、上手く実行できました。
本当にありがとうございました。
今後ともよろしくご指導下さい。


> いくつか方法があります。
> 1つめは,インストーラ版ダウンロードのページからBASIC728setup.exeをダウンロードして実行することです。これが一番簡単です。
> 2つめ2は,BASICのフォルダにある,SETUP.BATを実行することです。なお,エクスプローラで拡張子を表示する設定になっていないと“.BAT”の部分は表示されません。
> 3つめは,FAQのページのBASファイルの関連付けの修正にあります。
 

十進BASICのプログラムについて

 投稿者:ド素人  投稿日:2008年12月11日(木)11時59分5秒
返信・引用
  十進BASICで擬似乱数を使ったプログラムを作成したいと思っています。打率のデータを基に、どういう打順を組めば効率よく点が取れるのかを、乱数を発生させて作りたいのですが、どうしたらいいでしょうか?  

Re: 十進BASICのプログラムについて

 投稿者:山中和義  投稿日:2008年12月11日(木)19時54分8秒
返信・引用
  > No.154[元記事へ]

ド素人さんへのお返事です。

打った、送ったの単純で、5000試合の平均を表示します。
1試合ごとの内訳は、PRINT文の注釈を削除すれば表示されます。
ただし、5000回試合の表示には時間がかかります。(実用的でない)
!打順考察のためのシミュレーション

DATA 0.2, 0.2, 0.3, 0.3, 0.3, 0.2, 0.2, 0.1, 0.1
!DATA 0.1, 0.2, 0.2, 0.3, 0.2, 0.1, 0.3, 0.2, 0.3
!DATA 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2
DIM D(9) !9人分の打率
MAT READ D

RANDOMIZE

LET N=5000 !試合数
FOR x=1 TO N

   DIM SM(N) !総合得点
   LET P=1 !打順

   FOR w=1 TO 9 !9回まで

      LET B=0 !塁の状態
      LET S1=0 !得点
      LET O=0
      DO UNTIL O=3 !3アウトまで
      !PRINT P;"番打者:";
         IF RND<D(P) THEN !ヒットなら
            LET t=INT(RND*10)+1 !長打率など ※1〜10
            SELECT CASE t
            CASE 1,2,3,4
               LET v=1
            CASE 5,6,7
               LET v=2
            CASE 8,9
               LET v=3
            CASE ELSE
               LET v=4
            END SELECT
            !PRINT v;"塁打", !1〜4

            LET B=B*10+1 !v塁打で走者を送る
            LET S1=S1+INT(B/10^3)
            LET B=MOD(B,10^3)
            FOR i=0 TO v-2
               LET B=B*10
               LET S1=S1+INT(B/10^3)
               LET B=MOD(B,10^3)
            NEXT i
         ELSE
            LET O=O+1
            !PRINT "アウト",
         END IF
         !PRINT USING "# %%%": S1,B !塁の状態

         LET P=P+1 !次へ
         IF P>9 THEN LET P=1
      LOOP

      !PRINT w;"回";S1;"点"
      !PRINT
      LET SM(w)=SM(w)+S1
   NEXT w

NEXT x


LET S=0 !得点の分布
FOR w=1 TO 9
   PRINT w;"回";SM(w)/N;"点"
   LET S=S+SM(w)
NEXT w
PRINT "総合得点=";S/N


END
 

Re: 十進BASICのプログラムについて

 投稿者:ド素人  投稿日:2008年12月15日(月)16時11分49秒
返信・引用
  > No.155[元記事へ]

山中和義さんへのお返事です。

素早いお返事ありがとうございます。とても助かりました。またわからないことがあったら投稿させていただきます。
 

Re: 十進BASICのプログラムについて

 投稿者:荒田浩二  投稿日:2008年12月16日(火)12時15分34秒
返信・引用
  > No.154[元記事へ]

ド素人さんへのお返事です。

9人での打順は 9!=362880通りありますが、各打順ごとに1000試合をシミュレートしました。
試合のシミュレーションは単純にヒット3本で1点、以下ヒット1本ごとに1点追加。
実行には2進モードで約2時間20分かかりました。
ただし1000試合では試行回数が少なく、とくに各打者の打率のバラつきが小さいときは結果の信頼性は低いと思います。
上位100位を出力しましたが、あくまでも傾向を知るていどだと承知して下さい。

DECLARE EXTERNAL SUB perm
PUBLIC NUMERIC player,games,rank,total_point,worst_point
PUBLIC NUMERIC ave(9),best_order(100,9),best_point(100)
PRINT TIME$
LET t=TIME
LET player=9   ! 9!=362880通り
LET games=1000 ! 試合数
LET rank=100   ! ランク
MAT READ ave
DATA .460,.420,.380,.340,.300,.260,.220,.180,.140
!DATA .380,.360,.340,.320,.300,.280,.260,.240,.220
DIM a(player)
FOR i=1 TO player
   LET a(i)=i
NEXT i
MAT best_order=ZER
MAT best_point=ZER
LET total_point=0
LET worst_point=10*games
CALL perm(a,1)
FOR i=1 TO rank
   PRINT USING "No##  打順" : i;
   FOR j=1 TO player
      PRINT best_order(i,j);
   NEXT j
   PRINT USING "  期待値-%.### 点":best_point(i)/games
NEXT i
PRINT "最低期待値 =";worst_point/games;"点"
PRINT "平均 =";total_point/(games*FACT(player));"点"
PRINT TIME-t;"sec"
END

EXTERNAL SUB simulation(order())
LET sum_point=0
FOR i=1 TO games
   LET at_bat=0
   FOR inning=1 TO 9 ! 9回
      LET out_count=0
      LET hit=0
      DO
         IF ave(order(MOD(at_bat,player)+1))>RND THEN
            LET hit=hit+1
            IF hit>=3 THEN LET sum_point=sum_point+1
         ELSE
            LET out_count=out_count+1
         END IF
         LET at_bat=at_bat+1
      LOOP UNTIL out_count=3
   NEXT inning
NEXT i
LET total_point=total_point+sum_point
IF sum_point>best_point(rank) THEN ! ランク付け
   LET best_point(rank)=sum_point
   FOR j=1 TO player
      LET best_order(rank,j)=order(j)
   NEXT j
   FOR i=rank TO 2 STEP -1
      IF best_point(i)>best_point(i-1) THEN
         SWAP best_point(i),best_point(i-1)
         FOR j=1 TO player
            SWAP best_order(i,j),best_order(i-1,j)
         NEXT j
      ELSE
         EXIT SUB
      END IF
   NEXT i
ELSEIF sum_point<worst_point THEN
   LET worst_point=sum_point
END IF
END SUB

REM 十進BASIC添付"\BASICw32\SAMPLE\PERMUTAT.BAS"より
REM 1〜nの順列を辞書式順序で生成する。
EXTERNAL SUB perm(a(),n)
DECLARE EXTERNAL SUB simulation
IF n=player THEN
   CALL simulation(a)
ELSE
   FOR i=n TO player
      LET t=a(i)
      FOR j=i-1 TO n STEP -1
         LET a(j+1)=a(j)
      NEXT j
      LET a(n)=t
      CALL perm(a,n+1)
      LET t=a(n)
      FOR j=n TO i-1
         LET a(j)=a(j+1)
      NEXT j
      LET a(i)=t
   NEXT i
END IF
END SUB

No 1  打順 2  1  3  4  6  5  7  9  8   期待値 2.952 点
No 2  打順 3  4  1  2  5  6  9  8  7   期待値 2.914 点
No 3  打順 4  3  5  1  2  6  8  7  9   期待値 2.905 点
No 4  打順 6  3  4  1  2  5  9  8  7   期待値 2.902 点
No 5  打順 7  6  3  2  1  5  4  8  9   期待値 2.895 点
No 6  打順 3  1  2  4  5  6  7  9  8   期待値 2.889 点
No 7  打順 1  5  4  3  2  6  9  8  7   期待値 2.880 点
No 8  打順 4  1  3  2  5  6  8  9  7   期待値 2.879 点
No 9  打順 4  2  3  1  5  6  8  9  7   期待値 2.879 点
No10  打順 6  5  3  1  2  4  7  8  9   期待値 2.879 点
No11  打順 2  5  4  1  3  6  7  9  8   期待値 2.878 点
No12  打順 4  2  5  1  3  6  9  8  7   期待値 2.875 点
No13  打順 1  2  5  4  3  7  6  9  8   期待値 2.871 点
No14  打順 5  3  4  2  1  6  7  9  8   期待値 2.870 点
No15  打順 5  4  2  1  3  9  7  8  6   期待値 2.869 点
No16  打順 2  1  3  4  5  6  7  9  8   期待値 2.867 点
No17  打順 4  2  3  1  5  6  9  8  7   期待値 2.865 点
No18  打順 5  1  3  4  2  6  7  8  9   期待値 2.865 点
No19  打順 2  3  4  5  1  7  6  8  9   期待値 2.864 点
No20  打順 6  2  4  3  1  5  9  8  7   期待値 2.864 点
No21  打順 3  6  4  1  2  8  9  5  7   期待値 2.863 点
No22  打順 5  4  2  1  3  6  7  9  8   期待値 2.862 点
No23  打順 6  2  1  4  3  7  9  5  8   期待値 2.861 点
No24  打順 7  5  3  1  2  4  6  8  9   期待値 2.861 点
No25  打順 3  1  2  5  4  6  7  9  8   期待値 2.860 点
No26  打順 2  1  5  4  9  8  7  6  3   期待値 2.859 点
No27  打順 2  3  1  4  5  6  8  9  7   期待値 2.858 点
No28  打順 7  3  4  1  2  9  8  5  6   期待値 2.857 点
No29  打順 2  4  1  3  5  7  6  8  9   期待値 2.856 点
No30  打順 9  5  4  1  3  2  6  7  8   期待値 2.856 点
No31  打順 2  1  5  3  4  7  6  9  8   期待値 2.853 点
No32  打順 4  1  3  5  2  6  7  9  8   期待値 2.852 点
No33  打順 4  1  5  3  2  9  7  8  6   期待値 2.852 点
No34  打順 4  5  3  2  1  6  9  8  7   期待値 2.852 点
No35  打順 2  5  1  4  3  6  9  7  8   期待値 2.851 点
No36  打順 3  4  2  1  7  6  9  5  8   期待値 2.850 点
No37  打順 5  3  4  2  1  6  9  8  7   期待値 2.850 点
No38  打順 2  3  1  4  5  6  9  8  7   期待値 2.849 点
No39  打順 4  2  3  5  1  6  7  9  8   期待値 2.849 点
No40  打順 2  4  1  5  3  7  9  8  6   期待値 2.848 点
No41  打順 5  7  4  1  3  2  8  9  6   期待値 2.847 点
No42  打順 2  4  1  5  3  7  8  9  6   期待値 2.846 点
No43  打順 4  3  2  1  5  7  8  9  6   期待値 2.845 点
No44  打順 1  4  2  3  8  7  9  5  6   期待値 2.844 点
No45  打順 4  3  1  2  5  6  9  7  8   期待値 2.844 点
No46  打順 7  3  2  1  4  5  6  9  8   期待値 2.844 点
No47  打順 4  2  3  1  5  9  7  8  6   期待値 2.843 点
No48  打順 5  2  3  1  4  6  8  7  9   期待値 2.843 点
No49  打順 5  3  2  4  1  7  6  8  9   期待値 2.842 点
No50  打順 2  1  4  3  5  8  6  7  9   期待値 2.841 点
No51  打順 4  6  3  1  2  8  5  9  7   期待値 2.841 点
No52  打順 5  4  1  2  3  9  8  7  6   期待値 2.841 点
No53  打順 2  4  3  1  5  8  9  6  7   期待値 2.840 点
No54  打順 3  2  1  4  5  8  9  7  6   期待値 2.840 点
No55  打順 9  2  3  4  1  5  6  7  8   期待値 2.839 点
No56  打順 6  5  2  1  4  3  8  9  7   期待値 2.838 点
No57  打順 7  3  6  1  2  4  5  8  9   期待値 2.838 点
No58  打順 3  5  7  2  1  4  6  8  9   期待値 2.837 点
No59  打順 4  3  1  2  7  5  8  9  6   期待値 2.837 点
No60  打順 4  6  2  3  1  5  7  8  9   期待値 2.837 点
No61  打順 4  6  3  2  1  5  8  9  7   期待値 2.837 点
No62  打順 6  1  2  4  3  8  5  9  7   期待値 2.837 点
No63  打順 2  4  3  1  5  8  6  9  7   期待値 2.836 点
No64  打順 4  3  5  2  1  6  9  8  7   期待値 2.836 点
No65  打順 4  5  1  2  3  6  7  9  8   期待値 2.836 点
No66  打順 1  4  3  5  6  8  9  7  2   期待値 2.835 点
No67  打順 4  3  1  2  5  6  9  8  7   期待値 2.835 点
No68  打順 4  6  1  2  3  5  8  9  7   期待値 2.835 点
No69  打順 5  4  1  3  6  9  8  7  2   期待値 2.835 点
No70  打順 6  3  4  1  2  7  5  8  9   期待値 2.835 点
No71  打順 1  3  2  4  6  9  8  5  7   期待値 2.834 点
No72  打順 3  2  1  4  6  7  5  8  9   期待値 2.834 点
No73  打順 4  1  3  2  5  6  7  8  9   期待値 2.834 点
No74  打順 6  5  3  4  1  2  7  8  9   期待値 2.834 点
No75  打順 7  4  5  1  2  3  6  9  8   期待値 2.834 点
No76  打順 3  1  2  6  5  4  7  8  9   期待値 2.833 点
No77  打順 6  1  2  3  4  5  8  9  7   期待値 2.833 点
No78  打順 6  3  1  2  5  4  9  7  8   期待値 2.833 点
No79  打順 7  3  6  1  2  5  4  8  9   期待値 2.833 点
No80  打順 5  2  3  1  4  7  8  9  6   期待値 2.832 点
No81  打順 7  4  5  3  1  2  6  8  9   期待値 2.832 点
No82  打順 3  1  2  7  4  6  9  8  5   期待値 2.831 点
No83  打順 3  1  4  2  7  8  9  6  5   期待値 2.831 点
No84  打順 3  2  1  4  5  7  9  8  6   期待値 2.831 点
No85  打順 5  3  1  2  4  6  9  7  8   期待値 2.831 点
No86  打順 5  6  1  2  4  3  7  8  9   期待値 2.831 点
No87  打順 6  3  4  1  2  7  5  9  8   期待値 2.831 点
No88  打順 1  2  3  5  4  9  7  8  6   期待値 2.830 点
No89  打順 2  5  1  3  4  7  9  8  6   期待値 2.830 点
No90  打順 6  5  3  1  4  2  7  9  8   期待値 2.830 点
No91  打順 6  9  3  4  2  1  5  7  8   期待値 2.830 点
No92  打順 2  1  4  5  7  9  8  6  3   期待値 2.829 点
No93  打順 5  1  4  3  2  7  9  8  6   期待値 2.829 点
No94  打順 8  5  1  4  2  3  6  9  7   期待値 2.829 点
No95  打順 1  2  3  4  6  9  8  7  5   期待値 2.828 点
No96  打順 3  4  1  2  6  7  9  5  8   期待値 2.828 点
No97  打順 1  3  5  2  4  6  7  8  9   期待値 2.827 点
No98  打順 2  1  3  5  4  7  9  8  6   期待値 2.827 点
No99  打順 3  4  1  2  5  6  7  9  8   期待値 2.826 点
No100 打順 4  2  1  3  5  8  9  7  6   期待値 2.826 点

最低期待値 = 2.073 点
平均 = 2.44374 点
 

プログラムの書き直し

 投稿者:GAI  投稿日:2008年12月16日(火)22時55分17秒
返信・引用
  UBASICによる次のプログラムを十進BASICに書き直してもらいたいのですが、どなたかよろしくお願いいたします。

10 !euler function
20 input "n=";M
30 Mw=M:Phi=1
40 repeat
50   P=prmdiv(Mw)
60   Phi*=P-1:Mw\=P
70   while Mw@P=0:Phi*=P:Mw\=P:wend
80 until Mw=1
90 print Phi
100 end


オイラー関数(1 から n までの自然数のうち n と互いに素なものの個数)
を求める目的です。
 

Re: プログラムの書き直し

 投稿者:SECOND  投稿日:2008年12月17日(水)05時50分56秒
返信・引用  編集済
  > No.158[元記事へ]

GAIさんへのお返事です。

! 関数 prmdiv() の本来は、素数で割っていくようです。

! euler function
!------------------
INPUT PROMPT "n=":M
LET Mw=M
LET Phi=1
DO
   LET P=prmdiv(Mw)
   LET Phi=Phi*(P-1)
   LET Mw=INT(Mw/P)
   DO WHILE MOD(Mw,P)=0
      LET Phi=Phi*P
      LET Mw=INT(Mw/P)
   LOOP
LOOP UNTIL Mw=1
PRINT Phi

FUNCTION prmdiv(Mw) !1<の最小の約数
   FOR i=2 TO Mw
      IF MOD(Mw,i)=0 THEN EXIT FOR
   NEXT i
   LET prmdiv=i
END FUNCTION

END

<プログラムの照合用に> 原文を uBASIC で、実行した結果。
run
n=2~400
   1   2   2   4   2   6   4   6   4  10   4  12   6   8   8  16   6  18   8  12
  10  22   8  20  12  18  12  28   8  30  16  20  16  24  12  36  18  24  16  40
  12  42  20  24  22  46  16  42  20  32  24  52  18  40  24  36  28  58  16  60
  30  36  32  48  20  66  32  44  24  70  24  72  36  40  36  60  24  78  32  54
  40  82  24  64  42  56  40  88  24  72  44  60  46  72  32  96  42  60  40 100
  32 102  48  48  52 106  36 108  40  72  48 112  36  88  56  72  58  96  32 110
  60  80  60 100  36 126  64  84  48 130  40 108  66  72  64 136  44 138  48  92
  70 120  48 112  72  84  72 148  40 150  72  96  60 120  48 156  78 104  64 132
  54 162  80  80  82 166  48 156  64 108  84 172  56 120  80 116  88 178  48 180
  72 120  88 144  60 160  92 108  72 190  64 192  96  96  84 196  60 198  80 132
100 168  64 160 102 132  96 180  48 210 104 140 106 168  72 180 108 144  80 192
  72 222  96 120 112 226  72 228  88 120 112 232  72 184 116 156  96 238  64 240
110 162 120 168  80 216 120 164 100 250  72 220 126 128 128 256  84 216  96 168
130 262  80 208 108 176 132 268  72 270 128 144 136 200  88 276 138 180  96 280
  92 282 140 144 120 240  96 272 112 192 144 292  84 232 144 180 148 264  80 252
150 200 144 240  96 306 120 204 120 310  96 312 156 144 156 316 104 280 128 212
132 288 108 240 162 216 160 276  80 330 164 216 166 264  96 336 156 224 128 300
108 294 168 176 172 346 112 348 120 216 160 352 116 280 176 192 178 358  96 342
180 220 144 288 120 366 176 240 144 312 120 372 160 200 184 336 108 378 144 252
190 382 128 240 192 252 192 388  96 352 168 260 196 312 120 396 198 216 160
OK
 

Re: プログラムの書き直し

 投稿者:荒田浩二  投稿日:2008年12月17日(水)10時56分47秒
返信・引用
  > No.159[元記事へ]

SECONDさんへのお返事です。


> FUNCTION prmdiv(Mw) !1<の最小の約数
>    FOR i=2 TO Mw
>       IF MOD(Mw,i)=0 THEN EXIT FOR
>    NEXT i
>    LET prmdiv=i
> END FUNCTION



関数定義を改良しました。
引数が大きく、最小の約数も大きいとき効果があります。

FUNCTION prmdiv(Mw) !1<の最小の約数
   IF MOD(Mw,2)=0 THEN
      LET prmdiv=2
      EXIT FUNCTION
   ELSEIF MOD(Mw,3)=0 THEN
      LET prmdiv=3
      EXIT FUNCTION
   END IF
   FOR i=5 TO SQR(Mw) STEP 6
      IF MOD(Mw,i)=0 THEN
         LET prmdiv=i
         EXIT FUNCTION
      ELSEIF MOD(Mw,i+2)=0 THEN
         LET prmdiv=i+2
         EXIT FUNCTION
      END IF
   NEXT i
   LET prmdiv=Mw
END FUNCTION
 

固有ベクトルの算法

 投稿者:SECOND  投稿日:2008年12月17日(水)12時42分29秒
返信・引用  編集済
  固有ベクトルを高速に算出する方法を、ご指導ください。
※近似値でもよいです。CADなど、かなり速いですが、
 どんなアルゴリズムが、使われているのでしょうか。
 

Re: 固有ベクトルの算法

 投稿者:山中和義  投稿日:2008年12月17日(水)13時23分36秒
返信・引用
  > No.161[元記事へ]

SECONDさんへのお返事です。

> どなたか、固有ベクトルを高速に算出する方法を、ご指導ください。
> CADなどは、速いですが、どんなアルゴリズムが、使われているのでしょうか。


・対称行列
 ヤコビ法

アルゴリズムの本に掲載されている。手元にコードなし。


・最大の固有値・固有ベクトルの算出
 べき乗法(パワー法)

アルゴリズムの本に掲載されている。
数値計算の専門書には、複素数への拡張がされている。

!べき乗法による行列の固有値と固有ベクトルを求める
!※固有値が0、重複する場合は適用できない。
!※実数の固有値のみ。虚数を含む解は得られない。

!Ax=λIx、λ:固有値、x:固有ベクトル

LET N=3 !N次正方行列


DATA 2,1,-1 !λ=3,2,1
DATA 0,3,0
DATA 0,2,1

!DATA 0,1,1 !λ=2,1,0
!DATA -4,4,2
!DATA 4,-3,-1

!DATA 1,0,0 !λ=1(3重根)
!DATA 0,1,1
!DATA 0,0,1

DIM A(N,N) !行列A
MAT READ A
MAT PRINT A;


LET cEps=1e-6 !誤差 ※調整要、単精度

DIM u(N) !固有ベクトル

DIM AA(N,N) !作業用
MAT AA=A
FOR s=1 TO N !s番目
   CALL EigenPower(N,AA, lambda,u)
   PRINT "固有値=";lambda
   PRINT "固有ベクトル"
   MAT PRINT u;

   FOR i=1 TO N !残差行列を求めて、次へ
      FOR j=1 TO N
         LET AA(i,j)=AA(i,j)-lambda*u(i)*u(j)
      NEXT j
   NEXT i
NEXT s




DEF norm(v())=SQR(DOT(v,v)) !ノルム

SUB EigenPower(N,A(,), lambda,u()) !固有値(絶対値最大)、固有ベクトルを求める
   DIM u0(100),u2(100) !※最大100次

   MAT u=CON !初期値 ※ノルムが1
   MAT u=(1/norm(u))*u

   LET cMax=100
   FOR i=1 TO cMax !最大回数まで繰り返す
      MAT u0=u !直前のu

      MAT u=A*u0
      WHEN EXCEPTION IN
         MAT u=(1/norm(u))*u !正規化する
      USE
         PRINT "0ベクトルになりました。"
         STOP
      END WHEN

      MAT u2=u-u0 !収束したか確認する
      IF norm(u2)<cEps THEN EXIT FOR
      MAT u2=u+u0
      IF norm(u2)<cEps THEN EXIT FOR
   NEXT i
   IF i>cMax THEN
      PRINT "収束しません。"
      STOP
   END IF

   MAT u2=A*u
   LET lambda=DOT(u2,u)/DOT(u,u) !固有値
END SUB


END
 

Re: 固有ベクトルの算法

 投稿者:SECOND  投稿日:2008年12月17日(水)14時10分15秒
返信・引用  編集済
  > No.162[元記事へ]

山中和義さんへのお返事です。

ありがとうございました。

なぜこんなものを、というのは、
信号ベクトルの自己相関マトリクスの固有ベクトルを基底として、写像した信号ベクトルが、
信号ベクトルの圧縮の限界(KLT変換)になるのを実験しようというものです。
でも、リアルタイムに、10x10くらいの行列 というのは、きついです。
 

Re: 十進BASICのプログラムについて

 投稿者:ド素人  投稿日:2008年12月17日(水)15時02分48秒
返信・引用
  > No.155[元記事へ]

山中和義さんへのお返事です。

丁寧にプログラムを掲載していただきありがとうございます。
ひとつ質問があるのですが、「1試合ごとの内訳は、PRINT文の注釈を削除すれば表示されます。」と書いてある部分は、具体的にはどの部分のことをさしているのでしょうか?1試合ごとの内訳を知りたいのでぜひ教えていただけないでしょうか?よろしくお願いします。
 

Re: 十進BASICのプログラムについて

 投稿者:山中和義  投稿日:2008年12月17日(水)15時42分26秒
返信・引用  編集済
  > No.164[元記事へ]

ド素人さんへのお返事です。

> ひとつ質問があるのですが、「1試合ごとの内訳は、PRINT文の注釈を削除すれば表示されます。」と書いてある部分は、具体的にはどの部分のことをさしているのでしょうか?


!PRINT 〜 の形の部分です。十進BASICの注釈(コメント)は感嘆符(!マーク)です。

下記に削除したプログラムを掲載しておきます。

!打順考察のためのシミュレーション

DATA 0.2, 0.2, 0.3, 0.3, 0.3, 0.2, 0.2, 0.1, 0.1
!DATA 0.1, 0.2, 0.2, 0.3, 0.2, 0.1, 0.3, 0.2, 0.3
!DATA 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2
DIM D(9) !9人分の打率
MAT READ D

RANDOMIZE

LET N=10 !試合数 ※調整要
FOR x=1 TO N
   PRINT !<----- ここ
   PRINT "***";x;"試合目 ***" !<----- ここ

   DIM SM(N) !総合得点
   LET P=1 !打順

   FOR w=1 TO 9 !9回まで

      LET B=0 !塁の状態
      LET S1=0 !得点
      LET O=0
      DO UNTIL O=3 !3アウトまで
         PRINT P;"番打者:"; !<----- ここ
         IF RND<D(P) THEN !ヒットなら
            LET t=INT(RND*10)+1 !長打率など ※1〜10
            SELECT CASE t
            CASE 1,2,3,4
               LET v=1
            CASE 5,6,7
               LET v=2
            CASE 8,9
               LET v=3
            CASE ELSE
               LET v=4
            END SELECT
            PRINT v;"塁打", !1〜4 <----- ここ

            LET B=B*10+1 !v塁打で走者を送る
            LET S1=S1+INT(B/10^3)
            LET B=MOD(B,10^3)
            FOR i=0 TO v-2
               LET B=B*10
               LET S1=S1+INT(B/10^3)
               LET B=MOD(B,10^3)
            NEXT i
         ELSE
            LET O=O+1
            PRINT "アウト", !<----- ここ
         END IF
         PRINT USING "# %%%": S1,B !塁の状態 <----- ここ

         LET P=P+1 !次へ
         IF P>9 THEN LET P=1
      LOOP

      PRINT w;"回";S1;"点" !<----- ここ
      PRINT !<----- ここ
      LET SM(w)=SM(w)+S1
   NEXT w

NEXT x


PRINT
LET S=0 !得点の分布
FOR w=1 TO 9
   PRINT w;"回";SM(w)/N;"点"
   LET S=S+SM(w)
NEXT w
PRINT "総合得点=";S/N


END
 

Re: 十進BASICのプログラムについて

 投稿者:ド素人  投稿日:2008年12月17日(水)15時52分47秒
返信・引用
  > No.155[元記事へ]

山中和義さんへのお返事です。

たびたびすみません。DATAの次の行に書いてある!DATAはどのような意味があるのでしょうか?ここにはどのようなデータを書き込めばいいのでしょうか?無くても問題はないのでしょうか?
 

Re: 十進BASICのプログラムについて

 投稿者:山中和義  投稿日:2008年12月17日(水)16時23分21秒
返信・引用
  > No.166[元記事へ]

ド素人さんへのお返事です。

> DATAの次の行に書いてある!DATAはどのような意味があるのでしょうか?ここにはどのようなデータを書き込めばいいのでしょうか?無くても問題はないのでしょうか?


感嘆符から始まる行ですから、この行全体は注釈すなわち「実行されない文」となります。
したがって、あっても無くても問題になりません。


この注釈行を変更することで、別のパターンがすばやく確認できます。(メモも兼ねる)

例

DATA パターン1 <---- ここが実行される
!DATA パターン2
!DATA パターン3

を

!DATA パターン1
DATA パターン2  <---- ここが実行される
!DATA パターン3

と変更して、プログラムを実行する。
 

放物線Y=X^2の利用

 投稿者:GAI  投稿日:2008年12月17日(水)17時46分1秒
返信・引用
  Y=X^2 の放物線の思わぬ利用で、2つの数のかけ算の結果を次の作図で求めることをやれることを知りました。
例:3×5=15
である計算が
放物線上に2点A(-3,9)とB(5,25)を取り、A,Bの2点を結ぶ直線がY軸と交わる点P
を作図で求める。
このP点のY座標が求める積の値を知らせる。
一般にA(-a,(-a)^2),B(b,b^2)を結ぶ直線がY軸と交わる点が積a×bの値を示す。

この現象をプログラムにして、学生に解らせて確認して見せるものを作って頂きたく存じます。
 

Re: 放物線Y=X^2の利用

 投稿者:山中和義  投稿日:2008年12月17日(水)20時25分11秒
返信・引用
  > No.168[元記事へ]

GAIさんへのお返事です。

> この現象をプログラムにして、学生に解らせて確認して見せるものを作って頂きたく存じます。

放物線を描画できる範囲が原点近傍に限られますが、、、


放物線y=x^2と直線y=m*x+nの2つの交点A(a,?)とB(b,?)は、2次方程式x^2-m*x-n=0を解けばよい。
解と係数との関係から、a*b=-n、a+b=m。

a+bも計算できる!? 傾き!?

DEF f(x)=x^2 !関数y=x^2
DEF g(x,a,b)=(f(b)-f(a))/(b-a)*(x-a)+f(a) !点Aと点Bを通る直線

LET a=-2
LET b=4

SET bitmap SIZE 300,600
SET WINDOW -10,10,-20,20 !表示領域
DRAW grid !座標

FOR x=-10 TO 10 STEP 0.2 !放物線y=x^2を描く
   PLOT LINES: x,f(x);
NEXT x
PLOT LINES

SUB ten(x,y,s$)
   PLOT TEXT ,AT x+0.4,y: s$
   DRAW disk WITH SCALE(0.2)*SHIFT(x,y)
END SUB
CALL ten(-a,f(-a),"A")
CALL ten(b,f(b),"B")

FOR x=-10 TO 10 STEP 0.2 !直線を描く
   PLOT LINES: x,g(x,-a,b);
NEXT x
PLOT LINES

CALL ten(0,g(0,-a,b),"P") !y切片


PRINT g(0,-a,b), a*b !検算



DEF h(a,b)=(f(b)-f(a))/(b-a) !傾き
PRINT h(a,b), a+b


END
 

放物線で遊ぶ

 投稿者:GAI  投稿日:2008年12月18日(木)07時21分0秒
返信・引用
  掲載してもらったプログラムを参考にさせて頂いて、私なりにやって見たかった現象を作ってみました。
感覚として、計算尺で計算しているような雰囲気が出ます。
12345679×63
などの計算をお楽しみください。



10 DEF f(x)=x^2 !関数y=x^2
20 DEF g(x,a,b)=(f(b)-f(a))/(b-a)*(x-a)+f(a) !点Aと点Bを通る直線
30 INPUT PROMPT "2数を選ぶ":x,y
40 LET x1=INT(LOG10(x))
50 LET y1=INT(LOG10(y))
60 LET x=x/10^x1
70 LET y=y/10^y1
80 LET a=x
90 LET b=y
100 IF a>b THEN LET t=a ELSE LET t=b
110 SET bitmap SIZE 300,600
120 SET WINDOW -(t+1),t+1,-2,(t+1)^2+5 !表示領域
130 DRAW grid !座標
140 FOR x=-10 TO 10 STEP 0.2 !放物線y=x^2を描く
150    PLOT LINES: x,f(x);
160 NEXT x
170 PLOT LINES
180 SUB ten(x,y,s$)
190    PLOT TEXT ,AT x+0.4,y: s$
200    DRAW disk WITH SCALE(0.2)*SHIFT(x,y)
210 END SUB
220 CALL ten(-a,f(-a),"A")
230 CALL ten(b,f(b),"B")
240 FOR x=-10 TO 10 STEP 0.2 !直線を描く
250    PLOT LINES: x,g(x,-a,b);
260 NEXT x
270 PLOT LINES
280 CALL ten(0,g(0,-a,b),"P") !y切片
290 PRINT "Y切片の値";g(0,-a,b);
300 PRINT "計算結果"; a*b*10^(x1+y1) !検算
310 DEF h(a,b)=(f(b)-f(a))/(b-a) !傾き
320 !PRINT h(a,b), a+b
330 END
 

Re: プログラムの書き直し

 投稿者:山中和義  投稿日:2008年12月18日(木)15時43分28秒
返信・引用
  > No.158[元記事へ]

UBASICの整数論関連の組込み関数を移植しました。

!RSA公開鍵暗号の計算

PRINT modpow(1371,1241,2279) !1371を暗号化する。公開鍵43*53=2279と1241

PRINT eul(2279) !=2184、43と53と2184は秘密
PRINT gcd(43,53) !互いに素
PRINT gcd(2184,1241) !互いに素

PRINT modinv(1241,2184) !秘密鍵1649

PRINT modpow(2003,1649,2279) !2003を複合化する


!nの1より大きな最小の約数
PRINT prmdiv(1234567) !127
PRINT prmdiv(23456789) !23456789
!PRINT prmdiv(11111111111111111) !2071723


!素数の生成
PRINT prm(100) !541
PRINT nxtprm(999) !prm(1000)=7919
!PRINT nxtprm(9999) !prm(10000)=104729


!オイラー関数(1からnまでの自然数のうちnと互いに素なものの個数)
FOR N=2 TO 100
   LET S=0
   FOR i=1 TO N-1
      IF GCD(N,i)=1 THEN LET S=S+1
   NEXT i
   PRINT N;S, eul(N)
NEXT N


FOR i=2 TO 100
   PRINT USING "#### #### #### ####": i,fnSigma(i),eul(i),moeb(i)
NEXT i


END



!整数論関連 ※ubasicより

EXTERNAL FUNCTION prmdiv(n) !1より大きな最小の約数
IF MOD(n,2)=0 THEN !2の倍数
   LET prmdiv=2
ELSEIF MOD(n,3)=0 THEN !3の倍数
   LET prmdiv=3
ELSE
   FOR i=5 TO SQR(n) STEP 6
   !!!FOR i=5 TO INTSQR(n) STEP 6 !<----- ※有理数モード
      IF MOD(n,i)=0 THEN !5,11,17,23,29,…
         LET prmdiv=i
         EXIT FUNCTION
      ELSEIF MOD(n,i+2)=0 THEN !7,13,19,25,31,…
         LET prmdiv=i+2
         EXIT FUNCTION
      END IF
   NEXT i
   LET prmdiv=n !その数自身
END IF
END FUNCTION

EXTERNAL FUNCTION eul(n) !オイラー関数 φ(n)(1からnまでの自然数のうちnと互いに素なものの個数)
LET t=n
IF MOD(n,2)=0 THEN
   LET t=t/2
   DO
      LET n=n/2
   LOOP WHILE MOD(n,2)=0
END IF
LET d=3
DO WHILE n/d>=d
   IF MOD(n,d)=0 THEN
      LET t=t/d*(d-1)
      DO
         LET n=n/d
      LOOP WHILE MOD(n,d)=0
   END IF
   LET d=d+2
LOOP
IF n>1 THEN LET t=t/n*(n-1)
LET eul=t
END FUNCTION

EXTERNAL FUNCTION moeb(n) !メビウス関数 μ(n)
LET W=1
DO WHILE n>1
   LET P=prmdiv(n)
   IF MOD(n,P^2)=0 THEN
      LET W=0
      EXIT DO
   END IF
   LET W=-W
   LET n=INT(n/P)
LOOP
LET moeb=W
END FUNCTION

EXTERNAL FUNCTION modpow(a,b,n) !a^b≡x mod n のxを返す
IF b=0 THEN
   LET modpow=1
ELSE
   LET S=1
   DO WHILE b>0
      IF MOD(b,2)=1 THEN LET S=MOD(S*a,n) !ビットが1なら計算する
      LET b=INT(b/2) !べき乗bを2進展開する
      LET a=MOD(a*a,n)
   LOOP
END IF
LET modpow=S
END FUNCTION

EXTERNAL FUNCTION modinv(a,n) !nを法としたaの逆元 a*x (mod n)=1
LET M=n
LET Sa=1
LET Ta=0
DO WHILE M<>0
   LET Q=INT(a/M)
   LET U=a-Q*M
   LET Ua=Sa-Q*Ta
   LET a=M
   LET Sa=Ta
   LET M=U
   LET Ta=Ua
LOOP
IF a<>1 THEN
   LET modinv=0
ELSE
   IF Sa<0 THEN LET Sa=Sa+n
   LET modinv=Sa
END IF
END FUNCTION

EXTERNAL FUNCTION prm(n) !n番目の素数 ※nは1以上
DIM prime(n) !素数列
LET prime(1)=2 !1番目は2
LET k=2 !k番目
LET x=1 !検証する自然数
DO WHILE k<=n !N番目まで
   LET x=x+2 !奇数が対象
   LET j=1 !見つかった素数の倍数かどうか確認する
   DO WHILE j<k AND MOD(x,prime(j))<>0 !倍数なら途中で終了
      LET j=j+1
   LOOP
   IF j=k THEN !新しく見つかった素数を記録する
      LET prime(k)=x
      LET k=k+1
   END IF
LOOP
LET prm=prime(n)
END FUNCTION

EXTERNAL FUNCTION nxtprm(n) !n+1番目の素数
LET nxtprm=prm(n+1)
END FUNCTION

EXTERNAL FUNCTION gcd(a,b) !最大公約数
DO UNTIL b=0
   LET t=b
   LET b=MOD(a,b)
   LET a=t
LOOP
LET gcd=a
END FUNCTION

EXTERNAL FUNCTION lcm(a,b) !最小公倍数
LET lcm=a*b/gcd(a,b)
END FUNCTION


!ユーザー定義

EXTERNAL FUNCTION fnSigma(n) !約数の和 σ(n)
LET S=1
DO WHILE n>1
   LET W=1
   LET P=prmdiv(n)
   DO
      LET W=W*P+1
      LET n=INT(n/P)
   LOOP WHILE MOD(n,P)=0
   LET S=S*W
LOOP
LET fnSigma=S
END FUNCTION
 

Re: プログラムの書き直し

 投稿者:GAI  投稿日:2008年12月18日(木)19時29分52秒
返信・引用
  > No.171[元記事へ]

山中和義さんへのお返事です。

> UBASICの整数論関連の組込み関数を移植しました。

本(UBASICによるコンピュータ整数論:木田祐司・牧野潔夫著<日本評論社>)
で勉強していてる最中に、この中で使われている関数が十進basicでも使えたらなと思っている所に、山中さんから願ってもない移植のプログラムを提供して頂いたところでした。

整数論はやればやるだけ奥深さが感じられ、ガウスやオイラーなど名だたる天才が最も惹きつけられた魅力が潜んでいることがおぼろげながら窺い知れます。
当時、コンピュータという道具無しに直感(霊感?)を働かせて背後に潜む神秘さに心を奪われていった先人たちの感動を現代の魔法のマシーンを利用して凡人でも再経験して行きたいと思っています。
なにせ独学でやっていますので誤解や回り道をしているかもしれません。

整数論を誰にでも理解していけるようにコンピュータプログラムを組んでいく事はとても大切な分野ではないかと思う次第です。
この分野の書籍があまり無いように感じます。(私の不勉強かもしれませんが・・・)
整数論で使われるいろいろな関数をEXTERNAL FUNCTION として道具箱にいれておけば、いろいろな現象を再現できる可能性が出てきます。
こんな道具があったら便利だろうなと感じましたらお頼みしますのでよろしくお願いします。
また、この分野で驚くべき式や結論をご存知でしたらぜひともお教えください。
 

Re: プログラムの書き直し

 投稿者:荒田浩二  投稿日:2008年12月19日(金)12時24分41秒
返信・引用
  > No.171[元記事へ]

山中和義さんへのお返事です。


> !素数の生成
> PRINT prm(100) !541
> PRINT nxtprm(999) !prm(1000)=7919
> !PRINT nxtprm(9999) !prm(10000)=104729
>
> EXTERNAL FUNCTION prm(n) !n番目の素数 ※nは1以上
> DIM prime(n) !素数列
> LET prime(1)=2 !1番目は2
> LET k=2 !k番目
> LET x=1 !検証する自然数
> DO WHILE k<=n !N番目まで
>    LET x=x+2 !奇数が対象
>    LET j=1 !見つかった素数の倍数かどうか確認する
>    DO WHILE j<k AND MOD(x,prime(j))<>0 !倍数なら途中で終了
>       LET j=j+1
>    LOOP
>    IF j=k THEN !新しく見つかった素数を記録する
>       LET prime(k)=x
>       LET k=k+1
>    END IF
> LOOP
> LET prm=prime(n)
> END FUNCTION
>
> EXTERNAL FUNCTION nxtprm(n) !n+1番目の素数
> LET nxtprm=prm(n+1)
> END FUNCTION


n番目の素数を返す関数を改良しました。
prm(10000)ならば5秒、prm(100000)ならば35秒ほどで求まります。
prm(5761455)=99999989(10^8以下最大素数) を求めるには2進モードで約37分です。

EXTERNAL FUNCTION prm(n) ! n番目の素数
DIM prime(n)
FOR i=1 TO MIN(n,10)
   READ prime(i)
NEXT i
DATA 2,3,5,7,11,13,17,19,23,29
FOR i=11 TO n
   LET m30=MOD(prime(i-1),30)
   IF m30=1 OR m30=23 THEN LET a=prime(i-1)+6 ELSE LET a=prime(i-1)-2*MOD(m30,3)+6
   DO
      LET sqra=SQR(a)
      FOR j=4 TO i-1
         IF MOD(a,prime(j))=0 THEN EXIT FOR
         IF prime(j)>=sqra THEN
            LET prime(i)=a
            EXIT DO
         END IF
      NEXT j
      LET m30=MOD(a,30)
      IF m30=1 OR m30=23 THEN LET a=a+6 ELSE LET a=a-2*MOD(m30,3)+6
   LOOP
NEXT i
LET prm=prime(n)
END FUNCTION
 

Re: プログラムの書き直し

 投稿者:山中和義  投稿日:2008年12月19日(金)16時34分17秒
返信・引用  編集済
  > No.173[元記事へ]

荒田浩二さんへのお返事です。

>  n番目の素数を返す関数を改良しました。

助かります。素数を素早く扱うかがこの手のプログラムには必要ですね。

nxtprm(x)関数は、間違っていましたので差し替えておきます。
EXTERNAL FUNCTION nxtprm(x) !xより大きい素数の最小のもの
   DIM prime(x)

   FOR i=1 TO 10 !最初の10個
      READ prime(i)
      IF x<prime(i) THEN
         LET nxtprm=prime(i)
         EXIT FUNCTION
      END IF
   NEXT i
   DATA 2,3,5,7,11,13,17,19,23,29

   FOR i=11 TO INT(x) !11個目以降
      LET m30=MOD(prime(i-1),30)
      IF m30=1 OR m30=23 THEN LET a=prime(i-1)+6 ELSE LET a=prime(i-1)-2*MOD(m30,3)+6
      DO
         LET sqra=SQR(a)
         !!!LET sqra=INTSQR(a) !<----- ※有理数モード
         FOR j=4 TO i-1
            IF MOD(a,prime(j))=0 THEN EXIT FOR
            IF prime(j)>=sqra THEN
               LET prime(i)=a
               EXIT DO
            END IF
         NEXT j
         LET m30=MOD(a,30)
         IF m30=1 OR m30=23 THEN LET a=a+6 ELSE LET a=a-2*MOD(m30,3)+6
      LOOP

      IF x<prime(i) THEN
         LET nxtprm=prime(i)
         EXIT FUNCTION
      END IF
   NEXT i

   PRINT "見つかりません。"
   STOP
END FUNCTION



●prm(n)関数を使ったものを追加しておきます。(定義済みのサブルーチンは省略)
!素数の個数
!PRINT fnPrimePi(77777)


!原始根 genshi3
FOR LP=1 TO 100
   LET P=prm(LP) !最初の100個の素数に対して

   PRINT USING "##### ### |": P,fnGenshi(P);
   IF MOD(LP,5)=0 THEN PRINT
NEXT LP
PRINT


!原始根 genshi2
FOR LP=1 TO 100
   LET P=prm(LP) !最初の100個の素数に対して

   LET G=1
   IF P<>2 THEN
50       LET G=G+1
         LET W=1
         FOR i=1 TO P-2
            LET W=MOD(W*G,P)
            IF W=1 THEN GOTO 50
         NEXT i
      END IF

      PRINT USING "##### ### |": P,G;
      IF MOD(LP,5)=0 THEN PRINT
   NEXT LP
   PRINT


END


EXTERNAL FUNCTION fnPrimePi(X) !実数xに対しx以下の素数の個数
   LET S=1
   LET E=10000 !100,000以下の素数は10,000個未満だから ※
   DO WHILE E>S+1
      LET K=INT((S+E)/2) !2分探索
      IF prm(K)<=X THEN LET S=K ELSE LET E=K
   LOOP
   LET fnPrimePi=S
END FUNCTION

EXTERNAL FUNCTION fnGenshi(P) !原始根
   LET G=1
   LET N=P-1
   IF P<>2 THEN
180    LET G=G+1
       LET Nw=N
       DO
          LET Div=prmdiv(Nw)
          DO WHILE MOD(Nw,Div)=0
             LET Nw=INT(Nw/Div)
          LOOP
          IF modpow(G,INT(N/Div),P)=1 THEN GOTO 180
       LOOP UNTIL Nw=1
    END IF
    LET fnGenshi=G
 END FUNCTION
 

uBASIC からの、移植

 投稿者:SECOND  投稿日:2008年12月19日(金)17時30分43秒
返信・引用  編集済
  !
! uBASIC からの、移植。※原本は、ココにあります。(その他、多数同梱)
!  http://www.rkmath.rikkyo.ac.jp/~kida/ubgraph.lzh

!  アスキー・セーブ しなおしたもの。
!  http://homepage2.nifty.com/neutro/asm/ubgraph(ASC).lzh

! MAZE.UB
!---------------------------------
! 迷路を作る
! Pascal version from
! 奥村晴彦 コンピュータアルゴリズム事典(技術評論社) 349-350
! 〔付〕迷路を解く  by 岩瀬順一

OPTION BASE 0
SET WINDOW 0,500, 500,0
!
LET Xmax=90
LET Ymax=90
LET MaxCan=INT(Xmax*Ymax/4) ! must Ymax<=Xmax
LET Bsize=4
LET Xoff=INT((500-Xmax*Bsize)/2)
LET Yoff=INT((500-Ymax*Bsize)/3) ! 20
DIM Map_(Xmax,Ymax)
DIM CanX_(MaxCan),CanY_(MaxCan),DirX_(MaxCan),DirY_(MaxCan)
RANDOMIZE
!
FOR I=0 TO 1
   FOR J=0 TO Ymax
      LET Map_(I,J)=1
      LET Map_(Xmax-I,J)=1
   NEXT J
NEXT I
FOR J=0 TO 1
   FOR I=0 TO Xmax
      LET Map_(I,J)=1
      LET Map_(I,Ymax-J)=1
   NEXT I
NEXT J
LET X=2
FOR Y=4 TO Ymax-2
   CALL DOT_(X,Y)
NEXT Y
LET X=Xmax-2
FOR Y=2 TO Ymax-4
   CALL DOT_(X,Y)
NEXT Y
LET Y=2
FOR X=2 TO Xmax-2
   CALL DOT_(X,Y)
NEXT X
LET Y=Ymax-2
FOR X=2 TO Xmax-2
   CALL DOT_(X,Y)
NEXT X
LET Ncan=0
FOR I=2 TO INT(Xmax/(2)) -2
   CALL InsCan_(I*2,2)
   CALL InsCan_(I*2,Ymax-2)
NEXT I
FOR J=2 TO INT(Ymax/(2)) -2
   CALL InsCan_(2,J*2)
   CALL InsCan_(Xmax-2,J*2)
NEXT J
LET Ndir=4
LET DirX_(1)=2
LET DirY_(1)=0
LET DirX_(2)=0
LET DirY_(2)=2
LET DirX_(3)=-2
LET DirY_(3)=0
LET DirX_(4)=0
LET DirY_(4)=-2
DO WHILE Ncan>0
   CALL Selcan_(I,J)
   DO
      LET Ndir=4
      DO
         CALL SelDir_(DI,DJ)
         LET Ok=1-Map_(I+DI,J+DJ)
      LOOP UNTIL Ok<>0 OR Ndir=0
      IF Ok<>0 THEN
         CALL DOT_(I+INT(DI/(2)),J+INT(DJ/(2)) )
         LET I=I+DI
         LET J=J+DJ
         CALL DOT_(I,J)
         CALL InsCan_(I,J)
      END IF
   LOOP UNTIL NOT Ok<>0
LOOP

SUB DOT_(X,Y)
   LET Map_(X,Y)=1
   ! SET AREA COLOR 5
   PLOT AREA: Bsize*X+Xoff,Bsize*Y+Yoff;Bsize*X+Xoff+Bsize-1,Bsize*Y+Yoff;Bsize*X+Xoff+Bsize-1,Bsize*Y+Yoff+Bsize-1;Bsize*X+Xoff,Bsize*Y+Yoff+Bsize-1
END SUB

SUB InsCan_(I,J)
   LET Ncan=Ncan+1
   LET CanX_(Ncan)=I
   LET CanY_(Ncan)=J
END SUB

SUB Selcan_(I,J)
   local R
   LET R=int(Ncan*rnd)+1
   LET I=CanX_(R)
   LET J=CanY_(R)
   LET CanX_(R)=CanX_(Ncan)
   LET CanY_(R)=CanY_(Ncan)
   LET Ncan=Ncan-1
END SUB

SUB SelDir_(I,J)
   local R
   LET R=int(Ndir*rnd)+1
   LET I=DirX_(R)
   LET J=DirY_(R)
   LET DirX_(R)=DirX_(Ndir)
   LET DirY_(R)=DirY_(Ndir)
   LET DirX_(Ndir)=I
   LET DirY_(Ndir)=J
   LET Ndir=Ndir-1
END SUB

!--------------------------------------------------
!      この先は、岩瀬が書いた。
!      方針:袋小路があったら、ぬりつぶす
!
PLOT TEXT,AT Xoff*1.2,20 :"何かキーを押してください。迷路を解きます。"
PLOT TEXT,AT Xoff*1.2,40 :"Push any key to solve the maze."
CHARACTER INPUT s$
SET AREA COLOR 0
PLOT AREA :Xoff,0; 500,0; 500,40; Xoff,40
!
LET Map_(2,3)=0
LET Map_(Xmax-2,Ymax-3)=0 ! 出口、入口は0にする
FOR I=0 TO Xmax !      迷路の外は1にする
   FOR J=0 TO 1
      LET Map_(I,J)=0
   NEXT J
   FOR J=Ymax-1 TO Ymax
      LET Map_(I,J)=0
   NEXT J
NEXT I
FOR J=0 TO Ymax
   FOR I=0 TO 1
      LET Map_(I,J)=0
   NEXT I
   FOR I=Xmax-1 TO Xmax
      LET Map_(I,J)=0
   NEXT I
NEXT J
!
!
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
!$$$$$$$$$ MAIN ROUTINE TO SOLVE THE MAZE $$$$$$$$$$$$$$$$$$$$$$$$$$$
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
!
FOR K=6 TO Ymax
   FOR J=3 TO K-3
      CALL Routine_
   NEXT J
NEXT K
FOR K=Ymax+1 TO Xmax
   FOR J=3 TO Ymax-3
      CALL Routine_
   NEXT J
NEXT K
FOR K=Xmax+1 TO Xmax+Ymax-6
   FOR J=K-Xmax+3 TO Ymax-3
      CALL Routine_
   NEXT J
NEXT K

SUB Routine_
   LET I=K-J
   IF fnCheck(I,J)< 3 THEN EXIT SUB
   LET Ii=I
   LET Jj=J
   DO
      CALL Fil_(Ii,Jj)
      IF Map_(Ii-1,Jj)=0 THEN
         LET Ii=Ii-1
      ELSEIF Map_(Ii,Jj+1)=0 THEN
         LET Jj=Jj+1
      ELSEIF Map_(Ii+1,Jj)=0 THEN
         LET Ii=Ii+1
      ELSEIF Map_(Ii,Jj-1)=0 THEN
         LET Jj=Jj-1
      END IF
   LOOP UNTIL fnCheck(Ii,Jj)<>3
END SUB

SUB Fil_(X,Y)
   LET Map_(X,Y)=1
   SET AREA COLOR 4 !3
   PLOT AREA: Bsize*X+Xoff,Bsize*Y+Yoff;Bsize*X+Xoff+Bsize-1,Bsize*Y+Yoff;Bsize*X+Xoff+Bsize-1,Bsize*Y+Yoff+Bsize-1;Bsize*X+Xoff,Bsize*Y+Yoff+Bsize-1
END SUB

FUNCTION fnCheck(I,J) ! 袋小路の時3をかえす
   LET fnCheck=0
   IF Map_(I,J)=1 THEN EXIT FUNCTION
   LET fnCheck=Map_(I-1,J)+Map_(I,J+1)+Map_(I+1,J)+Map_(I,J-1)
END FUNCTION

END
 

トランプ占いでの確率

 投稿者:GAI  投稿日:2008年12月20日(土)08時05分32秒
返信・引用
  1.トランプ(52枚)をよく切って、時計回りに1時の位置から文字盤のようにカードを裏にして12枚並べ、中心に13枚目のカードを置く。これを繰り返し全てのカードを配る。

2.13枚目の一番下のカードを引く。
そのカードが5の時は5時の位置の一番上に表向きにして置き、5時の位置の一番下のカードを引く。
このカードの数字の示す位置に表向きに置き、その位置の一番下のカードを引く。

3.13枚目の位置のKが4枚でるまで2.を繰り返す。


このルールで12組(1時から12時の組)が全て表になってしまう確率をみてみたいのですが、(できたら0組〜12組での確率分布も知りたい。)
この占いをコンピュータにさせて頂けませんか?
 

Re: トランプ占いでの確率

 投稿者:SECOND  投稿日:2008年12月20日(土)13時12分19秒
返信・引用
  > No.176[元記事へ]

GAIさんへのお返事です。

昨近のTVで見られる、カード・マジックの中に、物理的には、有り得ないものが、
多々見られます、鳥肌立てて見ているよりは、遅れた頭をかかえる場合、なのか??

露骨に不思議なマジック、超常現象なども、代数学上の記述、異次元間の写像、
即ち、行列、マトリクスで、解き明かされる日が、将来来るようにも、思います。
世界も、私たち自身も、ひょっとして、巨大なだけの数学モデルかも・・!?
私は、頭悪くて代数学を、殆んど理解できませんが、その未来に魅せられています。
 

Re: トランプ占いでの確率

 投稿者:山中和義  投稿日:2008年12月20日(土)14時56分45秒
返信・引用
  > No.176[元記事へ]

GAIさんへのお返事です。

> このルールで12組(1時から12時の組)が全て表になってしまう確率をみてみたいのですが、(できたら0組〜12組での確率分布も知りたい。)


パーフェクト(すべてのカードがめくられた状態)になるには、
カードをめくっていった順を考えると、最後の52枚目にKのカードがあればよい。
これが4通りで、残り51枚の並び順(めくった順)は51!通りだから、4*51!通りとなる。

また、52枚のカードを並べる順は、52!通り。

したがって、パーフェクトは、4*51!/52!=4/52=1/13となると思います。



めくった回数の期待値は、42回。分布は、1時から12時は、3.2枚。13時は4枚。
 

Re: トランプ占いでの確率

 投稿者:荒田浩二  投稿日:2008年12月20日(土)20時21分44秒
返信・引用  編集済
  > No.176[元記事へ]

GAIさんへのお返事です。

10万回の試行で、4枚とも表になる組数はすべて同じ確率で出現すると出ました。


  組   確率  平均枚数
   0  .07669  25.06枚
   1  .07519  31.20枚
   2  .07792  35.14枚
   3  .07686  38.10枚
   4  .07674  40.48枚
   5  .07722  42.48枚
   6  .07848  44.25枚
   7  .07573  45.84枚
   8  .07778  47.28枚
   9  .07741  48.59枚
  10  .07723  49.81枚
  11  .07564  50.94枚
  12  .07711  52.00枚
              42.41枚


DECLARE EXTERNAL SUB sort
PUBLIC NUMERIC c
LET tt=TIME
LET s=4
LET n=13
LET c=s*n
DIM check(c),card(c),position(n,s),face(n),total(0 TO n-1),count(0 TO n-1)
LET test=100000 ! 100000で125秒
FOR t=1 TO test
   CALL prep
   CALL play
NEXT t
LET cc=0
PRINT " 組   確率  平均枚数"
FOR i=0 TO n-1
   PRINT USING " ##  .#####  ##.##枚" : i,total(i)/test,count(i)/total(i)
   LET cc=cc+count(i)
NEXT i
PRINT USING "             ##.##枚" : cc/test
PRINT INT(TIME-tt);"sec"

SUB prep
   FOR i=1 TO c
      LET check(i)=RND
   NEXT i
   CALL sort(check,card)
   !MAT PRINT card;
   FOR j=1 TO s
      FOR i=1 TO n
         LET position(i,j)=card((j-1)*n+i)
      NEXT i
   NEXT j
   !MAT PRINT position;
END SUB
SUB play
   MAT face=ZER
   LET cc=0
   CALL open_card(n)
   !MAT PRINT face;
   LET f=0
   FOR i=1 TO n-1
      IF face(i)=s THEN LET f=f+1
   NEXT i
   LET total(f)=total(f)+1
   LET count(f)=count(f)+cc
END SUB
SUB open_card(nn)
   LET cc=cc+1
   LET look=position(nn,1)
   FOR j=1 TO s-1
      LET position(nn,j)=position(nn,j+1)
   NEXT j
   LET p=MOD(look,n)+1
   !PRINT p;
   LET face(p)=face(p)+1
   IF face(n)=s THEN EXIT SUB
   CALL open_card(p)
END SUB
END

REM 十進BASIC添付"\BASICw32\Library\SORT2.LIB"より
! ixにはmと下限,上限を一致させた空の配列を指定する。
! mは参照されるのみ。
! ixにmの添字を大きさの順に並べて返す。
! つまり,m(ix(1))≦m(ix(2))≦m(ix(3))≦・・・となる。
EXTERNAL SUB sort(m(),ix())
FOR i=1 TO c
   LET ix(i)=i
NEXT i
CALL q_sort(m,ix,1,c)
END SUB
EXTERNAL SUB q_sort(m(),a(),l,r)
IF r<=l THEN
   EXIT SUB
ELSE
   LET i=l-1
   LET j=r
   LET pv=m(a(r))
   DO
      DO
         LET i=i+1
      LOOP UNTIL pv<=m(a(i))
      DO
         LET j=j-1
      LOOP UNTIL j<=i OR m(a(j))<=pv
      IF j<=i THEN EXIT DO
      LET t=a(i)
      LET a(i)=a(j)
      LET a(j)=t
   LOOP
   LET t=a(i)
   LET a(i)=a(r)
   LET a(r)=t
   CALL q_sort(m,a,l,i-1)
   CALL q_sort(m,a,i+1,r)
END IF
END SUB
 

Re: トランプ占いでの確率

 投稿者:SECOND  投稿日:2008年12月21日(日)07時58分9秒
返信・引用  編集済
  > No.178[元記事へ]

山中和義さんへのお返事です。

問題が、よくわからないので、かん違いかもしれませんが、
パーフェクトの、4*51! 通りの中で、
13時の位置に、4枚のKが全て集まる配置の、4!*48! 通りは、
スタート時点で、無限ループに落ちるため、除かなくてよろしいですか。

すみません、カン違いでした。
 

ルールの詳細

 投稿者:GAI  投稿日:2008年12月21日(日)08時24分49秒
返信・引用
  1.トランプ(52枚)をよく切って、時計回りに1時の位置から文字盤のようにカードを裏にして12枚並べ、中心に13枚目のカードを置く。これを繰り返し全てのカードを配る。
           *
          * *
         *   *
        *  *  *
         *   *
          * *
           *


2.13枚目(真ん中のパケット)の一番下のカードを引く。
そのカードが5の時は5時の位置の一番上に表向きにして置き、5時の位置の一番下のカードを引く。
このカードの数字がQなら12時の示す位置に表向きに置き、12時の位置の一番下のカードを引く。
これがKなら真ん中の山(時計の針の中心)の一番上に表向きで置く。
次に、この山(中心部分のパケット)の一番下のカードを引き出しそのカードの数字に従い次の作業をしていく。
<これを続けていくと、各時刻の文字盤数に対応する表向きのカードが集まっていく。>

3.13枚目の位置(中心に置かれたパケット)に4枚のKが表向きに置かれるまで2.を繰り返す。


一番下にKを仕込んでやってみましたが、最後まで行かず途中で終わってしまいました。
 

Re: ルールの詳細

 投稿者:荒田浩二  投稿日:2008年12月21日(日)09時32分27秒
返信・引用
  > No.181[元記事へ]

GAIさんへのお返事です。

次のように下からカードを配置してみてください。パーフェクトになるはずです。
私のあげたプログラムで3回目、18回目、20回目の例です。
パーフェクトは最後にKを引くわけですから、Kを一番上に仕込めば達成する確率が上がります。
  
   1時   12 11  6 12
   2時    2  2  8  6
   3時    4  9  1  2
   4時    1  1  9 13
   5時   12 10 11  2
   6時    9  5 10  7
   7時    4 10  3  4
   8時   12  7 11 11
   9時    6  7  3  8
  10時    7  8  9  3
  11時    8 10  1  6
  12時    5 13 13 13
  13時    5  4  3  5

   1時    7  4  1  9
   2時    7  9  1  6
   3時    1  5  3  9
   4時    5 11  4  6
   5時   13  2  2  3
   6時    4  8 10 13
   7時   11  3 12 11
   8時   10  8  6  2
   9時    5  9  7  4
  10時    6 11  5  7
  11時    8  8 13 13
  12時    3 12 10  2
  13時    1 12 12 10

   1時   10  3  9  3
   2時    2  8  8 12
   3時    4  1  2 10
   4時    4  6  1 12
   5時   13 11  6  7
   6時   11  1  1 12
   7時    4  5  2 13
   8時    8  6  8  2
   9時   12  9  6  5
  10時    7  3 11 13
  11時   11 10  4  3
  12時    7 10  7  5
  13時   13  9  9  5
 

今日の運勢を最高に

 投稿者:GAI  投稿日:2008年12月21日(日)12時16分46秒
返信・引用
  > No.182[元記事へ]

荒田浩二さんへのお返事です。


実際にトランプでやらないでも占えちゃうとはありがたいです。
確率が等分であるとは思ってもいませんでした。
パーフェクトが達成するためには13回をめどにやればいいのか!
荒田さんのプログラムでtest=1とおいてパーフェクトになるまでやって今日の運勢を毎日
最高にしようっと!!

ところで
パーフェクト達成のためのパターンを可能なだけ集めたいのですがどのようにすればよろしいのでしょうか?
そこからどんな条件が必要なのか知りたいですが。
 

時計のプログラミング

 投稿者:田村幸助  投稿日:2008年12月22日(月)11時09分20秒
返信・引用
  十進BASICで時計を作りたいのですが、
プログラムを教えていただけませんか?
時計はアナログ時計です。
 

Re: 時計のプログラミング

 投稿者:山中和義  投稿日:2008年12月22日(月)11時45分27秒
返信・引用
  > No.184[元記事へ]

田村幸助さんへのお返事です。

> 時計はアナログ時計です。

シンプルです。単位円上に文字盤を描いています。いろいろ改良してください。

秒について
他の手法(たとえば、TIME関数)で小数点以下(ミリ秒)を取得できますが、
正確な値は期待できませんので、秒針をなめらかに動かすことは難しいかと思います。

!アナログ時計

SET WINDOW -1.2,1.2,-1.2,1.2 !表示領域
SET TEXT JUSTIFY "center","half" !文字表示の書式

DO
   LET t$=TIME$ !時刻をhh:mm:ss形式で得る
   LET h=VAL(t$(1:2)) !数値へ
   LET m=VAL(t$(4:5))
   LET s=VAL(t$(7:8))

   SET DRAW mode hidden !ちらつみ防止(開始)
   CLEAR

   FOR i=1 TO 12 !文字盤
      LET th=PI/2-2*PI*i/12 !Y軸から時計まわり
      PLOT TEXT ,AT COS(th),SIN(th): STR$(i) !円周上
   NEXT i

   LET th=PI/2-2*PI*(h + m/60)/12 !時針
   PLOT LINES: 0,0; 0.6*COS(th),0.6*SIN(th)

   LET th=PI/2-2*PI*m/60 !分針
   PLOT LINES: 0,0; 0.9*COS(th),0.9*SIN(th)

   LET th=PI/2-2*PI*s/60 !秒針
   PLOT LINES: 0,0; 0.8*COS(th),0.8*SIN(th)

   SET DRAW mode explicit !ちらつき防止(終了)
LOOP

END
 

Re: 時計のプログラミング

 投稿者:荒田浩二  投稿日:2008年12月22日(月)18時34分45秒
返信・引用  編集済
  > No.185[元記事へ]

山中和義さんへのお返事です。


上書きせていただきました。
調べたら1分間に約8200回の描画をしていたので、秒の更新があったときに描画するようにしました。
文字盤部分もLOOPから出して描画時間を節約。
長針・短針を絵定義にし、PICTURE hand を書き換えることにより針のデザイン変更を容易にできるようにしました。


!アナログ時計(改)

SET WINDOW -1.2,1.2,-1.2,1.2 !表示領域
SET TEXT JUSTIFY "center","half" !文字表示の書式
SET TEXT HEIGHT 1.2/10
SET AREA COLOR 5 ! 水色
SET POINT STYLE 4 ! 。
DRAW disk WITH SCALE(1.1)
FOR i=1 TO 12 !文字盤
   LET th=PI/2-2*PI*i/12 !Y軸から時計まわり
   PLOT TEXT ,AT COS(th),SIN(th): STR$(i) !円周上
   FOR j=1 TO 4
      LET th=PI/2-2*PI*(5*i+j)/60
      PLOT POINTS : 0.94*COS(th),0.94*SIN(th)
   NEXT j
NEXT i

SET LINE COLOR "RED"
LET t0=INT(TIME)
DRAW clock(t0)

DO
   IF TIME-t0>=1 THEN ! 秒の更新で描画
      LET t0=INT(TIME)
      DRAW clock(t0)
   END IF
LOOP

PICTURE clock(t0)
   LET h=INT(t0/3600) !数値へ
   LET m=INT((t0-3600*h)/60)
   LET s=MOD(t0,60)

   SET DRAW mode hidden !ちらつき防止(開始)
   SET AREA COLOR 0 ! 白
   DRAW disk WITH SCALE(0.9) !針描画部分のみクリア

   LET th=PI/2-2*PI*(h + m/60)/12 !時針
   DRAW hand(3) WITH SCALE(0.6,1)*ROTATE(th)

   LET th=PI/2-2*PI*m/60 !分針
   DRAW hand(2) WITH SCALE(0.86,1)*ROTATE(th)

   LET th=PI/2-2*PI*s/60 !秒針
   PLOT LINES: 0,0; 0.8*COS(th),0.8*SIN(th)

   SET DRAW mode explicit !ちらつき防止(終了)
END PICTURE

PICTURE hand(col) !針描画
   SET AREA COLOR col
   PLOT AREA : -0.05,-0.03;1,-0.03;1,0.03;-0.05,0.03
END PICTURE

END
 

液体万華鏡

 投稿者:SECOND  投稿日:2008年12月23日(火)01時01分5秒
返信・引用  編集済
  !
! 液体万華鏡
!
! 錯視が、生じ難いよう1回転毎に、逆回転させるようにした。
! 液面の変化に伴う容積変動を、±3.85% 以下まで押えた。

!-----------------
!※正確な液面には、なっていません。改造歓迎。

SET TEXT BACKGROUND "OPAQUE"
SET WINDOW -1/4,1/4, -1/4,1/4
DIM x(2),y(2)

!中心(1/2,1/sqr(3)/2)、半径 r の円周上の点(x0(θ),y0(θ))
DEF x0(θ)=r*COS(θ)+1/2
DEF y0(θ)=r*SIN(θ)+1/SQR(3)/2

!中心(1/2,1/sqr(3)/2)、半径 r の円周上の点(x0(θ),y0(θ))、に接する直線
DEF f(x)=TAN(θ+PI/2)*(x-x0(θ))+y0(θ)

!_直線1とf(x)との交点(x1,y1)
!y=0 =TAN(θ+PI/2)*(x-x0(θ))+y0(θ)
DEF x1(θ)= -y0(θ)/TAN(θ+PI/2)+x0(θ)
LET y1=0

!/直線2とf(x)との交点(x2,y2)
!y=SQR(3)*x =TAN(θ+PI/2)*(x-x0(θ))+y0(θ)
DEF x2(θ)=(-y0(θ)+TAN(θ+PI/2)*x0(θ))/(TAN(θ+PI/2)-SQR(3))
DEF y2(θ)=SQR(3)*x2(θ)

!\直線3とf(x)との交点(x3,y3)
!y=-SQR(3)*(x-1) =TAN(θ+PI/2)*(x-x0(θ))+y0(θ)
DEF x3(θ)=(SQR(3)-y0(θ)+TAN(θ+PI/2)*x0(θ))/(TAN(θ+PI/2)+SQR(3))
DEF y3(θ)=-SQR(3)*(x3(θ)-1)

SET AREA COLOR 5
LET s00=SQR(3)/4
LET φ=0.001
LET stp=PI/180
DO
   IF 2*PI<=ABS(φ) THEN LET stp=-stp ! (+)左回転 (−)右回転
   LET φ=REMAINDER(φ, 2*PI) +stp
   !-----
   LET θ=φ+SIN(φ*51)*0.1+SIN(φ*49)*0.05 ! 水面揺れ..有り
   !LET θ=φ ! 水面揺れ..無し
   !-----
   LET r=0.19985-0.00355*COS(θ*6) ! 液面補正、残誤差±3.85%
   LET x00=0
   LET y00=0
   LET i=1
   LET x(i)=x1(θ)
   LET y(i)=y1
   IF 0<=x(i) AND x(i)<=1 AND 0<=y(i) AND y(i)<=SQR(3)/2 THEN LET i=i+1
   LET x(i)=x2(θ)
   LET y(i)=y2(θ)
   IF 0<=x(i) AND x(i)<=1 AND 0<=y(i) AND y(i)<=SQR(3)/2 THEN LET i=i+1.01
   IF i< 3 THEN
      LET x(i)=x3(θ)
      LET y(i)=y3(θ)
      IF 2< i THEN
         LET x00=1/2
         LET y00=SQR(3)/2
      ELSE
         LET x00=1
         LET y00=0
      END IF
   END IF
   LET ss2=ABS((x(1)-x00)*(y(2)-y00)-(y(1)-y00)*(x(2)-x00))
   SET DRAW mode hidden
   CLEAR
   DRAW D4(3) WITH SHIFT(-1/2,-1/SQR(3)/2)*ROTATE(φ-PI/2)
   DRAW center WITH SHIFT(-1/2,-1/SQR(3)/2)*ROTATE(-φ-PI/2)*SCALE(-1/8,1/8)
   PLOT TEXT,AT 0.13,0.23:"右クリックで終了"
   SET DRAW mode explicit
   WAIT DELAY 0.05
   MOUSE POLL mx,my,mlb,mrb
LOOP UNTIL mrb>=1

PICTURE center
   SET LINE COLOR 2
   SET LINE width 2
   PLOT LINES:0,0;1,0;1/2,SQR(3)/2;0,0
   SET LINE width 1
   SET LINE COLOR 1
END PICTURE

!------
PICTURE D4(k)
   IF 0< k THEN
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*SHIFT(1/4,SQR(3)/4) ! 上
      DRAW D4(k-1) WITH SCALE(1/2,-1/2)*SHIFT(1/4,SQR(3)/4) ! 中
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(-PI*2/3)*SHIFT(1/4,SQR(3)/4) !左
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(PI*2/3)*SHIFT(1,0) ! 右
   ELSE
      DRAW Set01
   END IF
END PICTURE

!------ 種の三角図
PICTURE Set01
   IF s00< ss2 THEN
      IF x00=0 THEN PLOT AREA:x(1),y(1);x(2),y(2);1/2,SQR(3)/2;1,0
      IF x00=1 THEN PLOT AREA:x(1),y(1);x(2),y(2);1/2,SQR(3)/2;0,0
      IF x00=1/2 THEN PLOT AREA:x(1),y(1);x(2),y(2);1,0;0,0
   ELSE
      PLOT AREA:x(1),y(1);x(2),y(2);x00,y00
   END IF
   PLOT LINES:x(1),y(1);x(2),y(2)
   PLOT LINES:0,0;1,0;1/2,SQR(3)/2;0,0
END PICTURE

END
 

Re: 今日の運勢を最高に

 投稿者:山中和義  投稿日:2008年12月23日(火)10時35分56秒
返信・引用  編集済
  > No.183[元記事へ]

GAIさんへのお返事です。

> パーフェクト達成のためのパターンを可能なだけ集めたいのですがどのようにすればよろしいのでしょうか?
> そこからどんな条件が必要なのか知りたいですが。


めくられるカードには、次のような単方向リスト(リンク)が構成されていればよいと思います。

●「n枚をめくる」カード束のつくり方
4枚のKを含むn枚(n=4〜52)のカードを用意する。(52−n枚は除いておく)
パーフェクトなら52枚となる。

(step.1)表向きに、上からK□■◇・・・○◆の順の束とする。□などの部分は何でもよい。
    最初のKは4枚から1つを選ぶ。□■◇・・・○◆には残り3枚のKが含まれる。

(step.2)次の手順で、逆配置の時計のようにカードを置く。
       12
      1 11
     2   10
    3  13  9
     4   8
      5 7
       6

    上から1番目のカード(K)を、2番目のカード(□)の指す位置に置く。
    上から2番目のカード(□)を、3番目のカード(■)の指す位置に置く。
    上から3番目のカード(■)を、4番目のカード(◇)の指す位置に置く。

     :
     :
     :

    上からn−1番目のカード(○)を、n番目のカード(◆)の指す位置に置く。
    上からn番目のカード(◆)を、13番目の位置に置く。

    テーブルの裏側から見た配置になっている。


(step.3)テーブルの表から見た配置にするため、カードを束ごと裏返しながら左右の位置を入れ替える。
    12、13,6時の位置は裏返すのみとなる。

(step.4)組が4枚ずつになるように、除いておいた52−n枚のカードを、(無作為に)裏向きで上に重ねていく。
    パーフェクトの場合はこの操作はない。

    めくる前の状態になる。

(step.5)13時位置から12時、11時、・・・のように(通常の)反時計まわりに1枚ずつそのままの状態で上に重ねながら回収する。



●めくられる枚数ごとの確率
「残るカード、K、めくられていくカード(3枚のKを含む)」の並び順として考える。
右端が最初にめくられるカード(13時の位置の底のカード)になる。
OPTION ARITHMETIC RATIONAL

LET t=fact(52)


LET s=0
FOR i=4 TO 52
   LET b=perm(48,52-i) * 4 * fact(i-1) !残るカード、K、めくられていくカード(3枚のKを含む)
   PRINT i;"枚 確率=";b/t
   LET s=s+b/t
NEXT i


PRINT "確率=";s !検算

END


作為の「種」を蒔くことで、花を満開にすることができます。(咲き方も同様)
 

Re: 時計のプログラミング

 投稿者:田村幸助  投稿日:2008年12月23日(火)19時50分37秒
返信・引用
  > No.186[元記事へ]

山中さん荒田さん
ありがとうございました。
 

剰余の計算

 投稿者:GAI  投稿日:2008年12月24日(水)12時02分1秒
返信・引用
  どんな大きな(10桁ほどは欲しい)x,n,aに対しても、次の剰余が求まるプログラム
を作って頂きたいです。
x^n mod a
 

Re: 剰余の計算

 投稿者:山中和義  投稿日:2008年12月24日(水)12時52分41秒
返信・引用  編集済
  > No.190[元記事へ]

GAIさんへのお返事です。

> どんな大きな(10桁ほどは欲しい)x,n,aに対しても、次の剰余が求まるプログラム
> を作って頂きたいです。
> x^n mod a


・提供済みUBASIC関数のmodpow(1234,56,789)


・PRINT MOD(1234^56,789) !1234^56 mod 789
 多桁の整数なら有理数モードで実行します。
 x^nが大きいと時間がかかります。


nが負や実数なら検討しないといけません。
 

Re: 剰余の計算

 投稿者:荒田浩二  投稿日:2008年12月25日(木)00時05分19秒
返信・引用
  > No.190[元記事へ]

GAIさんへのお返事です。

> どんな大きな(10桁ほどは欲しい)x,n,aに対しても、次の剰余が求まるプログラム
> を作って頂きたいです。
> x^n mod a

  (x mod a) = r とすれば、
  (x^n mod a) = (r^n mod a) といえるので、
   x>a のときは数値が大きくなりすぎず効果があります。

  [注意] 十進BASICのヘルプによると、有理数モードでは
  「べき指数は-2147483647〜2147483647の範囲の整数に限定」
  されるそうです。

! mod(x^n,a) 有利数モードで実行
LET x=1234
LET n=56
LET a=789
PRINT "x=";x
PRINT "n=";n
PRINT "a=";a
PRINT
PRINT "x^n=";x^n
PRINT "mod(x^n,a)=";MOD(x^n,a)
PRINT
LET r=MOD(x,a)
PRINT "r=mod(x,a)=";MOD(x,a)
PRINT "r^n=";r^n
PRINT "mod(r^n,a)=";MOD(r^n,a)
END
 

液体万華鏡のコマーシャル

 投稿者:SECOND  投稿日:2008年12月25日(木)01時57分10秒
返信・引用
  > No.187[元記事へ]

 錯視が、生じ難いよう1回転毎に、逆回転させるようにした。
 液面の変化に伴う容積変動を、±3.85% 以下まで押えた。
 液体の入っている真中の三角にコントラストを付けた。※改造歓迎
 

Re: 剰余の計算

 投稿者:荒田浩二  投稿日:2008年12月25日(木)02時09分38秒
返信・引用
  > No.190[元記事へ]

GAIさんへのお返事です。

> どんな大きな(10桁ほどは欲しい)x,n,aに対しても、次の剰余が求まるプログラム
> を作って頂きたいです。
> x^n mod a

  下のプログラムなら、計算中の最大値はr^2になります。
  rが8桁以下なら10進モードや2進モードで実行できます。
  rが8桁を超える場合は1000桁モードになります。

  x,n,aがともに10桁の下の例では、1000桁モードで約40分かかりました。

! mod(x^n,a)
LET x=9876543201
LET n=1234567890
LET a=6789012345

LET r=MOD(x,a)
LET k=r
FOR i=2 TO n
   LET k=MOD(k*r,a)
NEXT i
PRINT k
END
 

Re: 剰余の計算

 投稿者:SECOND  投稿日:2008年12月25日(木)04時29分36秒
返信・引用
  > No.190[元記事へ]

GAIさんへのお返事です。

山中氏の、EXTERNAL FUNCTION modpow(a,b,n) !a^b mod n ですが、
13桁まで、UBASIC の実行結果と一致します。(十進15桁defaultのまま)
14桁は、一致しない。
   10   print modpow(9999999999990,9999999999991,9999999999992)
   20   print modpow(9999999999991,9999999999992,9999999999993)
   30   print modpow(9999999999992,9999999999993,9999999999994)
   40   print modpow(9999999999993,9999999999994,9999999999995)
   50   print modpow(1999999999999,2999999999999,3999999999999)
   60   print modpow(2999999999999,3999999999999,4999999999999)
   70   print modpow(3999999999999,4999999999999,5999999999999)
   80   print modpow(4999999999999,5999999999999,6999999999999)
run
4328812006896
6296396057422
709006245058
6925339067979
2162020581010
1769850372477
5139725946770
6768106064755
OK
 

Re: 剰余の計算

 投稿者:白石 和夫  投稿日:2008年12月25日(木)09時11分50秒
返信・引用  編集済
  > No.190[元記事へ]

「基本のアルゴリズム」のページを見てください。
http://hp.vector.co.jp/authors/VA008683/F_Algor.htm

このプログラムは,a^n mod k を計算します。
kの値が8桁を超えるときは有理数モードで実行してください。

100 INPUT k
110 INPUT a,n
120 LET p=1
130 LET b=MOD(a,k)
140 DO UNTIL n=0
150    IF MOD(n,2)=1 THEN LET p=MOD(p*b,k)
160    LET b=MOD(b*b,k)
170    LET n=INT(n/2)
180 LOOP
190 PRINT p
200 END
 

Re: 剰余の計算

 投稿者:荒田浩二  投稿日:2008年12月25日(木)11時23分39秒
返信・引用  編集済
  > No.190[元記事へ]

GAIさんへのお返事です。

  x^nでべき指数をn=s*t*uと分解すれば、剰余計算の回数がs+t+uに減らせるのでnを素因数分解しました。
nが素数でなければ高速です。1000桁モードでも数秒です。

[投稿しようと掲示板を開いたら白石先生の投稿がありました。白石先生のプログラムではnが素数であるかに無関係で高速です。まあ、せっかく作ったので投稿します。]

追加編集[SECONDさんの投稿でさかのぼって確認しましたが、山中和義さんがすでに白石先生と同様の投稿をされていました。]

DECLARE EXTERNAL SUB prime_factor
PUBLIC NUMERIC prn(2000000),pf(100),f
DECLARE FUNCTION modn
LET x=9876543201
LET n=1234567890
LET a=6789012345
LET r=MOD(x,a)
CALL prime_factor(n) ! 素因数分解
LET k=r
FOR i=1 TO f
   LET k=modn(k,pf(i),a)
NEXT i
PRINT k
!
FUNCTION modn(r,n,a) ! mod(r^n,a)
   LET kk=r
   FOR ii=2 TO n
      LET kk=MOD(kk*r,a)
   NEXT ii
   LET modn=kk
END FUNCTION
END

REM ** 素因数分解 **
EXTERNAL SUB prime_factor(n)
DECLARE EXTERNAL SUB prime
LET f=0 ! 素因数の個数
LET q=n ! qは、商
LET m=1 ! 検証用変数
FOR i=1 TO 10
   READ prn(i)
NEXT i
DATA 2,3,5,7,11,13,17,19,23,29
LET i=1
DO WHILE MOD(q,prn(i))=0 ! 因数判定ルーチン
   LET f=f+1
   LET pf(f)=prn(i) ! pf(f)はnのf番目の素因数
   LET q=q/prn(i)
   LET m=m*prn(i)
LOOP
LET i=2
DO WHILE prn(i)<=SQR(q)
   DO WHILE MOD(q,prn(i))=0 ! 因数判定ルーチン
      LET f=f+1
      LET pf(f)=prn(i) ! pf(f)はnのf番目の素因数
      LET q=q/prn(i)
      LET m=m*prn(i)
   LOOP
   IF q=1 THEN EXIT DO
   LET i=i+1
   IF i>10 THEN CALL prime(i) ! i番目の素数
LOOP
IF q<>1 THEN
   LET f=f+1
   LET pf(f)=q
   LET m=m*q
END IF
IF m<>n THEN PRINT "error !!"
END SUB
!
REM ** 素数列生成(k番目の素数) **
EXTERNAL SUB prime(k)
LET m30=MOD(prn(k-1),30)
IF m30=1 OR m30=23 THEN LET a=prn(k-1)+6 ELSE LET a=prn(k-1)-2*MOD(m30,3)+6
DO
   LET sqra=SQR(a)
   FOR j=4 TO k-1
      IF MOD(a,prn(j))=0 THEN EXIT FOR
      IF prn(j)>=sqra THEN
         LET  prn(k)=a
         EXIT SUB
      END IF
   NEXT j
   LET m30=MOD(a,30)
   IF m30=1 OR m30=23 THEN LET a=a+6 ELSE LET a=a-2*MOD(m30,3)+6
LOOP
END SUB
 

剰余計算の調査より

 投稿者:GAI  投稿日:2008年12月25日(木)15時23分30秒
返信・引用
  数学に詳しい方は以下のことは明白なことであるでしょうが、私にとっては大発見でした。
以前
トランプのシャッフルに興味があったとき、次のことを調べていました。
カード(2n枚)でインのリフルシャッフルをしたとき、
<いま、カードが 2n枚
a1、a2、・・・、an、b1、b2、・・・、bn
あるとき、その順序を並べ替えて、
b1、a1、b2、a2、・・・・・・・・、bn、an
となるとき、
2n 枚のカードが「インでリフルシャッフル」されたということにする。>

これについて調べていくと(2〜100枚で調査)

枚数 同順復元回数 逆順復元回数    枚数 同順復元回数 逆順復元回数
2   2           1              52 52         26
4   4           2              54 20
6   3                           56 18           9
8   6           3              58 58         29
10 10         5              60 60         30
12 12         6              62   6
14   4                         64 12           6
16   8         4              66 66         33
18 18         9              68 22
20   6                         70 35
22 11                        72   9
24 20       10              74 20
26 18         9              76 30
28 28       14              78 39
30   5                         80 54         27
32 10         5              82 82         41
34 12                         84   8
36 36       18              86 28
38 12                        88 11
40 20       10              90 12
42 14         7              92 10
44 12                        94 36
46 23                         96 48         24
48 21                         98 30         15
50  8                       100100        50

なる調査結果を得ていました。

このことから、トランプ(52枚)で
アウトのリフルシャッフル(元のトップとボトムを常に再びリフル後のトップとボトムにする。)をすれば、52枚のアウトシャッフル=50枚のインシャッフルに同じなので、8回
で元に戻ることが起きることになる。

ところでここに出てくる数字がランダムに並んでいくことに不思議さを感じていました。
今度、作成して頂いたa^n(mod k)を計算して表を作成して、眺めていてある関係があることに気づきました。

この同順復元回数が
a=2,k=カードの枚数+1で計算させたとき、余りの値が1を最初にとる時のnに対応した。
<例>
カード52枚なら
 2^n≡1(MOD53)
なる最小のnが同順復元回数になっていた。
また
 2^n≡52 (MOD53)
なる最小nが逆順復元回数を知らせる。

トランプシャッフルと剰余が思わぬところで繋がったことにさらに不思議さが深まりました
 

Re: 剰余計算の調査より

 投稿者:山中和義  投稿日:2008年12月25日(木)16時50分57秒
返信・引用  編集済
  > No.198[元記事へ]

GAIさんへのお返事です。

> カード52枚なら
>  2^n≡1(MOD53)
> なる最小のnが同順復元回数になっていた。
> また
>  2^n≡52 (MOD53)
> なる最小nが逆順復元回数を知らせる。



1回のシャッフルでカードkが現れる位置をf(k)は(カードkはf(k)番目にある)
 f(k)=MOD(2*k,n+1)
と表せる。

m回シャッフルを繰り返すと
f(f(f(…(f(k)))))=2*(2*(2*…(2*k mod n+1) mod n+1) mod n+1) mod n+1=2^m*k mod n+1


一覧表をつくるプログラム
!リフルシャッフル

!n枚のカードを1,2,3,…,n-1,nに並べる。
!1回のシャッフルでカードkが現れる位置をf(k)と表す。(カードkはf(k)番目にある)
DEF f(k)=MOD(2*k,n+1)

FOR n=2 TO 100 STEP 2 !偶数
   PRINT USING "### 枚:":n;

   LET x=1 !カードxに着目
   LET iter=1000
   FOR m=1 TO iter !m回のシャッフル ※
      LET x=f(x) !2^m*k (mod n+1)
      !!!PRINT m;x
      IF x=n THEN PRINT USING "### 回目で逆順、":m; !逆順
      IF x=1 THEN EXIT FOR !もとに戻る
   NEXT m
   IF m>iter THEN
      PRINT USING "### 回では元に戻りません。":m
   ELSE
      PRINT USING "### 回目に元に戻る":m
   END IF

NEXT n

END


UBASICのmodinv関数を使った場合(サブルーチンは省略)
FOR n=2 TO 100 STEP 2 !偶数
   PRINT USING "### 枚:":n;

   LET iter=1000
   FOR m=1 TO iter
      LET x=modinv(2^m,n+1) !1枚目のカードの元の位置を得る
      IF x=n THEN PRINT USING "### 回目で逆順、":m; !逆順
      IF x=1 THEN EXIT FOR !もとに戻る
   NEXT m
   IF m>iter THEN
      PRINT USING "### 回では元に戻りません。":m
   ELSE
      PRINT USING "### 回目に元に戻る":m
   END IF

NEXT n
END
 

Re: プログラムの書き直し

 投稿者:SECOND  投稿日:2008年12月25日(木)20時28分59秒
返信・引用
  > No.171[元記事へ]

山中和義さんへのお返事です。

b=0 のときの値が変です。EXTERNAL FUNCTION modpow(a,b,n) !a^b≡x mod n のxを返す
 

Re: プログラムの書き直し

 投稿者:山中和義  投稿日:2008年12月25日(木)21時19分17秒
返信・引用
  > No.200[元記事へ]

SECONDさんへのお返事です。

> b=0 のときの値が変です。EXTERNAL FUNCTION modpow(a,b,n) !a^b≡x mod n のxを返す

b=0での場合分けは必要なしですね。(原形ではmodpow=1ではなくて、S=1でした。)


EXTERNAL FUNCTION modpow(a,b,n) !a^b≡x mod n のxを返す
   LET S=1
   DO WHILE b>0
      IF MOD(b,2)=1 THEN LET S=MOD(S*a,n) !ビットが1なら計算する
      LET b=INT(b/2) !べき乗bを2進展開する
      LET a=MOD(a*a,n)
   LOOP
   LET modpow=S
END FUNCTION
 

Re: 剰余計算の調査より

 投稿者:山中和義  投稿日:2008年12月26日(金)15時25分9秒
返信・引用
  > No.198[元記事へ]

GAIさんへのお返事です。


以前、山を使ったシャッフルがあったと思います。

「あるシャッフル方法の規則性」 > No.109 [元記事へ]


この場合は、

 LET p=3 !山の数
 DEF f(k)=MOD(p*(n-k+1),n+1)

 ただし、n=m*p(nはpの倍数)。

となるので、modpow関数またはmodinv関数を使うなら(サブルーチンは省略)
!山を使ったシャッフル
LET p=3 !山の数

FOR n=p TO 100 STEP p !pの倍数
   PRINT USING "### 枚:":n;

   LET iter=1000
   FOR m=1 TO iter
   !!!LET x=modinv((n*p)^m,n+1) !1枚目のカードの元の位置(カード番号)を得る
      LET x=modpow(n*p,m,n+1) !1番のカードの位置を得る
      IF x=n THEN PRINT USING "### 回目で逆順、":m; !逆順
      IF x=1 THEN EXIT FOR !もとに戻る
   NEXT m
   IF m>iter THEN
      PRINT USING "##### 回では元に戻りません。":m
   ELSE
      PRINT USING "### 回目に元に戻る":m
   END IF

NEXT n

END

で回数が求まると思います。
 

おーーーーー

 投稿者:GAI  投稿日:2008年12月26日(金)18時30分43秒
返信・引用
  > No.202[元記事へ]

山中和義さんへのお返事です。

ホントだ!!!
以前の山分けシャッフルもmodinvやmodpow関数を使うことで解明できるんですね。
数式だけだと近寄り難い印象がありますが、こんなにも役立つ機能を有しているなんてすばらしい。
整数論の本をあらためて読みたくなりました。
数字とはまったく不思議な振る舞いをするもんだ。(数字にしてみれば、当然の行動なんでしょうが・・・)
これは人間対コンピュータの関係に似ているのかもしれない。
コンピュータは指示された通りの行動をしているのに、思うように動かなせないこのもどかしさに似ています。
 

仕様でしょうか。

 投稿者:SECOND  投稿日:2008年12月27日(土)00時15分51秒
返信・引用
  !
!文字が、鏡像になりません、仕様でしょうか。
!
SET TEXT JUSTIFY "center","half"
SET WINDOW -2, 2, -2, 2
SET COLOR MIX(15) 0.5,0.5,0.5
DRAW grid

DRAW test WITH SCALE( 1, 1)
DRAW test WITH SCALE(-1, 1)
DRAW test WITH SCALE( 1,-1)

PICTURE test
   PLOT LINES: 0,0; 1,0; 0.7,0.8; 0,0
   PLOT POINTS: 0.2,0.1
   PLOT TEXT,AT 0.6,0.4 :"1234"
END PICTURE

END
 

時計、時計、時計

 投稿者:SECOND  投稿日:2008年12月27日(土)01時50分5秒
返信・引用
  !1つ覚えに過ぎるか?取りあえずミラーの中に入れてみた。plot text を避けて、
!plot label を使用したので、文字への効果は、ありません。

! 時計、時計、時計
!-------------------
LET N=2
LET NN=2^N
SET TEXT font "Century",11
SET TEXT JUSTIFY "center","half"
SET TEXT BACKGROUND "OPAQUE"
SET WINDOW -250/NN,250/NN,250/NN,-250/NN

LET φ=0
LET stp=-PI/180*6
DO
   LET t=INT(TIME)
   IF t0<>t THEN
      LET t0=t
      IF 2*PI<=ABS(φ) THEN LET stp=-stp
      LET φ=REMAINDER(φ, 2*PI) +stp
      !-----
      SET DRAW mode hidden
      CLEAR
      DRAW D4(N) WITH SHIFT(-300/2,-300/2/SQR(3))*ROTATE(φ*(-1)^N)*SCALE(1,(-1)^N)
      DRAW center WITH SHIFT(-300/2/NN,-300/2/NN/SQR(3))*ROTATE(φ)
      PLOT TEXT,AT 180/NN,-240/NN:"Right Click to Stop"
      SET DRAW mode explicit
   ELSE
      WAIT DELAY 0.05 ! 省電力効果
   END IF
   MOUSE POLL mx,my,mlb,mrb
LOOP UNTIL mrb>=1 ! 右クリックで停止

PICTURE center
   SET LINE COLOR 2
   SET LINE width 2
   PLOT LINES:0,0;300/NN,0;300/2/NN,300/2/NN*SQR(3);0,0
   SET LINE width 1
   SET LINE COLOR 1
END PICTURE

!------
PICTURE D4(k)
   IF 0< k THEN
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*SHIFT(300/4,SQR(3)*300/4) ! 内側の上
      DRAW D4(k-1) WITH SCALE(1/2,-1/2)*SHIFT(300/4,SQR(3)*300/4) ! 内側の中
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(-PI*2/3)*SHIFT(300/4,SQR(3)*300/4) !内側の左
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(PI*2/3)*SHIFT(300,0) ! 内側の右
   ELSE
      DRAW 時計図 WITH ROTATE(-φ)*SHIFT(300/2,300/2/SQR(3))
      PLOT LINES:0,0;300,0;300/2,SQR(3)*300/2;0,0 ! 外側の基準三角形(直接の描画は無し。)
   END IF
END PICTURE

!------
PICTURE 時計図
   SET AREA COLOR 1
   FOR i=1 TO 60
      LET a=PI/30*(i-15)
      IF MOD(i,5)=0 THEN
         PLOT label,AT 60*COS(a)+1, 60*SIN(a) :STR$(i/5) !数字
         DRAW disk WITH SCALE(1)*SHIFT(72*COS(a),72*SIN(a)) !5分目盛り
      ELSE
         DRAW disk WITH SCALE(.5)*SHIFT(72*COS(a),72*SIN(a)) !1分目盛り
      END IF
   NEXT i
   !--- 00:00 からt秒 の針回転 Gear
   DRAW hand(1) WITH SCALE(2.5, 0.75)*ROTATE(t*PI/21600) ! 時針
   DRAW hand(1) WITH ROTATE(t*PI/1800) ! 分針
   DRAW hand(1) WITH SCALE(0, 1.1)*ROTATE(t*PI/30) ! 秒針
   !--- 中心の飾り
   DRAW disk WITH SHIFT(0,0)*SCALE(4)
END PICTURE

PICTURE hand(c) ! 3針共用
   SET AREA COLOR c
   PLOT AREA: -1,15; 1,15; 1,-60; -1,-60
END PICTURE

END
 

疑問

 投稿者:GAI  投稿日:2008年12月27日(土)13時38分59秒
返信・引用
  > No.205[元記事へ]

SECONDさんへのお返事です。

万華鏡に万華鏡を入れ込むことはできるのでしょうか?
中に水や時計が入れられるなら、中に見ている万華鏡の映像を入れてみて見たい。
 

Re: 疑問

 投稿者:SECOND  投稿日:2008年12月27日(土)14時18分26秒
返信・引用  編集済
  > No.206[元記事へ]

GAIさんへのお返事です。

> 万華鏡に万華鏡を入れ込むことはできるのでしょうか?
> 中に水や時計が入れられるなら、中に見ている万華鏡の映像を入れてみて見たい。

実は、そのご返事をする前に、
以前に、投稿したものですが、下のプログラムを走らせて見て下さい。

!-----------------------------------------------------
!シルピンスキーのガスケットと並べて動かしてみる。

OPTION ARITHMETIC NATIVE
DIM px(11),py(11)

MAT READ px
DATA 0.20, 0.40, 0.60, 0.80, 0.70, 0.60, 0.50, 0.40, 0.30, 0.20, 0.40
MAT READ py
DATA 0.11, 0.11, 0.11, 0.11, 0.29, 0.47, 0.65, 0.47, 0.29, 0.11, 0.11

!----------
FOR N=0 TO 4
   FOR s=9 TO 1 STEP -1
      SET DRAW mode hidden
      CLEAR
      SET WINDOW -0.4,1.6, -1.1,0.9
      PLOT TEXT,AT 0.6,0.8:"ミラー縮小4分岐"
      PLOT TEXT,AT 0.8,0.7, USING "N= %%":N
      DRAW D4(N)
      SET WINDOW -1.0,1.0, -0.05,1.95
      PLOT TEXT,AT 0.6,0.8:"中を抜いたもの"
      PLOT TEXT,AT 0.8,0.7, USING "N= %%":N
      DRAW D42(N)
      SET WINDOW 0.0,4.0, -0.1,3.9
      PLOT TEXT,AT 0.1,1.8:"シルピンスキーのガスケット"
      PLOT TEXT,AT 1.2,1.6, USING "N= %%":N
      DRAW D3(N)
      SET DRAW mode explicit
      WAIT DELAY 0.2
   NEXT s
NEXT N

!------ ミラー縮小4分岐
PICTURE D4(k)
   IF 0<k THEN
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*SHIFT(1/4,SQR(3)/4) ! 上
      DRAW D4(k-1) WITH SCALE(1/2,-1/2)*SHIFT(1/4,SQR(3)/4) ! 中
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(-PI*2/3)*SHIFT(1/4,SQR(3)/4) ! 左
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(PI*2/3)*SHIFT(1,0) ! 右
   ELSE
      DRAW Set01
   END IF
END PICTURE

!------ ミラー縮小4分岐(中)を外すと、シルピンスキーのガスケットもどきになる。
PICTURE D42(k)
   IF 0<k THEN
      DRAW D42(k-1) WITH SCALE(1/2,1/2)*SHIFT(1/4,SQR(3)/4) ! 上
      ! これを外す DRAW D42(k-1) WITH SCALE(1/2,-1/2)*SHIFT(1/4,SQR(3)/4) ! 中
      DRAW D42(k-1) WITH SCALE(1/2,1/2)*ROTATE(-PI*2/3)*SHIFT(1/4,SQR(3)/4) ! 左
      DRAW D42(k-1) WITH SCALE(1/2,1/2)*ROTATE(PI*2/3)*SHIFT(1,0) ! 右
   ELSE
      DRAW Set01
   END IF
END PICTURE

!------ シルピンスキーのガスケット
PICTURE D3(k)
   IF 0<k THEN
   !---リンク・BASICで描く自己相似図形から拝借
      DRAW D3(k-1) WITH SCALE(1/2)
      DRAW D3(k-1) WITH SHIFT(-2,0)*SCALE(1/2)*SHIFT(2,0)
      DRAW D3(k-1) WITH SHIFT(-1,-SQR(3))*SCALE(1/2)*SHIFT(1,SQR(3))
   ELSE
      DRAW Set01
   END IF
END PICTURE

!------ 親集合の三角図1枚
PICTURE Set01
   PLOT LINES: 0,0; 1,0 ;0.5,SQR(3)/2 ;0,0
   SET AREA COLOR 2
   DRAW disk WITH SCALE(0.1)*SHIFT(px(s),py(s)) ! 飾り1
   SET AREA COLOR 3
   DRAW disk WITH SCALE(0.1)*SHIFT(px(s+1),py(s+1)) ! 飾り2
   SET AREA COLOR 4
   DRAW disk WITH SCALE(0.1)*SHIFT(px(s+2),py(s+2)) ! 飾り3
END PICTURE

END
 

シャッフルについて調べていたら

 投稿者:SECOND  投稿日:2008年12月29日(月)07時01分26秒
返信・引用
  !シャッフルについて調べていたら、このページに
!http://www004.upp.so-net.ne.jp/s_honma/number/shuffle.htm#別表
!GAI さんの調査された表と、その下の方に、C言語の検証プログラムが
!ありましたので、十進BASIC でも動くように書き直してみました。
!勝手に加筆して、結果に、おかしな数字が、出たりしていないでしょうか。

!#include <stdio.h>
!#include <string.h>
!int buf[1000], bufw[1000];
!int n;

!void shuffle(void)
!{
! int i;
! memcpy(bufw, buf, sizeof(buf[0]) * n);
! for(i = 0; i < n; ++i)
!  buf[i] = bufw[i / 2 + (i + 1) % 2 * n / 2];
!}

!int main(void)
!{
! int i, c, cc;
! for(n = 2; n <= 1000; n += 2){
!  for(i = 0; i < n; ++i)
!   buf[i] = i;
!  cc = c = 0;
!  do{
!   ++c;
!   shuffle();
!   for(i = 0; i < n; ++i)
!    if(buf[i] != n - 1 - i)
!     break;
!   if(i >= n && cc == 0)
!    cc = c;
!   for(i = 0; i < n; ++i)
!    if(buf[i] != i)
!     break;
!  }while(i < n);
!  printf("%3d %3d %3d\n", n, c, cc);
! }
! return 0;
!}

!----------------------------
!十進BASIC に移植。
! i=0~n-1 は、見づらいので i=1~n その他 無断加筆、ご容赦 )

LET maxim=13 ! 最大枚数 2~1000
DIM buf(1000), bufw(1000)

SUB in_riffle_shuffle !インのリフル。奇数枚は、後半を1枚多め
   MAT bufw=buf
   FOR i=1 TO n
      LET buf(i)= bufw(CEIL(i/2)+MOD(i,2)*INT(n/2)) !1234→3142, 12345→31425
   NEXT i
END SUB

SUB out_riffle_shuffle !アウトのリフル。奇数枚は、前半を1枚多め
   MAT bufw=buf
   FOR i=1 TO n
      LET buf(i)= bufw(CEIL(i/2)+MOD(i+1,2)*CEIL(n/2)) !1234→1324, 12345→13243
   NEXT i
END SUB

FOR n=2 TO maxim !STEP 2 ! Step を外せば奇数も計算。
!-----
   MAT buf=ZER(n) ! 配列サイズ調整、追加
   !-----
   FOR i=1 TO n
      LET buf(i)= i
   NEXT i
   LET cc=0
   LET c=0
   !-----
   IF maxim<15 THEN MAT PRINT USING REPEAT$(" ###",n) :buf ! 表示、追加
   !-----
   DO
      LET c=c+1
      CALL in_riffle_shuffle ! 1234→3142, 12345→31425
      !CALL out_riffle_shuffle ! 1234→1324, 12345→13243
      !-----
      IF maxim<15 THEN MAT PRINT USING REPEAT$(" ###",n) :buf ! 表示、追加
      !-----
      FOR i=1 TO n
         IF buf(i)<> n+1-i THEN EXIT FOR
      NEXT i
      IF i>n AND cc=0 THEN LET cc=c
      FOR i=1 TO n
         IF buf(i)<>i THEN EXIT FOR
      NEXT i
   LOOP UNTIL i>n
   PRINT USING "枚数=### 同順=### 逆順=###(復元回数)": n, c, cc
   IF maxim<15 THEN PRINT ! 表示、追加
NEXT n

END
 

お正月マジック

 投稿者:GAI  投稿日:2008年12月29日(月)12時31分20秒
返信・引用
  正月は一家団欒、親戚なども集まり子供たちも寄って来ます。
そこでトランプマジックをひとつ紹介。
誰かに52枚の中から勝手に5枚のカードを引かせる。
これをアシスタントに渡してもらう。(アシスタントの役目はあとで説明)
アシスタントはカードを一枚ずつ表向きにテーブルへ出して並べていく。
4枚並んだところで、待ったをかける。
ここであなた(マジシャン)は十分な演技を行なう。
マジシャンは残った一枚のカードのマークと数字を予言する。
最後の一枚を表向きに並べてもらう。(予言が的中する。)

<アシスタントの役目>
5枚のカードの中には必ず同じマークが存在する。
最初に表にして並べるカードはこのマークのカードの一つにする。(これで最後に残るカードのマークが判明する。)
次に3つのカードを並べるが、並べる順番を数字で
A>K>Q>J>10>9>8>7>6>5>4>3>2
の順序(ポーカーでの強弱に同じにする。)と決めておき、最初に置いたカードの数字と最後まで手元に残すカード(同じマーク)の数字の差(キーナンバー)に従って並べ方を工夫してやる。
ここで最初のカードと最後のカードの数字の配列差は必ず6以内に納まる。
これは数字を円周上の配列として考えておくとする。(時計回りにカウントする。)
        K
       Q A
         J    2
           10      3
            9     4
             8   5
              7 6

<最初に出すカードの数>   <最後まで残すカードの数>  <キーナンバー>
     A                2            1
          2                              4                       2
          3                              6                       3
          4                              8                       4
          5                             10                       5
          6                              Q                       6
          7                              K                       6
・・・・・・・・・・・・・
・・・・・・・・・・・・・
      K                              A                       1

<キーナンバーに対する3枚のカードの配列法則>
3枚のカードの数字を見比べて、3つでの強、中、弱を見る。
(もし同数であればマークで♠>♡>♢>♣ の順で強、弱を決める。)
(キーナンバー)   (3枚の配列順序)
   1:       弱 ・ 中 ・ 強
   2:       弱 ・ 強 ・ 中
   3:       中 ・ 弱 ・ 強
   4:       中 ・ 強 ・ 弱
   5:       強 ・ 弱 ・ 中
   6:       強 ・ 中 ・ 弱

<例1>
(客が引いた5枚のカード):♠J,♠2,♢5,♣J,♣2

(アシスタントが並べるカード順):♣J,♢5,♠J,♠2
                                *♣2 を最初に並べるとJまでは+9となるのでJとする。

(マジシャンの判断):1番目のカードマークより クラブの
           中・強・弱 で並んでいるから J+4より 数字は 2

<例2>
(客が引いた5枚のカード):♠J,♠4,♢2,♣J,♣2

(アシスタントが並べるカード順):♠J,♣J,♢2,♣2

(マジシャンの判断):1番目のカードマークより スペードの
           強・中・弱 で並んでいるので J+6 より数字は 4

これであなたは超能力者
 

UBASICのビット演算関数の実装

 投稿者:山中和義  投稿日:2008年12月29日(月)19時42分22秒
返信・引用
 
!真理値表
LET a=3 !0011のパターン
LET b=5 !0101のパターン

PRINT " b NOT" !否定
FOR i=0 TO 1
   PRINT bit(i,b); 1-bit(i,b) !b'=1-b
NEXT i
PRINT " a  b IMP" !論理包含
FOR i=0 TO 3
   PRINT bit(i,a); bit(i,b); bit(i,bitor(bitreverse(i,a),b)) !a' or b
NEXT i
PRINT " a  b EQV" !同値
FOR i=0 TO 3
   PRINT bit(i,a); bit(i,b); 1-bit(i,bitxor(a,b)) !(a xor b)'
NEXT i



!2の補数:定義より
LET n=16 !nビット符号付整数 -2^(n-1)〜2^(n-1)-1
LET m=2^n

LET a=3
LET aa=m-a !a+a'=m
FOR i=N-1 TO 0 STEP -1 !上の位から
   PRINT bit(i,aa);
NEXT i
PRINT


!2の補数:反転して1をたす
LET a=3
FOR i=N-1 TO 0 STEP -1 !上の位から
   LET a=bitreverse(i,a)
NEXT i
LET a=a+1
PRINT a !nビット符号なし整数 0〜2^n-1

!2の補数:反転して1をたす ※別解
LET a=3
FOR i=0 TO N-1 !下の位から
   IF bit(i,a)=1 THEN EXIT FOR !1が見つかるまで
   LET a=bitreset(i,a) !0にする
NEXT i
FOR k=i+1 TO N-1 !続き
   LET a=bitreverse(k,a) !0を1にする
NEXT k
PRINT a



!加算 a+b
LET a=123
LET b=45
DO WHILE bitand(a,b)>0
   LET t=bitxor(a,b)
   LET b=sft(bitand(a,b),1)
   LET a=t
LOOP
PRINT bitxor(a,b)


END


!ビット演算関連 ※UBASICより

EXTERNAL FUNCTION bit(n,x) !n番目のビット値 ※n,xは整数
IF n<>INT(n) OR x<>INT(x) THEN !整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET bit=MOD(INT(x/2^n),2)
END IF
END FUNCTION

EXTERNAL FUNCTION bitset(n,x) !n番目のビットを1にする ※n,xは非負整数
IF n<0 OR n<>INT(n) OR x<0 OR x<>INT(x) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET d=2^n !n桁
   LET bitset=(INT(x/d/2)*2+1)*d+MOD(x,d) !大きい桁+1+小さい桁
END IF
END FUNCTION

EXTERNAL FUNCTION bitreset(n,x) !n番目のビットを0にする ※n,xは非負整数
IF n<0 OR n<>INT(n) OR x<0 OR x<>INT(x) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET d=2^n !n桁
   LET bitreset=INT(x/d/2)*2*d+MOD(x,d) !大きい桁+1+小さい桁
END IF
END FUNCTION

EXTERNAL FUNCTION bitreverse(n,x) !n番目のビットを反転する ※n,xは非負整数
IF n<0 OR n<>INT(n) OR x<0 OR x<>INT(x) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET d=2^n !n桁
   LET a=INT(x/d)
   LET bitreverse=(INT(a/2)*4-a+1)*d+MOD(x,d) !大きい桁+NOT+小さい桁
END IF
END FUNCTION

EXTERNAL FUNCTION bitand(a,b) !ビットごとの論理積 ※a,bは非負整数
IF a<0 OR a<>INT(a) OR b<0 OR b<>INT(b) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET c=0 !値
   LET d=1
   DO UNTIL a=0 OR b=0 !最下位の桁から、桁数が小さい方まで
      LET aa=INT(a/2)
      LET bb=INT(b/2)
      LET c=c + MIN((a-aa*2),(b-bb*2)) * d !and(x,y)=MIN(x,y)

      LET a=aa !次へ
      LET b=bb
      LET d=d*2
   LOOP
   LET bitand=c
END IF
END FUNCTION

EXTERNAL FUNCTION bitor(a,b) !ビットごとの論理和 ※a,bは非負整数
IF a<0 OR a<>INT(a) OR b<0 OR b<>INT(b) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET c=0
   LET d=1
   DO UNTIL a=0 AND b=0 !桁数が大きい方
      LET aa=INT(a/2)
      LET bb=INT(b/2)
      LET c=c+MAX((a-aa*2),(b-bb*2)) * d !or(x,y)=MAX(x,y)
      LET a=aa !次へ
      LET b=bb
      LET d=d*2
   LOOP
   LET bitor=c
END IF
END FUNCTION

EXTERNAL FUNCTION bitxor(a,b) !ビットごとの排他的論理和 ※a,bは非負整数
IF a<0 OR a<>INT(a) OR b<0 OR b<>INT(b) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET c=0
   LET d=1
   DO UNTIL a=0 AND b=0 !桁数が大きい方
      LET aa=INT(a/2)
      LET bb=INT(b/2)
      LET c=c + MOD((a-aa*2)+(b-bb*2),2) * d !xor(x,y)=MOD(x+y,2)
      LET a=aa !次へ
      LET b=bb
      LET d=d*2
   LOOP
   LET bitxor=c
END IF
END FUNCTION

EXTERNAL FUNCTION bitcount(x) !1であるビットの個数 ※xは非負整数
IF x<0 OR x<>INT(x) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET c=0 !値
   DO UNTIL x=0 !最下位の桁から
      LET xx=INT(x/2) !商
      LET c=c + (x-xx*2) !余り

      LET x=xx !次へ
   LOOP
   LET bitcount=c
END IF
END FUNCTION

EXTERNAL FUNCTION sft(x,n) !nビットのシフトする ※nは整数
IF n<>INT(n) THEN !整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   IF n<0 THEN LET d=1/2 ELSE LET d=2
   FOR i=1 TO ABS(n)
      LET x=x*d
   NEXT i
   LET sft=x
END IF
END FUNCTION
 

数値積分式

 投稿者:しばっち  投稿日:2008年12月30日(火)09時36分6秒
返信・引用
  ニュートン・コーツ則 数値積分式
有理数モードでお試しください

OPTION BASE 0
PUBLIC NUMERIC MAXLEVEL
LET  MAXLEVEL=10 !'次数
DIM X(1),Y(MAXLEVEL),L(MAXLEVEL)
LET DISPMODE=0 !' 0 or else
LET INTEGRAL=1 !' INTEGRAL >= 1
LET SWITCH=0   !' 0...閉じた公式  else...開いた公式
IF DISPMODE<>0 THEN
   IF INTEGRAL > 1 THEN
      PRINT "DIM A(";STR$(INTEGRAL);"),B(";STR$(INTEGRAL);"),N(";STR$(INTEGRAL);")"
      PRINT "FOR I=1 TO";INTEGRAL
      LET A$="(" & CHR$(34) & " & STR$(I) & " & CHR$(34) & ")=" & CHR$(34) & ":"
      LET B$="(I)"
   ELSE
      LET A$="=" & CHR$(34) & ":"
      LET B$=""
   END IF
   LET C$="! INPUT  PROMPT " & CHR$(34)
   PRINT C$;"下限  ";A$;"A";B$
   PRINT C$;"上限  ";A$;"B";B$
   PRINT C$;"分割数";A$;"N";B$
   PRINT "READ A";B$;",B";B$;",N";B$
   IF INTEGRAL > 1 THEN PRINT "NEXT"
   FOR I=1 TO INTEGRAL
      PRINT "DATA 0,1,10"
   NEXT I
   FOR I=2 TO MAXLEVEL
      PRINT "PRINT INTEGRAL";STR$(I);"(";
      IF INTEGRAL=1 THEN
         PRINT "A,B,N)"
      ELSE
         FOR J=1 TO INTEGRAL
            PRINT "A(";STR$(J);"),B(";STR$(J);"),";
         NEXT J
         FOR J=1 TO INTEGRAL
            PRINT "N(";STR$(J);")";
            IF J < INTEGRAL THEN PRINT ",";
         NEXT J
         PRINT ")"
      END IF
   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"
   PRINT
END IF
LET  X(1)=1
FOR N=1 TO MAXLEVEL-1
   FOR I=0 TO N
      CALL CLR(Y)
      LET  P=1
      LET  Y(0)=1
      FOR J=0 TO N
         IF I<>J THEN
            LET  X(0)=-J
            CALL MUL(Y,X)
            LET P=P*(I-J)
         END IF
      NEXT  J
      CALL INTEGRAL(Y)
      IF SWITCH=0 THEN
         LET L(I)=HORNER(Y,N)/P
      ELSE
         LET L(I)=(HORNER(Y,N+1)-HORNER(Y,-1))/P
      END IF
   NEXT I
   IF DISPMODE<>0 THEN
      PRINT "EXTERNAL  FUNCTION INTEGRAL";STR$(N+1);"(";
      IF INTEGRAL > 1 THEN
         FOR J=1 TO INTEGRAL
            PRINT "A";STR$(J);",B";STR$(J);",";
         NEXT J
         FOR J=1 TO INTEGRAL
            PRINT "N";STR$(J);
            IF J < INTEGRAL THEN PRINT ",";
         NEXT J
      ELSE
         PRINT "A,B,N";
      END IF
      PRINT ")"
      IF SWITCH=0 THEN LET A$=STR$(N) ELSE LET A$=STR$(N+2)
      IF INTEGRAL=1 THEN
         PRINT "LET H=(B-A)/N/";A$
         PRINT "LET S=0"
         PRINT "FOR K=0 TO N-1"
         PRINT "LET S=S";
         FOR I=0 TO N
            IF SWITCH=0 THEN LET B$=STR$(I) ELSE LET B$=STR$(I+1)
            IF L(I) < 0 THEN PRINT "-"; ELSE PRINT "+";
            PRINT STR$(ABS(L(I)));"*H*FUNC(A+H*(";A$;"*K+";B$;"))";
         NEXT I
         PRINT
         PRINT "NEXT"
      ELSE
         IF SWITCH=0 THEN
            PRINT "DIM R(0 TO ";STR$(N);")"
         ELSE
            PRINT "DIM R(";STR$(N+1);")"
         END IF
         FOR I=0 TO N
            IF SWITCH=0 THEN LET B$=STR$(I) ELSE LET B$=STR$(I+1)
            PRINT "R(";B$;")=";
            IF L(I) < 0 THEN  PRINT "-";
            PRINT STR$(ABS(L(I)))
         NEXT I
         FOR J=1 TO INTEGRAL
            PRINT "LET H";STR$(J);"=(B";STR$(J);"-A";STR$(J);")/N";STR$(J);"/";A$
         NEXT J
         PRINT "LET S=0"
         FOR J=INTEGRAL TO 1 STEP -1
            PRINT "FOR K";STR$(J);"=0 TO N";STR$(J);"-1"
         NEXT J
         FOR J=1 TO INTEGRAL
            IF SWITCH=0 THEN
               PRINT "FOR J";STR$(J);"=0 TO";N
            ELSE
               PRINT "FOR J";STR$(J);"=1 TO";N+1
            END IF
         NEXT J
         PRINT "LET S=S+";
         FOR J=1 TO INTEGRAL
            PRINT "R(J";STR$(J);")*";
         NEXT J
         FOR I=1 TO INTEGRAL
            PRINT "H";STR$(I);"*";
         NEXT I
         PRINT "FUNC(";
         FOR I=1 TO INTEGRAL
            PRINT "A";STR$(I);"+H";STR$(I);"*(";A$;"*K";STR$(I);"+J";STR$(I);")";
            IF I < INTEGRAL THEN PRINT ",";
         NEXT I
         PRINT ")"
         FOR I=1 TO INTEGRAL*2
            PRINT "NEXT"
         NEXT I
      END IF
      PRINT "LET INTEGRAL";STR$(N+1);"=S"
      PRINT "END FUNCTION"
   ELSE
      PRINT "∫(x";STR$(N);",x0)f(x)dx=";
      FOR I=0 TO N
         IF L(I) < 0 THEN
            PRINT "-";
         ELSE
            IF I > 0 THEN PRINT "+";
         END IF
         PRINT STR$(ABS(L(I)));"*h*f(x";STR$(I);")";
      NEXT I
      PRINT
   END IF
   PRINT
NEXT N
END

EXTERNAL  SUB MUL(A(),B())
OPTION BASE 0
DIM C(MAXLEVEL)
FOR I=0 TO MAXLEVEL-1
   FOR J=0 TO 1
      LET  C(I+J)=C(I+J)+A(I)*B(J)
   NEXT J
NEXT I
CALL COPY(A,C)
END SUB

EXTERNAL  FUNCTION HORNER(A(),XX)
FOR N=MAXLEVEL TO 0 STEP -1
   IF A(N)<>0 THEN EXIT FOR
NEXT N
LET Y=A(N)
FOR I=N-1 TO 0 STEP -1
   LET  Y=Y*XX+A(I)
NEXT I
LET  HORNER=Y
END FUNCTION

EXTERNAL  SUB COPY(X(),Y())
FOR I=0 TO MAXLEVEL
   LET  X(I)=Y(I)
NEXT I
END SUB

EXTERNAL  SUB CLR(X())
FOR I=0 TO MAXLEVEL
   LET X(I)=0
NEXT I
END SUB

EXTERNAL  SUB INTEGRAL(A())
OPTION BASE 0
DIM B(MAXLEVEL)
FOR I=MAXLEVEL-1 TO 0 STEP -1
   LET  B(I+1)=A(I)/(I+1)
NEXT I
CALL COPY(A,B)
END SUB
 

ルジャンドル則係数計算

 投稿者:しばっち  投稿日: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
 

ラゲール則係数計算

 投稿者:しばっち  投稿日:2008年12月30日(火)09時41分16秒
返信・引用
  半無限区間積分
/∞
| f(x)dx
/0

ガウス・ラゲール則の係数(分点、重み)を算出する。
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 LAGUERREPARA(MAXLEVEL,X,W)
   PRINT "DIM X(";STR$(MAXLEVEL);"),W(";STR$(MAXLEVEL);")"
   PRINT "FOR I=1 TO";MAXLEVEL
   PRINT "READ X(I),W(I)"
   PRINT "NEXT"
   FOR I=1 TO INTEGRAL
      PRINT "INPUT  PROMPT ";CHR$(34);"GAMMA(";
      FOR J=1 TO INTEGRAL
         PRINT "X";STR$(J);
         IF J < INTEGRAL THEN PRINT ",";
      NEXT J
      PRINT ") X";STR$(I);"=";CHR$(34);":U";STR$(I)
   NEXT I
   PRINT "LET S=0"
   FOR I=1 TO INTEGRAL
      PRINT "FOR I";STR$(I);"=1 TO";MAXLEVEL
   NEXT I
   PRINT "LET  S=S+";
   FOR I=1 TO INTEGRAL
      PRINT "W(I";STR$(I);")*";
   NEXT I
   PRINT "FUNC(";
   FOR I=1 TO INTEGRAL
      PRINT "X(I";STR$(I);"),";
   NEXT I
   FOR I=1 TO INTEGRAL
      PRINT "U";STR$(I);
      IF I < INTEGRAL THEN PRINT ",";
   NEXT I
   PRINT ")*EXP(";
   FOR I=1 TO INTEGRAL
      PRINT "X(I";STR$(I);")";
      IF I < INTEGRAL THEN PRINT "+";
   NEXT I
   PRINT ")"
   FOR I=1 TO INTEGRAL
      PRINT "NEXT"
   NEXT I
   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);",";
   NEXT I
   FOR I=1 TO INTEGRAL
      PRINT "U";STR$(I);
      IF I < INTEGRAL THEN PRINT ",";
   NEXT I
   PRINT ")"
   PRINT "FUNC=";
   FOR I=1 TO INTEGRAL
      PRINT "EXP(-X";STR$(I);")*X";STR$(I);"^(U";STR$(I);"-1)";
      IF I < INTEGRAL THEN PRINT "*";
   NEXT I
   PRINT
   PRINT "END FUNCTION"
ELSE
   FOR N=2 TO MAXLEVEL
      CALL LAGUERREPARA(N,X,W)
      PRINT TAB(8+KETA/2);"分点";TAB(8+KETA*1.5);"   重み"
      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 LAGUERREPARA(N,A(),W())
OPTION ARITHMETIC DECIMAL_HIGH
OPTION BASE 0
DIM LA(MAXLEVEL+1),D(MAXLEVEL)
CALL LAGUERREPOLY(N,LA)
FOR I=0 TO N
   LET LA(I)=LA(I)/LA(N)
NEXT I
FOR I=1 TO N
   CALL DERIVATIVE(LA,D)
   LET XX=0
   DO
      LET X=XX
      LET XX=X-HORNER(N,LA,X)/HORNER(N,D,X)
   LOOP UNTIL ABS(HORNER(N,LA,XX)) < EPS AND ABS(X-XX) < EPS
   LET A(I)=XX
   LET W(I)=WEIGHT(N,XX)
   CALL DIV(LA,XX)
NEXT I
END SUB

EXTERNAL  SUB LAGUERREPOLY(N,NEWP()) !'ラゲール多項式(係数)
OPTION ARITHMETIC DECIMAL_HIGH
OPTION BASE 0
DIM P(N+1),OLDP(N)
LET OLDP(0)=1
LET P(1)=-1
LET P(0)=1
FOR I=0 TO N
   LET NEWP(I)=0
NEXT I
FOR K=2 TO N
   FOR J=0 TO K
      LET  NEWP(J)=NEWP(J)+(2*K-1)*P(J)-(K-1)^2*OLDP(J)
      LET  NEWP(J+1)=NEWP(J+1)-P(J)
   NEXT J
   IF K < N 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 LAGUERRE(NN,X) !'ラゲール多項式(値)
OPTION ARITHMETIC DECIMAL_HIGH
OPTION BASE 0
DIM L(NN+1)
LET  L(0)=1
LET  L(1)=1-X
FOR N=1 TO NN-1
   LET  L(N+1)=(2*N+1-X)*L(N)-N*N*L(N-1)
NEXT N
LET LAGUERRE=L(NN)
END FUNCTION

EXTERNAL  FUNCTION WEIGHT(N,X)
OPTION ARITHMETIC DECIMAL_HIGH
LET WEIGHT=FAC(N)^2/(X*LAGUERREDIFF(N,X)^2)
END FUNCTION

EXTERNAL  FUNCTION LAGUERREDIFF(N,X)
OPTION ARITHMETIC DECIMAL_HIGH
LET LAGUERREDIFF=(LAGUERRE(N+1,X)-(N+1-X)*LAGUERRE(N,X))/X
END FUNCTION

EXTERNAL  FUNCTION FAC(X)
OPTION ARITHMETIC DECIMAL_HIGH
LET S=1
FOR I=2 TO X
   LET S=S*I
NEXT I
LET FAC=S
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  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 DIV(A(),P)
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
 

エルミート則係数計算

 投稿者:しばっち  投稿日:2008年12月30日(火)09時42分28秒
返信・引用
  無限区間積分
/∞
| f(x)dx
/-∞

ガウス・エルミート則の係数(分点、重み)を算出する。
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 HERMITEPARA(MAXLEVEL,X,W)
   PRINT "DIM X(";STR$(MAXLEVEL);"),W(";STR$(MAXLEVEL);")"
   PRINT "FOR I=1 TO";MAXLEVEL
   PRINT "READ X(I),W(I)"
   PRINT "NEXT"
   PRINT "LET S=0"
   FOR I=1 TO INTEGRAL
      PRINT "FOR I";STR$(I);"=1 TO";MAXLEVEL
   NEXT I
   PRINT "LET  S=S+";
   FOR I=1 TO INTEGRAL
      PRINT "W(I";STR$(I);")*";
   NEXT I
   PRINT "FUNC(";
   FOR I=1 TO INTEGRAL
      PRINT "X(I";STR$(I);")";
      IF I < INTEGRAL THEN PRINT ",";
   NEXT I
   PRINT ")*EXP(";
   FOR I=1 TO INTEGRAL
      PRINT "X(I";STR$(I);")^2";
      IF I < INTEGRAL THEN PRINT "+";
   NEXT I
   PRINT ")"
   FOR I=1 TO INTEGRAL
      PRINT "NEXT"
   NEXT I
   PRINT "PRINT S,PI^";STR$(INTEGRAL/2)
   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 FUNC=EXP(";
   FOR I=1 TO INTEGRAL
      PRINT "-X";STR$(I);"^2";
   NEXT I
   PRINT ")"
   PRINT "END FUNCTION"
ELSE
   FOR N=2 TO MAXLEVEL
      CALL HERMITEPARA(N,X,W)
      PRINT TAB(8+KETA/2);"分点";TAB(8+KETA*1.5);"   重み"
      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 HERMITEPARA(N,A(),W())
OPTION ARITHMETIC DECIMAL_HIGH
OPTION BASE 0
DIM H(MAXLEVEL),D(MAXLEVEL)
CALL  HERMITEPOLY(N,H)
FOR I=0 TO N
   LET H(I)=H(I)/H(N)
NEXT I
FOR I=1 TO N
   CALL DERIVATIVE(H,D)
   LET XX=-15
   DO
      LET X=XX
      LET XX=X-HORNER(N,H,X)/HORNER(N,D,X)
   LOOP UNTIL ABS(HORNER(N,H,XX)) < EPS AND ABS(X-XX) < EPS
   LET A(I)=XX
   LET W(I)=WEIGHT(N,XX)
   CALL DIV(H,XX)
NEXT I
END SUB

EXTERNAL  SUB HERMITEPOLY(N,NEWP()) !'エルミート多項式(係数)
OPTION ARITHMETIC DECIMAL_HIGH
OPTION BASE 0
DIM P(N+1),OLDP(N)
LET  OLDP(0)=1
LET  P(1)=2
FOR I=0 TO N
   LET NEWP(I)=0
NEXT I
FOR K=2 TO N
   FOR J=1 TO K
      LET  NEWP(J)=NEWP(J)+2*P(J-1)
      LET  NEWP(J-1)=NEWP(J-1)-2*(K-1)*OLDP(J-1)
   NEXT J
   IF K < N 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 HERMITE(NN,X) !'エルミート多項式(値)
OPTION ARITHMETIC DECIMAL_HIGH
OPTION BASE 0
DIM H(NN+1)
LET  H(0)=1
LET  H(1)=2*X
FOR N=1 TO NN-1
   LET  H(N+1)=2*X*H(N)-2*N*H(N-1)
NEXT N
LET HERMITE=H(NN)
END FUNCTION

EXTERNAL  FUNCTION WEIGHT(N,X) !'重み
OPTION ARITHMETIC DECIMAL_HIGH
LET WEIGHT=2^(N+1)*FAC(N)*SQR(PI)/HERMITE(N+1,X)^2
END FUNCTION

EXTERNAL  FUNCTION FAC(X)
OPTION ARITHMETIC DECIMAL_HIGH
LET S=1
FOR I=2 TO X
   LET S=S*I
NEXT I
LET FAC=S
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)
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
 

不等間隔数値積分

 投稿者:しばっち  投稿日:2008年12月30日(火)09時43分55秒
返信・引用
  不等間隔 数値積分

/x(n)
| f(x)dx
/x(1)
積分区間 x(1)〜x(n)

PUBLIC NUMERIC MAXLEVEL
OPTION BASE 0
LET MAXLEVEL=10 !'最大次数 (MAXLEVEL > N)
LET N=5 !'データ数
DIM X(N),Y(N),A(MAXLEVEL),B(MAXLEVEL)
FOR I=1 TO N
   READ X(I),Y(I) !'y=x^2
NEXT I
CALL LARGRANGE(N,X,Y,A) !'ラグランジュ多項式
CALL INTEGRAL(A,B) !'積分
PRINT HORNER(N,B,X(N))-HORNER(N,B,X(1));X(N)^3/3-X(1)^3/3
!'CALL DERIVATIVE(A,B) !'微分
!'INPUT  PROMPT "f'(x) x=":XX
!'PRINT HORNER(N,B,XX);2*XX
DATA 0,0 !'離散値データ X値は等間隔でなくてもいい
DATA 1,1
DATA 3,9
DATA 4,16
DATA 6,36
END

EXTERNAL  SUB LARGRANGE(N,X(),Y(),A())
OPTION BASE 0
DIM U(MAXLEVEL),V(MAXLEVEL)
CALL CLR(A)
LET U(1)=1
FOR I = 1 TO N
   LET  R = Y(I)
   CALL CLR(V)
   LET V(0)=1
   FOR J = 1 TO N
      IF I <> J THEN
         LET U(0)=-X(J)
         CALL MUL(V,U)
         LET  R = R / (X(I)-X(J))
      END IF
   NEXT J
   CALL SHORTMUL(V,R)
   CALL ADD(A,V)
NEXT I
END SUB

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

EXTERNAL  SUB MUL(A(),B())
OPTION BASE 0
DIM C(MAXLEVEL)
FOR I=0 TO MAXLEVEL-1
   FOR J=0 TO 1
      LET  C(I+J)=C(I+J)+A(I)*B(J)
   NEXT   J
NEXT   I
CALL COPY(A,C)
END SUB

EXTERNAL  SUB INTEGRAL(A(),B())
FOR I=MAXLEVEL-1 TO 0 STEP -1
   LET  B(I+1)=A(I)/(I+1)
NEXT I
LET B(0)=0
END SUB

EXTERNAL  SUB ADD(A(),B())
FOR I=0 TO MAXLEVEL
   LET  A(I)=A(I)+B(I)
NEXT I
END SUB

EXTERNAL  SUB COPY(X(),Y())
FOR I=0 TO MAXLEVEL
   LET  X(I)=Y(I)
NEXT I
END SUB

EXTERNAL  SUB CLR(X())
FOR I=0 TO MAXLEVEL
   LET  X(I)=0
NEXT I
END SUB

EXTERNAL  SUB SHORTMUL(A(),X)
FOR I=0 TO MAXLEVEL
   LET A(I)=A(I)*X
NEXT I
END SUB

EXTERNAL  SUB DERIVATIVE(A(),B())
FOR I=MAXLEVEL TO 1 STEP -1
   LET  B(I-1)=I*A(I)
NEXT I
LET B(MAXLEVEL)=0
END SUB

--------------------------------------------------------------
不等間隔 数値積分 その2

/x(m)
| f(x)dx
/x(1)
積分区間 x(1)〜x(m)

LET N=5 !'データ数  条件...MOD(N-1,M-1)=0
LET M=3 !'小区間 間隔数
DIM X(N),Y(N),XX(M),YY(M)
FOR I=1 TO N
   READ X(I),Y(I) !'y=x^2
NEXT I
LET S=0
FOR I=1 TO N-M+1 STEP M-1 !'小区間に分割する X(1)〜X(3),X(3)〜X(5),X(5)〜X(7),...
   FOR K=0 TO M-1
      LET XX(K+1)=X(I+K)
      LET YY(K+1)=Y(I+K)
   NEXT K
   LET S=S+INTEGRAL(XX,YY,M) !'全区間分を足し合わせる
   !'LET SS=SS+INTEGRAL2(XX,YY,M) !'下記参照
NEXT I
PRINT S;(X(N)^3-X(1)^3)/3 !' ;SS
!'INPUT  PROMPT "f'(x) x=":XX
!'PRINT DERIVATIVE(N,X,Y,XX);2*XX !'下記参照
DATA 0,0 !'離散値データ X値は等間隔でなくてもいい
DATA 1,1
DATA 3,9
DATA 4,16
DATA 6,36
END

EXTERNAL  FUNCTION INTEGRAL(X(),Y(),M)
DECLARE EXTERNAL FUNCTION COMB
DIM H(M),XX(M),TEMP(M)
FOR I=1 TO M
   LET H(I)=1
   LET K=0
   FOR J=1 TO M
      IF I<>J THEN
         LET H(I)=H(I)/(X(I)-X(J))
         LET K=K+1
         LET XX(K)=X(J)
      END IF
   NEXT J
   LET SIGN=1
   FOR J=M TO 1 STEP -1
      LET SM=SM+SIGN*X(M)^J/J*COMB(XX,M,M-J,TEMP,1)*H(I)*Y(I)
      LET S1=S1+SIGN*X(1)^J/J*COMB(XX,M,M-J,TEMP,1)*H(I)*Y(I)
      LET SIGN=-SIGN
   NEXT J
NEXT I
LET INTEGRAL=SM-S1
END FUNCTION

EXTERNAL FUNCTION COMB(X(),N,R,A(),K)
IF R=0 THEN
   LET S=1
   FOR I=1 TO N
      IF A(I)=1 THEN LET S=S*X(I)
   NEXT I
   LET COMB=S
ELSE
   FOR I=K TO N-R+1
      LET A(I)=1
      LET SS=SS+COMB(X,N,R-1,A,I+1)
      LET A(I)=0
   NEXT I
   LET COMB=SS
END IF
END FUNCTION

--------------------------------------------------------------
不等間隔 数値積分 その3(上記参照)

未定係数法

EXTERNAL  FUNCTION INTEGRAL2(X(),Y(),N)
DIM A(N,N),B(N)
FOR I=1 TO N
   FOR J=1 TO N
      LET A(I,J)=X(J)^(I-1)
   NEXT J
   LET B(I)=(X(N)^I-X(1)^I)/I
NEXT I
MAT A=INV(A)
MAT B=A*B
FOR I=1 TO N
   LET S=S+B(I)*Y(I)
NEXT I
LET INTEGRAL2=S
END FUNCTION

--------------------------------------------------------------
不等間隔 数値微分(上記参照)

EXTERNAL  FUNCTION DERIVATIVE(N,X(),Y(),XX)
DIM A(N,N),B(N)
FOR I=1 TO N
   FOR J=1 TO N
      LET A(I,J)=X(J)^I
   NEXT J
   LET B(I)=I*XX^(I-1)
   !'LET B(I)=I*(I-1)*XX^(I-2) !'2階微分
NEXT I
MAT A=INV(A)
MAT B=A*B
FOR I=1 TO N
   LET S=S+B(I)*Y(I)
NEXT I
LET DERIVATIVE=S
END FUNCTION

--------------------------------------------------------------
不等間隔 数値微分(定義のみ)

EXTERNAL  FUNCTION DIFF(N,X(),Y(),XX)
DIM A(N)
FOR I=1 TO N
   LET  L=1
   LET  KK=0
   FOR J=1 TO N
      IF J<>I THEN
         LET  KK=KK+1
         LET  L=L*(X(I)-X(J))
         LET  A(KK)=X(J)
      END IF
   NEXT  J
   LET  S1=0
   FOR J=1 TO N-1
      LET  S=1
      FOR K=1 TO N-1
         IF K<>J THEN LET S=S*(XX-A(K))
      NEXT K
      LET  S1=S1+S
   NEXT J
   LET  SS=SS+S1*Y(I)/L
NEXT I
LET  DIFF=SS
END FUNCTION
 

多重積分

 投稿者:しばっち  投稿日:2008年12月30日(火)09時45分18秒
返信・引用
  再帰呼出しによる多重積分 シンプソン則

PUBLIC NUMERIC LEVEL
INPUT  PROMPT "多重積分 LEVEL=":LEVEL
DIM A(LEVEL),B(LEVEL),N(LEVEL),AA(LEVEL)
FOR I=1 TO LEVEL
   !'INPUT  PROMPT "下限  =":A(I)
   !'INPUT  PROMPT "上限  =":B(I)
   !'INPUT  PROMPT "分割数=":N(I)
   READ A(I),B(I),N(I)
NEXT I
DATA 0,1,10
DATA 0,1,10
DATA 0,1,10
DATA 0,1,10
PRINT SIMPSONRECURSIVE(LEVEL,AA,A,B,N)
END

EXTERNAL  FUNCTION SIMPSONRECURSIVE(LEV,AA(),A(),B(),N())
IF LEV=0 THEN
   LET  SIMPSONRECURSIVE=FUNC(AA)
ELSE
   LET  H=(B(LEV)-A(LEV))/N(LEV)/2
   FOR K=0 TO N(LEV)-1
      LET  AA(LEV)=A(LEV)+H*K*2
      LET  S=S+1/3*H*SIMPSONRECURSIVE(LEV-1,AA,A,B,N)
      LET  AA(LEV)=A(LEV)+H*(2*K+1)
      LET  S=S+4/3*H*SIMPSONRECURSIVE(LEV-1,AA,A,B,N)
      LET  AA(LEV)=A(LEV)+H*(2*K+2)
      LET  S=S+1/3*H*SIMPSONRECURSIVE(LEV-1,AA,A,B,N)
   NEXT K
   LET SIMPSONRECURSIVE=S
END IF
END FUNCTION

EXTERNAL  FUNCTION FUNC(X())
LET S=1
FOR I=1 TO LEVEL
   LET S=S-X(I)*X(I)
NEXT I
IF S > 0 THEN
   LET FUNC=SQR(S)
ELSE
   LET FUNC=0
END IF
END FUNCTION

--------------------------------------------------------------
再帰呼出しによる多重積分 ガウス・ルジャンドル則

PUBLIC NUMERIC W(10),X(10),LEVEL
INPUT  PROMPT "多重積分 LEVEL=":LEVEL
DIM A(LEVEL),B(LEVEL),XX(LEVEL),WW(LEVEL)
FOR I=1 TO LEVEL
   READ A(I),B(I)
NEXT I
DATA 0,1
DATA 0,1
DATA 0,1
DATA 0,1
RESTORE 10
FOR I=1 TO 10
   READ X(I),W(I)
NEXT I
PRINT LEGENDRERECURSIVE(LEVEL,XX,WW,A,B,10)
10 DATA -.9739065285171717,6.6671344308688138E-02 !'10点 ルジャンドル則
   DATA -.8650633666889845,1.4945134915058059E-01
   DATA -.6794095682990244,2.1908636251598204E-01
   DATA -.4333953941292472,2.6926671930999636E-01
   DATA -.1488743389816312,2.9552422471475287E-01
   DATA  .1488743389816312,2.9552422471475287E-01
   DATA  .4333953941292472,2.6926671930999636E-01
   DATA  .6794095682990244,2.1908636251598204E-01
   DATA  .8650633666889845,1.4945134915058059E-01
   DATA  .9739065285171717,6.6671344308688138E-02
END

EXTERNAL  FUNCTION LEGENDRERECURSIVE(LEV,XX(),WW(),A(),B(),N)
   IF LEV=0 THEN
      LET LEGENDRERECURSIVE=FUNC(XX)
   ELSE
      FOR I=1 TO N
         LET XX(LEV)=X(I)*(B(LEV)-A(LEV))/2+(A(LEV)+B(LEV))/2
         LET WW(LEV)=W(I)*(B(LEV)-A(LEV))/2
         LET S=S+LEGENDRERECURSIVE(LEV-1,XX,WW,A,B,N)*WW(LEV)
      NEXT I
      LET LEGENDRERECURSIVE=S
   END IF
END FUNCTION

EXTERNAL  FUNCTION FUNC(X())
LET S=1
FOR I=1 TO LEVEL
   LET S=S-X(I)*X(I)
NEXT I
IF S > 0 THEN
   LET FUNC=SQR(S)
ELSE
   LET FUNC=0
END IF
END FUNCTION

--------------------------------------------------------------
再帰呼出しによる多重積分 チェビシェフ則

PUBLIC NUMERIC LEVEL
INPUT  PROMPT "多重積分 LEVEL=":LEVEL
DIM A(LEVEL),B(LEVEL),N(LEVEL),X(LEVEL),W(LEVEL)
FOR I=1 TO LEVEL
   !'INPUT  PROMPT "下限  =":A(I)
   !'INPUT  PROMPT "上限  =":B(I)
   !'INPUT  PROMPT "分割数=":N(I)
   READ A(I),B(I),N(I)
NEXT I
DATA 0,1,10
DATA 0,1,10
DATA 0,1,10
DATA 0,1,10
PRINT TCHEBYCHEFFRECURSIVE(LEVEL,X,W,A,B,N)
END

EXTERNAL  FUNCTION TCHEBYCHEFFRECURSIVE(LEV,XX(),WW(),A(),B(),N())
IF LEV=0 THEN
   LET TCHEBYCHEFFRECURSIVE=FUNC(XX)
ELSE
   FOR I=0 TO N(LEV)-1
      LET XX(LEV)=COS((2*I+1)/2/N(LEV)*PI)*(B(LEV)-A(LEV))/2+(A(LEV)+B(LEV))/2
      LET WW(LEV)=SQR((B(LEV)-XX(LEV))*(XX(LEV)-A(LEV)))
      LET S=S+TCHEBYCHEFFRECURSIVE(LEV-1,XX,WW,A,B,N)*WW(LEV)
   NEXT I
   LET TCHEBYCHEFFRECURSIVE=S*PI/N(LEV)
END IF
END FUNCTION

EXTERNAL  FUNCTION FUNC(X())
LET S=1
FOR I=1 TO LEVEL
   LET S=S-X(I)*X(I)
NEXT I
IF S > 0 THEN
   LET FUNC=SQR(S)
ELSE
   LET FUNC=0
END IF
END FUNCTION

--------------------------------------------------------------
再帰呼出しによる多重積分 二重指数関数法(DE法)

[a,b]    q(t)=(b-a)/2*TANH(π/2*SINH(t))+(a+b)/2 q'(t)=π/2*(B-A)/2*COSH(X)*SECH(π/2*SINH(X))^2
[0,∞]   q(t)=EXP(π/2*SINH(t)) q'(t)=π/2*COSH(t)*EXP(π/2*SINH(t))
[-∞,∞] q(t)=SINH(π/2*SINH(t)) q'(t)=π/2*COSH(t)*COSH(π/2*SINH(t))

無限区間多重積分

PUBLIC NUMERIC LEVEL
INPUT  PROMPT "多重積分 LEVEL=":LEVEL
DIM X(LEVEL)
PRINT DE(LEVEL,X,1/16);PI^(LEVEL/2)
END

EXTERNAL  FUNCTION DE(LEV,X(),H)
IF LEV=0 THEN
   LET DE=FUNC(X)
ELSE
   FOR K=-4 TO 4 STEP H !'(要)調整 K=-6〜6,H=1/1000 程度
      LET X(LEV)=Q(K)
      LET  S=S+H*DE(LEV-1,X,H)*QQ(K)
   NEXT   K
   LET DE=S
END IF
END FUNCTION

EXTERNAL  FUNCTION Q(X)
LET Q=SINH(PI/2*SINH(X))
END FUNCTION

EXTERNAL  FUNCTION QQ(X)
LET QQ=PI/2*COSH(X)*COSH(PI/2*SINH(X))
END FUNCTION

EXTERNAL  FUNCTION FUNC(X())
LET S=0
FOR I=1 TO LEVEL
   LET S=S-X(I)*X(I)
NEXT I
LET  FUNC=EXP(S)
END FUNCTION
 

モンテカルロ積分

 投稿者:しばっち  投稿日:2008年12月30日(火)09時46分32秒
返信・引用
  多重積分モンテカルロ

RANDOMIZE
PUBLIC NUMERIC LEVEL
INPUT  PROMPT "多重積分 LEVEL=":LEVEL
DIM A(LEVEL),B(LEVEL),N(LEVEL),AA(LEVEL)
FOR I=1 TO LEVEL
!'INPUT  PROMPT "下限  =":A(I)
!'INPUT  PROMPT "上限  =":B(I)
!'INPUT  PROMPT "分割数=":N(I)
   READ A(I),B(I),N(I)
NEXT I
PRINT MONTE(LEVEL,A,B,10000)
!'PRINT MONTE2(LEVEL,A,B,10000,2000)
!'PRINT MONTESIMPSON(LEVEL,A,B,10000)
!'PRINT MONTERECURSIVE(LEVEL,AA,A,B,N)
DATA 0,1,50
DATA 0,1,50
DATA 0,1,50
DATA 0,1,50
END

EXTERNAL  FUNCTION MONTE(LEV,A(),B(),N)
RANDOMIZE
DIM AA(LEV)
LET H=1
FOR I=1 TO LEV
   LET H=H*(B(I)-A(I))
NEXT I
FOR K=1 TO N
   FOR I=1 TO LEV
      LET  AA(I)=A(I)+(B(I)-A(I))*RND
   NEXT I
   LET S=S+FUNC(AA)
NEXT  K
LET MONTE=H*S/N
END FUNCTION

EXTERNAL  FUNCTION MONTE2(LEV,A(),B(),N,NN)
RANDOMIZE
DIM AA(LEV)
LET HMAX=-MAXNUM
LET HMIN=MAXNUM
LET HH=1
FOR I=1 TO LEV
   LET HH=HH*(B(I)-A(I))
NEXT I
FOR K=1 TO NN
   FOR J=1 TO LEV
      LET  AA(J)=A(J)+(B(J)-A(J))*RND
   NEXT J
   LET H=FUNC(AA)
   LET HMIN=MIN(HMIN,MIN(H,0))
   LET HMAX=MAX(H,HMAX)
NEXT K
LET H=HMAX-HMIN
FOR K=1 TO N
   FOR J=1 TO LEV
      LET  AA(J)=A(J)+(B(J)-A(J))*RND
   NEXT J
   LET Z=H*RND+HMIN
   IF FUNC(AA) > 0 THEN
      IF Z > 0 AND Z < FUNC(AA) THEN LET M1=M1+1
   ELSE
      IF Z < 0 AND Z > FUNC(AA) THEN LET M2=M2+1
   END IF
NEXT K
LET MONTE2=HH*(M1-M2)/N*H
END FUNCTION

EXTERNAL  FUNCTION MONTERECURSIVE(LEV,AA(),A(),B(),N()) !'再帰式モンテカルロ
IF LEV=0 THEN
   LET  MONTERECURSIVE=FUNC(AA)
ELSE
   LET  H=B(LEV)-A(LEV)
   FOR K=1 TO N(LEV)
      LET  AA(LEV)=A(LEV)+H*RND
      LET S=S+MONTERECURSIVE(LEV-1,AA,A,B,N)
   NEXT K
   LET MONTERECURSIVE=H*S/N(LEV)
END IF
END FUNCTION

EXTERNAL  FUNCTION MONTESIMPSON(LEV,A(),B(),N)  !'モンテカルロ+シンプソン則
RANDOMIZE
DIM AA(LEV),T(LEV),HH(LEV)
LET H=1
FOR I=1 TO LEV
   LET H=H*(B(I)-A(I))
   LET HH(I)=(B(I)-A(I))/N/2
NEXT I
FOR K=1 TO N
   FOR I=1 TO LEV
      LET T(I)=(B(I)-A(I))*RND+A(I)
      LET AA(I)=A(I)+T(I)
   NEXT I
   LET S=S+1/3*H*FUNC(AA)
   FOR I=1 TO LEVEL
      LET AA(I)=A(I)+HH(I)+T(I)
   NEXT I
   LET S=S+4/3*H*FUNC(AA)
   FOR I=1 TO LEVEL
      LET AA(I)=A(I)+2*HH(I)+T(I)
   NEXT I
   LET S=S+1/3*H*FUNC(AA)
NEXT  K
LET MONTESIMPSON=S/N/2
END FUNCTION

EXTERNAL  FUNCTION FUNC(X())
LET S=1
FOR I=1 TO LEVEL
   LET S=S-X(I)*X(I)
NEXT I
IF S > 0 THEN
   LET FUNC=SQR(S)
ELSE
   LET FUNC=0
END IF
END FUNCTION

-----------------------------------------------
無限区間 多重積分モンテカルロ

PUBLIC NUMERIC LEVEL
INPUT  PROMPT "多重積分 LEVEL=":LEVEL
DIM X(LEVEL)
PRINT MONTEDE(LEVEL,X,10000);PI^(LEVEL/2)
END

EXTERNAL  FUNCTION MONTEDE(LEV,X(),N) !'モンテカルロ + DE法
RANDOMIZE
LET M=4 !'(要) 調整
LET H=2*M/N
FOR J=1 TO N
   LET V=1
   FOR I=1 TO LEV
      LET K=RND*M*2-M
      LET X(I)=Q(K)
      LET V=V*QQ(K)
   NEXT I
   LET S=S+H^LEV*FUNC(X)*V
NEXT J
LET MONTEDE=S*N^(LEV-1)
END FUNCTION

EXTERNAL  FUNCTION FUNC(X())
FOR I=1 TO LEVEL
   LET S=S-X(I)*X(I)
NEXT I
LET  FUNC=EXP(S)
END FUNCTION

EXTERNAL  FUNCTION Q(X)
LET Q=SINH(PI/2*SINH(X))
END FUNCTION

EXTERNAL  FUNCTION QQ(X)
LET QQ=PI/2*COSH(X)*COSH(PI/2*SINH(X))
END FUNCTION
 

おまけ

 投稿者:しばっち  投稿日:2008年12月30日(火)09時47分40秒
返信・引用
           /1 /1   /1
多重積分 |  | ...| sqr(1-x*x-y*y-...)dxdy...の検証用です
         /0 /0   /0

半径を1/2(R=.5)で実行してください

!' S(n+2)=V(n)*2*π*r S(n)...n次元球の表面積
!' V(n)=S(n)*r/n      V(n)...n次元球の体積
!' V(n)=π^(n/2)/GAMMA(n/2+1)*r^n
LET MAXLEVEL=20
DIM S(MAXLEVEL+2),V(MAXLEVEL+2)
INPUT  PROMPT "半径=":R !' 検証時 R=.5
LET S(2)=2*PI*R
LET V(2)=PI*R^2
LET S(3)=4*PI*R^2
LET V(3)=4/3*PI*R^3
FOR N=2 TO MAXLEVEL
   LET S(N+2)=V(N)*2*PI*R
   LET V(N+2)=S(N+2)*R/(N+2)
   PRINT N;"次元球の体積";V(N)   !';TAB(40);"表面積";S(N)
NEXT N
END


--- おまけ ---

有理数モードでお試しください

LET MAXLEVEL=20
DIM S(MAXLEVEL+2,3),V(MAXLEVEL+2,3)
LET S(2,1)=2
LET S(2,2)=1
LET S(2,3)=1
LET S(3,1)=4
LET S(3,2)=1
LET S(3,3)=2
LET V(2,1)=1
LET V(2,2)=1
LET V(2,3)=2
LET V(3,1)=4/3
LET V(3,2)=1
LET V(3,3)=3
FOR N=2 TO MAXLEVEL
   LET S(N+2,1)=V(N,1)*2
   LET S(N+2,2)=V(N,2)+1
   LET S(N+2,3)=V(N,3)+1
   LET V(N+2,1)=S(N+2,1)/(N+2)
   LET V(N+2,2)=S(N+2,2)
   LET V(N+2,3)=S(N+2,3)+1
   PRINT STR$(N);"次元球の体積   ";
   IF V(N,1)<>1 THEN LET A$=STR$(V(N,1)) & "*" ELSE LET A$=""
   IF V(N,2)=1 THEN LET P$="π" ELSE LET P$="π^" & STR$(V(N,2))
   IF V(N,3)=1 THEN LET R$="*r" ELSE LET R$="*r^" & STR$(V(N,3))
   PRINT A$;P$;R$
   PRINT STR$(N);"次元球の表面積 ";
   IF S(N,1)<>1 THEN LET A$=STR$(S(N,1)) & "*" ELSE LET A$=""
   IF S(N,2)=1 THEN LET P$="π" ELSE LET P$="π^" & STR$(S(N,2))
   IF S(N,3)=1 THEN LET R$="*r" ELSE LET R$="*r^" & STR$(S(N,3))
   PRINT A$;P$;R$
   PRINT
NEXT N
END


--- おまけ 2---

!'n次元球の体積
!'V(n)=1/(1*3*5*7*..*N)*2^((N+1)/2)*π^((N-1)/2)*R^N ...MOD(N,2)=1
!'V(n)=1/(2*4*6*8*..*N)*2^(N/2)    *π^(N/2)    *R^N ...MOD(N,2)=0
LET MAXLEVEL=20
FOR N=2 TO MAXLEVEL
   LET S=1
   FOR I=N TO 2 STEP -2
      LET  S=S/I
   NEXT I
   PRINT N;"次元球の体積   ";STR$(S*2^((N+MOD(N,2))/2));"*π^";STR$((N-MOD(N,2))/2);"*r^";STR$(N)
   PRINT N;"次元球の表面積 ";STR$(N*S*2^((N+MOD(N,2))/2));"*π^";STR$((N-MOD(N,2))/2);"*r^";STR$(N-1)
   PRINT
NEXT N
END

※ 便宜上「球」「体積」「表面積」として表示しています。
※ 2次元において、球とは「円」、体積とは「面積」、表面積とは「円周」のことです。
※ 4次元以上においても、これらの表示が正しいかどうか定かではありません。
※ n次元物体の「表面積」とは、n-1次元物体のことです。
 

PLOT TEXT

 投稿者:白石 和夫  投稿日:2008年12月30日(火)10時05分24秒
返信・引用
  > No.204[元記事へ]

現バージョンでは,PLOT TEXT文は表向き相似変換にのみ対応しています。
詳細と,対策は
http://hp.vector.co.jp/authors/VA008683/G_COMMANDS.htm
にあります。
 

Re: PLOT TEXT

 投稿者:SECOND  投稿日:2008年12月30日(火)14時22分40秒
返信・引用
  > No.221[元記事へ]

白石 先生へ

当時も、ASK PIXEL ARRAY文と、MAT PLOT CELLS文で、時計文字盤の全体を
包んで やってみたのですが著しい速度低下で、だめでした。
文字のみの12領域に分けて、余計な画素を送らないようにすればどうか、
もう一度試してみます。他に、何か代替する方法がありましたら、ご教示ください。
 

7セグメント数字表示のデジタル時計

 投稿者:山中和義  投稿日:2008年12月31日(水)09時21分11秒
返信・引用
  以前作った論理回路サブルーチンの一部を使って電子工作ふ〜(チップの組み立て)の記述です。
!7セグメント数字表示のデジタル時計(Clock)

LET w=400 !画面の大きさ
LET h=120
SET bitmap SIZE w+1,h+1 !ドット単位にする
SET WINDOW 0,w,h,0 !クライアント座標(左上が原点)


LET S0=-1
DO
   LET t$=TIME$ !時刻をhh:mm:ss形式で得る

   LET S=VAL(t$(7:8)) !秒
   IF S<>S0 THEN !更新されたら
      LET S0=S

      LET H=VAL(t$(1:2)) !時
      LET M=VAL(t$(4:5)) !分

      CALL clock_display(INT(H/10),MOD(H,10),INT(M/10),MOD(M,10),INT(S/10),MOD(S,10))
   END IF
LOOP



!電子部品(配置と配線)

!         ↓BCD(h10,h1,m10,m1,s10,s1)
!  ┌─ データラッチ
!  │     ↓BCD
!  │   デコーダ
!  │     ↓abcdefg
!  └→ 88:88:88
!         │
!         GND
SUB clock_display(h10,h1,m10,m1,s10,s1) !表示部
   SET DRAW mode hidden !ちらつき防止(開始)
   CLEAR

   DRAW LED(1,GND) WITH SCALE(20)*SHIFT(155,40) !コロン
   DRAW LED(1,GND) WITH SCALE(20)*SHIFT(155,80)

   !ダイナミック点灯表示
   DRAW DRIVER7segment(h10) WITH SCALE(20)*SHIFT(50,60) !時
   DRAW DRIVER7segment(h1) WITH SCALE(20)*SHIFT(110,60)

   DRAW DRIVER7segment(m10) WITH SCALE(20)*SHIFT(200,60) !分
   DRAW DRIVER7segment(m1) WITH SCALE(20)*SHIFT(260,60)

   DRAW DRIVER7segment(s10) WITH SCALE(15)*SHIFT(320,70) !秒
   DRAW DRIVER7segment(s1) WITH SCALE(15)*SHIFT(370,70)

   SET DRAW mode explicit !ちらつき防止(終了)
END SUB

PICTURE DRIVER7segment(BCD) !7セグメント数字表示にする
   CALL DECODE7segment(BCD, Za,Zb,Zc,Zd,Ze,Zf,Zg)
   DRAW LED7segmentKwithoutDP(Za,Zb,Zc,Zd,Ze,Zf,Zg)
END PICTURE


!電子部品(上位)

SUB DECODE7segment(n, Za,Zb,Zc,Zd,Ze,Zf,Zg) !7セグメント数字表示デコーダ
   IF n=0 THEN
      LET ptn$="1111110" !abcdedfgのオン・オフ状態
   ELSEIF n=1 THEN
      LET ptn$="0110000"
   ELSEIF n=2 THEN
      LET ptn$="1101101"
   ELSEIF n=3 THEN
      LET ptn$="1111001"
   ELSEIF n=4 THEN
      LET ptn$="0110011"
   ELSEIF n=5 THEN
      LET ptn$="1011011"
   ELSEIF n=6 THEN
      LET ptn$="1011111"
   ELSEIF n=7 THEN
      LET ptn$="1110000"
   ELSEIF n=8 THEN
      LET ptn$="1111111"
   ELSEIF n=9 THEN
      LET ptn$="1111011"
   ELSE
      PRINT "不正な値です。"; n
   END IF

   LET Za=VAL(ptn$(1:1))
   LET Zb=VAL(ptn$(2:2))
   LET Zc=VAL(ptn$(3:3))
   LET Zd=VAL(ptn$(4:4))
   LET Ze=VAL(ptn$(5:5))
   LET Zf=VAL(ptn$(6:6))
   LET Zg=VAL(ptn$(7:7))
END SUB

!    --a-      配置位置
!  f|    |b
!    --g-
!  e|    |c
!    --d-
PICTURE LED7segmentKwithoutDP(a,b,c,d,e,f,g) !7セグメント数字表示器  ※カソード・コモン
   DRAW bar(a,GND) WITH SHIFT(0,-2) !※左上が原点
   DRAW bar(b,GND) WITH ROTATE(PI/2)*SHIFT(1,-1)
   DRAW bar(c,GND) WITH ROTATE(PI/2)*SHIFT(1,1)
   DRAW bar(d,GND) WITH SHIFT(0,2)
   DRAW bar(e,GND) WITH ROTATE(PI/2)*SHIFT(-1,1)
   DRAW bar(f,GND) WITH ROTATE(PI/2)*SHIFT(-1,-1)
   DRAW bar(g,GND) WITH SHIFT(0,0)
END PICTURE


!電子部品(下位)

PICTURE bar(a,k) !発光ダイオードを表示する
   IF a=1 AND k=0 THEN
      PLOT AREA: -1,-0.3; 1,-0.3; 1,0.3; -1,0.3 !点灯 ※塗り潰し
   ELSE
      PLOT LINES: -1,-0.2; 1,-0.2; 1,0.2; -1,0.2; -1,-0.2 !消灯 ※枠
   END IF
END PICTURE

PICTURE LED(a,k) !発光ダイオードを表示する
   IF a=1 AND k=0 THEN
      DRAW disk WITH SCALE(0.4) !点灯
   ELSE
      DRAW circle WITH SCALE(0.4) !消灯
   END IF
END PICTURE

END
 

Re: 7セグメント数字表示のデジタル時計

 投稿者:SECOND  投稿日:2009年 1月 1日(木)03時00分30秒
返信・引用
  > No.223[元記事へ]

! 山中さんの7セグ数字で、気が付いた。ありがとうございます。
! plot_lines の、vector_fontで、PLOT TEXT を、カバーできた。
! やや長文と、やせた字形は難点ながら、時計の数字も、鏡像になった。
!
!-------------------
LET N=2
LET NN=2^N
SET WINDOW -250/NN,250/NN,250/NN,-250/NN
SET TEXT COLOR 4
SET TEXT BACKGROUND "OPAQUE"
LET φ=0
LET stp=-PI/180*6
DO
   LET t=INT(TIME)
   IF t0<>t THEN
      LET t0=t
      IF 2*PI<=ABS(φ) THEN LET stp=-stp
      LET φ=REMAINDER(φ, 2*PI) +stp
      !-----
      SET DRAW mode hidden
      CLEAR
      DRAW D4(N) WITH SHIFT(-300/2,-300/2/SQR(3))*ROTATE(φ*(-1)^N)*SCALE(1,(-1)^N)
      DRAW center WITH SHIFT(-300/2/NN,-300/2/NN/SQR(3))*ROTATE(φ)
      PLOT TEXT,AT 137/NN,-234/NN:"右クリックで停止"
      SET DRAW mode explicit
   ELSE
      WAIT DELAY 0.05 ! 省電力効果
   END IF
   MOUSE POLL mx,my,mlb,mrb
LOOP UNTIL mrb>=1 ! 右クリックで停止

PICTURE center
   SET LINE COLOR 2
   SET LINE width 2
   PLOT LINES:0,0;300/NN,0;300/2/NN,300/2/NN*SQR(3);0,0
   SET LINE width 1
   SET LINE COLOR 1
END PICTURE

!------
PICTURE D4(k)
   IF 0< k THEN
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*SHIFT(300/4,SQR(3)*300/4) ! 内側の上
      DRAW D4(k-1) WITH SCALE(1/2,-1/2)*SHIFT(300/4,SQR(3)*300/4) ! 内側の中
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(-PI*2/3)*SHIFT(300/4,SQR(3)*300/4) !内側の左
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(PI*2/3)*SHIFT(300,0) ! 内側の右
   ELSE
      DRAW 時計図 WITH ROTATE(-φ)*SHIFT(300/2,300/2/SQR(3))
      PLOT LINES:0,0;300,0;300/2,SQR(3)*300/2;0,0 ! 外側の基準三角形(直接の描画は無し。)
   END IF
END PICTURE

!------
PICTURE 時計図
   SET AREA COLOR 1
   FOR i=1 TO 60
      LET a=PI/30*(i-15)
      IF MOD(i,5)=0 THEN
         CALL linefont(i/5, 60*COS(a), 60*SIN(a)) !数字
         DRAW disk WITH SCALE(1)*SHIFT(72*COS(a),72*SIN(a)) !5分目盛り
      ELSE
         DRAW disk WITH SCALE(.5)*SHIFT(72*COS(a),72*SIN(a)) !1分目盛り
      END IF
   NEXT i
   !--- 00:00 からt秒 の針回転 Gear
   DRAW hand(1) WITH SCALE(2.5, 0.75)*ROTATE(t*PI/21600) ! 時針
   DRAW hand(1) WITH ROTATE(t*PI/1800) ! 分針
   DRAW hand(2) WITH SCALE(0, 1.1)*ROTATE(t*PI/30) ! 秒針
   !--- 中心の飾り
   DRAW disk WITH SHIFT(0,0)*SCALE(4)
END PICTURE

PICTURE hand(c) ! 3針共用
   SET AREA COLOR c
   PLOT AREA: -1,15; 1,15; 1,-60; -1,-60
END PICTURE

!-------------------------------------
SUB linefont(i,x,y) ! plot text の代替
   SELECT CASE i
   CASE 1
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 1
   CASE 2
      PLOT LINES:x-2.6,y-5;x+2.6,y-5;x+2.6,y;x-2.6,y;x-2.6,y+5;x+2.6,y+5 ! 2
   CASE 3
      PLOT LINES:x-2.6,y-5;x+2.6,y-5;x+2.6,y+5;x-2.6,y+5 ! 3a
      PLOT LINES:x-2.6,y;x+2.6,y ! 3b
   CASE 4
      PLOT LINES:x-2.6,y-5;x-2.6,y;x+2.6,y ! 4a
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 4b
   CASE 5
      PLOT LINES:x+2.6,y-5;x-2.6,y-5;x-2.6,y;x+2.6,y;x+2.6,y+5;x-2.6,y+5 ! 5
   CASE 6
      PLOT LINES:x+2.6,y-5;x-2.6,y-5;x-2.6,y+5;x+2.6,y+5;x+2.6,y;x-2.6,y ! 6
   CASE 7
      PLOT LINES:x-2.6,y-5;x+2.6,y-5;x+2.6,y+5 ! 7
   CASE 8
      PLOT LINES:x-2.6,y;x-2.6,y-5;x+2.6,y-5;x+2.6,y+5;x-2.6,y+5;x-2.6,y;x+2.6,y ! 8
   CASE 9
      PLOT LINES:x+2.6,y;x-2.6,y;x-2.6,y-5;x+2.6,y-5;x+2.6,y+5;x-2.6,y+5 ! 9
   CASE 10
      LET x=x-7
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 1
      LET x=x+11
      PLOT LINES:x-2.6,y+5;x-2.6,y-5;x+2.6,y-5;x+2.6,y+5;x-2.6,y+5 ! 0
   CASE 11
      LET x=x-5
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 1
      LET x=x+9
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 1
   CASE 12
      LET x=x-7
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 1
      LET x=x+11
      PLOT LINES:x-2.6,y-5;x+2.6,y-5;x+2.6,y;x-2.6,y;x-2.6,y+5;x+2.6,y+5 ! 2
   CASE ELSE
   END SELECT
END SUB

END
 

Re: 7セグメント数字表示のデジタル時計

 投稿者:荒田浩二  投稿日:2009年 1月 2日(金)21時16分48秒
返信・引用  編集済
  > No.224[元記事へ]

SECONDさんへのお返事です。

文字の鏡像を描画できるようにしました。MAT PLOT CELLSではその領域のすべての画素を描画し時間がかかるので、文字線のある画素のみ読込み、MAT PLOT POINTSで描画するようにしました。

SECONDさんのプログラムの3行目のSET WINDOW文の後ろにつぎのプログロムを挿入してみてください。既存のSUB linefontは廃してください。
Century体は日本語に対応してないので"右クリックで停止"を"Right Click to Stop"にもどしてください。

MAT PLOT文は3次元の配列には適応してないので、あまりスマートではないですがなんとか1秒以内に描画できると思います。遅れる場合は文字サイズ(th=13)を小さくしてみて下さい。

!
ASK TEXT HEIGHT ath
ASK TEXT JUSTIFY atjx$,atjy$
SET POINT STYLE 1
SET TEXT JUSTIFY "CENTER","HALF"
LET th=13
SET TEXT HEIGHT th
SET TEXT FONT "Century" ,0
ASK TEXT WIDTH("WW") tw
ASK PIXEL SIZE (0,0;1.2*th,1.2*tw) px,py
LET p=ABS(px*py)
DIM f0(p,2),f1(p,2),f2(p,2),f3(p,2),f4(p,2),f5(p,2),f6(p,2),f7(p,2),f8(p,2),f9(p,2),f10(p,2),f11(p,2),f12(p,2)
LET pitchx=WORLDX(PIXELX(0)+1)
LET pitchy=WORLDY(PIXELY(0)+1)
FOR i=1 TO 12
   PLOT TEXT ,AT 0,0 : STR$(i)
   MAT f0=ZER
   LET k=0
   FOR x=-0.6*tw TO 0.6*tw STEP pitchx
      FOR y=0.6*th TO -0.6*th STEP pitchy
         ASK PIXEL VALUE (x,y) pc
         IF pc=1 THEN ! 中間色(灰色)を読み込むなら条件を pc<>0
            LET k=k+1
            LET f0(k,1)=x
            LET f0(k,2)=y
         END IF
      NEXT y
   NEXT x
   CALL font_read
   CLEAR
NEXT i
SET TEXT HEIGHT ath
SET TEXT JUSTIFY atjx$,atjy$
!
SUB font_read
   MAT f12=ZER(k,2)
   FOR j=1 TO k
      LET f12(j,1)=f0(j,1)
      LET f12(j,2)=f0(j,2)
   NEXT j
   SELECT CASE i
   CASE 1
      MAT f1=f12
   CASE 2
      MAT f2=f12
   CASE 3
      MAT f3=f12
   CASE 4
      MAT f4=f12
   CASE 5
      MAT f5=f12
   CASE 6
      MAT f6=f12
   CASE 7
      MAT f7=f12
   CASE 8
      MAT f8=f12
   CASE 9
      MAT f9=f12
   CASE 10
      MAT f10=f12
   CASE 11
      MAT f11=f12
   CASE ELSE
   END SELECT
END SUB
SUB linefont(fi,x,y)
   SELECT CASE fi
   CASE 1
      DRAW  numplot(f1) WITH SHIFT(x,y)
   CASE 2
      DRAW  numplot(f2) WITH SHIFT(x,y)
   CASE 3
      DRAW  numplot(f3) WITH SHIFT(x,y)
   CASE 4
      DRAW  numplot(f4) WITH SHIFT(x,y)
   CASE 5
      DRAW  numplot(f5) WITH SHIFT(x,y)
   CASE 6
      DRAW  numplot(f6) WITH SHIFT(x,y)
   CASE 7
      DRAW  numplot(f7) WITH SHIFT(x,y)
   CASE 8
      DRAW  numplot(f8) WITH SHIFT(x,y)
   CASE 9
      DRAW  numplot(f9) WITH SHIFT(x,y)
   CASE 10
      DRAW  numplot(f10) WITH SHIFT(x,y)
   CASE 11
      DRAW  numplot(f11) WITH SHIFT(x,y)
   CASE 12
      DRAW  numplot(f12) WITH SHIFT(x,y)
   END SELECT
END SUB
PICTURE numplot(fm(,))
   MAT PLOT POINTS : fm
END PICTURE
!
 

Re: 7セグメント数字表示のデジタル時計

 投稿者:SECOND  投稿日:2009年 1月 2日(金)21時36分40秒
返信・引用  編集済
  > No.225[元記事へ]

荒田浩二さんへのお返事です。

ありがとうございます。
ただ私のパソコンは、Pentium-3, 500MHz なので、やや速度不足で、2秒飛びが増えて、
使用できませんでした。ごめんなさい。でも、MAT PLOT CELLS に比べ格段に高速です。
 

“独自の拡張”

 投稿者:SECOND  投稿日:2009年 1月 2日(金)21時47分5秒
返信・引用
 


十進BASIC の“独自の拡張”だけを、help から書き出してみた。

これをみると、DRAW GRID や、複素数など、重要な計算機能まで該当
しており、純粋な Full Basic でなくて、良かったと思います。


----------------------------------------------
OPTION ARITHMETIC DECIMAL_HIGH  10進1000桁(超越関数は17桁(末尾偶数))
OPTION ARITHMETIC COMPLEX    複素数
OPTION ARITHMETIC RATIONAL    有理数(無理関数は10進17桁(末尾偶数))
----------------------------------------------
RANDOMIZE 5489 ( 引数に0〜4294967295)
----------------------------------------------
FACT(x)   xの階乗
PERM(n,r)  順列の数
COMB(n,r)  二項係数(組合せの数)
ROUND(x)  xの小数点以下を丸めた値。
----------------------------------------------
BLEN(a$)     バイトを単位とするa$の文字列長。
SUBSTR$(a$,m,n)  a$のm文字目からn文字目までの部分文字列
MID$(a$,m,n)   a$のm文字目からのn文字
LEFT$(a$,n)    a$のはじめのn文字
RIGHT$(a$,n)   a$の末尾のn文字
----------------------------------------------
GetKeyState(n)  キーの状態を調べる
----------------------------------------------
MAT A=CROSS(B,C)  B,Cの外積(ベクトル積)
--------------------------------------------
MAT REDIM     配列の添字の上下限を再定義
----------------------------------------------
DIM A(N),B(2*N)  添字の上下限指定に変数を含む数値式
----------------------------------------------
色名 "WHITE","BLACK","BLUE","GREEN","RED","CYAN","MAGENTA","YELLOW","GRAY","SILVER",
   "白","黒","青","緑","赤","黄"
----------------------------------------------
SET LINE WIDTH 数値式              線の太さ
PLOT BEZIER: x1, y1 ; x2, y2 ; x3, y3; x4, y4  ベジェ曲線を描く。
SET BEAM MODE "IMMORTAL"  PLOT LINES以外の実行で描点の状態を変えない。
SET BEAM MODE "RIGOROUS"  描点の状態をJISの規定通りにoffにする。
----------------------------------------------
PLOT LABEL ,AT x,y : 文字列式
PLOT LABEL ,AT x,y ,USING 書式指定 : 式, 式 , …, 式
SET TEXT FONT FontName$ ,size
ASK TEXT WIDTH(文字列式) 数値変数   文字列の問題座標系における横幅
SET TEXT BACKGROUND "TRANSPARENT"
SET TEXT BACKGROUND "OPAQUE"
----------------------------------------------
DRAW GRID     x軸方向 間隔1,y軸方向 間隔1の格子を描く。
DRAW GRID(p,q)  x軸方向 間隔p,y軸方向 間隔qの格子を描く。
DRAW AXES     目盛り間隔がx軸方向1,y軸方向1のx軸とy軸を描く。
DRAW AXES(p,q)  目盛り間隔がx軸方向p,y軸方向qのx軸とy軸を描く。
DRAW GRID0
DRAW AXES0
SET AXIS COLOR  軸の色  廃止予定
----------------------------------------------
DRAW circle   原点を中心とする半径1の円を描く。
DRAW disk    原点を中心とする半径1の円とその内部を現在のarea colorで塗りつぶす。
----------------------------------------------
MOUSE POLL x,y,left,right マウスの位置をx,y left,rightにマウスボタンの状態
----------------------------------------------
PIXELX(x)  問題座標xに対応するピクセルx座標
PIXELY(y)  問題座標yに対応するピクセルy座標
WORLDX(x)  ピクセルx座標を問題座標に変換
WORLDY(y)  ピクセルy座標を問題座標に変換
PROBLEMX(x) WORLDX(x)と同義
PROBLEMY(y) WORLDY(y)と同義
----------------------------------------------
SET BITMAP SIZE width, height 描画領域の画素数
----------------------------------------------
FLOOD x,y 点(x,y)を始点として点(x,y)と同色でつながる領域を現在のarea colorで塗りつぶす。
PAINT x,y 点(x,y)を始点としてline colorの点を境界とする領域を現在のarea colorで塗りつぶす。
----------------------------------------------
GLOAD ファイル名  指定された名前の画像ファイルを読み込む。
GSAVE ファイル名  指定された名前で画像を保存する。
----------------------------------------------
SET COLOR MODE "NATIVE"  色指定:下位8ビットが赤,中位8ビットが緑,上位8ビットが青
SET COLOR MODE "REGULAR" パレットを用いる通常モード
COLORINDEX(r,g,b)     色指標を得る関数
----------------------------------------------
SET DRAW MODE HIDDEN   内部にあるビットマップメモリにのみ描画するモード
SET DRAW MODE EXPLICIT  画面とビットマップメモリの双方に描画するモード(標準の状態)
SET DRAW MODE NOTXOR   画面の色と指定された色のNOTXORの色で描く
SET DRAW MODE OVERWRITE 指定された色で描く(標準の状態)
----------------------------------------------
WAIT DELAY 数値式  指定された秒数だけ休止
PAUSE        Enterキーを待つ。
PAUSE 文字列式    文字列式の値を表示してEnterキーを待つ。
----------------------------------------------
EXECUTE ファイル名
EXECUTE ファイル名 WITH (式,式,・・・,式)
EXECUTE NOWAIT ファイル名
EXECUTE NOWAIT ファイル名 WITH (式,式,・・・,式)
PLAY 文字列式     関連付けを利用して文字列式が表すファイルをplayする。
PLAY NOWAIT 文字列式  指定されたプログラムの実行が終わるのを待たずに次の行に進む。
ASSOC PRINT 文字列式  関連付けを利用して文字列式が表すファイルをprintする。
----------------------------------------------
SWAP x,y       変数x,yの値を交換する。
BEEP          警告音を発する。
BEEP 数値式1, 数値式2  (NT/2000/XP) 数値式1は振動数(Hz),数値式2は継続時間(ms)
PLAYSOUND 文字列式     サウンドファイルを再生する。
PLAYSOUND 文字列式 ,ASYNC  再生が終わるのを待たずに次の行に進む。
----------------------------------------------
SET #経路番号 : ENDOFLINE CHR$(13)&CHR$(10)
SET #経路番号 : ENDOFLINE CHR$(10)&CHR$(13)
SET #経路番号 : ENDOFLINE CHR$(13)
SET #経路番号 : ENDOFLINE CHR$(10)
ASK #経路番号 : FILESIZE 数値変数  バイト単位のファイル長
SET DIRECTORY a$     カレントディレクトリを、a$が指定するディレクトリに変更
ASK DIRECTORY s$     カレントディレクトリを表す文字列を、文字列変数s$に代入
FILE GETNAME s$      ファイルを開くダイアログを表示し,指定するファイル名をs$に代入
FILE GETNAME s$, 文字列式  文字列式を既定の拡張子としてファイルダイアログを開く
FILE SPLITNAME (a$) path$, name$, ext$  ファイル名を表す文字列式a$を,3つに分割
FILE RENAME a$,b$            a$が示すファイルの名前をb$に変える
FILE DELETE a$             a$が示すファイルを削除する。
FILE LIST 文字列式,s$         s$には1次元文字列配列を書く。
FILES(文字列式)           文字列式に合致するファイルの数。
----------------------------------------------
OPEN # 数値式 : PRINTER  経路にプリンタを割り当てる
----------------------------------------------
OPEN # 数値式 : TextWindow1
OPEN # 数値式 : TextWindow1 ,ACCESS INPUT
OPEN # 数値式 : TextWindow1 ,ACCESS OUTPUT
OPEN # 数値式 : TextWindow1 ,ACCESS OUTIN
----------------------------------------------
COMPLEX(x , y) 複素数 x+ y i    //複素数モード
RE(z)     zの実部
IM(z)      zの虚部
CONJ(z)     zの共役複素数 CONJ(x + y i)= x - y i
ARG(z)     zの偏角、angle radians(-π< ~<=π) angle degrees(-180°< ~<=180°)
ABS(z)     zの絶対値
SQR(z)     zの平方根(偏角:-90°< ~<=90°)
SQR(-1)= i
EXP(z)     指数関数(角度単位は常にラジアン)
LOG(z)     zの自然対数。実部はlog|z|,虚部はarg z(単位は常にラジアンで -π〜π)。
図形変形関数の複素数への拡張( shift(z), scale(z),,, )
----------------------------------------------
NUMER(x)   xの分子(numerator)      //有理数モード
DENOM(x)   xの分母(denominator)
GCD(x,y)   xとyの最大公約数(Greatest Common Divisor)。結果は正符号をもつ。
INTSQR(x)   xの正の平方根の小数点以下を切り捨てた数値。INT(SQR(x))
INTLOG2(x)  xの整数部分の2を底とする対数の整数部分。INT(LOG2(INT(x)))

 

2009年占い

 投稿者:GAI  投稿日:2009年 1月 4日(日)18時27分13秒
返信・引用
  2009年作品を挑戦
� 複坑娃娃押檻横娃娃后法爍后瓧沓沓掘 淵薀奪�ーセブン!!!大当たり)

�∪称顳横娃娃糠�=平成21年=3×7年
より3,7で 3×7×37=777

��2009=7×7×7×7−7×7×7−7×7

�ぃ沓沓沓沓掘娃�
≡77777^77
≡77777^777
≡77777^7777
≡77777^77777
・・・・・・・・・・・・
≡77777^777・・・・・・・・・・・7
≡0(MOD2009)
 

Re: “独自の拡張”

 投稿者:荒田浩二  投稿日:2009年 1月 4日(日)21時51分27秒
返信・引用  編集済
  > No.227[元記事へ]

SECONDさんへのお返事です。

これもありますよ。

----------------------------------------------
識別名に漢字が使えるように文法を拡張している。
識別名に使えるのは,JIS文字コード表で"0"(数字のゼロ)以降の文字。
ただし,全角英数字で始まる名前は不可。
----------------------------------------------

全角文字22文字からなる変数名です。(注意;環境依存文字もあります)
10 LET かぃ1BdサΣβДя┴�鵜鍬吻岫爿澂筬絖雖鶲�=3
20 PRINT かぃ1BdサΣβДя┴�鵜鍬吻岫爿澂筬絖雖鶲�+5
30 END
 

Re: “独自の拡張”

 投稿者:SECOND  投稿日:2009年 1月 4日(日)22時42分47秒
返信・引用
  > No.229[元記事へ]

漢字 については、次の様に書かれていました。

「Full BASICはコード番号が0から127までの文字を使用することを前提に
 規格化されている。そのため,JISには128番以降の文字を扱うことにしても
 よいという程度のことしか書かれていない。」

これを見ると、むずかしい判断ですね。
仕方が無いので、とりあえず、白石先生が、"独自の拡張"とマークされた個所
だけに、しています。
 

Re: “独自の拡張”

 投稿者:荒田浩二  投稿日:2009年 1月 5日(月)00時08分3秒
返信・引用
  > No.230[元記事へ]

SECONDさんへのお返事です。

なるほど。JISにもあいまいな規定があるのですね。

ところで、あのおかしな変数名を作っていて思ったのですが、白石先生に提案があります。
JISコードでギリシャ文字より後ろから漢字の前までを、識別名から除外してはいかがでしょうか。
ロシア文字を読める人は少ないでしょうし、罫線素片が識別名にふさわしいとも思えません。環境依存文字の使用回避にもなります。
JIS規格とのかねあいもあるでしょうが、ご検討をお願いします。(差し出がましく申し訳ありません)
 

Re: “独自の拡張”

 投稿者:白石 和夫  投稿日:2009年 1月 6日(火)10時04分15秒
返信・引用  編集済
  > No.231[元記事へ]

公開するプログラムは,可能な限り,
http://hp.vector.co.jp/authors/VA008683/QA1.htm
に示すガイドラインにしたがってください。
独自拡張機能は,他に代替手段が存在しない場合にかぎり用いるのが大原則です。
たとえば,漢字などのマルチバイト文字を識別名に用いることは,代替手段が存在するので,推奨しません。
(外国人が見たら普通の漢字でも変てこな文字です)
 

Re: “独自の拡張”

 投稿者:荒田浩二  投稿日:2009年 1月 6日(火)18時57分16秒
返信・引用
  > No.232[元記事へ]

白石 和夫さんへのお返事です。

早速のご回答ありがとうございます。
個人で利用する以外では、拡張機能は使用してはいけないということですね。
漢字使用はともかく、拡張機能は便利なだけに原則を守るのはなかなか厳しいですが…。
 

Knight's Tour(ナイト・ツアー)

 投稿者:SECOND  投稿日:2009年 1月 7日(水)16時10分5秒
返信・引用  編集済
  !
! Knight's Tour(ナイト・ツアー)
!
! 注意!出発点に戻る経路 Closed Tour のみに、限定して計算。⇔Open Tour
!
! KNIGHTGR.UB
! Original Version  1990/10/01 by unknown
! Modified Version  1997/04/10 by Aiichi Yamasaki
! Modified Version  2009/01/06 uBASIC から、十進Basic へ移植。
!--------------------
OPTION BASE 0
SET TEXT background "OPAQUE"
SET POINT STYLE 4
!
LET DF=0 ! 0:通常 1:探索過程のstep 2:探索完了毎のstep //debug
LET Xw=6 !8 ! 盤の横巾
LET Yw=6 !8 ! 盤の縦巾
!-----
! Schwenk's Theorem
! For any m × n board with m less than or equal to n,
! a closed knight's tour is always possible
! unless one or more of these three conditions are true:
!1)m and n are both odd
!2)m = 1, 2, or 4; m and n are not both 1
!3)m = 3 and n = 4, 6, or 8
!
LET m= MIN(Xw,Yw)
LET n= MAX(Xw,Yw)
!
IF MOD(m,2)=1 AND MOD(n,2)=1 THEN CALL outer
IF (m=1 OR m=2 OR m=4) AND (m<>1 OR n<>1) THEN CALL outer
IF m=3 AND (n=4 OR n=6 OR n=8) THEN CALL outer

SUB outer
   beep
   PRINT "Xw=";Xw;"Yw=";Yw;" … No Closed Tour."
   STOP
END SUB

!-----
LET D0=INT(192/MAX(MAX(Xw,Yw),8)) ! 盤の1目幅
SET WINDOW -55/D0, 445/D0, 370/D0,-130/D0
PLOT TEXT,AT 0,-50/D0:"Knight's Tour"
LET Xct= 0
LET Yct= -30/D0 ! count--time の位置
CALL guide( 205/D0, 10/D0) ! x,y
!-----init
DIM P_(-2 TO Yw+1,-2 TO Xw+1), E_(-2 TO Yw+1,-2 TO Xw+1), I_(Xw*Yw), DX_(7), DY_(7)
MAT READ DX_,DY_
DATA  2, 1,-1,-2,-2,-1, 1, 2
DATA  1, 2, 2, 1,-1,-2,-2,-1
!-----
IF DF<>0 THEN MAT PRINT USING REPEAT$("## ",8): DX_ ! //debug
IF DF<>0 THEN MAT PRINT USING REPEAT$("## ",8): DY_ ! //debug
!-----init P_
MAT P_=CON
FOR y=0 TO Yw-1
   FOR x=0 TO Xw-1
      LET P_(y,x)=0
   NEXT x
NEXT y
!-----init E_
MAT E_=20*CON
FOR y=0 TO Yw-1
   FOR x=0 TO Xw-1
      LET E_(y,x)=0
   NEXT x
NEXT y
FOR y=0 TO Yw-1
   FOR x=0 TO Xw-1
      LET c=8
      FOR i=0 TO 7
         LET c=c-P_(y+DY_(i),x+DX_(i))
      NEXT i
      LET E_(y,x)=c
   NEXT x
NEXT y
!-----
IF DF<>0 THEN MAT PRINT USING REPEAT$(" ##",Xw+4) :P_ ! //debug
IF DF<>0 THEN MAT PRINT USING REPEAT$(" ##",Xw+4) :E_ ! //debug
!-----
LET sp=0 ! 0~(Xw*Yw-1) 階層位置(再帰型のStackPointerに相当)
LET xx=0 ! 開始地点
LET yy=0 ! (0,0)
LET I_(sp)=-1 ! 全階層の方向カウンター
LET Count=0
LET t0=TIME
IF DF<>0 THEN CALL PUTL(xx,yy,0,0,2) ! //debug
DO
   LET I_(sp)=I_(sp)+1
   LET ii=I_(sp)
   IF 7< ii THEN
      CALL BACK ! 1層戻す。
   ELSE
      IF P_(yy+DY_(ii),xx+DX_(ii))=0 THEN ! 重複検査。
         IF DF<>0 THEN CALL PUTL(xx,yy,DX_(ii),DY_(ii),2) ! //debug
         LET xx=xx+DX_(ii)
         LET yy=yy+DY_(ii)
         LET P_(yy,xx)=1
         !-----dec E_
         LET E_(yy,xx)= E_(yy,xx)+10
         FOR i=0 TO 7
            LET E_(yy+DY_(i),xx+DX_(i))= E_(yy+DY_(i),xx+DX_(i))-1
         NEXT i
         IF DF<>0 THEN CALL DISP_E ! 探索過程の配列 E_ モニター //debug
         !----- 1層進める。
         LET sp=sp+1
         LET I_(sp)=-1
         IF sp=Xw*Yw THEN
            CALL FIN ! 1経路の完成。
            CALL BACK ! 1層戻す。
         ELSEIF fnCHECK(xx,yy)<>0 THEN ! 次の重複検査前の、予見検査。
            CALL BACK ! 1層戻す。
         END IF
      END IF
   END IF
LOOP

SUB BACK
   LET P_(yy,xx)=0
   !-----inc E_
   LET E_(yy,xx)= E_(yy,xx)-10
   FOR i=0 TO 7
      LET E_(yy+DY_(i),xx+DX_(i))= E_(yy+DY_(i),xx+DX_(i))+1
   NEXT i
   !-----
   LET sp=sp-1
   IF sp=0 THEN STOP ! 終了、Count:1倍
   !IF sp< 0 THEN STOP ! 終了、Count:2倍(開始点も回転、帰路まで別経路になる)
   LET ii=I_(sp)
   LET xx=xx-DX_(ii)
   LET yy=yy-DY_(ii)
   IF DF<>0 THEN CALL PUTL(xx,yy,DX_(ii),DY_(ii),0) ! //debug
END SUB

FUNCTION fnCHECK(x,y) ! 予見検査。
   LET c=0
   IF sp< Xw*Yw-1 THEN
      LET fnCHECK=1 ! 帰りの引数=1
      IF ABS(I_(1)-I_(0))=4 THEN EXIT FUNCTION !return(1)
      FOR i=0 TO 7
         IF E_(y+DY_(i),x+DX_(i))< 2 THEN
            IF E_(y+DY_(i),x+DX_(i))=0 THEN EXIT FUNCTION !return(1)
            LET c=c-1
         END IF
      NEXT i
      IF c< -1 THEN
         IF sp<>1 THEN EXIT FUNCTION !return(1)
      END IF
      FOR y=0 TO Yw-1
         FOR x=0 TO Xw-1
            IF E_(y,x)< 2 THEN
               IF E_(y,x)=0 THEN  EXIT FUNCTION !return(1)
               LET c=c+1
               IF c>1 THEN  EXIT FUNCTION !return(1)
            END IF
         NEXT x
      NEXT y
   END IF
   LET fnCHECK=0 ! 帰りの引数=0
END FUNCTION !return(0)

SUB PUTL(x,y,dx,dy,c)
   SET LINE COLOR c
   PLOT LINES: x,y; x+dx,y+dy
   PLOT POINTS: x+dx,y+dy
END SUB

SUB DISP_E
   PRINT
   MAT PRINT USING REPEAT$(" ##",Xw+4) :E_
   IF DF=1 THEN pause ! //debug
END SUB

SUB FIN
!-----disp_A
   SET AREA COLOR 0
   PLOT AREA :0,0; Xw-1,0; Xw-1,Yw-1; 0,Yw-1
   LET x=0
   LET y=0
   CALL PUTL(x,y,0,0,2)
   FOR s=0 TO Xw*Yw-1
      CALL PUTL(x,y,DX_(I_(s)),DY_(I_(s)),2)
      LET x=x+DX_(I_(s))
      LET y=y+DY_(I_(s))
   NEXT s
   !-----disp cout--time
   LET Count=Count+1
   LET t1=INT(TIME-t0)
   IF t1< 0 THEN LET t1=t1+86400
   PLOT TEXT,AT Xct,Yct :"count= "& STR$(Count)& " ----- "&
&& USING$("%%",MOD(INT(t1/3600),24))& ":"&
&& USING$("%%",MOD(INT(t1/60),60))& ":"& USING$("%%",MOD(t1,60))
   IF DF=2 THEN pause ! //debug
END SUB

!----------ガイド表示-----
SUB guide(x,y)
   PLOT TEXT,AT x,y: "H V  一巡する経路の数"
   PLOT TEXT,AT x,y +20/D0,USING "3x4: can't close  ### open 参考": 2
   PLOT TEXT,AT x,y +40/D0,USING "5x5: can't close  ### open 参考": 304
   PLOT TEXT,AT x,y +60/D0,USING "5x6: ##,###,###,###,### closed": 8
   PLOT TEXT,AT x,y +80/D0,USING "6x6: ##,###,###,###,### closed": 9862
   PLOT TEXT,AT x,y+100/D0,USING "8x8: ##,###,###,###,### closed": 26534728821064
   !
   PLOT TEXT,AT x,y+140/D0:"Knight の移動規則"
   LET x=x+2
   LET y=y+160/D0+2
   SET LINE COLOR 2
   SET AREA COLOR 2
   LET j=SQR(5)
   FOR i=ATN(0.5) TO 2*PI STEP PI/2
      DRAW knight WITH ROTATE(i)*SHIFT(x,y)
      DRAW knight WITH ROTATE(-i)*SHIFT(x,y)
   NEXT i
   FOR j=-2 TO 2
      FOR i=-2 TO 2
         PLOT POINTS: x+i, y+j
      NEXT i
   NEXT j
END SUB

PICTURE knight
   PLOT LINES: 0,0; j,0
   PLOT AREA: j-0.4,-0.16; j,0; j-0.4,0.16; j-0.24,0
   PLOT POINTS: j,0
END PICTURE

END
 

Re: “独自の拡張”

 投稿者:白石 和夫  投稿日:2009年 1月 7日(水)16時59分52秒
返信・引用
  > No.233[元記事へ]

JISの範囲外の機能については,将来,変更もありえます。
たとえば,マルチバイト文字の識別名を使えなくする変更の可能性もあります。
(国際化の観点を重視すればその方向に進むことになります。)
なので,規格外の機能の使用は可能なかぎり避けてください。
 

PAUSE ボタン

 投稿者:SECOND  投稿日:2009年 1月 7日(水)17時15分48秒
返信・引用
  PAUSE の WINHANDLE(文字列式) が、解りません。
Box 位置の移動は、どうすればよいでしょうか。
 

Re: PAUSE ボタン

 投稿者:白石 和夫  投稿日:2009年 1月 7日(水)20時35分51秒
返信・引用  編集済
  > No.236[元記事へ]

PAUSEのフォームは常駐しないので,ハンドルの取得は難しいかと思います。
(PAUSE文のなかでウィンドウの作成から消去までの動作が完結してしまっている)
BASICの複数起動を行うようなことをすればできるかもしれませんが,一般には,
Win32APIを使って独自のウィンドウを作るのが順当な解決策のように思います。
 

Re: PAUSE ボタン

 投稿者:SECOND  投稿日:2009年 1月 7日(水)21時03分44秒
返信・引用
  > No.237[元記事へ]

白石 先生へ

 ありがとうございました。
 

Re: “独自の拡張”

 投稿者:荒田浩二  投稿日:2009年 1月 8日(木)12時57分40秒
返信・引用
  > No.233[元記事へ]

配列の添字の再定義をJISの規格内でできるようにしました。

JISに従うと、配列の宣言で添字には数値定数しか使えなくなります。
あらかじめある程度大きく配列を宣言しておき、MAT文で配列の大きさを変更できます。

DIM A(100),B(100),C(100)
LET m=3
LET n=8
MAT A=ZER(m)
MAT B=ZER(m*n)
MAT C=ZER(m TO n)

ところがMAT文では添字の下限を変更することはできないため、Cの下限は1,上限は6(=n-m+1)になります。
ヘルプでは『添字の下限を変えたいときは,MAT READ文か,拡張機能のMAT REDIM文を用いる。』とあります。
MAT READ C(m TO n) とすればよいわけですが、DATA文を読ませる必要があります。
MAT REDIM C(m TO n) ならば配列要素はそのままで添字の下限を変更できますがJIS規格外です。

次の外部副プログラム redim は、MAT REDIM文と同様の機能を持ちます。

DECLARE EXTERNAL SUB redim
DIM A(100)
LET m=3
LET n=8
CALL redim(A,m,n)  ! MAT REDIM A(m TO n)と同義
PRINT LBOUND(A),UBOUND(A)
END
!
EXTERNAL SUB redim(p(),m,n) !配列の添字の上下限を再定義
WHEN EXCEPTION IN
   DIM q(10000)
   MAT q=p
   MAT READ p(m TO n)
   DATA 0
USE
END WHEN
FOR i=m TO n
   LET p(i)=q(LBOUND(q)+i-m)
NEXT i
END SUB
 

MAT REDIMの代替

 投稿者:白石 和夫  投稿日:2009年 1月 8日(木)18時35分32秒
返信・引用
  > No.239[元記事へ]

EXTERNAL SUB redim(p(),m,n) !配列の添字の上下限を再定義
DATA 0
MAT READ p(m TO m)
MAT p=ZER(m TO n)
END SUB
でいけます。
 

2重振子メーター付(解析したい方へ)再投稿

 投稿者:SECOND  投稿日:2009年 1月10日(土)02時54分20秒
返信・引用  編集済
  !2重振子メーター付(解析したい方へ)再投稿

!2重振り子特有の下降衝撃時に、その急変する過程が、
!演算ピッチの間に入って脱落し、全エネルギーが変動する計算エラーが見られる。
!演算ピッチが小さいと、緩和するが、低速パソコンでは、描画ピッチが伴わない。

!-----
LET g= 9.8 ! m/s^2 重力加速度
LET m1=.188 ! kg おもり
LET m2=.188 ! kg
LET L1= 5 ! m 吊り棒
LET L2= 5 ! m
LET r1=.75*SQR(m1) ! おもりの描画径
LET r2=.75*SQR(m2)
!
LET dt=0.05 !sec. 演算ピッチ。高速機 ほど、小さく。(0.05は、Pentium3 500MHz)
!
!※0.01くらいが望ましいが、描画ピッチ(画面に表示)が、ついて来れなくなったら戻す。
! 2つのピッチが、ズレていると物理的な速度ではなくなる。
!
!------------ 2重振り子の方程式
! d(dθ1)/dt^2=
! [ g*{sinθ2*cosΔ-μ*sinθ1}-{L2*(θ2/dt)^2+L1*(θ1/dt)^2*cosΔ}*sinΔ]
!          /[ L1*{μ-cosΔ^2}]
! d(dθ2)/dt^2=
! [ g*μ*{sinθ1*cosΔ-sinθ2}+{μ*L1*(θ1/dt)^2+L2*(θ2/dt)^2*cosΔ}*sinΔ]
!          /[ L2*{μ-cosΔ^2}]
!
! g= 重力加速度 μ=(m1+m2)/m2 Δ=θ1-θ2
!
!---------- 式の整理(θ1θ2 共に、重力方向0からの左回り角)
LET μ2=m2/(m1+m2)
LET L21=L2/L1
!
!ss1=-g/L1*sinθ1 -μ2*L21*ω2^2*sinΔ
!ss2=-g/L2*sinθ2 +    ω1^2*sinΔ/L21
!D=1-μ2*COSΔ^2
!d(θ1)/dt=ω1
!d(θ2)/dt=ω2
!d(ω1)/dt=[      ss1 - L21*μ2*cosΔ*ss2 ] /D
!d(ω2)/dt=[ -cosΔ/L21*ss1 +        ss2 ] /D
!
!---------- 微分方程式のまま、ルンゲ・クッタ法で描画。
LET θ1=PI*0.8 ! 初期角度
LET θ2=PI*0.8
LET w1=0 ! 初期角速度
LET w2=0
!
DEF ss1(w2,θ1,θ2)=-g/L1*SIN(θ1) -μ2*L21*w2^2*SIN(θ1-θ2)
DEF ss2(w1,θ1,θ2)=-g/L2*SIN(θ2) +        w1^2*SIN(θ1-θ2)/L21
DEF D(θ1,θ2)=1-μ2*COS(θ1-θ2)^2
!
DEF α1(w1,w2,θ1,θ2)=( ss1(w2,θ1,θ2) -L21*μ2*COS(θ1-θ2)*ss2(w1,θ1,θ2) )/D(θ1,θ2)
DEF α2(w1,w2,θ1,θ2)=(-ss1(w2,θ1,θ2)*COS(θ1-θ2)/L21     +ss2(w1,θ1,θ2) )/D(θ1,θ2)

SUB RungeKutta
   LET w11=w1
   LET w12=w2
   LET α11=α1(w1,w2,θ1,θ2)
   LET α12=α2(w1,w2,θ1,θ2)
   !
   LET w21=w1+α11*dt/2
   LET w22=w2+α12*dt/2
   LET α21=α1(w21,w22,θ1+w11*dt/2,θ2+w12*dt/2)
   LET α22=α2(w21,w22,θ1+w11*dt/2,θ2+w12*dt/2)
   !
   LET w31=w1+α21*dt/2
   LET w32=w2+α22*dt/2
   LET α31=α1(w31,w32,θ1+w21*dt/2,θ2+w22*dt/2)
   LET α32=α2(w31,w32,θ1+w21*dt/2,θ2+w22*dt/2)
   !
   LET w41=w1+α31*dt
   LET w42=w2+α32*dt
   LET α41=α1(w41,w42,θ1+w31*dt,θ2+w32*dt)
   LET α42=α2(w41,w42,θ1+w31*dt,θ2+w32*dt)
   !
   LET θ1=θ1+(w11+2*w21+2*w31+w41)*dt/6
   LET θ2=θ2+(w12+2*w22+2*w32+w42)*dt/6
   LET w1=w1+(α11+2*α21+2*α31+α41)*dt/6
   LET w2=w2+(α12+2*α22+2*α32+α42)*dt/6
END SUB

!----エネルギー・メーター
DEF ep1=m1*g*(L1-L1*COS(θ1)) !位置1
DEF em1=(L1*w1)^2*m1/2 !運動1
DEF ep2=m2*g*( (L1-L1*COS(θ1)+L2)-L2*COS(θ2) ) !位置2
DEF em2=( (L1*w1)^2+(L2*w2)^2-2*L1*w1*L2*w2*COS(PI+θ1-θ2) )*m2/2 !運動2
!
!----run
LET w=13
SET WINDOW -w,w,-w,w
SET COLOR MIX(15) .5,.5,.5
SET TEXT background "OPAQUE"
LET t0=TIME
DO
   LET t=TIME
   IF dt=<ABS(t-t0) THEN
      SET DRAW mode hidden
      CLEAR
      DRAW grid(5,5)
      PLOT TEXT,AT -w*0.92,w*0.9:"おもりのエネルギー[J]"
      PLOT TEXT,AT -w*0.92,w*0.83:"位置1 運動1  位置2 運動2"
      PLOT TEXT,AT -w*0.96,w*0.76,USING"##.#### ##.#### ##.#### ##.####":ep1,em1,ep2,em2
      PLOT TEXT,AT -w*0.86,w*0.69,USING"##.####     ##.####":ep1+em1,ep2+em2
      PLOT TEXT,AT -w*0.62,w*0.62,USING"##.####":ep1+em1+ep2+em2
      PLOT TEXT,AT w*0.25,w*0.9:"マウス 右ボタンで、終了。"
      PLOT TEXT,AT w*0.4,w*0.76,USING"演算ピッチ=#.### 秒":dt
      PLOT TEXT,AT w*0.4,w*0.69,USING"描画ピッチ=#.### 秒":t-t0
      LET t0=t
      DRAW Pendulum0 WITH ROTATE(θ1)
      CALL RungeKutta ! 次のθ1,θ2 へ更新
      SET DRAW mode explicit
      !stop
   END IF
   WAIT DELAY 0 ! 省電力効果
   MOUSE POLL mx,my,mlb,mrb
LOOP UNTIL mrb=1

PICTURE Pendulum0
   DRAW circle WITH SCALE(0.2)
   DRAW Pendulum1(L1,r1,"1")
   DRAW Pendulum1(L2,r2,"2") WITH ROTATE(θ2-θ1)*SHIFT(0,-L1)
END PICTURE

PICTURE Pendulum1(L,r,w$)
   PLOT LINES: 0,0;0,-L
   DRAW disk WITH SCALE(r)*SHIFT(0,-L)
   PLOT TEXT,AT r, r-L:w$
END PICTURE

END
 

センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 1月15日(木)10時44分57秒
返信・引用
  直線上の酔歩問題
 コインを投げて、表が出たら+1、裏なら−1と数直線上を動く。

●シミュレーションによる解法(モンテカルロ法)
RANDOMIZE

LET N=6 !コインを投げる回数

DIM s(-N TO N) !点xに戻る回数
MAT s=ZER

LET iter=50000 !試行回数
FOR i=1 TO iter

   LET x=0 !原点
   FOR k=1 TO N !コインを投げる
      IF RND<0.5 THEN LET x=x+1 ELSE LET x=x-1 !表なら+1、裏なら−1
   NEXT k
   LET s(x)=s(x)+1 !結果

NEXT i

FOR i=-N TO N !点xに戻る確率
   PRINT i;s(i)/iter
NEXT i
PRINT

FOR i=-N TO N !場合の数
   PRINT USING "###: ###.##": i,s(i)/s(N) !x=Nを1とする
NEXT i

END


●理論値の算出

コインをn回投げて、k回表が出たする。
位置x=1*k+(-1)*(n-k)=2*k-nとなる。確率は、nCk(1/2)^k*(1-1/2)^(n-k)。

たとえば、n=6で原点の場合、0=2*k-nより、k=3。
LET x=0 !原点

LET k=(x+N)/2 !整数解があれば
IF k=INT(k) THEN
   PRINT k; comb(N,k)*(1/2)^k*(1-1/2)^(N-k)
ELSE
   PRINT "到達しません。"
END IF

END


投げる回数ごとの「場合の数」の一覧表は、パスカルの三角形をつくればよい。
!パスカルの三角形

LET N=10 !コインを投げる回数

LET a=1 !パスカルの三角形
LET b=0
LET c=1

DIM P(-N TO N) !数直線上の各点
MAT P=ZER
LET P(0)=1 !原点に位置付ける

FOR i=-N TO N !目盛り
   PRINT USING " ####": i;
NEXT i
PRINT
FOR i=-N TO N !数直線
   PRINT "----+";
NEXT i
PRINT

FOR i=0 TO N !指定回数

   MAT PRINT USING(REPEAT$(" ####",2*N+1)): P; !現状
   PRINT USING " ### 回の場合": i

   LET T1=0 !左 ※左端
   LET T2=P(-N) !中央
   FOR x=-N TO N !左から右へ走査する
      IF x+1>N THEN LET T3=0 ELSE LET T3=P(x+1) !右

      LET P(x)=a*T1+b*T2+c*T3

      LET T1=T2 !次へ
      LET T2=T3
   NEXT x

NEXT i

END
 

comb関数の不具合

 投稿者:山中和義  投稿日:2009年 1月16日(金)10時42分29秒
返信・引用
  有理数モードで1となる。

PRINT comb(3,6) !3C6
PRINT comb(3,-4)
END
 

Re: comb関数の不具合

 投稿者:白石 和夫  投稿日:2009年 1月16日(金)18時12分34秒
返信・引用
  > No.244[元記事へ]

ご報告ありがとうございます。
修正します。

> 有理数モードで1となる。
>
> PRINT comb(3,6) !3C6
> PRINT comb(3,-4)
> END
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 1月17日(土)13時27分49秒
返信・引用  編集済
  > No.243[元記事へ]

作表と表の計算、数列の生成
・2次元配列を使わず、順次求める

!九九表(乗算表)と〜数

!1の段 − 自然数
!2の段 − 偶数
!各段 − 倍数


LET N=9 !※書式(PRINT USING)の桁を調整すれば変更可能

DIM A(0 TO 2*N) !数列 An
DIM S(0 TO 2*N) !数列 Sn


!●平方数(四角数) n^2
MAT A=ZER
PRINT

FOR i=1 TO N
   FOR j=1 TO N
      LET t=i*j !乗算

      IF i=j THEN !対角線上なら
         PRINT USING "(####)": t;
         LET A(i)=t
      ELSE
         PRINT USING " #### ": t;
      END IF

   NEXT j
   PRINT
NEXT i
PRINT


!四角錐数(平方数の和)Square Pyramid Numbers
! Σ[k=1,n]k^2
! =1^2 + 2^2 + 3^2 + … + (n-1)^2 + n^2
! =n*(n+1)*(2*n+1)/6
MAT S=ZER

FOR i=1 TO N
   LET S(i)=S(i-1)+A(i) !和 ※A()は上記の平方数
NEXT i
FOR i=1 TO N !〜数を表示する
   PRINT S(i);
NEXT i
PRINT
PRINT


!奇数の和 1 + 3 + 5 + … + (2*n-3) + (2*n-1)
! Σ[k=1,n](2*k-1)
! =n^2
MAT S=ZER

FOR i=1 TO N
   LET S(i)=A(i)-A(i-1) !階差 ※A()は上記の平方数
NEXT i
FOR i=1 TO N !〜数を表示する
   PRINT S(i);
NEXT i
PRINT
PRINT



!●四面体数(三角数の和、三角錐数 tetrahedral number)
! Σ[k=1,n]k*(n-k+1)
! =1*n+2*(n-1)+3*(n-2)+ … +(n-1)*2+n*1
! =n*(n+1)*(n+2)/6
MAT A=ZER
PRINT

FOR i=1 TO N
   FOR j=1 TO N
      LET t=i*j !乗算

      LET A(i+j-1)=A(i+j-1)+t !右斜め(/)に加算する
      PRINT USING "####": t;

   NEXT j
   PRINT
   IF i<N THEN PRINT " ";REPEAT$(" /",N-1) !行間
NEXT i
PRINT

FOR i=1 TO N !〜数を表示する
   PRINT A(i);
NEXT i
PRINT
PRINT



!●立方数 n^3
MAT A=ZER
PRINT

FOR i=1 TO N
   FOR j=1 TO N
      LET t=i*j !乗算

      IF i<j THEN !L字に加算する
         LET A(j)=A(j)+t
         PRINT USING "│####": t;
      ELSE
         LET A(i)=A(i)+t
         PRINT USING " ####": t;
      END IF

   NEXT j
   PRINT "│" !行末
   PRINT REPEAT$("───",i);"┘";REPEAT$("  │",N-i) !行間
NEXT i
PRINT

FOR i=1 TO N !〜数を表示する
   PRINT A(i);
NEXT i
PRINT
PRINT



!立方数の和
! Σ[k=1,n]k^3=(n*(n+1)/2)^2の導出
! 1*Σ[k=1,n]k + 2*Σ[k=1,n]k + 3*Σ[k=1,n]k + … + (n-1)*Σ[k=1,n]k + n*Σ[k=1,n]k
! =(1+2+ … +(n-1)+n)*Σ[k=1,n]k
! =(Σ[k=1,n]k)^2
PRINT

FOR i=1 TO N
   FOR j=1 TO N
      LET t=i*j !乗算
      PRINT USING " ####": t;
   NEXT j
   PRINT " ←1段目の";i;"倍"
NEXT i
PRINT

MAT S=ZER
FOR i=1 TO N
   LET S(i)=S(i-1)+A(i) !※A()は上記の立方数
NEXT i
FOR i=1 TO N !〜数を表示する
   PRINT S(i);
NEXT i
PRINT
PRINT


END
 

一個の神経細胞(neuro)

 投稿者:SECOND  投稿日:2009年 1月18日(日)10時37分30秒
返信・引用  編集済
  !
! 一個の神経細胞(neuro)
! その カオス(chaos)を、探し、見る、ツール
!
!----------------------------
! "Neuro12"
!
! 2009.1.18
!----------------------------
OPTION ARITHMETIC NATIVE
OPTION BASE 0
SET TEXT background "OPAQUE"
SET POINT STYLE 1
SET AREA COLOR 0
LET DLY=50
DIM St(1,DLY) ,Sy(2000), B4(0,500)
!
LET Kr=0.5
LET Af=1
LET Ei=-70
LET Ss=0.31 ! Ss=(Kr-1)(theta-s(t)) …s(t)=0
LET theta=Ss/(Kr-1)

DEF Ri(Yi,Ss)=Kr*Yi-Af/(1+EXP(Ei*Yi))+Ss

PLOT TEXT,AT .04,.96:"*** Neuro Cell"
PLOT TEXT,AT .04,.92:"Right Click to Stop"
PLOT TEXT,AT .04,.89:"Left  Click & Drag '|' Line"
!
!-----
LET Y0=Af/100
LET Af2=Af
DO
   LET Af=Af2
   CALL ma200_
   ! ma100_
   !----- clear
   SET WINDOW -Af*2.07-Af*1.06,Af*2.07-Af*1.06,-Af*2.07-Af*1.05,Af*2.07-Af*1.05
   PLOT AREA: -Af,-Af;Af,-Af;Af,Af;-Af,Af
   !----- box outline
   SET LINE COLOR "blue"
   PLOT LINES: -Af,-Af; Af,-Af; Af,Af; -Af,Af; -Af,-Af
   !-----
   PLOT TEXT,AT Af*.03,Af*.85: "+Af Y(t+1)"
   PLOT TEXT,AT -Af*.97,Af*0.13: "Y(t)"
   PLOT TEXT,AT -Af*.97, 0: "-Af"
   PLOT TEXT,AT Af*.8, 0: "+Af"
   PLOT TEXT,AT Af*.03,-Af*.98: "-Af"
   !----- Sy(w)=Y(t)
   LET imax=pixelx(Af)-pixelx(-Af)
   LET dA1=(Af+Af)/imax
   FOR i=0 TO imax
      LET Sy(i)=Ri(-Af+i*dA1, Ss)
   NEXT i
   !-----
   DO
      LET Y1=Ri(Y0,Ss)
      !----- erase old signal
      LET W0=St(0,t)
      LET W1=St(1,t)
      FOR i=0 TO DLY-1
         IF W0=St(0,i) AND W1=St(1,i) AND t<>i THEN EXIT FOR
      NEXT i
      IF DLY=i THEN
         SET LINE COLOR 0
         PLOT LINES: W0,W0; W0,W1;
         PLOT LINES: W1,W1
      END IF
      !----- axis
      SET LINE COLOR "cyan" ! axis_Y(t)… ―
      PLOT LINES: -Af,0; Af,0
      SET LINE COLOR "magenta" ! axis_Y(t+1)…|
      PLOT LINES: 0,-Af; 0,Af
      !----- draw curve Y(t)
      SET LINE COLOR 1
      FOR i=0 TO imax
         PLOT LINES: -Af+i*dA1, Sy(i);
      NEXT i
      PLOT LINES
      !----- signal
      SET LINE COLOR "cyan" ! input_Y(t)…|
      PLOT LINES: Y0,Y0; Y0,Y1;
      SET LINE COLOR "magenta" ! output_Y(t+1)… ―
      PLOT LINES: Y1,Y1
      !-----
      LET St(0,t)=Y0
      LET St(1,t)=Y1
      LET t=MOD(t+1,DLY)
      LET Y0=Y1
      !-----
      WAIT DELAY .02
      MOUSE POLL x,y,mlb,mrb
   LOOP UNTIL mlb=1 OR mrb=1
   !
   !----- cursor input
   IF mlb=1 THEN
      SET WINDOW -0.1*Af,Af, -Af*2.1+Af*1.08,Af*2.1+Af*1.08
      DO
         MOUSE POLL x,y,mlb,mrb
         IF 0<=x AND x<=Af THEN
            IF y< Af THEN
               IF bx4<>pixelx(x) THEN
                  LET Ss=x
                  LET theta=Ss/(Kr-1)
                  CALL cursor4( bx4,B4)
               END IF
            ELSEIF x< Af*.43 THEN
               IF y< Af*1.4 THEN
               ELSEIF y< Af*1.7 THEN
                  IF bx3<>pixelx(x) THEN
                     LET Ei=x*120/(Af*.43)-120
                     CALL cursor13( bx3, 1.7, 1.4)
                  END IF
               ELSEIF y< Af*2.1 THEN
                  IF bx2<>pixelx(x) THEN
                     LET Kr=x*1/(Af*.43)
                     LET theta=Ss/(Kr-1)
                     CALL cursor13( bx2, 2.1, 1.8)
                  END IF
               ELSEIF y< Af*2.5 THEN
                  IF bx1<>pixelx(x) THEN
                     LET Af2=x*2/(Af*.43)+0.5
                     MAT St=ZER
                     LET Y0=Af/100
                     CALL cursor13( bx1, 2.5, 2.2)
                  END IF
               END IF
            END IF
         END IF
         WAIT DELAY .05
      LOOP UNTIL mlb=0
   END IF
LOOP UNTIL mrb=1

SUB cursor4( bx,B(,))
   MAT PLOT CELLS, IN worldx(bx),Af; worldx(bx),-Af: B
   LET bx=pixelx(x)
   ASK PIXEL ARRAY (x,Af) B
   SET LINE COLOR "red"
   PLOT LINES: x,-Af; x,Af
   PLOT TEXT,AT 0,Af,USING "Kr=#.### :Af=#.### :Ei=####.# :Ss=#.### :theta=####.###": Kr, Af, Ei, Ss, theta
END SUB

SUB cursor13( bx, uy,ly)
   SET LINE COLOR 0
   PLOT LINES: worldx(bx),Af*uy-dAy; worldx(bx),Af*ly+dAy
   LET bx=pixelx(x)
   SET LINE COLOR "red"
   PLOT LINES: x,Af*uy-dAy; x,Af*ly+dAy
   PLOT TEXT,AT 0,Af,USING "Kr=#.### :Af=#.### :Ei=####.# :Ss=#.### :theta=####.###": Kr, Af2, Ei, Ss, theta
END SUB

SUB ma200_
!----- clear
   SET WINDOW -0.1*Af,Af, -Af*2.1+Af*1.08,Af*2.1+Af*1.08
   PLOT AREA: 0,-Af;Af,-Af;Af,Af;0,Af
   !----- box outline
   SET LINE COLOR "blue"
   PLOT LINES: 0,-Af; Af,-Af; Af,Af; 0,Af; 0,-Af
   PLOT LINES: 0,0; Af,0
   !-----
   PLOT TEXT,AT -.06*Af,.9*Af : "+Af"
   PLOT TEXT,AT -.07*Af,-.05*Af : "Y(t)"
   PLOT TEXT,AT -.06*Af,-Af : "-Af"
   PLOT TEXT,AT Af*.5,-Af*.98: "0 <--- Ss ---> +Af"
   !-----
   LET dA2=Af/(pixelx(Af)-pixelx(0))
   LET dAy=Af/(pixely(Af)-pixely(0))
   LET Yt=0 ! Y(t)
   FOR j=0 TO Af STEP dA2 ! j= Ss= (Kr-1)*theta
      FOR i=0 TO 99
         LET Yt=Ri(Yt,j)
         PLOT POINTS: j,Yt
      NEXT i
   NEXT j
   !----- setup cursor Ss
   LET x=Ss
   ASK PIXEL SIZE (x,Af;x,-Af) i,j
   MAT B4=ZER(0,j-1)
   ASK PIXEL ARRAY (x,Af) B4
   LET bx4=pixelx(x)
   CALL cursor4( bx4, B4)
   !-----
   LET x=(Ei+120)*Af*.43/120 !// Ei=x*120/(Af*.43)-120
   LET bx3=pixelx(x)
   CALL cursor130( bx3, 1.7, 1.4, "Ei")
   LET x=Kr*Af*.43 !// Kr=x*1/(Af*.43)
   LET bx2=pixelx(x)
   CALL cursor130( bx2, 2.1, 1.8, "Kr")
   LET x=(Af-0.5)*Af*.43/2 !// Af2=x*2/(Af*.43)+0.5
   LET bx1=pixelx(x)
   CALL cursor130( bx1, 2.5, 2.2, "Af")
END SUB

SUB cursor130( bx, uy, ly, w$)
   PLOT TEXT,AT -.06*Af,Af*(uy-0.2): w$
   SET LINE COLOR "blue"
   PLOT LINES: 0,Af*uy; Af*.43,Af*uy; Af*.43,Af*ly; 0,Af*ly; 0,Af*uy
   CALL cursor13( bx, uy, ly)
END SUB

END
 

漂流するニューラル・ネット

 投稿者:SECOND  投稿日:2009年 1月18日(日)11時12分0秒
返信・引用  編集済
  !
! 漂流するニューラル・ネット(更新)再投稿
!
!----
OPTION ARITHMETIC NATIVE
OPTION BASE 0
SET WINDOW -10,10, 20,0
SET TEXT background "OPAQUE"
!
DIM E(99),R(99),theta(99),F(99)
DIM Y(99),X(99),NetWork(99,99)
DIM P_(1 TO 5, 99),Px(99)
DIM Sum(1 TO 5)
MAT READ P_
! 1)
DATA 1,1,0,0,0,0,0,0,1,1
DATA 1,1,1,0,0,0,0,1,1,1
DATA 0,1,1,1,0,0,1,1,1,0
DATA 0,0,1,1,1,1,1,1,0,0
DATA 0,0,0,1,1,1,0,0,0,0
DATA 0,0,0,0,1,1,1,0,0,0
DATA 0,0,1,1,1,1,1,1,0,0
DATA 0,1,1,1,0,0,1,1,1,0
DATA 1,1,1,0,0,0,0,1,1,1
DATA 1,1,0,0,0,0,0,0,1,1
! 2)
DATA 0,0,0,0,0,1,0,0,0,0
DATA 0,0,0,0,1,1,1,0,0,0
DATA 0,0,0,0,1,1,1,0,0,0
DATA 0,0,0,1,1,1,1,1,0,0
DATA 0,0,0,1,1,0,1,1,0,0
DATA 0,0,1,1,1,0,1,1,1,0
DATA 0,0,1,1,0,0,0,1,1,0
DATA 0,1,1,1,0,0,0,1,1,1
DATA 0,1,1,1,1,1,1,1,1,1
DATA 0,1,1,1,1,1,1,1,1,1
! 3)
DATA 0,0,1,1,1,0,0,0,1,1
DATA 0,1,1,1,1,1,1,1,1,1
DATA 1,1,1,0,1,1,1,1,0,0
DATA 1,1,0,0,0,1,1,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,1,1,0,0,0,1,1
DATA 0,0,1,1,1,1,0,1,1,1
DATA 1,1,1,1,1,1,1,1,1,0
DATA 1,1,0,0,0,1,1,1,0,0
DATA 0,0,0,0,0,0,0,0,0,0
! 4)
DATA 0,0,1,0,0,0,0,1,0,0
DATA 0,0,1,1,0,0,1,1,0,0
DATA 0,0,1,1,1,1,1,1,0,0
DATA 0,0,1,1,1,1,1,1,0,0
DATA 0,0,1,1,1,1,1,1,0,0
DATA 0,1,1,1,1,1,1,1,1,0
DATA 1,1,1,1,1,1,1,1,1,1
DATA 0,0,0,1,1,1,1,0,0,0
DATA 0,0,0,0,1,1,1,0,0,0
DATA 0,0,0,0,0,1,0,0,0,0
! 5)
DATA 0,0,0,0,1,1,0,0,0,0
DATA 0,1,1,0,1,1,0,1,1,0
DATA 0,1,0,0,1,1,0,0,1,0
DATA 0,0,0,0,1,1,0,0,0,0
DATA 1,1,1,1,1,1,1,1,1,1
DATA 1,1,1,1,1,1,1,1,1,1
DATA 0,0,0,0,1,1,0,0,0,0
DATA 0,1,1,0,1,1,0,1,1,0
DATA 0,1,1,0,1,1,0,1,1,0
DATA 0,0,0,0,1,1,0,0,0,0

!----- 初期値サンプル1(感で探すのは無理かも。)
! MAT theta=(-1.27)*CON
! LET Af=1.6
! LET Kr=0.92
! LET Kf=0.4
! LET Ei=-10
!
!----- 初期値サンプル2
MAT theta=ZER ! ニューロン不応の固定成分 (しきい値)
LET Af=1 ! ニューロン自身の感度を不応にする負性の自己帰還結合係数 と、
LET Kr=0.95 ! その減衰定数(0< ,< 1)
LET Kf=0.4 ! ニューロンが、他のニューロンから受ける相互結合の減衰定数(0< ,< 1)
LET Ei=-100 ! 2値化関数、S字形 sigmoid() の入力係数
!
!----- 引き金となる相互結合の刺激の作成(無信号からの励起はできない。)
RANDOMIZE !15 !6
DO
   LET j=0
   FOR i=0 TO 99
      LET F(i)=RND-0.5
      LET j=j+F(i)
   NEXT i
LOOP UNTIL ABS(j)< .002
!
!----- 環境の準備
SET LINE COLOR 2
FOR n_=1 TO 5
   LET w=0
   !----- サンプル・パターンの表示
   FOR j=0 TO 9
      FOR i=0 TO 9
         IF P_(n_,j*10+i)>0 THEN
            DRAW circle WITH SCALE(0.03)*SHIFT(i*.08-9, j*.08+n_+.9)
            LET w=w+1
         END IF
      NEXT i
   NEXT j
   PLOT TEXT,AT -6,n_+1.5:"Dots/Body="&STR$(w)&"/100"
   PLOT TEXT,AT -8,n_+1.5:":"&STR$(Sum(n_))
   LET DC=w/100 ! 平均値(直流成分)
   !-----
   ! 5つのパターンの平均値からの偏差(交流成分)を、
   ! 1つの行列 NetWork(,) の中に、埋め込む。相互結合係数の行列 作成。
   !
   !              5 (p) _  (p) _
   ! 共分散行列の作成 ωij=Σ(χi-χ)*(χj-χ)  …参照。
   !            p=1
   !-----

   FOR i=0 TO 99
      FOR j=0 TO 99
         LET NetWork(i,j)=NetWork(i,j)+(P_(n_,i)-DC)*(P_(n_,j)-DC)
      NEXT j
   NEXT i
NEXT n_
!-----
! 5つが、自己の共分散の形で合算され、1つなった行列 NetWork(,) で、
! 100個のニューロンを接続し、漂流させると・・・
!
! ( 周期の無い計算ですが、演算桁の制限による丸めのために、周期的
!   動作へ落ちています・・長々と、漂着しないときは、Run しなおす。)
!
!-----
PLOT TEXT,AT -9, 1:"漂流するニューラル・ネット"
PLOT TEXT,AT -9, 9:"右クリックで 終了"
PLOT TEXT,AT -9,10:"左クリック STOP/START"
SET LINE COLOR 1
DO
   DO
      LET T=T+1
      PLOT TEXT,AT -9,8:"t="&STR$(T)
      CALL DispX
      CALL Compare
      CALL Xi00
      MOUSE POLL mx,my,mlb,mrb
      WAIT DELAY 0
   LOOP UNTIL mlb=1 OR mrb=1
   !----- left click stop/start
   IF mlb=1 THEN
      DO
         WAIT DELAY 0.02
         MOUSE POLL mx,my,mlb,mrb
      LOOP UNTIL mlb=0
      DO
         WAIT DELAY 0.02
         MOUSE POLL mx,my,mlb,mrb
      LOOP UNTIL mlb=1 OR mrb=1
      WAIT DELAY 0.1
   END IF
   !----- right click stop end.
LOOP UNTIL mrb=1

!----- 各ニューロン0~99 の駆動
SUB Xi00
   FOR i=0 TO 99
      LET w=0
      FOR j=0 TO 99
         LET w=w+NetWork(i,j)*X(j)
      NEXT j
      LET F(i)=Kf*F(i)+w
      LET R(i)=Kr*(R(i)+theta(i))-Af*X(i)-theta(i)
      LET Y(i)=R(i)+F(i)
   NEXT i
   FOR i=0 TO 99
      IF Ei*Y(i)< 709 THEN ! 桁あふれ防止
         LET X(i)=1/(1+EXP(Ei*Y(i)))
      ELSE
         LET X(i)=1/(1+EXP(709))
      END IF
   NEXT i
END SUB

!----- 各ニューロンの出力 X(0~99) 発火の、画面表示。
SUB DispX
   SET DRAW mode hidden
   SET AREA COLOR 0
   PLOT AREA:-10,10; 0,10; 0,0; 10,0; 10,20;-10,20
   SET AREA COLOR 2 ! //fire
   FOR V=0 TO 9
      FOR H=0 TO 9
         LET i=V*10+H
         IF 0.5=< X(i) THEN
            PLOT AREA: H,V; H+1,V; H+1,V+1; H,V+1
            LET Px(i)=1
            SET COLOR MIX(0) 0,1,1 ! B.G.color cyan( text)
         ELSE
            PLOT LINES: H,V; H,V+1; H+1,V+1
            LET Px(i)=0
            SET COLOR MIX(0) 1,1,1 ! B.G.color 0
         END IF
         !----- ニューロンの内部(-~0~+) 0=< は発火
         PLOT TEXT,AT H*2-10, V*0.8+12, USING"###.###":Y(i)
      NEXT H
   NEXT V
   SET COLOR MIX(0) 1,1,1 ! B.G.color 0
   SET DRAW mode explicit
END SUB

!----- 生成パターンの分別 計数の、画面表示。
SUB Compare
   FOR n_=1 TO 5
      FOR i=0 TO 99
         IF P_(n_,i)<>Px(i) THEN EXIT FOR
      NEXT i
      IF 99< i THEN
      ! ----- 一致
         LET PC_=10 ! //timer ON 1st.to 2nd.Cursor
         IF PB_=n_ THEN EXIT SUB
         IF PN_>0 THEN PLOT TEXT,AT -8, PN_+1.5: ":"& STR$(Sum(PN_))& " " ! //old 1st.2nd.Cursor OFF
         LET PB_=n_ ! //flag 2nd.Cursor
         LET PN_=n_ ! //flag 1st.Cursor
         LET Sum(n_)=Sum(n_)+1 ! 計数
         SET COLOR MIX(0) 0,1,1 ! //new 1st.Cursor ON (B.G.color)
         PLOT label,AT -8, n_+1.5: ":"& STR$(Sum(n_))& " "
         SET COLOR MIX(0) 1,1,1
         beep
         EXIT SUB
         !-----
      END IF
   NEXT n_
   ! ----- 不一致
   IF PB_=0 THEN EXIT SUB
   IF PC_>1 THEN
      LET PC_=PC_-1
      EXIT SUB
   END IF
   SET COLOR MIX(0) .75,.75,.75 ! //new 2nd.Cursor ON (B.G.color)
   PLOT TEXT,AT -8, PB_+1.5: ":"& STR$(Sum(PB_))& " "
   SET COLOR MIX(0) 1,1,1
   LET PB_=0
END SUB

END
 

今年のセンター試験BASIC

 投稿者:山中和義  投稿日:2009年 1月20日(火)10時36分8秒
返信・引用
  ●問題とプログラム

p,qは異なる自然数とする。
与えられた自然数kについて、d以下の自然数kのうちで
 k=m*p+n*q、m,nは0以上の整数
で表すことができるものを小さい順に列挙する。

例. p=3,q=7,d=15のとき、 3  6  7  9  10  12  13  14  15   総数= 9
例. p=3,q=7,d=100のとき、総数= 94。


100 INPUT PROMPT "p=": P
110 INPUT PROMPT "q=": Q
120 INPUT PROMPT "d=": D
130 LET U=0
140 FOR K=1 TO D !d以下の自然数kのうちで
150    IF K-INT(K/P)*P=0 THEN GOTO 210 !kがpの倍数の場合(k=m*p+0) ※MOD(K,P)=0
160    FOR M=0 TO INT(K/P) !0からPで割った商まで ∵k=m*p+r
170       LET R=K-M*P !k-m*p=n*q
180       IF R-INT(R/Q)*Q=0 THEN GOTO 210 !rがqの倍数の場合 ※MOD(R,Q)=0
190    NEXT M
200    GOTO 230 !該当なし。次へ
210    PRINT K !条件を満たす
220    LET U=U+1
230 NEXT K
240 PRINT "総数="; U
250 END



●P=3,Q=7,D=100での総数を求める問題の解法について
 トレースするには手順が多すぎる。世界のナベアツではないが、ほとんどアホになってしまう。

そこで、・・・

・拡張ユークリッドの互除法 m*3+n*7=gcd(3,7)=1=k より
 整数組(m,n)で、kの倍数を表すことができる。(一意ではない)

これより
 問題文にヒントがある。
 1〜3*7=21までの整数が表現できるか確認する。 1,2,4,5,8,11が無理。


・「3の倍数と7の倍数との和」の線形性は、「左斜め」になる。(7=2*3+1ずつずれる)

 縦:3の倍数、横:7の倍数
   0   7  14  21  28  35  42  49  56  63  70  77  84
   3  10  17  24  31  38  45  52  59  66  73  80  87
   6  13  20  27  34  41  48  55  62  69  76  83  90
   9  16  23  30  37  44  51  58  65  72  79  86  93
  12  19  26  33  40  47  54  61  68  75  82  89  96
  15  22  29  36  43  50  57  64  71  78  85  92  99
  18  25  32  39  46  53  60  67  74  81  88  95 102
  21  28  35  42  49  56  63  70  77  84  91  98 105
  24  31  38  45  52  59  66  73  80  87  94 101 108
  27  34  41  48  55  62  69  76  83  90  97 104 111
  30  37  44  51  58  65  72  79  86  93 100 107 114
  33  40  47  54  61  68  75  82  89  96 103 110 117
  36  43  50  57  64  71  78  85  92  99 106 113 120
  39  46  53  60  67  74  81  88  95 102 109 116 123
  42  49  56  63  70  77  84  91  98 105 112 119 126
  45  52  59  66  73  80  87  94 101 108 115 122 129

これより
 一目瞭然!?


・・・と考えてみた。
 

Re: 今年のセンター試験BASIC

 投稿者:山中和義  投稿日:2009年 1月21日(水)11時08分47秒
返信・引用
  > No.249[元記事へ]

●210行目で、条件を満たすMとNを表示するように改良してみた。

・150行目を削除
・210行目にM,Nの計算を追加

100 INPUT PROMPT "p=": P
110 INPUT PROMPT "q=": Q
120 INPUT PROMPT "d=": D
130 LET U=0
140 FOR K=1 TO D !d以下の自然数kのうちで
150    !
160    FOR M=0 TO INT(K/P) !0からKをPで割った商まで
170       LET R=K-M*P !k-m*p=n*q
180       IF R-INT(R/Q)*Q=0 THEN GOTO 210 !rがqの倍数の場合 ※MOD(R,Q)=0
190    NEXT M
200    GOTO 230 !該当なし。次へ
210    PRINT K; M;INT(R/Q) !条件を満たすM,N ※
220    LET U=U+1
230 NEXT K
240 PRINT "総数="; U
250 END


*アルゴリズムの数学的背景
不定方程式 k=m*p+n*q は、k-m*p=n*q と変形される。
合同式で表すと、k-m*p≡0 mod q となる。

m は0以上の整数、p は自然数より、m*p≧0 となる。 同様に、n*q≧0。
また、n*q=k-m*p≧0 より、k≧m*p となる。
したがって解があれば、mは0〜INT(K/P)で見つかる。



●(m,n)の組は一通りでない。その組を調べる。

・180行目を変更と追加(210,220行目)
・150,200,210,220行目を削除

100 INPUT PROMPT "p=": P
110 INPUT PROMPT "q=": Q
120 INPUT PROMPT "d=": D
130 LET U=0
140 FOR K=1 TO D !d以下の自然数kのうちで
150    !
160    FOR M=0 TO INT(K/P) !0からKをPで割った商まで
170       LET R=K-M*P !k-m*p=n*q
180       IF R-INT(R/Q)*Q=0 THEN !rがqの倍数の場合 ※MOD(R,Q)=0
             PRINT K; M;INT(R/Q) !条件を満たすM,N
             LET U=U+1
          END IF
190    NEXT M
200    !
210    !
220    !
230 NEXT K
240 PRINT "総数="; U !※意味が変わる
250 END
 

let文の変数名並び

 投稿者:荒田浩二  投稿日:2009年 1月25日(日)00時25分45秒
返信・引用
  JISによると、let文には次のような構文があります。みなさんご存じでしたか。

10 DIM M(8)
20 LET a,b,c=5
30 PRINT a;b;c
40 LET a,b,c,M(b)=b+2
50 PRINT a;b;c
60 MAT PRINT M;
70 LET m$,n$="xyz"
80 PRINT m$,n$
90 END
 

格納できる マトリックス

 投稿者:与坂  昇平  投稿日:2009年 1月26日(月)10時22分43秒
返信・引用
  今日は
full  basic  で  有限要素法の 構造解析ソフトを  開発しています
C++ でも していますが
full  basic  は  グラヒックが  簡単で  c++ より  便利です
しかし
時間が  かかります

解析可能要素数は
3GRAM  で

full  basic  6000 要素
C++     12000 要素です


構造解析では  要素数  6000要素では
不足です
解析可能要素数  つまり
格納可能マトリツクス数を  増やすには
どうすればいいでしょうか ???

また
full  basic  は
64bit に  対応  していますか

是非
教えて下さい

よろしく
 

Re: 格納できる マトリックス

 投稿者:白石 和夫  投稿日:2009年 1月26日(月)17時40分30秒
返信・引用  編集済
  > No.252[元記事へ]

Full BASIC規格には,整数型の概念がありません。
規格の範囲では,32ビットの変数も64ビットの変数も使えません。
また,Full BASICには,配列の大きさに関する規定がありません。
規格上は,
DECLARE NUMERIC m(0 TO 10000000)
のような巨大な配列の宣言も許されます。
(仮称)十進BASICはメモリの使用効率がよくないので,
True BASICを試してみるとよいかも知れません。

(仮称)十進BASICの現在のバージョンのなかで最適化を図りたいのであれば,
ヘルプの言語使用の詳細の最後のページ「制限」に書いてある

★ 変数用管理用仮想メモリー
通常,変数管理用に割り当てる仮想メモリーは,実装物理メモリ容量から16Mバイトを減じた値(ただし,最小1Mバイト,最大512Mバイト)を上限とする。
なお,BASIC.INIにキーを追加することで直接指定することができる。

を参照して,BASIC.INIを書き換えてみてください。
なお,Win32アプリケーションのアドレス空間は2GBで,その一部に変数管理用メモリを割り当てるので,2048Mバイト以上を指定することはできませんし,2048MBより小さくても2048MBに近い数値を指定するとBASIC本体が正常に動作しません。
なお,2進モードの場合,配列は変数管理管理用メモリをほとんど消費しないので,変数管理用メモリの割り当てを減らすほうが効果的な可能性があります。

(注)BASIC.INIを使いたいときは,アーカイブ版をダウンロードし展開したものを使ってください。
(レジストリを使用する場合はレジストリの当該項目を修正することになります)

(参照)旧掲示板過去ログ
http://www.geocities.jp/thinking_math_education/log/22/koctpp/index.html
 

すみません編集させていただきました(測量最小二乗法について)

 投稿者:kikiriri  投稿日:2009年 1月29日(木)18時12分33秒
返信・引用  編集済
  測量網平均 最小二乗法について、
情報待つ、
 

Re: 測量最小二乗法について

 投稿者:山中和義  投稿日:2009年 1月30日(金)15時06分48秒
返信・引用
  > No.254[元記事へ]

kikiririさんへのお返事です。

参考サイト http://hw001.gate01.com/kazuok/geodetic/leveling.html

Full BASICの場合、行列が計算できるので、他の言語よりは簡単に計算できると思います。
ただ、2項演算までですから、展開しながらこつこつ計算する必要があります。

また、表計算の方がGUIを含めて実用化し易いかもしれません。


上記サイトの例題(PDFファイル内)のサンプルコーディング
!最小2乗法による測量網平均(条件方程式法)

!H型
!  A  C
! 1↓ 5 ↓3
!  P → Q
! 2↑  ↑4
!  B  D

!既知点
LET C=4 !数

DATA 25.645 !A点の標高(m)
DATA 24.666 !B点
DATA 25.024 !C点
DATA 25.699 !D点
DIM Z(C)
MAT READ Z

!観測値
LET P=5 !数

DATA -6.225, 0.44 !路線1 高低差(m)、路線長(km)
DATA -5.245, 0.25 !路線2
DATA  0.278, 0.33 !路線3
DATA -0.399, 0.26 !路線4
DATA  5.879, 0.44 !路線5

DIM X(P),G(P,P) !観測値、コアファクタ
MAT G=ZER
FOR i=1 TO P
   READ X(i),G(i,i)
NEXT i
MAT PRINT X;
MAT PRINT G;


!未知数
LET Px=2 !求点PとQ


!------------------------------

!自由度R ※条件方程式の数
LET R=P-Px


!条件方程式 UV=t
DIM U(R,P)
DATA 1,-1,0,0,0 !点Pについて HA+h1~=HB+h2~ より、(h1+v1)-(h2+v2)=HB-HA ∴v1-v2=-(h1+HA)+(h2+HB)
DATA 0,0,1,-1,0 !点Qについて HC+h3~=HD+h4~
DATA 1,0,0,-1,1 !点Pと点Qについて HA+h1~+h5~=HD+h4~
MAT READ U

DIM t(R,1)
FOR i=1 TO R
   LET s=0
   FOR j=1 TO P
      IF j>C THEN LET Zj=0 ELSE LET Zj=Z(j)
      LET s=s-(X(j)+Zj)*U(i,j)
   NEXT j
   LET t(i,1)=s
NEXT i
!!!LET t(1,1)=-X(1)+X(2)-Z(1)+Z(2) !0.001
!!!LET t(2,1)=-X(3)+X(4)-Z(3)+Z(4) !-0.002
!!!LET t(3,1)=-X(1)+X(4)-X(5)-Z(1)+Z(4) !0.001
MAT PRINT t;


!------------------------------

!相関式 NK=t、N=UG(Ut)より、K=(Ni)tを求める
DIM Ut(P,R)
MAT Ut=TRN(U)
DIM TMP(P,R) !G(Ut) ※次でも使う
MAT TMP=G*Ut
DIM N(R,R)
MAT N=U*TMP
MAT PRINT N;

DIM invN(R,R)
MAT invN=INV(N)
DIM K(R,1)
MAT K=invN*t

MAT PRINT K;


!補正値の計算(mm) V=G(Ut)K
DIM V(P,1)
MAT V=TMP*K

MAT PRINT V;


!最確値 X~=X+V
FOR i=1 TO P
   PRINT "路線";STR$(i);"=";X(i)+V(i,1)
NEXT i
PRINT "点P";Z(1)+(X(1)+V(1,1)); Z(2)+(X(2)+V(2,1)) !有効桁数 ##.###
PRINT "点Q";Z(3)+(X(3)+V(3,1)); Z(4)+(X(4)+V(4,1))




!精度の計算(mm^2) σ^2=(Kt)NK/r
DIM s2(1,1),Kt(1,R)
MAT Kt=TRN(K)
MAT s2=Kt*t !NK=t
LET sigma2=s2(1,1)/R

PRINT "σ^2=";sigma2


!分散行列(mm^2) σ^2*Gx、Gx=G-G(Ut)(Ni)UG
DIM Gx(P,P)
MAT Gx=TMP*invN !G(Ut)(Ni)
MAT Gx=Gx*U
MAT Gx=Gx*G
MAT Gx=G-Gx
MAT Gx=sigma2*Gx

MAT PRINT Gx;


END
 

すみません編集させていただきました

 投稿者:kikiriri  投稿日:2009年 1月30日(金)19時56分54秒
返信・引用  編集済
  測量最小二乗法について、
早速のご返答
ありがとうございました。
 

Re: ありがとうございました

 投稿者:山中和義  投稿日:2009年 1月30日(金)20時27分56秒
返信・引用
  > No.256[元記事へ]

kikiririさんへのお返事です。

> 用語について、説明お願いできないでしょうか。

測量用語の基礎知識 http://www.1roba.com/


また、参考文献
 最小二乗法と測量網平均の基礎 田島稔(著)、小牧和雄(著)  東洋書店 (2001/03)
などがあります。
 

ありがとうございました

 投稿者:kikiriri  投稿日:2009年 1月31日(土)11時09分30秒
返信・引用
  早速のご返答ありがとうございました。
参考にしたいと思います。
最小二乗法と測量網平均の基礎 田島稔(著)、小牧和雄(著)  東洋書店 (2001/03)
持っているんですが、正直読めないです。
測量の基礎から分かってないと思います。
正直どこから、どの程度?勉強すればいいのかが分かりません。
コロナ社 測量(1) 測量(2)
実教出版 測量演習ノート
など、
持っています。
”参考になるものがあれば紹介してください。”
”ひとつの目標というか、それが平均網のプログラミング化で。”
僕には参考にされていたページを見つけることさえできませんでしたので。
こうしてご助言求めている次第です。
よろしくお願いします。
 

編集させていただきました

 投稿者:kikiriri  投稿日:2009年 2月 1日(日)13時30分16秒
返信・引用  編集済
  長らく情報などの返答得られずこのような形で編集させていただきました。

気にしてくださった方々、誠にありがとうございました

ありがとうございました。
 

節点解析法について

 投稿者:大熊 正  投稿日:2009年 2月 1日(日)14時39分35秒
返信・引用
  増幅器を含む、交流回路の解析

1. CR回路2段の低域フィルターで単純な増幅器を含まないものは、
  節点方程式を立てて解けることが分りました。
  入力 E1 から最初の抵抗 R1,次がR2,その次が最終端子にアース
  に対しC2ガ在り、 このC2の出力が増幅器でK倍される。
    この増幅器の出力は、C1を介して R1とR2の節点に結ばれる。
  C1=2*C2 の時、K=1前後で最適である。
  即ち、典型的なアクテブ 2段フィルターの問題で質問いたします。

  C1 の電圧をE2 C2の電圧をE3とし、そのK倍の電圧がC1でR1とR2の
  節点に正帰還。とすると、E1とE3の関係式がでて、回路は解けます。

2. このようにまず解いて、周波数特性などを表示するのではなく、節点
 方程式のように、・・・・機械的に節点にアドミタンス等を挿入??
   して問題を解きたいのですが、E2やE3,そしてK等をマトリクス上でどう
  表現して良いか分りません。
  式を予め解かずとも、機械的に表示すれば、マトリクスが自動的に
  解いてくれるのではないかと期待しています。
   何方か御教えて下さると有り難いのですが。

3, マトリクスで複素数を MAT PRINT  A とやると、複素数がやたら
  長い表示になります。
  何とかPRINT USING #### 的に簡結な表示は出来ないでしょうか。
  無理にやるとマトリクスでは複素数をPRINT USING 表示は出来ないと
  表示されます。
 

Re: 節点解析法について

 投稿者:白石 和夫  投稿日:2009年 2月 1日(日)16時10分14秒
返信・引用
  > No.260[元記事へ]

> 3, マトリクスで複素数を MAT PRINT  A とやると、複素数がやたら
>   長い表示になります。
>   何とかPRINT USING #### 的に簡結な表示は出来ないでしょうか。
>   無理にやるとマトリクスでは複素数をPRINT USING 表示は出来ないと
>   表示されます。

実部と虚部,あるいは,絶対値と偏角など,虚数部分を含まない数値のペアに分けてから書式を指定してください。
また,MAT PRINT USINGみたいのが必要であれば,配列と書式を引数としてとる副プログラムを作成して使ってください。
 

Re: 節点解析法について

 投稿者:山中和義  投稿日:2009年 2月 2日(月)10時38分2秒
返信・引用  編集済
  > No.260[元記事へ]

大熊 正さんへのお返事です。

理想的なオペアンプの計算
 仮想の素子を考える(図2)
 ・ナレータ
  ��V+とV-との電位は同じ(イマージナリーショート)
  ��V+とV-とには電流が流れない(入力抵抗が無限大)
 ・ノレータ
  ��Voからは必要な電流が供給される(両方向)

これを適用すると、図3は、図1の等価回路になると思います。

この図3の回路図で節点方程式を考えます。
通常、Voは固定値とするが、アンプにより確定できません。(Vo=K*e2、e2は節点�△療徹漫�
そこで、アンプの入力を出力に反映させて(反復計算で)収束させます。


プログラムは図1のようなアンプを含んだ回路図で計算できるように
以前紹介した節点電位法のものを改良してあります。

1000 !節点電位法によるフィルタ回路の周波数解析(利得、位相)
1010
1020 OPTION ARITHMETIC COMPLEX
1030
1040 LET j=SQR(-1) !虚数単位 ※電気系はjを使う
1050
1060 LET f=60 !周波数[Hz]
1070 DEF w=2*PI*f !角周波数ω
1080
1090 DEF H2Ohm(L)=j*w*L ![H]を[Ω]へ
1100 DEF F2Ohm(C)=1/(j*w*C) ![F]を[Ω]へ
1110 DEF xL(L)=w*L !誘導リアクタンス
1120 DEF xC(C)=1/(w*C) !容量リアクタンス
1130
1140 SUB DispS(z) !複素数をS表示する ※スタインメッツ(Steinmetz)
1150    PRINT ABS(z);
1160    IF ABS(z)<>0 THEN
1170       IF arg(z)<>0 THEN PRINT "∠";DEG(arg(z));"°";
1180    END IF
1190    !PRINT
1200 END SUB
1210
1220 FUNCTION S2COMPLEX(l,th) !S表示(極座標形式)を複素数へ
1230    LET S2COMPLEX=COMPLEX(l*COS(RAD(th)),l*SIN(RAD(th)))
1240 END FUNCTION
1250 FUNCTION i2COMPLEX(im,th) !瞬時値式を複素数へ ※最大値、初期位相
1260    LET i2COMPLEX=S2COMPLEX(im/SQR(2),th) !実効値、初期位相
1270 END FUNCTION
1280 !-------------------- ここまでがサブルーチン
1290
1300
1310 SUB set_curcit !素子や結線を定義する
1320    !---------- ↓↓↓↓↓ ----------
1330
1340    !●回路図 Sallen-Key 3次ローパス・フィルタ
1350
1360    !参考サイト http://sim.okawa-denshi.jp/OPseikiLowkeisan.htm
1370
1380    !          ┌─C2─┬──────┐
1390    !          │   │ ┌──┐ │
1400    !          │   └─┤-  │ │
1410    !          │     │ K├─6─
1420    ! ─2─R1─3─R2─4─R3─5─┤+  │ ↑
1430    !  ↑   │       │ └──┘ │
1440    !  Vi   C1       C3      Vo
1450    !  ↓   │       │      ↓
1460    ! ─1───┴───────┴──────┴─
1470    !  │
1480    !  ≡アース
1490
1500    LET GND=1 !アース
1510    LET Vi=2 !入力端子
1520    LET Vo=6 !出力端子
1530
1540    !素子: Rn,Vn,In、n:番号(連番) ※2文字目以降は番号
1550    !値:
1560    !端子番号(起点): 1以上の値 ※節点
1570    !端子番号: 1以上の値 ※節点
1580
1590    CALL AddElements("R1",51e3,2,3) !51k[Ω]、枝路電流は2→3と仮定する
1600    CALL AddElements("C1",F2Ohm(0.0068e-6),3,1) !0.0068[μF]
1610    CALL AddElements("R2",82e3,3,4) !82k[Ω]
1620    CALL AddElements("C2",F2Ohm(0.022e-6),4,6) !0.022[μF]
1630    CALL AddElements("R3",39e3,4,5) !39k[Ω]
1640    CALL AddElements("C3",F2Ohm(330e-12),5,1) !330[pF]
1650
1660    !※電圧源の番号は1からの連番 例. CALL AddElements("V1",?,?,?) !?[V]
1670    !なし
1680
1690    CALL AddElements("A1",1.0,5,6) !アンプ 増幅率1.0,+端子5,出力端子6
1700
1710    !---------- ↑↑↑↑↑ ----------
1720
1730    CALL AddElements("Vi",10,GND,Vi) !10[V] ※測定用の電圧
1740 END SUB
1750
1760 !---------- ↓↓↓↓↓ ----------
1770 LET Ns=0 !電圧源の数
1780 LET Nd=6 !節点の数
1790 LET Na=1 !アンプの数
1800 !---------- ↑↑↑↑↑ ----------
1810
1820 LET N=Nd+Ns+Na+1
1830
1840 !●キルヒホッフの電流則より、節点方程式を組み立てる
1850 DIM A(N,N),x(N),b(N) !連立方程式 Ax=b
1860
1870 DIM AmpK(Na),AmpPlus(Na),AmpOut(Na)
1880
1890 SUB AddElements(el$,ev,nd1,nd2) !結線情報から回路方程式を組み立てる
1900    IF (nd1<1 OR nd1>Nd) OR (nd2<1 OR nd2>Nd) THEN
1910       PRINT "素子";el$;"の節点番号が違います。";nd1;nd2
1920       STOP
1930    END IF
1940
1950    !連立方程式を組み立てる Ax=b
1960    ! ┌  │  ┐┌ ┐ ┌ ┐
1970    ! │G │±1││V │=│I │ R,C,L,電流源(Nd個)
1980    !───┼─────────
1990    ! │±1│-Zp││Ip│ │Ep│ 電圧源(Ns個)、アンプ(Na個)、入力電圧源(1個)
2000    ! └  │  ┘└ ┘ └ ┘
2010
2020    SELECT CASE UCASE$(el$(1:1)) !素子に応じて
2030    CASE "V" !電圧源なら
2040       LET t$=UCASE$(el$(2:LEN(el$)))
2050       IF t$="I" THEN !計測用の入力電圧源なら
2060          LET p=Nd+Ns+Na+1
2070       ELSE
2080          LET p=VAL(t$) !番号を得る
2090          IF p<1 OR p>Ns THEN
2100             PRINT "電圧源の番号が違います。";el$
2110             STOP
2120          END IF
2130          LET p=p+Nd
2140       END IF
2150       LET A(nd1,p)=A(nd1,p)-1 !電流Ipが節点iから節点jへ流れたとして、(Vi-Vj)-Ip*Zp=Ep
2160       LET A(p,nd1)=A(p,nd1)-1
2170       LET A(nd2,p)=A(nd2,p)+1
2180       LET A(p,nd2)=A(p,nd2)+1
2190       LET A(p,p)=A(p,p)+0 !内部抵抗Zpは0とする
2200       LET b(p)=b(p)+ev !起電力
2210
2220    CASE "A" !アンプなら
2230       LET t=VAL(el$(2:LEN(el$))) !番号を得る
2240       IF t<1 OR t>Na THEN
2250          PRINT "アンプの番号が違います。";el$
2260          STOP
2270       END IF
2280       LET p=t+Nd+Ns !出力側をノレータ(初期値0Vの電圧源)として扱う
2290       LET A(GND,p)=A(GND,p)-1
2300       LET A(p,GND)=A(p,GND)-1
2310       LET A(nd2,p)=A(nd2,p)+1
2320       LET A(p,nd2)=A(p,nd2)+1
2330
2340       LET AmpK(t)=ev !増幅率
2350       LET AmpPlus(t)=nd1 !+端子
2360       LET AmpOut(t)=p !方程式内での出力端子
2370
2380    CASE "I" !電流源なら
2390       LET b(nd1)=b(nd1)-ev
2400       LET b(nd2)=b(nd2)+ev
2410
2420    CASE ELSE !素子なら
2430       LET Gij=1/ev
2440       !対角成分 ※節点に接続された素子(アドミタンス)の和
2450       LET A(nd1,nd1)=A(nd1,nd1)+Gij
2460       LET A(nd2,nd2)=A(nd2,nd2)+Gij
2470       !その他の成分 ※節点に接続された素子(アドミタンス)に-1をかけたものの和
2480       LET A(nd1,nd2)=A(nd1,nd2)-Gij
2490       LET A(nd2,nd1)=A(nd2,nd1)-Gij
2500
2510    END SELECT
2520 END SUB
2530
2540 DIM Ai(N,N) !連立方程式を解く
2550 SUB routine
2560    MAT A=ZER
2570    MAT b=ZER
2580    CALL set_curcit !結線から方程式を組み立てる
2590
2600    FOR i=1 TO Nd !結線されていない節点 1*Vi=0
2610       IF A(i,i)=0 THEN LET A(i,i)=1
2620    NEXT i
2630    LET A(GND,GND)=0 !電位を0とする
2640
2650    !!!MAT PRINT A; !dump it
2660    !!!MAT PRINT b;
2670
2680
2690    MAT Ai=INV(A)
2700    MAT x=Ai*b
2710    IF Na>0 THEN !アンプがあれば
2720       FOR iter=1 TO 100 !安定させる ※要調整
2730          FOR i=1 TO Na
2740             LET b(AmpOut(i))=AmpK(i)*x(AmpPlus(i)) !Vo=K*V+ ※入力を出力に反映させる
2750          NEXT i
2760          MAT x=Ai*b
2770       NEXT iter
2780    END IF
2790 END SUB
2800
2810
2820
2830 !SET bitmap SIZE 600,600 !画面を大きくする
2840 LET ymin=-150
2850 SET WINDOW -0.5,6.5, ymin,5 !表示領域
2860 DRAW grid(1,5) !左端の目盛り
2870
2880 FOR f=1 TO 6 !x軸が対数
2890    PLOT TEXT ,AT f-0.3,-0.15: mid$("10  100 1k  10k 100k1M  ",4*(f-1)+1,4)
2900 NEXT f
2910
2920 FOR f=10 TO 100000 STEP 100 !周波数[Hz]
2930    CALL routine
2940    PLOT LINES: LOG10(f),20*LOG10(ABS(x(Vo)/x(Vi))); !利得[dB]
2950 NEXT f
2960 PLOT LINES
2970
2980
2990 SET TEXT COLOR 2
3000 FOR i=5 TO ymin STEP -5 !右端の縦軸目盛り
3010    PLOT TEXT ,AT 6,i: STR$(i*2)&"°" !※利得のグラフに合わせるために2倍する
3020 NEXT i
3030
3040 SET LINE COLOR 2
3050 FOR f=10 TO 100000 STEP 100 !周波数[Hz]
3060    CALL routine
3070    LET t=arg(x(Vo)/x(Vi))
3080    IF t>0 THEN LET t=t-2*PI !0〜-2πへ補正する
3090    PLOT LINES: LOG10(f),DEG(t)/2; !位相θ ※利得のグラフに合わせるために1/2倍する
3100 NEXT f
3110 PLOT LINES
3120
3130
3140 END
 

マクローリン展開の高速近似値計算への応用

 投稿者:いがらしまなと  投稿日:2009年 2月 4日(水)18時40分56秒
返信・引用
  マクローリン展開の高速近似値計算への応用

1、十進法BASICによるプログラム

REM *** 逆行列で高速マクローリン展開
DIM a(3,3),b(3,1),c(3,1),d(3,3)
DEF f(x)=EXP(x)
LET x=0.0001
LET a(1,1)=x
LET a(1,2)=x^2
LET a(1,3)=x^3
LET a(2,1)=2*x
LET a(2,2)=4*x^2
LET a(2,3)=8*x^3
LET a(3,1)=3*x
LET a(3,2)=9*x^2
LET a(3,3)=27*x^3
MAT d=INV(a)
LET e=f(0)
LET c(1,1)=f(x)-e
LET c(2,1)=f(2*x)-e
LET c(3,1)=f(3*x)-e
MAT b=d*c
PRINT b(1,1)
PRINT b(2,1)
PRINT b(3,1)
END

2、理論

マクローリン展開の公式より

f(x)=a(0)+a(1)x+a(2)x^2+a(3)x^3+・・・・であるから。

x≒0に対して、解a(m)持つ連立方程式
f(nx)=a(0)+a(1)(nx)+a(2)(nx)^2+a(3)(nx)^3
を解くとマクロリン展開の近似値が求まる。

3、結果

f(x)=e^xのマクロリン展開を行列の逆行列を用いて計算した。

a(1)=0.999999999998332
a(2)=0.50000001
a(3)=0.166666766681668 を得るこれは真値

a(1)=1
a(2)=1/2=0.5
a(3)=1/6=0.1666・・・

に近い値となっている。

4、発展課題(自分に対して。。。。)

これをガウス・ジョルダン法により計算せよ!
 

(無題)

 投稿者:大熊 正  投稿日:2009年 2月 5日(木)10時42分50秒
返信・引用
  白石 様 山中 様  大熊です。

御多忙中の所、色々と御指導を頂きまことに有難うございます。

白石様
別途プログラムを作り、部分的に試した所、上手く動きました。

山中様
プログラムをコピーし、動かした所、綺麗に周波数特性が出ました。
「アンプの入力を出力に反映させて(反復計算で)収束させます。」
というのは、「目からうろこ」で驚きました。
総てを此れから勉強させていただきます。

それから、一番最後の 回路図は、どこから どのようにコピーし、
この投稿欄に貼りつけるのでしょうか。この投稿欄に貼りつけよう
としましたが、出来ませんでした。
また、パソコンの「メモ帖」や、10進BASIC にも貼り付きません。

出来ましたら、御教えください。

敬具
 

Re: (無題)

 投稿者:山中和義  投稿日:2009年 2月 5日(木)11時32分41秒
返信・引用  編集済
  > No.264[元記事へ]

大熊 正さんへのお返事です。

> それから、一番最後の 回路図は、どこから どのようにコピーし、
> この投稿欄に貼りつけるのでしょうか。この投稿欄に貼りつけよう
> としましたが、出来ませんでした。

この掲示板の投稿欄は(この画面の一番上)
 投稿者
 メール
 題名
 内容
 画像 ←←←ここ
 URL
となっていますが、この画像の欄に
自分のパソコン内の画像データ(gif、jpg、png形式)を指定するとアップロードすることができます。

画像データの作成は、Windoes付属の「ペイント」で可能です。保存のとき、gif、jpg形式にします。



> また、パソコンの「メモ帖」や、10進BASIC にも貼り付きません。

メモ帳やBASICの編集画面は「テキスト(文字)」のみを扱いますので、「画像」を貼り付けることはできません。
また簡易ワープロの「ワードパッド」では、「デキスト」と「画像」が扱えます。
したがって、画像データはプログラムとは別に管理(保存など)する必要があります。




●補足
 回路図を変更するときの修正箇所

−端子への入力の場合
1310 SUB set_circuit !素子や結線を定義する
1320    !---------- ↓↓↓↓↓ ----------
1330
1340    !●回路図 オペアンプ多重帰還型バンドパス・フィルタ
1350
1360    !参考サイト http://sim.okawa-denshi.jp/OPseikiLowkeisan.htm
1370
1380    !      ┌─C1─┬──────┐
1390    !      │   │      │
1400    !      │   R3      │
1410    !      │   │ ┌──┐ │
1420    ! ─2─R1─3─C2─4─┤-  ├─5─
1430    !  ↑   │     │ K│ ↑
1440    !  Vi   R2   ┌─┤+  │ Vo
1450    !  ↓   │   │ └──┘ ↓
1460    ! ─1───┴───┴──────┴─
1470    !  │
1480    !  ≡アース
1490
1500    LET GND=1 !アース
1510    LET Vi=2 !入力端子
1520    LET Vo=5 !出力端子
1530
1540    !素子: Rn,Cn,Ln,Vn,In、n:番号(連番) ※2文字目以降は番号
1550    !値:
1560    !端子番号(起点): 1以上の値 ※節点
1570    !端子番号: 1以上の値 ※節点
1580
1590    CALL AddElements("R1",5.1e3,2,3) !5.1k[Ω]、枝路電流は2→3と仮定する
1600    CALL AddElements("C1",F2Ohm(0.022e-6),3,5) !0.022[μF]
1610    CALL AddElements("R2",20e3,3,1) !20k[Ω]
1620    CALL AddElements("C2",F2Ohm(0.033e-6),3,4) !0.033[μF]
1630    CALL AddElements("R3",8.2e3,4,5) !8.2k[Ω]
1640    !
1650
1660    !※電圧源の番号は1からの連番 例. CALL AddElements("V1",?,?,?) !?[V]
1670    !なし
1680
1690    CALL AddElements("A1",-1.0,4,5) !アンプ 増幅率-1.0,−端子4,出力端子5
1700
1710    !---------- ↑↑↑↑↑ ----------
1720
1730    CALL AddElements("Vi",10,GND,Vi) !10[V] ※測定用の電圧
1740 END SUB
1750
1760 !---------- ↓↓↓↓↓ ----------
1770 LET Ns=0 !電圧源の数
1780 LET Nd=5 !節点の数
1790 LET Na=1 !アンプの数
1800 !---------- ↑↑↑↑↑ ----------
1810

通常、この箇所を変更します。

特に負帰還の場合は繰り返しは1回のみでよいみたいです。
2710    IF Na>0 THEN !アンプがあれば
2720       FOR iter=1 TO 1 !安定させる ※要調整  <---------- ここ
2730          FOR i=1 TO Na
2740             LET b(AmpOut(i))=AmpK(i)*x(AmpPlus(i)) !Vo=K*V+ ※入力を出力に反映させる
2750          NEXT i
2760          MAT x=Ai*b
2770       NEXT iter
2780    END IF


なお、サブルーチンset_circuitのスペルが違っていました。訂正します。
 

節点解析法について (2)

 投稿者:大熊 正  投稿日:2009年 2月 7日(土)11時32分28秒
返信・引用
  白石様 山中様 いつも御指導を頂き有難うございます。大熊です。

下記のごときプログラムを作り、山中様の回答を別解でなぞってみました。
答えは一致していると思ってます。
10進BASICは、マトリクスと複素数の計算が簡単に出来、初学修者にはとても
便利だと言うことを実感しています。

敬具


10 OPTION ARITHMETIC COMPLEX
   LET j=SQR(-1)
   OPTION BASE 1
   OPTION ANGLE DEGREES

   DIM FREQ(100,5)
   LET FREQ(1,1)=10
   LET FREQ(2,1)=12.25
   LET FREQ(3,1)=15
   LET FREQ(4,1)=17.32
   LET FREQ(5,1)=20
   LET FREQ(6,1)=24.5
   LET FREQ(7,1)=30
   LET FREQ(8,1)=34.6
   LET FREQ(9,1)=40
   LET FREQ(10,1)=50
   LET FREQ(11,1)=60
   LET FREQ(12,1)=70
   LET FREQ(13,1)=80
   LET FREQ(14,1)=90

   FOR I=1 TO 14
      LET P=I
      LET FREQ(I,1)=FREQ(P,1)
   NEXT I
   FOR I=15 TO 28
      LET P=I-14
      LET FREQ(I,1)=FREQ(P,1)*10
   NEXT I
   FOR I=29 TO 42
      LET P=I-28
      LET FREQ(I,1)=FREQ(P,1)*100
   NEXT I
   FOR I=43 TO 56
      LET P=I-42
      LET FREQ(I,1)=FREQ(P,1)*1000
   NEXT I
   LET FREQ(57,1)=100000

   ! FOR I=1 TO 57
   !    PRINT "FREQ(";I;",1)=";FREQ(I,1)
   ! NEXT I


   !                             ┌─C2─┬──────┐ 「注意」
   !                             │      │  ┌──┐  │   山中さんの回路と1番
   !                             │      └─┤-   │  │  端子番号が
   !                             │          │  K├─�エ� 小さくなってます。
   !         ┌─�;�R1─�※�R2─��─R3─�え;�+   │  ↑ V5
   !         ↑  ↑V1    ↑V2    ↑V3    ↑V4└──┘  │
   !         Is  Rs      C1              C3            │
   !         ↑  │      │              │            │
   !         ┴─0───┴───────┴──────┴─
   !             │
   !             ≡アース
   !    GND=0 !アース
   !    V1=1V !入力端子�� Rs=0.1オームに定電流源Is から10A流して1Vとする。
   !    V5=�� !出力端子�� V5=K*V4

20 ! CR 3段回路
   LET FF=1000             !Fの単位はヘルツ
   LET R1=51000            !Rの単位はオーム
   LET R2=82000
   LET R3=39000
   LET C1=0.00685/(10^6)   !Cの単位はuF,
   LET C2=0.022/(10^6)     !Cの単位はuF,
   LET C3=330/(10^12)      !Cの単位はPF,

   LET Y1=(2*PI*FF*C1)     !Yの単位はモー
   LET Y2=(2*PI*FF*C2)
   LET Y3=(2*PI*FF*C3)

   LET ω=(2*PI*FF)
   LET Rs=0.1    !Rsの単位はオーム      �,肇◆璽垢貌�れる。
   LET IS=10     !Isの単位はアムペア  Rsに加わる電流源で�,肇◆璽垢�1Vにする。

   LET NP=4
   DIM A(NP,NP)
   DIM T(NP,NP)

   DIM EOUT(NP,1)
   DIM B(NP,1)
   LET K=1

   !*********** データーと計算方法*****************
   !方法-1
   !  ミルマンの定理やキルヒホッフの法則なぞを多用、直接解く。

   !方法-2
   !  回路の�|嫉劼肇◆璽拘屬�0.1オームの抵抗、アドミッタンスGsをわざとつける。
   !  電流源 10A を入力にして�|嫉劼肇◆璽拘屬痢�Gs)に加えて V1を約  1Vとする。
   !  以下は、想定の回路につなげ、端子間のアドミッタンスを考え節点方程式を作る。
   !  � 辞△�R1,�◆辞�にR2,�◆璽◆璽垢僕椴�C1,��ー�い�R3,�ぁ璽◆璽垢僕椴�C3
   !  C3の電圧V4を増幅器に入力。�イ砲�V5=K*V4の電圧がでる。
   !  ��に増幅器の出力V5を、�イ�ら容量C2で ��に正帰還,・・・ V5=K*V4
   !  ��端子の電圧をV2,�C嫉劼療徹気�V3,�っ嫉劼療徹気�V4,�ッ嫉劼療徹気�V5
   !  総てアドミッタンスで計算。
   !  �´�,�↓�,����,�きづ� Gij(i=j)はその節点に接続されるアドミッタンスの和
   !  ��-��, ��-�� 等 Gij(i?j)は接続されてるアドミッタンスに-1を掛けて代入。
   !  Ampを除き、要素のみを考えると対称行列になり,ノードの数が行列の大きさ。
   !  行列は 5x5 だが V5=K*V4 を考えA(3,4)=-(1/R3)に A(3,5)=-ω*C2*jを加える
   !  Kは A(3,4)=-(1/R3)-K*ω*C2*j増幅器の出力 E5=K*E4の関係を入れA(3,5)を消す
   !  一方  A(4,3)=-(1/R3) とし非対称とした。A(4,3)=A(3,4)では不具合であった
   !  最終の行列は  4x4 の非対称に成るが、Kが直接指定できる利点があるようだ。
   !  結果はKの値に敏感で K=0.9875〜1.0125までで、K=1 が最適。K= 1.0125でピーク


   !方法-3
   !文献や投稿を参照

   !***********************方法-2の計算  今回はこれで挑戦*****************

   FOR K=0.9875 TO 1.0125 STEP 0.0125       !KはAMPのゲイン。
      FOR P=1 TO 57
         LET FF=FREQ(P,1)
         LET ω=(2*PI*FF)

         LET A(1,1)=(1/Rs)+(1/R1)           !�´|嫉劼離▲疋潺織鵐垢旅膩�
         LET A(1,2)=-(1/R1)                 !�´�端子のアドミタンスの -1

         LET A(1,3)=0
         LET A(1,4)=0

         LET A(2,1)=-(1/R1)
         LET A(2,2)=(1/R1)+(1/R2)+ω*C1*j  !�↓�端子のアドミタンスの合計
         LET A(2,3)=-(1/R2)
         LET A(2,4)=0

         LET A(3,1)=0
         LET A(3,2)=-(1/R2)
         LET A(3,3)=(1/R2)+(1/R3)+ω*C2*j  !���C嫉劼離▲疋潺織鵐垢旅膩�
         LET A(3,4)=-(1/R3)-K*ω*C2*j   !ここにKの値を入れ V5=K*V4 を反映。
         !ミルマンの定理を適用。
         LET A(4,1)=0
         LET A(4,2)=0
         LET A(4,3)=-(1/R3)                !A(3,4)とは値が異なる。
         LET A(4,4)=(1/R3)+ω*C3*j         !�きっ嫉劼離▲疋潺織鵐垢旅膩�

         LET B(1,1)=10   ! 電流源から10Aを流している。�|嫉劼�1Vになる。
         LET B(2,1)=0    ! キルヒホッフの法則から  ゼロである。
         LET B(3,1)=0    ! キルヒホッフの法則から  ゼロである。
         LET B(4,1)=0    ! キルヒホッフの法則から  ゼロである。
         MAT T=INV(A)
         MAT EOUT=T*B
         ! PRINT "FF=";FF
         ! MAT PRINT EOUT
         LET EE1=EOUT(1,1)
         LET EE2=EOUT(2,1)
         LET EE3=EOUT(3,1)
         LET EE4=EOUT(4,1)
         LET EE5=K*EOUT(4,1)
         PRINT
         LET FREQ(P,2)=20*LOG10(ABS(EE5))
         ! LET FREQ(P,3)=20*LOG10(ABS(EE3))
         LET  G5=(ATN(IM(EE5)/RE(EE5)))
         IF FF>750 THEN LET G5=G5-180
         IF G5>0 THEN LET G5=G5-180
         LET  FREQ(P,4)=G5
         ! LET  G3=(ATN(IM(EE3)/RE(EE3)))
         ! IF FF>750 THEN LET G3=G3-180
         ! LET  FREQ(P,5)=G3
      NEXT P
      PRINT "K=";K
      PRINT "番号   周波 数      E5         E3         θ5         θ3"
      FOR I=1 TO 57
         PRINT USING "###": I;
         PRINT USING " ###,###.#"  : FREQ(I,1);
         PRINT USING " ####.### dB": FREQ(I,2);
         PRINT USING " ####.### dB": FREQ(I,3);
         PRINT USING " ####.### 度": FREQ(I,4);
         PRINT USING " ####.### 度": FREQ(I,5)
      NEXT I

      !ここからは、山中様のグラフプログラムを参照。
      SET WINDOW 0.5,5.5, -55,5      !表示領域
      DRAW grid(1,5)                  ! 左端の目盛り
      FOR f=1 TO 6   !x軸が対数目盛 f=1 TO 5 で100k まで目盛る。
         SET COLOR 1 !1は黒色
  PLOT TEXT ,AT f-0.1,+0.15: mid$("10  100 1k  10k 100k ",4*(f-1)+1,4)
      NEXT f

      FOR f=1 TO 6   !y軸が直線目盛り
         SET COLOR 1 !1は黒色
  PLOT TEXT ,AT 0.8,-10*(f-1)-2: mid$("  0 -25 -50 -75 -100-125 ",4*(f-1)+1,4)
      NEXT f

      FOR I=1 TO 57 STEP 1 !周波数[Hz]
         SET COLOR 1
     PLOT LINES:LOG10(FREQ(I,1)) ,FREQ(I,2)/2.5; !利得[dB]
      NEXT I
      PLOT LINES

      !  FOR I=1 TO 57 STEP 1 !周波数[Hz]
      !     SET COLOR 5    !5は水色
      !     PLOT LINES: LOG10(FREQ(I,1)) ,FREQ(I,3)/2; !利得[dB]
      !  NEXT I
      !  PLOT LINES

      FOR I=1 TO 57 STEP 1 !位相角度[度]
         SET COLOR 4  !4は赤色
         PLOT LINES:LOG10(FREQ(I,1)) ,0.125*FREQ(I,4); !角度[度]
      NEXT I
      PLOT LINES

      !  FOR I=1 TO 57 STEP 1 !位相角度[度]
      !     SET COLOR 3   !3は緑色
      !     PLOT LINES:LOG10(FREQ(I,1)) ,0.25*FREQ(I,5); !角度[度]
      !  NEXT I
      !  PLOT LINES
      FOR f=1 TO 6     !y軸が直線目盛り
         SET COLOR 4
   PLOT TEXT ,AT 5.1,-10*(f-1)-2: mid$(" 0  -80 -160-240-320-400 ",4*(f-1)+1,4)
      NEXT f
      PRINT

   NEXT K   ! ここで,利得 Kを変化させる。

   !*******************************************************************
   !100 LET FF=1000
   !    PRINT 1/R1
   !    PRINT 1/R2
   !    PRINT 1/R3
   !    PRINT  Y1
   !    PRINT  Y2
   !    PRINT  Y3
   !   FOR I=1 TO NP      ! 白石様の御助言を参照。マトリクスのチェックをした。
   !      FOR J=1 TO NP
   !         LET Z=A(I,J)
   !         PRINT USING "(##.######### ":RE(Z);
   !         PRINT USING "##.#########)  ":IM(Z);
   !      NEXT J
   !      PRINT
   !   NEXT I
   !**********************************************************************

END
 

節点解析法について (3)

 投稿者:大熊 正  投稿日:2009年 2月 9日(月)12時12分3秒
返信・引用
  大熊です。
前回投稿したのですが、4X4行列が対称でないのが気に食わず、
5x5にし、そのうち4X4は対称で、5行目に一括して増幅器
の増幅度Kの関係を入れるように改良しました。
このようにすれば、入力ミスが少なく、後はマトリクスが自動で
答えを出してくれる・・・??。

敬具。

10 OPTION ARITHMETIC COMPLEX
   LET j=SQR(-1)
   OPTION BASE 1
   OPTION ANGLE DEGREES

   DIM FREQ(100,5)
   LET FREQ(1,1)=10
   LET FREQ(2,1)=12.25
   LET FREQ(3,1)=15
   LET FREQ(4,1)=17.32
   LET FREQ(5,1)=20
   LET FREQ(6,1)=24.5
   LET FREQ(7,1)=30
   LET FREQ(8,1)=34.6
   LET FREQ(9,1)=40
   LET FREQ(10,1)=50
   LET FREQ(11,1)=60
   LET FREQ(12,1)=70
   LET FREQ(13,1)=80
   LET FREQ(14,1)=90

   FOR I=1 TO 14
      LET P=I
      LET FREQ(I,1)=FREQ(P,1)
   NEXT I
   FOR I=15 TO 28
      LET P=I-14
      LET FREQ(I,1)=FREQ(P,1)*10
   NEXT I
   FOR I=29 TO 42
      LET P=I-28
      LET FREQ(I,1)=FREQ(P,1)*100
   NEXT I
   FOR I=43 TO 56
      LET P=I-42
      LET FREQ(I,1)=FREQ(P,1)*1000
   NEXT I
   LET FREQ(57,1)=100000

   ! FOR I=1 TO 57
   !    PRINT "FREQ(";I;",1)=";FREQ(I,1)
   ! NEXT I


   !                             ┌─C2─┬──────┐ 「注意」
   !                             │      │  ┌──┐  │   山中さんの回路と
   !                             │      └─┤-   │  │  1番端子番号が
   !                             │          │  K├─�エ� 小さい。
   !         ┌─�;�R1─�※�R2─��─R3─�え;�+   │  ↑ V5
   !         ↑  ↑V1    ↑V2    ↑V3    ↑V4└──┘  │
   !         Is  Rs      C1              C3            │
   !         ↑  │      │              │            │
   !         ┴─0───┴───────┴──────┴─
   !             │
   !             ≡アース
   !    GND=0 !アース
   !    V1=1V !入力端子�� Rs=0.1オームに定電流源Is から10A流して1V。
   !    V5=�� !出力端子�� V5=K*V4

20 ! CR 3段回路
   LET FF=1000             !Fの単位はヘルツ
   LET R1=51000            !Rの単位はオーム
   LET R2=82000
   LET R3=39000
   LET C1=0.00685/(10^6)   !Cの単位はuF,
   LET C2=0.022/(10^6)     !Cの単位はuF,
   LET C3=330/(10^12)      !Cの単位はPF,

   LET Y1=(2*PI*FF*C1)     !Yの単位はモー
   LET Y2=(2*PI*FF*C2)
   LET Y3=(2*PI*FF*C3)

   LET ω=(2*PI*FF)
   LET Rs=0.1    !Rsの単位はオーム      �,肇◆璽垢貌�れる。
   LET IS=10     !Isの単位はアムペア  Rsを1Vにする。

   LET NP=5
   DIM A(NP,NP)
   DIM T(NP,NP)

   DIM EOUT(NP,1)
   DIM B(NP,1)
   LET K=1

   !*********** データーと計算方法*****************
   !方法-1
   !  ミルマンの定理やキルヒホッフの法則なぞを多用、直接解く。

   !方法-2B
   !  回路の�|嫉劼肇◆璽拘屬�0.1オームの抵抗、アドミッタンスGsをとつける。
   !  電流源 10A を入力にして�|嫉劼肇◆璽拘屬痢�Gs)に加えて V1を約  1V。
   !  以下は、想定の回路につなげ、端子間のアドミッタンスを考え節点方程式。
   !  � 辞△�R1,�◆辞�にR2,�◆璽◆璽垢僕椴�C1,��ー�い�R3,�ぁ璽◆璽垢僕椴�
   !  C3、C3の電圧V4を増幅器に入力。�イ砲�V5=K*V4の電圧がでる。
   !  ��に増幅器の出力V5を、�イ�ら容量C2で ��に正帰還,・・・ V5=K*V4
   !  ��端子の電圧をV2,�C嫉劼療徹気�V3,�っ嫉劼療徹気�V4,�ッ嫉劼療徹気�V5
   !  総てアドミッタンスで計算。
   !  �´�,�↓�,����,�きづ� Gij(i=j)はその節点に接続されるアドミッタンス和
   !  ��-��, ��-�� 等 Gij(i?j)は接続されてるアドミッタンスに-1を掛けて代入
   !  Ampを除き、要素のみを考えると対称行列になり,ノードの数が行列の大きさ
   !  行列は 5x5 で4x4 の部分は対称に成る。 これが利点。
   !  行列の 5行目に E5=K*E4の関係をいれる。これが利点。
   !  Kは A(5,4)=-K   A(5,5)=1   B(5,1)=0  で増幅器の出力を関係付ける。
   !  最終の行列は  5x5 の非対称に成るが、Kが直接指定できる利点があるようだ
   !  結果はKの値に敏感で K=0.9875〜1.0125までで、K=1 が最適。


   !方法-3
   !文献や投稿を参照

   !***********************方法-2Bの計算  今回はこれで挑戦*****************

   FOR K=0.9875 TO 1.0125 STEP 0.0125       !KはAMPのゲイン。
      FOR P=1 TO 57
         LET FF=FREQ(P,1)
         LET ω=(2*PI*FF)

         LET A(1,1)=(1/Rs)+(1/R1)       !�´|嫉劼離▲疋潺織鵐垢旅膩�
         LET A(1,2)=-(1/R1)             !�´�端子のアドミタンスの -1
         LET A(1,3)=0
         LET A(1,4)=0
         LET A(1,5)=0

         LET A(2,1)=-(1/R1)
         LET A(2,2)=(1/R1)+(1/R2)+ω*C1*j  !�↓�端子のアドミタンスの合計
         LET A(2,3)=-(1/R2)
         LET A(2,4)=0
         LET A(2,5)=0

         LET A(3,1)=0
         LET A(3,2)=-(1/R2)
         LET A(3,3)=(1/R2)+(1/R3)+ω*C2*j!���C嫉劼離▲疋潺織鵐垢旅膩�
         LET A(3,4)=-(1/R3)   !A(4,3)と値が同じくし対称行列にする。
         LET A(3,5)=-ω*C2*j

         LET A(4,1)=0
         LET A(4,2)=0
         LET A(4,3)=-(1/R3)  !A(3,4)と値が同じくし対称行列にする。
         LET A(4,4)=(1/R3)+ω*C3*j !�きっ嫉劼離▲疋潺織鵐垢旅膩�
         LET A(4,5)=0

         LET A(5,1)=0
         LET A(5,2)=0
         LET A(5,3)=0
         LET A(5,4)=-K   ! ここにKの値を入れ V5=K*V4 を反映。
         LET A(5,5)=1    ! ここに1の値を入れ V5=K*V4 を反映。

         LET B(1,1)=10   ! 電流源から10Aを流す。�|嫉劼�1V。
         LET B(2,1)=0    ! キルヒホッフの法則から  ゼロである。
         LET B(3,1)=0    ! キルヒホッフの法則から  ゼロである。
         LET B(4,1)=0    ! キルヒホッフの法則から  ゼロである。
         LET B(5,1)=0    ! ここに0の値を入れ V5=K*V4 を反映。
         MAT T=INV(A)
         MAT EOUT=T*B
         ! PRINT "FF=";FF
         ! MAT PRINT EOUT
         LET EE1=EOUT(1,1)
         LET EE2=EOUT(2,1)
         LET EE3=EOUT(3,1)
         LET EE4=EOUT(4,1)
         LET EE5=EOUT(5,1)
         PRINT
         LET FREQ(P,2)=20*LOG10(ABS(EE5))
         ! LET FREQ(P,3)=20*LOG10(ABS(EE3))
         LET  G5=(ATN(IM(EE5)/RE(EE5)))
         IF FF>750 THEN LET G5=G5-180
         IF G5>0 THEN LET G5=G5-180
         LET  FREQ(P,4)=G5
         ! LET  G3=(ATN(IM(EE3)/RE(EE3)))
         ! IF FF>750 THEN LET G3=G3-180
         ! LET  FREQ(P,5)=G3
      NEXT P
      PRINT "K=";K
      PRINT "番号   周波 数      E5         E3         θ5         θ3"
      FOR I=1 TO 57
         PRINT USING "###": I;
         PRINT USING " ###,###.#"  : FREQ(I,1);
         PRINT USING " ####.### dB": FREQ(I,2);
         PRINT USING " ####.### dB": FREQ(I,3);
         PRINT USING " ####.### 度": FREQ(I,4);
         PRINT USING " ####.### 度": FREQ(I,5)
      NEXT I

      !ここからは、山中様のグラフプログラムを参照。
      SET WINDOW 0.5,5.5, -55,5      !表示領域
      DRAW grid(1,5)                  ! 左端の目盛り
      FOR f=1 TO 6   !x軸が対数目盛 f=1 TO 5 で100k まで目盛る。
         SET COLOR 1 !1は黒色
   PLOT TEXT ,AT f-0.1,+0.15: mid$("10  100 1k  10k 100k ",4*(f-1)+1,4)
      NEXT f

      FOR f=1 TO 6   !y軸が直線目盛り
         SET COLOR 1 !1は黒色
PLOT TEXT ,AT 0.8,-10*(f-1)-2: mid$("  0 -25 -50 -75 -100-125 ",4*(f-1)+1,4)
      NEXT f

      FOR I=1 TO 57 STEP 1 !周波数[Hz]
         SET COLOR 1
         PLOT LINES:LOG10(FREQ(I,1)) ,FREQ(I,2)/2.5; !利得[dB]
      NEXT I
      PLOT LINES

      !  FOR I=1 TO 57 STEP 1 !周波数[Hz]
      !     SET COLOR 5    !5は水色
      !     PLOT LINES: LOG10(FREQ(I,1)) ,FREQ(I,3)/2; !利得[dB]
      !  NEXT I
      !  PLOT LINES

      FOR I=1 TO 57 STEP 1 !位相角度[度]
         SET COLOR 4  !4は赤色
         PLOT LINES:LOG10(FREQ(I,1)) ,0.125*FREQ(I,4); !角度[度]
      NEXT I
      PLOT LINES

      !  FOR I=1 TO 57 STEP 1 !位相角度[度]
      !     SET COLOR 3   !3は緑色
      !     PLOT LINES:LOG10(FREQ(I,1)) ,0.25*FREQ(I,5); !角度[度]
      !  NEXT I
      !  PLOT LINES
      FOR f=1 TO 6     !y軸が直線目盛り
         SET COLOR 4
PLOT TEXT ,AT 5.1,-10*(f-1)-2: mid$(" 0  -80 -160-240-320-400 ",4*(f-1)+1,4)
      NEXT f
      PRINT
    NEXT K   ! ここで,利得 Kを変化させる。

END
 

コンデンサと、抵抗だけ?

 投稿者:SECOND  投稿日:2009年 2月 9日(月)12時48分25秒
返信・引用  編集済
  この回路で、700Hz 付近の、入出力電圧比を、計算して下さい。
きっと、信じられないことが、見つかります。
 

Re: コンデンサと、抵抗だけ?

 投稿者:大熊 正  投稿日:2009年 2月10日(火)10時18分37秒
返信・引用
  > No.268[元記事へ]

SECONDさんへのお返事です。

> この回路で、700Hz 付近の、入出力電圧比を、計算して下さい。
> きっと、信じられないことが、見つかります。

大熊です。
最近、習い覚えた節点方程式で解いたところ、確かに
700Hz付近で0.7dB 程度の盛り上がりが、ゆるやかに
ありました。
パッシブ素子のみで、トランスみたいな動作をするのは
確かに不思議です。

そこで御質問いたします。

(1)この回路は「???回路」として有名な回路なのですか。
(2)既に、なにかの製品に使われてるのでしょうか。

その他
(1)10進BASIC で既に作られた科学技術のソフトを 電気、
   土木、医療・・・・などと分類して登録してある
   インターネットの場所はありませんか。
   LINUX でそういうのが、ある事を最近知りました。
   10進BASIC でもあれば、皆が大層便利に使い発展に
   繋がると思います。

敬具
 

宣言可能な配列の大きさの上限

 投稿者:白石 和夫  投稿日:2009年 2月10日(火)11時28分54秒
返信・引用
  > No.252[元記事へ]

十進BASICが記憶領域として用いるメモリは大別してヒープとスタックの2種類があります。
スタックは,手続きの実行・終了にしたがって自動的に増減します。
ヒープは手続きの進行と非同期に確保・解放されます。
ヘルプの「言語使用の詳細」―「制限」の頁に記載されている「変数管理用メモリ」はスタックメモリに割り当てる領域です。

十進BASICは,
LET N=1000
DIM A(N)
のような拡張構文を許容するため,配列要素の実領域をヒープ上に確保します。
DIM B(1000)
のようにFull BASIC規格の範囲で宣言された配列はスタックメモリ上に確保できますが,
内部構造の複雑さを避けるためにどちらの形式の配列も配列要素はヒープ上に置いています。

配列を多用するプログラムを実行する場合には,変数管理用メモリを小さくとったほうが有利です。
しかし,ヒープから1回に取得できるメモリの大きさにはOS,開発言語および実行環境に由来する制限があります。
実装メモリ1GB(ビデオメモリを含む)のWindows XP機で,
BASIC.INIの[FRAME]セクションに
Virtualmemory=16
の記述を追加して実験すると,
10 OPTION ARITHMETIC NATIVE
20 DIM A(88000000)
30 END
程度が限界で,このプログラムを実行するとHDDへのスワップが発生します。
20行を A(90000000)に変えるとメモリ不足のエラーになります。
2進モードでは数値変数1個で8バイト占有するので,88000000個の変数は704MBに相当します。
なお,プログラムを実行すると,ヒープ領域のメモリの断片化が起こるので,プログラムの実行に成功したとき続けて要素数を増やしたプログラムを実行すると失敗する可能性が高くなります。成功した後の試行は,一旦,BASIC.EXEを終了・再起動後に行う必要があります。
また,このことは,プログラムの開発のために何度もプログラムの実行をくり返すような場面にもあてはまります。
 

Re: コンデンサと、抵抗だけ?

 投稿者:SECOND  投稿日:2009年 2月10日(火)20時01分34秒
返信・引用
  > No.269[元記事へ]

>(1)この回路は「???回路」として有名な回路なのですか。

  実は、このままでは、実用にならないのですが、もう1段のCRを追加し、
  CR3段型の昇圧回路にしたものが、50年も大昔(1962年以前)に、
  R−C カソード・ホロワ発振器 米国特許2769088
  ------------------------------------------------------------
  参考文献: エレクトロニクス エンジニアのための ラプラス変換
        ホルブルーク著 宮脇一男 訳(朝倉書店)
  ------------------------------------------------------------
  3段以上にすると、0移相での昇圧効果が得られ、ボルテージ・フォロアー
  のような、電圧利得<1 のバッファーだけで、出力インピーダンスの低い
  発振器が、作れます。
   (下記ベクトル図参照。直感的把握には、この方が解り易い。)

>(2)既に、なにかの製品に使われてるのでしょうか。

  殆んど知られていません。調べてはいませんが、もう時効だとも、思います。

>その他
>(1)10進BASIC で既に作られた科学技術のソフトを 電気、
   土木、医療・・・・などと分類して登録してある
   インターネットの場所はありませんか・・・

  それが、できるといいですね。複素数も使えない御本家よりは、
  「十進BASIC」の方がいいです。
 

Re: コンデンサと、抵抗だけ?(2)

 投稿者:大熊 正  投稿日:2009年 2月12日(木)14時21分48秒
返信・引用
  > No.271[元記事へ]

SECONDさんへのお返事です。

> >(1)この回路は「???回路」として有名な回路なのですか。
>
>   実は、このままでは、実用にならないのですが、もう1段のCRを追加し、
>   CR3段型の昇圧回路にしたものが、50年も大昔(1962年以前)に、
>   R−C カソード・ホロワ発振器 米国特許2769088
>   ------------------------------------------------------------
>   3段以上にすると、0移相での昇圧効果が得られ、ボルテージ・フォロアー
>   のような、電圧利得<1 のバッファーだけで、出力インピーダンスの低い
>   発振器が、作れます。
>

大熊 です。
勇を鼓して、3段に挑戦しました。1.225khz付近で0.9dbの盛り上がりでした。
何か、負荷が重いのだろうと、抵抗を図の下から1.5k,15k,150kと増やし、
容量を逆に下から0.1uF,0.01uF,0.001uFと減らすと、実に1.225khz付近で1.99db
の盛り上がりになりました。これなら発振しそうです。
・・・尚、2段でもこのようにすると、700HZ付近で1.153dbと増えました。


質問ですが
(1)発振器とは、何処とー何処を つなぐのでしょうか。
(2)其の時、マトリクスも答えがグジャグジャと止まらなく
   成るのでしょうか。・・・それで発振とする???。
(3)・・・別に方程式を作り時間で解くのでしょうか。
   このような時の方程式のサンプルを教えていただけると
   ありがたいのですが。

敬具
 

Re: コンデンサと、抵抗だけ?(2)

 投稿者:SECOND  投稿日:2009年 2月13日(金)00時43分30秒
返信・引用  編集済
  > No.272[元記事へ]

大熊 正さんへのお返事です。

プログラムではない為、ここに適当ではありませんが、ご参考に。

オペアンプ自体の周波数、位相特性が問題になるような高周波発振器でない場合、
帰還回路の計算だけで、十分だと思います。

発振条件は、ループゲイン1(0dB)、移相量は、0を含む2πの整数倍ですが、
0dB では、開始起動が、できない場合を含むため、ゲインを多めにします。
しかし、
正弦波が欲しい場合、起動の信頼性を確保する程度の少なめにしないと、
元々が、高調波を含んだ歪波なのに、益々正弦波形から、遠くなります。

どれくらい多目のゲインが適当かについて、数学的には1を越えてさえおれば、
いいのですが、実際のアンプの場合、無歪の正弦波を、維持するゲインに命中
させても、不安定で固定できません。出力振幅で、抵抗値の変化する素子を用い、
ゲインの自動制御をしない限り、正弦波は無理です。一般の発振器は、波形の尖頭
を、出力飽和に、ぶつける事で、安定を保っているため、必ず歪んでいます。

発振回路は、線型である限り、無限大か、減衰停止か、どちらかに流れますが、
計算上は、1周ループの伝達関数(出力/入力)を複素数で求め、
(実数部=1、虚数部=0)になる条件で、解としているようです。

下図は、CADで、発振させた例で、実物には、さらに、ダイナミック・レンジや、
直流バイアスを、検討します。(適当な参考書をさがして下さい。)
 

Re: コンデンサと、抵抗だけ?(2)

 投稿者:SECOND  投稿日:2009年 2月13日(金)06時08分54秒
返信・引用
  > No.273[元記事へ]

大熊 正さんへのお返事です。
<<追記>>
1KHz で、発振している帰還回路の特性が、下の様になっているのは、奇妙に
思えるかもしれません。発振している 1KHz 付近は、約 +0.1dB  +0.3deg.です。
昇圧の大きい部分は、位相角が2nπでなく、発振条件を、満たしていない。

0deg.でなく、やや進相ぎみなのは、OPアンプ内部の入出力インピーダンスが、
1MΩ, 100Ωになっていて、純粋な理想アンプではない事と、接続した事によって、
帰還回路の定数が、僅かに移動した為かと思います。
 

Re: コンデンサと、抵抗だけ?(2)

 投稿者:大熊 正  投稿日:2009年 2月13日(金)19時07分50秒
返信・引用
  > No.274[元記事へ]

SECONDさんへのお返事です。

> 大熊 正さんへのお返事です。
> <<追記>>
> 1KHz で、発振している帰還回路の特性が、下の様になっているのは、奇妙に
> 思えるかもしれません。発振している 1KHz 付近は、約 +0.1dB  +0.3deg.です。
> 昇圧の大きい部分は、位相角が2nπでなく、発振条件を、満たしていない。
>
> 0deg.でなく、やや進相ぎみなのは、OPアンプ内部の入出力インピーダンスが、
> 1MΩ, 100Ωになっていて、純粋な理想アンプではない事と、接続した事によって、
> 帰還回路の定数が、僅かに移動した為かと思います。


大熊です。
色々な図面を提示していただき有難うございます。
勉強しなければならぬことが実に多いことも
分りました。
今後とも御指導よろしく御願いいたします。

敬具
 

数値式文字列式評価

 投稿者:荒田浩二  投稿日:2009年 2月14日(土)00時14分36秒
返信・引用  編集済
 
十進BASICに添付されたサンプルプログラム"\BASICw32\SAMPLE\INTERPRE.bas"は数値式の評価を行います。
数値式を入力すると、その式の値を出力します。
それを次のように拡張しました。

(1) 数値定数
   小数点で始まる小数や、指数部のある数値も扱える。

(2) 組込み関数
   十進BASICの組込み関数は、配列や特殊な例を除きほとんど利用できる。

(3) 変数
   数値式に変数を使える。
   数値式内に変数を認識すると,変数名を表示し入力を求めてくる(中止は[中止]ボタンで)。
   変数への入力は数値式も可。ただし,この数値式に変数を含むことは不可。
    例) a^2+1 の変数a に[4],[-3/2],[8-3*5],[sqr(5)-1],[SIN(pi/6)]など入力可。[4*n+9]は不可。
   変数名の命名規則は十進BASICに準ずる(漢字可、PI,RND,MAXNUM,DATE,TIME,DATE$,TIME$以外の機能語も可)。
   配列には対応していない。

(4) 文字列式
   文字列式の評価も行える。その場合は入力する文字列式の先頭に「$=」を付ける。
    例) $=REPEAT$("aBc D",3) ; $="alphabet "&CHR$(64+Number) ; $="2*3+7="&STR$(2*3+7)
   文字列では大文字と小文字を区別する。空白も認識する。漢字も可。

(5) 文字列変数
   数値式や文字列式に、文字列変数を使用できる。
   文字列変数への入力は、文字列定数(前後の(")は不要)または文字列式が可。
   文字列変数に文字列式を入力する場合は先頭に「$=」を付ける。この文字列式に変数を含むことは不可。
    例) $=USING$(a$,800.52) のa$に[###],[$=REPEAT$("#",3)]など入力可。
    例) LEN(mj$&"yz") のmj$に[ab漢],[$=LTRIM$("  ab")&UCASE$"cd"]など入力可。[$="mn"&A$]は不可。
    例) VAL(c$)+7 のc$に[-2.5],[$=str$(1/2-3)]など入力可(-2.5は"-2.5"という文字列定数)。

(6) 部分文字列指定
   文字列変数に部分文字列指定ができる。
   ただし部分文字列指定より前に,同名の文字列変数が書かれている必要がある。
    例) $=a$&","&a$(3:5) ; $=UCASE$(cap$&"aBc")∩$(2:2-1+m) ; POS(r$,r$(k:k))
    誤入力例) $=box$(2:4)&","&box$
    修正例) $=REPEAT$(box$,0)&box$(2:4)&","&box$ ; $=SUBSTR$(box$,2,4)&","&box$

(7) ユーザー定義関数
   数値式に独自に定義した関数を使えるようにした。
   関数名は F1(a)、F2(a,b)、F3(a,b,c)、FS$(a$,b,c)。
   変数への入力にも使える。 例) SQR(r-4)+1 のrに[2*F2(3,7-5)]など入力可。
   この関数の定義部は1260行の後ろにあるので必要に応じて変更して下さい。再帰呼び出しも可能です。

入力例(関数名,変数名は大文字と小文字の区別はしない)
  2*.43+7E2  ;  MOD(10^2,int(MAX(7.4,sqr(10)+3)))-1  ;  sin(a)^2+cos(b)^2
  2*x^2-7*x+6  ;  1+INT(RND*n)  ;  INT(借入金*(1+年利/100)^年数)  ;  LEN("ab""cd ef gh")
  $=mj$&"xYz"&STR$(n)  ;  $=UCASE$(p$)&","&LCASE$(p$)  ;  $="0x"&BSTR$(Decimal,16)
  $=STR$(1/(2*a)*(-b+sqr(b^2-4*a*c)))&","&STR$((-b-sqr(b^2-4*a*c))/(2*a)) !2次方程式の2根
  $="a="&STR$(abs(m^2-n^2))&",b="&STR$(2*m*n)&",c="&STR$(m^2+n^2) !ピタゴラス数
  $=enter$&TIME$&USING$(".#",FP(TIME))  ;  m*f3(N-5,4,sqr(M))  ;  $=FS$("abc",x,6)&"."

目標としたのは「PRINT *******」で出力できる数値式、文字列式を網羅することでした。
配列以外は達成できたと思うのですがどうでしょう。
すべてをチェックしているわけでなく間違った数値式を入力してもエラー表示されないかもしれません。
不具合があれば報告お願いします。
REM 十進BASIC添付"\BASICw32\SAMPLE\INTERPRE.bas"に加筆
REM 行番号のない行が加筆部分。行番号は削除可。
1000 REM Full BASICのモジュールの使い方を示すサンプル
1010 REM
1020 REM 数値式の評価を行う
1030 REM 組込み関数は,SIN,COS,TAN, LOG, EXP, SQR, INT,ABSとPIのみ
1040 REM 大文字と小文字の区別はしない
1050 REM 数値式の文法はほぼFull BASICに準ずるが,関数名に続く括弧は空白を入れずに書く。
1060 REM 数値は,数字で始まり,コンマを1個以下含む数字の列としてのみ書ける。
1070 REM 零除算エラーなどは考慮していない。
1080 DECLARE EXTERNAL FUNCTION interpreter.expression  ! 数値式を評価する関数
1090 DECLARE EXTERNAL STRING interpreter.s$            ! 入力行
1100 DECLARE EXTERNAL NUMERIC interpreter.i            ! 入力行の文字位置
1110 DECLARE EXTERNAL SUB interpreter.skip             ! 空白文字を読み飛ばす副プログラム
     DECLARE EXTERNAL FUNCTION interpreter.str_expression$  !文字列式を評価する関数
     DECLARE EXTERNAL NUMERIC interpreter.vc,interpreter.sc !変数の個数(vc=数値,sc=文字列)
     DECLARE EXTERNAL SUB interpreter.error                 !エラーメッセージ
1120 LINE INPUT s$
1130 ! LET s$=UCASE$(s$) !文字列の小文字保持のため無効にした
     DO
        LET vc,sc=0
1140    LET i=1
1150    CALL skip
        IF s$(i:i)="$" THEN
           LET i=i+1
           CALL skip
           IF s$(i:i)="=" THEN
              LET i=i+1
              CALL skip
              PRINT str_expression$   ! 文字列式評価
           ELSE
              CALL error("$=")
           END IF
        ELSE
1160       PRINT expression   ! 数値式評価
        END IF
1170    IF i<>LEN(s$)+1 THEN PRINT "Syntax error" ! 比較式をi<LEN(s$)から変更
     LOOP UNTIL vc+sc=0 OR i<>LEN(s$)+1 ! 中止は[中止]ボタンで
1180 END
1190 !
1200 MODULE interpreter
  ! MODULE OPTION ARITHMETIC NATIVE ! DECIMAL_HIGH,COMPLEX,RATIONAL 数値オプション
1210 PUBLIC STRING s$
1220 PUBLIC NUMERIC i
1230 PUBLIC FUNCTION expression
1240 PUBLIC SUB skip
1250 SHARE FUNCTION term,factor,primary,numeric
     PUBLIC FUNCTION str_expression$
     PUBLIC NUMERIC vc,sc
     PUBLIC SUB error
     SHARE FUNCTION check,argument,rounding,position,bitval,v_chr,variable
     SHARE FUNCTION str_primary$,str_constant$,str_naming$,sub_string$,str_input$,bitstr$
     SHARE NUMERIC vari_val(20),inputv   ! 20=変数の個数
     SHARE STRING sn$,vari_name$(20),string$(20),str_name$(20)
     SHARE FUNCTION F1,F2,F3,FS$  !!! ユーザー定義関数
     ! MODULE OPTION ANGLE DEGREES  ! 角の大きさの単位
     ! MODULE OPTION CHARACTER BYTE ! 文字列処理の単位
     LET inputv=0
1260 !
     EXTERNAL FUNCTION F1(a)      !!! ユーザー定義関数
        let F1=a
     END FUNCTION
     EXTERNAL FUNCTION F2(a,b)    !!! ユーザー定義関数
        let F2=a+b
     END FUNCTION
     EXTERNAL FUNCTION F3(a,b,c)  !!! ユーザー定義関数
        let F3=a+b+c
     END FUNCTION
     EXTERNAL FUNCTION FS$(a$,b,c)  !!! ユーザー定義関数
        let FS$=a$&str$(b)&str$(c)
     END FUNCTION
     !
1270 EXTERNAL SUB skip
1280    DO WHILE s$(i:i)=" "
1290       LET i=i+1
1300    LOOP
1310 END SUB
1320 !
1330 EXTERNAL FUNCTION expression
1340    DECLARE NUMERIC n
1350    DECLARE STRING op$
1360    SELECT CASE s$(i:i)
1370    CASE "-"
1380       LET i=i+1
1390       CALL skip
1400       LET n=-term
1410    CASE "+"
1420       LET i=i+1
1430       CALL skip
1440       LET n=term
1450    CASE ELSE
1460       LET n=term
1470    END SELECT
1480    DO WHILE s$(i:i)="+" OR s$(i:i)="-"
1490       LET op$=s$(i:i)
1500       LET i=i+1
1510       CALL skip
1520       IF op$="+" THEN LET n=n+term ELSE LET n=n-term
1530    LOOP
1540    LET expression =n
1550    CALL skip
1560 END FUNCTION
1570 !
1580 EXTERNAL FUNCTION term
1590    DECLARE NUMERIC n
1600    DECLARE STRING op$
1610    LET n=factor
1620    DO WHILE s$(i:i)="*" OR s$(i:i)="/"
1630       LET op$=s$(i:i)
1640       LET i=i+1
1650       CALL skip
1660       IF op$="*" THEN LET n=n*factor ELSE LET n=n/factor
1670    LOOP
1680    LET term=n
1690 END FUNCTION
1700 !
1710 EXTERNAL FUNCTION factor
1720    DECLARE NUMERIC n
1730    LET n=primary
1740    DO WHILE s$(i:i)="^"
1750       LET i=i+1
1760       CALL skip
1770       LET n=n^primary
1780    LOOP
1790    LET factor=n
1800 END FUNCTION
1810 !
1820 EXTERNAL FUNCTION primary
1830    IF s$(i:i)>="0" AND s$(i:i)<="9" THEN
1840       LET  primary=numeric
        ELSEIF s$(i:i)="." THEN
           LET  primary=numeric
1850    ELSEIF UCASE$(s$(i:i+1))="PI" AND check(s$(i+2:i+2))=1 THEN ! 関数check加筆
1860       LET i=i+2
1870       CALL skip
1880       LET primary=PI  ! 有理数モード注意
        ELSEIF UCASE$(s$(i:i+2))="RND" AND check(s$(i+3:i+3))=1 THEN
           LET i=i+3
           CALL skip
           LET primary=RND ! 変数入力がある数値式では都度更新
        ELSEIF UCASE$(s$(i:i+3))="TIME" AND check(s$(i+4:i+4))=1 THEN
           LET i=i+4
           CALL skip
           LET primary=TIME ! 変数入力がある数値式では都度更新
        ELSEIF UCASE$(s$(i:i+3))="DATE" AND check(s$(i+4:i+4))=1 THEN
           LET i=i+4
           CALL skip
           LET primary=DATE ! 変数入力がある数値式では都度更新
           !ELSEIF UCASE$(s$(i:i+5))="MAXNUM" AND check(s$(i+6:i+6))=1 THEN
           !   LET i=i+6
           !   CALL skip
           !   LET primary=MAXNUM  ! 有理数モード不可
1890    ELSE
1900       IF s$(i:i)="(" THEN
1910          LET i=i+1
1920          CALL skip
1930          LET  primary=expression
           ELSEIF UCASE$(s$(i:i+2))="F1(" THEN   !!! ユーザー定義関数
              LET i=i+3
              CALL skip
              LET Primary=F1(expression)
           ELSEIF UCASE$(s$(i:i+2))="F2(" THEN   !!! ユーザー定義関数
              LET i=i+3
              CALL skip
              LET primary=F2(expression,argument)
           ELSEIF UCASE$(s$(i:i+2))="F3(" THEN   !!! ユーザー定義関数
              LET i=i+3
              CALL skip
              LET primary=F3(expression,argument,argument)
1940       ELSEIF UCASE$(s$(i:i+3))="SIN(" THEN ! 超越関数
1950          LET i=i+4
1960          CALL skip
1970          LET Primary=SIN(expression)
1980       ELSEIF UCASE$(s$(i:i+3))="COS(" THEN ! 超越関数
1990          LET i=i+4
2000          CALL skip
2010          LET Primary=COS(expression)
2020       ELSEIF UCASE$(s$(i:i+3))="TAN(" THEN ! 超越関数
2030          LET i=i+4
2040          CALL skip
2050          LET Primary=TAN(expression)
2060       ELSEIF UCASE$(s$(i:i+3))="LOG(" THEN ! 超越関数
2070          LET i=i+4
2080          CALL skip
2090          LET Primary=LOG(expression)
2100       ELSEIF UCASE$(s$(i:i+3))="EXP(" THEN ! 超越関数
2110          LET i=i+4
2120          CALL skip
2130          LET Primary=EXP(expression)
2140       ELSEIF UCASE$(s$(i:i+3))="SQR(" THEN ! 有理数モード注意
2150          LET i=i+4
2160          CALL skip
2170          LET Primary=SQR(expression)
2180       ELSEIF UCASE$(s$(i:i+3))="INT(" THEN
2190          LET i=i+4
2200          CALL skip
2210          LET Primary=INT(expression)
2220       ELSEIF UCASE$(s$(i:i+3))="ABS(" THEN
2230          LET i=i+4
2240          CALL skip
2250          LET Primary=ABS(expression)
           ELSEIF UCASE$(s$(i:i+3))="MOD(" THEN
              LET i=i+4
              CALL skip
              LET primary=MOD(expression,argument)
           ELSEIF UCASE$(s$(i:i+5))="ROUND(" THEN
              LET i=i+6
              CALL skip
              LET primary=rounding
           ELSEIF UCASE$(s$(i:i+4))="CEIL(" THEN
              LET i=i+5
              CALL skip
              LET Primary=CEIL(expression)
           ELSEIF UCASE$(s$(i:i+3))="SGN(" THEN
              LET i=i+4
              CALL skip
              LET Primary=SGN(expression)
           ELSEIF UCASE$(s$(i:i+2))="IP(" THEN
              LET i=i+3
              CALL skip
              LET Primary=IP(expression)
           ELSEIF UCASE$(s$(i:i+2))="FP(" THEN
              LET i=i+3
              CALL skip
              LET Primary=FP(expression)
           ELSEIF UCASE$(s$(i:i+9))="REMAINDER(" THEN
              LET i=i+10
              CALL skip
              LET primary=REMAINDER(expression,argument)
           ELSEIF UCASE$(s$(i:i+8))="TRUNCATE(" THEN
              LET i=i+9
              CALL skip
              LET primary=TRUNCATE(expression,argument)
           ELSEIF UCASE$(s$(i:i+4))="LOG2(" THEN ! 超越関数
              LET i=i+5
              CALL skip
              LET Primary=LOG2(expression)
           ELSEIF UCASE$(s$(i:i+5))="LOG10(" THEN ! 超越関数
              LET i=i+6
              CALL skip
              LET Primary=LOG10(expression)
           ELSEIF UCASE$(s$(i:i+3))="CSC(" THEN ! 超越関数
              LET i=i+4
              CALL skip
              LET Primary=CSC(expression)
           ELSEIF UCASE$(s$(i:i+3))="SEC(" THEN ! 超越関数
              LET i=i+4
              CALL skip
              LET Primary=SEC(expression)
           ELSEIF UCASE$(s$(i:i+3))="COT(" THEN ! 超越関数
              LET i=i+4
              CALL skip
              LET Primary=COT(expression)
           ELSEIF UCASE$(s$(i:i+4))="ASIN(" THEN ! 超越関数
              LET i=i+5
              CALL skip
              LET Primary=ASIN(expression)
           ELSEIF UCASE$(s$(i:i+4))="ACOS(" THEN ! 超越関数
              LET i=i+5
              CALL skip
              LET Primary=ACOS(expression)
           ELSEIF UCASE$(s$(i:i+3))="ATN(" THEN ! 超越関数
              LET i=i+4
              CALL skip
              LET Primary=ATN(expression)
           ELSEIF UCASE$(s$(i:i+5))="ANGLE(" THEN ! 超越関数
              LET i=i+6
              CALL skip
              LET primary=ANGLE(expression,argument)
           ELSEIF UCASE$(s$(i:i+4))="SINH(" THEN ! 超越関数
              LET i=i+5
              CALL skip
              LET Primary=SINH(expression)
           ELSEIF UCASE$(s$(i:i+4))="COSH(" THEN ! 超越関数
              LET i=i+5
              CALL skip
              LET Primary=COSH(expression)
           ELSEIF UCASE$(s$(i:i+4))="TANH(" THEN ! 超越関数
              LET i=i+5
              CALL skip
              LET Primary=TANH(expression)
              !ELSEIF UCASE$(s$(i:i+3))="EPS(" THEN ! 有理数モード不可
              !   LET i=i+4
              !   CALL skip
              !   LET Primary=EPS(expression)
           ELSEIF UCASE$(s$(i:i+3))="DEG(" THEN
              LET i=i+4
              CALL skip
              LET Primary=DEG(expression)
           ELSEIF UCASE$(s$(i:i+3))="RAD(" THEN
              LET i=i+4
              CALL skip
              LET Primary=RAD(expression)
           ELSEIF UCASE$(s$(i:i+3))="MAX(" THEN
              LET i=i+4
              CALL skip
              LET primary=MAX(expression,argument)
           ELSEIF UCASE$(s$(i:i+3))="MIN(" THEN
              LET i=i+4
              CALL skip
              LET primary=MIN(expression,argument)
           ELSEIF UCASE$(s$(i:i+4))="FACT(" THEN !十進BASIC独自拡張
              LET i=i+5
              CALL skip
              LET Primary=FACT(expression)
           ELSEIF UCASE$(s$(i:i+4))="PERM(" THEN !十進BASIC独自拡張
              LET i=i+5
              CALL skip
              LET primary=PERM(expression,argument)
           ELSEIF UCASE$(s$(i:i+4))="COMB(" THEN !十進BASIC独自拡張
              LET i=i+5
              CALL skip
              LET primary=COMB(expression,argument)
           ELSEIF UCASE$(s$(i:i+10))="COLORINDEX(" THEN !十進BASIC独自拡張
              LET i=i+11
              CALL skip
              LET primary=COLORINDEX(expression,argument,argument)
              !ELSEIF UCASE$(s$(i:i+7))="COMPLEX(" THEN !複素関数
              !   LET i=i+8
              !   CALL skip
              !   LET primary=COMPLEX(expression,argument)
              !ELSEIF UCASE$(s$(i:i+2))="RE(" THEN      !複素関数
              !   LET i=i+3
              !   CALL skip
              !   LET Primary=RE(expression)
              !ELSEIF UCASE$(s$(i:i+2))="IM(" THEN      !複素関数
              !   LET i=i+3
              !   CALL skip
              !   LET Primary=IM(expression)
              !ELSEIF UCASE$(s$(i:i+4))="CONJ(" THEN    !複素関数
              !   LET i=i+5
              !   CALL skip
              !   LET Primary=CONJ(expression)
              !ELSEIF UCASE$(s$(i:i+3))="ARG(" THEN     !複素関数
              !   LET i=i+4
              !   CALL skip
              !   LET Primary=ARG(expression)
              !ELSEIF UCASE$(s$(i:i+5))="NUMER(" THEN   !有理数モード専用
              !   LET i=i+6
              !   CALL skip
              !   LET Primary=NUMER(expression)
              !ELSEIF UCASE$(s$(i:i+5))="DENOM(" THEN   !有理数モード専用
              !   LET i=i+6
              !   CALL skip
              !   LET Primary=DENOM(expression)
              !ELSEIF UCASE$(s$(i:i+3))="GCD(" THEN     !有理数モード専用
              !   LET i=i+4
              !   CALL skip
              !   LET primary=GCD(expression,argument)
              !ELSEIF UCASE$(s$(i:i+6))="INTSQR(" THEN  !有理数モード専用
              !   LET i=i+7
              !   CALL skip
              !   LET Primary=INTSQR(expression)
              !ELSEIF UCASE$(s$(i:i+7))="INTLOG2(" THEN !有理数モード専用
              !   LET i=i+8
              !   CALL skip
              !   LET Primary=INTLOG2(expression)
           ELSEIF UCASE$(s$(i:i+3))="LEN(" THEN
              LET i=i+4
              CALL skip
              LET primary=LEN(str_expression$)
           ELSEIF UCASE$(s$(i:i+3))="POS(" THEN
              LET i=i+4
              CALL skip
              LET primary=position
           ELSEIF UCASE$(s$(i:i+3))="VAL(" THEN
              LET i=i+4
              CALL skip
              LET primary=VAL(str_expression$)
           ELSEIF UCASE$(s$(i:i+3))="ORD(" THEN
              LET i=i+4
              CALL skip
              LET primary=ORD(str_expression$)
           ELSEIF UCASE$(s$(i:i+4))="BVAL(" THEN
              LET i=i+5
              CALL skip
              LET primary=bitval
           ELSEIF UCASE$(s$(i:i+4))="BLEN(" THEN !十進BASIC独自拡張
              LET i=i+5
              CALL skip
              LET primary=BLEN(str_expression$)
           ELSEIF v_chr(s$(i:i))=1 THEN
              LET primary=variable    !  変数
              CALL skip
              EXIT FUNCTION
2260       ELSE
              CALL error("FUNCTION primary")
2270          PRINT "Syntax error"
2280          STOP
2290       END IF
2300       IF s$(i:i)=")" THEN
2310          LET i=i+1
2320          CALL skip
2330       ELSE
              CALL error("FUNCTION primary")
2340          PRINT "Syntax error"
2350          STOP
2360       END IF
2370    END IF
2380 END FUNCTION
2390 !
2400 EXTERNAL FUNCTION numeric
2410    DECLARE NUMERIC i0
2420    CALL skip
2430    LET i0=i
        IF s$(i:i)="." THEN ! 小数点で始まる
           LET i=i+1
        ELSE
2440       DO WHILE s$(i:i)>="0" AND s$(i:i)<="9"
2450          LET i=i+1
2460       LOOP
2470       IF s$(i:i)="." THEN LET i=i+1
        END IF
2480    DO WHILE s$(i:i)>="0" AND s$(i:i)<="9"
2490       LET i=i+1
2500    LOOP
        IF LEN(s$)>=i AND UCASE$(s$(i:i))="E" THEN ! 指数部
           LET i=i+1
           IF s$(i:i)="+" OR s$(i:i)="-" THEN LET i=i+1
           DO WHILE s$(i:i)>="0" AND s$(i:i)<="9"
              LET i=i+1
           LOOP
        END IF
2510    LET numeric=VAL(s$(i0:i-1))
2520    CALL skip
2530 END FUNCTION
2540 !
![その2]へ続く
 

Re: 数値式文字列式評価[その2]

 投稿者:荒田浩二  投稿日:2009年 2月14日(土)00時18分47秒
返信・引用
  > No.276[元記事へ]

! [その2]
  !  *以下すべて加筆部分*
     EXTERNAL FUNCTION check(c$) !! 予約語の後続字
        DECLARE STRING p$
        LET check=-1
        DO
           READ IF MISSING THEN EXIT DO : p$
           IF c$=p$ THEN LET check=1
        LOOP
        DATA " " , "+" , "-" , "*" , "/" , "^" , "," , ")" , ""
     END FUNCTION
     !
     EXTERNAL FUNCTION argument !! 引数
        CALL skip
        IF s$(i:i)="," THEN
           LET i=i+1
           CALL skip
        ELSE
           CALL error("FUNCTION argument,引数")
        END IF
        LET argument=expression
     END FUNCTION
     !
     EXTERNAL FUNCTION rounding  !! 関数ROUNDの識別
        DECLARE NUMERIC a
        LET a=expression
        IF s$(i:i)="," THEN
           LET i=i+1
           CALL skip
           LET rounding=ROUND(a,expression)
        ELSEIF s$(i:i)=")" THEN
           LET rounding=ROUND(a) ! 十進BASIC独自拡張
        ELSE
           CALL error("FUNCTION rounding,関数ROUND")
        END IF
     END FUNCTION
     !
     EXTERNAL FUNCTION position  !! 関数POSの識別
        DECLARE STRING aa$,bb$
        LET aa$=str_expression$
        IF s$(i:i)="," THEN
           LET i=i+1
           CALL skip
           LET bb$=str_expression$
           IF s$(i:i)=")" THEN
              LET position=POS(aa$,bb$)
           ELSEIF s$(i:i)="," THEN
              LET i=i+1
              CALL skip
              LET position=POS(aa$,bb$,expression)
           ELSE
              CALL error("FUNCTION position,関数POS")
           END IF
        ELSE
           CALL error("FUNCTION position,関数POS")
        END IF
     END FUNCTION
     !
     EXTERNAL FUNCTION bitval   !! 関数BVALの識別
        DECLARE STRING aa$
        LET aa$=str_primary$
        IF s$(i:i)="," THEN
           LET i=i+1
           CALL skip
           IF s$(i:i)="2" THEN
              LET i=i+1
              CALL skip
              LET bitval=BVAL(aa$,2)
           ELSEIF s$(i:i+1)="16" THEN
              LET i=i+2
              CALL skip
              LET bitval=BVAL(aa$,16)
           ELSE
              CALL error("FUNCTION bitval,関数BVAL")
           END IF
        ELSE
           CALL error("FUNCTION bitval,関数BVAL")
        END IF
     END FUNCTION
     !
     EXTERNAL FUNCTION v_chr(c$)   !! 変数名文字
        IF c$>="A" AND c$<="Z" OR c$>="a" AND c$<="z" OR c$>="ぁ" THEN !先頭文字及びそれ以降
           LET v_chr=1
        ELSEIF c$>="0" AND c$<="9" OR c$="_" OR c$>="0" THEN ! 2文字目以降
           LET v_chr=2
        ELSE
           LET v_chr=-1
        END IF
     END FUNCTION
     !
     EXTERNAL FUNCTION variable   !! 変数
        DECLARE NUMERIC j,vi
        DECLARE STRING vn$,aa$,vs$
        LET vn$=""
        DO WHILE v_chr(s$(i:i))>=1
           LET vn$=vn$&s$(i:i)
           LET i=i+1
        LOOP
        FOR j=1 TO vc
           IF UCASE$(vn$)=UCASE$(vari_name$(j)) THEN
              LET variable=vari_val(j)  ! 既出の変数
              EXIT FUNCTION
           END IF
        NEXT j
        LET vc=vc+1
        LET vari_name$(vc)=vn$
        IF inputv=0 THEN
           DO
              LINE INPUT PROMPT vn$&"=" : aa$ ! 変数への入力
           LOOP UNTIL aa$<>""
        ELSE
           CALL error("FUNCTION variable,変数入力")
        END IF
        LET vs$=s$
        LET vi=i
        LET s$=LTRIM$(aa$)
        LET i=1
        LET inputv=1
        LET vari_val(vc)=expression ! 変数に入力した数値式の処理
        LET inputv=0
        LET s$=vs$
        LET i=vi
        LET variable=vari_val(vc)
     END FUNCTION
     !
     !
     EXTERNAL FUNCTION str_expression$ !! 文字列式
        DECLARE STRING str_n$
        LET str_n$=str_primary$
        DO WHILE s$(i:i)="&"
           LET i=i+1
           CALL skip
           LET str_n$=str_n$&str_primary$
        LOOP
        LET str_expression$ =str_n$
        CALL skip
     END FUNCTION
     !
     EXTERNAL FUNCTION str_primary$ !! 文字列一次子
        DECLARE NUMERIC j
        IF s$(i:i)="""" THEN
           LET i=i+1
           LET str_primary$=str_constant$
        ELSEIF UCASE$(s$(i:i+4))="DATE$" THEN
           LET i=i+5
           CALL skip
           LET str_primary$=DATE$  !変数入力がある数値式では都度更新
        ELSEIF UCASE$(s$(i:i+4))="TIME$" THEN
           LET i=i+5
           CALL skip
           LET str_primary$=TIME$  !変数入力がある数値式では都度更新
        ELSE
           IF v_chr(s$(i:i))=1 THEN
              LET sn$=str_naming$ ! 文字列関数/変数名
              FOR j=1 TO sc
                 IF UCASE$(sn$)=UCASE$(str_name$(j)) THEN
                    CALL skip
                    IF s$(i:i)="(" THEN
                       LET i=i+1
                       CALL skip
                       LET str_primary$=sub_string$(string$(j)) !部分文字列
                    ELSE
                       LET str_primary$=string$(j)  ! 既出の文字列変数
                    END IF
                    EXIT FUNCTION
                 END IF
              NEXT j
           ELSE
              CALL error("FUNCTION str_primary$,文字列一次子")
           END IF
           SELECT CASE UCASE$(sn$)&s$(i:i)
           CASE "FS$("    !!! ユーザー定義関数
              LET i=i+1
              CALL skip
              LET str_primary$=FS$(str_expression$,argument,argument)
           CASE "REPEAT$("
              LET i=i+1
              CALL skip
              LET str_primary$=REPEAT$(str_expression$,argument)
           CASE "STR$("
              LET i=i+1
              CALL skip
              LET str_primary$=STR$(expression)
           CASE "USING$("
              LET i=i+1
              CALL skip
              LET str_primary$=USING$(str_expression$,argument)
           CASE "CHR$("
              LET i=i+1
              CALL skip
              LET str_primary$=CHR$(expression)
           CASE "LCASE$("
              LET i=i+1
              CALL skip
              LET str_primary$=LCASE$(str_expression$)
           CASE "UCASE$("
              LET i=i+1
              CALL skip
              LET str_primary$=UCASE$(str_expression$)
           CASE "LTRIM$("
              LET i=i+1
              CALL skip
              LET str_primary$=LTRIM$(str_expression$)
           CASE "RTRIM$("
              LET i=i+1
              CALL skip
              LET str_primary$=RTRIM$(str_expression$)
           CASE "BSTR$("
              LET i=i+1
              CALL skip
              LET str_primary$=bitstr$
           CASE "SUBSTR$(" ! 十進BASIC独自拡張
              LET i=i+1
              CALL skip
              LET str_primary$=SUBSTR$(str_expression$,argument,argument)
           CASE "MID$("    ! 十進BASIC独自拡張
              LET i=i+1
              CALL skip
              LET str_primary$=MID$(str_expression$,argument,argument)
           CASE "LEFT$("   ! 十進BASIC独自拡張
              LET i=i+1
              CALL skip
              LET str_primary$=LEFT$(str_expression$,argument)
           CASE "RIGHT$("  ! 十進BASIC独自拡張
              LET i=i+1
              CALL skip
              LET str_primary$=RIGHT$(str_expression$,argument)
           CASE ELSE
              LET str_primary$=str_input$ ! 文字列入力
              CALL skip
              EXIT FUNCTION
           END SELECT
           IF s$(i:i)=")" THEN
              LET i=i+1
              CALL skip
           ELSE
              CALL error("FUNCTION str_primary$")
           END IF
        END IF
     END FUNCTION
     !
     EXTERNAL FUNCTION str_constant$  !! 文字列定数
        DECLARE STRING cc$
        LET cc$=""
        DO
           IF s$(i:i)="""" THEN
              IF s$(i+1:i+1)="""" THEN ! [""]の識別
                 LET cc$=cc$&s$(i:i)
                 LET i=i+2
              ELSE
                 LET i=i+1
                 EXIT DO
              END IF
           ELSE
              LET cc$=cc$&s$(i:i)
              LET i=i+1
              IF i>LEN(s$)+1 THEN
                 CALL error("FUNCTION str_constant$,文字列定数")
                 EXIT DO
              END IF
           END IF
        LOOP
        CALL skip
        LET str_constant$=cc$
     END FUNCTION
     !
     EXTERNAL FUNCTION str_naming$ !! 文字列関数/変数名
        LET sn$=""
        DO WHILE v_chr(s$(i:i))>=1
           LET sn$=sn$&s$(i:i)
           LET i=i+1
        LOOP
        IF s$(i:i)="$" THEN
           LET str_naming$=sn$&s$(i:i)
           LET i=i+1
        ELSE
           CALL error("FUNCTION str_naming$,文字列関数/変数名")
        END IF
     END FUNCTION
     !
     EXTERNAL FUNCTION sub_string$(ss$)  !! 部分文字列
        DECLARE NUMERIC a
        LET a=expression
        IF s$(i:i)=":" THEN
           LET i=i+1
           CALL skip
           LET sub_string$=ss$(a:expression)
           IF s$(i:i)=")" THEN
              LET i=i+1
              CALL skip
           ELSE
              CALL error("FUNCTION sub_string$,部分文字列")
           END IF
        ELSE
           CALL error("FUNCTION sub_string$,部分文字列")
        END IF
     END FUNCTION
     !
     EXTERNAL FUNCTION str_input$  !! 文字列入力
        DECLARE NUMERIC j,vi
        DECLARE STRING vs$
        LET sc=sc+1
        LET str_name$(sc)=sn$
        IF inputv=0 THEN
           LINE INPUT PROMPT sn$&"=" : string$(sc)
        ELSE
           CALL error("FUNCTION str_input$,文字列入力")
        END IF
        LET j=1
        DO WHILE string$(sc)(j:j)=" "
           LET j=j+1
        LOOP
        IF string$(sc)(j:j)="$" THEN
           LET j=j+1
           DO WHILE string$(sc)(j:j)=" "
              LET j=j+1
           LOOP
           IF string$(sc)(j:j)="=" THEN
              LET vs$=s$
              LET vi=i
              LET s$=string$(sc)(j+1:LEN(string$(sc)))
              LET s$=LTRIM$(s$)
              LET i=1
              LET inputv=1
              LET string$(sc)=str_expression$ ! 文字列変数に入力した文字列式の処理
              LET inputv=0
              LET s$=vs$
              LET i=vi
           END IF
        END IF
        LET str_input$=string$(sc)
     END FUNCTION
     !
     EXTERNAL FUNCTION bitstr$   !! 関数BSTR$の識別
        DECLARE NUMERIC a
        LET a=expression
        IF s$(i:i)="," THEN
           LET i=i+1
           CALL skip
           IF s$(i:i)="2" THEN
              LET i=i+1
              CALL skip
              LET bitstr$=BSTR$(a,2)
           ELSEIF s$(i:i+1)="16" THEN
              LET i=i+2
              CALL skip
              LET bitstr$=BSTR$(a,16)
           ELSE
              CALL error("FUNCTION bitstr$,関数BSTR$")
           END IF
        ELSE
           CALL error("FUNCTION bitstr$,関数BSTR$")
        END IF
     END FUNCTION
     !
     EXTERNAL SUB error(e$)  !! エラー表示
        PRINT "Error (";e$;")"
        !STOP
     END SUB
     !
2550 END MODULE
 
 

伝達関数によるフィルタ回路の周波数解析、過渡解析

 投稿者:山中和義  投稿日:2009年 2月16日(月)11時47分59秒
返信・引用
  ●伝達関数による周波数解析
OPTION ARITHMETIC COMPLEX

LET j=SQR(-1) !虚数単位

LET f=60 !周波数[Hz]
DEF w=2*PI*f !角周波数ω

SUB DispS(z) !複素数をS表示する ※スタインメッツ(Steinmetz)
   PRINT ABS(z);
   IF ABS(z)<>0 THEN
      IF arg(z)<>0 THEN PRINT "∠";DEG(arg(z));"°";
   END IF
   PRINT
END SUB
!-------------------- ここまでがサブルーチン


!---------- ↓↓↓↓↓ ----------
LET xmax=6 !<----- ※要調整
LET ymin=-50
LET ymax=5


!●回路図 CRローパス・フィルタ
!vi・─R1┬─・vo
!    C1
!     │
!    ≡
! 参考サイト http://sim.okawa-denshi.jp/CRlowkeisan.htm

LET R1=1.6e3 !1.6k[Ω]
LET C1=0.1e-6 !0.1μ[F]

DEF G(s)=1/(s*C1*R1+1) !入出力システムの伝達関数 G(s)=Vo/Vi=(1/(C1*R1))/(s+1/(C1*R1))
!---------- ↑↑↑↑↑ ----------


!!!SET bitmap SIZE 600,600 !画面を大きくする
SET WINDOW -0.5,xmax+0.5, ymin,ymax !表示領域
DRAW grid(1,5) !左端の目盛り

FOR f=1 TO xmax !x軸が対数
   PLOT TEXT ,AT f-0.3,-0.15: mid$("10  100 1k  10k 100k1M  10M 100M",4*(f-1)+1,4)
NEXT f

FOR xx=0 TO xmax STEP 0.025 !周波数[Hz]
   LET f=10^xx !xx=LOG10(f)
   LET t=ABS(G(j*w))
   PLOT LINES: xx,20*LOG10(t); !利得[dB]
NEXT xx
PLOT LINES


SET TEXT COLOR 2
FOR k=ymax TO ymin STEP -5 !右端の縦軸目盛り
   PLOT TEXT ,AT xmax,k: STR$(k*2)&"°" !※利得のグラフに合わせるために2倍する
NEXT k

SET LINE COLOR 2
FOR xx=0 TO xmax STEP 0.05 !周波数[Hz]
   LET f=10^xx
   LET th=arg(G(j*w))
   IF th>0 THEN LET th=th-2*PI !0〜-2πへ補正する <----- ※要調整
   PLOT LINES: xx,DEG(th)/2; !位相θ[deg] ※利得のグラフに合わせるために1/2倍する
NEXT xx
PLOT LINES


END


●伝達関数による過渡解析
OPTION ARITHMETIC COMPLEX

DECLARE EXTERNAL SUB IFFT !逆フーリエ変換

DEF C(s)=G(s)*R(s) !応答関数
DEF R(s)=1/s !指令関数 ※ステップ関数

LET Vi=1 !1∠0°[V] ※仮の電圧源


!----- ↓↓↓↓↓ -----
LET T=2e-3 !時間区間 [0,T]


!●回路図 CRローパス・フィルタ
!vi・─R1┬─・vo
!    C1
!     │
!    ≡
! 参考サイト http://sim.okawa-denshi.jp/CRlowkeisan.htm

LET R1=1.6e3 !1.6k[Ω]
LET C1=0.1e-6 !0.1μ[F]

DEF G(s)=1/(s*C1*R1+1) !入出力システムの伝達関数 G(s)=Vo/Vi=(1/(C1*R1))/(s+1/(C1*R1))
!----- ↑↑↑↑↑ -----


!逆ラプラス変換
! f(t)=lim [ω→∞] { 1/(2π*j)∫F(s)*Exp(s*t)ds [γ-j*ω,γ+j*ω] }、jは虚数単位、γ>0とωは実数。
!s=γ+j*2πωとすると、ds=j*2πdω。
!これを上式に代入して、変形すると、
! f(t)=Exp(γt)∫F(γ,ω)*Exp(j*2πω)dω [-∞,∞]
!右辺の積分部分は逆フーリエ変換。

LET N=1024*8 !データ総数 ※2のべき乗、大きいほど精度がよい
DIM d(0 TO N-1) !入出力用配列

LET Gamma=5 !※3〜7
!γを大きくすれば精度は上がりそうだが、
!あとでExp(γt)をかけるので、tが大きいところで発散する。

LET rr=Gamma/T !γを決める

FOR k=0 TO N/2 !変換データの作成
   LET Cs=C( COMPLEX(rr, 2*PI*k/T) ) !sk=γ+j*2π*k/T、k=0〜n-1
   LET Hw=(COS(2*PI*k/N)+1)/2 !データは離散なため、ハニング関数をかけて平滑化する ※精度の向上
   LET d(k)=N/T*Cs*Hw !n/T*Y(k) * Hw 0〜N/2

   IF NOT(k=0 OR k=N/2) THEN LET d(N-k)=COMPLEX(Re(d(k)),-Im(d(k))) !N-1〜N/2+1は、共役複素数
NEXT k


CALL IFFT(d) !高速逆フーリエ変換


SET WINDOW -T/8,T,-Vi*1.2,Vi*1.2 !表示領域
DRAW grid(T/4,Vi/5)

PLOT TEXT ,AT T*7/8,0: "[秒]"

LET dt=T/N !時間刻み幅 ��t

FOR k=0 TO N-1 STEP 8 !結果の表示 [0,T]
   LET tt=k*dt !経過時間
   PLOT LINES: tt, Re(d(k))*EXP(rr*tt); !Exp(γt)をかける ※Exp(γ*k*T/n)、k=0〜n-1
   PRINT Re(d(k))*EXP(rr*tt) !debug
NEXT k


END



EXTERNAL SUB IFFT(x()) !高速逆フーリエ変換 x() : 入力/出力データ
OPTION ARITHMETIC COMPLEX
DECLARE EXTERNAL SUB FFTMAIN
LET nx=SIZE(x)
LET theta=2*PI/nx ! W = Exp(-j * 2π/N * -1) = Exp(j * theta)とする
CALL FFTMAIN(x, theta)
MAT x=(1/nx)*x
END SUB

EXTERNAL SUB FFTMAIN(x(), theta)
OPTION ARITHMETIC COMPLEX
LET nx=SIZE(x)
IF MOD(nx, 2)<>0 THEN !DFTの計算
   DIM w(0 TO nx-1), xtmp(0 TO nx-1)
   MAT xtmp=x
   FOR k=0 TO nx-1
      LET tmp=theta*k
      FOR n=0 TO nx-1
         LET w(n)=EXP( COMPLEX(0, tmp*n) )
      NEXT n
      LET x(k)=DOT(w, xtmp)
   NEXT k
ELSE !2分して再帰呼出し
   LET hnx=nx/2
   DIM x0(0 TO hnx-1), x1(0 TO hnx-1)
   FOR k=0 TO hnx-1
      LET x0(k)=x(k)+x(k+hnx)
      LET wk=EXP( COMPLEX(0, theta*k) )
      LET x1(k)=wk*(x(k)-x(k+hnx))
   NEXT k
   CALL FFTMAIN(x0, 2*theta)
   CALL FFTMAIN(x1, 2*theta)
   FOR k=0 TO hnx-1
      LET x(2*k)=x0(k)
      LET x(2*k+1)=x1(k)
   NEXT k
END IF
END SUB
 

Re: 伝達関数によるフィルタ回路の周波数解析、過渡解析

 投稿者:山中和義  投稿日:2009年 2月16日(月)14時51分17秒
返信・引用  編集済
  > No.278[元記事へ]

伝達関数は、閉路方程式や節点方程式などで記述された連立方程式から導かれる。

差し替え
!●回路図 CRローパス・フィルタ
!vi・─R1┬─・vo
!    C1
!     │
!    ≡
! 参考サイト http://sim.okawa-denshi.jp/CRlowkeisan.htm

LET R1=1.6e3 !1.6k[Ω]
LET C1=0.1e-6 !0.1μ[F]

DEF G(s)=1/(s*C1*R1+1) !入出力システムの伝達関数 G(s)=Vo/Vi=(1/(C1*R1))/(s+1/(C1*R1))
!---------- ↑↑↑↑↑ ----------


この箇所を下記のプログラムに置き換える。

LET Vi=1 !1∠0°[V] ※仮の電圧源

FUNCTION Laplace(e$,Z,s) !ラプラス変換
   SELECT CASE UCASE$(e$)
   CASE "R"
      LET Laplace=Z !R*i(t)
   CASE "L"
      LET Laplace=s*Z !L*d{i(t)}/dt
   CASE "C"
      LET Laplace=1/(s*Z) !1/C*∫{i(t)}dt
   CASE ELSE
      PRINT "未サポートの素子です。"
      STOP
   END SELECT
END FUNCTION


!●回路図 CRローパス・フィルタ
!    a
!vi・─R1┬─・vo
!    C2
!     │
!    ≡
! 参考サイト http://sim.okawa-denshi.jp/CRlowkeisan.htm

!----- ↓↓↓↓↓ -----
LET M=2 !素子の数
!----- ↑↑↑↑↑ -----

DIM A(M,M),x(M),b(M) !A*x=b ※Z(s)*I(s)=E(s)
DIM iA(M,M)

FUNCTION G(s) !伝達関数
   MAT A=ZER !A(式の番号,素子の番号) ※下記の設定で0は省略するため、あらかじめ0を入れておく
   MAT b=ZER !b(式の番号) ※電流または電圧の和

   !---------- ↓↓↓↓↓ ----------
   LET R1=Laplace("R",1.6e3,s) !1.6k[Ω]
   LET C2=Laplace("C",0.1e-6,s) !0.1μ[F]


   !キルヒホッフの電流則
   LET A(1,1)=1 !節点a i1(t)-i2(t)=0 ⇒ I1(s)-I2(s)=0
   LET A(1,2)=-1

   !キルヒホッフの電圧則
   LET A(2,1)=R1 !網目 R1*i1(t) +1/C2*∫i2(t)dt =Vi(t) ⇒ R1*I1(s)+1/(s*C2)*I2(s)=Vi(s)
   LET A(2,2)=C2
   LET b(2)=Vi
   !---------- ↑↑↑↑↑ ----------

   MAT iA=INV(A)
   MAT x=iA*b !各素子の電流I(s)を求める
   !!!mat print x


   !---------- ↓↓↓↓↓ ----------
   LET Vo=C2*x(2) ! Vo(t)=1/C2*∫i2(t)dt ⇒ Vo(s)=1/(s*C2)*I2(s)
   !---------- ↑↑↑↑↑ ----------

   LET G=Vo/Vi
END FUNCTION
!---------- ↑↑↑↑↑ ----------
 

Re: コンデンサと、抵抗だけ?(2)

 投稿者:SECOND  投稿日:2009年 2月17日(火)03時16分38秒
返信・引用  編集済
  > No.273[元記事へ]

<<補足事項>>
”計算上は、1周ループの伝達関数(出力/入力)を複素数で求め、
(実数部=1、虚数部=0)になる条件で、解としている・・・ ”について、

自分で計算したものでは、ありませんが、
該当の3段型CR昇圧回路の伝達関数です。( R =R1=R2=R3, C =C1=C2=C3 )

ZT(s)=(1+5*R*C*s+6*R^2*C^2*s^2)/(1+5*R*C*s+6*R^2*C^2*s^2 + R^3*C^3*c^3)←誤り
ZT(s)=(1+5*R*C*s+6*R^2*C^2*s^2)/(1+5*R*C*s+6*R^2*C^2*s^2 + R^3*C^3*s^3)←正(09/2/25)

-----------------------------------
以下は、我流の理解なため、間違いがあるかもしれません。参考程度に御容赦。

電圧で考える場合の、
伝達関数( 出力電圧/入力電圧 ) を求める時、LCR素子のインピーダンスを、
sL, 1/sC , R
jωL, 1/jωC, R  のどちらを用いて表現すると、何が解るかを、考えます。

sL 1/sC  R とする意味。(s=σ+jω の複素数)

 ・・・回路電流を、I'(t)=(初期位相電流)*exp(st) に前提したときの、電圧降下の係数。

L の電圧降下=  L * dI'(t)/dt =L*s*I'(t)     = sL * I'(t)
C の電圧降下=(1/C)* ∫ I'(t)dt =(1/C)*(1/s )*I'(t) =(1/sC) * I'(t)
R の電圧降下=  R * I'(t)

jωL 1/jωC R とする意味。

 ・・・回路電流を、I(t)=(初期位相電流)*exp(jωt) に前提したときの、電圧降下の係数。

L の電圧降下=  L * dI(t)/dt =L*jω*I(t)     = jωL * I(t)
C の電圧降下=(1/C)* ∫ I(t)dt =(1/C)*(1/jω)*I(t) =(1/jωC) * I(t)
R の電圧降下=  R * I(t)


-------- 発振回路の場合 -----------
これらのインピーダンスを用いて、電圧入出力の比(伝達関数)を作り、

伝達関数ZT() の入出力を接続し、ループを作ったときの状態を、次の式で表現します。
(OPアンプも中に含めておく)
伝達関数ZT(s)=1
伝達関数ZT(jω)=1

この方程式から出てくる根sや、解のjωは、どんな意味を持つか。

外部入力の無い状態で、内部に回路電流
I'(t)=(初期位相電流)*exp(st) 又は、I(t)=(初期位相電流)*exp(jωt)

なる電流が、自立できる事を、意味します。sの実数部が正なら、角速度ωで発振です
伝達関数ZT()=1 の解 s、jωは、(初期位相電流)については、何らの制限もしていません。

ここで、伝達関数ZT(jω)=1 の方は、解が無い可能性があります。

I(t)=(初期位相電流)*exp(jωt) なる
定常的な回路内電流を前提しているため、伝達関数ZT(jω)=1 は、初期値の自由度を除くと、
その解の電流は、1つの定常的な、波形電流だけです。

発振器のように、ループ内に、成長する振動電流が、時間と伴に発達しているなら、
ループ内電流を、(初期位相電流)*exp(jωt) 形式で、表現出来ないためでしょう。

-------------------------------------
1つの波形は、定常的な複数の単振動、(初期位相電流)*exp(jωt) が集まる合成波
ですから、
jωを、σ+jωの様な、実数部σを持つ複素数sを用いて、
回路内電流を、I'(t)=(初期位相電流)*exp(st) に、前提すると、

各スペクトルは、独立にその振幅も変化させる事が出来、スペクトラムの時間変化を表現
する事が可能となり、2つの異なる波形への変遷が、記述出来るでしょう。
即ち、過渡的な電流波形をも、伝達関数ZT(s)=1 は、解として持てる事を、意味します。

これが、sを使用するインピーダンス概念が、jωより好まれ、優れている点です。
-------------------------------------

※現在、時間がキツイために、以上についての質問は、しないで下さい。すみません。
 

Re: 伝達関数によるフィルタ回路の周波数解析、過渡解析

 投稿者:大熊 正  投稿日:2009年 2月17日(火)12時23分48秒
返信・引用
  > No.279[元記事へ]

山中和義さんへのお返事です。

> 伝達関数は、閉路方程式や節点方程式などで記述された連立方程式から導かれる。
>
> 差し替え
>
> <PRE>
>
> !●回路図 CRローパス・フィルタ
> !vi・─R1┬─・vo
> !    C1
> !     │
> !    ≡
> ! 参考サイト http://sim.okawa-denshi.jp/CRlowkeisan.htm
>
> LET R1=1.6e3 !1.6k[Ω]
> LET C1=0.1e-6 !0.1μ[F]
>
> DEF G(s)=1/(s*C1*R1+1) !入出力システムの伝達関数 G(s)=Vo/Vi=(1/(C1*R1))/(s+1/(C1*R1))
> !---------- ↑↑↑↑↑ ----------
> </PRE>
>
>
> この箇所を下記のプログラムに置き換える。
>
>
> <PRE>
>
> LET Vi=1 !1∠0°[V] ※仮の電圧源
>
> FUNCTION Laplace(e$,Z,s) !ラプラス変換
>    SELECT CASE UCASE$(e$)
>    CASE "R"
>       LET Laplace=Z !R*i(t)
>    CASE "L"
>
> !●回路図 CRローパス・フィルタ
> !    a
> !vi・─R1┬─・vo
> !    C2
> !     │
> !    ≡
> ! 参考サイト http://sim.okawa-denshi.jp/CRlowkeisan.htm
>
> !----- ↓↓↓↓↓ -----
> LET M=2 !素子の数
> !----- ↑↑↑↑↑ -----
>
> DIM A(M,M),x(M),b(M) !A*x=b ※Z(s)*I(s)=E(s)
> DIM iA(M,M)
>
>    !---------- ↓↓↓↓↓ ----------
>    LET Vo=C2*x(2) ! Vo(t)=1/C2*∫i2(t)dt ⇒ Vo(s)=1/(s*C2)*I2(s)
>    !---------- ↑↑↑↑↑ ----------
>
>    LET G=Vo/Vi
> END FUNCTION
> !---------- ↑↑↑↑↑ ----------

*****************************

大熊です。
コピーして差し替えましたが最後の下記の部分
    LET G=Vo/Vi
END FUNCTION
!---------- ↑↑↑↑↑ ----------


LET G=Vo/Vi で「Gは関数名 文法上の誤り」と出て動きません。

敬具
 

Re: 伝達関数によるフィルタ回路の周波数解析、過渡解析

 投稿者:山中和義  投稿日:2009年 2月17日(火)13時09分15秒
返信・引用
  > No.281[元記事へ]

大熊 正さんへのお返事です。

> LET G=Vo/Vi で「Gは関数名 文法上の誤り」と出て動きません。

うまく切り貼りができていないようなので、最初のプログラムに差し替えたものを掲載します。
OPTION ARITHMETIC COMPLEX

LET j=SQR(-1) !虚数単位

LET f=60 !周波数[Hz]
DEF w=2*PI*f !角周波数ω

SUB DispS(z) !複素数をS表示する ※スタインメッツ(Steinmetz)
   PRINT ABS(z);
   IF ABS(z)<>0 THEN
      IF arg(z)<>0 THEN PRINT "∠";DEG(arg(z));"°";
   END IF
   PRINT
END SUB
!-------------------- ここまでがサブルーチン


!---------- ↓↓↓↓↓ ----------
LET xmax=6 !<----- ※要調整
LET ymin=-50
LET ymax=5


LET Vi=1 !1∠0°[V] ※仮の電圧源

FUNCTION Laplace(e$,Z,s) !ラプラス変換
   SELECT CASE UCASE$(e$)
   CASE "R"
      LET Laplace=Z !R*i(t)
   CASE "L"
      LET Laplace=s*Z !L*d{i(t)}/dt
   CASE "C"
      LET Laplace=1/(s*Z) !1/C*∫{i(t)}dt
   CASE ELSE
      PRINT "未サポートの素子です。"
      STOP
   END SELECT
END FUNCTION


!●回路図 CRローパス・フィルタ
!    a
!vi・─R1┬─・vo
!    C2
!     │
!    ≡
! 参考サイト http://sim.okawa-denshi.jp/CRlowkeisan.htm

!----- ↓↓↓↓↓ -----
LET M=2 !素子の数
!----- ↑↑↑↑↑ -----

DIM A(M,M),x(M),b(M) !A*x=b ※Z(s)*I(s)=E(s)
DIM iA(M,M)

FUNCTION G(s) !伝達関数
   MAT A=ZER !A(式の番号,素子の番号) ※下記の設定で0は省略するため、あらかじめ0を入れておく
   MAT b=ZER !b(式の番号) ※電流または電圧の和

   !---------- ↓↓↓↓↓ ----------
   LET R1=Laplace("R",1.6e3,s) !1.6k[Ω]
   LET C2=Laplace("C",0.1e-6,s) !0.1μ[F]


   !キルヒホッフの電流則
   LET A(1,1)=1 !節点a i1(t)-i2(t)=0 ⇒ I1(s)-I2(s)=0
   LET A(1,2)=-1

   !キルヒホッフの電圧則
   LET A(2,1)=R1 !網目 R1*i1(t) +1/C2*∫i2(t)dt =Vi(t) ⇒ R1*I1(s)+1/(s*C2)*I2(s)=Vi(s)
   LET A(2,2)=C2
   LET b(2)=Vi
   !---------- ↑↑↑↑↑ ----------

   MAT iA=INV(A)
   MAT x=iA*b !各素子の電流I(s)を求める
   !!!mat print x


   !---------- ↓↓↓↓↓ ----------
   LET Vo=C2*x(2) ! Vo(t)=1/C2*∫i2(t)dt ⇒ Vo(s)=1/(s*C2)*I2(s)
   !---------- ↑↑↑↑↑ ----------

   LET G=Vo/Vi
END FUNCTION
!---------- ↑↑↑↑↑ ----------


!!!SET bitmap SIZE 600,600 !画面を大きくする
SET WINDOW -0.5,xmax+0.5, ymin,ymax !表示領域
DRAW grid(1,5) !左端の目盛り

FOR f=1 TO xmax !x軸が対数
   PLOT TEXT ,AT f-0.3,-0.15: mid$("10  100 1k  10k 100k1M  10M 100M",4*(f-1)+1,4)
NEXT f

FOR xx=0 TO xmax STEP 0.025 !周波数[Hz]
   LET f=10^xx !xx=LOG10(f)
   LET t=ABS(G(j*w))
   PLOT LINES: xx,20*LOG10(t); !利得[dB]
NEXT xx
PLOT LINES


SET TEXT COLOR 2
FOR k=ymax TO ymin STEP -5 !右端の縦軸目盛り
   PLOT TEXT ,AT xmax,k: STR$(k*2)&"°" !※利得のグラフに合わせるために2倍する
NEXT k

SET LINE COLOR 2
FOR xx=0 TO xmax STEP 0.05 !周波数[Hz]
   LET f=10^xx
   LET th=arg(G(j*w))
   IF th>0 THEN LET th=th-2*PI !0〜-2πへ補正する <----- ※要調整
   PLOT LINES: xx,DEG(th)/2; !位相θ[deg] ※利得のグラフに合わせるために1/2倍する
NEXT xx
PLOT LINES


END
 

Re: 伝達関数によるフィルタ回路の周波数解析、過渡解析

 投稿者:大熊 正  投稿日:2009年 2月18日(水)10時54分41秒
返信・引用
  > No.282[元記事へ]

山中和義さんへのお返事です。

> 大熊 正さんへのお返事です。
>
> > LET G=Vo/Vi で「Gは関数名 文法上の誤り」と出て動きません。
>
> うまく切り貼りができていないようなので、最初のプログラムに差し替えたものを掲載します。
>
>

大熊です。
今度はすぐ上手く動きました。お忙しい中、有難うございました。

過渡特性のプログラムも、こういうのが在ったらいいな・・・
と思っていた矢先でした。今後も大事に使わせていただきます。

敬具
 

Re: 節点解析法について (3)

 投稿者:SECOND  投稿日:2009年 2月19日(木)11時24分57秒
返信・引用  編集済
  > No.267[元記事へ]

大熊 正さんへのお返事です。

! Rsを付加するのは、良くありません。
! 下の2つの回路は、同じものです。テブナンの定理を。
!                             ┌─C2─┬──────┐
!                             │      │  ┌──┐  │
!                             │      └─┤-   │  │
!                             │          │    ├─�エ�
!             ┌─R1─�;�R2─�※�R3─��─┤+   │  ↑ V5
!             ↑      ↑V1    ↑V2    ↑V3└──┘  │
!             Vin     C1              C3     K=1    │
!             │      │              │            │
!             0───┴───────┴──────┴─
!
! |(1/R1)+(1/R2)+ω*C1*j -(1/R2)               0                | |V1| |Vin/R1|
! |-(1/R2)               (1/R2)+(1/R3)+ω*C2*j -(1/R3)-K*ω*C2*j| |V2|=| 0    |
! |0                     -(1/R3)               (1/R3)+ω*C3*j   | |V3| | 0    |
!

!                             ┌─C2─┬──────┐
!                             │      │  ┌──┐  │
!                             │      └─┤-   │  │
!         ┌─────┐      │          │    ├─�エ�
!         │ ┌─R1─�;�R2─�※�R3─��─┤+   │  ↑ V5
!         ↑  │      ↑V1    ↑V2    ↑V3└──┘  │
!   Is=Vin/R1 │      C1              C3     K=1    │
!         ↑  │      │              │            │
!         ┴─0───┴───────┴──────┴─
!
! K≒1は、ボルテージフォロアとしての利得で、AMP自体の電圧利得は、10E6 程度に極めて大きい。
! 回路上で、K<>1にするには、
! V5〜Amp(-in)間に、減衰器を挿入→ K>1、減衰器出力内部抵抗は、大きくても可。
! V5〜C2 間に、減衰器を挿入→ K<1、減衰器出力内部抵抗は、十分に小さい事。
!
OPTION ANGLE DEGREES
OPTION ARITHMETIC COMPLEX
LET j=COMPLEX(0,1)
LET NP=3
DIM FREQ(57,5), A(NP,NP), T(NP,NP), EOUT(NP,1), B(NP,1)
!----
! 周波数10Hz~100KHz、等比ステップ
FOR i=1 TO 57
   LET FREQ(i,1)=10^(1+4*(i-1)/56)
NEXT i
!----
! CR 3段回路
LET R1=51000            !Ω
LET R2=82000            !Ω
LET R3=39000            !Ω
LET C1=0.00685/(10^6)   !F
LET C2=0.022/(10^6)     !F
LET C3=330/(10^12)      !F
!----
SET WINDOW 0.5,5.5, -55,5
DRAW grid(1,5)
FOR K=1-0.0125 TO 1.0125 STEP 0.0125
   FOR P=1 TO 57
      LET ω=(2*PI*FREQ(P,1))
      !
      LET A(1,1)=(1/R1)+(1/R2)+j*ω*C1
      LET A(1,2)=-(1/R2)
      LET A(1,3)=0
      !
      LET A(2,1)=-(1/R2)
      LET A(2,2)=(1/R2)+(1/R3)+j*ω*C2
      LET A(2,3)=-(1/R3)-K*j*ω*C2
      !
      LET A(3,1)=0
      LET A(3,2)=-(1/R3)
      LET A(3,3)=(1/R3)+j*ω*C3
      !
      LET Vin=1           !1V
      LET B(1,1)=(Vin/R1) !電圧源Vin 直列抵抗R1を、電流源Vin/R1 並列抵抗R1 に変形。
      LET B(2,1)=0
      LET B(3,1)=0
      MAT T=INV(A)
      MAT EOUT=T*B
      LET EE1=EOUT(1,1)
      LET EE2=EOUT(2,1)
      LET EE3=EOUT(3,1)
      !
      LET Gv=K*EOUT(3,1)/Vin
      LET FREQ(P,2)=20*LOG10(ABS(Gv))
      LET Pv=arg(Gv)
      IF Pv>0 THEN LET Pv=Pv-360
      LET  FREQ(P,4)=Pv
   NEXT P
   !------
   !リスト
   PRINT "K=";K
   PRINT "番号   周波数      E5         θ5"
   FOR i=1 TO 57
      PRINT USING "###": i;
      PRINT USING " ###,###.#"  : FREQ(i,1);
      PRINT USING " ####.### dB": FREQ(i,2);
      PRINT USING " ####.### 度": FREQ(i,4)
   NEXT i
   !------
   !グラフ
   FOR f=1 TO 6
      SET TEXT COLOR "black"
      PLOT TEXT ,AT f-0.1, 1: mid$("10  100 1k  10k 100k ",4*(f-1)+1,4) !x軸 10Hz^100kHz
      PLOT TEXT ,AT 0.8,-10*(f-1)-2: mid$("  0 -25 -50 -75 -100-125 ",4*(f-1)+1,4) !左y軸 0~-125dB
      SET TEXT COLOR "red"
      PLOT TEXT ,AT 5.1,-10*(f-1)-2: mid$(" 0  -80 -160-240-320-400 ",4*(f-1)+1,4) !右y軸 0~-400°
   NEXT f
   SET LINE COLOR "black"
   FOR i=1 TO 57
      PLOT LINES:LOG10(FREQ(i,1)) ,FREQ(i,2)/2.5; !利得[dB]
   NEXT i
   PLOT LINES
   SET LINE COLOR "red"
   FOR i=1 TO 57
      PLOT LINES:LOG10(FREQ(i,1)) ,0.125*FREQ(i,4); !位相角度[度]
   NEXT i
   PLOT LINES
NEXT K

END
 

Re: 節点解析法について (3)

 投稿者:大熊 正  投稿日:2009年 2月20日(金)14時06分15秒
返信・引用
  > No.284[元記事へ]

SECONDさんへのお返事です。

> ! Rsを付加するのは、良くありません。
> ! 下の2つの回路は、同じものです。テブナンの定理を。

> !
> ! |(1/R1)+(1/R2)+ω*C1*j -(1/R2)               0                | |V1| |Vin/R1|
> ! |-(1/R2)               (1/R2)+(1/R3)+ω*C2*j -(1/R3)-K*ω*C2*j| |V2|=| 0    |
> ! |0                     -(1/R3)               (1/R3)+ω*C3*j   | |V3| | 0    |
> !

> !                             ┌─C2─┬──────┐
> !                             │      │  ┌──┐  │
> !                             │      └─┤-   │  │
> !         ┌─────┐      │          │    ├─�エ�
> !         │ ┌─R1─�;�R2─�※�R3─��─┤+   │  ↑ V5
> !         ↑  │      ↑V1    ↑V2    ↑V3└──┘  │
> !   Is=Vin/R1 │      C1              C3     K=1    │
> !         ↑  │      │              │            │
> !         ┴─0───┴───────┴──────┴─
> !
> LET NP=3
> DIM FREQ(57,5), A(NP,NP), T(NP,NP), EOUT(NP,1), B(NP,1)
> !----
> ! 周波数10Hz~100KHz、等比ステップ
> FOR i=1 TO 57
>    LET FREQ(i,1)=10^(1+4*(i-1)/56)
> NEXT i
> !----
>

大熊 です。

お忙しいところ、色々御検討頂きまして有難うございます。
(1)入力にRsが無くてもよいことや、
(2)周波数10Hz~100KHz、等比ステップでプログラムが
   簡素に綺麗になることなど勉強させていただきました。

このプラグラムをコピーして、直ぐに動かしました。
綺麗にグラフを描いてくれました。
本当に有難うございます。
今後とも御指導のほどよろしくお願いいたします。


敬具
 

式の評価、もう1つの拡張

 投稿者:山中和義  投稿日:2009年 2月20日(金)15時39分28秒
返信・引用  編集済
  「数の組」に対する「式の評価(計算)」ができるように次の拡張を行った。
・構文解析と演算との部分を分離
・FUNCTION文では返り値を1つのみのため、SUB文で記述

「数の組」とは
  関数、変数、定数の通常の数式の場合、「値」(1つ)
  有理数の場合、「分子と分母」(2つ)
  複素数の場合、「実数部と虚数部」(2つ)
  ベクトル、行列の場合、「要素列」(n個)
  1変数多項式の係数が整数の場合、「係数列」(n個)
 とする。


記述例 1変数多項式の係数が整数の場合

!式(中置記法)の評価 - 1変数多項式の係数が整数の場合 ※UBASIC相当

DECLARE EXTERNAL SUB expr.eval

!LET s$="(x-2)*(x-3)*(x-4)*(x-5)"
LET s$="(x^2-2*x+3)^2"
!LET s$="(x^5-5*x^3+5*x^2-1)/(x^2+3*x+1)" !商 x^3-3*x^2+3*x-1、余り 0
!LET s$="mod(2*x^3-13*x^2-26*x-15,x^2-2*x+3)" !商 2*x-9、余り -50*x+12
!LET s$="gcd(3*x^2+5*x-2,3*x^2-7*x+2)" !12*x-4 { 3*x-1 }
!LET s$="lcm(3*x^2+5*x-2,3*x^2-7*x+2)" !3/4*x^3-1/4*x^2-3*x+1 { (x+2)*(x-2)*(3*x-1) }
!LET s$="lcm(x^3-16*x,x^3-8*x^2+16*x)"


DIM a(0 TO 8) !係数 a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
CALL eval(s$, a,rc) !式

MAT PRINT a; !x^0,x^1,x^2, … の順 debug

IF rc=0 THEN CALL poly_disp(a) !結果を表示する

END



MODULE expr

PUBLIC NUMERIC p,ErrNo !共通変数

!●解析部分

!下位の共通ルーチン
EXTERNAL FUNCTION token$(s$) !1文字読み込む
   CALL EatSpace(s$)
   IF p<=LEN(s$) THEN LET token$=s$(p:p) ELSE LET token$=""
END FUNCTION

EXTERNAL SUB EatSpace(s$) !空白を読み飛ばす
   DO WHILE s$(p:p)=" " AND p<=LEN(s$)
      LET p=p+1
   LOOP
END SUB

EXTERNAL SUB CheckToken(s$,L$) !文字を確認する
   CALL EatSpace(s$)
   IF UCASE$(s$(p:p+LEN(L$)-1))<>L$ THEN CALL Error(L$&"がありません。")
   LET p=p+LEN(L$) !eat it
END SUB

EXTERNAL SUB Error(x$) !メッセージを表示する
   PRINT
   PRINT x$; p

   LET errNo=1
END SUB


!上位ルーチン
PUBLIC SUB eval
EXTERNAL SUB eval(s$, v(),rc) !式の評価
   LET errNo=0 !エラーコード
   LET p=1 !文字列へのポインタ
   CALL expression(s$, v) !計算する
   LET rc=errNo
END SUB

EXTERNAL SUB expression(s$, v()) !式
   DIM w(0 TO UBOUND(v))

   LET t$=token$(s$)
   IF t$="-" THEN !符号なら
      LET p=p+1 !eat it

      CALL term(s$, v)
      IF errNo<>0 THEN EXIT SUB

      CALL op_neg(v, v) !v=-v
   ELSE
      IF t$="+" THEN LET p=p+1 !eat it
      CALL term(s$, v)
   END IF
   IF errNo<>0 THEN EXIT SUB


   LET t$=token$(s$)
   DO WHILE t$="+" OR t$="-" !加算、減算なら
      LET p=p+1 !eat it

      CALL term(s$, w)
      IF errNo<>0 THEN EXIT SUB

      IF t$="+" THEN !計算する
         CALL op_add(v,w, v) !v=v+w
      ELSE
         CALL op_sub(v,w, v) !v=v-w
      END IF
      IF errNo<>0 THEN EXIT SUB

      LET t$=token$(s$) !次へ
   LOOP
END SUB

EXTERNAL SUB term(s$, v()) !項
   DIM w(0 TO UBOUND(v))

   CALL factor(s$,v)
   IF errNo<>0 THEN EXIT SUB

   LET t$=token$(s$)
   DO WHILE t$="*" OR t$="/" !乗算、除算なら
      LET p=p+1 !eat it

      CALL factor(s$,w)
      IF errNo<>0 THEN EXIT SUB

      IF t$="*" THEN !計算する
         CALL op_mul(v,w, v) !v=v*w
      ELSE
         CALL op_div(v,w, v) !v=v/w
      END IF
      IF errNo<>0 THEN EXIT SUB

      LET t$=token$(s$) !次へ
   LOOP
END SUB

EXTERNAL SUB factor(s$, v()) !因子
   DIM w(0 TO UBOUND(v))

   LET t$=token$(s$)
   IF t$="(" THEN !括弧なら
      LET p=p+1 !eat it

      CALL expression(s$,w) !式
      IF errNo<>0 THEN EXIT SUB

      MAT v=w

      CALL CheckToken(s$,")") !閉じ括弧か確認する
   ELSE
      CALL num(s$,v)
   END IF
   IF errNo<>0 THEN EXIT SUB


   LET t$=token$(s$)
   DO WHILE t$="^" !べき乗なら
      LET p=p+1 !eat it

      LET t$=token$(s$)
      IF t$="(" THEN !括弧なら
         LET p=p+1 !eat it

         CALL expression(s$,w) !式
         IF errNo<>0 THEN EXIT SUB

         CALL CheckToken(s$,")") !閉じ括弧か確認する
      ELSE
         CALL num(s$,w)
      END IF
      IF errNo<>0 THEN EXIT SUB


      CALL op_pow(v,w, v) !計算する v=v^w
      IF errNo<>0 THEN EXIT SUB


      LET t$=token$(s$) !次へ
   LOOP
END SUB

EXTERNAL SUB num(s$,v()) !数
   DIM w(0 TO UBOUND(v)),x(0 TO UBOUND(v))

   LET c=fnc(s$)
   IF c>0 THEN !関数なら
      LET t$=token$(s$)
      IF t$="(" THEN !括弧なら
         LET p=p+1 !eat it

         CALL expression(s$,w) !引数1
         IF errNo<>0 THEN EXIT SUB

         MAT v=w

         CALL CheckToken(s$,",") !カンマか確認する

         CALL expression(s$,w) !引数2
         IF errNo<>0 THEN EXIT SUB

         IF c=1 THEN !modpow(a,n,b)形式
            CALL CheckToken(s$,",") !カンマか確認する

            CALL expression(s$,w) !引数3
            IF errNo<>0 THEN EXIT SUB

            MAT x=w

            CALL set_fnc3(c,v,w,x, v) !v=fnc(v,w,x)
         ELSE
            CALL set_fnc2(c,v,w, v) !v=fnc(v,w)
         END IF
         IF errNo<>0 THEN EXIT SUB

         CALL CheckToken(s$,")") !閉じ括弧か確認する
      ELSE
         CALL Error("不正な文字です。")
      END IF

   ELSE
      LET c=var(s$)
      IF c>0 THEN !変数なら
         CALL set_var(c, v)
      ELSE
         LET c=number(s$)
         IF c>=0 THEN !定数(数値)なら
            CALL set_number(c, v)
         ELSE
            CALL Error("不正な文字です。")
         END IF
      END IF

   END IF
END SUB

EXTERNAL FUNCTION fnc(s$) !関数
   DATA "MODPOW","MODINV","MOD","GCD","LCM" !※文字長が大きい順
   LET k=0
   DO
      LET k=k+1
      READ IF MISSING THEN EXIT DO: d$
      IF UCASE$(s$(p:p+LEN(d$)-1))=UCASE$(d$) THEN !一致したら
         LET p=p+LEN(d$)
         LET fnc=k
         EXIT FUNCTION
      END IF
   LOOP
   LET fnc=-1
END FUNCTION

EXTERNAL FUNCTION var(s$) !変数
   LET t$=UCASE$(token$(s$)) !大文字へ
   IF "A"<=t$ AND t$<="Z" THEN
   !!!IF t$="X" THEN
      LET p=p+1 !eat it
      LET var=ORD(t$)-ORD("@") !オフセット @=0,A=1,B=2,…,Z=26
   ELSE
      LET var=-1
   END IF
END FUNCTION

EXTERNAL FUNCTION number(s$) !数値(0、正の整数)
   LET i0=p !先頭位置を記録する

   LET t$=token$(s$)
   DO WHILE t$>="0" AND t$<="9"
      LET p=p+1
      LET t$=token$(s$)
   LOOP

   LET number=-1
   IF p>i0 THEN LET number=VAL(s$(i0:p-1)) !数字列の範囲を切り取る
END FUNCTION


つづく
 

Re: 式の評価、もう1つの拡張

 投稿者:山中和義  投稿日:2009年 2月20日(金)15時42分40秒
返信・引用  編集済
  > No.286[元記事へ]

つづき

!●演算部分 ※「数の組」に応じて演算を定義する

EXTERNAL SUB op_neg(v1(), v()) !符号(負)
   MAT v=(-1)*v1
END SUB

EXTERNAL SUB op_add(v1(),v2(), v()) !加算
   MAT v=v1+v2
END SUB

EXTERNAL SUB op_sub(v1(),v2(), v()) !減算
   MAT v=v1-v2
END SUB

EXTERNAL SUB op_mul(v1(),v2(), v()) !乗算
   LET N=UBOUND(v)
   DIM w(0 TO N*2) !桁数は2倍になる

   MAT w=ZER
   FOR i=0 TO N !係数
      FOR j=0 TO N
         LET w(i+j)=w(i+j)+v1(i)*v2(j) !畳み込み
      NEXT j
   NEXT i
   IF poly_degree(w)>N THEN CALL Error("オーバーフロー")

   FOR i=0 TO N !下n桁をコピーする
      LET v(i)=w(i)
   NEXT i
END SUB

EXTERNAL SUB op_div(v1(),v2(), v()) !除算
   DIM Q(0 TO UBOUND(v)),R(0 TO UBOUND(v))

   IF poly_degree(v2)=0 AND v2(0)=0 THEN !定数の0なら
      CALL Error("0では割れません。")
      EXIT SUB
   END IF
   CALL poly_div(v1,v2, Q,R)
   MAT v=Q !商 ※v=INT(v1/v2)に相当
END SUB

EXTERNAL SUB op_pow(v1(),v2(), v()) !べき算
   DIM x(0 TO UBOUND(v)),T(0 TO UBOUND(v))

   MAT x=v1 !x=v1

   MAT T=ZER !定数1
   LET T(0)=1

   IF poly_degree(v1)=0 THEN !定数項のみ(定数)
      IF poly_degree(v2)>0 THEN CALL Error("べき数は整数のみ")
      IF errNo<>0 THEN EXIT SUB
      IF v1(0)=0 AND v2(0)<0 THEN CALL Error("0の負べき乗")
      IF errNo<>0 THEN EXIT SUB

      LET v(0)=v1(0)^v2(0)
   ELSE
      IF poly_degree(v2)>0 OR v2(0)<0 THEN CALL Error("べき数は非負整数のみ")
      IF errNo<>0 THEN EXIT SUB

      LET m=v2(0)
      DO UNTIL m=0
         IF MOD(m,2)=1 THEN CALL op_mul(T,x, T) !ビットが1なら、T=T*x
         IF errNo<>0 THEN EXIT SUB
         CALL op_mul(x,x, x) !x=x^2
         IF errNo<>0 THEN EXIT SUB

         LET m=INT(m/2) !2進数にする
      LOOP
      MAT v=T
   END IF
END SUB


EXTERNAL SUB set_fnc(c,v1(), v()) !関数(値)を設定する ※引数1個
!該当関数なし
END SUB

EXTERNAL SUB set_fnc2(c,v1(),v2(), v()) !関数(値)を設定する ※引数2個
   LET N=UBOUND(v)
   DIM Q(0 TO N),R(0 TO N),A(0 TO N),B(0 TO N)

   SELECT CASE c !各関数に応じて
   CASE 2 !modinv
      PRINT "modinv関数は未サポート!"
   CASE 3 !剰余
      CALL poly_div(v1,v2, Q,R)
      MAT v=R !余り
   CASE 4,5 !最大公約数、最小公倍数
      MAT A=v1
      MAT B=v2
      DO UNTIL poly_degree(B)=0 AND B(0)=0 !b=0
         CALL poly_div(A,B, Q,R) !R=MOD(a,b)
         MAT A=B !a=b
         MAT B=R !b=R
      LOOP

      IF c=5 THEN !LCM=v1*v2/GCD(v1,v2)
         CALL op_div(v1,A, Q)
         IF errNo<>0 THEN EXIT SUB
         CALL op_mul(Q,v2, v)
      ELSE !GCD
         MAT v=A
      END IF
   CASE ELSE
   END SELECT
END SUB

EXTERNAL SUB set_fnc3(c,v1(),v2(),v3(), v()) !関数(値)を設定する ※引数3個
   PRINT "modpow関数は未サポート!"
END SUB

EXTERNAL SUB set_var(c, v()) !変数(値)
   MAT v=ZER
   LET v(1)=1 !x^1の係数
END SUB

EXTERNAL SUB set_number(c, v()) !定数(数値)
   MAT v=ZER
   LET v(0)=c !x^0の係数
END SUB

END MODULE



!補助ルーチン

!演算関連

EXTERNAL SUB poly_div(A(),B(), Q(),R()) !除算 ※被除数=商*除数+余り
DIM w(0 TO UBOUND(A))

LET aa=poly_degree(A)
LET bb=poly_degree(B)

MAT Q=ZER !商、その次数
LET qq=MAX(aa-bb,0)

MAT R=A !余り、その次数
LET rr=aa

DO WHILE rr>=bb !被除数の次数が除数のより大きいなら
   IF R(rr)<>0 THEN !係数が0以外なら
      LET k=R(rr)/B(bb) !商の係数
      LET Q(rr-bb)=k !商

      MAT w=ZER !余り
      FOR i=bb TO 0 STEP -1 !R=A-k*B ※筆算参照
         LET w(rr-bb+i)=k*B(i)
      NEXT i
      MAT R=R-w
   END IF
   LET rr=rr-1 !次の次数へ
LOOP
END SUB

EXTERNAL FUNCTION poly_degree(v()) !次数を得る
FOR i=UBOUND(v) TO 1 STEP -1
   IF v(i)<>0 THEN EXIT FOR !係数が0でない最初の位置
NEXT i
LET poly_degree=i
END FUNCTION


!表示関連

EXTERNAL SUB poly_disp(A()) !多項式を表示する a(X)=ΣAkX^k=AnX^n+An-1X^n-1+…+A1X+A0
LET aa=poly_degree(A) !最初の項
CALL mono_disp(A(aa),aa)
FOR i=aa-1 TO 0 STEP -1 !次項
   LET w=A(i)
   IF w>0 THEN PRINT "+";
   IF w<>0 OR (w=0 AND aa=0) THEN CALL mono_disp(w,i)
NEXT i
END SUB

EXTERNAL SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
IF k<>0 THEN !x^nで
   IF ak=1 THEN !係数が1なら
   ELSEIF ak=-1 THEN !係数が−1なら
      PRINT "-";
   ELSE
      PRINT STR$(ak);"*";
   END IF
END IF
IF k=0 THEN !次数が0なら
   PRINT STR$(ak);
ELSEIF k=1 THEN !次数が1なら
   PRINT "X";
ELSE
   PRINT "X^";STR$(k);
END IF
END SUB


以上
 

Re: 節点解析法について (3)

 投稿者:SECOND  投稿日:2009年 2月22日(日)01時18分14秒
返信・引用  編集済
  > No.284[元記事へ]

!<<付録>>
! トランジスタ1つのエミッタ・フォロアなどを使用する場合、利得Gv が
! 十分でなく、入力のイマジナル・ショート扱いが出来ない場合も、あります。
! Gv=10〜100位の小さい時、下図のKで計算します。

!                         直列帰還型 Negative.Feed.Back amp
!                         Gv →∞、K →1 の簡易ベクトル図
!             ┌─R1─��               ──────→V3
!             ↑                       →  ────→(Ei)+(Ei)*Gv =V3
!             Vin                     (Ei) (Ei)*Gv =V5
!             │                                         K=V5/V3
!             0              ┌───────────┐
!                             │      ┌──────┐│ ※(Ei)は、
!             同 上            C2      │  ┌───┐││   +~-の差分
!                             │      └─┤-     │││
!         ┌─────┐      │       (Ei)│利得Gv├┴�エ�
!         │ ┌─R1─�;�R2─�※�R3─��─┤+     │  ↑ V5
!         ↑  │      ↑V1    ↑V2    ↑V3└───┘  │
!   Is=Vin/R1 │      C1              C3   K=Gv/(1+Gv)│
!         ↑  │      │              │              │
!         ┴─0───┴───────┴───────┴─
!
! | 1/R1+1/R2+j*ω*C1  -1/R2                0             | |V1| |Vin/R1|
! |-1/R2                1/R2+1/R3+j*ω*C2  -1/R3-K*j*ω*C2| |V2|=| 0    |
! | 0                  -1/R3                1/R3+j*ω*C3  | |V3| | 0    |
!

OPTION ANGLE DEGREES
OPTION ARITHMETIC COMPLEX
LET NP=3
LET rss=10 !14 周波数、10倍毎のステップ数
!
DIM FREQ(0 TO rss*4, 4), A(NP,NP), T(NP,NP), EOUT(NP,1), B(NP,1)
!----
! 周波数10Hz~100KHz、等比ステップ
FOR p=0 TO rss*4
   LET FREQ(p,1)=10^(1+p/rss)
NEXT p
!----
! CR 3段回路
LET R1=51E3       !Ω
LET R2=82E3       !Ω   51E3 ! 以下、右側の数値でGv=100でも、ほぼ平坦に戻る。
LET R3=39E3       !Ω
LET C1=0.00685E-6 !F    0.0047E-6
LET C2=0.022E-6   !F    0.033E-6
LET C3=330E-12    !F    270E-12
!----
SET WINDOW 0.5,5.5, -55,5
DRAW grid(1,5)
!----
! 目盛り
FOR p=0 TO 5
   SET TEXT COLOR "black"
   PLOT TEXT ,AT p+0.9, 1    :mid$("10  100 1k  10k 100k", 4*p+1, 4)    !x軸 10Hz~100kHz
   PLOT TEXT ,AT 0.7,-10*p-2 :mid$("  0 -25 -50 -75 -100-125", 4*p+1, 4)!y軸 0~-125dB 左
   SET TEXT COLOR "red"
   PLOT TEXT ,AT 5.1,-10*p-2 :mid$(" 0  -80 -160-240-320-400", 4*p+1, 4)!y軸 0~-400°右
NEXT p
!----
FOR Gv=10 TO 100 STEP 10
   LET K=Gv/(1+Gv)
   PRINT USING "Gv=### K=.####" :Gv, K
   PRINT "番号   周波数      E5         θ5"
   !----
   FOR p=0 TO rss*4
      LET ω=2*PI*FREQ(p,1)
      !
      LET A(1,1)= 1/R1+1/R2+COMPLEX(0,ω*C1)
      LET A(1,2)=-1/R2
      LET A(1,3)=0
      LET A(2,1)=-1/R2
      LET A(2,2)= 1/R2+1/R3+COMPLEX(0,ω*C2)
      LET A(2,3)=-1/R3-K*COMPLEX(0,ω*C2)
      LET A(3,1)=0
      LET A(3,2)=-1/R3
      LET A(3,3)= 1/R3+COMPLEX(0,ω*C3)
      !
      LET Vin=1
      LET B(1,1)=Vin/R1
      LET B(2,1)=0
      LET B(3,1)=0
      !
      MAT T=INV(A)
      MAT EOUT=T*B
      !
      LET Af=K*EOUT(3,1)/Vin
      LET Pf=arg(Af)
      IF Pf>0 THEN LET Pf=Pf-360
      LET FREQ(p,2)=20*LOG10(ABS(Af))
      LET FREQ(p,4)=Pf
      !------
      !リスト
      PRINT USING "### ###,###.# ####.### dB ####.### 度": p, FREQ(p,1), FREQ(p,2), FREQ(p,4)
      !------
      !グラフ
      IF 0<p THEN
         SET LINE COLOR "black"
         PLOT LINES:LOG10(FREQ(p-1,1)),0.4*FREQ(p-1,2); LOG10(FREQ(p,1)),0.4*FREQ(p,2) !利得[dB]
         SET LINE COLOR "red"
         PLOT LINES:LOG10(FREQ(p-1,1)),0.125*FREQ(p-1,4); LOG10(FREQ(p,1)),0.125*FREQ(p,4) !位相[度]
      END IF
   NEXT p
NEXT Gv

END
 

Re: 節点解析法について (3)

 投稿者:大熊 正  投稿日:2009年 2月22日(日)14時41分46秒
返信・引用
  > No.288[元記事へ]

SECONDさんへのお返事です。

> !<<付録>>
> ! トランジスタ1つのエミッタ・フォロアなどを使用する場合、利得Gv が
> ! 十分でなく、入力のイマジナル・ショート扱いが出来ない場合も、あります。
> ! Gv=10〜100位の小さい時、下図のKで計算します。
>
> !                         直列帰還型 Negative.Feed.Back amp
> !                         Gv →∞、K →1 の簡易ベクトル図
> !             ┌─R1─��               ──────→V3
> !             ↑                       →  ────→(Ei)+(Ei)*Gv =V3
> !             Vin                     (Ei) (Ei)*Gv =V5
> !             │                                         K=V5/V3
> !             0              ┌───────────┐
> !                             │      ┌──────┐│ ※(Ei)は、
> !             同 上            C2      │  ┌───┐││   +~-の差分
> !                             │      └─┤-     │││
> !         ┌─────┐      │       (Ei)│利得Gv├┴�エ�
> !         │ ┌─R1─�;�R2─�※�R3─��─┤+     │  ↑ V5
> !         ↑  │      ↑V1    ↑V2    ↑V3└───┘  │
> !   Is=Vin/R1 │      C1              C3   K=Gv/(1+Gv)│
> !         ↑  │      │              │              │
> !         ┴─0───┴───────┴───────┴─
> !
> ! | 1/R1+1/R2+j*ω*C1  -1/R2                0             | |V1| |Vin/R1|
> ! |-1/R2                1/R2+1/R3+j*ω*C2  -1/R3-K*j*ω*C2| |V2|=| 0    |
> ! | 0                  -1/R3                1/R3+j*ω*C3  | |V3| | 0    |
> !
>

大熊です。
お忙しい所、色色と御指導頂き有難うございます。

スマートなプログラムや方程式の考え方について
勉強させていただいております。
今後ともよろしく御願いいたします。

敬具


 

Re: 節点解析法について (3)

 投稿者:SECOND  投稿日:2009年 2月23日(月)16時03分38秒
返信・引用  編集済
  > No.288[元記事へ]

!<<付録2>>
! 節点方程式:キルヒホッフ第1法則 …1点への電流 総和=0
! 網路方程式:キルヒホッフ第2法則 …閉回路の電位差総和=0

! 余計ですが、網路方程式(第2法則)の方を、使った例。
!
!                   ┌───────────┐
!                   │      ┌──────┐│
!                   C2      │  ┌───┐││
!                   ││i3  └─┤-     │││
!                   │└───┐│利得Gv├┴┼─
!  ┌─R1─┬─R2─┴─R3─┬┼┤+     │  ↑ Vout=K*(i2+i3)/(j*ω*C3)
!   ↑ ┌→ │    ┌→      │↓└───┘  │
!   Vin│i1 C1    │i2      C3   K=Gv/(1+Gv)│
!   │ └   │    └        │              │
!   0───┴───────┴───────┴─
!
! | R1+1/(j*ω*C1) -1/(j*ω*C1)                   0                         | |i1| |Vin |
! |-1/(j*ω*C1)     1/(j*ω*C1)+R2+R3+1/(j*ω*C3) R3+1/(j*ω*C3)            | |i2|=| 0  |
! | 0               R3+1/(j*ω*C3)                1/(j*ω*C2)+R3+1/(j*ω*C3)| |i3| |Vout|

! | R1+1/(j*ω*C1) -1/(j*ω*C1)                   0                                     | |i1| |Vin|
! |-1/(j*ω*C1)     1/(j*ω*C1)+R2+R3+1/(j*ω*C3) R3+1/(j*ω*C3)                        | |i2|=| 0 |
! | 0               R3+1/(j*ω*C3)-K/(j*ω*C3)    1/(j*ω*C2)+R3+1/(j*ω*C3)-K/(j*ω*C3)| |i3| | 0 |
!

OPTION ANGLE DEGREES
OPTION ARITHMETIC COMPLEX
LET NP=3
LET rss=10 !14 周波数、10倍毎のステップ数
!
DIM FREQ(0 TO rss*4, 4), A(NP,NP), T(NP,NP), IOUT(NP,1), B(NP,1)
!----
! 周波数10Hz~100KHz、等比ステップ
FOR p=0 TO rss*4
   LET FREQ(p,1)=10^(1+p/rss)
NEXT p
!----
! CR 3段回路      ! (Gv=1000000) ! (Gv=100)
LET R1=51E3       !Ω
LET R2=51E3       !Ω 82E3       ! 51E3
LET R3=39E3       !Ω
LET C1=0.0047E-6  !F  0.00685E-6 ! 0.0047E-6
LET C2=0.033E-6   !F  0.022E-6   ! 0.033E-6
LET C3=270E-12    !F  330E-12    ! 270E-12
!----
SET WINDOW 0.5,5.5, -55,5
DRAW grid(1,5)
!----
! 目盛り
FOR p=0 TO 5
   SET TEXT COLOR "black"
   PLOT TEXT ,AT p+0.9, 1    :mid$("10  100 1k  10k 100k", 4*p+1, 4)    !x軸 10Hz~100kHz
   PLOT TEXT ,AT 0.7,-10*p-2 :mid$("  0 -25 -50 -75 -100-125", 4*p+1, 4)!y軸 0~-125dB 左
   SET TEXT COLOR "red"
   PLOT TEXT ,AT 5.1,-10*p-2 :mid$(" 0  -80 -160-240-320-400", 4*p+1, 4)!y軸 0~-400°右
NEXT p
!----
FOR Gv=10 TO 100 STEP 10
   LET K=Gv/(1+Gv)
   PRINT USING "Gv=### K=.####" :Gv, K
   PRINT "番号   周波数    Vout/Vin    θ"
   !----
   FOR p=0 TO rss*4
      LET ω=2*PI*FREQ(p,1)
      !
      LET A(1,1)= R1+1/COMPLEX(0,ω*C1)
      LET A(1,2)=-1/COMPLEX(0,ω*C1)
      LET A(1,3)=0
      LET A(2,1)=-1/COMPLEX(0,ω*C1)
      LET A(2,2)= 1/COMPLEX(0,ω*C1)+R2+R3+1/COMPLEX(0,ω*C3)
      LET A(2,3)= R3+1/COMPLEX(0,ω*C3)
      LET A(3,1)=0
      LET A(3,2)= R3+1/COMPLEX(0,ω*C3)-K/COMPLEX(0,ω*C3)
      LET A(3,3)=1/COMPLEX(0,ω*C2)+R3+1/COMPLEX(0,ω*C3)-K/COMPLEX(0,ω*C3)
      !
      LET Vin=1
      LET B(1,1)=Vin
      LET B(2,1)=0
      LET B(3,1)=0
      !
      MAT T=INV(A)
      MAT IOUT=T*B
      !
      LET Af=K*((IOUT(2,1)+IOUT(3,1))/COMPLEX(0,ω*C3))/Vin
      LET Pf=arg(Af)
      IF Pf>0 THEN LET Pf=Pf-360
      LET FREQ(p,2)=20*LOG10(ABS(Af))
      LET FREQ(p,4)=Pf
      !------
      !リスト
      PRINT USING "### ###,###.# ####.### dB ####.### 度": p, FREQ(p,1), FREQ(p,2), FREQ(p,4)
      !------
      !グラフ
      IF 0< p THEN
         SET LINE COLOR "black"
         PLOT LINES:LOG10(FREQ(p-1,1)),0.4*FREQ(p-1,2); LOG10(FREQ(p,1)),0.4*FREQ(p,2) !利得[dB]
         SET LINE COLOR "red"
         PLOT LINES:LOG10(FREQ(p-1,1)),0.125*FREQ(p-1,4); LOG10(FREQ(p,1)),0.125*FREQ(p,4) !位相[度]
      END IF
   NEXT p
NEXT Gv

END

!
下図は、i3 を逆方向にしたもので、全く同じものです。各式の負号に注意!
!
!                   ┌───────────┐
!                   │      ┌──────┐│
!                   C2↑    │  ┌───┐││
!                   ││i3  └─┤-     │││
!                   │└───┐│利得Gv├┴┼─
!  ┌─R1─┬─R2─┴─R3─┬┼┤+     │  ↑ Vout=K*(i2-i3)/(j*ω*C3)
!   ↑ ┌→ │    ┌→      │  └───┘  │
!   Vin│i1 C1    │i2      C3   K=Gv/(1+Gv)│
!   │ └   │    └        │              │
!   0───┴───────┴───────┴─
!
! | R1+1/(j*ω*C1) -1/(j*ω*C1)                    0                         | |i1| | Vin |
! |-1/(j*ω*C1)     1/(j*ω*C1)+R2+R3+1/(j*ω*C3) -R3-1/(j*ω*C3)            | |i2|=|  0  |
! | 0              -R3-1/(j*ω*C3)                 1/(j*ω*C2)+R3+1/(j*ω*C3)| |i3| |-Vout|

! | R1+1/(j*ω*C1) -1/(j*ω*C1)                    0                                     | |i1| |Vin|
! |-1/(j*ω*C1)     1/(j*ω*C1)+R2+R3+1/(j*ω*C3) -R3-1/(j*ω*C3)                        | |i2|=| 0 |
! | 0              -R3-1/(j*ω*C3)+K/(j*ω*C3)     1/(j*ω*C2)+R3+1/(j*ω*C3)-K/(j*ω*C3)| |i3| | 0 |
!

! i3 逆方向の、差し替え部分( 左端!を外して使用。)
!      LET A(1,1)= R1+1/COMPLEX(0,ω*C1)
!      LET A(1,2)=-1/COMPLEX(0,ω*C1)
!      LET A(1,3)= 0
!      LET A(2,1)=-1/COMPLEX(0,ω*C1)
!      LET A(2,2)= 1/COMPLEX(0,ω*C1)+R2+R3+1/COMPLEX(0,ω*C3)
!      LET A(2,3)=-R3-1/COMPLEX(0,ω*C3)
!      LET A(3,1)= 0
!      LET A(3,2)=-R3-1/COMPLEX(0,ω*C3)+K/COMPLEX(0,ω*C3)
!      LET A(3,3)= 1/COMPLEX(0,ω*C2)+R3+1/COMPLEX(0,ω*C3)-K/COMPLEX(0,ω*C3)
!      !
!      LET Vin=1
!      LET B(1,1)=Vin
!      LET B(2,1)=0
!      LET B(3,1)=0
!      !
!      MAT T=INV(A)
!      MAT IOUT=T*B
!      !
!      LET Af=K*((IOUT(2,1)-IOUT(3,1))/COMPLEX(0,ω*C3))/Vin
!ここまで
!
 

編集させていただきました

 投稿者:kikiriri  投稿日:2009年 2月23日(月)18時50分14秒
返信・引用  編集済
  > No.255[元記事へ]

山中和義さんへのお返事です。

> kikiririさんへのお返事です。

長らくご返答いただけなかったため、

このような形で編集させていただきました。

山中和義さんへ

  kikiririより

 ご回答(プログラム)、誠にありがとうございました。
 

!3段型CR昇圧回路を使った発振器の、複素平面軌跡

 投稿者:SECOND  投稿日:2009年 2月26日(木)09時48分16秒
返信・引用
  > No.280[元記事へ]

!上のリンクページの伝達関数ZT(s)に誤字が有った事を御詫びします。

!3段型CR昇圧回路を使った発振器の、複素平面軌跡

!立体描画は、山中氏の3Dグラフによる。

!3段型CR昇圧回路の伝達関数ZT(s) ( R =R1=R2=R3, C =C1=C2=C3 )
! ZT(s)=(1+5*R*C*s+6*R^2*C^2*s^2)/(1+5*R*C*s+6*R^2*C^2*s^2 + R^3*C^3*s^3)

!ZT(s)*K=1 ! 増幅率 K を縦列して、入出力短絡ループにした式。この根 s を求める。

!(1+5*R*C*s+6*R^2*C^2*s^2)*K=(1+5*R*C*s+6*R^2*C^2*s^2 + R^3*C^3*s^3)
! R^3*C^3*s^3 +(1-K)(1+5*R*C*s+6*R^2*C^2*s^2)=0
! s^3 +6*(1-K)/(R*C)*s^2 +5*(1-K)/(R^2*C^2)*s +(1-K)/(R^3*C^3) =0
! この3根sを、増幅率 K=Gv/(1+Gv) の関数として、描く。(Gv は、裸アンプの利得)

! sの実数部が正の領域が、発振可能な領域です。グラフを見ると、増幅率の変化で、
! 実に広範囲に、発振周波数の移動が見られ、周波数の安定は、良くないかもしれない。

SET TEXT BACKGROUND "OPAQUE"
OPTION ARITHMETIC COMPLEX
LET N=3
DIM A(N),Xr(N)
!
LET R=12E3      !Ω
LET C=0.0033E-6 !F
LET RC=R*C

!------------------
! z y で表示する( 山中氏の3DプロットSUB)
! │/
! ・─x
!------------------
SUB rotx(x,y,z,a)
   LET w=y*COS(a)-z*SIN(a)
   LET z=y*SIN(a)+z*COS(a)
   LET y=w
END SUB

SUB rotz(x,y,z,a)
   LET w=x*COS(a)-y*SIN(a)
   LET y=x*SIN(a)+y*COS(a)
   LET x=w
END SUB

SUB plots(x,y,z)
   CALL rotz(x,y,z,-PI/2.5)
   CALL rotx(x,y,z,-PI/10)
   PLOT LINES:x,y;
END SUB

SUB plott(x,y,z,w$)
   CALL rotz(x,y,z,-PI/2.5)
   CALL rotx(x,y,z,-PI/10)
   PLOT TEXT,AT x,y:w$
END SUB
!------------------

SET WINDOW -4.2,3.7, -3.6,4.3
!-----
! 目盛り
FOR x=-2 TO 1
   IF x=0 THEN SET LINE STYLE 1 ELSE SET LINE STYLE 3
   CALL plots((x),-3, 0)
   CALL plots((x),+3, 0) ! (x) は、SUB からxの書き戻しの防止。
   PLOT LINES
   CALL plott(x-.1, -3.7, 0, USING$("######",x*5000) )
NEXT x
FOR y=-3 TO 3
   IF y=0 THEN SET LINE STYLE 1 ELSE SET LINE STYLE 3
   CALL plots(-2,(y), 0)
   CALL plots( 1,(y), 0)
   PLOT LINES
   CALL plott(1.3, y-.3, 0, STR$(y*5000)&"j" )
   CALL plott(1.6, y-.4, 0, USING$("#####",y*5000/(2*PI))&"Hz" )
NEXT y
SET LINE STYLE 1
!----
SET LINE COLOR 1
CALL plots(-2,0,0)
CALL plots(-2,0,4)
PLOT LINES
CALL plott(-2, 0.1, 1.5, "K=0.90" )
CALL plott(-2, 0.1, 2.5, "K=0.95" )
CALL plott(-2, 0.1, 3.5, "K=1.0" )
!
!-----
! K と根のグラフ
LET rss=15 ! Gv=10~100000 10倍毎のステップ数
FOR p=0 TO 4*rss
   LET Gv=10^(1+p/rss)
   LET K=Gv/(1+Gv)
   !
   LET A(1)=6*(1-K)/RC
   LET A(2)=5*(1-K)/RC^2
   LET A(3)=(1-K)/RC^3
   CALL DKA_00
   !
   PRINT USING "Gv=###### K=.#####": Gv,K;
   FOR s=1 TO 3
      PRINT USING"┃#####.# #####.#Hz" :re(Xr(s)),im(Xr(s))/(2*PI);
      SET LINE COLOR s+1
      CALL plots(re(Xr(s))/5000,im(Xr(s))/5000, 0)
      CALL plots(re(Xr(s))/5000,im(Xr(s))/5000,(K-0.8)*20)
      PLOT LINES
   NEXT s
   PRINT
NEXT p


!DKA (Durand Kerner Aberth) 法による高次方程式の根
!--------------------------------------------
! X^n + A(1)*X^(n-1) + ... + A(n) = 0

! Xr( 1 ~ n ) <== root
!--------------------------------------------
SUB DKA_00
   LET r=1
   FOR j=2 TO N
      LET rn=ABS(A(j))^(1/j)
      if r<rn then LET r=rn
   NEXT j
   FOR j=1 TO N
      LET Xr(j)=-A(1)/N+r*EXP( complex(0,1)*2*PI/N *(j-3/4) )
   NEXT j
   FOR m=0 TO 100
      LET mfx=0
      LET maj=0
      FOR j=1 TO N
         LET Xk=1
         LET fx=1
         FOR w=1 TO N
            LET fx=fx*Xr(j)+A(w)
            IF w<>j THEN LET Xk=Xk*(Xr(j)-Xr(w))
         NEXT w
         LET Xr(j)=Xr(j)-fx/Xk
         IF mfx<ABS(fx) THEN LET mfx=ABS(fx)
         IF maj<ABS(fx/Xk) THEN LET maj=ABS(fx/Xk)
      NEXT j
      IF mfx<.0000001 AND maj<.0000001 THEN EXIT FOR
   NEXT m
END SUB

END
 

特性多項式の係数から安定性を判別する方法

 投稿者:山中和義  投稿日:2009年 3月 3日(火)10時26分22秒
返信・引用
  系の安定性の判別
・多項式の根をDKA法などで求める
・多項式の係数から
  :

●ラウス(routh)の安定判別法
LET N=4 !次数
DIM A(0 TO N) !多項式の係数 A(n)*s^n+A(n-1)*s^(n-1)+ … +A(1)*s+A(0)、A(n)>0

DATA 1,5,10,10,4 !s^4+5*s^3+10*s^2+10*s+4


FOR i=N TO 0 STEP -1
   READ A(i) !係数を読み込む

   IF A(i)<=0 THEN !すべて正かどうか確認する
      PRINT "安定な多項式でない。"
      STOP
   END IF
NEXT i


!ラウス表をつくる
!1行 B1 A(N)   A(N-2) A(N-4) …
!2行 B2 A(N-1) A(N-3) A(N-5) …  → B1
!3行 B3 → B2
! :    → B3
! :
LET M=INT(N/2)
DIM B1(0 TO M),B2(0 TO M),B3(0 TO M)

FOR i=0 TO N !0行目、1行目
   IF MOD(i,2)=0 THEN LET B1(INT(i/2))=A(N-i) ELSE LET B2(INT(i/2))=A(N-i)
NEXT i
MAT PRINT B1; !debug
MAT PRINT B2;

FOR l=2 TO N !2行目〜N行目
   MAT B3=ZER
   FOR i=0 TO M-1
      LET B3(i)=-1/B2(0)*( B1(0)*B2(i+1) - B1(i+1)*B2(0) )
   NEXT i
   MAT PRINT B3; !debug
   IF B3(0)<=0 THEN !ラウス数列がすべて正かどうか確認する
      PRINT "安定な多項式でない。"
      STOP
   END IF

   MAT B1=B2
   MAT B2=B3
NEXT l

PRINT "安定な多項式である。"

END



●フルビッツ(Hurwitz)の安定判別法
LET N=4 !次数
DIM A(0 TO N) !多項式の係数 A(n)*s^n+A(n-1)*s^(n-1)+ … +A(1)*s+A(0)

DATA 1,5,10,10,4 !s^4+5*s^3+10*s^2+10*s+4


FOR i=N TO 0 STEP -1
   READ A(i) !係数を読み込む

   IF A(i)<=0 THEN !すべて正かどうか確認する
      PRINT "安定な多項式でない。"
      STOP
   END IF
NEXT i


!フルビッツ行列式をつくる
!│A(n-1) A(n-3) A(n-5) … 0 │
!│A(n)  A(n-2) A(n-4) … 0 │
!│0   A(n-1) A(n-3) … 0 │
!│0   A(n)  A(n-2) … 0 │
!  :
!  :
!│0   0   0  … A(1)│

DIM B(N,N)
FOR m=1 TO N
   MAT B=ZER(m,m)
   LET k=N-1
   FOR i=1 TO m
      FOR j=1 TO m
         LET t=k-2*(j-1)
         IF t>=0 AND t<=N THEN LET B(i,j)=A(t)
      NEXT j
      LET k=k+1
   NEXT i
   MAT PRINT B; !debug
   IF DET(B)<=0 THEN
      PRINT "不安定な多項式です。"
      !STOP
   END IF
   PRINT "行列式=";DET(B) !debug
NEXT m

PRINT "安定な多項式である。"

END
 

状態方程式から伝達関数を求める

 投稿者:山中和義  投稿日:2009年 3月 3日(火)10時36分9秒
返信・引用
 
!1入力1出力、状態変数がN個の1階の連立微分方程式
! 状態方程式 x'(t)=A*x(t)+b*u(t) ※A:N×N、b:N×1
! 出力方程式 y(t)=C*x(t) ※C:1×N
!から
! 伝達関数 G(s)=c*INV(s*I-A)*b=c*adj(s*I-A)*b/det(s*I-A)
!を求める


!行列関連
FUNCTION tr(A(,)) !行列Aのトレース
   LET t=0
   FOR i=1 TO N
      LET t=t+A(i,i)
   NEXT i
   LET tr=t
END FUNCTION

!多項式関連
SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
   IF k<>0 THEN !x^nで
      IF ak=1 THEN !係数が1なら
      ELSEIF ak=-1 THEN !係数が−1なら
         PRINT "-";
      ELSE
         PRINT STR$(ak);"*";
      END IF
   END IF
   IF k=0 THEN !次数が0なら
      PRINT STR$(ak);
   ELSEIF k=1 THEN !次数が1なら
      PRINT "s";
   ELSE
      PRINT "s^";STR$(k);
   END IF
END SUB
!-------------------- ここまでがサブルーチン


!---------- ↓↓↓↓↓ ----------
LET N=3 !状態変数の数

DATA 0,0,-6 !A
DATA 1,0,-11
DATA 0,1,-6

DATA 1 !b
DATA 0
DATA 0

DATA 0,0,1 !c
!---------- ↑↑↑↑↑ ----------


DIM A(N,N),b(N,1),c(1,N)

MAT READ A
MAT READ b
MAT READ c


!Frame法、Leverrir-Faddeev法
! adj(s*I-A)=s^(n-1)*I+s^(n-2)*β1+ … +s*βn-2+βn-1
! det(s*I-A)=s^n+α1*s^(n-1)+ … + αn-1*s+αn
!のとき
! β0=I、k=1〜nについて
!  Xk=A*βk-1
!  αk=-trace(Xk)/k
!  βk=Xk+αk*I
!の逐次計算でαk、βkが求まる。

DIM c1(N) !多項式 c(1)*X^(N-1)+c(2)*X^(N-2)+ … +c(N-1)*X+c(N) の係数
DIM c2(N) !多項式 X^N+c(1)*X^(N-1)+c(2)*X^(N-2)+ … +c(N-1)*X+c(N) の係数
DIM X(N,N),sE(N,N),T1(1,N),T2(1,1) !作業用

MAT X=IDN !adj(s*I-A)
FOR k=1 TO N
!!!MAT PRINT X; !debug
   MAT T1=c*X !c*adj(s*I-A)*b ※定数*多項式*定数
   MAT T2=T1*b
   LET c1(k)=T2(1,1)

   MAT X=A*X
   LET c2(k)=-tr(X)/k !det(s*I-A)
   MAT sE=(c2(k))*IDN
   MAT X=X+sE
NEXT k


!!!MAT PRINT c1; !debug
PRINT "分子= ";
FOR i=1 TO N !分子側の多項式を表示する
   LET w=c1(i)
   IF w>0 THEN PRINT "+";
   IF w<>0 THEN CALL mono_disp(w,N-i)
NEXT i
PRINT

!!!MAT PRINT c2; !debug
PRINT "分母= ";
CALL mono_disp(1,N) !分母側の多項式を表示する
FOR i=1 TO N
   LET w=c2(i)
   IF w>0 THEN PRINT "+";
   IF w<>0 THEN CALL mono_disp(w,N-i)
NEXT i


END
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 3月 6日(金)19時59分4秒
返信・引用  編集済
  > No.246[元記事へ]

●n!(nの階乗)の末尾の0の数
末尾が0になるのは、10のべき数(10,100,1000,…)なので、この10を数えればよい。
10は、2と5の組合せなので、この2と5を数えればよい。
nの階乗の中に2は十分あるので、5の数を求める。

例. 10!=3628800なので、2個
OPTION ARITHMETIC RATIONAL

LET N=20

PRINT fact(N) !検算


LET A=N
LET S=0 !5の数を数える
DO UNTIL A=0
   LET A=INT(A/5) !5,5^2,5^3,…で割る
   LET S=S+A
LOOP
PRINT S;"個"


!LET A=N
!LET S=0 !2の数を数える
!DO UNTIL A=0
!   LET A=INT(A/2) !2,2^2,2^3,…で割る
!   LET S=S+A
!LOOP
!PRINT S;"個"

END


●n!の素因数分解
2〜nまでの素数で、それぞれの個数を求める。(上記を利用する)
LET N=20

FOR i=2 TO N
   IF isPRIME(i)=-1 THEN !素数に対して

      LET a=N
      LET s=0 !素数iの個数
      DO UNTIL a=0
         LET a=INT(a/i)
         LET s=s+a
      LOOP
      PRINT STR$(i);"^";STR$(s) !べき乗で表示

   END IF
NEXT i

END


!●素数かどうか判定する(エラトステネスのふるい法)
! 変数 N: 判定する数値。※2以上
! 関数値:k>0 素数でない(kは約数)、-1 素数
EXTERNAL FUNCTION isPRIME(N)
IF MOD(N,2)=0 THEN !2で割り切れるなら素数でない
   LET isPRIME=2
   IF N=2 THEN LET isPRIME=-1 !2は素数
ELSE
   LET isPRIME=-1 !素数である
   FOR i=3 TO SQR(N) STEP 2 !Nの平方根までの奇数で繰り返す
   !!!FOR i=3 TO INTSQR(N) STEP 2 !Nの平方根までの奇数で繰り返す
      IF MOD(N,i)=0 THEN !iで割り切れるなら素数でない
         LET isPRIME=i
         EXIT FOR
      END IF
   NEXT i
END IF
END FUNCTION


●n!の計算
数の並びの対称性を利用する。
! 10!=1*2*3*4*5*6*7*8*9*10の場合

! 中央値 m=6
! 5と7 (m-1)*(m+1)=m^2-1=36-1=35、d=1
! 4と8 (m-2)*(m+2)=m^2-4=(m^2-1)-3=35-3=32、d=3
! 3と9 (m-3)*(m+3)=m^2-9=(m^2-4)-5=32-5=27、d=5
! 2と10 (m-4)*(m+4)=m^2-16=(m^2-9)-7=27-7=20、d=7
! 1 無視
! ∴10!=6*35*32*27*20

LET N=10

LET m=INT(N/2+1) !中央値
LET s=m
LET mm=m*m

LET d=1
FOR i=1 TO N-m
   LET mm=mm-d
   LET s=s*mm

   LET d=d+2 !1,3,5,7,… 奇数
NEXT i

PRINT s

END
 

Parabola Mandala (幾何学アート)

 投稿者:yossy  投稿日:2009年 3月 7日(土)11時59分10秒
返信・引用
  !Parabola Mandala(幾何学アート)
OPTION ANGLE DEGREES
SUB circle(a,b,r)
   FOR t=0 TO 360
      PLOT LINES: a+r*COS(t),b+r*SIN(t);
   NEXT t
   PLOT LINES
END SUB
DEF f(x)=x^2-x
LET c=(2*SQR(2))
LET d=(12*SQR(2))/5
LET e=(4-c)
LET g=24/5
LET h=(SQR(2)-1)
DIM M(4,4)!図形の裏返し
MAT READ M
DATA 0, 1, 0, 0
DATA 1, 0, 0, 0
DATA 0, 0, 1, 0
DATA 0, 0, 0, 1
!Lotus Mandala(右側の曼荼羅)
SET BITMAP SIZE 800,400
SET WINDOW -6.8,6.8,-6.8,6.8
SET VIEWPORT 0.5,1.0,0,0.5
CALL circle(0,0,c)
CALL circle(d,-d,e)
CALL circle(-d,d,e)
CALL circle(d,d,e)
CALL circle(-d,-d,e)
CALL circle(0,g,e)
CALL circle(0,-g,e)
CALL circle(g,0,e)
CALL circle(-g,0,e)
DRAW nike
DRAW nike WITH ROTATE(90)
DRAW nike WITH ROTATE(180)
DRAW nike WITH ROTATE(270)
DRAW nike WITH M
DRAW nike WITH M*ROTATE(90)
DRAW nike WITH M*ROTATE(180)
DRAW nike WITH M*ROTATE(270)
DRAW pothos WITH SCALE(h)*SHIFT(d,-d)
DRAW pothos WITH SCALE(h)*ROTATE(180)*SHIFT(-d,d)
DRAW pothos WITH SCALE(h)*ROTATE(90)*SHIFT(d,d)
DRAW pothos WITH SCALE(h)*ROTATE(270)*SHIFT(-d,-d)
DRAW pothos WITH M*SCALE(h)*ROTATE(180)*SHIFT(0,g)
DRAW pothos WITH M*SCALE(h)*SHIFT(0,-g)
DRAW pothos WITH M*SCALE(h)*ROTATE(90)*SHIFT(g,0)
DRAW pothos WITH M*SCALE(h)*ROTATE(270)*SHIFT(-g,0)
!Pothos Mandala(左側の曼荼羅)
SET BITMAP SIZE 800,400
SET WINDOW -6.8,6.8,-6.8,6.8
SET VIEWPORT 0,0.5,0,0.5
CALL circle(0,0,c)
CALL circle(d,-d,e)
CALL circle(-d,d,e)
CALL circle(d,d,e)
CALL circle(-d,-d,e)
CALL circle(0,g,e)
CALL circle(0,-g,e)
CALL circle(g,0,e)
CALL circle(-g,0,e)
DRAW pothos
DRAW pothos WITH SCALE(h)*SHIFT(d,-d)
DRAW pothos WITH SCALE(h)*ROTATE(180)*SHIFT(-d,d)
DRAW pothos WITH SCALE(h)*ROTATE(90)*SHIFT(d,d)
DRAW pothos WITH SCALE(h)*ROTATE(270)*SHIFT(-d,-d)
DRAW pothos WITH M*SCALE(h)*ROTATE(180)*SHIFT(0,g)
DRAW pothos WITH M*SCALE(h)*SHIFT(0,-g)
DRAW pothos WITH M*SCALE(h)*ROTATE(90)*SHIFT(g,0)
DRAW pothos WITH M*SCALE(h)*ROTATE(270)*SHIFT(-g,0)
PICTURE nike
   FOR x=0 TO 2 STEP 0.01
      PLOT LINES: x,f(x);
   NEXT x
   FOR x=9/4 TO 1/4 STEP -0.01
      PLOT LINES: x-1/4,f(x)-13/16;
   NEXT x
END PICTURE
PICTURE pothos
   FOR y=-2 TO 1 STEP 0.01
      PLOT LINES: -f(ABS(y)),y;
   NEXT y
   FOR x=-1/4 TO -9/4 STEP -0.01
      PLOT LINES: x+1/4,SGN(x)*f(ABS(x))+13/16;
   NEXT x
   FOR x=-2 TO 2 STEP 0.01
      PLOT LINES: x,SGN(x)*f(ABS(x));
   NEXT x
END PICTURE
END

http://www15.plala.or.jp/pothos/

 

Heart Magic (幾何学アート)

 投稿者:yossy  投稿日:2009年 3月 7日(土)12時36分29秒
返信・引用
  以前、第1掲示板で掲載させていただいた動画プログラムの、簡略版です。アニメーションの結果の画像をその下に載せてあります。新しく開設した私のウェブサイトに、幾何学アートのプログラミング・データを置いていますので、よろしければぜひ一度覗いてみてください。

!Heart Magic(幾何学アート)
OPTION ANGLE DEGREES
DEF f(x)=x^2-x
DEF g(x)=-x^2-x
DEF h(x)=-x^2+1/2*x+1
DEF i(y)=y^2-y
DEF j(y)=y^2+1/2*y-1
DEF k(y)=y^2-1/2*y-1
DEF l(y)=-y^2+1/2*y+1
DIM M(4,4)
MAT READ M !図形の裏返し
DATA 0, 1, 0, 0
DATA 1, 0, 0, 0
DATA 0, 0, 1, 0
DATA 0, 0, 0, 1
SET WINDOW -9.2,9.2,-9.2,9.2
!集合
FOR n=6.9 TO 0 STEP -0.01
   SET DRAW mode hidden
   CLEAR
   DRAW pothos WITH M*ROTATE(180)*SHIFT(0,n)
   DRAW pothos WITH M*SHIFT(0,-n)
   DRAW pothos WITH M*ROTATE(90)*SHIFT(n,0)
   DRAW pothos WITH M*ROTATE(270)*SHIFT(-n,0)
   DRAW pothos WITH SHIFT(n,-n)
   DRAW pothos WITH ROTATE(180)*SHIFT(-n,n)
   DRAW pothos WITH ROTATE(90)*SHIFT(n,n)
   DRAW pothos WITH ROTATE(270)*SHIFT(-n,-n)
   WAIT DELAY 0.01
   SET DRAW mode explicit
NEXT n
WAIT DELAY 8
!発散
FOR n=0 TO 6.9 STEP 0.01
   SET DRAW mode hidden
   CLEAR
   DRAW heart1 WITH SHIFT(-n,n)
   DRAW heart1 WITH ROTATE(180)*SHIFT(-n/3,n)
   DRAW heart1 WITH M*SHIFT(n/3,n)
   DRAW heart1 WITH ROTATE(90)*SHIFT(n,n)
   DRAW heart2 WITH SHIFT(-n,n/3)
   DRAW heart2 WITH ROTATE(180)*SHIFT(-n/3,n/3)
   DRAW heart2 WITH ROTATE(90)*SHIFT(n/3,n/3)
   DRAW heart2 WITH ROTATE(270)*SHIFT(n,n/3)
   DRAW heart3 WITH SHIFT(-n,-n/3)
   DRAW heart3 WITH ROTATE(180)*SHIFT(-n/3,-n/3)
   DRAW heart3 WITH ROTATE(90)*SHIFT(n/3,-n/3)
   DRAW heart3 WITH ROTATE(270)*SHIFT(n,-n/3)
   DRAW heart3 WITH M*ROTATE(180)*SHIFT(-n,-n)
   DRAW heart3 WITH M*SHIFT(-n/3,-n)
   DRAW heart3 WITH M*ROTATE(90)*SHIFT(n/3,-n)
   DRAW heart3 WITH M*ROTATE(270)*SHIFT(n,-n)
   WAIT DELAY 0.01
   SET DRAW mode explicit
NEXT n
PICTURE heart1
   FOR x=-1 TO 1 STEP 0.01
      PLOT LINES: x,f(ABS(x));
   NEXT x
   FOR y=0 TO (1+SQR(17))/4 STEP 0.01
      PLOT LINES: l(y),y;
   NEXT y
   FOR y=(1+SQR(17))/4 TO 0 STEP -0.01
      PLOT LINES: k(y),y;
   NEXT y
END PICTURE
PICTURE heart2
   FOR x=-1 TO 0 STEP 0.01
      PLOT LINES: x,g(x);
   NEXT x
   FOR y=0 TO 1 STEP 0.01
      PLOT LINES: i(y),y;
   NEXT y
   FOR x=0 TO 2 STEP 0.01
      PLOT LINES: x,h(x);
   NEXT x
   FOR y=-2 TO 0 STEP 0.01
      PLOT LINES: j(y),y;
   NEXT y
END PICTURE
PICTURE heart3
   FOR y=-2 TO 1 STEP 0.01
      PLOT LINES: -f(ABS(y)),y;
   NEXT y
   FOR x=-1/4 TO -9/4 STEP -0.01
      PLOT LINES: x+1/4,SGN(x)*f(ABS(x))+13/16;
   NEXT x
END PICTURE
PICTURE pothos
   FOR y=-2 TO 1 STEP 0.01
      PLOT LINES: -f(ABS(y)),y;
   NEXT y
   FOR x=-1/4 TO -9/4 STEP -0.01
      PLOT LINES: x+1/4,SGN(x)*f(ABS(x))+13/16;
   NEXT x
   FOR x=-2 TO 2 STEP 0.01
      PLOT LINES: x,SGN(x)*f(ABS(x));
   NEXT x
END PICTURE
END

http://www15.plala.or.jp/pothos/

 

部分分数分解

 投稿者:山中和義  投稿日:2009年 3月 8日(日)14時52分16秒
返信・引用
  変数xの有理式

           B(n-1)*x^(n-1)+B(n-2)*x^(n-2)+ … +B(1)*x+B(0)
---------------------------------------------------------
  A(n)*x^n+A(n-1)*x^(n-1)+A(n-2)*x^(n-2)+ … +A(1)*x+A(0)

とする。分母の多項式が、
 (x-α1)*(x-α2)* … *(x-αn) ※重根は含まない
と因数分解可能のとき

    k1        k2             kn
------- + ------- + … + -------
(x-α1)   (x-α2)        (x-αn)

と部分分数に分解できる。

LET N=3 !次数

DIM A(0 TO N),B(0 TO N-1) !係数

DATA 6,-1,-3 !分子 6*x^2-x-3
DATA 1,0,-1,0 !分母 x^3-x=x*(x+1)*(x-1)
DATA 0,1 !根,重複度
DATA -1,1
DATA 1,1

!DATA 0,1,1 !分子 s+1
!DATA 1,-5,8,-4 !分母 s^3-5*s^2+8*s-4=(s-1)*(s-2)^2
!DATA 1,1 !根,重複度
!DATA 2,2

FOR i=N-1 TO 0 STEP -1
   READ B(i)
NEXT i
FOR i=N TO 0 STEP -1
   READ A(i)
NEXT i


!ヘヴィサイド(Heaviside)の展開定理
! F(x)=B(x)/A(x)とする。
! x-αが分母A(x)の重複度1の因数とすると
! 部分分数 C/(x-α) の係数は、C=(x-α)*F(x)│x=αとなる。
!
! x-αが分母A(x)の重複度mの因数とすると
! 部分分数 C1/(x-α)+C2/(x-α)^2+ … +Cm/(x-α)^m の係数は、
! Cm-k=1/k!*d^k/dx^k{(x-α)^m*F(x)}│x=α、k=0,1,2,…,m-1となる。

DIM Q(0 TO N),T1(0 TO 4*N),T2(0 TO 4*N) !作業用
DIM AA(0 TO 2*N),BB(0 TO 2*N),dA(0 TO 2*N),dB(0 TO 2*N)

LET Lp=N
DO WHILE Lp>0 !各根に対して
   READ v,m !α、重複度

   SELECT CASE m
   CASE 1 !単根なら
      CALL poly_divByLin(A,v, Q,R) !(x-α)*F(x)=B(x)/(A(x)/(x-α))
      CALL PrintOut(B,Q,0,v)

   CASE ELSE !重複根なら
      MAT AA=A
      MAT BB=B

      FOR j=1 TO m !(x-α)^m*F(x)の0階微分
         CALL poly_divByLin(AA,v, Q,R) !(x-α)^m*F(x)=B(x)/(A(x)/(x-α)^m)
         MAT AA=Q
      NEXT j
      CALL PrintOut(BB,AA,m,v) !Cm

      FOR k=1 TO m-1 !k階微分
      !微分の公式 (B/A)'=(B'*A-B*A')/A^2
         CALL poly_diff(BB, dB) !B'
         CALL poly_diff(AA, dA) !A'
         CALL poly_mul(dB,AA, T1) !分子
         CALL poly_mul(BB,dA, T2)
         MAT T1=T1-T2
         CALL poly_copy(T1, BB)
         CALL poly_mul(AA,AA, T1) !分母
         CALL poly_copy(T1, AA)

         CALL PrintOut(BB,AA,m-k,v/fact(k)) !Cm-k
      NEXT k

   END SELECT


   LET Lp=Lp-m !次へ
LOOP


SUB PrintOut(B(),A(),k,v) !分数を表示する
   PRINT poly_val(B,v)/poly_val(A,v); !分子側=C

   IF v>0 THEN !分母側=x-α
      PRINT "/ ( x -";v;")";
   ELSEIF v<0 THEN
      PRINT "/ ( x +";ABS(v);")";
   ELSE
      PRINT "/ x ";
   END IF
   IF k>1 THEN PRINT " ^";k ELSE PRINT !べき乗
END SUB

END


!補助ルーチン

!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)

!演算関連

EXTERNAL FUNCTION poly_degree(A()) !次数を得る
FOR i=UBOUND(A) TO 1 STEP -1
   IF A(i)<>0 THEN EXIT FOR !係数が0でない最初の位置
NEXT i
LET poly_degree=i
END FUNCTION

EXTERNAL SUB poly_divByLin(A(),v, Q(),R) !多項式a(x)をx-αで割ったときの商q(x)と余りRを求める
MAT Q=ZER
LET aa=poly_degree(A) !次数
IF aa>0 THEN !1次式以上なら
   LET qq=aa-1 !次数
   LET Q(qq)=A(aa) !商 ※組立除法
   FOR i=qq TO 1 STEP -1
      LET Q(i-1)=A(i)+Q(i)*v
   NEXT i
   LET R=A(0)+Q(0)*v !余り
ELSE
   LET Q(0)=0 !商
   LET R=A(0) !余り
END IF
END SUB

EXTERNAL FUNCTION poly_val(A(),v) !多項式を計算する(数値代入)
LET k=0
FOR i=UBOUND(A) TO 0 STEP -1 !Hornerの方法
   LET k=k*v+A(i) !(…(((An*X+An-1)*X+An-2)*X+An-3)*X+…+A1)*X+A0
NEXT i
LET poly_val=k
END FUNCTION

EXTERNAL SUB poly_copy(A(), S()) !代入 S=A
MAT S=ZER
FOR i=0 TO UBOUND(S)
   LET S(i)=A(i)
NEXT i
END SUB

EXTERNAL SUB poly_mul(A(),B(), S()) !乗算 S=A*B ※S≠A、S≠B
MAT S=ZER
FOR i=UBOUND(A) TO 0 STEP -1
   FOR j=UBOUND(B) TO 0 STEP -1
      LET S(i+j)=S(i+j)+A(i)*B(j) !すべての係数をかける
   NEXT j
NEXT i
END SUB

EXTERNAL SUB poly_diff(A(), S()) !微分 S=A'
FOR i=1 TO UBOUND(A)
   LET S(i-1)=i*A(i)
NEXT i
END SUB
 

Re: 部分分数分解

 投稿者:山中和義  投稿日:2009年 3月 8日(日)22時42分25秒
返信・引用
  > No.299[元記事へ]

別解. 通分して分子側の多項式の係数B()と比較して、恒等式(連立方程式)を解く
LET N=3 !次数

DIM A(0 TO N),B(0 TO N-1) !係数

!DATA 6,-1,-3 !分子 6*x^2-x-3
!DATA 1,0,-1,0 !分母 x*(x^2-1)
!DATA 0,1 !根,重複度
!DATA -1,1
!DATA 1,1

DATA 0,1,1 !分子 s+1
DATA 1,-5,8,-4 !分母 s^3-5*s^2+8*s-4=(s-1)*(s-2)^2
DATA 1,1 !根,重複度
DATA 2,2

FOR i=N-1 TO 0 STEP -1
   READ B(i)
NEXT i
FOR i=N TO 0 STEP -1
   READ A(i)
NEXT i


DIM C(N,N),k(N) !連立方程式 C*k=B
DIM Q(0 TO N) !分母がx-αkの(通分したときの)分子側の係数

DIM AA(0 TO N),v(N),m(N)

LET Lp=1
DO UNTIL Lp>N !各根に対して
   READ v(Lp),m(Lp) !1次因子x-αk、重複度m

   CALL poly_divByLin(A,v(Lp), Q,R) !通分したときの係数=(分母側の多項式)/(x-αk)
   FOR j=1 TO N !Lp列目に設定する
      LET C(j,Lp)=Q(j-1)
   NEXT j

   FOR i=1 TO m(Lp)-1 !重複根なら
      MAT AA=Q

      CALL poly_divByLin(AA,v(Lp), Q,R) !通分したときの係数=(分母側の多項式)/(x-αk)^m
      FOR j=1 TO N !Lp+i列目に設定する
         LET C(j,Lp+i)=Q(j-1)
      NEXT j
   NEXT i

   LET Lp=Lp+m(Lp) !次へ
LOOP
!!!MAT PRINT C; !debug


DIM Ci(N,N) !恒等式を解く
MAT Ci=INV(C)
MAT k=Ci*B


LET Lp=1 !結果を表示する
DO UNTIL Lp>N
   FOR i=0 TO m(Lp)-1
      CALL PrintOut(k(Lp+i),v(Lp),i+1)
   NEXT i
   LET Lp=Lp+m(Lp) !次へ
LOOP

SUB PrintOut(c,v,k) !分数を表示する
   PRINT c; !分子側=C

   IF v>0 THEN !分母側=x-α
      PRINT "/ ( x -";v;")";
   ELSEIF v<0 THEN
      PRINT "/ ( x +";ABS(v);")";
   ELSE
      PRINT "/ x ";
   END IF
   IF k>1 THEN PRINT " ^";k ELSE PRINT !べき乗
END SUB

END


!補助ルーチン

!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)

!演算関連

EXTERNAL FUNCTION poly_degree(A()) !次数を得る
FOR i=UBOUND(A) TO 1 STEP -1
   IF A(i)<>0 THEN EXIT FOR !係数が0でない最初の位置
NEXT i
LET poly_degree=i
END FUNCTION

EXTERNAL SUB poly_divByLin(A(),v, Q(),R) !多項式a(x)をx-αで割ったときの商q(x)と余りRを求める
MAT Q=ZER
LET aa=poly_degree(A)
IF aa>0 THEN !1次式以上なら
   LET qq=aa-1 !次数
   LET Q(qq)=A(aa) !商 ※組立除法
   FOR i=qq TO 1 STEP -1
      LET Q(i-1)=A(i)+Q(i)*v
   NEXT i
   LET R=A(0)+Q(0)*v !余り
ELSE
   LET Q(0)=0 !商
   LET R=A(0) !余り
END IF
END SUB
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 3月 9日(月)21時48分27秒
返信・引用  編集済
  > No.296[元記事へ]

組立除法の(意外な)使い道
・関数値 - 記数法の計算、平均変化率、定積分
・微分係数 - 多項式のテイラー展開、ニュートン法による代数方程式の求根
これらを用いるシーンで利用できる。

その一例をコーディングしてみました。
!●記数法の計算

LET N=5 !桁数
DATA 1,1,0,1,0,1 !2進法 110101

DIM A2(0 TO N),Q2(0 TO N)
FOR i=N TO 0 STEP -1
   READ A2(i)
NEXT i
CALL poly_divByLin(A2,2, Q2,R) !p(x)/(x-2)
PRINT R !10進法



!●多項式のテイラー展開

LET N=4 !次数
DATA 1,-2,-20,23,13 !x^4-2*x^3-20*x^2+23*x+13
DATA 5 !x=a

DIM A(0 TO N) !係数
FOR i=N TO 0 STEP -1
   READ A(i)
NEXT i
READ v


DIM Q(0 TO N),AA(0 TO N) !作業用

MAT AA=A
FOR i=0 TO N-1 !Σf[k](a)/k!*(x-a)^k
   CALL poly_divByLin(AA,v, Q,R) !k階微分係数 ※<----------
   PRINT R;" * ( x -";v;") ^";i

   MAT AA=Q !次へ
NEXT i
PRINT Q(0);" * ( x -";v;") ^";N



!●代数方程式の根をニュートン法で求める(関数値、微分係数)

LET cEps=1e-10 !精度  ※要調整

LET N=3 !次数
DATA 1,-2,0,-9 !x^3-2*x^2-9=(x-3)*(x^2+x+3)

LET Xk=2 !近似根

DIM A3(0 TO N),Q3(0 TO N),QQ3(0 TO N)
FOR i=N TO 0 STEP -1
   READ A3(i)
NEXT i

LET iter=200 !反復回数
FOR k=1 TO iter
   CALL poly_divByLin(A3,Xk, Q3,f) !関数値※<----------
   CALL poly_divByLin(Q3,Xk, QQ3,df) !微分係数 ※<----------
   LET WXk=Xk-f/df !Xk+1=Xk-f(Xk)/f'(Xk)
   IF ABS(WXk-Xk)<=ABS(Xk)*cEps THEN EXIT FOR !収束すれば終了
   LET Xk=WXk !次へ
NEXT k
IF k>iter THEN
   PRINT iter;"回では収束しません。"
   STOP
END IF

PRINT USING "## ##.###############": k,Xk


END


!補助ルーチン

!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)

!演算関連

EXTERNAL FUNCTION poly_degree(A()) !次数を得る
FOR i=UBOUND(A) TO 1 STEP -1
   IF A(i)<>0 THEN EXIT FOR !係数が0でない最初の位置
NEXT i
LET poly_degree=i
END FUNCTION

EXTERNAL SUB poly_divByLin(A(),v, Q(),R) !多項式a(x)をx-αで割ったときの商q(x)と余りrを求める
MAT Q=ZER
LET s=0
FOR i=poly_degree(A) TO 0 STEP -1 !ホーナーの方法
   LET Q(i)=s !※「係数にxを掛けて次の係数を加える」が組立除法になる
   LET s=s*v+A(i) !(…(((An*X+An-1)*X+An-2)*X+An-3)*X+…+A1)*X+A0
NEXT i
LET R=s
END SUB
 

!同値データーを安定化する、クイック・ソート

 投稿者:SECOND  投稿日:2009年 3月10日(火)18時49分59秒
返信・引用  編集済
  !同値データーを安定化する、クイック・ソート

! クイック・ソートは、今でも最速の部類にありながら、
!同じ評価値の、名札の順番が、ソート後に、乱れる難点があります。
!それを、拡張された下位桁の内部付加で、補償した。
!所要時間が、約1.25倍程度( ソート数 99999個 で測った) に遅く
!なりましたが、まだ、速い方です。
!
! 処理後の(ソート値)が、同値で並んでいるサンプル番号( No: )を、
! 処理前のサンプル番号( No: )の並びと、比べて下さい。
!----------------------------------------------------------
!
!テキスト・ウィンドウの、左上位置(x0,y0)と、幅(xw,yw)。
CALL SetWindowPos( WinHandle("TEXT" ),0, 100,200,800,350, 0)

SUB SetWindowPos( handle,C2, x0,y0,xw,yw, nFLG ) ! nFLG: 0=x0y0xwyw 1=x0y0 2=xwyw
   ASSIGN "user32.dll","SetWindowPos"
END SUB

!----------------------------------------------------------
LET SU=999 ! サンプルのデーター数
DIM NO_(SU), VA$(SU) ! サンプル番号、ソートするサンプルの値
DIM stb(SU) ! 同値データー順番を、安定化する拡張配列
!
LET u_$=REPEAT$("#",LEN(STR$(SU)))
LET u0$=REPEAT$("%",LEN(STR$(SU)))

SUB PRNdata(w$)
   MAT PRINT USING "      / No: "& REPEAT$(u_$& " ",SU): NO_
   MAT PRINT USING w$&     " 値: "& REPEAT$(u_$& " ",SU): VA$
END SUB

SUB Ready
!--- サンプルの作成
   RANDOMIZE 19650218 !デフォールトRND の繰返し再生
   FOR i=1 TO SU
      LET NO_(i)=i ! サンプル番号、固有のIDだが、乱れの識別のため登録順と同じにする。
      LET VA$(i)=USING$(u0$,SU*RND) ! ソートする評価値
   NEXT i
   !---
   FOR i=1 TO SU
      LET stb(i)=i ! 同値 の登録順の安定用番号( サンプルの登録順番号 )
   NEXT i
   CALL PRNdata("元の順\")
   LET t0=TIME
END SUB

SUB Result(w$)
!--- 結果のプリント
   LET t1=TIME-t0
   IF t1< 0 THEN LET t1=t1+86400
   CALL PRNdata("ソート\")
   FOR i=2 TO SU
      IF VA$(i-1)>VA$(i) THEN EXIT FOR
   NEXT i
   IF SU< i THEN PRINT w$& ": ソート時間:";t1;"sec." ELSE  PRINT w$& ": Error!"
   PRINT
END SUB

!----
CALL Ready
CALL Qsort(1,SU)
CALL Result("安定クイック")
!
CALL Ready
CALL Qsort00(1,SU)
CALL Result("通常クイック")
!
PRINT "※時間計測は、±0.05 sec 程度、無意味なバラツキ有り、"&
&& "データー数>=9999 以上で測って下さい。"
PRINT " 現在のデーター数:";SU;

!------
! 順序を安定化した、クイック・ソート
SUB Qsort(L,R)
   local i,j
   LET i=L
   LET j=R
   LET v$=VA$((L+R)/2)
   LET ss=stb((L+R)/2)
   DO
      DO WHILE VA$(i)< v$ OR (VA$(i)=v$ AND stb(i)< ss)
         LET i=i+1
      LOOP
      DO WHILE v$< VA$(j) OR (VA$(j)=v$ AND ss< stb(j))
         LET j=j-1
      LOOP
      IF j< i THEN EXIT DO
      SWAP NO_(i),NO_(j)
      SWAP VA$(i),VA$(j)
      SWAP stb(i),stb(j)
      LET i=i+1
      LET j=j-1
   LOOP UNTIL j< i
   IF L< j THEN CALL Qsort(L,j)
   IF i< R THEN CALL Qsort(i,R)
END SUB

!------
! 通常のクイック・ソート(比較用)
SUB Qsort00(L,R)
   local i,j
   LET i=L
   LET j=R
   LET v$=VA$((L+R)/2)
   DO
      DO WHILE VA$(i)< v$
         LET i=i+1
      LOOP
      DO WHILE v$< VA$(j)
         LET j=j-1
      LOOP
      IF j< i THEN EXIT DO ! 等号付 j<=i は、暴走。
      SWAP NO_(i),NO_(j)
      SWAP VA$(i),VA$(j)
      LET i=i+1
      LET j=j-1
   LOOP UNTIL j< i ! 等号付 j<=i は、低速。
   IF L< j THEN CALL Qsort00(L,j)
   IF i< R THEN CALL Qsort00(i,R)
END SUB

END
 

Re: 状態方程式から伝達関数を求める

 投稿者:山中和義  投稿日:2009年 3月10日(火)20時51分18秒
返信・引用  編集済
  > No.302[元記事へ]

大熊 正さんへのお返事です。


 状態方程式 x'(t)=A*x(t)+b*u(t)
 出力方程式 y(t)=C*x(t)
の意味は、

 系 u(入力)→ [ x'=A*x+b*u、y=c*x ] → y(出力)
を表します。

簡単な例をあげて算出方法を紹介します。

●RC回路の場合

  Vi─R1─┬─Vo
u →   x C1  → y
      │
      ≡

ここで、C1にかかる電圧をxとします。

状態方程式は、C1に流れる電流i=C1*dx/dt=C1*x'より、C1*x'=(Vi-Vo)/R1=(u-x)/R1
したがって、x'=-1/(C1*R1)*x+1/(C1*R1)*u

また、出力方程式は、y=Vo=x


行列(1×1)で表すと
[x']=[-1/(C1*R1)][x] + [1/(C1*R1)]*[u]
[y]=[x]

これより
 A=-1/(C1*R1)
 b=1/(C1*R1)
 c=1
となります。



●オペアンプ正帰還型ローパス・フィルタの場合
   ┌C1┬──┐
   │ └ - │
Vi─R1┴R2┬ + K┴─Vo
     C2
     │
     ≡

C1,C2にかかる電圧をx1,x2、電流をi1,i2とします。
R1,R2,C2経路、Vi=(i1+i2)*R1+i2*R2+x2 … (1)
R1,C1,Vo経路、Vi=(i1+i2)*R1+x1+Vo … (2)
電流、i1=C1*x1'、i2=C2*x2' … (3),(4)
オペアンプ、Vo=K*x2 … (5)

u=Vi=(1)=(2)、(4)より、x2'=(x1+(K-1)*x2)/(R2*C2) … (6)

(1)に(3),(4)を代入してi1,i2を消す。さらに(6)を代入してx2を消すと
x1'=-(R1+R2)/(R1*R2*C1)*x1 -{(K-1)*(R1+R2)+R2}/(R1*R2*C1)*x2 +(1/(R1*C1))*u … (7)

この(6),(7)が状態方程式を表します。

また、出力方程式は(5)より、y=Vo=K*x2 … (8)


サンプル ※元のプログラムではC1,C2が重複するため、係数の変数名を変更してあります。
!行列関連
FUNCTION tr(A(,)) !行列Aのトレース
   LET t=0
   FOR i=1 TO N
      LET t=t+A(i,i)
   NEXT i
   LET tr=t
END FUNCTION

!多項式関連
SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
   IF k<>0 THEN !x^nで
      IF ak=1 THEN !係数が1なら
      ELSEIF ak=-1 THEN !係数が−1なら
         PRINT "-";
      ELSE
         PRINT STR$(ak);"*";
      END IF
   END IF
   IF k=0 THEN !次数が0なら
      PRINT STR$(ak);
   ELSEIF k=1 THEN !次数が1なら
      PRINT "s";
   ELSE
      PRINT "s^";STR$(k);
   END IF
END SUB
!-------------------- ここまでがサブルーチン


!系 u(入力)→ [ x'=A*x+b*u、y=c*x ] →y(出力)

!---------- ↓↓↓↓↓ ----------
LET N=2 !状態変数の数

DIM A(N,N),b(N,1),c(1,N)

LET R1=30e3 !30k[Ω]
LET R2=18e3 !18k[Ω]
LET C1=0.01e-6 !0.01μ[F]
LET C2=0.0047e-6 !0.0047μ[F]
LET K=1 !ボルテージ・フォロワより、アンプの増幅率は1

LET A(1,1)=-(R1+R2)/(R1*R2*C1)
LET A(1,2)=-((K-1)*(R1+R2)+R2)/(R1*R2*C1)
LET A(2,1)=1/(R2*C2)
LET A(2,2)=(K-1)/(R2*C2)

LET b(1,1)=1/(R1*C1)
LET b(2,1)=0

LET c(1,1)=0
LET c(1,2)=K
!---------- ↑↑↑↑↑ ----------


!Frame法、Leverrir-Faddeev法
! adj(s*I-A)=s^(n-1)*I+s^(n-2)*β1+ … +s*βn-2+βn-1
! det(s*I-A)=s^n+α1*s^(n-1)+ … + αn-1*s+αn
!のとき
! β0=I、k=1〜nについて
!  Xk=A*βk-1
!  αk=-trace(Xk)/k
!  βk=Xk+αk*I
!の逐次計算でαk、βkが求まる。

DIM p1(N) !分子側の多項式 c(1)*X^(N-1)+c(2)*X^(N-2)+ … +c(N-1)*X+c(N) の係数
DIM p2(N) !分母側の多項式 X^N+c(1)*X^(N-1)+c(2)*X^(N-2)+ … +c(N-1)*X+c(N) の係数
DIM X(N,N),sE(N,N),T1(1,N),T2(1,1) !作業用

MAT X=IDN !adj(s*I-A)
FOR k=1 TO N
   MAT PRINT X; !debug
   MAT T1=c*X !c*adj(s*I-A)*b ※定数*多項式*定数
   MAT T2=T1*b
   LET p1(k)=T2(1,1)

   MAT X=A*X
   LET p2(k)=-tr(X)/k !det(s*I-A)
   MAT sE=(p2(k))*IDN
   MAT X=X+sE
NEXT k


!※既約分数でない

!!!MAT PRINT p1; !debug
PRINT "分子= ";
FOR i=1 TO N !分子側の多項式を表示する
   LET w=p1(i)
   IF w>0 THEN PRINT "+";
   IF w<>0 THEN CALL mono_disp(w,N-i)
NEXT i
PRINT

!!!MAT PRINT p2; !debug
PRINT "分母= ";
CALL mono_disp(1,N) !分母側の多項式を表示する
FOR i=1 TO N
   LET w=p2(i)
   IF w>0 THEN PRINT "+";
   IF w<>0 THEN CALL mono_disp(w,N-i)
NEXT i


END
 

Re: 状態方程式から伝達関数を求める

 投稿者:山中和義  投稿日:2009年 3月11日(水)11時42分34秒
返信・引用  編集済
  > No.304[元記事へ]

補足

●伝達関数を求める
状態方程式 (6),(7)
 [ x1' ] = [ -(R1+R2)/(R1*R2*C1)  -{(K-1)*(R1+R2)+R2}/(R1*R2*C1) ] [ x1 ] + [ 1/(R1*C1) ] [ u ]
 [ x2' ]  [ 1/(R2*C2)            (K-1)/(R2*C2)                  ] [ x2 ]   [ 0         ]
出力方程式 (8)
 [ y ] = [ 0  K ] [ x1 ]
          [ x2 ]
と行列で表される。

K=1とすると
A=[ -(R1+R2)/(R1*R2*C1)  -1/(R1*C1) ]
  [ 1/(R2*C2)            0          ]

c=[ 0  1 ]


伝達関数 G(s)
=c*INV(s*I-A)*b
=[ 0  1 ] [ s+(R1+R2)/(R1*R2*C1)  1/(R1*C1) ]-1 [ 1/(R1*C1) ]
          [ -1/(R2*C2)            s         ]   [ 0         ]

まず、(s*I-A)の逆行列は
 [a b]-1 = 1/(a*d-b*c)[d -b] より
 [c d]                [-c a]

INV(s*I-A)
=[ s+(R1+R2)/(R1*R2*C1)  1/(R1*C1) ]-1
 [ -1/(R2*C2)            s         ]
=1/{(s+(R1+R2)/(R1*R2*C1))*s + 1/(R1*R2*C1*C2)} * [ s          -1/(R1*C1)           ]
                                                  [ 1/(R2*C2)  s+(R1+R2)/(R1*R2*C1) ]
となる。この場合、係数部分の分母が伝達関数の分母になる。

また、行列部分は
[ 0  1 ] * 上記 * [ 1/(R1*C1) ]
                  [ 0         ]
=[ 1/(R2*C2)  s+(R1+R2)/(R1*R2*C1) ] [ 1/(R1*C1) ]
                                     [ 0         ]
=1/(R1*R2*C1*C2)
となる。こらが伝達関数の分子になる。

したがって
G(s)
=1/(R1*R2*C1*C2) * 1/{ (s+(R1+R2)/(R1*R2*C1))*s + 1/(R1*R2*C1*C2) }
={ 1/(R1*R2*C1*C2) } / { (s^2+{1/(R2*C1)+1/(R1*C1)}*s + 1/(R1*R2*C1*C2) }


●最近の投稿のネタです。
回路解析
 キルヒホッフの法則
  直流回路、交流回路
  定常状態、過渡状態

  連立方程式を解く(代数方程式による表現)
   枝路電流法
    ┌±1┐[i]=┌0┐
    └ Z ┘  └E┘
   網目解析
    網目(閉路)電流法(閉路方程式 Z*I=E)
   節点解析
    節点電位法(節点方程式 G*E=I)

   抵抗、電流、電圧の計算
   入力電圧と出力電圧の比
    周波数解析
     ボード線図(利得、位相)
     ナイキスト線図


  状態方程式と出力方程式を解く(連立1次常微分方程式による表現)
   ラプラス変換
    伝達関数
     有理式
      零点(分子側の多項式)
      極(分母側の多項式)
       特性方程式の根(固有値)
      代数方程式の根
       DKA法

     システムの応答
      周波数解析
       ボード線図(利得、位相)
       ナイキスト線図
      過渡解析
       逆ラプラス変換
        部分分数分解
         代数方程式の根、組立除法
        逆フーリエ変換

     安定判別
      特性方程式の根、係数
      根軌跡

   オイラー法、ルンゲクッタ法


  フィルタ回路
  増幅器(アペアンプ)
   負帰還、正帰還
   アクティブ・フィルタ回路
 

! 観賞グラフ

 投稿者:SECOND  投稿日:2009年 3月15日(日)03時57分47秒
返信・引用  編集済
  ! 観賞グラフ
! 輝く マンデルブロー( 添付サンプル Complex\mandelbm.bas の着色改変)
!
OPTION ARITHMETIC COMPLEX
SET POINT STYLE 1
!
FOR n=0 TO 50
   SET COLOR MIX(    n) 0   ,0     ,n/51   !BLACK =< < BLUE
   SET COLOR MIX( 51+n) 0   ,n/51  ,1      !BLUE =< < CYAN
   SET COLOR MIX(102+n) 0   ,1     ,1-n/51 !CYAN =< < GREEN
   SET COLOR MIX(153+n) n/51,1     ,0      !GREEN =< < YELLOW
   SET COLOR MIX(204+n) 1   ,1-n/51,0      !YELLOW =< < RED
NEXT n
!SET COLOR MIX(255) 1,0,0 !=RED
SET COLOR MIX(255) 0.549,0.549,0.561 !=GRAY =default
!
LET XL=-2
LET XR=.8
LET w1=XR-XL
LET w2=w1/2
!
SET WINDOW XL, XR,-w2,w2
ASK PIXEL SIZE(XL,-w2; XR,w2) px,py
!
! マンデルブローのμ-map
! f(z)=z^2+μの反復が有界となる複素数μの集合
! 発散の判定に至るまでの繰り返し回数で色分け。
!
FOR x=XL TO XR STEP w1/(px-1)
   FOR y=0 TO w2 STEP w1/(py-1)
      LET z=0
      FOR n=1 TO 255
         LET z=z^2+COMPLEX(x,y)
         IF 2< ABS(z) THEN
            IF n< 64 THEN SET POINT COLOR n*4 ELSE SET POINT COLOR 255
            PLOT POINTS :x,y
            PLOT POINTS :x,-y
            EXIT FOR
         END IF
      NEXT n
   NEXT y
NEXT x

!--------------
pause !一時停止
SET COLOR MIX(0) 1,1,1
CLEAR

! 左へ伸びる白線(無発散領域)は、本来は、細い線で見えない位なので、
! 以下の様にすると、消える。速度が落ちるので、他に方法も・・。
!--------------

FOR x=XL TO XR STEP w1/(px-1)
   FOR y=-w2-w1/(py-1)/2 TO w2 STEP w1/(py-1) !故意に(x,0)を描点の間に挟む。
      LET z=0
      FOR n=1 TO 255
         LET z=z^2+COMPLEX(x,y)
         IF 2< ABS(z) THEN
            IF n< 64 THEN SET POINT COLOR n*4 ELSE SET POINT COLOR 255
            PLOT POINTS :x,y !上下の対象プロットをしない。
            EXIT FOR
         END IF
      NEXT n
   NEXT y
NEXT x

END
 

Re: ! 観賞グラフ

 投稿者:山中和義  投稿日:2009年 3月16日(月)15時03分27秒
返信・引用
  > No.307[元記事へ]

不等式f(x,y)>0の領域がつくる模様

平面は、各関数やそのnの値を変更することで可能です。
単色ですが平面の起伏によって、おもしろい模様が描けます。

また、等高線で色分けするのも良いかと思います。

!不等式f(x,y)>0の領域がつくる模様

!関数の定義 f(x,y)=0
LET n=0.25
DEF g(x,y)=COS(PI*y)-n/COS(PI*x) !n=[-1,1]

!LET n=0.2
!DEF g(x,y)=x*y/n-(x^2+y^2)/(COS(2*PI*x)+COS(2*PI*y)) !n=[0.1,1]

!LET n=0.5
!DEF g(x,y)=COS(2*PI*y)-COS(2*PI*(COS(2*n*PI*x)+COS(2*n*PI*y))) !n=[0.1,2]

!LET n=3
!DEF g(x,y)=COS(PI*x*y/n)-(COS(2*PI*x)+COS(2*PI*y)) !n=[0.1,5]

!LET n=0.2
!DEF g(x,y)=n*COS(PI*x*y)-(SIN(2*PI*x)+SIN(2*PI*y)) !n=[-0.5,0.5]

!LET n=25
!DEF g(x,y)=COS(PI*x*y)-COS(n*x*y/(x^2+y^2)) !n=[1,100]

!LET n=25
!DEF g(x,y)=COS(PI*x*y)-x*y*COS(n*x*y/(x^2+y^2)) !n=[1,100]


LET a=-5 !x=[a,b] ※xy座標の表示領域
LET b=5
LET c=a !y=[c,d]
LET d=b


SET WINDOW a,b,c,d !表示領域を設定する
DRAW grid(1,1) !座標を描く
ASK PIXEL SIZE (a,c; b,d) w,h !画像の縦横の大きさ(ドット単位)を調べる

!条件を満たす領域を描く
SET POINT STYLE 1 !ドット形式
SET POINT COLOR 2
FOR j=1 TO h !画面全体を走査する
   LET y=WORLDY(j) !ドットをxy座標に変換する
   FOR i=1 TO w
      LET x=WORLDX(i)

      WHEN EXCEPTION IN
         LET z=g(x,y) !関数値を計算する
         IF z>0 THEN !正の部分を切り取る
            PLOT POINTS: x,y
         END IF
      USE !0割りなどの例外処理
      END WHEN

   NEXT i
NEXT j

END
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 3月20日(金)21時31分59秒
返信・引用
  > No.301[元記事へ]

> 組立除法の(意外な)使い道
>
> EXTERNAL SUB poly_divByLin(A(),v, Q(),R) !多項式a(x)をx-αで割ったときの商q(x)と余りrを求める
> MAT Q=ZER
> LET s=0
> FOR i=poly_degree(A) TO 0 STEP -1 !ホーナーの方法
>    LET Q(i)=s !※「係数にxを掛けて次の係数を加える」が組立除法になる
>    LET s=s*v+A(i) !(…(((An*X+An-1)*X+An-2)*X+An-3)*X+…+A1)*X+A0
> NEXT i
> LET R=s
> END SUB


前出の組立除法の算出(サブルーチンpoly_divByLin参照)をよく見ると、
ホーナー法による関数値を求めるのと同じです。
したがって、関数値と微分係数はまとめて計算できます。(サブルーチンFxdFx参照)

関数値と微分係数を同時に扱う問題を解いてみます。

!●接線の方程式

!整関数y=f(x)は、組立除法で、y=Q(x)*(x-a)^2+m*(x-a)+nに変形できる。
!y=f(x)上の点P(a,f(a))における接線は、y=m*(x-a)+nになる。

LET N=3 !次数

DATA 1,0,0,0 !y=f(x)=x^3
LET a=1 !点P

DIM A2(0 TO N)
FOR i=N TO 0 STEP -1
   READ A2(i)
NEXT i

CALL FxdFx(N,A2,a, f,df) !関数値と微分係数 ※<----------
PRINT df;"* (x + "; -a;") +";f !y=f'(a)*(x-a)+f(a)



!●代数方程式の根をニュートン法で求める(関数値、微分係数)

LET cEps=1e-10 !精度  ※要調整

!LET N=3 !次数
!DATA 1,-2,0,-9 !x^3-2*x^2-9=(x-3)*(x^2+x+3)
LET N=4
DATA 1,-4,-1,10,6 !(x+1)(x-3)(x^2-2*x-2)

LET Xk=4 !近似根

DIM A3(0 TO N)
FOR i=N TO 0 STEP -1
   READ A3(i)
NEXT i

LET iter=200 !反復回数
FOR k=1 TO iter
   CALL FxdFx(N,A3,Xk, f,df) !関数値と微分係数 ※<----------
   LET WXk=Xk-f/df !Xk+1=Xk-f(Xk)/f'(Xk)
   IF ABS(WXk-Xk)<=ABS(Xk)*cEps THEN EXIT FOR !収束すれば終了
   LET Xk=WXk !次へ
NEXT k
IF k>iter THEN
   PRINT iter;"回では収束しません。"
   STOP
END IF

PRINT USING "## ##.###############": k,Xk


END


!補助ルーチン

!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)

!演算関連

EXTERNAL SUB FxdFx(n,a(),x0, f,df) !関数値f(x0)と微分係数f'(x0)を求める ※n≧1
LET f=a(n)
LET df=f
FOR j=n-1 TO 1 STEP -1 !ホーナー法(組立除法)
   LET f=f*x0+a(j)
   LET df=df*x0+f
NEXT j
LET f=f*x0+a(0)
END SUB
 

ビット列関数

 投稿者:荒田浩二  投稿日:2009年 3月26日(木)14時47分32秒
返信・引用
  白石先生に質問です。

ビット列操作関数BVAL(b$,r),BSTR$(v,r)の第2引数は十進BASICでは2と16の数値定数しか認めていませんが、
JISを読むと数値式やr=8についても認めてもよいように思うのですがいかがでしょうか。

JISの「14.7 ビット列操作」「14.7.4 意味 (1)」の「表14.1 ビット列関数」に
『b$:文字列式;  r,v:指標;  rのとる値: 2, 8又は16だけ』
とありますが「附属書E 生成規則一覧」には
『5.2 指標 = 数値式』
とあります。(指標の定義は 5.2.4 (3)にあります)

また『2, 8又は16だけ』はおそらく "only 2, 8 or 16" のまずい直訳で、意味としては「2,8,16だけ」だと思います。
8についても定義することを要請しているように受け取れます。


いつも素人がわけのわからんことを主張して申し訳ございません。何かしらご教示をいただければ幸いです。
 

Re: ビット列関数

 投稿者:白石 和夫  投稿日:2009年 3月26日(木)18時22分29秒
返信・引用
  > No.310[元記事へ]

BVALとBSTR$はJIS Full BASICでは実時間機能単位で定義されています。
実時間機能を実装しようとすると面倒が多々出てくるので当面その予定はありません。
ですが,2進数,16進数の表現はできないと不便なのでJIS互換となるようにその機能を用意しています。
Full BASICのBVAL(s$,r),BSTR$(n,r)はrの部分を数値式で指定できますが,十進BASICでは定数のみです。
8進に対応するのはさほど難しくないのですが,現在のPC環境でその必要性を感じることがないので省いています。
 

Re: ビット列関数

 投稿者:荒田浩二  投稿日:2009年 3月26日(木)20時40分47秒
返信・引用
  > No.311[元記事へ]

早々にご回答いただきありがとうございます。

実時間機能を省いている以上、本来ビット列関数自体を定義する必要がなく、言わばサービスでつけているということですね。
私の誤解は、ビット列関数を他の組込み関数と同様に捉えていたところにあるようです。
丁寧にご説明いただき理解することができました。ありがとうございました。
 

クイック・ソートのアニメーション

 投稿者:SECOND  投稿日:2009年 4月 1日(水)23時48分4秒
返信・引用  編集済
  > No.303[元記事へ]

!クイック・ソートのアニメーション
!
!写像ソートが使用できない場合、依然、最高速なクイック・ソートの手順。

!概略
! データーが、左(L)から右(R)に並んでいて、右(R)へ向かって昇順に、
! 並び替えたいとする。

!1)データー列 順番の中央位置の値を「基準値」に選ぶ。この値は、
!  全データー値の平均とも限らず、不遇にも一番大きな値や、一番小さな値に
!  選ばれる場合も含まれている。

!2)この「基準値」以上の値のデーターは、R側に、
!  この「基準値」以下の値のデーターは、L側に、2つの領域に分ける。
!  「基準値」は、1)の条件なので、分割の境界が、
!  どちらかの端に寄っていき、不均衡になる事もある。
!  各々の領域は、降順や昇順にする必要は無く、以上と以下に、分ければ良い。

!3)分割された2領域、それぞれは、新たなデーター列として、
!  上の1)2)の操作を同様に行なう。それも又、2つずつに分かれていく。
!  ・・・この繰り返しを、分割領域1つの長さが、1以下になって、
!  分割出来なくなるまで、進めると、全体のソートが終了している。


DIM VA$(100)

SUB div1time(i,j)
!----------  以上の分割を1回行なうブログラム。i=L,j=R で開始。
   LET v$=VA$((i+j)/2)
   DO
      DO WHILE VA$(i)< v$
         LET i=i+1
      LOOP
      DO WHILE v$< VA$(j)
         LET j=j-1
      LOOP
      IF j< i THEN EXIT DO ! 等号付 j<=i は、不良。連続の再帰で暴走する。
      SWAP VA$(i),VA$(j)
      LET i=i+1
      LET j=j-1
   LOOP UNTIL j< i ! 等号付 j<=i は、不適。連続の再帰で低速。
   !----------
END SUB

!上の結果のi,j (L … j)(i … R) を、
!        ↓ ↓ ↓ ↓
!   次のL,R (L … R)(L … R) として、上記の処理を行い、
!   両区間のデーター数が、各々1以下( <=1 )になるまで繰返す。


!===================
SUB QuickSort(L,R) ! 上を、連続に行なうブログラム。
   local i,j
   LET i=L
   LET j=R
   !----------
   ! 上のプログラム("---"の内側)を、ココに置いて、
   ! 再帰的に、繰返し使用。
   !----------
   CALL div1time(i,j) !これでも良い。…再帰文の分離は、local 変数に用心!
   !----------
   IF L< j THEN CALL QuickSort(L,j) !データー数1個以下( L>=j) になるまで。
   IF i< R THEN CALL QuickSort(i,R) !データー数1個以下( i>=R) になるまで。
END SUB


!========================== 上記の動作の、図解アニメーション ============
!LET samp$="079427856083621"
LET samp$="0794278069836215794278560836215806083"
LET L=1
LET R=LEN(samp$)
FOR k=L TO R
   LET VA$(k)=samp$(k:k)
NEXT k
!
SET TEXT background "Opaque"
SET TEXT font "MS ゴシック",11
SET WINDOW -1,40, 30,0
SET LINE width 2
PLOT TEXT,AT 1,1.5:"** クイック・ソートの手順 **"
LET s=26
PLOT TEXT,AT 1,s :"下線の付いた文字は、L~ R 中央位置で選ばれた「基準値」"
PLOT TEXT,AT 1,s+1 :"その「基準値」で、分割された下の段の色分、"
SET COLOR MIX(0) 0,1,1
PLOT TEXT,AT 1,s+2 :"青は「基準値」以下"
SET COLOR MIX(0) 1,1,0
PLOT TEXT,AT 13,s+2 :"黄は「基準値」以上"
SET COLOR MIX(0) 1,1,1
PLOT TEXT,AT 25,s+2 :"(無色:分割不要、確定)"
PLOT TEXT,AT 1,s+3 :"描画の順序は、再帰文としての、実行順序そのまま。"
LET s=3
!
CALL plotVA(L,R,s,L,R)
CALL GraphQS(L,R)
CALL plotVA(L,R,m+1,L,R)

SUB GraphQS(L,R) ! 分割繰返しの構造を、グラフィックに表示。
   local i,j
   LET i=L
   LET j=R
   LET s=s+1
   SET COLOR MIX(0) 1,1,1
   PLOT TEXT,AT L,s :"L"
   PLOT TEXT,AT R,s :"R"
   LET s=s+1
   !----------
   CALL div1time(i,j) !← 冒頭の(分割を1回行なう・・)文を、実際に使用。
   CALL plotVA(L,R,s,i,j)
   IF m< s THEN LET m=s
   WAIT DELAY .1 ! 描画の速さの調整。
   !----------
   IF L< j THEN CALL GraphQS(L,j)
   IF i< R THEN CALL GraphQS(i,R)
   LET s=s-2
END SUB

SUB plotVA(L,R,y,i,j)
   FOR x=L TO R
      IF L=i AND R=j THEN
         SET COLOR MIX(0) .8,.8,.8
         !SET COLOR MIX(0) 1,1,1
      ELSEIF x<=j THEN
         SET COLOR MIX(0) 0,1,1
      ELSEIF i<=x THEN
         SET COLOR MIX(0) 1,1,0
      ELSE
         SET COLOR MIX(0) 1,1,1
      END IF
      PLOT TEXT,AT x,y :VA$(x)
      IF L<>j AND ROUND((L+j)/2)=x OR i<>R AND ROUND((i+R)/2)=x THEN
         PLOT LINES:x+.2,y;x+.6,y
      END IF
   NEXT x
END SUB

END

! 付録: ※冒頭説明〜付録含めて、全文をコピー貼り付け、実行する。
!-------------------------------------
! Swapの直後に、分割終了する場合で、
! 時々、どちらにも属さないデーターが、すき間を、開ける時がある。

! ※下は i=J で、swap 不要の終了ですが、iJ は、進めないと、次のL〜Rが、
!  1つ長くなって、速度が落ちる。if~then swap より、無条件 swap が速い。
!  このケースは、基準のv$ の位置が、次の分割から除かれており、又、v$ 自体、
!  その位置が、移動していない、即ちソート後の位置として、確定している。

!  L       iJ       R
!  ▽▽▽▽▽▽▽▽●△△△△△△△△
!       VA$()= v$ =VA$()
!          swap
!  L      J i      R
!  ▽▽▽▽▽▽▽▽●△△△△△△△△
!          v$
!次のL−−−−−−R L−−−−−−R
 

微分方程式の数値解法

 投稿者:しまむら1243  投稿日:2009年 4月10日(金)21時05分30秒
返信・引用
  次の微分方程式を、数値計算で解く場合の方法を教えてください。

回路の微分方程式
(一次側の電圧平衡式)L1*Δi1/Δt+R1*(1+sin(w*t))*i1-M*Δi2/Δt=E
(二次側の電圧平衡式)M*Δi1/Δt=L2*Δi2/Δt+R2*i2

変圧器で結合された電気回路の式で記号の意味は次のとおりです。
 t :時間[s]
 E :一次側直流定電圧電源[V] 例えば10[V]
 i1:一次側電流[A]
 L1:変圧器一次側自己インダクタンス[H] 例えば0.1[H]
  r :一次側直列変動抵抗で、r=R1*(1+sin(ω*t)
      R1:一定抵抗[Ω] 例えば1000[Ω]
    ω :可変抵抗rの変動角周波数[rad/s] 例えば2*PI*50[rad/s]
 i2:二次側電流[A]
 L2:変圧器二次側自己インダクタンス[H] 例えば0.1[H]
  R2:変圧器二次負荷抵抗[Ω]  例えば10[Ω]
 M:変圧器一次二次相互インダクタンス[H]=SQR(L1*L2)

ルンゲ・クッタ法が使えそうも無く、単純なオイラー法(修正無)で解こうとしたが発散してうまくいきません。よろしくお願いします。
 

Re: 微分方程式の数値解法

 投稿者:SECOND  投稿日:2009年 4月13日(月)08時56分12秒
返信・引用  編集済
  > No.314[元記事へ]

!こんにちは、おひさしぶりです。ご参考程度に、自信がなくて・・

!以下は、ルンゲクッタ法で、時系列の数値解と、その動きを描いてみましたが、
!クリチカルな点など、いくつか不明な面もあります。


!回路の微分方程式
!(一次側の電圧平衡式)L1*Δi1/Δt+R1*(1+sin(w*t))*i1-M*Δi2/Δt=E
!(二次側の電圧平衡式)M*Δi1/Δt=L2*Δi2/Δt+R2*i2
!---------------------------
!計算用の微分方程式
! f1(t, i1)= (di1/dt)= ( E-R1*(1+sin(w*t))*i1+M*(di2/dt) )/L1
! f2(t, i2)= (di2/dt)= ( M*(di1/dt)-R2*i2 )/L2
!
!※上のままでは、正帰還 暴走するので、f1(),f2() に、バッファ f1_,f2_ を付けた。
DEF f1(t, i1)=( E-R1*(1+SIN(w9*t))*i1+M*f2_ )/L1 ! f2_=f2(t, i2)
DEF f2(t, i2)=( M*f1_-R2*i2 )/L2                 ! f1_=f1(t, i1)

LET E=10
LET R1=1000
LET i1=E/R1/2
LET i2=0
LET L1=50 !0.1 小さいと、オーバーフロー?
LET L2=2 !0.1 小さいと、オーバーフロー?
LET R2=10
LET M=SQR(L1*L2)
LET w9=2*PI*1 !50 小さいと、描画ピッチ演算ピッチ共に無理
!
LET dt=0.05 !sec. 演算ピッチ。描画ピッチが遅れない程度に。

SUB RungeKutta4_1(t, i1)
   LET k1=f1(t, i1)
   LET k2=f1(t+dt/2, i1+k1*dt/2)
   LET k3=f1(t+dt/2, i1+k2*dt/2)
   LET k4=f1(t+dt,   i1+k3*dt )
   LET i1=i1+(k1+2*k2+2*k3+k4)*dt/6
   LET f1_=f1(t, i1)
END SUB

SUB RungeKutta4_2(t, i2)
   LET k1=f2(t, i2)
   LET k2=f2(t+dt/2, i2+k1*dt/2)
   LET k3=f2(t+dt/2, i2+k2*dt/2)
   LET k4=f2(t+dt,   i2+k3*dt )
   LET i2=i2+(k1+2*k2+2*k3+k4)*dt/6
   LET f2_=f2(t, i2)
END SUB

!----run
LET t=0
LET w=.5 !13
SET WINDOW -w,w,-w,w
SET LINE width 3
SET COLOR MIX(15) .5,.5,.5
SET TEXT background "OPAQUE"
LET t0=TIME
DO
   LET t1=TIME
   IF dt=< ABS(t1-t0) THEN
      SET DRAW mode hidden
      CLEAR
      DRAW grid(5,5)
      PLOT TEXT,AT w*0.25,w*0.9:"マウス 右ボタンで、終了。"
      PLOT TEXT,AT w*0.4,w*0.76,USING"演算ピッチ=#.### 秒":dt
      PLOT TEXT,AT w*0.4,w*0.69,USING"描画ピッチ=#.### 秒":t1-t0
      LET t0=t1
      PRINT t;i1;i2;f1_;f2_
      !---
      PLOT TEXT,AT-w/2.5,i1:"i1"
      PLOT TEXT,AT w/2.9,i2:"i2"
      PLOT LINES :-w/3,i1;0,i1
      PLOT LINES : w/3,i2;0,i2
      !---
      SET DRAW mode explicit
      CALL RungeKutta4_1(t,i1) ! 次のi1 へ更新
      CALL RungeKutta4_2(t,i2) ! 次のi2 へ更新
      LET t=t+dt
   END IF
   WAIT DELAY 0 ! 省電力効果
   MOUSE POLL mx,my,mlb,mrb
LOOP UNTIL mrb=1

END
 

Re: 微分方程式の数値解法

 投稿者:しまむら1243  投稿日:2009年 4月13日(月)19時13分9秒
返信・引用
  > No.315[元記事へ]

SECONDさんへのお返事です。

SECONDさん、こんにちわ。ご無沙汰しております。変な題材にも関わらず、早速のご教示ありがとうございます。

未だ数値計算の内容を読み終えていないのですが、早速、作成していただいたプログラムを走らせて見ました。
電流が振動している様子は、横軸に時間、縦軸に大きさを採って表すのが一般的ですが、SECONDさんの発想は斬新的だと思いました。

さて質問の意図を記載しなくて申し訳ありませんでしたが、トランジスタの教科書では、「変圧器結合のエミッタ接地A級増幅回路のコレクタ〜エミッタ間電圧は、電圧E(一般にはVccと書く)を中心として±Eの範囲で振動する」と書かれています。
つまり、変圧器の一次側電圧のピーク値は2Eになることを意味しているのですが、何故E以上になりうるのか?を数値計算で確認したかったものです。

提示した微分方程式の抵抗rは、トランジスタのベース電流を正弦波に振動させたときの電流増幅機能を、変動する抵抗rで置き換えて模擬したつもりです。
(教科書では電流増幅機能で説明しているが、トランジスタが電流を増幅するのではなく、ベース電流が変化することによってトランジスタのC〜E間抵抗が変化し、その結果、外部電源Eから流れる電流i1が大きく変動して電流が増幅された様に見える、と思っているので。)

そして最終的に知りたいことは、トランスの一次側電圧 「Vt=E-r*i1 」は、直流電源電圧がEしか無いにも関わらず、Eを中心として0〜2Eの範囲で正弦波状に振動する、つまり確かに「 2E>=Vt>=0 」で正弦波杖に振動する事を見たいのです。

この様な意図であるため、波形図は横軸に時間t[s]、縦軸にi1[A](最終的にはVt[V])として頂くと有難いです。勝って言って申し訳ありません。
 

Re: 微分方程式の数値解法

 投稿者:SECOND  投稿日:2009年 4月13日(月)20時30分23秒
返信・引用
  > No.316[元記事へ]

しまむら1243さんへのお返事です。

大変、申し訳有りませんが、ご期待には答えられません。それよりこのテーマにて
ルンゲクッタでの描画とその動きに、いくつか不明な部分が見つかりまして、それに
気をとられております。できれば、その追跡にお力添えを、頂きたかったのですが。
トランス結合A級増幅器にスピーカがつながった状態にしては、安定性を欠き、
正帰還暴走したり、クリチカルに過ぎるのでは、ないだろうか?
 

Re: 微分方程式の数値解法

 投稿者:しまむら1243  投稿日:2009年 4月14日(火)04時18分58秒
返信・引用
  > No.317[元記事へ]

SECONDさんへのお返事です。

> しまむら1243さんへのお返事です。
>
> 大変、申し訳有りませんが、ご期待には答えられません。それよりこのテーマにて
> ルンゲクッタでの描画とその動きに、いくつか不明な部分が見つかりまして、それに
> 気をとられております。できれば、その追跡にお力添えを、頂きたかったのですが。
> トランス結合A級増幅器にスピーカがつながった状態にしては、安定性を欠き、
> 正帰還暴走したり、クリチカルに過ぎるのでは、ないだろうか?

波形を描くように手を入れさせて頂きました。すると
1)変圧器一次電圧波形は正弦波Vt=Esin(wt)[V]が出ました。 感激!!です。
でも私はVt=E+Esin(wt)を想定していたので正しい結果なのかが判断できず。

2)電流波形は正弦波振動しません。1)と併せて何処かにロジック上の問題があるようですが、未だ分かりません。

!------- 以下変更したプログラム------
!※上のままでは、正帰還 暴走するので、f1(),f2() に、バッファ f1_,f2_ を付けた。
DEF f1(t, i1)=( E-R1*(1+SIN(w9*t))*i1+M*f2_ )/L1 ! f2_=f2(t, i2)
DEF f2(t, i2)=( M*f1_-R2*i2 )/L2                 ! f1_=f1(t, i1)

LET E=10
LET R1=1000
LET L1=0.5 !0.2以下にするとオーバーフロー?
LET L2=0.1
LET R2=10
LET M=SQR(L1*L2)
LET frq=50 !信号周波数[Hz]
LET dt=0.001 !微分時間[s]

LET drawTime=0.1 ![s] !描画時間で、frq×drawTimeサイクル分だけ描画する。
LET iBairitu=500 !電流波形描画拡大倍率

LET i1_=0 ! i1の初期値
LET i2_=0 ! i2の初期値
LET Vt_=E !変圧器一次電圧Vtの初期値
LET t_=0  ! tの初期値

SUB RungeKutta4_1(t_, i1_,i1)
   LET k1=f1(t_, i1_)
   LET k2=f1(t_+dt/2, i1_+k1*dt/2)
   LET k3=f1(t_+dt/2, i1_+k2*dt/2)
   LET k4=f1(t_+dt,   i1_+k3*dt )
   LET i1=i1_+(k1+2*k2+2*k3+k4)*dt/6
   LET f1_=f1(t_, i1)
END SUB

SUB RungeKutta4_2(t_, i2_,i2)
   LET k1=f2(t_, i2_)
   LET k2=f2(t_+dt/2, i2_+k1*dt/2)
   LET k3=f2(t_+dt/2, i2_+k2*dt/2)
   LET k4=f2(t_+dt,   i2_+k3*dt )
   LET i2=i2_+(k1+2*k2+2*k3+k4)*dt/6
   LET f2_=f2(t_, i2)
END SUB

!----run
LET w=2*PI*frq !交流信号の角周波数[rad/s]
LET nmax=drawTime/dt !計算点数

SET WINDOW -0,drawTime,-15,15
DRAW grid

FOR n=1 TO nmax
   LET t=n*dt
   CALL RungeKutta4_1(t_,i1_,i1)
   CALL RungeKutta4_2(t_,i2_,i2)
   LET Vt=E-R1*(1+SIN(w*t))*i1

   SET LINE COLOR "red" !電流i1波形描画色
   PLOT LINES:t_,i1_*iBairitu;t,i1*iBairitu

   SET LINE COLOR "black" !電圧波形描画色
   PLOT LINES:t_,Vt_;t,Vt

   PLOT LINES: t_,0;t,0 !時間軸描画

   LET t_=t   ! 次のt へ更新
   LET i1_=i1 ! 次のi1 へ更新
   LET i2_=i2 ! 次のi2 へ更新
   LET Vt_=Vt ! 次のi2 へ更新
Next N

END
 

Re: 微分方程式の数値解法

 投稿者:山中和義  投稿日:2009年 4月14日(火)08時28分2秒
返信・引用
  > No.318[元記事へ]

しまむら1243さんへのお返事です。

●このプログラムについて

 DEF f1(t, i1)=( E-R1*(1+SIN(w9*t))*i1+M*f2_ )/L1 ! f2_=f2(t, i2)
と
 LET Vt=E-R1*(1+SIN(w*t))*i1

で、ωの変数名が違う。

改修案
 DEF文のw9をwとして、
 刻み幅を、LET dt=0.000001 !微分時間[s] とする。



●オイラー法、ルンゲ・クッタ法の適用できる式の形式
 2変数の連立1次常微分方程式
  Δi1/Δt=f1(t,i1,i2)
  Δi2/Δt=f2(t,i1,i2)
 が一般ですが、右辺に微分が含まれていても可能なのか?

改修案
 SECONDさんの工夫でOK!?



私も正しい結果かどうか判断できませんが、波形を表示するプログラムを掲載します。

●その1
!回路図
!   →i1    N:1  →i2
!  ┌r───・┐ ┌────┬
!  E    Vt↑L1 L2↑V2  R2
!  └─────┘ └・───┴

!抵抗rから変圧器までのFパラメータ(二端子対回路としてみると)
! ┌ 1 r ┐┌ N 0  ┐=┌ N r/N ┐
! └ 0 1 ┘└ 0 1/N ┘ └ 0 1/N ┘

!ただし、巻き数比N=SQR(L1/L2)とする。

!二端子対の両端の電圧、電流は
! ┌ E ┐=┌ N r/N ┐┌ V2 ┐
! └ i1 ┘ └ 0 1/N ┘└ i2 ┘
!となり、整理すると
! ┌ E ┐=┌ N*V2+r/N*i2 ┐ … ��
! └ i1 ┘ └ 1/N*i2   ┘ … ��

!二次側電圧V2=R2*i2より、i2=V2/R2 … ��

!��を�,紡綟�して、V2=(N*R2)/(r+N^2*R2)*E … ��

!これを��に代入して、i2=N/(r+N^2*R2)*E … ��

!�△紡綟�して、i1=E/(r+N^2*R2) … ��

!また、変圧器の一次側電圧Vt=E-r*i1 … �� である。


LET E=10
LET L1=0.5
LET R1=1000
DEF r=R1*(1+SIN(w*t))
LET w=2*PI*50
LET R2=10
LET L2=0.1

LET N=SQR(L1/L2)
SUB routine
   LET V2=N*R2*E/(r+N^2*R2)
   LET i2=N*E/(r+N^2*R2)
   LET i1=E/(r+N^2*R2)
   LET Vt=E-r*i1
END SUB


LET yy=12 !縦軸の範囲

LET TT=50e-3 !時間区間 [0,T]


!!!SET bitmap SIZE 600,600 !画面を大きくする
SET WINDOW -TT/8,TT,-yy,yy !表示領域
DRAW grid(TT/5,yy/6)

PLOT TEXT ,AT TT*7/8,0: "[秒]"


SET LINE COLOR 1
PLOT LINES: t,Vt; t,Vt
SET LINE COLOR 4
PLOT LINES: t,i1; t,i1

FOR t=0 TO TT STEP TT/10000
   CALL routine
   !!!PRINT t;i1,V2;i2

   SET LINE COLOR 1
   PLOT LINES: t,Vt; t,Vt
   SET LINE COLOR 4
   PLOT LINES: t,i1; t,i1 !※
NEXT t
PLOT LINES


END


●その2
!回路図
!      →i1   →i2
!  ┌r───・┐ ┌────┬
!  E    V1↑L1 L2↑V2  R2
!  └─────┘ └・───┴

! E-r*i1=V1=L1*Δi1/Δt-M*Δi2/Δt
!      M*Δi1/Δt-L2*Δi2/Δt=V2=R2*i2

!2変数i1,i2の連立1次常微分方程式で表される。

!行列で表現すると
! ┌ E-r*i1 ┐=┌ L1 -M ┐┌ Δi1/Δt ┐
! └ R2*i2 ┘ └ M  -L2 ┘└ Δi2/Δt ┘

! ┌ Δi1/Δt ┐=1/(-L1*L2+M*M)┌ -L2 M ┐┌ E-r*i1 ┐
! └ Δi2/Δt ┘        └ -M L1 ┘└ R2*i2 ┘

!ところで、M=SQR(L1*L2)より、上記の変形はできない。

!したがって、M=k*SQR(L1*L2)として考える。


!精度が悪いため、計算の後半では誤差が累積されやすくなる。



!2変数の連立1次常微分方程式の解

!----- ↓↓↓↓↓ -----

LET yy=12 !縦軸の範囲

LET TT=50e-3 !時間区間 [0,T]

DEF r(t)=R1*(1+SIN(w*t))
!DEF f1(t,i1,i2)=1/(L1*L2-M*M)*(L2*(E-r(t)*i1) - M*R2*i2)
!DEF f2(t,i1,i2)=1/(L1*L2-M*M)*(-M*(E-r(t)*i1) +L1*R2*i2)
DEF f1(t,i1,i2)=1/(-L1*L2+M*M)*(-L2*(E-r(t)*i1) + M*R2*i2)
DEF f2(t,i1,i2)=1/(-L1*L2+M*M)*( -M*(E-r(t)*i1) +L1*R2*i2)


LET E=10 ![V]
LET L1=0.5 ![H]
LET R1=1000 ![Ω]
LET w=2*PI*50 ![rad/s]
LET L2=0.1 ![H]
LET R2=10 ![Ω]

LET K=0.999 !理想変圧器 K=1 ※
LET M=K*SQR(L1*L2) ![H]

!----- ↑↑↑↑↑ -----


!!!SET bitmap SIZE 600,600 !画面を大きくする
SET WINDOW -TT/8,TT,-yy,yy !表示領域
DRAW grid(TT/5,yy/6)

PLOT TEXT ,AT TT*7/8,0: "[秒]"


!●オイラー法
LET t=0 !初期値 i1(0)=0、i2(0)=0
LET i1=0
LET i2=0
SET LINE COLOR 1
PLOT LINES: t,E-r(t)*i1; t,E-r(t)*i1
SET LINE COLOR 4
PLOT LINES: t,i1; t,i1

LET h=TT/500000 !刻み幅 ※
FOR i=1 TO 500000
   LET k1=h*f1(t,i1,i2)
   LET k2=h*f2(t,i1,i2)
   LET i1=i1+k1
   LET i2=i2+k2
   LET t=t+h

   !!!PRINT t,i1,i2

   SET LINE COLOR 1
   PLOT LINES: t,E-r(t)*i1; t,E-r(t)*i1

   SET LINE COLOR 4
   PLOT LINES: t,i1; t,i1
NEXT i
PLOT LINES


END
 

Re: 微分方程式の数値解法

 投稿者:山中和義  投稿日:2009年 4月14日(火)14時12分40秒
返信・引用
  > No.318[元記事へ]

しまむら1243さんへのお返事です。

> 2)電流波形は正弦波振動しません。

i=E/Rだから、分母のRを0〜2*R(正弦波)としても、iは正弦波になりません。



SET WINDOW -1,5,-1,15
DRAW grid

LET E=1
LET R1=5
FOR t=0 TO 5 STEP 0.001
   LET r=R1*(1+SIN(5*t))
   LET i=E/r
   PLOT LINES: t,r; t,r !正弦波
   !PLOT LINES: t,i; t,i !正弦波?
NEXT t

END
 

Re: 微分方程式の数値解法

 投稿者:しまむら1243  投稿日:2009年 4月14日(火)15時24分22秒
返信・引用
  > No.320[元記事へ]

山中和義さんへのお返事です。

山中さん、ご教示ありがとうございます。
確かにrが正弦波状に変化しても、その逆数は正弦波状にはならないですね。根本的な誤りをしていました。
と言うことは、トランジスタの電流増幅機能(ベースに正弦波信号を入力すると、ほぼ正弦波状の電流出力が得られる)を模擬する可変抵抗は、正弦波の逆数で設定したほうが良いということになりそうですね。
SECONDさん、山中さんからご教示いただいたコードを、その観点で見てみます。

取り敢えずSECONDさんの原版の作画部分を再修正したものを下記に示します。
周波数を高くし、結合係数を小さくすると正弦波状に近づきます。
変圧器一次側電圧が±Eで振動するのも確認出来る様になりつつあります。

!※上のままでは、正帰還 暴走するので、f1(),f2() に、バッファ f1_,f2_ を付けた。
DEF f1(t, i1)=( E-R1*(1+SIN(w*t))*i1+M*f2_ )/L1 ! f2_=f2(t, i2)
DEF f2(t, i2)=( M*f1_-R2*i2 )/L2                 ! f1_=f1(t, i1)

LET E=10
LET R1=10000
LET ketugo=0.8 !結合係数で、1に近づけると波形が鋭利になり発振する
LET L1=0.2
LET L2=0.1
LET R2=2
LET frq=10000     !信号周波数[Hz]
LET ndiv=5000     !1サイクルの計算分割数
LET drawHz=10     ! 1画面で表示するサイクル数[Hz]
LET pass_gamen=1  !初期過渡時の描画面をパスする回数
LET iBairitu=1000 !電流波形描画拡大倍率。1000で1目盛り1[mA]になる

LET nmax=drawHz*ndiv !1画面の描画点数
LET dt=1/frq/ndiv    !計算微分時間[s]

LET M=ketugo*SQR(L1*L2)
LET w=2*PI*frq       !交流正弦波信号の角周波数[rad/s]
LET i1_=0            ! i1の初期値
LET i2_=0            ! i2の初期値
LET Vt_=0            !変圧器一次電圧Vtの初期値
LET t_=0             ! tの初期値

!----run

SET WINDOW -0,nmax,-2*E,2*E
DRAW grid

FOR nn=0 TO pass_gamen
   FOR n=0 TO nmax
      IF n=0 THEN LET xn_=0
      LET t=n*dt
      LET xn=n
      CALL RungeKutta4_1(t_,i1_,i1)
      CALL RungeKutta4_2(t_,i2_,i2)
      LET Vt=E-R1*(1+SIN(w*t))*i1

      IF nn=pass_gamen THEN
         SET LINE COLOR "red" !電流i1波形描画色
         PLOT LINES:xn_,i1_*iBairitu;xn,i1*iBairitu
         !SET LINE COLOR "blue" !電流i2波形描画色
         !PLOT LINES:xn_,i2_*iBairitu;xn,i2*iBairitu
         SET LINE COLOR "black" !電圧波形描画色
         PLOT LINES:xn_,Vt_;xn,Vt
         PLOT LINES: xn_,0;xn,0 !時間軸描画
         SET LINE COLOR "green" !電圧±E[V]ライン
         PLOT LINES:xn_,-E;xn,-E
         PLOT LINES:xn_,E;xn,E
      END IF

      LET t_=t   ! 次のt へ更新
      LET i1_=i1 ! 次のi1 へ更新
      LET i2_=i2 ! 次のi2 へ更新
      LET Vt_=Vt ! 次のVt へ更新
      LET xn_=xn
   next N
NEXT nn

SUB RungeKutta4_1(t_, i1_,i1)
   LET k1=f1(t_, i1_)
   LET k2=f1(t_+dt/2, i1_+k1*dt/2)
   LET k3=f1(t_+dt/2, i1_+k2*dt/2)
   LET k4=f1(t_+dt,   i1_+k3*dt )
   LET i1=i1_+(k1+2*k2+2*k3+k4)*dt/6
   LET f1_=f1(t_, i1)
END SUB

SUB RungeKutta4_2(t_, i2_,i2)
   LET k1=f2(t_, i2_)
   LET k2=f2(t_+dt/2, i2_+k1*dt/2)
   LET k3=f2(t_+dt/2, i2_+k2*dt/2)
   LET k4=f2(t_+dt,   i2_+k3*dt )
   LET i2=i2_+(k1+2*k2+2*k3+k4)*dt/6
   LET f2_=f2(t_, i2)
END SUB

END



> しまむら1243さんへのお返事です。
> > 2)電流波形は正弦波振動しません。
> i=E/Rだから、分母のRを0〜2*R(正弦波)としても、iは正弦波になりません。
>
> SET WINDOW -1,5,-1,15
> DRAW grid
>
> LET E=1
> LET R1=5
> FOR t=0 TO 5 STEP 0.001
>    LET r=R1*(1+SIN(5*t))
>    LET i=E/r
>    PLOT LINES: t,r; t,r !正弦波
>    !PLOT LINES: t,i; t,i !正弦波?
> NEXT t
>
> END
 

PLOT LINES文の不具合

 投稿者:山中和義  投稿日:2009年 4月15日(水)10時32分54秒
返信・引用  編集済
  SET WINDOW wx1,wx2,wy1,wy2
PLOT LINES: x1,y1; x2,y2

画面から大きく外れる線分を描く場合(y1またはy2がwy2との差が1e7以上)、
クリッピングされるはずの線分が、点(x1,wy2)として画面上端に表示される。

左端も点(wx1,y1)で同様。


サンプル1
SET WINDOW -1,1,-1,1
LET y=1e8
PLOT LINES: x,y; x+0.5,y !上端中央に点が見える
END


サンプル2
SET WINDOW -1,1,-1,1
LET y=1e8
FOR x=-1 TO 1 STEP 0.001 !実線が見える(0.1、0.01なら点々になる)
   PLOT LINES: x,y; x+0.5,y
NEXT x
END
 

Re: PLOT LINES文の不具合

 投稿者:白石 和夫  投稿日:2009年 4月16日(木)08時59分14秒
返信・引用
  > No.322[元記事へ]

line width を2以上にすると問題がでるようです。
調べた環境はWindows XPとVistaですが,
line widthを変えないときは線が描かれませんでした。

Windows NT系の場合,GDI(でよかったか?)は32ビットの座標空間をもつので,
-2^31〜2^31-1でクリップした数値をWindowsに渡しています。

line style または Line Width を2以上にすると,
おかしなことが起こるようです。

テストプログラム
ビットマップのサイズを801×801にして実行

10 SET WINDOW 0,800,0,800
20 LET m=2^28
30 ! SET LINE WIDTH 2
31 SET LINE STYLE 2
40 FOR i=1 TO 400
50    PLOT LINES: 0,-m+i; 200,-m+i
60 NEXT i
70 END

20行はm=2^29,2^30でも同様

Win32APIの詳細な動作がわからないので,
ロジカルな問題ではないので,解決にはテストが必要です。
他の環境での動作テストの報告を歓迎します。
 

Re: PLOT LINES文の不具合

 投稿者:山中和義  投稿日:2009年 4月16日(木)12時21分59秒
返信・引用
  > No.323[元記事へ]

> 他の環境での動作テストの報告を歓迎します。

30,31行をコメントアウトしたプログラムで、
WindowsMeの場合、画面サイズで発生する、しないがあります。


発生する
 401×401、501×501、801×801、1001×1001(破線)、1601×1601(点線)

発生しない
 321×321、640×400、640×480、641×641、1281×1281、2001×2001


10 SET WINDOW 0,800,0,800
20 LET m=2^28
30 !SET LINE WIDTH 2
31 !SET LINE STYLE 2
40 FOR i=1 TO 400
50    PLOT LINES: 0,-m+i; 200,-m+i
60 NEXT i
70 END


30,31行を有効にしても動作は同じです。線幅は関係ないようです。

また、画面サイズによって、発生する場合のmの値が異なります。
たとえば、401×401なら、m=2^17以上。 501×501なら、m=2^19以上。 801×801なら、m=2^16以上。


補足
 前出のプログラムをPLOT POINTS文で実行する場合はOK(点、線は描かれない)です。

SET WINDOW -1,1,-1,1
LET y=2^13 !これ以上から
FOR x=-1 TO 1 STEP 0.001
   PLOT POINTS: x,y !OK
   !PLOT LINES: x,y; x,y !NG 中央に横実線が見える。 m=2^22以上なら画面上端へ
NEXT x
END
 

Re: PLOT LINES文の不具合

 投稿者:荒田浩二  投稿日:2009年 4月16日(木)19時31分56秒
返信・引用
  > No.323[元記事へ]

> 他の環境での動作テストの報告を歓迎します。

ビットマップサイズや線幅、描画位置を網羅的に調べました。
WindowsVistaでは、LINE WIDTH の設定が1のときにはエラーはありませんでした。
LINE WIDTH の設定が4,5のときは3と同じ挙動でした。
また、j>=32のときはj=32、j<=-32のときはj=-32と同じ挙動です(全てを調査したわけではないですが)。


結果の例(err=1となるjの値)
801×801の場合
  w=1 → ない
  w=2 → j<=-28,28<=j<=30 (j<=-32では画面上端に描画される)
  w=3,4,5 → ABS(j)>=28 (j<=-32では画面上端に描画される)
641×641の場合
  w=1 → ない
  w=2 → j<=-32 (画面上端に描画される)
  w=3,4,5 → ABS(j)>=32 (画面上端に描画される)


FOR bs=101 TO 1201 STEP 100
   PRINT "BITMAP SIZE "&STR$(bs)&"×"&STR$(bs)
   SET bitmap SIZE bs,bs
10    SET WINDOW 0,800,0,800
      SET TEXT HEIGHT 30
      FOR w=1 TO 3  ! w=4,5はw=3と同じ挙動
         PRINT "LINE WIDTH =";w
         FOR j=-32 TO -10
            CALL test
         NEXT j
         FOR j=10 TO 32
            CALL test
         NEXT j
         PRINT
      NEXT w
      PRINT
   NEXT bs
   SUB test
      CLEAR
      PLOT TEXT ,AT 300,560 : "BITMAP SIZE "&STR$(bs)&"×"&STR$(bs)
      PLOT TEXT ,AT 300,480 : "w = "&STR$(w)
      PLOT TEXT ,AT 300,400 : "j = "&STR$(j)
20    LET m=SGN(j)*2^ABS(j)
30    SET LINE WIDTH w
31    !SET LINE STYLE 2
40    FOR i=1 TO 400
50       PLOT LINES: 0,-m+i; 200,-m+i
60    NEXT i
      LET err=0
      FOR y=0 TO 800
         ASK PIXEL VALUE(1,y) col
         IF col=1 THEN LET err=1
      NEXT y
      IF err=1 THEN
         PRINT j;
         WAIT DELAY 0.3
      END IF
   END SUB
70 END


全結果
BITMAP SIZE 101×101
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31  31  32
LINE WIDTH = 3
-32 -31  31  32

BITMAP SIZE 201×201
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31 -30  30  31  32
LINE WIDTH = 3
-32 -31 -30  30  31  32

BITMAP SIZE 301×301
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31  31  32
LINE WIDTH = 3
-32 -31  31  32

BITMAP SIZE 401×401
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31 -30 -29  29  30  31
LINE WIDTH = 3
-32 -31 -30 -29  29  30  31  32

BITMAP SIZE 501×501
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31  31
LINE WIDTH = 3
-32 -31  31  32

BITMAP SIZE 601×601
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31 -30  30  31
LINE WIDTH = 3
-32 -31 -30  30  31  32

BITMAP SIZE 701×701
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31  31
LINE WIDTH = 3
-32 -31  31  32

BITMAP SIZE 801×801
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31 -30 -29 -28  28  29  30
LINE WIDTH = 3
-32 -31 -30 -29 -28  28  29  30  31  32

BITMAP SIZE 901×901
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31
LINE WIDTH = 3
-32 -31  31  32

BITMAP SIZE 1001×1001
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31 -30  30
LINE WIDTH = 3
-32 -31 -30  30  31  32

BITMAP SIZE 1101×1101
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31
LINE WIDTH = 3
-32 -31  31  32

BITMAP SIZE 1201×1201
LINE WIDTH = 1

LINE WIDTH = 2
-32 -31 -30 -29  29  30
LINE WIDTH = 3
-32 -31 -30 -29  29  30  31  32
 

Re: PLOT LINES文の不具合

 投稿者:白石 和夫  投稿日:2009年 4月16日(木)20時53分47秒
返信・引用
  > No.324[元記事へ]

Windows Meの場合は,GDIの座標系が16ビットなので,
ピクセル座標系に変換した後,-2^15〜2^15-1の範囲に
座標値を切り詰めた後に描画させています。
 

Re: PLOT LINES文の不具合

 投稿者:山中和義  投稿日:2009年 4月16日(木)22時10分58秒
返信・引用
  > No.326[元記事へ]

WindowsMeでの実行結果を報告します。

プログラムの修正
 画面左端
  ASK PIXEL VALUE(1,y) col
 を
  ASK PIXEL VALUE(0,y) col
 と変更


320×240はOKです!
GDI内でのクリッピングは、ビットマップ・サイズが16の倍数以外ではうまく計算できていないようです。

BITMAP SIZE 101×101
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31  32
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31  32
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31  32

BITMAP SIZE 201×201
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32

BITMAP SIZE 301×301
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31  32
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31  32
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31  32

BITMAP SIZE 401×401
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31

BITMAP SIZE 501×501
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31

BITMAP SIZE 601×601
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18  18  19  20  21  22  23  24  25  26  27  28  29  30  31
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18  18  19  20  21  22  23  24  25  26  27  28  29  30  31
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18  18  19  20  21  22  23  24  25  26  27  28  29  30  31

BITMAP SIZE 701×701
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30  31

BITMAP SIZE 801×801
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30

BITMAP SIZE 901×901
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30

BITMAP SIZE 1001×1001
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18  18  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18  18  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18  18  19  20  21  22  23  24  25  26  27  28  29  30

BITMAP SIZE 1101×1101
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19  19  20  21  22  23  24  25  26  27  28  29  30

BITMAP SIZE 1201×1201
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17  17  18  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17  17  18  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17  17  18  19  20  21  22  23  24  25  26  27  28  29  30





BITMAP SIZE 320×240
LINE WIDTH = 1

LINE WIDTH = 2

LINE WIDTH = 3



BITMAP SIZE 640×400
LINE WIDTH = 1
-17  17  18
LINE WIDTH = 2
-17  17  18
LINE WIDTH = 3
-17  17  18


BITMAP SIZE 640×480
LINE WIDTH = 1
-32
LINE WIDTH = 2
-32
LINE WIDTH = 3
-32


BITMAP SIZE 1281×1281
LINE WIDTH = 1
-32 -31
LINE WIDTH = 2
-32 -31
LINE WIDTH = 3
-32 -31

 

Re: PLOT LINES文の不具合

 投稿者:白石 和夫  投稿日:2009年 4月17日(金)14時52分13秒
返信・引用
  > No.327[元記事へ]

SET WINDOWで定義される座標系をGDI座標系と一致させるために
ASK PIXEL SIZE (0,1;1,0) a,b
LET a=a-1
LET b=b-1
SET WINDOW 0,a,b,0
で座標系を定義してください。
Windowsでは,左上端座標が原点(0,0)で,右下方向に座標値が増加します。
 

Re: PLOT LINES文の不具合

 投稿者:白石 和夫  投稿日:2009年 4月17日(金)15時03分3秒
返信・引用  編集済
  > No.328[元記事へ]

Windows XPでの結果ですが,ビットマップサイズが16の倍数かどうかは関係ないみたいです。

LET s=512
SET bitmap SIZE s,s
SET WINDOW 0,s-1,s-1,0
SET LINE STYLE 2
LET m=2^27
FOR i=m TO m+1000
   PLOT LINES: 100,m+i; 200,m+i
NEXT i
END
 

Re: PLOT LINES文の不具合

 投稿者:山中和義  投稿日:2009年 4月17日(金)18時01分49秒
返信・引用
  > No.328[元記事へ]

> SET WINDOWで定義される座標系をGDI座標系と一致させるために

規則性が見えてきました。上下左右端すべてこの状態になります。
BITMAP SIZE 101×101
LINE WIDTH = 1
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 2
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30
LINE WIDTH = 3
-32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30
FOR bs=101 TO 1201 STEP 100
   PRINT "BITMAP SIZE "&STR$(bs)&"×"&STR$(bs)
   SET bitmap SIZE bs,bs
   !SET bitmap SIZE 640,480
   ASK PIXEL SIZE (0,1;1,0) a,b
   LET a=a-1
   LET b=b-1
   SET WINDOW 0,a,b,0
   !!!10    SET WINDOW 0,800,0,800
   SET TEXT HEIGHT 30
   FOR w=1 TO 3  ! w=4,5はw=3と同じ挙動
      PRINT "LINE WIDTH =";w
      FOR j=-32 TO -10
         CALL test
      NEXT j
      FOR j=10 TO 32
         CALL test
      NEXT j
      PRINT
   NEXT w
   PRINT
NEXT bs
SUB test
   CLEAR
   PLOT TEXT ,AT 300,560 : "BITMAP SIZE "&STR$(bs)&"×"&STR$(bs)
   PLOT TEXT ,AT 300,480 : "w = "&STR$(w)
   PLOT TEXT ,AT 300,400 : "j = "&STR$(j)
20    LET m=SGN(j)*2^ABS(j)
30    SET LINE WIDTH w
31    !!!SET LINE STYLE 2
40    FOR i=1 TO 400
50       PLOT LINES: 0,m+i; 200,m+i !左端に発生<---------- ※
         !52       PLOT LINES: m+i,0; m+i,200 !上端<---------- ※
60    NEXT i
      LET err=0
      FOR y=0 TO 800
         ASK PIXEL VALUE(0,y) col !左端<---------- ※
         !ASK PIXEL VALUE(y,0) col !上端<---------- ※
         IF col=1 THEN LET err=1
      NEXT y
      IF err=1 THEN
         PRINT j;
         WAIT DELAY 0.3
      END IF
   END SUB
70 END
 

Re: PLOT LINES文の不具合

 投稿者:山中和義  投稿日:2009年 4月17日(金)20時41分56秒
返信・引用
  > No.328[元記事へ]

白石 和夫さんへのお返事です。

古い情報ですが
 座標が極端に大きい場合に GDI 呼び出しが失敗する
 http://support.microsoft.com/kb/299533/ja


「この問題は Microsoft Windows XP では解決されています。」と書いてありますが、、、

線幅が1、線種が実線以外では、まだ一部発生する と言うことでしょうか。

(クリッピングなどがGDI依存のままでは)本件は、制限事項になってしまいますね。
 

Re: PLOT LINES文の不具合

 投稿者:白石 和夫  投稿日:2009年 4月18日(土)09時39分46秒
返信・引用
  > No.333[元記事へ]

Windows XPで観察される現象は,GDIに渡した座標値の上位,何ビットかを無視して処理されていることです。その範囲が明確になれば対応は可能です。
現状は,-2^31より小さければ-2^31に書き換え,2^31-1より大きければ2^31-1に書き換えています。SDKの記述が間違っているとのことなので,これを-2^26〜2^26-1の範囲に変えればいいのだろうと思います。

Windows Meでも同様なのだろうと思いますが,上位の何ビットが無視されるのかが問題です。
 

Re: PLOT LINES文の不具合

 投稿者:山中和義  投稿日:2009年 4月18日(土)14時14分37秒
返信・引用
  > No.334[元記事へ]

白石 和夫さんへのお返事です。

> Windows Meでも同様なのだろうと思いますが,上位の何ビットが無視されるのかが問題です。

プログラムとしては、ちょっと強引ですが、、、

BASICのグラフィックス画面(タイトルバー、メニューバーを含むウインドウ)をhDCとして確認してみました。

結果は、-2^15〜2^15の範囲のようです。(32ビット指定だが、上位16ビットは無効となる)


>> Windows Meの場合は,GDIの座標系が16ビットなので,
>> ピクセル座標系に変換した後,-2^15〜2^15-1の範囲に
>> 座標値を切り詰めた後に描画させています

これならちゃんと描画するのでは?

OPTION CHARACTER byte

LET w=320
LET h=240

SET BITMAP SIZE w,h !画面サイズ
SET WINDOW 0,w-1,0,h-1 !左下が原点。横がX、縦Y


LET hWnd=FndWnd("TPaintForm","") !ウインドウハンドルを取得する

LET Rect$=REPEAT$(" ",4*4)
LET n=ClientRect(hWnd, Rect$)
PRINT int32(Rect$,0);int32(Rect$,4);int32(Rect$,8);int32(Rect$,12)

LET n=GetWndRect(hWnd, Rect$)
PRINT int32(Rect$,0);int32(Rect$,4);int32(Rect$,8);int32(Rect$,12)



IF hWnd>0 THEN
   LET hDC=GetWndDC(hWnd) !デバイスコンテキストを取得する

   IF hDC>0 THEN
   !LET n=SetForeWnd(hWnd)

      LET n=Ellipse(hDC,20,20,100,200)

      LET m=-2^16 !<-------------------- -2^15〜2^15はOK
      LET n=MoveTo(hDC,0,m,0) !
      LET n=LineTo(hDC,200,m) !

      WAIT DELAY 2

      LET n=ReleaseDC(hWnd, hDC) !デバイスコンテキストを開放する
   END IF
END IF

END



!--------------------------------------------------
!
EXTERNAL FUNCTION DWORD$(n)
OPTION CHARACTER byte
LET r=MOD(n,2^8)
LET s$=CHR$(r)
LET n=(n-r)/2^8
LET r=MOD(n,2^8)
LET s$=s$ & CHR$(r)
LET n=(n-r)/2^8
LET r=MOD(n,2^8)
LET s$=s$ & CHR$(r)
LET n=(n-r)/2^8
LET r=MOD(n,2^8)
LET DWORD$=s$ & CHR$(r)
END FUNCTION

EXTERNAL FUNCTION WORD$(n)
OPTION CHARACTER byte
LET r=MOD(n,2^8)
LET s$=CHR$(r)
LET n=(n-r)/2^8
LET r=MOD(n,2^8)
LET WORD$=s$ & CHR$(r)
END FUNCTION

EXTERNAL FUNCTION int32(s$,p)
OPTION CHARACTER byte
LET n=0
FOR i=1 TO 4
   LET n=n+256^(i-1)*ORD(s$(p+i:p+i))
NEXT i
IF n<2^31 THEN LET int32=n ELSE LET int32=n-2^32
END FUNCTION

EXTERNAL FUNCTION int16(s$,p)
OPTION CHARACTER byte
LET n=0
FOR i=1 TO 2
   LET n=n+256^(i-1)*ORD(s$(p+i:p+i))
NEXT i
IF n<2^15 THEN LET int16=n ELSE LET int16=n-2^16
END FUNCTION


!user32.dll
EXTERNAL FUNCTION CloseWnd(hWnd)
ASSIGN "user32.dll","CloseWindow"
END FUNCTION

EXTERNAL FUNCTION CopyRect(lpDstRect$, lpSrcRect$)
ASSIGN "user32.dll","CopyRect"
END FUNCTION

EXTERNAL FUNCTION FndWnd(lpClassName$, lpWindowName$)
ASSIGN "user32.dll","FindWindowA"
END FUNCTION

EXTERNAL FUNCTION FillRect(hDC, lpRect$, hbr)
ASSIGN "user32.dll","FillRect"
END FUNCTION

EXTERNAL FUNCTION GetActWnd
ASSIGN "user32.dll","GetActiveWindow"
END FUNCTION

EXTERNAL FUNCTION ClientRect(hWnd, lpRect$)
ASSIGN "user32.dll","GetClientRect"
END FUNCTION

EXTERNAL FUNCTION GetForeWnd
ASSIGN "user32.dll","GetForegroundWindow"
END FUNCTION

EXTERNAL FUNCTION GetWndDC(hWnd)
ASSIGN "user32.dll","GetWindowDC"
END FUNCTION

EXTERNAL FUNCTION GetWndRect(hWnd, lpRect$)
ASSIGN "user32.dll","GetWindowRect"
END FUNCTION

EXTERNAL FUNCTION IsWndVisible(hWnd)
ASSIGN "user32.dll","IsWindowVisible"
END FUNCTION

EXTERNAL FUNCTION MoveWnd(hWnd, x, y, cx, cy)
ASSIGN "user32.dll","MoveWindow"
END FUNCTION

EXTERNAL FUNCTION OffsetRect(lpRect$, dx, dy)
ASSIGN "user32.dll","OffsetRect"
END FUNCTION

EXTERNAL FUNCTION ReleaseDC(hWnd, hDC)
ASSIGN "user32.dll","ReleaseDC"
END FUNCTION

EXTERNAL FUNCTION SetActWnd(hWnd)
ASSIGN "user32.dll","SetActiveWindow"
END FUNCTION

EXTERNAL FUNCTION SetForeWnd(hWnd)
ASSIGN "user32.dll","SetForegroundWindow"
END FUNCTION

EXTERNAL FUNCTION SetRect(lpRect$, xLeftRect, yTopRect, xRightRect, yBottomRect)
ASSIGN "user32.dll","SetRect"
END FUNCTION

EXTERNAL FUNCTION SetWndPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlag)
ASSIGN "user32.dll","SetWindowPos"
END FUNCTION

EXTERNAL FUNCTION SetWndText(hWnd, lpString$)
ASSIGN "user32.dll","SetWindowTextA"
END FUNCTION

EXTERNAL FUNCTION ShowWnd(hWnd, nCmdShow)
ASSIGN "user32.dll","ShowWindow"
END FUNCTION


!gdi32.dll
EXTERNAL FUNCTION SolidBrush(crColor)
ASSIGN "gdi32.dll","CreateSolidBrush"
END FUNCTION

EXTERNAL FUNCTION Ellipse(hDC, nLeftRect, nTopRect, nRightRect, nBottomRect)
ASSIGN "gdi32.dll","Ellipse"
END FUNCTION

EXTERNAL FUNCTION LineTo(hDC, x, y)
ASSIGN "gdi32.dll","LineTo"
END FUNCTION

EXTERNAL FUNCTION MoveTo(hDC, x, y, lpPoint)
ASSIGN "gdi32.dll","MoveToEx"
END FUNCTION

EXTERNAL FUNCTION Rectangle(hDC, nLeftRect, nTopRect, nRightRect, nBottomRect)
ASSIGN "gdi32.dll","Rectangle"
END FUNCTION
 

Re: PLOT LINES文の不具合

 投稿者:白石 和夫  投稿日:2009年 4月19日(日)15時09分7秒
返信・引用  編集済
  > No.334[元記事へ]

完全かどうか定かではありませんが,修正版を作成しました。(Ver. 3.7.1)
問題が残るようであればお知らせください。
 

画像処理(エフェクト)

 投稿者:山中和義  投稿日:2009年 4月20日(月)20時13分25秒
返信・引用
  ページめくり
OPTION ARITHMETIC NATIVE !CPUパワー

SET COLOR MODE "NATIVE"
GLOAD "c:\BASICw32\SAMPLE\ZENKOUJI.JPG" !画像を読み込む
ASK PIXEL SIZE (0,0; 1,1) w,h !画像の縦横の大きさ(ピクセル単位)を調べる
DIM p(w,h),q(w,h) !画像の大きさに対応する配列要素を用意する
ASK PIXEL ARRAY (0,1) p !画像の各点の色情報を配列に格納する
PRINT "画像の大きさ 縦:";h;" 横:";w
!SET BITMAP SIZE w,h !ウィンドウの大きさを画像に合わせる


LET R=30 !めくりの半径 ※
LET Dx=20 !めくりの量 ※
LET th=RAD(30) !めくりの方向 ※


DIM M1(3,3),M2(3,3),M4(3,3),M5(3,3),M7(3,3),M8(3,3)
MAT M1=IDN !画像の中央を原点へ
LET M1(1,3)=-w/2
LET M1(2,3)=-h/2

MAT M2=IDN !めくり方向をX軸に一致させ、半径を1とする
LET M2(1,1)=COS(th)/R
LET M2(1,2)=SIN(th)/R
LET M2(2,1)=-SIN(th)/R
LET M2(2,2)=COS(th)/R

MAT M4=IDN !めくりの中心を原点へ
LET M4(1,3)=-Dx/R

MAT M5=IDN !INV(M4)
LET M5(1,3)=Dx/R

MAT M7=IDN !INV(M2)
LET M7(1,1)=COS(th)*R
LET M7(1,2)=-SIN(th)*R
LET M7(2,1)=SIN(th)*R
LET M7(2,2)=COS(th)*R

MAT M8=IDN !INV(M1)
LET M8(1,3)=w/2
LET M8(2,3)=h/2


MAT q=ZER !黒色

!座標変換 f:(x,y)→(xx,yy)の逆変換を考える

!下側の部分
DIM t(3)
FOR yy=1 TO h !変換後の画素位置で走査する
   FOR xx=1 TO w

      LET t(1)=xx !非線形変換前の線形変換
      LET t(2)=yy
      LET t(3)=1

      MAT t=M1*t
      MAT t=M2*t
      MAT t=M4*t

      !非線形変換

      !横から見た図(効果のかかる方向をX軸方向にとる)
      !Z軸
      !↑
      !・→ X軸
      !      視線
      !       ↓
      !          x'=1
      !        ──・     上側
      !           \    ↑
      !  めくりの中心 → *  ・x'=0 --------
      !           /    ↓
      ! 画素面 ─────・     下側
      !          x'=-1
      !
      !・下側と上側の順に2回の描画で陰面消去を行う

      LET op=0 !計算誤差を避けるため元の値を使う
      SELECT CASE t(1) !x'=R*Sin(θz)
      CASE IS >=1
         LET op=-1 !NOP
      CASE IS >=0
         LET t(1)=ASIN(ABS(t(1))) !0≦R*ArcSin(x'/R)≦R*PI/2
         LET op=1 !変換された座標を使う
      CASE ELSE !x'
      END SELECT

      MAT t=M5*t !非線形変換後の線形変換
      MAT t=M7*t
      MAT t=M8*t
      !PRINT xx;yy !debug
      !MAT PRINT t;

      LET x=INT(t(1)) !元の画素での位置
      LET y=INT(t(2))

      SELECT CASE op !元の画素を読み込んで書き込む
      CASE 0
         LET q(xx,yy)=p(xx,yy)
      CASE 1
         IF x<1 OR x>w OR y<1 OR y>h THEN !範囲内なら
         ELSE
            LET q(xx,yy)=p(x,y)
         END IF
      CASE ELSE
      END SELECT

   NEXT xx
NEXT yy

!MAT PLOT CELLS, IN 0,1; 1,0 :q !画像を表示する debug
!STOP

!上側の部分(めくり上がって裏返る部分)
FOR yy=1 TO h !変換後の画素位置で走査する
   FOR xx=1 TO w

      LET t(1)=xx !非線形変換前の線形変換
      LET t(2)=yy
      LET t(3)=1

      MAT t=M1*t
      MAT t=M2*t
      MAT t=M4*t


      !非線形変換
      !!!●巻き込まない場合は、こちら
      LET op=0 !計算誤差を避けるため元の値を使う
      SELECT CASE t(1)
      CASE IS >=1
         LET op=-1 !NOP
      CASE IS >=0
         LET t(1)=PI-ASIN(ABS(t(1))) !R*PI/2≦R*PI-R*ArcSin(x'/R)≦R*PI
         LET op=1
      CASE ELSE
         LET t(1)=PI-t(1) !R*PI-x'
         LET op=1
      END SELECT

      !!!●巻き込む場合は、こちら
      !!!LET op=0 !計算誤差を避けるため元の値を使う
      !!!SELECT CASE t(1)
      !!!CASE IS >=1
      !!!   LET op=-1 !NOP
      !!!CASE IS >=0
      !!!   LET t(1)=PI-ASIN(ABS(t(1)))
      !!!   LET op=1
      !!!CASE IS >=-1
      !!!   LET t(1)=PI+ASIN(ABS(t(1)))
      !!!   LET op=1
      !!!CASE ELSE
      !!!   LET op=-1 !NOP
      !!!END SELECT


      MAT t=M5*t !非線形変換後の線形変換
      MAT t=M7*t
      MAT t=M8*t
      !PRINT xx;yy !debug
      !MAT PRINT t;

      LET x=INT(t(1)) !元の画素での位置
      LET y=INT(t(2))

      SELECT CASE op !元の画素を読み込んで書き込む
      CASE 0
         LET q(xx,yy)=p(xx,yy)
      CASE 1
         IF x<1 OR x>w OR y<1 OR y>h THEN !範囲内なら
         ELSE
            LET q(xx,yy)=p(x,y)
         END IF
      CASE ELSE
      END SELECT

   NEXT xx
NEXT yy

MAT PLOT CELLS, IN 0,1; 1,0 :q !画像を表示する

END
 

Re: 画像処理(エフェクト)

 投稿者:山中和義  投稿日:2009年 4月21日(火)10時30分2秒
返信・引用
  > No.337[元記事へ]

●球
OPTION ARITHMETIC NATIVE !CPUパワー

SET COLOR MODE "NATIVE"
GLOAD "c:\BASICw32\SAMPLE\ZENKOUJI.JPG" !画像を読み込む
ASK PIXEL SIZE (0,0; 1,1) w,h !画像の縦横の大きさ(ピクセル単位)を調べる
DIM p(w,h),q(w,h) !画像の大きさに対応する配列要素を用意する
ASK PIXEL ARRAY (0,1) p !画像の各点の色情報を配列に格納する
PRINT "画像の大きさ 縦:";h;" 横:";w
!SET BITMAP SIZE w,h !ウィンドウの大きさを画像に合わせる


LET Rx=100 !球の半径
LET Ry=100
LET Sx=150 !球の中心
LET Sy=150
LET Tx=w/2+50 !貼付け位置
LET Ty=h/2


DIM M1(3,3),M2(3,3),M3(3,3),M6(3,3),M7(3,3),M8(3,3)
MAT M1=IDN !中心の移動
LET M1(1,3)=-Sx
LET M1(2,3)=-Sy

MAT M2=IDN !比率の変換
LET M2(1,1)=1/Rx
LET M2(2,2)=1/Ry

MAT M7=IDN !INV(M2)
LET M7(1,1)=Rx
LET M7(2,2)=Ry

MAT M8=IDN !貼付け画像の移動
LET M8(1,3)=Tx
LET M8(2,3)=Ty


MAT q=ZER !黒色

!座標変換 f:(x,y)→(xx,yy)の逆変換を考える

DIM t(3)
FOR yy=1 TO h !変換後の画素位置で走査する
   FOR xx=1 TO w

      LET t(1)=xx !非線形変換前の線形変換
      LET t(2)=yy
      LET t(3)=1

      MAT t=M1*t
      MAT t=M2*t

      LET tt=SQR(t(1)*t(1)+t(2)*t(2)) !(x,y)に応じて回転する
      IF tt=0 THEN
         LET co=0
         LET si=0
      ELSE
         LET co=t(1)/tt
         LET si=t(2)/tt
      END IF

      MAT M3=IDN
      LET M3(1,1)=co !X軸上への写像
      LET M3(1,2)=si
      LET M3(2,1)=-si
      LET M3(2,2)=co

      MAT t=M3*t


      !非線形変換
      IF t(1)>=0 AND t(1)<1 THEN !球の内
         LET t(1)=ASIN(t(1)) !凸
         !LET t(1)=ATN(t(1))*1.5 !凹
         LET op=1 !変換された座標を使う
      ELSE !球の外
         LET op=0 !計算誤差を避けるため元の値を使う
      END IF


      SELECT CASE op !元の画素を読み込んで書き込む
      CASE 0
         LET q(xx,yy)=p(xx,yy)
      CASE 1
         MAT M6=IDN !INV(M3) !非線形変換後の線形変換
         LET M6(1,1)=co
         LET M6(1,2)=-si
         LET M6(2,1)=si
         LET M6(2,2)=co

         MAT t=M6*t
         MAT t=M7*t
         MAT t=M8*t
         !PRINT xx;yy !debug
         !MAT PRINT t;

         LET x=INT(t(1)) !元の画素での位置
         LET y=INT(t(2))

         IF x<1 OR x>w OR y<1 OR y>h THEN !範囲内なら
         ELSE
            LET q(xx,yy)=p(x,y)
         END IF
      CASE ELSE !NOP
      END SELECT

   NEXT xx
NEXT yy

MAT PLOT CELLS, IN 0,1; 1,0 :q !画像を表示する

END


●モザイク
OPTION ARITHMETIC NATIVE !CPUパワー

SET COLOR MODE "NATIVE"
GLOAD "c:\BASICw32\SAMPLE\ZENKOUJI.JPG" !画像を読み込む
ASK PIXEL SIZE (0,0; 1,1) w,h !画像の縦横の大きさ(ピクセル単位)を調べる
DIM p(w,h),q(w,h) !画像の大きさに対応する配列要素を用意する
ASK PIXEL ARRAY (0,1) p !画像の各点の色情報を配列に格納する
PRINT "画像の大きさ 縦:";h;" 横:";w
!SET BITMAP SIZE w,h !ウィンドウの大きさを画像に合わせる


LET Rx=10 !1辺の長さ
LET Ry=10
LET th=RAD(30) !方向


DIM M1(3,3),M2(3,3),M7(3,3),M8(3,3)
MAT M1=IDN !画像の中央を原点へ
LET M1(1,3)=-w/2
LET M1(2,3)=-h/2

MAT M2=IDN !方向をX軸に一致させ、半径を1とする
LET M2(1,1)=COS(th)/Rx
LET M2(1,2)=SIN(th)/Rx
LET M2(2,1)=-SIN(th)/Ry
LET M2(2,2)=COS(th)/Ry

MAT M7=IDN !INV(M2)
LET M7(1,1)=COS(th)*Rx
LET M7(1,2)=-SIN(th)*Rx
LET M7(2,1)=SIN(th)*Ry
LET M7(2,2)=COS(th)*Ry

MAT M8=IDN !INV(M1)
LET M8(1,3)=w/2
LET M8(2,3)=h/2


MAT q=ZER !黒色

!座標変換 f:(x,y)→(xx,yy)の逆変換を考える

DIM t(3)
FOR yy=1 TO h !変換後の画素位置で走査する
   FOR xx=1 TO w

      LET t(1)=xx !非線形変換前の線形変換
      LET t(2)=yy
      LET t(3)=1

      MAT t=M1*t
      MAT t=M2*t

      !非線形変換
      LET t(1)=INT(t(1))+0.5
      LET t(2)=INT(t(2))+0.5

      MAT t=M7*t !非線形変換後の線形変換
      MAT t=M8*t
      !PRINT xx;yy !debug
      !MAT PRINT t;

      LET x=INT(t(1)) !元の画素での位置
      LET y=INT(t(2))

      IF x<1 OR x>w OR y<1 OR y>h THEN !範囲内なら
      ELSE
         LET q(xx,yy)=p(x,y)
      END IF

   NEXT xx
NEXT yy

MAT PLOT CELLS, IN 0,1; 1,0 :q !画像を表示する

END
 

FILE GETNAME について

 投稿者:木嶌小春  投稿日:2009年 4月22日(水)18時39分55秒
返信・引用
  FILE GETNAME を使用してファイルに保存したいのですが,以前のバージョン(7.2.8で確認)は,ファイルが存在しない場合は新たにファイルを作成して保存できまし た。7.3.1で下記のプログラムを実行し,新たなファイル名を入力すると,"ファイルが見つかりません。指定されたファイル名が正しいかどうか確認して 下さい。" というエラーメッセージが出ます。対処方法を教えて下さい。よろしくお願いします。


PRINT  ; "出力ファイル名  file name = " ;
FILE GETNAME FILENAME2$
OPEN #1 : NAME FILENAME2$
CLOSE #1
END
 

Re: FILE GETNAME について

 投稿者:白石 和夫  投稿日:2009年 4月23日(木)08時35分22秒
返信・引用
  > No.339[元記事へ]

とりあえず,
http://hp.vector.co.jp/authors/VA008683/Dialogs.htm
の記述にしたがってGetSaveFileNameで代用してください。

なお,File GetNameは規格外の命令なので,どうするのがよいのか今後検討します。
 

Re: FILE GETNAME について

 投稿者:木嶌小春  投稿日:2009年 4月23日(木)10時36分5秒
返信・引用
  > No.340[元記事へ]

ありがとうございました。
GetSaveFileName に変更してみます。
File GetName が従来通り使えるとプログラムを変更しなくてすむので助かりますが・・・・。よろしくお願いします。
 

極座標

 投稿者:荒田浩二  投稿日:2009年 4月27日(月)09時22分5秒
返信・引用  編集済
  一部修正しました(赤字)。

極座標軸を描画する外部絵定義(polar)を作りました。
動径,偏角の数字の有無や目盛間隔など指定できます。
偏角の表示は,1[-180<θ<=180]か,2[0<=θ<360]のどちらかを指定できます。
十進BASICの直交座標軸を描画するDRAW AXESやDRAW GRIDと仕様を合せているので重ねての描画も可能です。

外部絵定義 p_coordinate は,問題座標を極座標に変換して表示します。


DECLARE EXTERNAL PICTURE polar,p_coordinate
READ x0,x9,y0,y9
SET WINDOW x0,x9,y0,y9
!DATA -1,1,-1,1   ! 2*2
DATA -2.1,2.1,-2.1,2.1  ! 4.2*4.2
!DATA 0.2,2.5,-0.6,1.7  ! 2.3*2.3
!DATA -8.5,-3.5,4,9  ! 5*5

! 極座標軸(動径表示位置(0〜3),偏角表示範囲(0〜2),軸,動径目盛間隔,偏角目盛間隔(度))
DRAW polar(2,2,"grid",0.5,15)
!DRAW AXES(0.5,0.5) ! 直交座標軸(十進BASIC独自拡張)
!DRAW GRID(0.5,0.5) ! 直交座標軸(十進BASIC独自拡張)

DEF r(t)=t/PI       ! 螺旋
!DEF r(t)=1*(1-0.8^2)/(1+0.8*COS(t)) ! 楕円(長半径=1,離心率=0.8)
!DEF r(t)=0.8*0.5/(1-0.8*COS(t)) ! 楕円(離心率=0.8,準線x=-0.5)
!DEF r(t)=2*COS(t)   ! 円
!DEF r(t)=1+COS(t)   ! カージオイド
!DEF r(t)=2*SIN(2*t) ! 正葉曲線
!DEF r(t)=1/(5/4*COS(t)+3/2*SIN(t)) ! 直交座標(4/5,0),(0,2/3)を通る直線

CALL red_point1
SET BEAM MODE "IMMORTAL"
LET t0=0       ! LET t0=-PI
LET t9=2*PI    ! LET t9=PI
FOR t=t0 TO t9+1E-8 STEP (t9-t0)/500
   CALL red_point2
   WHEN EXCEPTION IN
      PLOT LINES : r(t)*COS(t),r(t)*SIN(t);
      ! PLOT POINTS : r(t)*COS(t),r(t)*SIN(t)
   USE
      PLOT LINES
   END WHEN
   WAIT DELAY 0.01
NEXT t
PLOT LINES
SET BEAM MODE "RIGOROUS"
BEEP

PLOT TEXT ,AT (x9+x0)/2,y0 : "クリックで極座標表示,右クリックで終了"
DRAW p_coordinate(2,3) ! 極座標表示(偏角範囲(1〜2),表示位置(1〜4))

SUB red_point1
   IF SGN(x0)<>SGN(x9) THEN LET rx0=0 ELSE LET rx0=MIN(ABS(x0),ABS(x9))
   IF SGN(y0)<>SGN(y9) THEN LET ry0=0 ELSE LET ry0=MIN(ABS(y0),ABS(y9))
   LET r1=SQR(rx0^2+ry0^2)  ! 動径最小値
   LET r9=SQR(MAX(ABS(x0),ABS(x9))^2+MAX(ABS(y0),ABS(y9))^2) ! 動径最大値
   LET r8=r1+(r9-r1)/SQR(2) ! 赤点移動半径
   LET x1=r8*COS(t0)
   LET y1=r8*SIN(t0)
END SUB
SUB red_point2
   LET x2=r8*COS(t)
   LET y2=r8*SIN(t)
   SET POINT STYLE 3
   SET POINT COLOR 0
   PLOT POINTS : x1,y1
   SET POINT COLOR 4
   PLOT POINTS : x2,y2 ! 赤点*
   LET x1=x2
   LET y1=y2
   SET POINT STYLE 1
   SET POINT COLOR 1
END SUB

END


REM 極座標軸(動径表示位置,偏角表示範囲,軸,動径目盛間隔,偏角目盛間隔)
EXTERNAL PICTURE polar(rn,tn,ag$,rs,ts)
! rn=動径表示位置(0無,1始線,2十字状,3放射状) ; tn=偏角表示範囲(0無,1[-180〜180],2[0〜360])
! ag$=軸("axis"始線のみ,"grid"円放射格子) ; rs=動径目盛間隔(>=0) ; ts=偏角目盛間隔(0<=ts<360)
ASK LINE COLOR alc
ASK LINE STYLE als
ASK TEXT COLOR atc
ASK TEXT JUSTIFY atjx$,atjy$
ASK AREA COLOR aac
SET LINE COLOR 15
SET TEXT COLOR 15
SET TEXT JUSTIFY "RIGHT","TOP"
ASK WINDOW x0,x9,y0,y9
LET r9=SQR(MAX(ABS(x0),ABS(x9))^2+MAX(ABS(y0),ABS(y9))^2) ! 動径最大値
IF SGN(x0)<>SGN(x9) THEN LET rx0=0 ELSE LET rx0=MIN(ABS(x0),ABS(x9))
IF SGN(y0)<>SGN(y9) THEN LET ry0=0 ELSE LET ry0=MIN(ABS(y0),ABS(y9))
SET LINE STYLE 1
PLOT LINES : 0,0 ; r9,0  ! 極座標始線
IF rn>=1 THEN PLOT TEXT ,AT 0,0 : STR$(0)
IF rs>0 THEN  ! 動径目盛
   ASK DEVICE SIZE PX,PY,S$
   LET r0=rs*INT(SQR(rx0^2+ry0^2)/rs) ! 動径最小目盛
   FOR r=r0 TO r9 STEP rs
      IF LCASE$(ag$)="axis" OR LCASE$(ag$)="axes" THEN
         PLOT LINES : r,-(y9-y0)/PY/2000 ; r,(y9-y0)/PY/2000 ! 始線目盛
      ELSEIF LCASE$(ag$)="grid" THEN
         SET LINE STYLE 3
         DRAW CIRCLE WITH SHIFT(0,0)*SCALE(r) ! 同心円
      END IF
      IF rn=>1 THEN  ! 動径数字あり
         PLOT TEXT ,AT r,0 : STR$(r)     ! 始線
         IF rn>=2 THEN
            PLOT TEXT ,AT 0,r : STR$(r)  ! 十字状上
            PLOT TEXT ,AT -r,0 : STR$(r) ! 十字状左
            PLOT TEXT ,AT 0,-r : STR$(r) ! 十字状下
         END IF
      END IF
   NEXT r
END IF
IF ts>0 THEN  ! 偏角目盛
   SET LINE STYLE 3
  !FOR t=ts TO 360-ts+1E-6 STEP ts

   FOR t=ts TO 360-1E-6 STEP ts
       IF LCASE$(ag$)="grid" THEN PLOT LINES : 0,0;r9*COS(RAD(t)),r9*SIN(RAD(t)) ! 放射状破線
      IF rn=3 THEN ! 動径数字放射状
         FOR r=r0 TO r9 STEP rs
            PLOT TEXT ,AT r*COS(RAD(t)),r*SIN(RAD(t)) : STR$(r)
         NEXT r
      END IF
   NEXT t
   IF tn>=1 THEN ! 偏角数字あり(単位;度)
      LET r1=SQR(rx0^2+ry0^2)  ! 動径最小値
      LET r5=(r1+r9)/2 ! 偏角数字位置
      IF rn=3 THEN SET TEXT BACKGROUND "OPAQUE"
     !FOR t=ts TO 360-ts+1E-6 STEP ts

      FOR t=ts TO 360-1E-6 STEP ts
         IF MOD(t,90)<>0 OR rn<=1 OR rs=0 THEN
            IF t<=180 OR tn=2 THEN LET a=t ELSE LET a=t-360 ! a=偏角
            CALL adjust(a)
            PLOT TEXT ,AT r5*COS(RAD(t)),r5*SIN(RAD(t)) : STR$(a)
         END IF
      NEXT t
   END IF
END IF
SET TEXT BACKGROUND "TRANSPARENT"
SET LINE COLOR alc
SET LINE STYLE als
SET TEXT COLOR atc
SET TEXT JUSTIFY atjx$,atjy$
SET AREA COLOR aac

SUB adjust(d) ! 偏角数字位置調整
   IF ABS(d)<=67.5 OR d>=292.5 THEN
      LET tj1$="LEFT"
   ELSEIF ABS(d)>67.5 AND ABS(d)<112.5 OR d>247.5 AND d<292.5 THEN
      LET tj1$="CENTER"
   ELSE
      LET tj1$="RIGHT"
   END IF
   IF ABS(d)<22.5 OR d>337.5 OR ABS(d)>157.5 AND d<202.5 THEN
      LET tj2$="HALF"
   ELSEIF d>=22.5 AND d<67.5 OR d>112.5 AND d<=157.5 THEN
      LET tj2$="BASE"
   ELSEIF d>=67.5 AND d<=112.5 THEN
      LET tj2$="BOTTOM"
   ELSEIF d>=-112.5 AND d<=-67.5 OR d>=247.5 AND d<=292.5 THEN
      LET tj2$="TOP"
   ELSE
      LET tj2$="CAP"
   END IF
   SET TEXT JUSTIFY tj1$,tj2$
END SUB
END PICTURE


REM 極座標(r,θ)表示
EXTERNAL PICTURE p_coordinate(tn,p)
! マウスポインタが指す点の極座標(動径,偏角)を表示
! 左クリック(ドラッグ)で表示,右クリックで終了
! tn=偏角範囲(1[-π<θ<=π],2[0<=θ<2π]) ; p=表示位置(1右上,2左上,3左下,4右下)
ASK WINDOW x0,x9,y0,y9
ASK TEXT JUSTIFY atjx$,atjy$
ASK TEXT HEIGHT ath
ASK AREA COLOR aac
SET TEXT FONT "",10
SET AREA COLOR 0
IF SGN(x0)<>SGN(x9) THEN LET rx0=0 ELSE LET rx0=MIN(ABS(x0),ABS(x9))
IF SGN(y0)<>SGN(y9) THEN LET ry0=0 ELSE LET ry0=MIN(ABS(y0),ABS(y9))
LET r1=SQR(rx0^2+ry0^2)  ! 動径最小値
LET r9=SQR(MAX(ABS(x0),ABS(x9))^2+MAX(ABS(y0),ABS(y9))^2) ! 動径最大値
LET r9d=LOG10(r9)
LET rd=LOG10((r9-r1)/2000)
IF r9d>0 THEN LET u$=REPEAT$("-",CEIL(r9d)-1)&"%" ELSE LET u$="%"
IF rd<0 THEN LET u$=u$&"."&REPEAT$("#",CEIL(ABS(rd)))
CALL position
DO
   MOUSE POLL mx,my,ml,mr
   IF ml=1 THEN
      LET r=SQR(mx^2+my^2)  ! 動径
      WHEN EXCEPTION IN
         LET t=ANGLE(mx,my) ! 偏角(-π<t<=π)
         IF tn=2 AND t<0 THEN LET t=t+2*PI ! 偏角(0<=t<2π)
      USE
         LET r,t=0 ! 特異点(極)
      END WHEN
      LET r$=USING$(u$,r)             ! 動径
      LET t$=USING$("-%.####",t)      ! 偏角
      LET d$=USING$("---%.##",DEG(t)) ! (度)
      PLOT AREA : x1,y1;x2,y1;x2,y2;x1,y2
      PLOT TEXT ,AT x1,y1 : r$&"  "&t$&"("&d$&"°)"
   END IF
   WAIT DELAY 0.01 ! CPU負荷軽減
LOOP UNTIL mr=1    ! 右クリックで終了
SET TEXT JUSTIFY atjx$,atjy$
SET TEXT HEIGHT ath
SET AREA COLOR aac

SUB position ! 表示位置
   ASK TEXT WIDTH(REPEAT$("W",LEN(u$)+20)) atw
   LET x1=x9
   LET x2=x9-atw
   LET y1=y9
   LET y2=y9-1.1*ath
   SELECT CASE p
   CASE 1  ! 画面右上
      SET TEXT JUSTIFY "RIGHT","TOP"
   CASE 2  ! 画面左上
      SET TEXT JUSTIFY "LEFT","TOP"
      LET x1=x0
      LET x2=x0+atw
   CASE 3  ! 画面左下
      SET TEXT JUSTIFY "LEFT","BOTTOM"
      LET x1=x0
      LET x2=x0+atw
      LET y1=y0
      LET y2=y0+1.1*ath
   CASE 4  ! 画面右下
      SET TEXT JUSTIFY "RIGHT","BOTTOM"
      LET y1=y0
      LET y2=y0+1.1*ath
   END SELECT
END SUB
END PICTURE
 

Re: 微分方程式の数値解法

 投稿者:SECOND  投稿日:2009年 5月 2日(土)17時18分22秒
返信・引用  編集済
  > No.315[元記事へ]

!どなたか御知恵 拝借 お願いします。

!先のルンゲクッタ法で、他の微分要素を含み、暴走を生じ、それを押えるために
!安定化バッファ、f1_ f2_ を用いたが、その是非を、別な等価回路と網回路で計算
!し直し、比較して確かめた。 一致する様で、正しい波形だった。
!計算間隔 0.0105秒 では互いの差( ルンゲ・クッタ1、ルンゲ・クッタ2 )が目立ち
!ますが、 〜0.0005秒くらいで重なります。(全文コピー、RUN)
!
!問題は、ラプラス変換とも比較しようとした際に生じ、R1(b+sinωt)i(t)部分の変換で、
!時間関数の、抵抗と電流の積が、

! R1(b+sinωt)i(t) → R1*b*i(t)+R1*j/2*( e^(j*w*t)-e^(-j*w*t) )*i(t)
!      ラプラス変換 → R1*b*i(s)+R1*j/2*(  i(s-jw) - i(s+jw)   )

!のようになって、i(s) にまとまらず、i(s)を決定できずに、強引に jw=0 での i(s)に
! s-jw, s+jw を代入して求めた i(s) を逆変換して i(t) を出した。(添付画像の式参照)
!しかし・・

!R1=30 付近の低い値では、比較的一致するも、R1=100以上あたりから著しく外れる。
!原因は、強引な i(s)の前提ですが、参考例題も見当たらず難渋している。

!下の laplace_ON を1にすると、ルンゲ・クッタ2 との比較テストモードに入ります。
!ルンゲ・クッタ1は、オーバーフローしやすい為、除いています。

!問題を簡単にするため、2次回路開放同然 R2→1e9 で、
! E, L1, R1(1+sinωt) の3素子のみの直列回路として、その電流i(t)と
!                                   R1(1+sinωt)の、両端電圧v(t)を、描きます。
! ラプラス変換   v(t)灰, i(t)緑
! ルンゲ・クッタ2 v(t)赤, i(t)青  … 2次側は単独、L2開放端v2(t)赤, i2(t)青≒0
!---------------------------
!
OPTION ARITHMETIC COMPLEX
LET laplace_ON=0

!---------------------------ルンゲ・クッタ1で計算。(バッファが無いと暴走する)
!回路の微分方程式   r(t)=R1*(1+sin(w*t))
!
!  i1┌→┐M┌→┐i2    (一次側の電圧平衡式)L1*(di1/dt)+r(t)*i1-M*(di2/dt)=E
!    ┌─┐ ┌─┐      (二次側の電圧平衡式)M*(di1/dt)=L2*(di2/dt)+R2*i2
!    │  L1 L2  R2
!    E   │ └─┘
!    │  r(t)=R1*(1+sin(w*t))
!    └─┘
!  バッファ無しでは    f1(t, i1)= (di1/dt)= ( E-R1*(1+sin(w*t))*i1+M*(di2/dt) )/L1
!  暴走する 微分方程式 f2(t, i2)= (di2/dt)= ( M*(di1/dt)-R2*i2 )/L2

!---------------------------ルンゲ・クッタ2で計算。(バッファ不要)
!相互インダクタンス M= k*(√L1*L2)の結合係数 k=1 として、漏れ磁束の無い場合、
!回路のi1側に揃えるT型等価回路で、網路を変更。
!
!    ┌ i31→┐         上の回路と等価な i2 =(i31+i21)*SQR(L1/L2)
!        ┌→┐i21
!    ┌─┬─┐                 (i31の網路) R2*L1/L2*(i31+i21) +r(t)*i31= E
!    │  L1  R2*L1/L2           (i21の網路) R2*L1/L2*(i31+i21) +L1*(di21/dt)= 0
!    E   ├─┘
!    │  r(t)=R1*(1+sin(w*t))
!    └─┘
!                                              i31= (E-R2*L1/L2*i21) /(r(t)+R2*L1/L2)
!                              E+L1*(di21/dt)= r(t)*i31
!                             E+L1*(di21/dt)= r(t)*(E-R2*L1/L2*i21) /(r(t)+R2*L1/L2)
!                                    (
!                                     )
!問題の無い 微分方程式 f21(t, i21)= (di21/dt)= -(E+r(t)*i21) /(L2/R2*r(t)+L1)

!-------------------------------
LET E=10
LET R1=1000
LET L1=20
LET L2=20
LET R2=1000
LET M=SQR(L1*L2) !結合係数 k=1
!
LET b=1
LET w=2*PI*1 !1Hz
DEF r(t)=R1*(b+SIN(w*t))
!
IF laplace_ON=1 THEN
   LET R1=30
   LET R2=1e9
END IF
!
!-----ルンゲ・クッタ1
DEF f1(t,i1)=( E-r(t)*i1+M*f2_ )/L1 ! f2_…直接のf2()は、不可
DEF f2(t,i2)=( M*f1_-R2*i2 )/L2     ! f1_…直接のf1()は、不可

SUB RungeKutta_1(t,i1,i2)
   LET k1=f1(t,i1)
   LET k2=f1(t+dt/2, i1+k1*dt/2)
   LET k3=f1(t+dt/2, i1+k2*dt/2)
   LET k4=f1(t+dt,   i1+k3*dt )
   LET i1=i1+(k1+2*k2+2*k3+k4)*dt/6
   LET f1_=f1(t,i1) ! f1_…f1()のバッファ
   !
   LET k1=f2(t,i2)
   LET k2=f2(t+dt/2, i2+k1*dt/2)
   LET k3=f2(t+dt/2, i2+k2*dt/2)
   LET k4=f2(t+dt,   i2+k3*dt )
   LET i2=i2+(k1+2*k2+2*k3+k4)*dt/6
   LET f2_=f2(t,i2) ! f2_…f2()のバッファ
END SUB

!-----ルンゲ・クッタ2
DEF i31=(E-R2*L1/L2*i21)/(r(t)+R2*L1/L2)
DEF f21(t,i21)=-(E+r(t)*i21)/(L2/R2*r(t)+L1)
DEF i20=(i31+i21)*SQR(L1/L2)

SUB RungeKutta_2(t,i21)
   LET k1=f21(t,i21)
   LET k2=f21(t+dt/2, i21+k1*dt/2)
   LET k3=f21(t+dt/2, i21+k2*dt/2)
   LET k4=f21(t+dt,   i21+k3*dt )
   LET i21=i21+(k1+2*k2+2*k3+k4)*dt/6
END SUB

!-----ラプラス逆変換
DIM Xr(5)
!   xr(0)=0 …根は6個、0は自明で因数分解から除いた。
LET Xr(1)=-R1*b/L1
LET Xr(2)=COMPLEX(0,w)
LET Xr(3)=COMPLEX(-R1*b/L1,w)
LET Xr(4)=COMPLEX(0,-w)
LET Xr(5)=COMPLEX(-R1*b/L1,-w)
FOR j=1 TO 5
   PRINT Xr(j)
NEXT j
DEF Gs(s)=E/L1*( (s^2+w^2)*((s+R1*b/L1)^2+w^2) -R1/L1*s*w*(2*s+R1*b/L1) )*EXP(s*t)
DEF k_0=Gs(0    )/ (       (0    -Xr(1))*(0    -Xr(2))*(0    -Xr(3))*(0    -Xr(4))*(0    -Xr(5)) )
DEF k_1=Gs(Xr(1))/ ( Xr(1)              *(Xr(1)-Xr(2))*(Xr(1)-Xr(3))*(Xr(1)-Xr(4))*(Xr(1)-Xr(5)) )
DEF k_2=Gs(Xr(2))/ ( Xr(2)*(Xr(2)-Xr(1))              *(Xr(2)-Xr(3))*(Xr(2)-Xr(4))*(Xr(2)-Xr(5)) )
DEF k_3=Gs(Xr(3))/ ( Xr(3)*(Xr(3)-Xr(1))*(Xr(3)-Xr(2))              *(Xr(3)-Xr(4))*(Xr(3)-Xr(5)) )
DEF k_4=Gs(Xr(4))/ ( Xr(4)*(Xr(4)-Xr(1))*(Xr(4)-Xr(2))*(Xr(4)-Xr(3))              *(Xr(4)-Xr(5)) )
DEF k_5=Gs(Xr(5))/ ( Xr(5)*(Xr(5)-Xr(1))*(Xr(5)-Xr(2))*(Xr(5)-Xr(3))*(Xr(5)-Xr(4))               )
DEF k0_5=re(k_0+k_1+k_2+k_3+k_4+k_5) !留数の和

!-----run
SET TEXT background "OPAQUE"
DIM baki(10),bakv(10) ! drawing channels
!
FOR dt=0.0105 TO 0.000499 STEP -0.001 !演算ピッチ sec. pitch time
   IF laplace_ON=1 THEN LET dt=.0005
   SET DRAW mode hidden
   CLEAR
   SET DRAW mode explicit
   LET t=0 !計算開始 sec. calculation start
   LET ts=0 !描画開始 sec. drawing start
   LET tw=3 !描画時間 sec. drawing time
   LET Vw=28 !+目盛上限(上側グラフ)1の倍数、Volt.Ampere. maximum scale
   LET ofs=15 !+目盛上限(下側グラフ)5の倍数、Under_Graph offset !CEIL(Vw/10)*5
   !
   LET i21= -E/R1   ! ルンゲ・クッタ2 初期値( i1=i31←i21, i2=i20←i21+i31) at t=0
   LET i1=i31       !┐
   LET i2=i20       !┼ルンゲ・クッタ1 初期値! at t=0
   LET f2_=f2(t,i2) !┘
   !
   IF laplace_ON=1 THEN LET i21=0
   !
   SET WINDOW -.06*tw, tw, -Vw,Vw
   SET COLOR MIX(15) .5,.5,.5
   DRAW grid(1,5)
   PLOT TEXT,AT .1,Vw*0.92,USING"計算間隔=#.###### 秒。 計算開始後###.### 秒からの描画":dt,ts
   PLOT TEXT,AT .1,Vw*0.86,USING"ω=#.##rad/s E=##V L1=##H L2=##H k=1 R1=####Ω R2=####Ω":w,E,L1,L2,R1,R2
   PLOT TEXT,AT .1,-0.1*Vw:"r(t)="& STR$(R1)& "*("& STR$(b)& "+sinωt)"
   DO
      IF laplace_ON=1 THEN
      !-----ラプラス
         CALL Grph( "green","i1(x20mA)", K0_5*50, "gray","v1(x1V)", K0_5*r(t) , 8, 0)
      ELSE
      !-----ルンゲ・クッタ1
         CALL Grph( "blue","i1(x20mA)", i1*50 , "red","v1(x1V)",r(t)*i1          , 1, 0)
         CALL Grph( "blue","i1(x20mA)", i1*50 , "red","v1(x1V)", E-(L1*f1_-M*f2_), 2, 0)
         CALL Grph( "blue","i2(x2mA)" ,-i2*500, "red","v2(x1V)", L2*f2_-M*f1_    , 3, ofs )
         CALL Grph( "blue","i2(x2mA)" ,-i2*500, "red","v2(x1V)",-R2*i2           , 4, ofs )
         CALL RungeKutta_1(t,i1,i2)
      END IF
      !-----ルンゲ・クッタ2
      CALL Grph( "blue","i1(x20mA)", i31*50 , "red","v1(x1V)", r(t)*i31       , 5, 0)
      CALL Grph( "blue","i1(x20mA)", i31*50 , "red","v1(x1V)", E+L1*f21(t,i21), 6, 0)
      CALL Grph( "blue","i2(x2mA)" ,-i20*500, "red","v2(x1V)",-R2*i20         , 7, ofs)
      CALL RungeKutta_2(t, i21)
      !-----
      LET t=t+dt
   LOOP UNTIL ts+tw< t
NEXT dt

!-----draw
SUB Grph( icol$,i$,i, vcol$,v$,v, n, ofs)
   SET WINDOW -.06*tw, tw, -Vw+ofs, Vw+ofs
   IF ts< t THEN
      SET LINE COLOR vcol$
      PLOT LINES :t-ts-dt, bakv(n); t-ts, v
      SET LINE COLOR icol$
      PLOT LINES :t-ts-dt, baki(n); t-ts, i
   ELSEIF t=ts THEN
      SET TEXT COLOR vcol$
      PLOT TEXT,AT .1, .17*Vw :v$
      SET TEXT COLOR icol$
      PLOT TEXT,AT .1, .11*Vw :i$
      IF ofs<>0 THEN
         SET LINE COLOR 15
         PLOT LINES :-.06*tw, 0; tw,0
         SET TEXT COLOR 15
         ASK PIXEL SIZE (0,0 ;tw,Vw) px,py
         FOR j=5*INT((-Vw+ofs)/5+1) TO ofs-1 STEP 5
            PLOT TEXT,AT -22*tw/px, j-15*Vw/py, USING"###":j
         NEXT j
      END IF
      SET TEXT COLOR 1
   END IF
   LET baki(n)=i
   LET bakv(n)=v
END SUB

END
 

Re: 微分方程式の数値解法

 投稿者:しまむら1243  投稿日:2009年 5月 5日(火)21時04分16秒
返信・引用
  > No.343[元記事へ]

SECONDさんへのお返事です。

SECONDさん、いろいろご検討頂いて有り難うございます。

!---------------------------ルンゲ・クッタ2で計算。(バッファ不要)
!相互インダクタンス M= k*(√L1*L2)の結合係数 k=1 として、漏れ磁束の無い場合、
!回路のi1側に揃えるT型等価回路で、網路を変更。
!問題の無い 微分方程式 f21(t, i21)= (di21/dt)= -(E+r(t)*i21) /(L2/R2*r(t)+L1)

変圧器の一次側換算等価回路で考えるこの案、いいですね。
原式にしたがって忠実に計算するのが一番正確だと拘っていて気付きませんでした。

ただ一寸電気的に理解できないのは、等価回路方式ではk=1の場合を扱えるのに、原式から行列を使ってルンゲ・クッタ法を適用できる連立微分式を導かれた 山中さんの式だとk=1の場合が扱えない、という点です。等価回路も山中さんの連立微分式も、同じ原式から組み立てられたものなのですが。。でもこれはプ ログラミングとは別の問題ですね。

さてラプラス変換を利用してルンゲ・クッタの修正法を検証しようと

!のようになって、i(s) にまとまらず、i(s)を決定できずに、強引に jw=0 での i(s)に
! s-jw, s+jw を代入して求めた i(s) を逆変換して i(t) を出した。(添付画像の式参照)

とされていますが、t=+0で(は未だ交流になっていないから)jw=0とする、という手法はsin(wt)のラプラス変換の原型が崩されてしまうので、理屈的に不合理になって無理ではないかと思います。
では、何か巧い方法は?と言われると、ラプラス変換は定係数の微分式に有用であって、変係数の微分式に適用出来ないのではないでしょうか。残念ながら手元の工学用数学書とネット検索した限りではその様な記載しか無かったです。

私は山中さんが導かれた連立微分式にルンゲ・クッタ法を適用したものと、SECONDさんが作成されたルンゲ・クッタ修正法とを同じ条件で計算してみまし たが、t=+0の立ち上がり付近でSECONDさんの波形には高周波振動が含まれていた点を除けば、ぴったり合っていました。
 

Re: 微分方程式の数値解法

 投稿者:SECOND  投稿日:2009年 5月 5日(火)22時50分21秒
返信・引用
  > No.345[元記事へ]

しまむら1243さんへのお返事です。

こんにちは、調査して頂いたようで、大変感謝します。でも今の私には、

> では、何か巧い方法は?と言われると、ラプラス変換は定係数の微分式に有用であって、変係数の微分式に適用出来ないのではないでしょうか。残念ながら手元の工学用数学書とネット検索した限りではその様な記載しか無かったです。

この文だけしか、目に入りません。本当に不可能なのか否か、にわかには受け入れがたく
もうしばらくは、探索にこだわってみます。ありがとうございました。
 

描画公表とプログラム

 投稿者:六甲の初心者  投稿日:2009年 5月 9日(土)04時36分37秒
返信・引用
  初めて投稿します。教えていただく事項だけでもいいのでしょうか。
ある物理現象についてそれを時間的変化で表示するアルゴリズムを思いつきBASICで書きました
この結果を公表して有用なものかどうか評価をいただければと考えるのですが。
まず、公表の手段もさだかではありません。ホームペジ(未作)上、動画投稿、など。
いずれかの場合も、まだプログラムを公表せずに済むことが希望なのですが可能なのでしょうか。
教えていただければ幸いです。
 

Re: 描画公表とプログラム

 投稿者:SECOND  投稿日:2009年 5月10日(日)00時19分30秒
返信・引用
  > No.347[元記事へ]

六甲の初心者さんへのお返事です。

ヘルプ・ファイル冒頭の、
(仮称)十進BASICについて→「使用規定および著作権」の中に、

「(仮称)十進BASICは教育研究を目的として作成されたプログラムです。
  本BASICを利用して得られた研究結果は必ず公開してください。」 とあります。

是非、公開して下さい。著作権などには、無関係だと思います。
数学的遺産は、過去に高度なものが多く、失われているだけかも知れません。
私自身 抱える問題なども、何処かで解決されていて、忘れ去られたもの
では、ないでしょうか。
 

Re: 描画公表とプログラム

 投稿者:六甲の初心者  投稿日:2009年 5月10日(日)08時40分0秒
返信・引用
  > No.348[元記事へ]

SECONDさんありがとうございます
私の表現が足らないところもあったのですが、考えたプロセスは常に公表しなければならず、それが出来なければ他の言語に変えなさいということですね
了解しました

ただ、BASICは子供のころから意識せずに書きとめてきましたので何か腑に落ちない気がしていますが


> 六甲の初心者さんへのお返事です。
>
> ヘルプ・ファイル冒頭の、
> (仮称)十進BASICについて→「使用規定および著作権」の中に、
>
> 「(仮称)十進BASICは教育研究を目的として作成されたプログラムです。
>   本BASICを利用して得られた研究結果は必ず公開してください。」 とあります。
>
> 是非、公開して下さい。著作権などには、無関係だと思います。
> 数学的遺産は、過去に高度なものが多く、失われているだけかも知れません。
> 私自身 抱える問題なども、何処かで解決されていて、忘れ去られたもの
> では、ないでしょうか。
 

Re: 描画公表とプログラム

 投稿者:SECOND  投稿日:2009年 5月10日(日)10時43分57秒
返信・引用
  > No.349[元記事へ]

六甲の初心者さんへのお返事です。

>他の言語に変えなさいというこ・・・

では、ないと思います。誤解されましたのであれば、御詫びします。
これは、先生のご希望と期待で、強要の意図は、絶対にないと思います。
 

!スカイ・ウェイ

 投稿者:SECOND  投稿日:2009年 5月10日(日)13時25分52秒
返信・引用
  !こんなものが、出て来た。(再投稿?、再々・・不明)
!このアニメは、山中和義氏のガイドにより、大昔しに、作成したものです。

!スカイ・ウェイ
!-----
DIM Tr(4,4),Mv(4,4),Mp(4,4) !被写体移動、視点移動、プロジェクション変換
DIM mx(4,4),Xz(4,4),zY(4,4) !作業用、XY_Xz変換、XY_zY変換

MAT Tr=IDN
MAT Mv=IDN

!-----Y軸→Z軸 XY平面図→XZ平面図
MAT READ Xz
DATA 1,0,0,0
DATA 0,0,1,0 !Xz(2,1)=Z軸水平傾斜、Xz(2,2)=Z軸垂直傾斜
DATA 0,0,0,0
DATA 0,0,0,1 !Xz(4,2)=増設Y座標

!-----X軸→Z軸 XY平面図→ZY平面図
MAT READ zY
DATA 0,0,1,0 !zY(1,1)=Z軸水平傾斜、zY(1,2)=Z軸垂直傾斜
DATA 0,1,0,0
DATA 0,0,0,0
DATA 0,0,0,1 !zY(4,1)=増設X座標

!-----3D(X,Y,Z)→2D(X,Y)/Z プロジェクション変換 Mp(行,列)

SET WINDOW -1,1,-1,1 ! 画面スケールで、投影距離調整。
!           行列は、1に正規化した。
MAT READ Mp
DATA 1,0,0,0 !(X,Y,Z,1)→(1X,1Y,1Z,1Z) 3列目の1Z は無効。
DATA 0,1,0,0 !
DATA 0,0,1,1 !      4列目の1Z→ 描画倍率=1/1Z で 遠近効果する。
DATA 0,0,0,0 !             (距離1への投影)

!-----
!原画_行ベクトル Tr   論理_行ベクトル
!  (X,Y,0,1)|1 0 0 0| →(X,Y,Z,1)Z 座標の追加。
!       |0 1 0 0|
!       |0 0 1 0|
!       |0 0 Z 1|
!論理_行ベクトル  Mv   論理_行ベクトル
!  (X,Y,Z,1)|1 0 0 0| →(X-x,Y-y,Z-z,1)視点(x,y,z)からの相対座標。
!       |0 1 0 0|
!       |0 0 1 0|
!       |-x -y -z 1|
!論理_行ベクトル  Mp    表示_行ベクトル
!(X-x,Y-y,Z-z,1)|1 0 0 0| →(X-x,Y-y,Z-z,Z-z) Z 座標を、縮小率へ転写。
!        |0 1 0 0|
!        |0 0 1 1|
!        |0 0 0 0|
!4列目Z-z:倍率逆数(分母)= 1/{Z-z} Z座標→投影縮小率。

!-----
!等加速度運動
DEF v(t)=v0  +a*t     !速度
DEF d(t)=v0*t+a*t*t/2 !移動距離 ※∫v(t)dt

LET v0=15 ! m/s 初速度
LET a=-v0^2/2/298 ! m/s^2 減速加速度, -v0^2/2/移動距離
!
LET t0=TIME !開始
DO WHILE v(t)>0 !減速、停止するまで
   LET t=TIME-t0 !経過時間を得る
   IF t>tb+0.15 THEN
      LET tb=t
      PRINT USING "時間=###.## 速度=##.##  走行距離=###.##":t,v(t),d(t)
      SET DRAW mode hidden !裏ページに書く、ちらつき防止の開始
      CALL Animation( d(t)) !位置d(t)の前方描画
      SET DRAW mode explicit !裏ページの表示、ちらつき防止の終了
   END IF
LOOP

DEF yaw(z)=10*SIN((z-2)*0.1) !カーブ、横の偏差
DEF d_yaw(z)= COS((z-2)*0.1) !カーブ、微分係数
DEF pitch(z)=5*SIN(z*0.1) !ピッチ、縦の偏差
DEF d_pitch(z)=0.5*COS(z*0.1) !ピッチ、微分係数

SUB Animation(d) !-----バス位置d の外界を描く
   CLEAR
   !----空
   SET AREA COLOR 17
   PLOT AREA:-1,0; 1,0; 1,1; -1,1
   !----地
   SET AREA COLOR 42
   PLOT AREA:-1,0; 1,0; 1,-1; -1,-1
   !----文字
   SET TEXT COLOR 0
   SET TEXT FONT "",90
   !
   !バス位置d が固定(Z=1.5m)する様に 視点dd (Z=0m)を後ろへ下げる。
   !視点dd(Z=0)を中心、バス位置d(Z=1.5)を画面の枠に合わせる。投影面(Z=1.5)に射影。
   !前方170m から、視点dd(Z=0)の 0.1m前方(Z=0.1)を限界に、※奥から描く
   !
   !----視点移動のマトリクス Mv
   LET dd=d-1.5
   LET Mv(4,1)=-2-yaw(d) !車道左端から2m と左右動
   LET Mv(4,2)=-1.5-pitch(d) !高さ1.5m と上下動
   LET Mv(4,3)=-dd !バス位置d の後方1.5m
   !----
   ! 1    ,0      ,0 , 0|
   ! 0    ,1      ,0 , 0|
   ! 0    ,0      ,1 , 0|
   !-2-yaw(d) ,-1.5-pitch(d),-dd, 1|
   !----
   FOR i=2.5*INT(d/2.5)+170 TO dd+0.1 STEP -2.5
   ! ----被写体移動のマトリクス Tr
      LET Tr(4,1)=yaw(i) !左右動
      LET Tr(4,2)=pitch(i) !上下動
      LET Tr(4,3)=i !z座標
      !----
      ! 1   ,0    ,0, 0|
      ! 0   ,1    ,0, 0|
      ! 0   ,0    ,1, 0|
      ! yaw(i) ,pitch(i) ,i, 1|
      !----
      MAT mx=Tr*Mv*Mp
      DRAW 道路 WITH mx
      IF REMAINDER(i,10) =5 THEN DRAW 街路樹 WITH mx
      IF REMAINDER(i,10) =0 THEN
         IF REMAINDER(i,50)=0 THEN DRAW バス停(2)WITH mx ELSE DRAW バス停(4)WITH mx !(終点=3 途中=4)
         DRAW 建物(8,-9,3,3,1) WITH mx !(x,y,幅,高,奥)
         DRAW 建物(-8,-9,3,3,1) WITH mx !(x,y,幅,高,奥)
      END IF
   NEXT i
END SUB

!パーツのサイズ。バスの位置d (Z=1.5m)で、表示倍率 1/z=1/1.5

PICTURE 建物(x,y,w,h,d1)
! ---顔面
   LET zY(1,1)=d_yaw(i+w/2) !Z軸水平傾斜、カーブの微分
   LET zY(1,2)=0 !d_pitch(i+w/2) !Z軸垂直傾斜、ピッチの微分
   LET zY(4,1)=x !増設X軸
   DRAW 前後面(y,w,h) WITH zY !元のX軸→Z軸
   !---背面
   LET zY(4,1)=x+d1 !増設X軸
   DRAW 前後面(y,w,h) WITH zY !元のX軸→Z軸
   !---屋上
   LET Xz(2,1)=d_yaw(i+w/2) !Z軸水平傾斜、z軸カーブの微分
   LET Xz(2,2)=0 !d_pitch(i+w/2) !Z軸垂直傾斜、z軸ピッチの微分
   LET Xz(4,2)=y+h !増設Y軸
   DRAW 水平面(x,w,d1) WITH Xz !元のY軸→Z軸
   !---床面
   LET Xz(4,2)=y !増設Y軸
   DRAW 水平面(x,w,d1) WITH Xz !元のY軸→Z軸
   !---側面
   SET AREA COLOR 22
   PLOT AREA:x,y; x+d1,y; x+d1,y+h; x,y+h
END PICTURE
!
PICTURE 前後面(y,w,h)
   SET AREA COLOR 25
   PLOT AREA:0,y; w,y; w,y+h; 0,y+h !(Z,Y)座標として描く。
END PICTURE
PICTURE 水平面(x,w,d1)
   SET AREA COLOR 25 !26
   PLOT AREA:x,0; x+d1,0; x+d1,w; x,w !(X,Z)座標として描く。
END PICTURE

PICTURE 道路
   LET Xz(2,1)=d_yaw(i+2.2/2) !Z軸水平傾斜、z軸カーブの微分
   LET Xz(2,2)=d_pitch(i+2.2/2) !Z軸垂直傾斜、z軸ピッチの微分
   LET Xz(4,2)=0 !増設Y軸
   DRAW 路面 WITH Xz !元のY軸→Z軸
   !---継ぎ目線
   PLOT LINES:  0,0; 2.9,0
   PLOT LINES:3.1,0;   6,0
END PICTURE
PICTURE 路面
   SET AREA COLOR 15
   PLOT AREA:0,0; 6,0; 6,2.2; 0,2.2 !(X,Z)座標として描く。
END PICTURE

PICTURE 街路樹
   SET AREA COLOR 12 !幹
   PLOT AREA:-0.075,0; 0.075,0; 0.025,3; -0.025,3
   SET AREA COLOR 10 !葉
   FOR w=1 TO 7
      DRAW disk WITH SCALE(0.3+0.05-RND*0.1)*SHIFT(0.4-RND*0.8, 2.7+0.325-RND*0.75)
   NEXT W
END PICTURE

PICTURE バス停(c)
   SET AREA COLOR c
   PLOT AREA:-0.025,0; 0.025,0; 0.025,2; -0.025,2
   DRAW disk WITH SCALE(0.5)*SHIFT(0,2)
   PLOT TEXT,AT -.35,1.74,USING ">%%":STR$(i)
END PICTURE

END
 

プレイリストを作る

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時30分6秒
返信・引用
  プレイリストファイル(拡張子 m3u asx)を作る
リストの編集機能(リストの追加、削除、順番の入れ替え等)はありません
名前でソートするのみ


INPUT  PROMPT "INPUT FILE PATH =":PT$ !'絶対パス
IF RIGHT$(PT$,1)<>"\" THEN LET PT$=PT$ & "\"
LET PA$=PT$
LET PT$=PT$ & "*.*" !'ワイルドカード
LET  N=FILES(PT$)
IF N > 0 THEN
   DIM N$(N),NAME$(N),EXT$(N)
   FILE LIST PT$, N$
ELSE
   PRINT "No File"
   STOP
END IF
FOR I=1 TO N
   FILE SPLITNAME(N$(I)) PATH$,NA$,EX$
   IF POS(".WAV.WMA.MP3",UCASE$(EX$)) > 0 THEN !'拡張子判別
      LET  NN=NN+1
      LET  NAME$(NN)=NA$ !'リスト登録
      LET  EXT$(NN)=EX$
   END IF
NEXT I
IF NN=0 THEN
   PRINT "No File"
   STOP
END IF
FOR I=1 TO NN  !' せいぜい数十曲程度 (1曲3分×100曲=5時間 !?)
   FOR J=I+1 TO NN
      IF NAME$(I) > NAME$(J) THEN !'!昇順にソート
         SWAP NAME$(I),NAME$(J)
         SWAP EXT$(I),EXT$(J)
      END IF
   NEXT J
NEXT I
PRINT "ファイル数=";NN
DO
   INPUT  PROMPT "SAVE FILE NAME=":F$ !'拡張子(.asx) OR (.m3u)を付加すること
LOOP UNTIL UCASE$(RIGHT$(F$,3))="M3U" OR UCASE$(RIGHT$(F$,3))="ASX"
OPEN #1:NAME F$
SELECT CASE UCASE$(RIGHT$(F$,3))
CASE "M3U"
   FOR I=1 TO NN
      PRINT #1:PA$;NAME$(I);EXT$(I) !'絶対パス指定
   NEXT I
CASE "ASX"
   PRINT #1:CHR$(60);"asx version = ";CHR$(34);"3.0";CHR$(34);" ";CHR$(62)
   FOR I=1 TO NN
      PRINT #1:CHR$(9);CHR$(60);"entry";CHR$(62)
      PRINT #1:CHR$(9);CHR$(9);CHR$(60);"title";CHR$(62);NAME$(I);CHR$(60);"/title";CHR$(62)
      PRINT #1:CHR$(9);CHR$(9);CHR$(60);"ref href = ";CHR$(34);PA$;NAME$(I);EXT$(I);CHR$(34);" /";CHR$(62)
      PRINT #1:CHR$(9);CHR$(60);"/entry";CHR$(62)
   NEXT I
   PRINT #1:CHR$(60);"/asx";CHR$(62)
END SELECT
CLOSE #1
END
 

2変数二分法

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時31分20秒
返信・引用
  RANDOMIZE
DEF FNF(X, Y) = A * X + B * Y - E
DEF FNG(X, Y) = C * X + D * Y - F
LET A=INT(RND*10)+1
LET B=INT(RND*10)+1
LET C=INT(RND*10)+1
LET D=INT(RND*10)+1
LET E=INT(RND*10)-5
LET F=INT(RND*10)-5
PRINT A;"* X +";B;"* Y=";E
PRINT C;"* X +";D;"* Y=";F
LET  XH = 100
LET  XL = -XH
DO
   LET  XM = (XH + XL) / 2
   LET  YM = (F - C * XM) / D !' G(X,Y)=0 を Y=GG(X)の形に変形し、XMを代入
   LET  YH = (F - C * XH) / D !' G(X,Y)=0 を Y=GG(X)の形に変形し、XHを代入
   IF FNF(XM, YM) * FNF(XH, YH) < 0 THEN LET  XL = XM ELSE LET  XH = XM
LOOP UNTIL ABS(FNF(XM, YM)) < 1E-8 AND ABS(FNG(XM, YM)) < 1E-8
PRINT "X,Y="; XM; YM
PRINT "X,Y=";(D*E-B*F)/(A*D-B*C);(A*F-C*E)/(A*D-B*C) !'検算
END
 

浮動小数変換

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時32分34秒
返信・引用
  IEEE754 浮動小数変換
正規化数のみ対応 (非正規化数、無限大、NaN値には対応していません)


OPTION CHARACTER BYTE
LET  X=1/3
PRINT  CVS(FLOAT2STR$(X,8,23)) !'float 32bit
PRINT  STR2FLOAT(PACKDBL$(X),11,52) !'double 64bit
PRINT  STR2FLOAT(FLOAT2STR$(X,15,64),15,64) !'long double 80bit
END

EXTERNAL  FUNCTION AND(X,Y)
LET  XO=X
LET  YO=Y
LET  A=1
LET  S=0
FOR I=0 TO 31
   LET  XX=MOD(XO,2)
   LET  YY=MOD(YO,2)
   IF YY+XX=2 THEN  LET  S=S+A
   LET  XO=INT(XO/2)
   LET  YO=INT(YO/2)
   LET  A=A*2
NEXT I
LET  AND=S
END FUNCTION

EXTERNAL  FUNCTION CVS(A$)
!'IEEE754 32bit str to float
OPTION CHARACTER BYTE
OPTION BASE 0
DIM B(32)
LET  A$=LEFT$(A$,4)
LET  K = 0
FOR I = 4 TO 1 STEP -1
   LET  D$ = MID$(A$, I, 1)
   FOR J = 0 TO 7
      IF AND(ORD(D$),2 ^ (7 - J))<>0 THEN LET  B(K) = 1 ELSE LET  B(K) = 0
      LET  K = K + 1
   NEXT J
NEXT I
FOR I = 1 TO 8
   LET  E = E + B(I) * 2 ^ (8 - I)
NEXT I
LET  E=E-127
FOR I = 9 TO 31
   LET  S = S + B(I) * 2 ^ (8 - I)
NEXT I
LET  X=2^E*(S+1)
IF B(0)=1 THEN LET  X=-X
LET  CVS=X
END FUNCTION

EXTERNAL  FUNCTION MKS$(X)
!'IEEE754 32bit float to str
OPTION CHARACTER BYTE
OPTION BASE 0
DIM B(32)
IF X < 0 THEN LET  B(0)=1
IF X<>0 THEN
   IF ABS(X) < 1 THEN
      DO WHILE 2^(N+1) > ABS(X)
         LET  N=N-1
      LOOP
      LET  N=N+1
   ELSE
      DO WHILE 2^(N+1) < ABS(X)
         LET  N=N+1
      LOOP
   END IF
   LET  NN=N
   LET  N=N+127
   FOR I=1 TO 8
      IF AND(N,2^(8-I))<>0 THEN LET  B(I)=1
   NEXT I
   LET  T=(ABS(X)-2^NN)/2^NN
   FOR I=9 TO 31
      LET  T=T*2
      IF T >= 1 THEN
         LET  B(I)=1
         LET  T=T-INT(T)
      END IF
   NEXT I
END IF
LET  AA$=CHR$(B(0)*128+B(1)*64+B(2)*32+B(3)*16+B(4)*8+B(5)*4+B(6)*2+B(7))
LET  BB$=CHR$(B(8)*128+B(9)*64+B(10)*32+B(11)*16+B(12)*8+B(13)*4+B(14)*2+B(15))
LET  CC$=CHR$(B(16)*128+B(17)*64+B(18)*32+B(19)*16+B(20)*8+B(21)*4+B(22)*2+B(23))
LET  DD$=CHR$(B(24)*128+B(25)*64+B(26)*32+B(27)*16+B(28)*8+B(29)*4+B(30)*2+B(31))
LET  MKS$=DD$ & CC$ & BB$ & AA$
END FUNCTION

EXTERNAL  FUNCTION FLOAT2STR$(X,L,M) !'可変精度浮動小数変換
!'符号(1 bit) 指数部(L bit) 仮数部(M bit)
OPTION CHARACTER BYTE
OPTION BASE 0
IF MOD(L+M+1,8)<>0 THEN EXIT FUNCTION
DIM B(1+L+M)
IF X < 0 THEN LET  B(0)=1
IF X<>0 THEN
   IF ABS(X) < 1 THEN
      DO WHILE 2^(N+1) > ABS(X)
         LET  N=N-1
      LOOP
      LET  N=N+1
   ELSE
      DO WHILE 2^(N+1) < ABS(X)
         LET  N=N+1
      LOOP
   END IF
   FOR I=1 TO L
      IF AND(N+2^(L-1)-1,2^(L-I))<>0 THEN LET  B(I)=1
   NEXT I
   LET  T=(ABS(X)-2^N)/2^N
   FOR I=1+L TO 1+L+M
      LET  T=T*2
      IF T >= 1 THEN
         LET  B(I)=1
         LET  T=T-INT(T)
      END IF
   NEXT I
END IF
FOR J=0 TO (1+L+M)/8-1
   LET  AA$=CHR$(B(8*J)*128+B(8*J+1)*64+B(8*J+2)*32+B(8*J+3)*16+B(8*J+4)*8+B(8*J+5)*4+B(8*J+6)*2+B(8*J+7)) & AA$
NEXT J
LET  FLOAT2STR$=AA$
END FUNCTION

EXTERNAL  FUNCTION STR2FLOAT(A$,N,M)
!'符号(1 bit) 指数部(N bit) 仮数部(M bit)
OPTION CHARACTER BYTE
OPTION BASE 0
IF MOD(N+M+1,8)<>0 THEN EXIT FUNCTION
DIM B(1+N+M)
LET  K=0
FOR I=INT((1+N+M)/8) TO 1 STEP -1
   LET  D$=MID$(A$, I, 1)
   FOR J=0 TO 7
      IF AND(ORD(D$),2^(7-J))<>0 THEN LET  B(K)=1
      LET  K=K+1
   NEXT J
NEXT I
FOR I=1 TO N
   LET  E=E+B(I)*2^(N-I)
NEXT I
LET  E=E-(2^(N-1)-1)
FOR I=1+N TO 1+N+M
   LET  S=S+B(I)*2^(N-I)
NEXT I
LET  X=2^E*(1+S)
IF B(0)=1 THEN LET X=-X
LET  STR2FLOAT=X
END FUNCTION
 

ペジエ曲線

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時33分59秒
返信・引用
  ペジエ曲線

!'TT=1-T
!'(TT+T)^(N-1)  N=点の数 (0 <= T <= 1)
CALL GINIT(640,400)
RANDOMIZE
INPUT PROMPT  "点の数 =": N !' N > 1
DIM X(N), Y(N)
FOR I = 1 TO N
   LET  X(I) = INT(RND * 640)
   LET  Y(I) = INT(RND * 400)
   CALL CIRCLEFULL (X(I),Y(I),6,I)
NEXT I
FOR T = 0 TO 1 STEP 1 / 256
   LET  XX = 0
   LET  YY = 0
   LET  TT=(1-T)
   SELECT CASE N
   CASE 2
      LET  XX = TT*X(1)+T*X(2)
      LET  YY = TT*Y(1)+T*Y(2)
   CASE 3
      LET  XX = TT^2*X(1)+2*TT*T*X(2)+T^2*X(3)
      LET  YY = TT^2*Y(1)+2*TT*T*Y(2)+T^2*Y(3)
      !'CASE 4
      !'    LET  XX = TT^3*X(1)+3*TT^2*T*X(2)+3*TT*T^2*X(3)+T^3*X(4)
      !'    LET  YY = TT^3*Y(1)+3*TT^2*T*Y(2)+3*TT*T^2*Y(3)+T^3*Y(4)
      !'CASE 5
      !'   LET  XX = TT^4*X(1)+4*TT^3*T*X(2)+6*TT^2*T^2*X(3)+4*TT*T^3*X(4)+T^4*X(5)
      !'   LET  YY = TT^4*Y(1)+4*TT^3*T*Y(2)+6*TT^2*T^2*Y(3)+4*TT*T^3*Y(4)+T^4*Y(5)
   CASE ELSE
      FOR I=1 TO N
         LET XX=XX+TT^(N-I)*T^(I-1)*X(I)*COMB(N-1,I-1)
         LET YY=YY+TT^(N-I)*T^(I-1)*Y(I)*COMB(N-1,I-1)
      NEXT I
   END SELECT
   IF T = 0 THEN
      LET  XA=XX
      LET  YA=YY
   END IF
   CALL LINE(XA,YA,XX,YY,7)
   LET  XA=XX
   LET  YA=YY
NEXT T
IF N=4 THEN
   SET COLOR 1
   PLOT BEZIER: X(1), Y(1) ; X(2), Y(2) ; X(3), Y(3); X(4), Y(4) !'ラインが一致する
END IF
END

EXTERNAL  SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW  0 , XSIZE-1 , YSIZE-1, 0
SET POINT STYLE  1
SET COLOR MIX(0) 0,0,0
SET COLOR MIX(1) 0,0,1
SET COLOR MIX(2) 1,0,0
SET COLOR MIX(3) 1,0,1
SET COLOR MIX(4) 0,1,0
SET COLOR MIX(5) 0,1,1
SET COLOR MIX(6) 1,1,0
SET COLOR MIX(7) 1,1,1
CLEAR
END SUB

EXTERNAL  SUB LINE(XS,YS,XE,YE,C)
SET COLOR C
PLOT LINES: XS,YS;XE,YE
END SUB

EXTERNAL  SUB CIRCLEFULL (X0, Y0, R, C)
LET  X = R
LET  D = X
LET  Y = 0
DO WHILE X >= Y
   CALL LINE (X0 - X, Y0 + Y,X0 + X, Y0 + Y, C)
   CALL LINE (X0 - X, Y0 - Y,X0 + X, Y0 - Y, C)
   CALL LINE (X0 - Y, Y0 + X,X0 + Y, Y0 + X, C)
   CALL LINE (X0 - Y, Y0 - X,X0 + Y, Y0 - X, C)
   LET  D = D - 2 * Y + 1
   LET  Y = Y + 1
   IF D < 0 THEN
      LET  D = D + 2 * X - 2
      LET  X = X - 1
   END IF
LOOP
END SUB
 

グラデーション

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時35分27秒
返信・引用
  N次多項式、補間式によるグラデーション画像の生成


RANDOMIZE
LET  XSIZE=640 !'画像サイズ
LET  YSIZE=400
CALL GINIT(XSIZE,YSIZE)
LET  TH=INT(RND*90)
LET  S=SIN(TH*PI/180)
LET  C=COS(TH*PI/180)
LET R1=INT(RND*256)
LET R2=INT(RND*256)
LET R3=INT(RND*256)
LET R4=INT(RND*256)
LET G1=INT(RND*256)
LET G2=INT(RND*256)
LET G3=INT(RND*256)
LET G4=INT(RND*256)
LET B1=INT(RND*256)
LET B2=INT(RND*256)
LET B3=INT(RND*256)
LET B4=INT(RND*256)
LET MODE=INT(RND*40)+1
SELECT CASE INT(RND*4)
CASE 0
   FOR YY=0 TO YSIZE-1
      FOR XX=0 TO XSIZE-1
         LET  T=(C*XX+S*(YSIZE-YY))/(XSIZE*C+YSIZE*S)
         LET RR=INTERPOLANT(MODE,R1,R2,T)
         LET GG=INTERPOLANT(MODE,G1,G2,T)
         LET BB=INTERPOLANT(MODE,B1,B2,T)
         CALL PSET(XX,YY,RR,GG,BB)
      NEXT XX
   NEXT YY
CASE 1
   LET  N=INT(RND*7)+3
   DIM X(N,N),Y(N),R(N),G(N),B(N)
   FOR I=1 TO N
      FOR J=1 TO N
         LET  T=(I-1)/(N-1)
         LET  X(I,J)=T^(N-J)
      NEXT J
   NEXT I
   MAT X=INV(X)
   FOR I=1 TO N
      LET  Y(I)=INT(RND*256)
   NEXT I
   MAT R=X*Y !'redの係数
   FOR I=1 TO N
      LET  Y(I)=INT(RND*256)
   NEXT I
   MAT G=X*Y !'greenの係数
   FOR I=1 TO N
      LET  Y(I)=INT(RND*256)
   NEXT I
   MAT B=X*Y !'blueの係数
   FOR YY=0 TO YSIZE-1
      FOR XX=0 TO XSIZE-1
         LET  T=(C*XX+S*(YSIZE-YY))/(XSIZE*C+YSIZE*S)
         LET RR=0
         LET GG=0
         LET BB=0
         FOR I=1 TO N  !'多項式の計算
            LET  RR=RR*T+R(I)
            LET  GG=GG*T+G(I)
            LET  BB=BB*T+B(I)
         NEXT I
         CALL PSET(XX,YY,RR,GG,BB)
      NEXT  XX
   NEXT  YY
CASE 2 !'四角形
   FOR YY=0 TO YSIZE-1
      FOR XX=0 TO XSIZE-1
         LET  RR=RECTCOL(0,0,XSIZE-1,YSIZE-1,R1,R2,R3,R4,XX,YY,MODE)
         LET  GG=RECTCOL(0,0,XSIZE-1,YSIZE-1,G1,G2,G3,G4,XX,YY,MODE)
         LET  BB=RECTCOL(0,0,XSIZE-1,YSIZE-1,B1,B2,B3,B4,XX,YY,MODE)
         CALL PSET(XX,YY,RR,GG,BB)
      NEXT  XX
   NEXT  YY
CASE 3 !'三角形
   LET R5=INT(RND*256)
   LET G5=INT(RND*256)
   LET B5=INT(RND*256)
   LET X1=0
   LET Y1=0
   LET X2=XSIZE-1
   LET Y2=0
   LET X3=X2
   LET Y3=YSIZE-1
   LET X4=0
   LET Y4=YSIZE-1
   LET X5=INT(XSIZE/2)
   LET Y5=INT(YSIZE/2)
   FOR YY=0 TO YSIZE-1
      FOR XX=0 TO XSIZE-1
         IF AREA3(X5,Y5,X1,Y1,X2,Y2,XX,YY)<>0 THEN
            LET  RR=TRIANGLECOL(X5,Y5,X1,Y1,X2,Y2,R5,R1,R2,XX,YY)
            LET  GG=TRIANGLECOL(X5,Y5,X1,Y1,X2,Y2,G5,G1,G2,XX,YY)
            LET  BB=TRIANGLECOL(X5,Y5,X1,Y1,X2,Y2,B5,B1,B2,XX,YY)
         ELSEIF AREA3(X5,Y5,X2,Y2,X3,Y3,XX,YY)<>0 THEN
            LET  RR=TRIANGLECOL(X5,Y5,X2,Y2,X3,Y3,R5,R2,R3,XX,YY)
            LET  GG=TRIANGLECOL(X5,Y5,X2,Y2,X3,Y3,G5,G2,G3,XX,YY)
            LET  BB=TRIANGLECOL(X5,Y5,X2,Y2,X3,Y3,B5,B2,B3,XX,YY)
         ELSEIF AREA3(X5,Y5,X3,Y3,X4,Y4,XX,YY)<>0 THEN
            LET  RR=TRIANGLECOL(X5,Y5,X3,Y3,X4,Y4,R5,R3,R4,XX,YY)
            LET  GG=TRIANGLECOL(X5,Y5,X3,Y3,X4,Y4,G5,G3,G4,XX,YY)
            LET  BB=TRIANGLECOL(X5,Y5,X3,Y3,X4,Y4,B5,B3,B4,XX,YY)
         ELSEIF AREA3(X5,Y5,X4,Y4,X1,Y1,XX,YY)<>0 THEN
            LET  RR=TRIANGLECOL(X5,Y5,X4,Y4,X1,Y1,R5,R4,R1,XX,YY)
            LET  GG=TRIANGLECOL(X5,Y5,X4,Y4,X1,Y1,G5,G4,G1,XX,YY)
            LET  BB=TRIANGLECOL(X5,Y5,X4,Y4,X1,Y1,B5,B4,B1,XX,YY)
         END IF
         CALL PSET(XX,YY,RR,GG,BB)
      NEXT  XX
   NEXT  YY
END SELECT
END

EXTERNAL SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET COLOR MODE "NATIVE"
CLEAR
SET POINT STYLE 1
SET WINDOW 0,XSIZE-1,YSIZE-1,0
END SUB

EXTERNAL SUB PSET(X,Y,R,G,B)
LET  RR=MIN(255,MAX(0,INT(R)))
LET  GG=MIN(255,MAX(0,INT(G)))
LET  BB=MIN(255,MAX(0,INT(B)))
SET COLOR COLORINDEX(RR/255,GG/255,BB/255)
PLOT POINTS: X , Y
END SUB

EXTERNAL  FUNCTION RECTCOL(X1,Y1,X2,Y2,C1,C2,C3,C4,X,Y,MODE)
LET  P=(X-X1)/(X2-X1)
LET  Q=(Y-Y1)/(Y2-Y1)
LET S1=INTERPOLANT(MODE,C1,C2,P)
LET S2=INTERPOLANT(MODE,C3,C4,Q)
LET RECTCOL=INTERPOLANT(MODE,S1,S2,Q)
END FUNCTION

EXTERNAL  FUNCTION INTERPOLANT(MODE,A,B,T) !'補間式
LET T=MIN(1,MAX(0,T))
SELECT CASE MODE
CASE 1
   LET  V=(1-T)*A+B*T
CASE 2
   LET  V=(1-T)^2*A+B*T^2
CASE 3
   LET  V=(1-T)^3*A+B*T^3
CASE 4
   LET  V=(1-T)^4*A+B*T^4
CASE 5
   LET  V=(1-T)^5*A+B*T^5
CASE 6
   LET  V=(1-T^2)*A+B*T^2
CASE 7
   LET  V=(1-T^3)*A+B*T^3
CASE 8
   IF T=1 THEN LET  V=B ELSE  LET  V=SQR(1-T^2)*A+B*T^2
CASE 9
   IF T=1 THEN LET  V=B ELSE  LET  V=SQR(1-T^3)*A+B*T^3
CASE 10
   IF T=1 THEN LET  V=B ELSE  LET  V=SQR(1-T^2)^3*A+B*T
CASE 11
   LET  N=1/2
   LET  M=1/3
   IF T=1 THEN LET  V=B  ELSE LET  V=(1-T^M)^N*A+B*T^M
CASE 12
   LET  V=A*COS(PI/2*T)+B*SIN(PI/2*T)
CASE 13
   LET  V=A*COS(PI/2*T)^2+B*SIN(PI/2*T)^3
CASE 14
   LET  V=A*COS(PI/2*T^2)+B*SIN(PI/2*T^2)
CASE 15
   LET  V=A*(B/A)^T
CASE 16
   LET  V=A*EXP(T*LOG(B/A))
CASE 17
   LET  V=A+(B-A)*TAN(PI/4*T)
CASE 18
   LET  V=A+(B-A)*SIN(PI/2*T)
CASE 19
   LET  V=A+(B-A)*LOG(T+1)/LOG(2)
CASE 20
   LET  V=A+(B-A)*LOG(2*T+1)/LOG(3)
CASE 21
   LET  V=A+(B-A)*LOG((EXP(1)-1)*T+1)
CASE 22
   LET  V=A+(B-A)*(2^T-1)
CASE 23
   LET  V=A+(B-A)*ATN(T)*4/PI
CASE 24
   IF T=0 THEN LET  V=A ELSE  LET  V=A+(B-A)*LOG(10*T)/LOG(10)
CASE 25
   LET  V=A+(B-A)*SQR(T)
CASE 26
   LET  V=A+(B-A)*T^(1/5)
CASE 27
   LET V=A+(B-A)*T^10
CASE 28
   LET  V=A+(B-A)*ATN(T)*4/PI
CASE 29
   LET  V=A+(B-A)*ASIN(T)*2/PI
CASE 30
   LET  V=A+(B-A)*SIN(PI/2*T)^COS(PI/2*T)
CASE 31
   LET V=A+T-1+ABS(B-A)^T
CASE 32
   LET V=A+(B-A)*(1-(1-T)^T)
CASE 33
   LET V=A+(B-A)*(1-(1-T)/(1+T^2))
CASE 34
   LET V=A+(B-A)*(T*T*T+T*T+T)/(2*T*T+1)
CASE 35
   IF T=1 THEN LET V=B ELSE LET V=A+(B-A)*SIN(PI*(1-T))/((1-T)*PI)
CASE 36
   LET V=A+(B-A)*(T^3+3*T^2+2*T)/(T^2+2*T+3)
CASE 37
   LET V=A+(B-A)*T^3/(T^2+T-1)
CASE 38
   LET V=A+(B-A)*(4^T-1)/(2^T+1)
CASE 39
   LET V=A+(B-A)*(T+T^2+T^3+T^4+T^5+T^6+T^7)/7
CASE 40
   LET V=A+(B-A)*(5^T-1)/4
END SELECT
LET INTERPOLANT=V
END FUNCTION

EXTERNAL  FUNCTION AREA3(X1, Y1, X2, Y2, X3, Y3, PX, PY)
LET  T = TRIANGLE(X1, Y1, X2, Y2, X3, Y3)
LET  A = TRIANGLE(X1, Y1, X2, Y2, PX, PY)
LET  B = TRIANGLE(X2, Y2, X3, Y3, PX, PY)
LET  C = TRIANGLE(X1, Y1, X3, Y3, PX, PY)
IF ABS(A + B + C - T) < 1 THEN LET  AREA3 = -1 ELSE LET  AREA3 = 0
END FUNCTION

EXTERNAL  FUNCTION TRIANGLE(X1, Y1, X2, Y2, X3, Y3) !'三角形の面積
LET  TRIANGLE = ABS(X1 * Y2 + X2 * Y3 + X3 * Y1 - X2 * Y1 - X3 * Y2 - Y3 * X1) / 2
END FUNCTION
 

Re: グラデーション

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時36分51秒
返信・引用
  > No.356[元記事へ]

続き


EXTERNAL  FUNCTION TRIANGLECOL(OX,OY,AX,AY,BX,BY,C1,C2,C3,X,Y)
LET  A = AX - OX
LET  B = BX - OX
LET  C = AY - OY
LET  D = BY - OY
LET  PX = X - OX
LET  PY = Y - OY
LET  DET = A * D - B * C
IF DET = 0 THEN
   EXIT FUNCTION
END IF
LET  S = (D * PX - B * PY) / DET
IF S < 0 THEN
   EXIT FUNCTION
END IF
LET  T = (A * PY - C * PX) / DET
IF T < 0 THEN
   EXIT FUNCTION
END IF
IF S + T <= 1 THEN
   LET  TRIANGLECOL=(1-S)*(1-T)*C1+S*C2+T*C3
END IF
END FUNCTION
 

半角、全角文字変換

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時38分13秒
返信・引用  編集済
  半角、全角文字変換


PRINT CDBL$("ABCDABC123") !'半角を全角文字へ
PRINT CSNG$("あいうABCDE1231234") !'全角を半角文字へ
FOR I=1 TO 100
   PRINT CDBL$(STR$(I) & ":" & NUM2ROMAN$(I))
NEXT I
END

EXTERNAL  FUNCTION CDBL$(X$)
FOR I=1 TO LEN(X$)
   LET  F$=MID$(X$,I,1)
   RESTORE
   DO
      READ A$,AA$
   LOOP UNTIL A$="" OR F$=A$
   IF A$="" THEN LET  AA$=F$
   LET  L$=L$ & AA$
NEXT I
LET  CDBL$=L$
DATA A,A,B,B,C,C,D,D,E,E,F,F,G,G,H,H,I,I,J,J,K,K,L,L,M,M,N,N,O,O,P,P,Q,Q,R,R,S,S,T,T,U,U,V,V,W,W,X,X,Y,Y,Z,Z
DATA a,a,b,b,c,c,d,d,e,e,f,f,g,g,h,h,i,i,j,j,k,k,l,l,m,m,n,n,o,o,p,p,q,q,r,r,s,s,t,t,u,u,v,v,w,w,x,x,y,y,z,z
DATA 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9
DATA "!",!,"#",#,"$",$,"%",%,"&",&,"'",’,"(", (,")",),"=",=,"~",〜,"+",+,"-",−,"*",*,"/",/,".",.,"<",<,">",>,"?",?,";",;,":",:,"@",@,"\",¥
DATA " "," "
DATA "",""
END FUNCTION

EXTERNAL  FUNCTION CSNG$(X$)
FOR I=1 TO LEN(X$)
   LET  F$=MID$(X$,I,1)
   RESTORE
   DO
      READ A$,AA$
   LOOP UNTIL A$="" OR F$=AA$
   IF A$="" THEN LET  A$=F$
   LET  L$=L$ & A$
NEXT I
LET  CSNG$=L$
DATA A,A,B,B,C,C,D,D,E,E,F,F,G,G,H,H,I,I,J,J,K,K,L,L,M,M,N,N,O,O,P,P,Q,Q,R,R,S,S,T,T,U,U,V,V,W,W,X,X,Y,Y,Z,Z
DATA a,a,b,b,c,c,d,d,e,e,f,f,g,g,h,h,i,i,j,j,k,k,l,l,m,m,n,n,o,o,p,p,q,q,r,r,s,s,t,t,u,u,v,v,w,w,x,x,y,y,z,z
DATA 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9
DATA "!",!,"#",#,"$",$,"%",%,"&",&,"'",’,"(", (,")",),"=",=,"~",〜,"+",+,"-",−,"*",*,"/",/,".",.,"<",<,">",>,"?",?,";",;,":",:,"@",@,"\",¥
DATA " "," "
DATA "",""
END FUNCTION

EXTERNAL  FUNCTION NUM2ROMAN$(X) !'(アラビア)数字 to ローマ数字(1以上4000未満)
LET R$=""
IF X < 4000 AND X > 0 THEN
   OPTION BASE 0
   DIM T$(4,9)
   FOR I=1 TO 3
      FOR J=1 TO 9
         READ T$(I,J)
      NEXT J
   NEXT I
   DATA I,II,III,IV,V,VI,VII,VIII,IX
   DATA X,XX,XXX,XL,L,LX,LXX,LXXX,XC
   DATA C,CC,CCC,CD,D,DC,DCC,DCCC,CM
   FOR J=1 TO 3
      READ T$(4,J)
   NEXT J
   DATA M,MM,MMM,MMMM
   LET A$=LTRIM$(STR$(INT(X)))
   FOR I=LEN(A$) TO 1 STEP -1
      LET J=VAL(MID$(A$,LEN(A$)-I+1,1))
      LET R$=R$ & T$(I,J)
   NEXT I
END IF
LET NUM2ROMAN$=R$
END FUNCTION
 

数あて

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時39分39秒
返信・引用
  数あてゲーム

桁数(N)を決める
N桁の数字を入れていく
各桁は全て異なる数字
ヒット・・・数字と位(数字の位置)が一致している数
チップ・・・数字は合っているが位(数字の位置)が違っている数

RANDOMIZE
LET NUM$="0123456789"
!' LET NUM$="0123456789abcdef"
DO
   INPUT PROMPT  "桁数=": N !' 4〜5桁程度
LOOP UNTIL LEN(NUM$) >= N
LET T$=NUM$
FOR I = 1 TO N
   LET  R = INT(RND * LEN(T$))+1 !'乱数で1文字ずつ決める
   LET ANS$=ANS$ & MID$(T$,R,1)
   LET T$=LEFT$(T$,R-1) & RIGHT$(T$,LEN(T$)-R) !'選ばれた数字は候補から消す
NEXT I
PRINT N;"桁の数字を入力して下さい。 "
PRINT "GIVE UP は '*' です。"
LET COUNT=1
DO
   DO
      LET FL=0
      PRINT COUNT; "回目 ";
      INPUT PROMPT  "NUMBER = ": S$
      !' LET S$=LCASE$(S$)
      IF ANS$ = S$ THEN
         PRINT "大当たり !!"
         STOP
      ELSEIF S$ = "*" THEN
         PRINT "正解は"; ANS$; "でした。"
         STOP
      ELSEIF S$ = "/" THEN
         IF LEN(SS$)=N AND H > 0 THEN
            PRINT "ヒント  ";
            FOR I=1 TO N
               IF MID$(SS$,I,1)=MID$(ANS$,I,1) THEN PRINT MID$(ANS$,I,1); ELSE PRINT "?";
            NEXT I
            PRINT
            LET SS$=""
            LET COUNT = COUNT + 1
         END IF
         LET FL=1
      ELSEIF LEN(S$)<>N THEN
         PRINT N;"桁の数字ではありません"
         LET FL=1
      ELSE
         FOR I=1 TO N
            IF POS(NUM$,MID$(S$,I,1))=0 THEN
               PRINT "無効な文字があります"
               LET FL=1
               EXIT FOR
            END IF
         NEXT I
      END IF
   LOOP UNTIL FL=0
   LET  H = 0
   LET  C = 0
   FOR I = 1 TO N
         IF MID$(S$,I,1) = MID$(ANS$,I,1) THEN LET  H = H + 1 !'数字と位(位置)が一致
      FOR J = 1 TO N
         IF I <> J AND MID$(S$,I,1) = MID$(ANS$,J,1) THEN LET  C = C + 1 !'数字は一致するが位(位置)が違う
      NEXT J
   NEXT I
   PRINT "ヒット";H; " チップ"; C
   LET  COUNT = COUNT + 1
   LET SS$=S$
LOOP
END
 

カラーパズル

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時40分56秒
返信・引用
  パズルゲーム
3×3マスで構成され、配置はテンキーの数字キー(1〜9)と一致する。

数字の"1"で 4,1,2
数字の"2"で 1,2,3,5
数字の"3"で 2,3,6
数字の"4"で 1,4,5,7
数字の"5"で 2,4,5,6,8
数字の"6"で 3,5,6,9,
数字の"7"で 4,7,8
数字の"8"で 5,7,8,9
数字の"9"で 6,8,9 の配置が変化する

色は、白、黄、水、緑、紫、赤、青、黒、そしてまた白の順に変化していく
画面の色全てを消したら(全て黒)クリア


OPTION BASE 0
RANDOMIZE
CALL GINIT(300,300)
SET WINDOW  0 , 3 , 3, 0
DIM X(9),Y(9),M(9),K(9,5)
FOR I=1 TO 9
   READ X(I),Y(I)
NEXT I
DATA -1,1
DATA 0,1
DATA 1,1
DATA -1,0
DATA 0,0
DATA 1,0
DATA -1,-1
DATA 0,-1
DATA 1,-1
FOR I=1 TO 9
   FOR J=1 TO 5
      READ K(I,J)
   NEXT J
NEXT I
DATA 1,2,4,0,0
DATA 1,2,3,5,0
DATA 2,3,6,0,0
DATA 1,4,7,5,0
DATA 2,4,5,6,8
DATA 3,5,6,9,0
DATA 4,7,8,0,0
DATA 5,7,8,9,0
DATA 6,8,9,0,0
!' LET KAISU=INT(RND*18)+3
INPUT  PROMPT "回数=":KAISU
DIM ANS(KAISU),UNDO(KAISU)
FOR I=1 TO KAISU
   LET N=INT(RND*9)+1
   LET ANS(I)=N
   CALL MASU(N,1)
NEXT I
CALL DISPLAY
LET L=KAISU
DO
   PRINT "残り回数=";L
   INPUT PROMPT "Number=":T$
   IF T$="*" THEN
      EXIT DO
   ELSEIF T$="/" THEN
      IF KK > 0 THEN
         CALL MASU(UNDO(KK),1)
         LET KK=KK-1
         LET L=L+1
      END IF
   ELSEIF POS("123456789",T$) > 0 THEN
      LET TE=VAL(T$)
      LET KK=KK+1
      LET UNDO(KK)=TE
      CALL MASU(TE,-1)
      LET L=L-1
   END IF
   CALL DISPLAY
LOOP UNTIL L=0
FOR I=1 TO 9
   IF M(I)=0 THEN LET CHK=CHK+1
NEXT I
   SET COLOR 7
   CLEAR
IF CHK=9 THEN
   SET TEXT HEIGHT 0.32
   PLOT TEXT ,AT 0,1.5: "Congratulations"
ELSE
   SET TEXT HEIGHT 3/5.6
   PLOT TEXT ,AT 0,1.5: "Game Over"
   WAIT DELAY 1.5
   MAT M=ZER
   FOR L=1 TO KAISU
      CALL MASU(ANS(L),1)
   NEXT   L
   CALL DISPLAY
   WAIT DELAY 2
   FOR L=KAISU TO 1 STEP -1
      LET N=ANS(L)
      PRINT "No.";KAISU-L+1;"Number=";N
      CALL MASU(N,-1)
      CALL DISPLAY
      WAIT DELAY 1
   NEXT  L
END IF

SUB MASU(TE,C)
   FOR J=1 TO 5
      LET V=M(K(TE,J))+C
      IF V < 0 THEN LET V=7
      IF V > 7 THEN LET V=0
      LET M(K(TE,J))=V
   NEXT J
END SUB

SUB DISPLAY
   FOR J=1 TO 9
      CALL BOXFULL(X(J)+1,Y(J)+1,X(J)+2,Y(J)+2,M(J))
   NEXT J
   FOR I=1 TO 2
      FOR J=1 TO 2
         CALL LINE(I,0,I,3,7)
         CALL LINE(0,J,3,J,7)
      NEXT J
   NEXT I
END SUB
END

EXTERNAL  SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET POINT STYLE  1
SET COLOR MODE "REGULAR"
SET COLOR MIX(0) 0,0,0
SET COLOR MIX(1) 0,0,1
SET COLOR MIX(2) 1,0,0
SET COLOR MIX(3) 1,0,1
SET COLOR MIX(4) 0,1,0
SET COLOR MIX(5) 0,1,1
SET COLOR MIX(6) 1,1,0
SET COLOR MIX(7) 1,1,1
CLEAR
END SUB

EXTERNAL SUB BOXFULL(X1,Y1,X2,Y2,C)
SET COLOR C
PLOT AREA: X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB

EXTERNAL  SUB LINE(XS,YS,XE,YE,C)
SET COLOR C
PLOT LINES
PLOT LINES: XS,YS;XE,YE
END SUB
 

Re: カラーパズル

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時42分21秒
返信・引用
  > No.360[元記事へ]

マウス版 マスを左クリックする

OPTION BASE 0
RANDOMIZE
!' INPUT  PROMPT "SIZE 横,縦=":XSIZE,YSIZE
LET XSIZE=INT(RND*7)+3
LET YSIZE=INT(RND*7)+3
CALL GINIT(80*XSIZE,80*YSIZE)
SET WINDOW  0 , XSIZE , YSIZE, 0
SET TEXT JUSTIFY "LEFT" , "HALF"
FOR I=1 TO XSIZE-1
   FOR J=1 TO YSIZE-1
      CALL LINE(I,0,I,YSIZE,7)
      CALL LINE(0,J,XSIZE,J,7)
   NEXT J
NEXT I
LET KAISU=INT(RND*10)+3
!' INPUT  PROMPT "回数=":KAISU
DIM M(XSIZE,YSIZE),XX(KAISU),YY(KAISU)
DIM UNDOX(KAISU),UNDOY(KAISU)
FOR K=1 TO KAISU
   LET X=INT(RND*XSIZE)
   LET Y=INT(RND*YSIZE)
   LET XX(K)=X
   LET YY(K)=Y
   CALL MASU(X,Y,1)
NEXT  K
CALL DISPLAY
LET L=KAISU
DO
   LET FL=0
   PRINT "残り回数=";L
   DO
      MOUSE POLL X,Y,LEFT,RIGHT
   LOOP WHILE LEFT=1 OR RIGHT=1
   DO
      MOUSE POLL X,Y,LEFT,RIGHT
      IF GETKEYSTATE(27)<0 THEN LET FL=1
   LOOP WHILE LEFT=0 AND RIGHT=0 AND FL=0
   IF FL=1 THEN EXIT DO
   IF RIGHT=1 THEN
      IF KK > 0 THEN
         LET X=UNDOX(KK)
         LET Y=UNDOY(KK)
         LET KK=KK-1
         CALL MASU(X,Y,1)
         CALL DISPLAY
         LET L=L+1
      END IF
   ELSEIF LEFT=1 THEN
      LET X=INT(X)
      LET Y=INT(Y)
      PRINT "X,Y=(";X;",";Y;")"
      LET KK=KK+1
      LET UNDOX(KK)=X
      LET UNDOY(KK)=Y
      CALL MASU(X,Y,-1)
      LET L=L-1
      CALL DISPLAY
   END IF
LOOP UNTIL L=0
FOR I=0 TO XSIZE-1
   FOR J=0 TO YSIZE-1
      IF M(I,J)=0 THEN LET CHK=CHK+1
   NEXT  J
NEXT I
CLEAR
SET COLOR 7
IF CHK=XSIZE*YSIZE THEN !' ゲームクリア
   SET TEXT HEIGHT XSIZE/9.375
   PLOT TEXT ,AT 0,YSIZE/2: "Congratulations"
ELSE
   SET TEXT HEIGHT XSIZE/5.6
   PLOT TEXT ,AT 0,YSIZE/2: "Game Over"
   WAIT DELAY 1.5
   MAT M=ZER
   FOR K=1 TO KAISU
      CALL MASU(XX(K),YY(K),1)
   NEXT K
   CALL DISPLAY
   WAIT DELAY 2
   FOR K=KAISU TO 1 STEP -1 !'解答の表示
      CALL MASU(XX(K),YY(K),-1)
      PRINT "No.";KAISU-K+1;" X,Y=(";XX(K);",";YY(K);")"
      CALL DISPLAY
      WAIT DELAY 1
   NEXT K
END IF

SUB MASU(X,Y,C)
   FOR I=-1 TO 1
      FOR J=-1 TO 1
         IF X+I >= 0 AND Y+J >= 0 AND X+I < XSIZE AND Y+J < YSIZE AND I*J=0 THEN
            LET V=M(X+I,Y+J)+C
            IF V < 0 THEN LET V=7
            IF V > 7 THEN LET V=0
            LET M(X+I,Y+J)=V
         END IF
      NEXT J
   NEXT  I
END SUB

SUB DISPLAY !'画面表示
   FOR I=0 TO XSIZE-1
      FOR J=0 TO YSIZE-1
         CALL BOXFULL(I,J,I+1,J+1,M(I,J))
      NEXT  J
   NEXT I
   FOR I=1 TO XSIZE-1
      FOR J=1 TO YSIZE-1
         CALL LINE(I,0,I,YSIZE,7)
         CALL LINE(0,J,XSIZE,J,7)
      NEXT J
   NEXT I
END SUB
END

EXTERNAL  SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET POINT STYLE  1
SET COLOR MODE "REGULAR"
SET COLOR MIX(0) 0,0,0
SET COLOR MIX(1) 0,0,1
SET COLOR MIX(2) 1,0,0
SET COLOR MIX(3) 1,0,1
SET COLOR MIX(4) 0,1,0
SET COLOR MIX(5) 0,1,1
SET COLOR MIX(6) 1,1,0
SET COLOR MIX(7) 1,1,1
CLEAR
END SUB

EXTERNAL SUB BOXFULL(X1,Y1,X2,Y2,C)
SET COLOR C
PLOT AREA: X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB

EXTERNAL  SUB LINE(XS,YS,XE,YE,C)
SET COLOR C
PLOT LINES
PLOT LINES: XS,YS;XE,YE
END SUB
 

数値合わせ

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時44分24秒
返信・引用
  目標値を越えず、数値の合計値が最大(目標値との差が最小)
となる数値の組み合わせを求める

組み合わせを利用して探索する

N個の中から1個選ぶ組み合わせ
N個の中から2個選ぶ組み合わせ
N個の中から3個選ぶ組み合わせ
            :
N個の中からN個選ぶ組み合わせ

総探索数は COMB(N,1)+COMB(N,2)+...+COMB(N,N)=2^N-1

DECLARE EXTERNAL FUNCTION COMB
PUBLIC NUMERIC MAXSIZE,MSIZE,B(20),EPS
PUBLIC STRING T$(20),TT$(20)
DIM A(20),C(20),TI$(20),TEMP(20) !'個数は10〜15程度を想定
LET N=1
LET EPS=0
LET SUM=0
DO
   INPUT  PROMPT "数値(" & STR$(N) & ") ":A(N) !'(ファイルサイズ、演奏時間等)
   IF A(N)=0 THEN !' 0で入力終了
      LET N=N-1
      EXIT DO
   END IF
   LET SUM=SUM+A(N)
   !' INPUT  PROMPT "タイトル(" & STR$(N) & ") ":T$(N) !'(ファイル名、曲名等)
   LET N=N+1
LOOP
INPUT  PROMPT "目標値=":MAXSIZE !'(メディア容量、空き容量等)
IF MAXSIZE >= SUM THEN
   CALL DISPLAY(N,A,T$)
   STOP
END IF
!' INPUT  PROMPT "許容範囲=":EPS !'目標値 - 合計値 <= 許容範囲 となる組み合わせの表示
LET MMIN=MAXSIZE
LET K=0
DO
   LET K=K+1
   FOR I=1 TO N
      IF A(I) >= MAXSIZE/K THEN EXIT DO
   NEXT I
LOOP UNTIL K=N
FOR R=K TO N-1
   LET MSIZE=MAXSIZE
   MAT TEMP=ZER
   LET RR=R
   CALL COMB(A,N,RR,TEMP,1)
   IF MSIZE < MMIN THEN
      LET MMIN=MSIZE
      MAT C=B
      MAT TI$=TT$
   END IF
NEXT R
IF MMIN > 0 THEN CALL DISPLAY(N,C,TI$)
END

EXTERNAL SUB COMB(X(),N,R,A(),K)
IF R=0 THEN
   LET S=0
   FOR I=1 TO N
      IF A(I)=1 THEN
         LET S=S+X(I)
      END IF
      IF S > MAXSIZE THEN EXIT SUB
   NEXT I
   IF MAXSIZE >= S AND MAXSIZE-S <= MSIZE THEN
      LET MSIZE=MAXSIZE-S
      MAT B=ZER
      MAT TT$=NUL$
      LET M=0
      FOR J=1 TO N
         IF A(J)=1 THEN
            LET M=M+1
            LET B(M)=X(J)
            LET TT$(M)=T$(J)
         END IF
      NEXT  J
      IF MSIZE <= EPS THEN
         CALL DISPLAY(N,B,TT$)
      END IF
   END IF
ELSE
   FOR I=K TO N-R+1
      LET A(I)=1
      CALL COMB(X,N,R-1,A,I+1)
      LET A(I)=0
   NEXT I
END IF
END SUB

EXTERNAL  SUB DISPLAY(N,A(),K$())
LET S=0
FOR I=1 TO N
   IF A(I)<>0 THEN
      PRINT "No.";I;":";A(I);"  ";K$(I)
      LET S=S+A(I)
   END IF
NEXT I
PRINT "計";S;"残差";MAXSIZE-S
END SUB

ex.1
目標値と合計値との差が最小となる組み合わせ

37  39  43  69  75  81  88  108  120  122  128
目標値 700

ex.2
必ずしも目標値と合計値は一致しない

20  23  26  44  54  58  75  78  90  95  110  132
目標値 700
 

多項式代入

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時46分3秒
返信・引用
  多項式に多項式を代入 f(g(x))


OPTION BASE 0
PUBLIC NUMERIC MAXLEVEL
LET  MAXLEVEL=20
DIM X(MAXLEVEL),Y(MAXLEVEL)
CALL COSINE(X)
CALL SINE(Y)
PRINT "COS(SIN(X))"
CALL HORNER(X,Y)
CALL DISPLAY(X)
LET XX=.5
PRINT VALUE(X,XX);COS(SIN(XX)) !'検算
PRINT
CALL CLR(X)
LET X(0)=-1
LET X(2)=2 !'2*X^2-1  COS 2倍角式
CALL REPEATFUNC(X,4) !'COS 2^4倍角式
PRINT "F(F(F(F(X))))"
CALL DISPLAY(X)
LET XX=COS(RAD(30)/2^4)
PRINT VALUE(X,XX);F(F(F(F(XX)))) !'検算
PRINT COS(RAD(30))
PRINT
CALL COSINE(X)
CALL RCPFUNC(X) !'逆数
PRINT "1/COS(X)"
CALL DISPLAY(X)
LET XX=.5
PRINT VALUE(X,XX);1/COS(XX) !'検算
PRINT
CALL COSINE(X)
CALL SQRFUNC(X) !'平方根
PRINT "SQR(COS(X))"
CALL DISPLAY(X)
LET XX=.5
PRINT VALUE(X,XX);SQR(COS(XX)) !'検算
PRINT
CALL COSINE(X)
LET N=SQR(2)
CALL ROOTFUNC(X,N) !'非整数乗
PRINT "COS(X)^";N
CALL DISPLAY(X)
LET XX=.5
PRINT VALUE(X,XX);COS(XX)^N !'検算
PRINT
CALL COSINE(X)
CALL SINE(Y)
CALL POWERFUNC(X,Y) !'多項式乗
PRINT "COS(X)^SIN(X)"
CALL DISPLAY(X)
LET XX=.5
PRINT VALUE(X,XX);COS(XX)^SIN(XX) !'検算
END

EXTERNAL  FUNCTION F(X)
LET F=2*X*X-1 !'COS 2倍角
END FUNCTION

EXTERNAL  FUNCTION VALUE(A(),XX) !'多項式 F(X)の値
LET  N=DIMCHECK(A)
LET  Y=A(N)
FOR I=N-1 TO 0 STEP -1
   LET  Y=Y*XX+A(I)
NEXT I
LET  VALUE=Y
END FUNCTION

EXTERNAL  SUB HORNER(F(),G())
!' 多項式 F[X}に多項式 G[X]を代入 F[G[X]]
OPTION BASE 0
DIM Y(MAXLEVEL)
LET  N=DIMCHECK(F)
LET  Y(0)=F(N)
FOR I=N-1 TO 0 STEP -1
   CALL MUL(Y,G)
   LET  Y(0)=Y(0)+F(I)
NEXT I
CALL COPY(F,Y)
END SUB

EXTERNAL  SUB REPEATFUNC(X(),N)
!'F[F[F[...F[X]]]]...]
OPTION BASE 0
DIM C(MAXLEVEL),T(MAXLEVEL)
CALL COPY(C,X)
CALL COPY(T,X)
FOR I=2 TO N
   CALL HORNER(C,X)
   CALL COPY(X,C)
   CALL COPY(C,T)
NEXT I
END SUB

EXTERNAL  SUB RCPFUNC(X())
!'1/(1-F[X])=1+F[X]+F[X]^2+F[X]^3+...収束半径(ABS(F[X]) < 1)
!'1/F[X]=1/(1-(1-F[X])
OPTION BASE 0
DIM C(MAXLEVEL),Y(MAXLEVEL)
LET  Y(0)=1
FOR I=0 TO MAXLEVEL
   LET  C(I)=1 !'1+F[X]+F[X]^2+F[X]^3+...
NEXT I
CALL SUBST(Y,X) !'1-F[X]
CALL HORNER(C,Y)
CALL COPY(X,C)
END SUB

EXTERNAL  SUB SQRFUNC(X())
!' SQR(1-(1-F[X]))  収束半径(ABS(F[X]) < 1)
OPTION BASE 0
DIM C(MAXLEVEL),Y(MAXLEVEL)
LET  Y(0)=1
CALL SUBST(Y,X) !'1-F[X]
CALL COMB(C,1,-1,1,.5) !'(1-X)^.5
CALL HORNER(C,Y)
CALL COPY(X,C)
END SUB

EXTERNAL  SUB ROOTFUNC(X(),N)
!' (1-(1-F[X]))^N  収束半径(ABS(F[X]) < 1)
OPTION BASE 0
DIM C(MAXLEVEL),Y(MAXLEVEL)
LET  Y(0)=1
CALL SUBST(Y,X) !'1-F[X]
CALL COMB(C,1,-1,1,N) !'(1-X)^N
CALL HORNER(C,Y)
CALL COPY(X,C)
END SUB

EXTERNAL  SUB LOGFUNC(X())
!'LOG(F[X])
OPTION BASE 0
DIM C(MAXLEVEL)
CALL LN(C)
LET  X(0)=X(0)-1
CALL HORNER(C,X)
CALL COPY(X,C)
END SUB

EXTERNAL  SUB EXPFUNC(X())
!'EXP(F[X])
OPTION BASE 0
DIM C(MAXLEVEL)
CALL EXPON(C)
CALL HORNER(C,X)
CALL COPY(X,C)
END SUB

EXTERNAL  SUB POWERFUNC(F(),G())
!' F[X] ^ G[X] = EXP(G[X]*LOG(F[X]))
CALL LOGFUNC(F)
CALL MUL(F,G)
CALL EXPFUNC(F)
END SUB

EXTERNAL  SUB DISPLAY(A())
LET  N=DIMCHECK(A)
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

EXTERNAL  SUB COMB(X(),A,B,M,N) !'二項定理  収束半径(ABS(F[X]) < 1)
!' (A+B*X^M)^N = A^N+N*A^(N-1)*B*X^M+N*(N-1)/2!*A^(N-2)*B^2*X^(2*M)+...B^N*X^(M*N)+B^N
CALL CLR(X)
LET  NN=1
LET  X(0)=A^N
FOR I=1 TO INT(MAXLEVEL/M)
   LET  NN=NN*(N-I+1)/I
   LET  X(M*I)=NN*A^(N-I)*B^I
NEXT I
END SUB

EXTERNAL  SUB SINE(X())
!' SIN(X)
CALL CLR(X)
LET  X(1)=1
LET  T=1
FOR I=3 TO MAXLEVEL STEP 2
   LET T=-T/(I-1)/I
   LET  X(I)=T
NEXT I
END SUB

EXTERNAL  SUB COSINE(X())
!' COS(X)
CALL CLR(X)
LET  X(0)=1
LET  T=1
FOR I=2 TO MAXLEVEL STEP 2
   LET T=-T/(I-1)/I
   LET  X(I)=T
NEXT I
END SUB

EXTERNAL  SUB EXPON(X())
!' EXP(X)
LET  X(0)=1
LET  T=1
FOR I=1 TO MAXLEVEL
   LET  T=T/I
   LET  X(I)=T
NEXT I
END SUB

EXTERNAL  SUB LN(X())
!'LOG(1+X)
LET X(0)=0
FOR I=1 TO MAXLEVEL
   IF MOD(I,2)=1 THEN LET  X(I)=1/I ELSE LET  X(I)=-1/I
NEXT I
END SUB

EXTERNAL  SUB SUBST(Y(),X())
FOR I=0 TO MAXLEVEL
   LET  Y(I)=Y(I)-X(I)
NEXT I
END SUB
 

Re: 多項式代入

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時47分11秒
返信・引用
  > No.363[元記事へ]

続き


EXTERNAL  SUB COPY(X(),Y())
FOR I=0 TO MAXLEVEL
   LET  X(I)=Y(I)
NEXT I
END SUB

EXTERNAL  SUB MUL(Y(),X())
OPTION BASE 0
DIM C(MAXLEVEL)
FOR J=0 TO MAXLEVEL
   FOR I=0 TO MAXLEVEL-J
      LET  C(I+J)=C(I+J)+Y(I)*X(J)
   NEXT I
NEXT J
CALL COPY(Y,C)
END SUB

EXTERNAL  SUB CLR(X())
FOR I=0 TO MAXLEVEL
   LET  X(I)=0
NEXT I
END SUB

EXTERNAL  FUNCTION DIMCHECK(X())
FOR N=MAXLEVEL TO 0 STEP -1
   IF X(N)<>0 THEN EXIT FOR
NEXT N
LET  DIMCHECK=N
END FUNCTION
 

Re: 描画公表とプログラム

 投稿者:六甲の初心者  投稿日:2009年 5月10日(日)16時05分40秒
返信・引用
  > No.350[元記事へ]

SECONDさんへのお返事です。

SECONDさんがこのようにおっしゃっても
> これは、先生のご希望と期待で、強要の意図は、絶対にないと思います。

著作権として
「本BASICを利用して得られた研究結果は必ず公開してください。」
と明文化してあれば「強要の意図は、絶対にない」とは言えなく誰をも縛るものと断言できると思います

SECONDさんの強要なしのお話をいただき
当方としては2〜3年の書き換えを覚悟しかけていたので、少したじろいでいます。
出来ればもやもやのままで過ごしたくありませんので「先生」のご意思を確かめられたらと思うのですが
もしSECONDさんのおっしゃるとおりなのでしたら、上記の著作権の項を書き換えていただきたく思います

考えてみれば、寡聞にしてBASICは日本人が1人で作ったものではないですよね
たまたまこのBASICを使って技術開発などをしていて新規のアルゴリズムやノウハウを生み出すことも十分に考えられ、その場合も内容公開を1人の「先生」が要求できるのか、はなはだ疑問ですね
それとも、このBASICは「先生」の個人の権利が確立しているのでしょうか。それなら何も言うことはないのですが





> 六甲の初心者さんへのお返事です。
>
> >他の言語に変えなさいというこ・・・
>
> では、ないと思います。誤解されましたのであれば、御詫びします。
> これは、先生のご希望と期待で、強要の意図は、絶対にないと思います。
 

Re: 描画公表とプログラム

 投稿者:なかむら  投稿日:2009年 5月11日(月)00時56分47秒
返信・引用
  > No.365[元記事へ]

六甲の初心者さん、SECONDさんへのコメントです。

法律の専門家ではありませんが、個人的な意見を述べさせてください。

「本BASICを利用して得られた研究結果は必ず公開してください。」

とありますので、研究結果の公開は原則として要請されているものと
考えられます。
しかし、要請されているものは研究結果ですので、それがすなわち
プログラムのソースコードであるか否かは場合によるかと考えます。

たとえば、あるクラスの生徒に十進BASICと他の言語をつかって、
コンピュータの授業を行ったとき(たとえば三角形の面積をもとめ
させるとか)、どちらの言語を用いたほうがより理解が容易か?
という調査を行った場合、この結果は理解度の差であり、そのとき
用いた三角形の面積を求めるプログラムではないと思います。
(比較を正確に行うためにはソースコードの比較も必要かもしれま
せんが)

したがって、六甲の初心者さんの最初のご質問にもどって、
発表したい成果があるが、プログラムのソースすべては公開したくない、
どうしたらよいか?
というところに知恵を絞るということで良いのではないかと思います。
残念ながら現状ではどのような方法があるか私には見当がつきませんが。

研究の結果を公開したくない、というのであれば、十進BASICは使うべき
ではない、という気がしますが今回の場合は成果を発表したいがどうし
たらよいか?という話のように見受けられますが、いかがでしょう?
(単に屁理屈でしょうか?)
個人的には、たとえば計算機がわりに十進BASICをつかっている場合に
その計算結果や計算式をすべて研究結果として公開すべきかといわれ
れば、答えは No ではないかと思います。
研究結果の発表という形でこのコミュニティに何らかの貢献ができれば
という姿勢が重要なのではないかと思います。
もちろん、そういった使用は不可だということであれば話は別ですが。
 

Re: 描画公表とプログラム

 投稿者:六甲の初心者  投稿日:2009年 5月11日(月)09時11分38秒
返信・引用
  > No.366[元記事へ]

なかむらさんへのお返事です。

当方の趣旨をもう一度捕らえていただいてありがとうございます
殆どなかむらさんのおっしゃるとおりです

昔から気軽に使い(〜30年)計算やグラフ表示をたのしんできました
数年前からなんと無しに取り組んで(このときこのBASICをダウンロードしたと思われる)きたテーマが、最近結果が出るようになりこの関係者にはかなり役に立つのではないかと思い公開して評価してもらおうかと考えました
しかし、この件では大変な時間(3万時間以上)と労力が掛っている。確か他の言語では何か処理をしてソースプログラムがわからないようになったはず、BASICでも何か方法があるのかな

と思って、当方の最初の質問になったわけです。そしたら、すべて公開する規定のあることを知らされたわけです

当方の発想の数箇所の部分の権利が保護されればなんら問題はないのですが、少なくともそれまでは中身の公開を避ける方法があれば、ということです

なかむらさんもご存知ないということですが、やっぱりこの言語を使ってしまった宿命でしょうか

調べましたら、文教大学の白石和夫教授とのことですね。
白石教授殿、是非とも当方の悩みに教育者としてお答えください。
または権利の根拠をお示しいただければ即解決です。


> 六甲の初心者さん、SECONDさんへのコメントです。
>
> 法律の専門家ではありませんが、個人的な意見を述べさせてください。
>
> 「本BASICを利用して得られた研究結果は必ず公開してください。」
>
> とありますので、研究結果の公開は原則として要請されているものと
> 考えられます。
> しかし、要請されているものは研究結果ですので、それがすなわち
> プログラムのソースコードであるか否かは場合によるかと考えます。
>
> たとえば、あるクラスの生徒に十進BASICと他の言語をつかって、
> コンピュータの授業を行ったとき(たとえば三角形の面積をもとめ
> させるとか)、どちらの言語を用いたほうがより理解が容易か?
> という調査を行った場合、この結果は理解度の差であり、そのとき
> 用いた三角形の面積を求めるプログラムではないと思います。
> (比較を正確に行うためにはソースコードの比較も必要かもしれま
> せんが)
>
> したがって、六甲の初心者さんの最初のご質問にもどって、
> 発表したい成果があるが、プログラムのソースすべては公開したくない、
> どうしたらよいか?
> というところに知恵を絞るということで良いのではないかと思います。
> 残念ながら現状ではどのような方法があるか私には見当がつきませんが。
>
> 研究の結果を公開したくない、というのであれば、十進BASICは使うべき
> ではない、という気がしますが今回の場合は成果を発表したいがどうし
> たらよいか?という話のように見受けられますが、いかがでしょう?
> (単に屁理屈でしょうか?)
> 個人的には、たとえば計算機がわりに十進BASICをつかっている場合に
> その計算結果や計算式をすべて研究結果として公開すべきかといわれ
> れば、答えは No ではないかと思います。
> 研究結果の発表という形でこのコミュニティに何らかの貢献ができれば
> という姿勢が重要なのではないかと思います。
> もちろん、そういった使用は不可だということであれば話は別ですが。
 

Re: 描画公表とプログラム

 投稿者:白石 和夫  投稿日:2009年 5月11日(月)10時13分33秒
返信・引用
  > No.365[元記事へ]

研究結果の公開については,その方法や時期などについて何も言及していないので,
さほど実効性のある規定とは思っていませんが,
フリーソフトはコミュニティによって育てられるものであることなど,
フリーソフトとして公開していることの意味を理解した上でご利用いただきたいと思います。
 

Re: 描画公表とプログラム

 投稿者:六甲の初心者  投稿日:2009年 5月11日(月)11時06分19秒
返信・引用
  > No.368[元記事へ]

白石 和夫さんへのお返事です。

早速の先生からのご返信をいただきありがとうございます
しかし当方の希望したお答えとは離れています
ご本人があいまいに言うことによって済ませたとしても周りの方々は十分な配慮を重ねて最大限の希望がそこにあると解釈し流布することでしょう 大学では当然のなりゆきです

十分な地位、名声もすでに得られたことですから つまらん言いがかりを避けるために著作権のところの表現を少し変えて見られることをお勧めします

特定のコミュニティとは関係なくこつこつ成果が上がることもあります。手段の工夫からではなく本質的現象を捉えた場合などです

まさかそれを捕らえるための網ではないでしょうね

> 研究結果の公開については,その方法や時期などについて何も言及していないので,
> さほど実効性のある規定とは思っていませんが,
> フリーソフトはコミュニティによって育てられるものであることなど,
> フリーソフトとして公開していることの意味を理解した上でご利用いただきたいと思います。
 

Re: 描画公表とプログラム

 投稿者:白石 和夫  投稿日:2009年 5月11日(月)16時58分22秒
返信・引用
  > No.369[元記事へ]

GPL版は異なったライセンスの元で配布しています。
GPLの理念に同意されるようであれば,GPL版をお使いください。
Windows版実行ファイルの配布はありませんが,
開発はWindows上で行っているので,Windowsでも動作します。
http://www.geocities.jp/thinking_math_education/IntelMac.htm#SOURCE
 

Re: 描画公表とプログラム

 投稿者:六甲の初心者  投稿日:2009年 5月12日(火)05時00分57秒
返信・引用
  > No.370[元記事へ]

白石 和夫さんへのお返事です。

ご返事が遅れました

著作権の項の変更のご意思はなしと承知しました
実績ある先生の名声に傷をつける気は全くありませんのでこの場での議論は当方としてはこれまでとします

ただ、先生にとってマイナス要因となりうる当該の事項の変更は強くお勧めします(法的にも強くないと思います) このような声は大学の世界でははなかなか聞こえないと思いますが、当方のような状況になった人はいくらでもいるのではないですか
更に、そのような人が出ないように「条件付きフリーソフフト」であることを明確にうたうべきです うっかりダウンロードされるのを防いでください

もし、変更される場合は、この場においてお知らせいただくようお願いします



> GPL版は異なったライセンスの元で配布しています。
> GPLの理念に同意されるようであれば,GPL版をお使いください。
> Windows版実行ファイルの配布はありませんが,
> 開発はWindows上で行っているので,Windowsでも動作します。
> http://www.geocities.jp/thinking_math_education/IntelMac.htm#SOURCE
 

Re: 描画公表とプログラム

 投稿者:白石 和夫  投稿日:2009年 5月12日(火)09時11分39秒
返信・引用  編集済
  > No.371[元記事へ]

六甲の初心者さんへのお返事です。

フリーソフトである以上,作者の定めた使用条件が合わないと感じたら,
その時点で試用をあきらめていただくしかありません。
たとえば,バグ報告をしたくないという人は,バグを発見した時点で
以後,使用する権利を失います。

なお,フリーソフトには ”as is”であることを強調したものもありますが,
十進BASICはそれとは異なり,利用者とともに育てていくことを目指したフリーソフトです。
その理念に賛同される方に使っていただきたく思います。
 

諸兄殿

 投稿者:SECOND  投稿日:2009年 5月12日(火)13時15分51秒
返信・引用  編集済
  諸兄殿
衣食住足りなければ、あらゆる義務は、無いですね。しかし、そうでなかったなら、
勉学と教育は、人類が、地球環境へ返せる 唯一の支払いのビジネスではないだろうか。
この不払いが、天災につながらないかを、心配する。

その昔、坊主たちは、色即是空(しきそくぜくう)と唱えていました。
他の人も、自分と同じ様に、モノを見ていると、思うのは、間違いの意味です。
認識と価値観は、相対性で、人により、実に、様々違います。

1つの言語システムを、記述し、そのデバッグを続ける事は、一生を費やすほど大変な、
作業です。生甲斐が、重ならない限り、利害だけで出来る事では、ありません。
フリーソフトですから、ご自由になるでしょう。

私も、でしゃばりすぎたと、反省しております。
 

文字の変換

 投稿者:山中和義  投稿日:2009年 5月12日(火)13時39分43秒
返信・引用
              ひらがな
             ↑↓
 半角カタカナ → 全角カタカナ
        ←
 半角数字     全角数字
 半角英字     全角英字
 半角記号     全角記号

を行うサブルーチンをつくってみました。

DECLARE EXTERNAL FUNCTION StrConv.ASC$ ,StrConv.JIS$ !半角、全角
DECLARE EXTERNAL FUNCTION StrConv.ToHiragana$ ,StrConv.ToKatakana$ !ひらがな、カタカナ


LET t$="BASICプログラミングーぅ〜!"
PRINT ASC$(t$) !半角へ
PRINT JIS$(ASC$(t$)) !全角へ

PRINT ToKatakana$("abcXYZあいうカキク890 *?")
PRINT ToHiragana$("abcXYZあいうカキク890 *?")

END


MODULE StrConv !文字の変換

!「半角 → 全角」対応表 ※JISコード(JIS X 0201)順
DATA " "," " !32
DATA "!","!" !33
DATA """","”" !34
DATA "#","#" !35
DATA "$","$" !36
DATA "%","%" !37
DATA "&","&" !38
DATA "'","’" !39
DATA "(","(" !40
DATA ")",")" !41
DATA "*","*" !42
DATA "+","+" !43
DATA ",","," !44
DATA "-","−" !45
DATA ".","." !46
DATA "/","/" !47
DATA "0","0" !48
DATA "1","1" !49
DATA "2","2" !50
DATA "3","3" !51
DATA "4","4" !52
DATA "5","5" !53
DATA "6","6" !54
DATA "7","7" !55
DATA "8","8" !56
DATA "9","9" !57
DATA ":",":" !58
DATA ";",";" !59
DATA "<","<" !60
DATA "=","=" !61
DATA ">",">" !62
DATA "?","?" !63
DATA "@","@" !64
DATA "A","A" !65
DATA "B","B" !66
DATA "C","C" !67
DATA "D","D" !68
DATA "E","E" !69
DATA "F","F" !70
DATA "G","G" !71
DATA "H","H" !72
DATA "I","I" !73
DATA "J","J" !74
DATA "K","K" !75
DATA "L","L" !76
DATA "M","M" !77
DATA "N","N" !78
DATA "O","O" !79
DATA "P","P" !80
DATA "Q","Q" !81
DATA "R","R" !82
DATA "S","S" !83
DATA "T","T" !84
DATA "U","U" !85
DATA "V","V" !86
DATA "W","W" !87
DATA "X","X" !88
DATA "Y","Y" !89
DATA "Z","Z" !90
DATA "[","[" !91
DATA "\","¥" !92
DATA "]","]" !93
DATA "^","^" !94
DATA "_","_" !95
DATA "`","‘" !96
DATA "a","a" !97
DATA "b","b" !98
DATA "c","c" !99
DATA "d","d" !100
DATA "e","e" !101
DATA "f","f" !102
DATA "g","g" !103
DATA "h","h" !104
DATA "i","i" !105
DATA "j","j" !106
DATA "k","k" !107
DATA "l","l" !108
DATA "m","m" !109
DATA "n","n" !110
DATA "o","o" !111
DATA "p","p" !112
DATA "q","q" !113
DATA "r","r" !114
DATA "s","s" !115
DATA "t","t" !116
DATA "u","u" !117
DATA "v","v" !118
DATA "w","w" !119
DATA "x","x" !120
DATA "y","y" !121
DATA "z","z" !122
DATA "{","{" !123
DATA "|","|" !124
DATA "}","}" !125
DATA "~","〜" !126

DATA "。","。" !161
DATA "「","「" !162
DATA "」","」" !163
DATA "、","、" !164
DATA "・","・" !165
DATA "ヲ","ヲ" !166
DATA "ァ","ァ" !167
DATA "ィ","ィ" !168
DATA "ゥ","ゥ" !169
DATA "ェ","ェ" !170
DATA "ォ","ォ" !171
DATA "ャ","ャ" !172
DATA "ュ","ュ" !173
DATA "ョ","ョ" !174
DATA "ッ","ッ" !175
DATA "ー","ー" !176
DATA "ア","ア" !177
DATA "イ","イ" !178
DATA "ウ","ウ" !179
DATA "エ","エ" !180
DATA "オ","オ" !181
DATA "カ","カ" !182
DATA "キ","キ" !183
DATA "ク","ク" !184
DATA "ケ","ケ" !185
DATA "コ","コ" !186
DATA "サ","サ" !187
DATA "シ","シ" !188
DATA "ス","ス" !189
DATA "セ","セ" !190
DATA "ソ","ソ" !191
DATA "タ","タ" !192
DATA "チ","チ" !193
DATA "ツ","ツ" !194
DATA "テ","テ" !195
DATA "ト","ト" !196
DATA "ナ","ナ" !197
DATA "ニ","ニ" !198
DATA "ヌ","ヌ" !199
DATA "ネ","ネ" !200
DATA "ノ","ノ" !201
DATA "ハ","ハ" !202
DATA "ヒ","ヒ" !203
DATA "フ","フ" !204
DATA "ヘ","ヘ" !205
DATA "ホ","ホ" !206
DATA "マ","マ" !207
DATA "ミ","ミ" !208
DATA "ム","ム" !209
DATA "メ","メ" !210
DATA "モ","モ" !211
DATA "ヤ","ヤ" !212
DATA "ユ","ユ" !213
DATA "ヨ","ヨ" !214
DATA "ラ","ラ" !215
DATA "リ","リ" !216
DATA "ル","ル" !217
DATA "レ","レ" !218
DATA "ロ","ロ" !219
DATA "ワ","ワ" !220
DATA "ン","ン" !221
DATA "゙","゛" !222
DATA "゚","゜" !223


!「全角カタカナ → 半角カタカナ」の対応表
DATA "ァ","ァ", "ア","ア", "ィ","ィ", "イ","イ", "ゥ","ゥ", "ウ","ウ", "ェ","ェ", "エ","エ", "ォ","ォ", "オ","オ"
DATA "カ","カ", "ガ","ガ", "キ","キ", "ギ","ギ", "ク","ク", "グ","グ", "ケ","ケ", "ゲ","ゲ", "コ","コ", "ゴ","ゴ"
DATA "サ","サ", "ザ","ザ", "シ","シ", "ジ","ジ", "ス","ス", "ズ","ズ", "セ","セ", "ゼ","ゼ", "ソ","ソ", "ゾ","ゾ"
DATA "タ","タ", "ダ","ダ", "チ","チ", "ヂ","ヂ", "ッ","ッ", "ツ","ツ", "ヅ","ヅ", "テ","テ", "デ","デ", "ト","ト", "ド","ド"
DATA "ナ","ナ", "ニ","ニ", "ヌ","ヌ", "ネ","ネ", "ノ","ノ"
DATA "ハ","ハ", "バ","バ", "パ","パ", "ヒ","ヒ", "ビ","ビ", "ピ","ピ", "フ","フ", "ブ","ブ", "プ","プ", "ヘ","ヘ", "ベ","ベ", "ペ","ペ", "ホ","ホ", "ボ","ボ", "ポ","ポ"
DATA "マ","マ", "ミ","ミ", "ム","ム", "メ","メ", "モ","モ"
DATA "ャ","ャ", "ヤ","ヤ", "ュ","ュ", "ユ","ユ", "ョ","ョ", "ヨ","ヨ"
DATA "ラ","ラ", "リ","リ", "ル","ル", "レ","レ", "ロ","ロ"
DATA "ヮ","ワ", "ワ","ワ", "ヰ","イ", "ヱ","エ", "ヲ","ヲ", "ン","ン", "ヴ","ヴ", "ヵ","カ", "ヶ","ケ"


SHARE STRING JisTBL$(0 TO 255), KataTBL$(9505 TO 9590)
DO
   READ IF MISSING THEN EXIT DO : a$,aa$ !インデックス、変換値
   IF ORD(a$)<256 THEN
      LET JisTBL$(ORD(a$))=aa$ !ハッシュ表をつくる
   ELSE
      LET KataTBL$(ORD(a$))=aa$
   END IF
LOOP
!-------------------- ここまでが初期処理


つづく
 

Re: 文字の変換

 投稿者:山中和義  投稿日:2009年 5月12日(火)13時42分8秒
返信・引用
  > No.374[元記事へ]

つづき

!関数、サブルーチンの定義

PUBLIC FUNCTION ASC$
EXTERNAL FUNCTION ASC$(x$) !全角文字を半角文字に変換する
   LET xx$=""
   FOR i=1 TO LEN(x$) !対象の文字列について
      LET t=ORD(x$(i:i))

      SELECT CASE t
      CASE 9008 TO 9017 !数字0〜9
         LET w$=CHR$(t-ORD("0")+ORD("0"))

      CASE 9025 TO 9050 !英字A〜Z
         LET w$=CHR$(t-ORD("Z")+ORD("Z"))
      CASE 9057 TO 9082 !英字a〜z
         LET w$=CHR$(t-ORD("z")+ORD("z"))

      CASE 9505 TO 9590 !カタカナ
         LET w$=KataTBL$(t) !変換表を参照して置き換える

      CASE 8481 !記号
         LET w$=" "
      CASE 8490
         LET w$="!"
      CASE 8521
         LET w$=""""
      CASE 8564
         LET w$="#"
      CASE 8560
         LET w$="$"
      CASE 8563
         LET w$="%"
      CASE 8565
         LET w$="&"
      CASE 8519
         LET w$="'"
      CASE 8522
         LET w$="("
      CASE 8523
         LET w$=")"
      CASE 8566
         LET w$="*"
      CASE 8540
         LET w$="+"
      CASE 8484
         LET w$=","
      CASE 8541
         LET w$="-"
      CASE 8485
         LET w$="."
      CASE 8511
         LET w$="/"
      CASE 8487
         LET w$=":"
      CASE 8488
         LET w$=";"
      CASE 8547
         LET w$="<"
      CASE 8545
         LET w$="="
      CASE 8548
         LET w$=">"
      CASE 8489
         LET w$="?"
      CASE 8567
         LET w$="@"
      CASE 8526
         LET w$="["
      CASE 8559
         LET w$="\"
      CASE 8527
         LET w$="]"
      CASE 8496
         LET w$="^"
      CASE 8498
         LET w$="_"
      CASE 8518
         LET w$="`"
      CASE 8528
         LET w$="{"
      CASE 8515
         LET w$="|"
      CASE 8529
         LET w$="}"
      CASE 8513
         LET w$="~"

      CASE 8483 !記号 ※カタカナ
         LET w$="。"
      CASE 8534
         LET w$="「"
      CASE 8535
         LET w$="」"
      CASE 8482
         LET w$="、"
      CASE 8486
         LET w$="・"
      CASE 8508
         LET w$="ー"
      CASE 8491
         LET w$="゙"
      CASE 8492
         LET w$="゚"

      CASE ELSE
         LET w$=CHR$(t) !そのまま
      END SELECT

      LET xx$=xx$ & w$
   NEXT i
   LET ASC$=xx$
END FUNCTION

PUBLIC FUNCTION JIS$
EXTERNAL FUNCTION JIS$(x$) !半角文字を全角文字に変換する
   LET xx$=""
   LET i=1
   DO WHILE i<=LEN(x$) !対象文字を順に調べる
      LET t=ORD(x$(i:i))

      SELECT CASE t
      CASE 32 TO 126 !記号・英数字なら
         LET xx$=xx$ & JisTBL$(t) !変換表を参照して置き換える
      CASE 161 TO 223 !半角カタカナなら
         IF i<LEN(x$) THEN LET tt=ORD(x$(i+1:i+1)) ELSE LET tt=0
         IF tt=222 AND ( (t>=182 AND t<=196) OR (t>=202 AND t<=206) ) THEN !カ〜ト、ハ〜ホの濁点
            LET xx$=xx$ & CHR$(ORD(JisTBL$(t))+1) !1文字とする
            LET i=i+1
         ELSEIF tt=223 AND (t>=202 AND t<=206) THEN !ハ〜ホの半濁点
            LET xx$=xx$ & CHR$(ORD(JisTBL$(t))+2)
            LET i=i+1
         ELSE
            LET xx$=xx$ & JisTBL$(t)
         END IF
      CASE ELSE !それ以外なら
         LET xx$=xx$ & CHR$(t) !そのまま
      END SELECT

      LET i=i+1 !次へ
   LOOP

   LET JIS$=xx$
END FUNCTION

PUBLIC FUNCTION ToHiragana$
EXTERNAL FUNCTION ToHiragana$(x$) !全角カタカナをひらがなに変換する
   LET xx$=x$
   FOR i=1 TO LEN(x$) !対象文字を順に調べる
      LET t=ORD(x$(i:i))
      IF t<ORD("ァ") OR t>ORD("ン") THEN
      ELSE
         LET xx$(i:i)=CHR$(t-ORD("ァ")+ORD("ぁ"))
      END IF
   NEXT i
   LET ToHiragana$=xx$
END FUNCTION

PUBLIC FUNCTION ToKatakana$
EXTERNAL FUNCTION ToKatakana$(x$) !ひらがなを全角カタカナに変換する
   LET xx$=x$
   FOR i=1 TO LEN(x$) !対象文字を順に調べる
      LET t=ORD(x$(i:i))
      IF t<ORD("ぁ") OR t>ORD("ん") THEN
      ELSE
         LET xx$(i:i)=CHR$(t-ORD("ぁ")+ORD("ァ"))
      END IF
   NEXT i
   LET ToKatakana$=xx$
END FUNCTION

END MODULE

 

グラデーションな図形

 投稿者:山中和義  投稿日:2009年 5月14日(木)11時03分26秒
返信・引用
  グラデーション図形を描くルーチンをつくってみました。 実は以前つくったものの抜粋ですが、、、

●サンプル1
DIM x(0 TO 20),y(0 TO 20),r(0 TO 20),g(0 TO 20),b(0 TO 20) !頂点の位置と色

SET WINDOW -10,10,-10,10 !表示領域

DATA 1,0,0 !色RGB
DATA 1,1,0
DATA 0,1,0
DATA 0,1,1
DATA 0,0,1
DATA 1,0,1
DATA 1,0,0

CALL PLOT.Init !※


LET x(0)=0 !始点(0,0)、終点(3,0)
LET x(1)=3
LET y(0)=0
LET y(1)=0
PICTURE L1 !横線
   CALL PLOT.LINES(x,y,r,g,b) !※
END PICTURE

READ r(0),g(0),b(0) !始点の色

FOR i=1 TO 6
   READ r(1),g(1),b(1) !終点の色

   DRAW BAR WITH SHIFT(i*3-12,0)

   LET r(0)=r(1) !次へ
   LET g(0)=g(1)
   LET b(0)=b(1)
NEXT i

PICTURE BAR !棒状
   FOR j=8 TO -8 STEP -0.05
      DRAW L1 WITH SHIFT(0,j)
   NEXT j
END PICTURE

END




●サンプル2
DIM x(0 TO 20),y(0 TO 20),r(0 TO 20),g(0 TO 20),b(0 TO 20) !頂点の位置と色

SET WINDOW -10,10,-10,10 !表示領域

DATA 1,0,0 !色RGB
DATA 1,1,0
DATA 0,1,0
DATA 0,1,1
DATA 0,0,1
DATA 1,0,1
DATA 1,0,0

CALL PLOT.Init !※

LET  x(0)=0 !1点目の位置(中央)
LET  y(0)=0

LET  r(0)=0.2 !頂点の色
LET  g(0)=0.2
LET  b(0)=0.2

LET  x(1)=9*COS(0) !2点目
LET  y(1)=9*SIN(0)
READ r(1),g(1),b(1)

FOR i=1 TO 6 !六角形 ※三角形が6つ
   LET  x(2)=9*COS(i*PI/3) !3点目
   LET  y(2)=9*SIN(i*PI/3)
   READ r(2),g(2),b(2)

   CALL PLOT.AREALIMIT(3, x,y, r,g,b) !※

   LET  x(1)=x(2) !次へ
   LET  y(1)=y(2)

   LET  r(1)=r(2)
   LET  g(1)=g(2)
   LET  b(1)=b(2)
NEXT i

END


つづく
 

Re: グラデーションな図形

 投稿者:山中和義  投稿日:2009年 5月14日(木)11時04分36秒
返信・引用
  > No.376[元記事へ]

つづき

以下のプログラムを、それぞれのサンプルのEND文以降につなげてください。

MODULE PLOT !各頂点の色をもとに線分と凸多角形にグラデーションをかける

SET POINT STYLE 1 !マークの形状

SHARE NUMERIC Xmin(0 TO 1024),Xmax(0 TO 1024) !y座標(y行)におけるx座標の最小値、最大値 ※要調整
SHARE NUMERIC Rmin(0 TO 1024),Rmax(0 TO 1024)
SHARE NUMERIC Gmin(0 TO 1024),Gmax(0 TO 1024)
SHARE NUMERIC Bmin(0 TO 1024),Bmax(0 TO 1024)

SHARE NUMERIC ww,hh !スクリーンの位置、大きさ

EXTERNAL SUB Init !レンダリングターゲットを初期化する
   SET COLOR mode "NATIVE" !RGB指定
   SET TEXT font "",12 !文字サイズ
   ASK WINDOW x1,x2,y1,y2 !座標系の端の座標を取得する
   ASK PIXEL SIZE (x1,y1; x2,y2) ww,hh !画面の大きさ(ピクセル単位)を調べる
END SUB

EXTERNAL SUB SetPixel(x,y,c) !座標(x,y,z)に色(r,g,b)で点を描く ※PLOT POINTS: x,y と同じ
   SET POINT COLOR c
   PLOT POINTS: WORLDX(x), WORLDX(y) !問題座標に戻して描く
   !!!PLOT POINTS: x * (x2 - x1) / ww + x1, y * (y2 - y1) / hh + y1 !問題座標に戻して描く
END SUB


PUBLIC SUB POINTS !※PLOT POINTS: x,y と同じ
EXTERNAL SUB POINTS(xx,yy,rr,gg,bb) !線分を描画する
   LET  x1 = PIXELX(xx)
   LET  y1 = PIXELY(yy)

   IF (y1 >= 0) AND (y1 < hh) THEN !画面内なら
      IF (x1 >= 0) AND (x1 < ww) THEN
         CALL SetPixel(INT(x1),INT(y1), colorindex(rr,gg,bb))
      END IF
   END IF
END SUB

PUBLIC SUB LINES !※PLOT LINES: x0,y0; x1,y1 または MAT PLOT LINES,LIMIT 2: x,y と同じ
EXTERNAL SUB LINES(xx(),yy(),rr(),gg(),bb()) !線分を描画する
   LET  x1 = PIXELX(xx(0))
   LET  y1 = PIXELY(yy(0))

   LET  x2 = PIXELX(xx(1))
   LET  y2 = PIXELY(yy(1))

   LET  r1 = rr(0) !初期値を設定する
   LET  g1 = gg(0)
   LET  b1 = bb(0)

   SET DRAW mode hidden !ちらつき防止(開始)

   IF (x1 = x2) AND (y1 = y2) THEN !始点と終点が同じなら
      IF (y1 >= 0) AND (y1 < hh) THEN !画面内なら
         IF (x1 >= 0) AND (x1 < ww) THEN
            CALL SetPixel(INT(x1),INT(y1), colorindex(r1,g1,b1))
         END IF
      END IF
   ELSE
      LET  dx = x2 - x1 !相対的長さ
      LET  dy = y2 - y1

      IF ABS(dy) < ABS(dx) THEN !xの方が増分が多い
      !□□□■
      !□■■□  y=l*x+mの式として考える
      !■□□□
         LET  l = dy / dx !傾きを求める
         LET  dr = (rr(1) - rr(0)) / dx
         LET  dg = (gg(1) - gg(0)) / dx
         LET  db = (bb(1) - bb(0)) / dx
         FOR i=0 TO dx STEP SGN(dx)
            LET  x = x1 + i
            LET  y = l * i + y1
            LET  r = dr * i + r1
            LET  g = dg * i + g1
            LET  b = db * i + b1
            IF (y >= 0) AND (y < hh) THEN !画面内なら
               IF (x >= 0) AND (x < ww) THEN
                  CALL SetPixel(INT(x),INT(y), colorindex(r,g,b))
               END IF
            END IF
         NEXT i
      ELSE !yの方が増分が多い
      !□□■
      !□■□  x=l*y+mの式として考える
      !□■□
      !■□□
         LET  l = dx / dy !傾きを求める
         LET  dr = (rr(1) - rr(0)) / dy
         LET  dg = (gg(1) - gg(0)) / dy
         LET  db = (bb(1) - bb(0)) / dy
         FOR i=0 TO dy STEP SGN(dy)
            LET  x = l * i + x1
            LET  y = y1 + i
            LET  r = dr * i + r1
            LET  g = dg * i + g1
            LET  b = db * i + b1
            IF (y >= 0) AND (y < hh) THEN !画面内なら
               IF (x >= 0) AND (x < ww) THEN
                  CALL SetPixel(INT(x),INT(y), colorindex(r,g,b))
               END IF
            END IF
         NEXT i
      END IF
   END IF

   SET DRAW mode explicit !ちらつき防止(終了)
END SUB

PUBLIC SUB AREALIMIT !!※MAT PLOT AREA,LIMIT n: x,y と同じ
EXTERNAL SUB AREALIMIT(NumOfVtx, xx(),yy(),rr(),gg(),bb()) !凸多角形(頂点番号による面の定義)を描画する
   IF NumOfVtx < 3 THEN EXIT SUB

   DIM sx(0 TO NumOfVtx-1),sy(0 TO NumOfVtx-1)
   FOR i=0 TO NumOfVtx-1 !問題座標からピクセル座標に変換する
      LET  sx(i) = PIXELX(xx(i))
      LET  sy(i) = PIXELY(yy(i))
      !!!LET  sx(i) = (xx(i) - x1) * ww / (x2 - x1)
      !!!LET  sy(i) = (yy(i) - y1) * hh / (y2 - y1)
   NEXT i

   LET  top = +2147483647 !バッファの使用範囲を設定する
   LET  btm = -2147483648
   FOR i=0 TO NumOfVtx-1
      IF top > sy(i) THEN LET  top = sy(i)
      IF btm < sy(i) THEN LET  btm = sy(i)
   NEXT i
   LET  top = INT(top)
   LET  btm = INT(btm)
   IF top < 0 THEN LET  top = 0
   IF btm > hh THEN LET  btm = hh

   FOR i=top TO btm-1 !最大最小バッファを初期化する
      LET  Xmin(i) = +2147483647
      LET  Xmax(i) = -2147483648
   NEXT i

   FOR i=0 TO NumOfVtx-2 !稜線の数だけ
      CALL ScanEdge(i,i+1, sx,sy,rr,gg,bb) !稜線が描く各点を求める
   NEXT i
   CALL ScanEdge(NumOfVtx-1,0, sx,sy,rr,gg,bb)

   SET DRAW mode hidden !ちらつき防止(開始)

   FOR y=top TO btm-1 !各ライン(y座標)ごとに走査する - ラスタライズ

      LET  l = (Xmax(y) - Xmin(y)) + 1 !増分値を計算する
      LET  dr = (Rmax(y) - Rmin(y)) / l
      LET  dg = (Gmax(y) - Gmin(y)) / l
      LET  db = (Bmax(y) - Bmin(y)) / l

      LET  r = Rmin(y) !初期値を設定する
      LET  g = Gmin(y)
      LET  b = Bmin(y)

      FOR x=Xmin(y) TO Xmax(y) !ライン上での直線を描く ※PLOT LINES: Xmin(y),y; Xmax(y),y
         IF (x >= 0) AND (x < ww) THEN !画面内なら
            CALL SetPixel(x,y,colorindex(r,g,b)) !問題座標に戻して描く
         END IF
         LET  r = r + dr !次へ
         LET  g = g + dg
         LET  b = b + db
      NEXT x

   NEXT y

   SET DRAW mode explicit !ちらつき防止(終了)
END SUB

EXTERNAL SUB ScanEdge(v1,v2, xx(),yy(),rr(),gg(),bb()) !頂点v1と頂点v2を結ぶ稜線(辺)が描く各点を求める
   LET  l = ABS(INT(yy(v2) - yy(v1))) + 1 !幅を計算する

   LET  dx = (xx(v2) - xx(v1)) / l !増分値を計算する
   LET  dy = (yy(v2) - yy(v1)) / l
   LET  dr = (rr(v2) - rr(v1)) / l
   LET  dg = (gg(v2) - gg(v1)) / l
   LET  db = (bb(v2) - bb(v1)) / l

   LET  x = xx(v1) !初期値を設定する
   LET  y = yy(v1)
   LET  r = rr(v1)
   LET  g = gg(v1)
   LET  b = bb(v1)

   FOR i=0 TO l-1 !各ライン(y座標)ごとに
      LET  px = INT(x)
      LET  py = INT(y)

      IF (py >= 0) AND (py < hh) THEN !画面内なら
         IF Xmin(py) > px THEN !左端位置を記録する
            LET  Xmin(py) = px
            LET  Rmin(py) = r
            LET  Gmin(py) = g
            LET  Bmin(py) = b
         END IF

         IF Xmax(py) < px THEN !右端位置を記録する
            LET  Xmax(py) = px
            LET  Rmax(py) = r
            LET  Gmax(py) = g
            LET  Bmax(py) = b
         END IF
      END IF
      LET  x = x + dx !次へ
      LET  y = y + dy
      LET  r = r + dr
      LET  g = g + dg
      LET  b = b + db
   NEXT i

END SUB

END MODULE
 

C言語版の移植

 投稿者:山中和義  投稿日:2009年 5月15日(金)10時58分0秒
返信・引用
  Tiny programs for constants computation
 http://numbers.computation.free.fr/Constants/TinyPrograms/tinycodes.html
にπ、eなどの多桁を求めるC言語のショートプログラムがあります。

Q&Aのコーナー
 CやJavaで書かれた数値計算アルゴリズムの移植
  http://hp.vector.co.jp/authors/VA008683/ImportC.htm
を参考に、書き換えてみました。

これより、機械的に置き換えるパターンが見えてきます。


●サンプル1
!eの9000桁
!main(){int N=9009,n=N,a[9009],x;while(--n)a[n]=1+1/n;
!for(;N>9;printf("%d",x))
!for(n=N--;--n;a[n]=x%n,x=10*a[n-1]+x/n);}

!整形すると
!main(){
!  int N=9009,n=N,a[9009],x;
!  while(--n)
!    a[n]=1+1/n;
!  for( ;N>9; printf("%d",x) )
!    for( n=N--; --n; a[n]=x%n, x=10*a[n-1]+x/n );
!}

REM---> main(){
!nop

REM---> int N=9009,n=N,a[9009],x;
LET N=9009
LET n_=N !※C言語は大文字と小文字は区別される
DIM a(0 TO 9009-1) !※C言語は初期化しないため値は不定
LET x=0 !※

REM --> while(--n)
DO
   LET n_=n_-1
   IF n_=0 THEN EXIT DO

   REM --> a[n]=1+1/n;
   LET a(n_)=1+IP(1/n_)

LOOP

REM---> for(;N>9;printf("%d",x))
!nop !for(※; ; )部分

DO !for( ;※; )部分
   IF NOT N>9 THEN EXIT DO


   REM---> for(n=N--;--n;a[n]=x%n,x=10*a[n-1]+x/n)
   LET n_=N !for(※; ; )部分
   LET N=N-1

   DO !for( ;※; )部分
      LET n_=n_-1
      IF NOT n_<>0 THEN EXIT DO


      REM---> ;


      LET a(n_)=REMAINDER(x,n_) !for( ; ;※)部分
      LET x=10*a(n_-1)+IP(x/n_)

   LOOP


   PRINT x; !for( ; ;※)部分

LOOP

REM---> }

END


●サンプル2
!π
!main(){int a=1e4,c=3e3,b=c,d=0,e=0,f[3000],g=1,h=0;
!for(;b;!--b?printf("%04d",e+d/a),e=d%a,h=b=c-=15:f[b]=(d=d/g*b+a*(h?f[b]:2e3))%(g=b*2-1));}

!整形すると
!main(){
!  int a=1e4,
!      c=3e3,
!      b=c,
!      d=0,
!      e=0,
!      f[3000],
!      g=1,
!      h=0;
!  for(;
!      b;
!      !--b?
!        printf("%04d",e+d/a),
!        e=d%a,
!        h=b=c-=15
!      :
!        f[b]=(d=d/g*b+a*(h?
!                           f[b]
!                         :
!                           2e3
!                        )
!                         )%(g=b*2-1)
!     )
!    ;
!}

REM---> main(){
!nop

REM---> int a=1e4,c=3e3,b=c,d=0,e=0,f[3000],g=1,h=0;
LET a=1E4
LET c=3E3
LET b=c
LET d=0
LET e=0
DIM f(0 TO 3000-1) !※C言語は初期化しないため値は不定
LET g=1
LET h=0

REM---> for(;b;!--b?printf("%04d",e+d/a),e=d%a,h=b=c-=15:f[b]=(d=d/g*b+a*(h?f[b]:2e3))%(g=b*2-1))
!nop !for(※; ; )部分

DO !for( ;※; )部分
   IF NOT b<>0 THEN EXIT DO


   REM---> ;


   !for( ; ;※)部分
   LET b=b-1 ! !--b?〜:〜部分
   IF NOT b<>0 THEN
      PRINT USING "%%%%": e+IP(d/a); !printf("%04d",e+d/a),
      LET e=REMAINDER(d,a) !e=d%a,
      LET AX_=c-15 !h=b=c-=15
      LET h,b,c=AX_
   ELSE
      IF h<>0 THEN LET AX_=f(b) ELSE LET AX_=2E3 !h?〜:〜部分
      LET d=IP(d/g)*b+a*AX_ !d=d/g*b+a*(〜)部分
      LET g=b*2-1 !g=b*2-1部分
      LET f(b)=REMAINDER(d,g) !f[b]=(〜)%(〜)
   END IF

LOOP

REM---> }

END
 

Re: C言語版の移植

 投稿者:山中和義  投稿日:2009年 5月16日(土)11時12分42秒
返信・引用
  > No.378[元記事へ]

●サンプル3
!2の平方根の2400桁
!main(){int a=1000,b=0,c=1413,d,f[1414],n=800,k;
!for(;b<c;f[b++]=14);
!for(;n--;d+=*f*a,printf("%.3d",d/a),*f=d%a)
!for(d=0,k=c;--k;d/=b,d*=2*k-1)f[k]=(d+=f[k]*a)%(b=100*k);}

!整形すると
!main(){
!  int a=1000,b=0,c=1413,d,f[1414],n=800,k;
!  for( ;b<c; f[b++]=14 );
!  for( ;n--; d+=*f*a,printf("%.3d",d/a),*f=d%a )
!    for( d=0,k=c; --k; d/=b,d*=2*k-1 )
!      f[k]=(d+=f[k]*a)%(b=100*k);
!  }

REM---> main(){
!nop

REM---> int a=1000,b=0,c=1413,d,f[1414],n=800,k;
LET a=1000
LET b=0
LET c=1413
DIM f(0 TO 1414-1) !※C言語は初期化しないため値は不定
LET n=800
LET k=0 !※C言語は初期化しないため値は不定

REM---> for( ;b<c; f[b++]=14 );
!nop !for(※; ; )部分

DO !for( ;※; )部分
   IF NOT b<c THEN EXIT DO


   REM--> ;


   LET f(b)=14 !for( ; ;※)部分
   LET b=b+1

LOOP


REM---> for( ;n--; d+=*f*a,printf("%.3d",d/a),*f=d%a )
!nop !for(※; ; )部分

DO !for( ;※; )部分
   IF NOT n<>0 THEN EXIT DO
   LET n=n-1


   REM---> for(d=0,k=c; --k; d/=b,d*=2*k-1 )
   LET d=0 !for(※; ; )部分
   LET k=c

   DO !for( ;※; )部分
      LET k=k-1
      IF NOT k<>0 THEN EXIT DO


      REM--> f[k]=(d+=f[k]*a)%(b=100*k);
      LET d=d+f(k)*a
      LET b=100*k
      LET f(k)=REMAINDER(d,b)


      LET d=IP(d/b) !for( ; ;※)部分
      LET d=d*(2*k-1)

   LOOP


   LET d=d+f(0)*a !for( ; ;※)部分
   PRINT USING "%%%": IP(d/a) !最小桁数3桁
   LET f(0)=REMAINDER(d,a)

LOOP


REM---> }

END
 

質問です

 投稿者:キューピー  投稿日:2009年 5月18日(月)02時30分11秒
返信・引用
  最近BASICの存在を知って少し使いだしました。
分数の和の計算も出来ますか?
1/1+1/2+1/3+・・・+1/1129っていうのをやってみたいんですが、どのよぅにプログラムを使えばいいんですか?
すみませんが誰か回答お願いします(ノ△T)
 

Re: 質問です

 投稿者:白石 和夫  投稿日:2009年 5月18日(月)07時59分58秒
返信・引用
  > No.380[元記事へ]

結果を分数の形でほしいときは有理数モードを使います。
10 OPTION ARITHMETIC RATIONAL
20 LET t=0
30 FOR k=1 TO 1129
40    LET t=t+1/k
50 NEXT k
60 PRINT t
70 END
ただし,有理数モードはJIS規格の範囲外です。
標準BASICの範囲内でこの計算を行うプログラムを作るのは上級者向きの課題です。
 

Re: 質問です

 投稿者:キューピー  投稿日:2009年 5月19日(火)08時38分51秒
返信・引用
  > No.381[元記事へ]

上級者向きだったんですか。。。
初級から何かと頑張ります。
ありがとうございました。
 

フラクタル図形とアフィン写像

 投稿者:堀江 伸一  投稿日:2009年 5月22日(金)10時54分52秒
返信・引用  編集済
  10進Basic素晴らしいソフトですね。
イメージしにくかったフラクタルやアフィン写像の連続適用に関係する部分が理解しやすく操作も容易というのは非常にありがたいです。

学習中フラクタル図形を作っていてよくわからないことが出てきました。
複数のアフィン写像を組み合わせることによる連続写像に関する理論についてです。



まだ勉強中でよくわからないのですが、アフィン写像とフラクタルの関係はどのようなものなのでしょうか?
特に、規則的なフラクタル図形が得られるときとそうでないときの見極めに興味があります。

個人的には行列の面積拡大率が1以下のときフラクタル図形は規則的に描かれ、行列の面積拡大率が1以上のときは図形が巨大化し、カオスな図が描かれるという感じをうけたのですがよくわかりませんでした。
回転がかかってくる場合と、拡大縮小のみの場合で違う感じもうけます。


カオス理論にくらべたら、アフィン写像という線形代数の中での変形はまだ単純な世界。
ある程度の学習は可能だと感じています。
 

Re: フラクタル図形とアフィン写像

 投稿者:白石 和夫  投稿日:2009年 5月22日(金)14時43分49秒
返信・引用
  > No.383[元記事へ]

コンピュータのよいところは,仮説を簡単に検証してみれるところにあると思います。
いろいろ実験してみて,仮説が正しいそうだという確証が得られたら証明を試みる
という研究スタイルがとれるのがコンピュータの利点です。
ただし,計算機には計算精度の限界という壁があります。
たとえば,アフィン変換はいくつ合成してもアフィン変換ですが,
コンピュータだと,極限に近いところではおかしな挙動を示すかも知れません。
 

Σ1/kの多桁を求める

 投稿者:山中和義  投稿日:2009年 5月22日(金)22時06分56秒
返信・引用
  以前投稿した多桁(多倍長)ルーチンの「除算」ができました。
動作検証のため、先の分数計算を行いました。
!定数
DECLARE EXTERNAL NUMERIC MultiPrecision.RADIX, MultiPrecision.L2
DECLARE EXTERNAL NUMERIC MultiPrecision.c0(), MultiPrecision.c1()

!演算
DECLARE EXTERNAL FUNCTION MultiPrecision.lNum2Str$, MultiPrecision.lcomp
DECLARE EXTERNAL SUB MultiPrecision.lStr2Num, MultiPrecision.lcopy
DECLARE EXTERNAL SUB MultiPrecision.ladd, MultiPrecision.lsub
DECLARE EXTERNAL SUB MultiPrecision.lmul, MultiPrecision.ldiv

DECLARE EXTERNAL SUB MultiPrecision.llmul, MultiPrecision.ldivqr
!----------------------------------------


!Σ[k=1,n]1/k の計算

LET t0=TIME


DIM P(0 TO L2),Q(0 TO L2)
CALL lStr2Num("0",P) !t=P/Q=1
CALL lStr2Num("1",Q)

DIM T1(0 TO L2),T2(0 TO L2)
FOR k=1 TO 1129
   CALL lmul(P,k, T1) !t=t+1/k=(P*k+Q)/(Q*k) 通分
   CALL ladd(T1,Q, P)
   CALL lmul(Q,k, T2)
   CALL lcopy(T2,Q)
NEXT k
PRINT lNum2Str$(P)
PRINT lNum2Str$(Q)


DIM A(0 TO L2),B(0 TO L2)
CALL lcopy(P,A) !LET A=P !copy it
CALL lcopy(Q,B) !LET B=Q

LET c=0 !繰り返し回数 debug
DO UNTIL lcomp(B,c0)=0 !最大公約数を求める
   LET c=c+1 !debug
   CALL ldivqr(A,B, T1,T2) !LET R=MOD(A,B) !MOD(x,y)=x-y*INT(x/y)
   CALL lcopy(B,A) !LET A=B
   CALL lcopy(T2,B) !LET B=R
LOOP
PRINT "c=";c !debug
PRINT "gcd=";lNum2Str$(A) !PRINT "gcd=";A !debug

CALL ldivqr(P,A, T1,T2) !LET P=P/A !約分
CALL lcopy(T1,P)
CALL ldivqr(Q,A, T1,T2) !LET Q=Q/A
CALL lcopy(T1,Q)

PRINT "P=";lNum2Str$(P) !PRINT "P=";P !結果の表示
PRINT "Q=";lNum2Str$(Q) !PRINT "Q=";Q


PRINT TIME-t0

END


MODULE MultiPrecision !正の多桁(多倍長)整数の計算

!桁の数字の列を格納する配列a()を考える。
!上位桁      下位桁
!a(L2),a(L2-1),…,a(1),a(0) の構造で表すことができる。
!言い換えると、n進数表記の各桁がa()となる。
!たとえば、100進数とすると、a(k)は正の整数2桁(0〜99)となる。
!例. 12345は1*100*100+23*100+45だから、a(2)=1、a(1)=23、a(0)=45。


SHARE NUMERIC KETA
PUBLIC NUMERIC RADIX,L2

LET KETA=4 !桁数 1,2,3,4 ※32bitか64bit整数の範囲
LET RADIX=10^KETA !基数

LET L=3000 !求める桁数 ※
LET L2=INT(L/KETA)+1 !配列の大きさ


PUBLIC NUMERIC c0(0 TO 1000) !※
CALL lStr2Num("0",c0) !定数0
PUBLIC NUMERIC c1(0 TO 1000) !※
CALL lStr2Num("1",c1) !定数1

SHARE NUMERIC aa(0 TO 1000),bb(0 TO 1000),m(0 TO 1000) !作業用 ※


!----- 下位の演算ルーチン

PUBLIC SUB ladd
EXTERNAL SUB ladd(a(),b(), c()) !多桁+多桁 ※C=A+B
   LET cy=0 !桁上がり
   FOR i=0 TO L2 !下の桁から
      LET d=a(i)+b(i)+cy !同じ桁で
      IF d<RADIX THEN
         LET c(i)=d
         LET cy=0
      ELSE
         LET c(i)=d-RADIX
         LET cy=1 !上の桁へ
      END IF
   NEXT i
   IF cy>0 THEN
      PRINT "加算オーバーフロー"
      STOP
   END IF
END SUB
PUBLIC SUB lsub
EXTERNAL SUB lsub(a(),b(), c()) !多桁−多桁 ※A>B、C=A-B
   LET brrw=0 !借り
   FOR i=0 TO L2 !下の桁から
      LET d=a(i)-b(i)-brrw !同じ桁で
      IF d>=0 THEN
         LET c(i)=d
         LET brrw=0
      ELSE
         LET c(i)=d+RADIX
         LET brrw=1 !上の桁から借りる
      END IF
   NEXT i
   IF brrw>0 THEN
      PRINT "減算A-Bで、A>Bではありません。"
      STOP
   END IF
END SUB
PUBLIC SUB lmul
EXTERNAL SUB lmul(a(),b, c())  !多桁×正の整数(0〜255)※10000進数なら32767
   LET cy=0
   FOR i=0 TO L2 !下の桁から
      LET d=a(i)*b+cy
      LET cy=INT(d/RADIX) !桁上がり
      LET c(i)=MOD(d,RADIX) !この桁
   NEXT i
   IF cy>0 THEN
      PRINT "乗算オーバーフロー"
      STOP
   END IF
END SUB
PUBLIC SUB ldiv
EXTERNAL SUB ldiv(a(),b, c()) !多桁÷正の整数(0〜255)※10000進数なら32767
   IF b=0 THEN
      PRINT "0では割れません。"
      STOP
   END IF

   LET r=0 !余り
   FOR i=L2 TO 0 STEP -1 !上の桁から
      LET d=a(i)+r
      LET c(i)=INT(d/b) !商はこの桁
      LET r=MOD(d,b)*RADIX !余りを下の桁へ
   NEXT i
END SUB

PUBLIC SUB lcopy
EXTERNAL SUB lcopy(a(), b()) !コピー B=A
   FOR i=0 TO L2 !mat b=a
      LET b(i)=a(i) !同じ桁で
   NEXT i
END SUB
PUBLIC FUNCTION lcomp
EXTERNAL FUNCTION lcomp(a(),b()) !比較 A>Bなら1、A=Bなら0、A<Bなら-1
   FOR i=L2 TO 0 STEP -1 !上の桁から
      IF a(i)>b(i) THEN
         LET lcomp=1
         EXIT FUNCTION
      ELSEIF a(i)<b(i) THEN
         LET lcomp=-1
         EXIT FUNCTION
      END IF
   NEXT i
   LET lcomp=0
END FUNCTION

つづく
 

Re: Σ1/kの多桁を求める

 投稿者:山中和義  投稿日:2009年 5月22日(金)22時08分13秒
返信・引用  編集済
  > No.385[元記事へ]

つづき

!----- 入力、出力ルーチン

PUBLIC SUB lStr2Num
EXTERNAL SUB lStr2Num(a$, a()) !数字列を多桁整数に変換する
   FOR i=0 TO L2
      LET A(i)=0
   NEXT i
   FOR i=LEN(a$) TO 1 STEP -KETA
      LET d=INT((LEN(a$)-i)/KETA)
      IF d>L2 THEN
         PRINT "桁数が足りません。"
         STOP
      END IF
      LET a(d)=VAL(a$(i-KETA+1:i))
   NEXT i
END SUB
PUBLIC FUNCTION lNum2Str$
EXTERNAL FUNCTION lNum2Str$(a()) !多桁整数を数字列に変換する
   LET aMSD=GetMSD(a)
   IF aMSD<0 THEN !0なら
      LET a$=" 0"
   ELSE
      LET a$=" "&STR$(a(aMSD)) !1桁目
      FOR i=aMSD-1 TO 0 STEP -1 !2桁目以降
         LET a$=a$&right$("000"&STR$(a(i)),4)
      NEXT i
   END IF
   LET lNum2Str$=a$
END FUNCTION


!----- 上位の演算ルーチン

PUBLIC SUB llmul
EXTERNAL SUB llmul(a(),b(), c())  !多桁×多桁 ※C=A*B
   FOR i=0 TO L2*2 !mat c=zer
      LET c(i)=0
   NEXT i

   LET aMSD=GetMSD(a)
   LET bMSD=GetMSD(b)
   IF aMSD<0 OR bMSD<0 THEN EXIT SUB !乗数、被乗数が0なら

   FOR j=0 TO bMSD !乗数:下の桁から
      LET cy=0
      IF b(j)>0 THEN !0は計算しない
         FOR i=0 TO aMSD !被乗数:下の桁から
            LET d=a(i)*b(j)+cy + c(i+j) !累積 ※筆算参照 O(n^2)
            LET c(i+j)=MOD(d,RADIX) !この桁
            LET cy=INT(d/RADIX) !桁上がり
         NEXT i
         IF cy>0 THEN LET c(j+aMSD+1)=cy !上位桁へ
      END IF
   NEXT j
END SUB

EXTERNAL FUNCTION GetMSD(a()) !最上位桁の位置を得る
   FOR i=L2 TO 0 STEP -1
      IF a(i)<>0 THEN EXIT FOR
   NEXT i
   LET GetMSD=i !桁位置 ※0なら-1
END FUNCTION

PUBLIC SUB ldivqr
EXTERNAL SUB ldivqr(a(),b(), q(),r()) !多桁÷多桁 ※商q 余りr
   LET bMSD=GetMSD(b)
   IF bMSD<0 THEN !除数が0かどうか確認する
      PRINT "0では割れません。"
      STOP
   END IF

   FOR i=0 TO L2 !商を0とする
      LET q(i)=0
   NEXT i

   LET v=b(bMSD) !最上位桁の値を得る
   LET nk=INT(RADIX/(v+1)) !b(MSD)をRADIX/2以上にするための最小係数
   IF nk>1 THEN
      CALL lmul(b,nk, bb) !除数の最上位桁をRADIX/2以上、RADIX未満にする
      CALL lmul(a,nk, aa) !aもnk倍する
   ELSE
      CALL lcopy(b, bb) !×1
      CALL lcopy(a, aa)
   END IF

   LET t=GetMSD(bb)
   DO UNTIL lcomp(aa,bb)<0 !a<bなら終了
      LET s=GetMSD(aa)
      IF aa(s)>=bb(t) THEN
         IF CompareOffset(aa,bb,s-t)>=0 THEN !a>=b*RADIX^(s-t)を検査する
            LET u=s-t !商の最上位桁位置uおよび値q(u)の候補を求める
            LET q(u)=1
         ELSE
            LET u=s-t-1
            LET q(u)=RADIX-1
         END IF
      ELSE
         LET u=s-t-1
         LET q(u)=INT( (aa(s)*RADIX+aa(s-1))/bb(t) )
      END IF

      CALL lmul(bb,q(u), m)
      DO WHILE CompareOffset(aa,m,u)<0 !a>=m=b*q(0)を満たす最大のq(u)を求める
         LET q(u)=q(u)-1
         CALL lmul(bb,q(u), m)
      LOOP

      CALL SubOffset(aa,m, u) !a=a-b*q(u)*RADIX^u
   LOOP

   IF nk>1 THEN
      CALL ldiv(aa,nk, r) !余り 1/nk倍
   ELSE
      CALL lcopy(aa, r)
   END IF
END SUB
EXTERNAL FUNCTION CompareOffset(a(),b(),n) !桁をずらして比較する
   LET aMSD=GetMSD(a)
   LET bMSD=GetMSD(b)+n
   IF aMSD>bMSD THEN
      LET CompareOffset=1
   ELSEIF aMSD<bMSD THEN
      LET CompareOffset=-1
   ELSE
      FOR i=aMSD TO n STEP -1
         IF a(i)>b(i-n) THEN
            LET CompareOffset=1
            EXIT FUNCTION
         END IF
         IF a(i)<b(i-n) THEN
            LET CompareOffset=-1
            EXIT FUNCTION
         END IF
      NEXT i
      DO !a(aMSD)〜a(n)とb(bMSD)〜b(0)が一致する場合、
         IF NOT i>=0 THEN EXIT DO !a(n-1)〜a(0)に非零のものがあれば、aの方が大きい
         IF a(i)<>0 THEN
            LET CompareOffset=1
            EXIT FUNCTION
         END IF
         LET i=i-1
      LOOP
      LET CompareOffset=0
   END IF
END FUNCTION
EXTERNAL SUB SubOffset(a(),b(),n) !桁をずらして減算 ※a=a-b*RADIX^n
   LET brrw=0 !借り
   LET bMSD=GetMSD(b) !最上位桁までbをひく
   FOR i=0 TO bMSD
      LET d=a(i+n)-b(i)-brrw !同じ桁で
      IF d>=0 THEN
         LET a(i+n)=d
         LET brrw=0
      ELSE
         LET a(i+n)=d+RADIX
         LET brrw=1 !上の桁から借りる
      END IF
   NEXT i
   DO !上位桁への桁借り
      IF NOT brrw<>0 THEN EXIT DO
      IF a(i+n)<>0 THEN
         LET a(i+n)=a(i+n)-1
         LET brrw=0
      ELSE
         LET a(i+n)=RADIX-1
         LET brrw=1
      END IF
      LET i=i+1
   LOOP
END SUB

END MODULE
 

Re: フラクタル図形とアフィン写像

 投稿者:山中和義  投稿日:2009年 5月23日(土)11時07分0秒
返信・引用  編集済
  > No.383[元記事へ]

堀江 伸一さんへのお返事です。

> アフィン写像とフラクタルの関係はどのようなものなのでしょうか?
> 特に、規則的なフラクタル図形が得られるときとそうでないときの見極めに興味があります。


作図的な解釈ですが、、、


縮小写像(の和集合Ω)を

アフィン変換(拡大・縮小、回転、平行移動)で表し、(代数式、行列、複素数による表記が可能である)

原形に対してこれを(ある確率で)繰り返し適用させて、(再帰処理、繰り返し処理を実行する)

自己相似な図形(集合A)を発生させる。
 

Re: フラクタル図形とアフィン写像

 投稿者:SECOND  投稿日:2009年 5月23日(土)14時48分49秒
返信・引用  編集済
  > No.383[元記事へ]

堀江 伸一さんへのお返事です。

「周期を∞に発散させて二度と元に戻る事は無い。」が、これらに共通しています。
にもかかわらず、
隣接する出力と出力の間に、行なわれた計算は、概してシンプルで、
一意的な入出力が、しかも、繰返し同じ式を、用いているのも、注目されます。

以上の特徴は、カオスの定義と言っても良いのでは、自分では、考えています。
フラクタルも、カオスの一形態だと、思います。

ランダムとされる現象も、ポアンカレ切断面(注1)の様な、規則性が、発見
されれば、カオスに、変わるのですから、不明なだけのランダムかも知れません。

かつて、生物は、ミクロな遺伝情報から、全身の形状を、どんな方法で制御、
形作っているのかが、謎でした。が、フラクタル写像に、その鍵が有るようです。


(注1)n番目の出力が、それ以前のn−1、n−2、・・・の出力を、入力としての、
    関数出力になっているならば、その関数の入出力空間が、ポアンカレ切断面です。
    2次元面でないかもしれませんが、
    時間軸から見ると、垂直断面の様な、概念なので、そう呼ばれるようです。

    例)Xn = 4 * Xn-1 *( 1 - Xn-1 ) は、y=4x(1-x) の2次曲線の面を
      ポアンカレ切断面として、離散空間では、カオスになっている数列です。

 アファイン(アフィン)集合を与える行列や、人体の遺伝情報、株価の予測式?なども、
 ポアンカレ切断面のパッケージでは、ないでしょうか。

 又、これらは、次世代の、劇的な、圧縮、解凍への応用性を持ち、
   線型圧縮の数理的な限界、KLT変換を越えます。DNA は、その実際例?サンプル?
 

ありがとうございます

 投稿者:堀江伸一  投稿日:2009年 5月23日(土)15時07分20秒
返信・引用
  山中和義さん、定義をありがとうございます。
SECONDさんポアンカレ切断面。
新しい言葉を覚えました。

Xi+1=f(Xi)
の関数fがポアンカレ切断面ですね?


写像fが見つかればランダムでなくカオス。
理解しました。


山中和義さん。
既定の図形をアフィン変換で変形して重ねる、大きさの異なるスタンプを重ねるような写像ならいいですが、どうみても基本となるスタンプのような形が見出せそうもないようなアフィン変換の組が設定できるようなきがしてなりません。


まだ初学なのできれいに扱えるようなところから学習しようかと考えていますがちょっと気になります。
 

Re: ありがとうございます

 投稿者:SECOND  投稿日:2009年 5月24日(日)06時26分47秒
返信・引用  編集済
  > No.389[元記事へ]

> Xi+1=f(Xi)
> の関数fがポアンカレ切断面ですね?

関数fそのものではなくて、関数fの入出力領域の形状です。
一次元の例では、その形が、関数fと同一で、区別出来なくて、
まずかったですが、多くは、関数fが、微分方程式の形式で、解も
不明なまま、ルンゲクッタで描ける程度で、分りません。
ポアンカレ切断面は、その曲線や領域の中に、関数fの入出力が、
閉じている意味を持ち、関数fの存在を示唆するものです。

微分方程式も、差分化して描いている過程を考えると、
i番目からi+1番目の境界の関数で、関数として固定されていますが、
ポアンカレ切断面の場所の移動(iの移動)で、その入出力領域の
形状が、変化したりもします。

でも概念は、そのとおりかも知れない。この辺は、私もわからない。
 

Re: ありがとうございます

 投稿者:SECOND  投稿日:2009年 5月25日(月)00時20分17秒
返信・引用
  > No.390[元記事へ]

!ポアンカレ切断面の実際例です。
!
!レスラー方程式を、ルンゲ・クッタ4で描いています。グラフは、
!xyzの3次元の振る舞いですが、中央の図は、上から見たxy平面です。
!周囲30度 角度ごとに配置された12枚の図が、
!その角度での、ポアンカレ切断面で、縦:Z軸、横:中心からの半径距離
!になります。

!-------------------------------
OPTION ANGLE DEGREES
LET x=-2
LET y=0
LET z=0
LET a=0.398
LET b=2
LET c=4
!-----レスラー方程式( 非線形項が、z*x 1つだけのカオス)
DEF dxdt(  y,z)=-y-z       ! (dx/dt)= -y -z
DEF dydt(x,y  )= x+a*y     ! (dy/dt)=  x +a*y
DEF dzdt(x  ,z)= b+z*(x-c) ! (dz/dt)=  b +z*(x-c)

SUB RungeKutta
   LET kx1=dxdt(  y,z)
   LET ky1=dydt(x,y  )
   LET kz1=dzdt(x  ,z)
   !
   LET kx2=dxdt(            y+ky1*dt/2 ,z+kz1*dt/2)
   LET ky2=dydt(x+kx1*dt/2, y+ky1*dt/2            )
   LET kz2=dzdt(x+kx1*dt/2             ,z+kz1*dt/2)
   !
   LET kx3=dxdt(            y+ky2*dt/2 ,z+kz2*dt/2)
   LET ky3=dydt(x+kx2*dt/2, y+ky2*dt/2            )
   LET kz3=dzdt(x+kx2*dt/2             ,z+kz2*dt/2)
   !
   LET kx4=dxdt(          y+ky3*dt ,z+kz3*dt)
   LET ky4=dydt(x+kx3*dt, y+ky3*dt          )
   LET kz4=dzdt(x+kx3*dt           ,z+kz3*dt)
   !
   LET x=x+(kx1+2*kx2+2*kx3+kx4)*dt/6
   LET y=y+(ky1+2*ky2+2*ky3+ky4)*dt/6
   LET z=z+(kz1+2*kz2+2*kz3+kz4)*dt/6
END SUB

!-----run
SET TEXT background "OPAQUE"
SET COLOR MIX(15) .5,.5,.5
SET POINT STYLE 1
DIM vl(12),vr(12),vb(12),vt(12) ,va(12)
DATA .8, .8, .6, .4, .2, 0 , 0 , 0 , .2, .4, .6, .8
DATA 1 , 1 , .8, .6, .4, .2, .2, .2, .4, .6, .8, 1
DATA .4, .6, .8, .8, .8, .6, .4, .2, 0 , 0 , 0 , .2
DATA .6, .8, 1 , 1 , 1 , .8, .6, .4, .2, .2, .2, .4
DATA  0, 30, 60, 90,120,150,180,-150,-120,-90,-60,-30
MAT READ vl,vr,vb,vt,va
!
CLEAR
LET dt=.03 !演算ピッチ sec. pitch time
LET t=0
DO
   SET VIEWPORT .2, .8, .2, .8
   SET WINDOW -7,7,-7,7! -4,6, -6,3
   IF 0< t THEN
      PLOT LINES:bakx,baky; x,y
   ELSE
      DRAW axes !grid(1,1)
      FOR p=1 TO 12
         PLOT LINES:0,0;8*COS(va(p)),8*SIN(va(p))
         PLOT TEXT,AT 6.6*COS(va(p))-.15, 6.6*SIN(va(p))-.3 :STR$(va(p))
      NEXT p
   END IF
   LET bakx=x
   LET baky=y
   CALL RungeKutta
   FOR p=1 TO 12
      IF ABS( va(p)-ANGLE(x,y))< 1 THEN
         CALL poincare
      END IF
   NEXT p
   LET t=t+dt
LOOP UNTIL 2000< t

SUB poincare
   SET VIEWPORT vl(p),vr(p),vb(p),vt(p)
   SET WINDOW -1,7,-1,7
   !PLOT LINES:-1,-1;7,-1;7,7;-1,7;-1,-1
   DRAW axes
   PLOT POINTS: SQR(x^2+y^2),z
END SUB

END
 

わからないです・・・

 投稿者:キューピー  投稿日:2009年 5月25日(月)02時48分58秒
返信・引用
  N=INT11において
Hn>Nとなる最小のnを求めるプログラムっていうのは、どうやって求めればいいんですか?
Hn=1/1+1/2+1/3+1/4+・・・
なんですけど(@_@;)
 

Re: わからないです・・・

 投稿者:白石 和夫  投稿日:2009年 5月25日(月)09時13分7秒
返信・引用  編集済
  > No.392[元記事へ]

質問意図が不明(日本語が??)ですが,
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1126545731
と同じ趣旨の課題であるのなら,
試行錯誤によって論理を構築する訓練のための課題だと思います。
おそらく,ここを自力で乗り越えないと,後が苦しくなる急所でしょう。
 

Re: わからないです・・・

 投稿者:山中和義  投稿日:2009年 5月25日(月)10時39分44秒
返信・引用  編集済
  > No.392[元記事へ]

キューピーさんへのお返事です。

こんなサイトを見つけました。

愉快な等式
 http://blue.kakiko.com/mmrmmr/


このサイトの上から2/3の所

整数値に近い逆数和
 http://blue.kakiko.com/mmrmmr/htm/eqtn27.html


先のサンプルのように、FOR〜NEXT文で置き換えることもできますが、
FOR〜NEXT文は、一般的に繰り返し回数がわかっているときに使います。

Σ1/k=1/1+1/2+1/3+ … +1/k を次のように解釈するといいでしょう。

先の問題は、
! 1129
!t=Σ1/k=1/1+1/2+1/3+ … +1/1129
! k=1

LET t=0 !部分和

LET k=1
DO
   LET t=t+1/k !t=Σ1/k

   IF k=1129 THEN EXIT DO
   LET k=k+1
LOOP
PRINT k

PRINT t !結果

END

となります。今回は、

 t>11
t=Σ1/k
 k=1

ですから、、、 パズルですね!?
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 5月26日(火)10時05分2秒
返信・引用
  > No.309[元記事へ]

数列の数値計算 - 一般項、漸化式、Σ

次のようなパターンで、定義や計算式をBASIC言語に置き換えて計算する。
!例題1 自然数の和
! def a(n)=n (n>=1) ※一般項
! t=Σ{a[k]; k=1,t>300} ※和が300を超えるとき、最小のkとその和を表示する
! print k,t
!
! ※擬似言語による表現

DEF a(n)=n !def a(n)=n (n>=1) の部分

LET t=0 !Σ{a[k]; k=1,t>300} の部分
LET k=1
DO
   LET t=t+a(k)

   IF t>300 THEN EXIT DO
   LET k=k+1
LOOP

PRINT "k=";k, "t=";t !print k,t の部分



!例題1の別解
FOR k=1 TO 300 !上限 ∵1+2+3+ … +k
   LET t=k*(k+1)/2 !和の公式 Σk
   IF t>300 THEN EXIT FOR
NEXT k
PRINT "k=";k, t



!例題2
! def2 y[1]=1, y[n+1]=3*y[n]+2 (n>=1) ※隣接二項間漸化式
! print y[n=1,10] ※1〜10項を表示する

FUNCTION y(n) !def2 y[1]=1, y[n+1]=3*y[n]+2 (n>=1) の部分
   local k,y0,y1
   LET y1=1 !<---
   IF n=1 THEN !第1項
      LET y=y1
   ELSE
      FOR k=2 TO n !第2項以降
         LET y0=y1
         LET y1=3*y0+2 !<---
      NEXT k
      LET y=y1
   END IF
END FUNCTION

FOR n=1 TO 10 !print x[n=1,10] の部分
   PRINT n;y(n)
NEXT n




!!例題3 フィボナッチ数列
! def3 x[1]=0, x[2]=1, x[n+2]=x[n+1]+x[n] (n>=1) ※隣接三項間漸化式
! for n=1 to n ※周期のある数列へ
!  print x[n] mod 4 ※余りを表示する
! next

FUNCTION x(n) !def3 x[1]=1, x[2]=1, x[n+2]=x[n+1]+x[n] (n>=1) の部分
   local k,x0,x1,x2
   LET x1=0 !<---
   IF n=1 THEN !第1項
      LET x=x1
   ELSE
      LET x2=1 !<---
      IF n=2 THEN !第2項
         LET x=x2
      ELSE
         FOR k=3 TO n !第3項以降
            LET x0=x1
            LET x1=x2
            LET x2=x1+x0 !<---
         NEXT k
         LET x=x2
      END IF
   END IF
END FUNCTION

FOR n=1 TO 30
   PRINT n; MOD(x(n+1),4) !print x[n] mod 4 の部分
NEXT n



END


扱う項が小さい場合、配列と対応させる方法もある。
メモリ性能は落ちるが、予め計算することで時間性能は向上する。


時間性能の比較として、フィボナッチ数列の「再帰呼出し」を掲載する。

定義は簡潔になるが、項が大きくなると時間がかかり、BASIC側のスタックオーバーフローが発生する。
FUNCTION f(n)
   IF n<2 THEN
      LET f=n !f(0)=0, f(1)=1
   ELSE
      LET f=f(n-1)+f(n-2) !f(n)=f(n-1)+f(n-2) n≧2
   END IF
END FUNCTION

FOR k=0 TO 30 !1〜30項を表示する
   PRINT k;f(k)
NEXT k

END
 

つづき。

 投稿者:SECOND  投稿日:2009年 5月26日(火)12時10分6秒
返信・引用
  > No.391[元記事へ]

!先の、改良版。
!
!角度の窓を止め、角度を越える1番目で、採取する。(sens lead edge)
!文は読み辛くなるが、ピッチ幅広くても、採取出来、ピッチ幅に応じた
!ボケになるため、ピッチ幅の、評価が出来る。速度も速い。
!-30°(330°)度付近のボケが、取れた。

!レスラー方程式、3次元グラフ、中央の図は、上から見たxy平面。
!周囲30度 ごとに配置された12枚の図は、
!その角度での、ポアンカレ切断面( 縦:z軸、横:中心からの距離)
!-------------------------------
LET x=-3
LET y=0
LET z=0
LET a=0.398
LET b=2
LET c=4
!-----レスラー方程式( 非線形項が、z*x 1つだけのカオス。形状:メビウスの帯)
DEF dxdt(  y,z)=-y-z       ! (dx/dt)= -y -z
DEF dydt(x,y  )= x+a*y     ! (dy/dt)=  x +a*y
DEF dzdt(x  ,z)= b+z*(x-c) ! (dz/dt)=  b +z*(x-c)

SUB RungeKutta
   LET kx1=dxdt(  y,z)
   LET ky1=dydt(x,y  )
   LET kz1=dzdt(x  ,z)
   !
   LET kx2=dxdt(            y+ky1*dt/2 ,z+kz1*dt/2)
   LET ky2=dydt(x+kx1*dt/2, y+ky1*dt/2            )
   LET kz2=dzdt(x+kx1*dt/2             ,z+kz1*dt/2)
   !
   LET kx3=dxdt(            y+ky2*dt/2 ,z+kz2*dt/2)
   LET ky3=dydt(x+kx2*dt/2, y+ky2*dt/2            )
   LET kz3=dzdt(x+kx2*dt/2             ,z+kz2*dt/2)
   !
   LET kx4=dxdt(          y+ky3*dt ,z+kz3*dt)
   LET ky4=dydt(x+kx3*dt, y+ky3*dt          )
   LET kz4=dzdt(x+kx3*dt           ,z+kz3*dt)
   !
   LET x=x+(kx1+2*kx2+2*kx3+kx4)*dt/6
   LET y=y+(ky1+2*ky2+2*ky3+ky4)*dt/6
   LET z=z+(kz1+2*kz2+2*kz3+kz4)*dt/6
END SUB

!-----run
SET TEXT background "OPAQUE"
SET COLOR MIX(15) .5,.5,.5
SET POINT STYLE 1
OPTION ANGLE DEGREES
OPTION BASE 0
DIM vl(11),vr(11),vb(11),vt(11) ,va(11)
DATA .8, .8, .6, .4, .2, 0 , 0 , 0 , .2, .4, .6, .8
DATA 1 , 1 , .8, .6, .4, .2, .2, .2, .4, .6, .8, 1
DATA .4, .6, .8, .8, .8, .6, .4, .2, 0 , 0 , 0 , .2
DATA .6, .8, 1 , 1 , 1 , .8, .6, .4, .2, .2, .2, .4
DATA  0, 30, 60, 90,120,150,180,210,240,270,300,330
MAT READ vl,vr,vb,vt,va
!
LET dt=.02 !sec. pitch time
LET t=0
DO
   SET VIEWPORT .2, .8, .2, .8
   SET WINDOW -7,7,-7,7
   LET xya= MOD(ANGLE(x,y),360) !xya= 0~< 360 ←  0~180~(-180)< ~< 0
   IF 0< t THEN
      PLOT LINES: bakx,baky; x,y
   ELSE
      DRAW axes
      FOR i=11 TO 0 STEP -1
         PLOT LINES:0,0;8*COS(va(i)),8*SIN(va(i))
         PLOT TEXT,AT 6.6*COS(va(i))-.15, 6.6*SIN(va(i))-.3 :STR$(va(i))
         IF xya<=va(i) THEN LET p=i ! 初期角度の va()番号 を探す。
      NEXT i
   END IF
   !----
   IF p=0 THEN
      IF xya< va(1) THEN CALL poincare ! 0度の va() のみ。
   ELSE
      IF va(p)<=xya THEN CALL poincare ! 30~330度の va()
   END IF
   !----
   LET bakx=x
   LET baky=y
   CALL RungeKutta
   LET t=t+dt
LOOP UNTIL 1400< t

SUB poincare
   SET VIEWPORT vl(p),vr(p),vb(p),vt(p)
   SET WINDOW -1,7,-1,7
   DRAW axes
   PLOT POINTS: SQR(x^2+y^2),z
   LET p=MOD(p+1,12) ! 次の va()番号
END SUB

END
 

関数定義でエラーが発生

 投稿者:虎の耳  投稿日:2009年 5月26日(火)22時25分46秒
返信・引用
  DEF f(x)=LOG(1-x)
とか,
DEF f(x)=SQR(4-x^2)
でエラーがでるようになりました.
(以前はでていなかったような・・・)
ご検討をよろしくおねがいします.
 

Re: 関数定義でエラーが発生

 投稿者:白石 和夫  投稿日:2009年 5月27日(水)08時07分4秒
返信・引用  編集済
  > No.397[元記事へ]

虎の耳さんへのお返事です。

> DEF f(x)=LOG(1-x)
> とか,
> DEF f(x)=SQR(4-x^2)
> でエラーがでるようになりました.
> (以前はでていなかったような・・・)
> ご検討をよろしくおねがいします.

どんなエラーが出ますか。
翻訳時エラーですか,実行時エラーですか。
十進BASICのバージョンはいくつですか。

なお,
10 DEF f(x)=LOG(1-x)
20 PRINT f(2)
30 END
みたいなプログラムは,実行時のエラーになるのが仕様です。
(エラーにならなければバグです。)
 

注釈行

 投稿者:カノン  投稿日:2009年 5月27日(水)15時50分57秒
返信・引用
  拝啓 はじめまして。かつて、色々なBASICを触っておりましたが、このたび十進BASICを
見つけました。年寄りの手習いと思って取り組みましたが、はやばやと引っかかってしまいました。プログラムの"END"のあとに、少し長文のコメントを入 れたところ、なんだかんだとクレームがつき、プログラムの実行ができません。かっては、どのBASICでもこんなことはなかったように思います。どうすれ ばいいのかご教示ねがいます。
 

Re: 注釈行

 投稿者:山中和義  投稿日:2009年 5月27日(水)16時13分30秒
返信・引用  編集済
  > No.399[元記事へ]

カノンさんへのお返事です。

> プログラムの"END"のあとに、少し長文のコメントを入れたところ、
REM 注釈
REM 注釈
REM 注釈

! 注釈
! 注釈
! 注釈

END

REM 注釈
REM 注釈
REM 注釈

のような記述でしょうか?

END文以降は、!(感嘆符)による注釈を使ってください。

REM 注釈
REM 注釈
REM 注釈

! 注釈
! 注釈
! 注釈

END

! 注釈
! 注釈
! 注釈


また、次のようにREM文が最後にならなければ記述もできます。
 :(略)
 :

END

REM 注釈
REM 注釈
REM 注釈

EXTERNAL SUB test !またはEXTERNAL FUNCTION
END SUB
 

これは、鳥なのか

 投稿者:SECOND  投稿日:2009年 5月27日(水)21時09分8秒
返信・引用
  !これは、鳥なのか。
!
OPTION ARITHMETIC NATIVE
!---------------------------------------
LET t$="グモゥスキー~ミラー写像"
LET u=-0.8
DEF F(x)= u*x+2*(1-u)*x^2/(1+x^2)
DEF x1(x,y)= y+0.008*(1-0.05*y^2)*y+F(x)
DEF y1(x,y)=-x+F(x1(x,y))
!---------------------------------------
!写像の連鎖が、カオスになっている座標(x,y)の描画です。
!Affine 写像の様な、2分岐や、多分岐 は無く、N回目の写像も、
!1つだけの写像が続き、増えませんので、再帰型は、あまり要はなく、
!1:再帰コールしない正順番、2:再帰型の逆順番、の2通り描画。

! 再帰型。但し、N回後の最終写像から、N,,,2,1,0 逆順で描画される。
SUB fr(k, x,y)
   IF 0< k THEN CALL fr(k-1, x1(x,y),y1(x,y))
   PLOT POINTS: x,y
END SUB

! 写像の順番どうりに、0,1,2,,,N 正順番で描画。
SUB fo(N, x,y)
   FOR k=0 TO N
      PLOT POINTS: x,y
      LET wx= x1(x,y) ! x= x1(x,y) ←本来ですが、x の変化は、次式の後に。
      LET y= -x+F(wx) ! y= y1(x,y) ←本来ですが、wx で計算の節約。
      LET x=wx
   NEXT k
END SUB

SET TEXT FONT "MS 明朝",12
SET TEXT BACKGROUND "OPAQUE"
SET POINT STYLE 1
LET N=50000
!
LET h=20
LET xm= h*0.1
LET ym= h*0.35
SET WINDOW xm-h,xm+h, ym-h,ym+h
CALL fo(N,.1,2) ! 写像の正順で描画 0,1,2,,,N
!
LET h=30
LET xm= h*0.2
LET ym=-h*0.4
SET WINDOW xm-h,xm+h, ym-h,ym+h
PLOT TEXT,AT xm-h*0.15, ym+h*0.85:t$& " N= "& STR$(N)
PLOT TEXT,AT xm-h*0.9, ym+h*0.85:"しばらく御待ち下さい。"
CALL fr(N,.1,2) ! 最終写像から逆順で描画 N,,,2,1,0
PLOT TEXT,AT xm-h*0.9, ym+h*0.85:" 描画の終了     "

END
 

注釈行

 投稿者:カノン  投稿日:2009年 5月28日(木)18時05分15秒
返信・引用
  山中和義どの、早速のご回答を有難うございました。お蔭様で、各行の"REM"を"!"に変えてみましたら、プログラムの実行が可能となりました。この件以外でも感じていますが、この
十進BASICというのは簡単なようで、これまでの様々なBASICと比較すると、細かいところで色々と癖がありますね。
これからも愚問を発するかも知れませんが、よろしくお願いする次第です。
 

Re: 関数定義でエラーが発生

 投稿者:虎の耳  投稿日:2009年 5月28日(木)21時42分45秒
返信・引用
  > No.398[元記事へ]

白石 和夫さんへのお返事です。

お騒がせしました.
私のプログラムミスでした.
 

Re: これは、鳥なのか

 投稿者:SECOND  投稿日:2009年 5月29日(金)11時10分47秒
返信・引用
  > No.401[元記事へ]

気が付かなかった・・

! 再帰型。但し、N回後の最終写像から、N,,,2,1,0 逆順で描画される。
SUB fr(k, x,y)
   IF 0< k THEN CALL fr(k-1, x1(x,y),y1(x,y))
   PLOT POINTS: x,y
END SUB

   ↓の様に、行を入れ替えると、

! 再帰型。! 写像の順番どうりに、0,1,2,,,N 正順番で描画。
SUB fr(k, x,y)
   PLOT POINTS: x,y
   IF 0< k THEN CALL fr(k-1, x1(x,y),y1(x,y))
END SUB
 

座標軸描画のバグ

 投稿者:荒田浩二  投稿日:2009年 6月 5日(金)18時49分43秒
返信・引用
  軸・格子を描く組込みの絵定義に、いくつかの不具合を発見したので報告します。

(1) GRID(p,q),AXES(p,q),GRID0(p,q),AXES0(p,q)で一方の引数を0にすると横軸縦軸ともに目盛りが描かれない。

(2) GRID(p,q),AXES(p,q)で特定の数値を設定すると右端,上端の数字が描かれない。
10 LET a=23  ! a=41,46,51,82,87,92,97,…
20 LET b=1   ! b=2,4,8,11,13,16,21,22,26,27,…
30 SET WINDOW -a,a,-b,b
40 DRAW GRID(a/5,b/10)
50 END

(3) GRID(p,q),AXES(p,q)でy座標の領域の幅をごく小さく設定すると、描かれないはずのx軸の数字が上端に描画されることがある。
10 LET c=.0000001
20 SET WINDOW -5,5,7-c,7
30 DRAW GRID(1,c/10)
40 END
 

Re: 座標軸描画のバグ

 投稿者:白石 和夫  投稿日:2009年 6月 6日(土)18時07分17秒
返信・引用
  > No.405[元記事へ]

ご報告ありがとうございました。
文字列の一部が境界にかかると文字列全体を描かないのはWindows APIの仕様だと思います。
座標値の扱いが変なのは,以前に報告のあったPLOT LINES文の不具合と同種のものです。
こちらはPLOT TEXT文にもかかわる不具合なので対策を考えます。
 

立体曲線の、変形指示MAT文 による描画。

 投稿者:SECOND  投稿日:2009年 6月 7日(日)00時37分5秒
返信・引用  編集済
  ! 立体曲線 f(x,y,z,t)の、変形指示MAT文 による描画。
!
! PLOT LINES :x1,y1,z1; x2,y2,z2 は、エラーですが、これを、picture 文に
! 置いて、draw picture with matrix したかの様に、描く。
!
! x1,y1,z1; x2,y2,z2 の両端 座標だけを、picture 文に渡して、
! draw … with … を実行し、座標のみの、変形、回転をする。
! x1,y1,z1; x2,y2,z2 のその出力から、x,y 成分だけの線を引く。

!(言い換えると、picture 文の中で、PLOT LINES をせず、出てから、PLOT する)
!-------------------------------

! ローレンツ方程式、3次元グラフ

!「例」描くグラフは、対流現象の近似式として知られるカオスです。
!-------------------------------
LET s=10
LET b=8/3
LET r=28
!-----ローレンツ方程式(カオス)
DEF dxdt(x,y  )= -s*x +s*y    ! (dx/dt)= -s*x +s*y
DEF dydt(x,y,z)= -x*z +r*x -y ! (dy/dt)= -x*z +r*x -y
DEF dzdt(x,y,z)=  x*y -b*z    ! (dz/dt)=  x*y -b*z

SUB RungeKutta
   LET kx1=dxdt(x,y  )
   LET ky1=dydt(x,y,z)
   LET kz1=dzdt(x,y,z)
   !
   LET kx2=dxdt(x+kx1*dt/2, y+ky1*dt/2            )
   LET ky2=dydt(x+kx1*dt/2, y+ky1*dt/2 ,z+kz1*dt/2)
   LET kz2=dzdt(x+kx1*dt/2, y+ky1*dt/2 ,z+kz1*dt/2)
   !
   LET kx3=dxdt(x+kx2*dt/2, y+ky2*dt/2            )
   LET ky3=dydt(x+kx2*dt/2, y+ky2*dt/2 ,z+kz2*dt/2)
   LET kz3=dzdt(x+kx2*dt/2, y+ky2*dt/2 ,z+kz2*dt/2)
   !
   LET kx4=dxdt(x+kx3*dt, y+ky3*dt          )
   LET ky4=dydt(x+kx3*dt, y+ky3*dt ,z+kz3*dt)
   LET kz4=dzdt(x+kx3*dt, y+ky3*dt ,z+kz3*dt)
   !
   LET x=x+(kx1+2*kx2+2*kx3+kx4)*dt/6
   LET y=y+(ky1+2*ky2+2*ky3+ky4)*dt/6
   LET z=z+(kz1+2*kz2+2*kz3+kz4)*dt/6
END SUB

!-----run
OPTION ANGLE DEGREES
DIM pV1(4), pV2(4), P3D(4,4), rotx(4,4)
MAT rotx=IDN
!
LET ax=-75 ! 原点を通り、画面の水平軸での回転( x 軸とは、限らず。)
!
! 1,       0, 0, 0
! 0, cos(ax), 0, 0
! 0,-sin(ax), 1, 0
! 0,       0, 0, 1
!
LET rotx(2,2)=COS(ax)
LET rotx(3,2)=-SIN(ax)
!
LET xm=0
LET ym=20
LET h=40
SET WINDOW xm-h,xm+h,ym-h,ym+h
LET dt=.005 !sec. pitch time
!
FOR az=-45 TO 315 STEP 10 ! z軸での回転。360 度、一回り。
!----
   LET x=2
   LET y=1
   LET z=24
   !----
   LET t=0
   IF -45< az THEN SET DRAW mode hidden
   CLEAR
   PLOT TEXT,AT xm+h*.2,ym+h*.9 :"lorenz ローレンツ方程式"
   DO
      IF 0< t THEN
      !---3D 曲線(x,y,z)
         DRAW line3D( bakx,baky,bakz, x,y,z) WITH ROTATE(az)*rotx
         PLOT LINES: pV1(1),pV1(2); pV2(1),pV2(2)
      ELSE
      !   ---X 軸
         DRAW line3D( -30,0,0, 30,0,0) WITH ROTATE(az)*rotx
         PLOT LINES: pV1(1),pV1(2); pV2(1),pV2(2)
         PLOT TEXT,AT pV2(1),pV2(2) :"(X)"
         !---Y 軸
         DRAW line3D( 0,-30,0, 0,30,0) WITH ROTATE(az)*rotx
         PLOT LINES: pV1(1),pV1(2); pV2(1),pV2(2)
         PLOT TEXT,AT pV2(1),pV2(2) :"(Y)"
         !---Z 軸
         DRAW line3D( 0,0,-10, 0,0,50) WITH ROTATE(az)*rotx
         PLOT LINES: pV1(1),pV1(2); pV2(1),pV2(2)
         PLOT TEXT,AT pV2(1),pV2(2) :"(Z)"
      END IF
      !----
      LET bakx=x
      LET baky=y
      LET bakz=z
      CALL RungeKutta
      LET t=t+dt
   LOOP UNTIL 30< t ! 100 くらいが良いのかも… 遅くなる。
   SET DRAW mode explicit
NEXT az

PICTURE line3D(x1,y1,z1, x2,y2,z2)
   MAT P3D=TRANSFORM !← draw ・・・ with matrix で与えられた matrix
   LET pV1(1)=x1
   LET pV1(2)=y1
   LET pV1(3)=z1   !入力 z1 座標は、出力 x1,y1 に反映、描画される。
   LET pV1(4)=1
   MAT pV1=pV1*P3D !出力 z1 座標pV1(3)は、描画しない。
   LET pV2(1)=x2
   LET pV2(2)=y2
   LET pV2(3)=z2   !入力 z2 座標は、出力 x2,y2 に反映、描画される。
   LET pV2(4)=1
   MAT pV2=pV2*P3D !出力 z2 座標pV2(3)は、描画しない。
END PICTURE

END
 

Re: 座標軸描画のバグ

 投稿者:荒田浩二  投稿日:2009年 6月 7日(日)21時49分10秒
返信・引用
  > No.406[元記事へ]

よろしくお願いいたします。
 

つづき

 投稿者:SECOND  投稿日:2009年 6月 9日(火)05時14分11秒
返信・引用  編集済
  > No.407[元記事へ]

! 立体曲線 f(x,y,z,t)を、変形指示MAT文で、描く(2)
!
! 前回、くどい事をしていたようで、整理した。
! 配列ベクトル x,y,z 座標を入力に、単に、変形指示MAT文だけで変形回転する。
! x,y,z のその出力から、x,y 成分だけの PLOT。
!-------------------------------

! レスラー方程式 3次元グラフ

! 非線形項が、z*x 1つだけのカオス。形状:メビウスの帯
!-------------------------------
LET a=0.398
LET b=2
LET c=4
!-----レスラー方程式
SUB Dxyz( kx,ky,kz, x,y,z)
   LET kx=-y-z       ! (dx/dt)= -y -z
   LET ky= x+a*y     ! (dy/dt)=  x +a*y
   LET kz= b+z*(x-c) ! (dz/dt)=  b +z*(x-c)
END SUB

SUB RungeKutta
   CALL Dxyz( kx1,ky1,kz1, x,y,z)
   CALL Dxyz( kx2,ky2,kz2, x+kx1*dt/2,y+ky1*dt/2,z+kz1*dt/2)
   CALL Dxyz( kx3,ky3,kz3, x+kx2*dt/2,y+ky2*dt/2,z+kz2*dt/2)
   CALL Dxyz( kx4,ky4,kz4, x+kx3*dt  ,y+ky3*dt  ,z+kz3*dt  )
   LET x=x+(kx1+2*kx2+2*kx3+kx4)*dt/6
   LET y=y+(ky1+2*ky2+2*ky3+ky4)*dt/6
   LET z=z+(kz1+2*kz2+2*kz3+kz4)*dt/6
END SUB

!-----run
OPTION CHARACTER byte !ウムラウト"o" =CHR$(246) をエラーにさせない。
OPTION ANGLE DEGREES
DIM pV(4), P3D(4,4), rotx(4,4)
!
MAT rotx=IDN ! 単位行列
LET ax=-55   ! 原点を通り、画面の水平軸での回転( x 軸とは、限らず。)
!
!(x,y,z,1)| 1,       0, 0, 0 | PLOT 座標ベクトルは、行ベクトル。
!         | 0, cos(ax), 0, 0 | 4列目の1は、拡大率の逆数であるが、
!         | 0,-sin(ax), 1, 0 | draw 文で、描画しないので、無視して可。
!         | 0,       0, 0, 1 |
!
LET rotx(2,2)=COS(ax)
LET rotx(3,2)=-SIN(ax)
!
LET xm=0
LET ym=2
LET h=7
SET WINDOW xm-h,xm+h,ym-h,ym+h
LET dt=.05    ! sec. pitch time
LET SS=35     ! z軸回り、開始角度
LET EE=SS-360 ! +360:左回転 -360:右回転
!
FOR az=SS TO EE STEP SGN(EE-SS)*10 ! z軸、一回り360 度
   MAT P3D=ROTATE(az)*rotx
   !----
   IF az<>SS THEN SET DRAW mode hidden
   CLEAR
   SET TEXT font "Courier",11
   PLOT TEXT,AT xm+h*.2,ym+h*.9 :"R"& CHR$(246)& "ssler"
   SET TEXT font "標準ゴシック",11
   PLOT TEXT,AT xm+h*.45,ym+h*.9 :"レスラー方程式" ! PEN-off
   !---座標軸
   CALL axes3D( -6,0,0, 6,0,0, "(X)" )
   CALL axes3D( 0,-6,0, 0,6,0, "(Y)" )
   CALL axes3D( 0,0,-2, 0,0,8, "(Z)" )
   !---3D 曲線
   LET x=-3
   LET y=0
   LET z=0
   FOR t=0 TO 300 STEP dt
      CALL line3D(x,y,z)
      CALL RungeKutta
   NEXT t
   SET DRAW mode explicit
NEXT az

SUB axes3D(x1,y1,z1, x2,y2,z2, a$ )
   CALL line3D(x1,y1,z1)
   CALL line3D(x2,y2,z2)
   PLOT TEXT,AT pV(1),pV(2) :a$ ! PEN-off
END SUB

SUB line3D(x,y,z)
   LET pV(1)=x
   LET pV(2)=y
   LET pV(3)=z   !入力 z 座標は、出力 x,y に反映、描画される。
   MAT pV=pV*P3D
   PLOT LINES: pV(1),pV(2); !出力 z 座標pV(3)は、不要。 PEN-on
END SUB

END
 

電子回路で 作られたカオス

 投稿者:SECOND  投稿日:2009年 6月12日(金)05時12分43秒
返信・引用  編集済
  > No.407[元記事へ]

!先の投稿、ローレンツ方程式で、DEF dxdt()、DEF・・・の引数に脱落が
!ありました。すみません。 ( 現在、訂正済み。)
!-------------------------------

! 立体曲線 f(x,y,z,t)を、変形指示MAT文で、描く(3)
!-------------------------------
OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES
DIM pV(4), P3D(4,4), rotx(4,4), LH(6), copy(0 TO 100000, 3)
MAT rotx=IDN ! 単位行列
!
!-----
! 電子回路で 作られたカオス。(添付図参照)
LET t$="Double Scroll Attractor ダブル スクロール アトラクタ"

! 変曲点(±Bp)のある 負性抵抗回路への 電流=ih( 電圧 )
DEF ih(x)= g0*x+(g1-g0)*( ABS(x+Bp)-ABS(x-Bp) )/2

SUB Dxyz( kx,ky,kz, x,y,z)
   LET kx= (gR*(y-x) -ih(x))/C1 ! (d vC1/dt)= (gR*(vC2-vC1)-ih(vC1))/C1
   LET ky= (gR*(x-y) +z )/C2    ! (d vC2/dt)= (gR*(vC1-vC2)+iL     )/C2
   LET kz= -y/L                 ! (d iL /dt)= -vC2/L
END SUB

LET C1= 1/9 !コンデンサー   (パラメーター C1~Bp)
LET C2= 1   !コンデンサー
LET L=  1/7 !インダクター
LET gR= 0.7 !Rのコンダクタンス(アドミタンスの実数部)
LET g0=-0.5 !負性抵抗回路の微分コンダクタンス(〜<-Bp    +Bp<〜)
LET g1=-0.8 !負性抵抗回路の微分コンダクタンス(  -Bp<〜<+Bp  )
LET Bp= 1   !負性抵抗回路の、変曲点の電圧 絶対値。
!
LET x=-1e-7 !初期値 x,y,z
LET y= 1e-7
LET z= 1e-7
DATA -3,3, -3,3, -2.5,3 !座標軸の両端 xL,xH, yL,yH, zL,zH
MAT READ LH
LET xm=0    !画面中心 xm,ym
LET ym=.5   !
LET h=3.5   !画面片幅 ±h
LET dt=.01  ! pitch time
LET t99=120 ! close time
LET ax=-85  !z軸を、画面の水平軸で回転、傾ける角度
LET SS=-25  !z軸での、回転 開始角度
LET EE=SS+360 !    回転 終了角度 +360:左回転 -360:右回転
CALL graph3D


!-----
SUB RungeKutta
   CALL Dxyz( kx1,ky1,kz1, x,y,z)
   CALL Dxyz( kx2,ky2,kz2, x+kx1*dt/2,y+ky1*dt/2,z+kz1*dt/2)
   CALL Dxyz( kx3,ky3,kz3, x+kx2*dt/2,y+ky2*dt/2,z+kz2*dt/2)
   CALL Dxyz( kx4,ky4,kz4, x+kx3*dt  ,y+ky3*dt  ,z+kz3*dt  )
   LET x=x+(kx1+2*kx2+2*kx3+kx4)*dt/6
   LET y=y+(ky1+2*ky2+2*ky3+ky4)*dt/6
   LET z=z+(kz1+2*kz2+2*kz3+kz4)*dt/6
END SUB

SUB graph3D
!-----run
!z軸を、画面の水平軸で回転、傾ける行列 rotx
!(x,y,z,1)| 1,       0, 0, 0 | 十進の、PLOTベクトルは、行ベクトル。
!         | 0, cos(ax), 0, 0 | 4列目の1は、拡大率の逆数であるが、
!         | 0,-sin(ax), 1, 0 | draw~with~ で効果する。
!         | 0,       0, 0, 1 | このプログラムでは、無視して可。
   LET rotx(2,2)=COS(ax)
   LET rotx(3,2)=-SIN(ax)
   !
   SET WINDOW xm-h,xm+h,ym-h,ym+h
   !
   FOR az=SS TO EE STEP SGN(EE-SS)*10 ! z軸で、一回り360 度
      MAT P3D=ROTATE(az)*rotx
      !----
      IF az<>SS THEN SET DRAW mode hidden
      CLEAR
      PLOT TEXT,AT xm-h*.8,ym+h*.9 :t$ ! PEN-off
      !---座標軸
      CALL axes3D( LH(1),0,0, LH(2),0,0, "(X)" )
      CALL axes3D( 0,LH(3),0, 0,LH(4),0, "(Y)" )
      CALL axes3D( 0,0,LH(5), 0,0,LH(6), "(Z)" )
      !---3D 曲線
      IF az=SS THEN
         LET n=0
         FOR t=0 TO t99 STEP dt
            LET copy(n,1)=x
            LET copy(n,2)=y ! 1回目(開始角度)で、3D記録を撮る。
            LET copy(n,3)=z
            CALL line3D(x,y,z)
            CALL RungeKutta
            LET n=n+1
         NEXT t
      ELSE
         FOR n=0 TO n-1
            LET x=copy(n,1)
            LET y=copy(n,2) ! 2回目以降は、記録の再生で、高速描画。
            LET z=copy(n,3)
            CALL line3D(x,y,z)
         NEXT n
      END IF
      SET DRAW mode explicit
   NEXT az
END SUB

SUB axes3D(x1,y1,z1, x2,y2,z2, a$ )
   CALL line3D(x1,y1,z1)
   CALL line3D(x2,y2,z2)
   PLOT TEXT,AT pV(1),pV(2) :a$ ! PEN-off
END SUB

SUB line3D(x,y,z)
   LET pV(1)=x
   LET pV(2)=y
   LET pV(3)=z   !入力 z 座標は、出力 x,y に反映、描画される。
   MAT pV=pV*P3D
   PLOT LINES: pV(1),pV(2); !出力 z 座標pV(3)は、不要。 PEN-on
END SUB

END
 

ヤリイカの巨大神経

 投稿者:SECOND  投稿日:2009年 6月14日(日)22時46分58秒
返信・引用  編集済
  ! 立体曲線 f(x,y,z,t)を、変形指示MAT文で、描く(4)
!-------------------------------
OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES
DIM pV(4), P3D(4,4), rotx(4,4), LH(6), copy(0 TO 100000, 3)
LET pV(4)=1 ! shift()*rotate()* … で必要。
MAT rotx=IDN
!
!-----
LET t$="ヤリイカの巨大神経(カオス) 数学モデル"
LET t2$="Hodgkin-Huxley ホジキン−ハクスレイ方程式 のストレンジ アトラクタ"

DEF I(t)= I0+A*SIN( 360*f*t ) ! 膜電流 +外部入力

LET t3$="膜電位 V →( X)"
! (d V/dt)= I(t)-120*m^3*h*(V-115) -40*n^4*(V+12) -.24*(V-10.613)
!
LET t4$="ナトリウム 活性化変数( 0< m< 1) →( Y)"
! (d m/dt)= .1*(25-V)/(EXP((25-V)/10)-1)*(1-m) -4*EXP(-V/18)*m
!
LET t5$="ナトリウム不活性化変数( 0< h< 1) →( Z)"
! (d h/dt)= .07*EXP(-V/20)*(1-h) -1/(EXP((30-V)/10)+1)*h

! カリウム活性化変数( 0< n< 1) →描画しない。
! (d n/dt)= .01*(10-V)/(EXP((10-V)/10)-1)*(1-n) -.125*EXP(-V/80)*n

SUB Dxyzn( kx,ky,kz,kn, x,y,z,n)
   LET kx= I(t)-120*y^3*z*(x-115) -40*n^4*(x+12) -.24*(x-10.613) ! (d V/dt)
   LET ky= .1*(25-x)/(EXP((25-x)/10)-1)*(1-y) -4*EXP(-x/18)*y    ! (d m/dt)
   LET kz= .07*EXP(-x/20)*(1-z) -1/(EXP((30-x)/10)+1)*z          ! (d h/dt)
   LET kn= .01*(10-x)/(EXP((10-x)/10)-1)*(1-n) -.125*EXP(-x/80)*n! (d n/dt)
END SUB

LET I0=20   !膜電流 パラメーター
LET A=40
LET f=.3000001
!
LET x=6.24  !初期値 x,y,z,n
LET y=.0761
LET z=.301
LET n=.519
!
DATA -15,100, -.3,1, -.04,.49 !座標軸の両端座標 xL,xH, yL,yH, zL,zH
MAT READ LH
LET Sx=1    !スケール倍率 Sx,Sy,Sz
LET Sy=50
LET Sz=200
!
LET xm=40   !画面中心 xm,ym
LET ym=52
LET hw=80   !画面幅/2 ±hw
LET dt=.05  ! pitch time
LET t99=500 ! close time
LET zox=40  !z軸と、平行な回転軸へのオフセットxy
LET zoy=20
LET ax=-75  !回転軸を、画面の水平軸で倒し、傾ける角度
LET SS=-25    !回転 開始角度
LET EE=SS+360 !回転 終了角度 +360:左回転 -360:右回転
CALL graph3D


!-----
SUB RungeKutta
   CALL Dxyzn( kx1,ky1,kz1,kn1, x,y,z,n)
   CALL Dxyzn( kx2,ky2,kz2,kn2, x+kx1*dt/2,y+ky1*dt/2,z+kz1*dt/2,n+kn1*dt/2)
   CALL Dxyzn( kx3,ky3,kz3,kn3, x+kx2*dt/2,y+ky2*dt/2,z+kz2*dt/2,n+kn2*dt/2)
   CALL Dxyzn( kx4,ky4,kz4,kn4, x+kx3*dt  ,y+ky3*dt  ,z+kz3*dt  ,n+kn3*dt  )
   LET x=x+(kx1+2*kx2+2*kx3+kx4)*dt/6
   LET y=y+(ky1+2*ky2+2*ky3+ky4)*dt/6
   LET z=z+(kz1+2*kz2+2*kz3+kz4)*dt/6
   LET n=n+(kn1+2*kn2+2*kn3+kn4)*dt/6
END SUB

SUB graph3D
!-----run
!回転軸を、画面の水平軸で倒し、傾ける行列 rotx
!(x,y,z,1)| 1,       0, 0, 0 | 十進の、PLOTベクトルは、行ベクトル。
!         | 0, cos(ax), 0, 0 | 4列目の1は、拡大率の逆数、draw文 で効果。
!         | 0,-sin(ax), 1, 0 | 直接の plot lines では、1 にリセットされる。
!         | 0,       0, 0, 1 | 行列の計算では、平行移動を、可能にする。
   LET rotx(2,2)=COS(ax)       !このプログラムでは、SHIFT(,) で必要。
   LET rotx(3,2)=-SIN(ax)
   !
   SET WINDOW xm-hw,xm+hw,ym-hw,ym+hw
   !
   FOR az=SS TO EE STEP SGN(EE-SS)*10 ! 回転軸で、10 度づつ回す。
      MAT P3D=SHIFT(-zox,-zoy)*ROTATE(az)*SHIFT(zox,zoy)*rotx
      !----
      IF az<>SS THEN SET DRAW mode hidden
      CLEAR
      PLOT TEXT,AT xm-hw*.9,ym+hw*.90 :t$
      PLOT TEXT,AT xm-hw*.9,ym+hw*.83 :t2$
      PLOT TEXT,AT xm-hw*.9,ym-hw*.92 :t5$
      PLOT TEXT,AT xm-hw*.9,ym-hw*.99 :t4$& "  "& t3$ ! PEN-off
      !---座標軸
      CALL axes3D( LH(1),0,0, LH(2),0,0, STR$(LH(2))& "( X)" )
      CALL axes3D( 0,LH(3),0, 0,LH(4),0, STR$(LH(4))& "( Y)" )
      CALL axes3D( 0,0,LH(5), 0,0,LH(6), STR$(LH(6))& "( Z)" )
      !---3D 曲線
      IF az=SS THEN
         LET ci=0
         FOR t=0 TO t99 STEP dt
            LET copy(ci,1)=x
            LET copy(ci,2)=y ! 1回目(開始角度)で、3D記録を撮る。
            LET copy(ci,3)=z
            ! PRINT x;y;z;n ! データーを保存したい時。
            CALL line3D(x,y,z)
            CALL RungeKutta
            LET ci=ci+1
         NEXT t
      ELSE
         FOR ci=0 TO ci-1 ! 2回目以降は、記録の再生で、高速描画。
            CALL line3D( copy(ci,1),copy(ci,2),copy(ci,3) )
         NEXT ci
      END IF
      SET DRAW mode explicit
   NEXT az
END SUB

SUB axes3D(x1,y1,z1, x2,y2,z2, a$ )
   CALL line3D(x1,y1,z1)
   CALL line3D(x2,y2,z2)
   PLOT TEXT,AT pV(1),pV(2) :a$ ! PEN-off
END SUB

SUB line3D(x,y,z)
   LET pV(1)=x*Sx  !描画目盛は、全方向等しくないと、回転で、形が保てない。
   LET pV(2)=y*Sy  !スケール Sx,Sy,Sz の違いは、入力の倍率として、行なう。
   LET pV(3)=z*Sz  !入力 z 座標は、出力 x,y に反映、描画される。
   MAT pV=pV*P3D
   PLOT LINES: pV(1),pV(2); ! PEN-on
END SUB

END
 

Re: 座標軸描画のバグ

 投稿者:山中和義  投稿日:2009年 6月15日(月)10時49分32秒
返信・引用
  > No.406[元記事へ]

ユーザー絵定義を使った場合は、(2),(3)は正常に表示するようだ。
10 LET c=.0000001
20 SET WINDOW -5,5,7-c,7
30 DRAW GRID2(1,c/10) ! <-----
40 END
50 MERGE "grid2.lib" ! <----- ※EXTERNAL PICTURE 文による直接の記述もOK


また、DRAW circle、DRAW disk についても同じ現象が発生する。
SET WINDOW -500,500,-500,500

LET phi=(1+SQR(5))/2 !黄金比
LET a=2*PI*phi !黄金角

LET r=1
LET th=0
FOR i=0 TO 900
   LET r=1.1*r !らせん状
   LET th=th+a
   LET x1=r*COS(th)
   LET y1=r*SIN(th)
   !DRAW disk WITH SCALE(r*0.3)*SHIFT(x1,y1)
   DRAW circle WITH SCALE(r*0.3)*SHIFT(x1,y1)
NEXT i

END

MERGE "circle.lib"


WindowsMeとXPでは、障害内容が違う。
 Meの場合、OSのDIBENG.DLLでエラーとなりBASICが強制終了となる。
 XPの場合、描画しない、黒ベタになる。
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 6月17日(水)10時24分11秒
返信・引用  編集済
  > No.395[元記事へ]

問題
 自然数nに対して、n=p^2*q(p,qは自然数)となるpとqを求める

解答
!●その1 1≦p^2≦n、1≦q≦nを満たすp,qの積が、式n=p^2*qを満たす

LET n=324

FOR p=INT(SQR(n)) TO 1 STEP -1 !p^2の候補
   LET x=p^2
   FOR q=1 TO n !qの候補
   !FOR q=1 TO n/x !qの候補 ※q=n/p^2より
      IF x*q=n THEN !式を満たす
         PRINT "p=";p; "q=";q
      END IF
   NEXT q
NEXT p



!★その2−1 n=p^2*qより、p^2はnの約数(nはp^2の倍数)

LET n=324

FOR p=INT(SQR(n)) TO 1 STEP -1 !候補を大きい方から
   LET x=p^2
   IF MOD(n,x)=0 THEN !p^2はnの約数より
   !IF INT(n/x)*x=n THEN !nはp^2の倍数より
      LET q=n/x
      PRINT "p=";p; "q=";q
   END IF
NEXT p



!●その2−2 n=p^2*qより、qはnの約数(nはqの倍数)

LET n=324

FOR q=1 TO n !候補を小さい方から
   IF MOD(n,q)=0 THEN !qはnの約数より
   !IF INT(n/q)*q=n THEN !nはqの倍数より
      LET p=SQR(n/q)
      IF p=INT(p) THEN !pは自然数
         PRINT "p=";p; "q=";q
      END IF
   END IF
NEXT q



!★その3−1 n=p^2*qより、qの1次方程式q=n/p^2を解く

LET n=324

FOR p=INT(SQR(n)) TO 1 STEP -1 !約数p^2の候補を大きい方から
   LET q=n/p^2
   IF q=INT(q) THEN !qは自然数より
      PRINT "p=";p; "q=";q
   END IF
NEXT p



!●その3−2 n=p^2*qより、pの2次方程式p^2=n/qを解く

LET n=324

FOR q=1 TO n !約数qの候補を小さい方から
   LET x=n/q
   IF x=INT(x) THEN !pは自然数より、x=n/q=p^2は自然数
      LET p=SQR(x)
      IF p=INT(p) THEN !同様に、p=SQR(n/q)は自然数
         PRINT "p=";p; "q=";q
      END IF
   END IF
NEXT q



!★その4 素因数分解 n=2^a*3^b*5^c* …とすると、a=INT(a/2)*2+MOD(a,2)、b,c,…も同様

LET n=324

LET p=1
LET q=1

LET x=n
LET m=2
DO WHILE x>1 !1まで繰り返す
   LET K=0
   DO WHILE MOD(x,m)=0 !mで割り切れるなら(mは因数)
      LET x=x/m !割り切れるまで(m^Kの形)
      LET K=K+1
   LOOP

   PRINT m;"^";K !debug
   LET p=p*m^INT(K/2) !商
   LET q=q*m^MOD(K,2) !余り

   IF m>2 THEN !2,3,5,7,9,・・・で調べる
      LET m=m+2
   ELSE
      LET m=m+1
   END if
LOOP

PRINT "p=";p; "q=";q


END
 

平方根の計算

 投稿者:山中和義  投稿日:2009年 6月20日(土)15時37分30秒
返信・引用  編集済
  SQR(32)-SQR(3)*{2*SQR(2)+SQR(6)}+12/SQR(6) = SQR(2)

を計算するプログラムを試作してみました。

現状、手コンパイルで式は定義する必要があります。

係数が分数になる場合は、有理数モードで実行してください。
(ルーチンSqNormalizeのINT(SQR(n))をINTSQR(n)に変更する)

!平方根の計算

!p*SQR(q)を、「SQR(q)とその係数p」として、配列a(q)=pで表せる。
!∵n=p^2*q、n,p,q≧0とすると、SQR(n)=p*SQR(q)と変形できる。
! これより、SQR(32)=4*SQR(2)となり、同類項をまとめる場合、共通項SQR(2)として扱える。
! また、SQR()を配列として解釈すると、SQR(n)を一意に表現できる。

LET szRt=10 !扱う平方根の範囲 ※必要に応じて変更のこと

!演算関連
SUB SqSet(n, a()) !a=SQR(n)とする
   IF INT(n)<>n THEN
      PRINT "整数を設定してください。"; n
      STOP
   END IF
   MAT a=ZER
   CALL SqNormalize(ABS(n), p,q)
   IF n<0 THEN LET q=-q
   LET a(q)=p
END SUB
SUB SqSetQ(x,y, a()) !a=SQR(x/y)、x:整数、y:正の整数 とする
   IF y<=0 OR INT(y)<>y THEN
      PRINT "正の整数を設定してください。"; y
      STOP
   END IF
   CALL SqSet(x*y, a)
   CALL SqDivN(a,y, a)
END SUB
SUB SqSetN(n, a()) !a=nとする
   MAT a=ZER
   LET a(1)=n
END SUB

SUB SqAdd(a(),b(), c()) !加算 c=a+b
   MAT c=a+b
END SUB
SUB SqSub(a(),b(), c()) !減算 c=a-b
   MAT c=a-b
END SUB
SUB SqMulN(a(),N, c()) !乗算 c=a*N ※{√(x)+√(y)+ … }*N
   MAT c=(N)*a
END SUB
SUB SqDivN(a(),N, c()) !除算 c=a/N ※{√(x)+√(y)+ … }/N
   IF N=0 THEN
      PRINT "0では割れません。"
      STOP
   END IF
   MAT c=(1/N)*a
END SUB
DIM w(-szRt TO szRt) !作業用
SUB SqMulS(a(),B, c()) !乗算 c=a*B ※{√(x)+√(y)+ … }*√(B)
   MAT w=ZER
   FOR i=LBOUND(a) TO UBOUND(a)
      IF a(i)<>0 THEN !係数が0以外なら
         IF i*B<0 THEN
            CALL SqNormalize(ABS(i*B), p,q) !※√(-a)*√(b)=√(-a*b)、√(a)*√(-b)=√(-a*b)
            LET q=-q
         ELSE
            CALL SqNormalize(i*B, p,q) !※√(a)*√(b)=√(a*b)
            IF B<0 THEN LET p=-p !※√(-a)*√(-b)=-√(a*b)
         END IF
         LET w(q)=w(q)+a(i)*p !√(a[])*√(B)
      END IF
   NEXT i
   MAT c=w
END SUB
SUB SqDivS(a(),B, c()) !除算 c=a/B ※{√(x)+√(y)+ … }/√(B)
   IF B=0 THEN
      PRINT "0では割れません。"
      STOP
   END IF
   CALL SqMulS(a,B, c) !√(i)*√(B)/B ※分母を有理化する
   CALL SqDivN(c,B, c)
END SUB

DIM w0(-szRt TO szRt),w1(-szRt TO szRt) !作業用
SUB SqMul(a(),b(), c()) !乗算 c=a*b ※{√(x)+√(y)+ … }*{√(u)+√(v)+ … }
   MAT w0=ZER
   FOR k=LBOUND(b) TO UBOUND(b)
      LET Bk=b(k) !√(a[])*√(b[k])
      IF Bk<>0 THEN !係数が0以外なら
         CALL SqMulS(a,k, w1) !平方根の中の部分
         CALL SqMulN(w1,Bk, w1) !係数の部分
         MAT w0=w0+w1
      END IF
   NEXT k
   MAT c=w0
END SUB
DIM w2(-szRt TO szRt),w3(-szRt TO szRt),w4(-szRt TO szRt),w5(-szRt TO szRt) !作業用
SUB SqDiv(a(),b(), c()) !除算 c=a/b ※{√(x)+√(y)+ … }/{√(u)+√(v)+ … }
   MAT w2=a
   MAT w3=b
   DO
      FOR k=LBOUND(b) TO UBOUND(b) !平方根を探す
         IF k<>1 AND w3(k)<>0 THEN EXIT FOR
      NEXT k
      IF k>UBOUND(b) THEN EXIT DO !平方根がなくなれば、有理化を終了する

      MAT w4=w3 !{√(u)+√(v)+ … }-√(k)をつくって、(s+t)*(s-t)=s^2-t^2の形へ
      LET w4(k)=-w3(k)

      CALL SqMul(w2,w4, w5) !分子側 {√(x)+√(y)+ … }*{√(u)+√(v)+ … -√(k)}
      MAT w2=w5
      CALL SqMul(w3,w4, w5) !分母側 {{√(u)+√(v)+ … }+√(k)}*{{√(u)+√(v)+ … }-√(k)}
      MAT w3=w5
   LOOP
   CALL SqDivN(w2,w3(1), c) !分子/分母
END SUB
SUB SqPow(a(),n, x()) !べき乗 x=a^n ※{√(x)+√(y)+ … }^n
   IF INT(n)<>n THEN
      PRINT "べき乗数が整数ではありません。"; n
      STOP
   END IF
   CALL SqSetN(1, w3) !x=1
   MAT w2=a !b=a
   LET n2=ABS(n)
   DO UNTIL n2=0
      IF MOD(n2,2)=1 THEN CALL SqMul(w3,w2, w3) !x=x*b
      CALL SqMul(w2,w2, w2) !b=b*b
      LET n2=INT(n2/2)
   LOOP
   IF n<0 THEN !負なら逆数にする
      CALL SqSetN(1, w2)
      CALL SqDiv(w2,w3, w3) !x=1/x
   END IF
   MAT x=w3
END SUB

SUB SqNormalize(n, p,q) !平方根の中をできるだけ小さな正の整数に直す
!※n=p^2*q、n,p,q≧0とすると、SQR(n)=p*SQR(q)と変形できる。
   LET q=1 !※SQR(0)=0*SQR(1)とする ※n=0なら、1行下のFOR文でp=0は設定される
   FOR p=INT(SQR(n)) TO 1 STEP -1 !約数p^2の候補を大きい方から
   !FOR p=INTSQR(n) TO 1 STEP -1 !約数p^2の候補を大きい方から ※有理数モードのとき
      LET q=n/p^2
      IF q=INT(q) THEN EXIT FOR !qは自然数より
   NEXT p
END SUB

!出力関連
SUB SqPrint(a()) !√(x)+√(y)+ … 形式で表示する
   LET flg=0
   FOR i=LBOUND(a) TO UBOUND(a) !小さい順に
      LET Ai=a(i) !係数
      IF Ai<>0 THEN
         IF flg=1 THEN PRINT " + "; !継続なら
         IF Ai<0 THEN
            PRINT "( ";Ai;") ";
         ELSE
            IF i=1 OR Ai<>1 THEN PRINT Ai; !係数が1以外なら
         END IF
         IF i<>1 THEN !SQR(1)以外なら
            IF Ai<>1 THEN PRINT "* "; !係数が1以外なら
            PRINT "SQR(";i;")";
         END IF
         LET flg=1
      END IF
   NEXT i
   IF flg=0 THEN PRINT " 0";
   PRINT
END SUB
!------------------------------ ここまでがサブルーチン

DIM T1(-szRt TO szRt),T2(-szRt TO szRt),T3(-szRt TO szRt) !作業用



!●例1 SQR(32)-SQR(3)*{2*SQR(2)+SQR(6)}+12/SQR(6) の計算

DIM c2(-szRt TO szRt),c3(-szRt TO szRt),c6(-szRt TO szRt),c32(-szRt TO szRt) !定数
CALL SqSet(32, c32) !c32=SQR(32)
CALL SqSet(3, c3) !c3=SQR(3)
CALL SqSet(2, c2) !c2=SQR(2)
CALL SqSet(6, c6) !c6=SQR(6)

CALL SqMulN(c2,2, T1) !T1=2*SQR(2)
CALL SqAdd(T1,c6, T1) !T1=2*SQR(2)+SQR(6)
!CALL SqPrint(T1)
CALL SqMul(c3,T1, T3) !T3=SQR(3)*{2*SQR(2)+SQR(6)}
!!!または、CALL SqMulS(T1,3, T3) !T3=SQR(3)*{2*SQR(2)+SQR(6)}
!CALL SqPrint(T3)

CALL SqSub(c32,T3, T1) !T1=SQR(32)-SQR(3)*{2*SQR(2)+SQR(6)}

DIM n12(-szRt TO szRt) !定数
CALL SqSetN(12, n12) !n12=12

CALL SqDivS(n12,6, T2) !T2=12/SQR(6)
!CALL SqPrint(T2)
CALL SqAdd(T1,T2, T1) !T1=SQR(32)-SQR(3)*{2*SQR(2)+SQR(6)}+12/SQR(6)

CALL SqPrint(T1) !結果




!●例2 (-5+SQR(-9))/(3-SQR(-4)) の計算

DIM n3(-szRt TO szRt),nm5(-szRt TO szRt) !定数
CALL SqSetN(3, n3) !n3=3
CALL SqSetN(-5, nm5) !nm5=-5

DIM cm4(-szRt TO szRt),cm9(-szRt TO szRt) !定数
CALL SqSet(-4, cm4) !cm4=SQR(-4)
CALL SqSet(-9, cm9) !cm9=SQR(-9)

CALL SqAdd(nm5,cm9, T1) !T1=-5+SQR(-9)
CALL SqSub(n3,cm4, T2) !T2=3-SQR(-4)
CALL SqDiv(T1,T2, T3) !T3=(-5+SQR(-9))/(3-SQR(-4))

CALL SqPrint(T3) !結果


END
 

絵定義に関して

 投稿者:sukehiro  投稿日:2009年 6月21日(日)07時56分21秒
返信・引用
  Microsoft BASIC互換モードに於いて、

xbase=100:ybase=100
draw enban1
draw enban1 with rotate(0.2)*scale(2)

picture enban1
  circle(xbase+100,ybase+100),100,4
  line(xbase,ybase)-(xbase+100,ybase+100),5
end picture

を実行すると、
with rotate(0.2)*scale(2)が無視されます。
特にエラーにはなりません。

Microsoft BASIC互換モードに於いて、大部分の、標準BASICモードの命令記述で動作するのですが、本事例につては、動作不可なのでしょうか。
 

Re: 絵定義に関して

 投稿者:白石 和夫  投稿日:2009年 6月21日(日)11時03分51秒
返信・引用  編集済
  > No.415[元記事へ]

Microsoft BASIC互換モードで有効なCIRCLE文は,Full BASICの命令ではないので,
絵定義の内部で使われることを考慮していません。
Full BASIC互換を意識した独自拡張命令のDRAW CIRCLE文は変換に対応します。
なお,Full BASIC規格に含まれる命令には図形変形の影響を受けると定められたものと
影響を受けないと定められたものがあります。図形変形の影響を受ける命令は機能語
PLOTと機能語GETを含むもののみです。
http://hp.vector.co.jp/authors/VA008683/G_COMMANDS.htm
を参考にしてください。
 

Re: 座標軸描画のバグ

 投稿者:白石 和夫  投稿日:2009年 6月22日(月)17時18分41秒
返信・引用
  > No.405[元記事へ]

> (1) GRID(p,q),AXES(p,q),GRID0(p,q),AXES0(p,q)で一方の引数を0にすると横軸縦軸ともに目盛りが描かれない。
 仕様です。
 本来であれば続行可能例外とすべきところですが,無条件に無視して先に進みます。


> (2) GRID(p,q),AXES(p,q)で特定の数値を設定すると右端,上端の数字が描かれない。
> 10 LET a=23  ! a=41,46,51,82,87,92,97,…
> 20 LET b=1   ! b=2,4,8,11,13,16,21,22,26,27,…
> 30 SET WINDOW -a,a,-b,b
> 40 DRAW GRID(a/5,b/10)
> 50 END
 数字だけの問題でなく,格子自体の描画が欠落していました。

> (3) GRID(p,q),AXES(p,q)でy座標の領域の幅をごく小さく設定すると、描かれないはずのx軸の数字が上端に描画されることがある。
> 10 LET c=.0000001
> 20 SET WINDOW -5,5,7-c,7
> 30 DRAW GRID(1,c/10)
> 40 END
 Windowsの座標系に縮小するアルゴリズムがWindowsの実際の動作に適合しないのが原因のようです。
 

Re: 座標軸描画のバグ

 投稿者:白石 和夫  投稿日:2009年 6月22日(月)18時25分16秒
返信・引用
  > No.412[元記事へ]

> SET WINDOW -500,500,-500,500
> LET phi=(1+SQR(5))/2 !黄金比
> LET a=2*PI*phi !黄金角
> LET r=1
> LET th=0
> FOR i=0 TO 900
>    LET r=1.1*r !らせん状
>    LET th=th+a
>    LET x1=r*COS(th)
>    LET y1=r*SIN(th)
>    !DRAW disk WITH SCALE(r*0.3)*SHIFT(x1,y1)
>    DRAW circle WITH SCALE(r*0.3)*SHIFT(x1,y1)
> NEXT i
> END
>  Meの場合、OSのDIBENG.DLLでエラーとなりBASICが強制終了となる。

Win Meの場合,Windowsの座標系に許される範囲外の座標値を指定すると
DIBENG.DLLでエラーになるようです。
とりあえず,GDI座標系の範囲外の数値が渡らないようにしてみます。
 

Re: 座標軸描画のバグ

 投稿者:荒田浩二  投稿日:2009年 6月24日(水)22時14分51秒
返信・引用
  > No.417[元記事へ]

対処していただきありがとうございます。

>> (1) GRID(p,q),AXES(p,q),GRID0(p,q),AXES0(p,q)で一方の引数を0にすると横軸縦軸ともに目盛りが描かれない。
> 仕様です。
> 本来であれば続行可能例外とすべきところですが,無条件に無視して先に進みます。

y=tan(x)のグラフ描画で DRAW GRID(PI/2,0) という座標軸がほしかったので無理なお願いをしました。
独自の対策として、座標設定より大きな数値を引数に取れば目盛りは描画されないので DRAW GRID(PI/2,100) とし目的を達しました。
一般的には次の絵定義grid2で描画可能です。

SET WINDOW -5,5,-5,5
DRAW grid2(0,1)
END
EXTERNAL PICTURE grid2(p,q)
ASK WINDOW x1,x2,y1,y2
IF p<>0 THEN LET a=p ELSE LET a=2*(ABS(x1)+ABS(x2))
IF q<>0 THEN LET b=q ELSE LET b=2*(ABS(y1)+ABS(y2))
DRAW GRID(a,b)
END PICTURE
 

3D曲線 を、マウスで、ひっくり返す

 投稿者:SECOND  投稿日:2009年 6月27日(土)18時52分20秒
返信・引用
  ! 3D曲線 を、マウスで、ひっくり返す。
! サンプルに、見づらい Hodgkin-Huxley 方程式 のグラフを、使用。
!-------------------------------
OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES
DIM pV(4), P3D(4,4), LH(6), copy(0 TO 100000, 3)
DIM rotx(4,4), shxyzM(4,4), shxyzP(4,4)
MAT rotx=IDN
MAT shxyzM=IDN
MAT shxyzP=IDN
!
!-----
LET t$="ヤリイカの巨大神経(カオス)"
LET t2$="Hodgkin-Huxley ホジキン−ハクスレイ方程式 のストレンジ アトラクタ"

DEF I(t)= I0+A*SIN( 360*f*t ) ! 膜電流 +外部入力

LET t3$="膜電位 V →( X)"
! (d V/dt)= I(t)-120*m^3*h*(V-115) -40*n^4*(V+12) -.24*(V-10.613)
LET t4$="ナトリウム 活性化変数( 0< m< 1) →( Y)"
! (d m/dt)= .1*(25-V)/(EXP((25-V)/10)-1)*(1-m) -4*EXP(-V/18)*m
LET t5$="ナトリウム不活性化変数( 0< h< 1) →( Z)"
! (d h/dt)= .07*EXP(-V/20)*(1-h) -1/(EXP((30-V)/10)+1)*h
!            カリウム活性化変数( 0< n< 1) →描画しない。
! (d n/dt)= .01*(10-V)/(EXP((10-V)/10)-1)*(1-n) -.125*EXP(-V/80)*n

SUB Dxyzn( kx,ky,kz,kn, x,y,z,n)
   LET kx= I(t)-120*y^3*z*(x-115) -40*n^4*(x+12) -.24*(x-10.613) ! (d V/dt)
   LET ky= .1*(25-x)/(EXP((25-x)/10)-1)*(1-y) -4*EXP(-x/18)*y    ! (d m/dt)
   LET kz= .07*EXP(-x/20)*(1-z) -1/(EXP((30-x)/10)+1)*z          ! (d h/dt)
   LET kn= .01*(10-x)/(EXP((10-x)/10)-1)*(1-n) -.125*EXP(-x/80)*n! (d n/dt)
END SUB

LET I0=20   !膜電流 パラメーター
LET A=40
LET f=.3000001
!
LET x=6.24  !初期値 x,y,z,n
LET y=.0761
LET z=.301
LET n=.519
LET dt=.05  !RungeKutta pitch time
LET t99=500 !RungeKutta close time
DATA -15,100, -.3,1, -.04,.45 !座標軸の両端座標 xL,xH, yL,yH, zL,zH
MAT READ LH
LET zox=35  !回転 旋回中心点 center へのオフセットxyz
LET zoy=.6
LET zoz=.2
!
LET Sx=1    !スケール倍率 Sx,Sy,Sz
LET Sy=50
LET Sz=200
LET xm=35   !画面中心 xm,ym
LET ym=35
LET hw=80   !画面幅/2 ±hw
!
LET ax=-75  !z軸をx軸で倒す開始角度
LET ay=0    !z軸をy軸で倒す開始角度
LET SS=0    !z軸 回転開始角度
LET ST= +5  !z軸 回転ステップ +:左回転 -:右回転
!
SET WINDOW xm-hw,xm+hw,ym-hw,ym+hw
CALL graph3D


!-----
SUB RungeKutta
   CALL Dxyzn( kx1,ky1,kz1,kn1, x,y,z,n)
   CALL Dxyzn( kx2,ky2,kz2,kn2, x+kx1*dt/2,y+ky1*dt/2,z+kz1*dt/2,n+kn1*dt/2)
   CALL Dxyzn( kx3,ky3,kz3,kn3, x+kx2*dt/2,y+ky2*dt/2,z+kz2*dt/2,n+kn2*dt/2)
   CALL Dxyzn( kx4,ky4,kz4,kn4, x+kx3*dt  ,y+ky3*dt  ,z+kz3*dt  ,n+kn3*dt  )
   LET x=x+(kx1+2*kx2+2*kx3+kx4)*dt/6
   LET y=y+(ky1+2*ky2+2*ky3+ky4)*dt/6
   LET z=z+(kz1+2*kz2+2*kz3+kz4)*dt/6
   LET n=n+(kn1+2*kn2+2*kn3+kn4)*dt/6
END SUB

SUB graph3D
! 回転 旋回中心点 center を 原点へ移動し、又、元へ戻す行列。
!(x,y,z,1)|      1,      0,      0, 0 |
!         |      0,      1,      0, 0 |
!         |      0,      0,      1, 0 |
!         |-zox*Sx,-zoy*Sy,-zoz*Sz, 1 |
   LET shxyzM(4,1)=-zox*Sx
   LET shxyzM(4,2)=-zoy*Sy
   LET shxyzM(4,3)=-zoz*Sz
   !
   !(x,y,z,1)|      1,      0,      0, 0 |
   !         |      0,      1,      0, 0 |
   !         |      0,      0,      1, 0 |
   !         | zox*Sx, zoy*Sy, zoz*Sz, 1 |
   LET shxyzP(4,1)=zox*Sx
   LET shxyzP(4,2)=zoy*Sy
   LET shxyzP(4,3)=zoz*Sz
   !
   LET az=SS
   CALL rot_panel
   !---3D 曲線、1回目で、3D原画 記録を撮る。
   LET ci=0
   FOR t=0 TO t99 STEP dt
      LET copy(ci,1)=x
      LET copy(ci,2)=y
      LET copy(ci,3)=z
      ! PRINT x;y;z;n ! データーを保存したい時。
      CALL line3D(x,y,z)
      CALL RungeKutta
      LET ci=ci+1
   NEXT t
   !----
   MOUSE POLL m_x,m_y,mlb,mrb
   LET mxbak=m_x
   LET mybak=m_y
   DO
      IF mlb=0 THEN LET az=MOD(az+ST,360) ! z軸で、1ステップ回す。
      SET DRAW mode hidden
      CALL rot_panel
      !---3D 曲線、2回目以降は、記録の再生で、高速描画。
      FOR ci=0 TO ci-1
         CALL line3D( copy(ci,1),copy(ci,2),copy(ci,3) )
      NEXT ci
      SET DRAW mode explicit
      !----
      MOUSE POLL m_x,m_y,mlb,mrb
      IF mlb=1 THEN
         LET ax=ax -(m_y-mybak)!/2 ! 変移方向は、+90度 回す。
         LET ay=ay +(m_x-mxbak)!/2
      END IF
      LET mxbak=m_x
      LET mybak=m_y
      ! WAIT DELAY 0.05
   LOOP UNTIL mrb=1
END SUB

SUB rot_panel
   LET ar0=SQR(ax^2+ay^2) ! 旋回角度
   IF ar0<>0 THEN LET DIRar0=ANGLE(ax,ay) ! 旋回軸の方向
   IF 180< ar0 THEN
      LET ax=(ar0-360)*COS(DIRar0)
      LET ay=(ar0-360)*SIN(DIRar0)
   END IF
   ! xy平面上、0度方向(x軸)を、軸として旋回する行列 rotx
   !(x,y,z,1)| 1,        0,        0, 0 |
   !         | 0, cos(ar0), sin(ar0), 0 |
   !         | 0,-sin(ar0), cos(ar0), 0 |
   !         | 0,        0,        0, 1 |
   LET rotx(2,2)=COS(ar0)
   LET rotx(3,2)=-SIN(ar0)
   LET rotx(2,3)=SIN(ar0)
   LET rotx(3,3)=COS(ar0)
   !
   MAT P3D= shxyzM*ROTATE(az-DIRar0)*rotx*ROTATE(DIRar0)*shxyzP !変形指示MAT
   !----
   CLEAR
   PLOT TEXT,AT xm-hw*.9,ym+hw*.90 :t2$
   PLOT TEXT,AT xm-hw*.9,ym+hw*.83 :t$
   PLOT TEXT,AT xm+hw*.1,ym+hw*.83,USING"Ax=####  Ay=####  Az=####":ax,ay,az
   PLOT TEXT,AT xm-hw*.9,ym-hw*.92 :t5$
   PLOT TEXT,AT xm-hw*.9,ym-hw*.99 :t4$& "  "& t3$ ! PEN-off
   !---
   IF ar0< 90 THEN SET AREA COLOR "cyan" ELSE SET AREA COLOR "black"
   DRAW disk WITH SCALE(15)*P3D ! 原点近傍、裏表 のマーカー1
   DRAW disk WITH SCALE(5)*SHIFT(zox*Sx,zoy*Sy)*P3D ! マーカー2
   CALL axes3D( zox,zoy,0, zox,zoy,zoz, "center" ) ! マーカー3
   !---座標軸
   CALL axes3D( LH(1),0,0, LH(2),0,0, STR$(LH(2))& "( X)" )
   CALL axes3D( 0,LH(3),0, 0,LH(4),0, STR$(LH(4))& "( Y)" )
   CALL axes3D( 0,0,LH(5), 0,0,LH(6), STR$(LH(6))& "( Z)" )
END SUB

SUB axes3D(x1,y1,z1, x2,y2,z2, a$ )
   CALL line3D(x1,y1,z1)
   CALL line3D(x2,y2,z2)
   PLOT TEXT,AT pV(1),pV(2) :a$ ! PEN-off
END SUB

SUB line3D(x,y,z)
   LET pV(1)=x*Sx  !描画目盛は、全方向等しくないと、回転で、形が保てない。
   LET pV(2)=y*Sy  !スケール Sx,Sy,Sz の違いは、入力の倍率として、行なう。
   LET pV(3)=z*Sz  !入力 z 座標は 出力 x,y に反映。出力zは 描画不可。
   LET pV(4)=1 ! shxyzM …shxyzP で必要。
   MAT pV=pV*P3D
   PLOT LINES: pV(1),pV(2); ! PEN-on
END SUB

END

!-----
!1)画面に写るxyz軸の、z軸に平行で、
!  center を通る軸で、常時回転。
!
!2)マウス 左ボタン押下で 一時停止、離すと再開。
!      右ボタン押下で 終了。
!
!3)左ボタン押下のまま、引きずると、
!  xy平面に平行で、center を通る
!  任意な方向の軸で、全体が旋回する。
!
! (z軸 先端を、ドラッグする感じ。)
!
!※ここまで 貼り付けて、実行時のヘルプにする。
 

対数の計算

 投稿者:山中和義  投稿日:2009年 6月29日(月)19時47分16秒
返信・引用  編集済
  ・同じ底での加減算と整数倍

未サポート
・異なる底での加減算と整数倍、乗除算
!対数の計算

!自然数nを、素因数分解 n=2^a*3^b*5^c* … とすると、
!LOG(n)=LOG(2^a*3^b*5^c* … )=a*LOG(2)+b*LOG(3)+c*LOG(5)+ … となる。
!真数が同じ素数のものを同類項としてまとめることができる。

OPTION ARITHMETIC RATIONAL

LET szLg=100 !扱う対数の範囲 ※必要に応じて変更のこと
LET cBASE=2 !仮の底 ※正の実数 a≠1 をとる

!演算関連
SUB LogSet(n, a()) !a=LOG(n)とする
   IF n<=0 OR INT(n)<>n THEN
      PRINT "非負の整数ではありません。"; n
      STOP
   END IF

   MAT a=ZER

   LET x=n !素因数分解 n=2^a*3^b*5^c* …
   LET m=2
   DO WHILE x>1 !1まで繰り返す
      LET K=0
      DO WHILE MOD(x,m)=0 !mで割り切れるなら(mは因数)
         LET x=x/m !割り切れるまで(m^Kの形)
         LET K=K+1
      LOOP

      LET a(m)=K !m^K ※ … + K*LOG(m) + …

      IF m>2 THEN !2,3,5,7,9,・・・で調べる
         LET m=m+2
      ELSE
         LET m=m+1
      END if
   LOOP
END SUB
DIM w0(szLg),w1(szLg) !作業用
SUB LogSetQ(x,y, a()) !a=LOG(x/y)、x:整数、y:正の整数 とする
   IF y<=0 OR INT(y)<>y THEN
      PRINT "正の整数を設定してください。"; y
      STOP
   END IF
   CALL LogSet(x, w0) !LOG(x/y)=LOG(x)-LOG(y)
   CALL LogSet(y, w1)
   CALL LogSub(w0,w1, a)
END SUB
SUB LogSetN(n, a()) !a=nとする
   MAT a=ZER
   LET a(cBASE)=n
END SUB

SUB LogAdd(a(),b(), c()) !加算 c=a+b
   MAT c=a+b
END SUB
SUB LogSub(a(),b(), c()) !減算 c=a-b
   MAT c=a-b
END SUB
SUB LogMulN(a(),N, c()) !乗算 c=a*N ※{Log(x)+Log(y)+ … }*N
   MAT c=(N)*a
END SUB
SUB LogDivN(a(),N, c()) !除算 c=a/N ※{Log(x)+Log(y)+ … }*N
   IF N=0 THEN
      PRINT "0では割れません。"
      STOP
   END IF
   MAT c=(1/N)*a
END SUB

!出力関連
SUB LogPrint(a()) !LOG(x)+LOG(y)+ … 形式で表示する
   LET flg=0
   FOR i=1 TO UBOUND(a) !小さい順に
      LET Ai=a(i) !係数
      IF Ai<>0 THEN
         IF flg=1 THEN PRINT " + "; !継続なら

         IF Ai<0 THEN
            PRINT "( ";Ai;") ";
         ELSE
            IF i=cBASE OR Ai<>1 THEN PRINT Ai; !係数が1以外なら
         END IF

         IF i<>cBASE THEN !真数が底以外なら
            IF Ai<>1 THEN PRINT "* "; !係数が1以外なら
            PRINT "Log";STR$(cBASE);"(";i;")";
         END IF
         LET flg=1
      END IF
   NEXT i
   IF flg=0 THEN PRINT " 0";
   PRINT
END SUB
SUB LogPrintQ(a()) !m/n+LOG(x/y) 形式で表示する
   CALL LogPack(a, K,x1,x2)

   IF K<>0 THEN PRINT K; !有理数の部分

   !無理数の部分
   IF x1/x2=1 THEN !真数=1の場合
      IF K=0 THEN PRINT "+ 0";
   ELSEIF x1=1 THEN !真数=1/x2の場合
      PRINT "- Log";STR$(cBASE);"(";x2;")";
   ELSE
      PRINT "+ Log";STR$(cBASE);"(";x1/x2;")";
   END IF
   PRINT
END SUB

!補助ルーチン
DIM b(szLg),c(szLg) !作業用
SUB LogYYY(a(),b(), K) !c=a-b^Kを調べる
   LET K=0 !引いた回数

   FOR i=1 TO UBOUND(b)
      IF b(i)<>0 THEN EXIT FOR !最小の素因数を探す
   NEXT i
   IF i>UBOUND(a) OR a(i)=0 THEN EXIT SUB !共通な素因数がない場合

   LET cSGN=1 !符号
   IF a(i)*b(i)<0 THEN LET cSGN=-1

   MAT c=a
   DO
      IF cSGN>0 THEN MAT c=c-b ELSE MAT c=c+b

      FOR i=1 TO UBOUND(c)
         IF c(i)*a(i)<0 THEN EXIT DO !引きすぎかどうか確認する
      NEXT i

      LET K=K+1
   LOOP
   LET K=cSGN*K

   IF cSGN>0 THEN MAT c=c+b ELSE MAT c=c-b !引き戻し
END SUB
SUB LogPack(a(), K,nn,mm) !1つの項にまとめる a*Log(x)+b*Log(y)+ … =Log(x^a*y^b* … )
   IF INT(cBASE)=cBASE THEN !整数なら
      CALL LogSet(cBASE, b) !底を素因数分解する
   ELSE
      CALL LogSetQ(NUMER(cBASE),DENOM(cBASE), b)
   END IF
   CALL LogYYY(a,b, K) !真数=底^K ?

   IF K=0 THEN
      CALL LogYYY(b,a, K) !底と真数をひっくり返す。底=真数^K ?
      IF k<>0 THEN LET K=1/K
   END IF

   IF K<>0 THEN MAT a=c


   LET nn=1 !分子
   LET mm=1 !分母
   FOR i=1 TO UBOUND(a) !真数を1つにまとめる
      IF a(i)<0 THEN !係数が負なら、分母へ
         LET mm=mm*i^ABS(a(i))
      ELSE
         LET nn=nn*i^a(i)
      END IF
   NEXT i


   IF nn<>1 AND mm=1 THEN !真数が1より大きな整数なら
      FOR i=1 TO UBOUND(b) !底
         IF b(i)<>0 THEN
            IF a(i)=0 THEN !共通素因子がなければ
               LET K1=0
               EXIT FOR
            END IF
            LET K1=a(i)/b(i) !底=真数^K1 ?
         END IF
      NEXT i
      IF K1<>0 THEN
         LET K=K+K1
         LET nn=1
      END IF
   END IF

   !!!PRINT "K=";K; "nn=";nn; "mm=";mm !debug
END SUB
!------------------------------ ここまでがサブルーチン

DIM T1(szLg),T2(szLg),T3(szLg),T4(szLg) !作業用


!●例1 LOG(2/3)+LOG(12/25)-LOG(8/15) = LOG(3)-LOG(5) = LOG(3/5) の計算

LET cBASE=2 !底

CALL LogSetQ(2,3, T1) !T1=LOG(2/3)
CALL LogSetQ(12,25, T2) !T1=LOG(12/25)
CALL LogAdd(T1,T2, T1)
CALL LogSetQ(8,15, T2) !T1=LOG(8/15)
CALL LogSub(T1,T2, T1)

!!!MAT PRINT T1; !debug
CALL LogPrint(T1)
CALL LogPrintQ(T1)



!●例2 LOG10(7/4)-LOG10(9)-2*LOG10(5/3)-LOG10(49)/2 = -2 の計算

LET cBASE=10 !底

CALL LogSetQ(7,4, T1) !T1=LOG(7/4)
CALL LogSet(9, T2) !T2=LOG(9)
CALL LogSub(T1,T2, T1)

CALL LogSetQ(5,3, T2) !T2=LOG(5/3)
CALL LogMulN(T2,2, T2)
CALL LogSub(T1,T2, T1)

CALL LogSet(49, T2) !T2=LOG(49)
CALL LogDivN(T2,2, T2)
CALL LogSub(T1,T2, T1)

!MAT PRINT T1; !debug
CALL LogPrint(T1)
CALL LogPrintQ(T1)



!●例3 LOG27(1/9) = -2/3 の計算

!LET cBASE=9
LET cBASE=27

!CALL LogSetQ(1,3, T1)
CALL LogSetQ(1,9, T1)
!MAT PRINT T1; !debug
CALL LogPrint(T1)
CALL LogPrintQ(T1)


END
 

循環小数の計算

 投稿者:山中和義  投稿日:2009年 7月 2日(木)10時50分2秒
返信・引用  編集済
  循環小数を分数に変換して、分数どうしで計算する。結果を循環小数に戻す。
変換する関数をつくれば、有理数モードで計算できる。
OPTION ARITHMETIC RATIONAL

LET MaxLevel=200 !循環節の最大桁数
DIM s(MaxLevel) !循環節の候補


!●循環小数を分数へ

!筆算
! x=0.1[23]
! 100*x-x=12.3[23]-0.1[23]=12.2 ∴99*x=122/10 ∴x=61/495

!LET x$="2.2[234]" !2.2234234234…
!LET x$="0.0[90]" !0.0909090…
!LET x$="0.[142857]" !0.142857142857…
LET x$="0.1[23]" !0.1232323…

PRINT ExVAL(x$)



!● 0.1[23] ÷ 0.[14] の結果を循環小数で表せ。 答え 0.8[714285]

LET t=ExVAL("0.1[23]") / ExVAL("0.[14]")
PRINT t, ExSTR$(t)


FUNCTION ExVAL(x$) !数値を表現する文字列を数値に変換する
   LET L=LEN(x$) !文字列長を得る

   LET p=0 !有限小数の桁数
   LET k=0 !循環節の桁数。有限小数の場合、0
   LET A=0
   LET cSGN=1 !符号
   LET flag=0 !「整数」 ※数値の型

   LET i=1 !数字列の読み込み位置
   DO WHILE i<=L !上位の桁から順に
      LET t$=UCASE$(x$(i:i))
      IF t$="." THEN !小数点なら
         IF flag<>0 THEN
            PRINT "小数点の位置が不正です。"; x$
            STOP
         END IF
         LET flag=1 !「有限小数」
      ELSEIF t$="+" THEN !+符号なら
         IF i<>1 THEN
            PRINT "+符号の位置が不正です。"; x$
            STOP
         END IF
      ELSEIF t$="-" THEN !−符号なら
         IF i<>1 THEN
            PRINT "−符号の位置が不正です。"; x$
            STOP
         END IF
         LET cSGN=-1
      ELSEIF t$="[" THEN !循環小数なら
         IF flag<>1 THEN !小数部か?
            PRINT "循環小数の開始位置が不正です。"; x$
            STOP
         END IF
         LET flag=2 !「循環小数」
      ELSEIF t$="]" THEN
         IF i<>L THEN !右端か?
            PRINT "循環小数の終了位置が不正です。"; x$
            STOP
         END IF
      ELSE
         LET A=A*10+VAL(t$) !多項式(( … ((a[1]*10+a[2])*10+a[3])*10 … +a[i-2])*10+a[i-1])*10+a[i] ※左シフト
         IF flag=1 THEN LET p=p+1
         IF flag=2 THEN LET k=k+1
      END IF

      LET i=i+1 !次へ
   LOOP

   !PRINT A; flag;cSGN;p;k !debug
   IF flag<2 THEN !有限小数(整数も含む)の場合
      LET ExVAL=cSGN * A/10^p
   ELSE !循環小数の場合
      LET B=INT(A/10^k)
      LET ExVAL=cSGN * (A-B)/(10^(k+p)-10^p)
   END IF
END FUNCTION

FUNCTION ExSTR$(x) !数値式を表示するときの文字列に変換する
   LET a=ABS(x)


   !整数部
   LET aa=INT(a) !小数部を削除する

   LET b$="" !変換後の数

   DO WHILE aa>=10
      LET b$=STR$(MOD(aa,10))&b$ !a=b[k]*10^k+b[k-1]*10^(k-1)+ … +b[1]*10^1+b[0]*10^0より

      LET aa=INT(aa/10) !次の桁へ ※右シフト
   LOOP
   LET b$=STR$(aa)&b$


   !小数部
   LET aa=a-INT(a) !整数部を削除する

   LET k=1 !小数桁

   DO UNTIL aa=0 !小数第1位から順に
      IF k=1 THEN !初回のみ
         LET b$=b$&"." !小数点をつける
         LET p=POS(b$,".")
      ELSE
         FOR i=1 TO k-1 !循環したか確認する
            IF s(i)=aa THEN !循環節
               LET b$(i+p:i+p)="["&b$(i+p:i+p) !開始記号を挿入
               LET b$=b$&"]" !終了記号
               EXIT DO
            END IF
         NEXT i
      END IF
      LET s(k)=aa

      LET aa=aa*10 !左シフト
      LET b$=b$&STR$(INT(aa)) !a=S[-1]*10^(-1)+S[-2]*10^(-2)+ … +S[-(k-1)]*10^(-(k-1))+S[-k]*10^(-k)より

      LET aa=aa-INT(aa) !整数部分を削除して、次の桁へ

      LET k=k+1
      IF k>MaxLevel THEN !循環小数によるループを回避する
         PRINT "変換を打ち切りました。"
         EXIT DO
      END IF
   LOOP

   IF x<0 THEN LET ExSTR$="-"&b$ ELSE LET ExSTR$=b$ !….…形式
END FUNCTION

END
 

希望

 投稿者:SECOND  投稿日:2009年 7月 2日(木)17時08分35秒
返信・引用
  最近、頻繁に JWORD のウィンドウが現れ、例え干渉せずにブラウザを閉じても、
下の様な2本のクッキーが、作られます。
できれば、先生の大学内に、掲示板を設けて頂く事は、出来ないでしょうか。

nec-pcuse@soft[?].txt
    jwd_c_APcommon, 9199_teacup, download.jword.jp/soft/
    1024, 4055316224, 30014381, 3363342720, 30014180, *

nec-pcuse@flt2[?].txt
    9199_teacup_9199_teacup_001, 1, download.jword.jp/pub/flt2/
    1024, 1083495936, 30014784, 3290842720, 30014180, *
 

Re: 希望

 投稿者:白石 和夫  投稿日:2009年 7月 2日(木)20時50分12秒
返信・引用
  > No.423[元記事へ]

通常のWebページも管理が容易でないため外部の資源に頼っています。
掲示板開設に必要な条件が整っているのかどうかもわかりません。

とりあえず,掲示板閲覧に Mozilla Firefoxを使ってみてください。
Mozilla Firefoxを掲示板閲覧専用に使っていますが,快適です。
 

Re: 循環小数の計算

 投稿者:山中和義  投稿日:2009年 7月 3日(金)15時27分2秒
返信・引用  編集済
  > No.422[元記事へ]

おおげさに考えずに、、、
!問 0.1[23] ÷ 0.[14] の結果を循環小数で表せ。 答え 0.8[714285]

OPTION ARITHMETIC RATIONAL


!●循環小数を分数に変換する筆算
! 有限小数(整数も含む)の部分
!  循環節までの部分 ※小数部分の桁数を「有限小数の桁数」とする。
! 循環小数の部分
!  分子: 循環節
!  分母: repeat$("9",循環節の桁数) & repeat$("0",有限小数の桁数)
!
! 例. 12.345[6789] の場合、12.345+6789/9999000 となる。

LET a=0.1+23/990 !上記に従って、式を組み立てる
LET b=0.+14/99
PRINT a; b; a/b
PRINT USING "#.###############################": a/b


!●無限等比級数の和を使って分数に変換する
! 例. 12.345[6789] の場合、12.345+0.0006789/(1-1/10^4) となる。
!  0.0006789: 最初の循環節を小数表現
!  4: 循環節の桁数
! ∵循環小数の部分は
!   0.0006789
!   +0.00000006789
!   +0.000000000006789
!   + ・・・ 、すなわち、初項0.0006789,公比1/10^4=0.0001の無限等比級数

LET a=0.1+0.023/(1-1/10^2)
LET b=0.+0.14/(1-1/10^2)
PRINT a; b; a/b
PRINT USING "#.###############################": a/b

END
 

Re: 希望

 投稿者:なかむら  投稿日:2009年 7月 4日(土)08時47分17秒
返信・引用
  > No.424[元記事へ]

余談ですが、(WinのVerによってはお使いになれないかもしれませんが)

Webブラウザを複数インストールしたくない(IEをプライマリで
つかっていてその他のブラウザを入れたくない場合など)は Firefox の
Portable版を利用するという手もあります。

基本的に、適当なフォルダを作ってそこにプログラムをコピー
(インストーラがその作業を行ってくれますが)すれば
そのフォルダ内で完結して動作し、削除するときもフォルダ
ごと消すだけ、というものです(PCの各種設定を汚しません)。

以下ご参考。(窓の杜の記事)
http://www.forest.impress.co.jp/article/2008/06/20/firefoxportable3.html

ダウンロードはこちらからできます。
http://portableapps.com/apps/internet/firefox_portable/localization

Firefoxを試すだけ、という場合に便利かもしれません。
 

Re: 希望

 投稿者:SECOND  投稿日:2009年 7月 4日(土)19時13分40秒
返信・引用  編集済
  > No.426[元記事へ]

お気遣い、とてもありがとうございます。

実は、私自身の為ではなく、最近、投稿者が減少している感が非常に強く、その原因に
なってはしないかと、心配しておりました。「おおげさ」なようで・・すね。
 

白石先生へ

 投稿者:SECOND  投稿日:2009年 7月 6日(月)03時18分45秒
返信・引用  編集済
  白石先生へ
御世話になります。complex\ sin_2.BAS 外部例外 ご返事の件の 環境 詳細です。
「拡大する枠」までは、かなりな頻度で、行けるのですが、その先で、止まります。

<システムのプロパティ> のコピー。
全般                        <仮想メモリ>
システム :                ハードディスク: C:\4417MB の空き
   Microsoft Windows 98             最小: 128 MB
   Second Edition                           最大: 最大値なし
   4.10.2222 A
製造およびサポート元 :
   NEC
   LaVie
   GenuineIntel
   x86 Family 6 Model 8 Stepping 1
   255.0MB の RAM


<追記>
先頃、外部例外のご報告を、先生にお送りした所、次の様なご返事を頂きました。
ご協力、おねがいします。

-------------------------
ご報告ありがとうございます。
complex\ sin_2.BAS は,DEF文での(BASICの)例外を頻繁に起こさせるプログラムです。
十進BASICは例外が起こるたびごとに例外に関係した情報を動的に確保されるメモリ上に保存します。
そのメモリは不要になると解放されるのですが,メモリの断片化のために必要以上の(Windowsの)仮想
メモリを消費する可能性があります。
Windowsの仮想メモリの拡張がうまくいかず,例外0EとしてBASICに戻されているように思います。
Windowsの仮想メモリの設定にもディスクの残量にも問題がないようでしたら,
原因の特定には同じ現象を起こす環境を特定する必要があるので,
OSのバージョン情報とともに掲示板に書き込んでいただけないでしょうか。
 

Re: 白石先生へ

 投稿者:白石 和夫  投稿日:2009年 7月 6日(月)10時36分57秒
返信・引用
  > No.428[元記事へ]

「拡大する枠」までは正常に動作し,「拡大する枠」の直後に問題が起こるのであれば,
ディスプレー・ドライバの問題の可能性もあるので,Windowsのコントロールパネルの「画面のプロパティ」の「トラブルシューティング」でハードウェアアクセラレータの目盛りを下げてみてください。
 

Re: 白石先生へ

 投稿者:SECOND  投稿日:2009年 7月 6日(月)17時27分8秒
返信・引用  編集済
  > No.429[元記事へ]

アクセラレーターを、止めると、症状が、消えました。 ディスプレイドライバーは、
RAGE MOBILITY PCI (日本語) バージョン:4.12.2083 製造元 :ATI Tech. - Enhanced
ですが、止めてしまうと、他に支障があるため、下の様にして、しのいでいます。
 すみません。ありがとうございました。

しきい値の、710 は、ギリギリ一杯なので、709 にしました。

FOR u= left TO right STEP (right-left)/px
   FOR v = bottom TO top STEP (top-bottom)/py
      LET Lambda=COMPLEX(u,v)
      LET z=0.5             ! 初期値
      FOR n = 1 TO 250
         IF ABS(i*z)< 710 THEN LET z=lambda*sin(z) ELSE EXIT FOR !桁あふれ防止
      NEXT n
      IF 250< n THEN PLOT POINTS: u,v
   NEXT v
NEXT u


<<追記>>
やはり、アクセラレーターを、止めても、頻度は少ないですが、
「例外 0E が、0028:C0059CA9 で発生しました。」で、終ってしまいます。
上の差替え文では、確実に動くのですが・・

WinXP などで、何事もなければ、この問題は、Win98SE 以前のバグのようでもあり、
追跡は、割愛してください。ありがとうございました。
 

Re: 循環小数の計算

 投稿者:荒田浩二  投稿日:2009年 7月 6日(月)20時22分7秒
返信・引用
  > No.422[元記事へ]

山中和義さんの FUNCTION ExSTR$(x) で分数を循環小数に変換するループを拝見し、これを10進15桁モードではできないかと思い立ち作ってみました。
計算過程は筆算と同じです。分母をnとすれば、n-1桁までで割り切れるか同じ余りが現れるかです。
計算結果の桁数に制限はないのです(真値が求まります)が、分母の大きさで配列sを宣言しているため、分母が大きすぎるとエラーになります。
1000桁モード,有理数モードでも実行できます。(2進モードでは小数で誤差が出てしまう)

DECLARE EXTERNAL FUNCTION Ex2STR$ ! 分数を小数,循環小数の文字列に変換する関数
DO
   READ IF MISSING THEN EXIT DO : x$
   PRINT x$ ; "  入力数値"
   CALL fraction(x$,a,b)  ! 整数,有限小数,循環小数,分数の文字列(x$)を既約分数(a/b)に変換
   IF a>=0 THEN LET m$=" " ELSE LET m$=""
   IF b=1 THEN LET f$=STR$(a) ELSE LET f$=STR$(a)&"/"&STR$(b)
   PRINT m$&f$ ; "  分数表示"
   PRINT a/b ; " 小数15桁表示"
   PRINT m$&Ex2STR$(a,b) ; "  小数真値[循環節]表示" ! 分数(a/b)を小数,循環小数の文字列に変換
   PRINT
LOOP

DATA "-18" , "47." , "-12.34" , "-.67" , "+972.[51]" , "-73.482[3058]"
DATA "0.000[217]" , "+6.0054[83]" , ".031[040]" , "-78/13" , "0/26" , "740.52/29.84"
DATA "634517/3637" , "24/56" , "-5/12" , "91/35" , "886240513930735/10485760"

END


EXTERNAL SUB fraction(x$,numer,denom) ! x$を分数numer/denomに変換
LET dec$=LTRIM$(RTRIM$(x$))
IF dec$(1:1)="-" THEN LET s=-1 ELSE LET s=1
IF dec$(1:1)="+" OR dec$(1:1)="-" THEN LET dec$=dec$(2:LEN(dec$))

LET sp=POS(dec$,"/")
IF sp>1 THEN ! 分数
   LET numer=VAL(dec$(1:sp-1))
   LET denom=VAL(dec$(sp+1:LEN(dec$)))
   CALL reduce(numer,denom) ! 約分
   LET numer=s*numer
   EXIT SUB
END IF

LET dp=POS(dec$,".")
IF dp=0 OR dp=LEN(dec$) THEN ! 整数
   LET numer=s*VAL(dec$)
   LET denom=1
   EXIT SUB
END IF

IF dp=1 THEN LET intp=0 ELSE LET intp=VAL(dec$(1:dp-1)) ! 整数部
LET rp=POS(dec$,"[")
IF rp=0 THEN  ! 有限小数
   LET dl=LEN(dec$)-dp
   LET denom=10^dl
   LET numer=intp*denom+VAL(dec$(dp+1:LEN(dec$)))
   CALL reduce(numer,denom)
   LET numer=s*numer
   EXIT SUB
END IF

IF rp=dp+1 THEN
   LET dconst=0  ! 例"37.[61]"
   LET dconst_denom=1
   LET dl=0
ELSE
   LET dconst=VAL(dec$(dp+1:rp-1)) ! 小数定数部
   LET dl=rp-dp-1                  ! 小数定数部桁数
   LET dconst_denom=10^dl
   CALL reduce(dconst,dconst_denom)
END IF
LET rl=LEN(dec$)-rp-1                 ! 循環節桁数
LET recur=VAL(dec$(rp+1:LEN(dec$)-1)) ! 循環節
LET recur_denom=10^(LEN(dec$)-dp-2)*(1-1/10^rl)
CALL reduce(recur,recur_denom)

!PRINT intp;dconst;dconst_denom;intp+dconst/dconst_denom
!PRINT recur;recur_denom;recur/recur_denom

!!  intp/1 + dconst/dconst_denom + recur/recur_denom
LET numer=intp*dconst_denom+dconst
CALL reduce(numer,dconst_denom)
LET numer=numer*recur_denom+recur*dconst_denom
LET denom=dconst_denom*recur_denom
CALL reduce(numer,denom)
LET numer=s*numer

END SUB


EXTERNAL FUNCTION Ex2STR$(numer,denom) !分数を小数,循環小数の文字列に変換
!「No.422 循環小数の計算(山中和義氏)」FUNCTION ExSTR$(x) 参照

IF SGN(numer/denom)=-1 THEN LET u$="-" ELSE LET u$=""
LET numer=ABS(numer)
LET denom=ABS(denom)
CALL reduce(numer,denom) ! 約分

!整数部
IF denom=1 THEN
   LET Ex2STR$=u$&STR$(numer)
   EXIT FUNCTION
END IF

DIM s(denom-1) ! 剰余を格納する配列
LET aa=INT(numer/denom) !小数部を削除する
IF aa=0 THEN LET b$="." ELSE LET b$=STR$(aa)&"."

!小数部
LET p=POS(b$,".")
LET numer=MOD(numer,denom) ! 剰余(商=aa)
LET k=1 !小数桁

DO UNTIL numer=0
   FOR i=1 TO k-1 !循環したか確認する
      IF s(i)=numer THEN
         LET b$(i+p:i+p)="["&b$(i+p:i+p) !開始記号を挿入
         LET b$=b$&"]" !終了記号
         EXIT DO
      END IF
   NEXT i
   LET s(k)=numer
   LET b$=b$&STR$(INT(10*numer/denom))

   LET numer=MOD(10*numer,denom)

   LET k=k+1
   IF k>denom THEN ! 配列sの添字オーバーを回避する
      PRINT "変換を打ち切りました。"
      EXIT DO
   END IF
LOOP

LET Ex2STR$=u$&b$
END FUNCTION


EXTERNAL SUB reduce(p,q) ! 約分
!十進BASIC添付 "\BASICw32\Math\GCDLOOP.BAS" 参照
REM 互除法により,入力された2数の最大公約数を求める → その後,約分
LET a=p
LET b=q
DO
   LET r=MOD(a,b)
   IF r=0 THEN EXIT DO
   LET a=b
   LET b=r
LOOP
LET p=p/b
LET q=q/b
END SUB
 

Re: 白石先生へ

 投稿者:白石 和夫  投稿日:2009年 7月 7日(火)10時04分21秒
返信・引用
  > No.430[元記事へ]

広く症例を集めることで,原因がWin98SEにあるのか,それともビデオドライバにあるのか,特定できると思います。そのための掲示板利用です。
(その観点で題名が不適切です)
 

問題を、表面化するプログラムです

 投稿者:SECOND  投稿日:2009年 7月 7日(火)15時31分35秒
返信・引用  編集済
  > No.432[元記事へ]

!すみません。気をつけます。
!問題を、表面化するプログラムです。アクセラレーターを停止しても、
!「例外 0E が、0028:C0059CA9 で発生しました。」 まで、1〜120秒。

DO
   WHEN EXCEPTION IN
      LET w=EXP(12345)
   USE
   END WHEN
   PRINT 12345
LOOP
END

!私の環境:Win98SE, Pentium-3, 500MHz, 256MB, 4GBの空き(HDD),
!     ディスプレイ アダプタ RAGE MOBILITY PCI(日本語)
 

Re: 問題を、表面化するプログラムです

 投稿者:白石 和夫  投稿日:2009年 7月 7日(火)16時37分27秒
返信・引用
  > No.433[元記事へ]

PRINT文がないときは正常に動作しますか?

DO
    WHEN EXCEPTION IN
       LET w=EXP(12345)
    USE
    END WHEN
LOOP
END
 

Re: 問題を、表面化するプログラムです

 投稿者:SECOND  投稿日:2009年 7月 7日(火)17時30分10秒
返信・引用  編集済
  > No.434[元記事へ]

はい、PRINT 文が無ければ、5分以上走れるようです。が、メモ帳などでも、
画面アクセスが、重なると、文中に、PRINT 文が無くても、
「例外 0E が、0028:C0059CA9 で発生しました。」で、BASIC.EXE まで終了します。

<追記>
どうも、一定していないようです。PRINT 文が無い状態で、他の画面も、何もしない
状態でも、繰返している内、90秒くらいで、同様に、「例外 0E が、・・・」に
なっていました。EXP()の例外を、止めない限り出来ないような、感じです。

ご参考、他の関数などは、全く安定です。(sinh,cosh は、exp()と同症状)
DO
   WHEN EXCEPTION IN
      LET w=LOG(-12345) !100000^12345 !1/0 ! EXP(12345)
   USE
   END WHEN
   PRINT 12345
LOOP

※tanh(2e99)、sinh(12345)、cosh(12345)、の結果では、tanh だけが安定でした。
 又、許容入力が、特別に大きく、1e99まで、エラーになりませんが、なぜですか。
 

球体を描くプログラム

 投稿者:9mm  投稿日:2009年 7月 8日(水)02時34分51秒
返信・引用
  三次元座標にたくさん座標をとって球体を作りたいんですが、どんな座標をとれば球体のように見えるんでしょうか?
さらにその球体がバウンドしているようなプログラムを作りたいんですが、可能でしょうか?
まだBASICを習ったばっかりなのであまり難しいことはできません…

ぜひ教えてください。
 

Re: 球体を描くプログラム

 投稿者:白石 和夫  投稿日:2009年 7月 8日(水)07時56分27秒
返信・引用
  > No.436[元記事へ]

球面の描き方は,サンプルプログラムの
SAMPLE\SPHERICA.BAS
を参照してください。
バウンドしているように見せるためには,
描画中は
DRAW MODE HIDDEN
の状態で見せないようにして
描画が終わったら
DRAW MODE EXPLICIT
を実行します。
詳細は,
http://hp.vector.co.jp/authors/VA008683/QA6.htm
にあります。
また,毎度描くと遅くなるので,
ASK PIXEL ARRAY
で画素レベルで記憶し,
MAT PLOT CELLS
で位置をずらして描くことになると思います。
 

Re: 問題を、表面化するプログラムです

 投稿者:白石 和夫  投稿日:2009年 7月 8日(水)08時10分25秒
返信・引用
  > No.435[元記事へ]

ビデオドライバがFPU例外の干渉を受けているのだろうと思います。

十進モードだと,超越関数,無理関数の演算にFPUを使います。
2進モードと複素数モードではすべての演算をFPUで行います。
2進モードか複素数モードで桁あふれエラーを起こすようなプログラムを実行してみてください。

OPTION ARITHMETIC NATIVE
LET i=1
DO
   WHEN EXCEPTION IN
      LET a=2
      DO
         LET a=a*a
      LOOP
   USE
      PRINT i;"回目"
   END WHEN
   LET i=i+1
LOOP
END

なお,NEC PC9801 Win95版
http://www.geocities.jp/thinking_math_education/basicw95.htm
でもテストしてみてください。この版はFPU例外を抑止しています。
 

Re: 球体を描くプログラム

 投稿者:白石 和夫  投稿日:2009年 7月 8日(水)08時59分24秒
返信・引用  編集済
  > No.437[元記事へ]

OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES
LET theta0=-125
LET z0=10
REM z軸のまわりにtheta0度回転したsphreを,
REM 点(0,0,z0)から見たように描く。
DIM p(4,4)         ! 点 0,0,z0を中心とする射影
MAT p=IDN
LET p(3,4)=-1/z0
DIM rotx(4,4)      ! x軸のまわりの-90°回転
MAT rotx=IDN
LET rotx(2,2)=COS(-90)
LET rotx(2,3)=SIN(-90)
LET rotx(3,2)=-SIN(-90)
LET rotx(3,3)=COS(-90)

ASK PIXEL SIZE (0,1;1,0) a,b
DIM sp(a,b)

SET COLOR mode "NATIVE"
SET WINDOW -2, 2, -2, 2

DRAW sphere0 WITH ROTATE(theta0)  * rotx
ASK PIXEL ARRAY (-2,2) sp
FOR t = 0 TO 360*3 STEP 15   ! 球体を3回バウンドさせる
   SET DRAW mode hidden
   CLEAR
   DRAW sphere WITH SHIFT(0,SIN(t))
   SET DRAW mode explicit
NEXT t

PICTURE sphere
   MAT PLOT CELLS ,IN -2,2; 2,-2: sp
END PICTURE

END


! 単位球を描く
EXTERNAL PICTURE sphere0
OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES

DIM sz(4,4),ry(4,4)
MAT READ sz
DATA 1,0,0,0
DATA 0,1,0,0
DATA 0,0,1,0
DATA 0,0,1,1
MAT READ ry
DATA  0, 0,-1, 0
DATA  0, 1, 0, 0
DATA  1, 0, 0, 0
DATA  0, 0, 0, 1
! 球面を描く
SET AREA STYLE "SOLID"
FOR t=0 TO 180
   FOR p=0 TO 359
      LET ry(1,3)=-SIN(t)
      LET ry(3,1)=SIN(t)
      LET ry(1,1)=COS(t)
      LET ry(3,3)=COS(t)
      DRAW Trapezoid(t) WITH sz*ry*ROTATE(p)
   NEXT p
NEXT t

PICTURE Trapezoid(t)      ! tは天頂角
   DIM N(3)
   CALL makeNormal(N)
   IF N(3)>0 THEN     ! 外側が手前なら面を描く
      CALL setBrightness(N)
      PLOT AREA: -PI/360, -SIN(t-0.5)*PI/360; PI/360,-SIN(t+0.5)*PI/360; PI/360,SIN(t+0.5)*PI/360; -PI/360,SIN(t-0.5)*PI/360
   END IF
END PICTURE

END PICTURE

! 変換された座標系における法線ベクトルを求める
EXTERNAL SUB makeNormal(N())
OPTION ARITHMETIC NATIVE
DIM m(4,4),A(4),B(4),C(4)
MAT m=TRANSFORM
MAT READ A
DATA 0,0,0,1
MAT READ B
DATA 1,0,0,1
MAT READ C
DATA 1,1,0,1
MAT A=A*M
MAT B=B*M
MAT C=C*M
MAT A=(1/A(4))*A
MAT B=(1/B(4))*B
MAT C=(1/C(4))*C
MAT REDIM A(3)
MAT REDIM B(3)
MAT REDIM C(3)
MAT A=B-A
MAT B=C-B
MAT N=CROSS(A,B)
END SUB

EXTERNAL SUB setBrightness(N())
OPTION ARITHMETIC NATIVE
DIM A(3)
MAT READ A      ! 光源の向き
DATA -4,5,3
LET s=DOT(A,N)/(SQR(DOT(A,A))*SQR(DOT(N,N)))
LET s=(0.8*s+1)/2
SET AREA COLOR COLORINDEX(s,s,s)
END SUB
 

Re: 問題を、表面化するプログラムです

 投稿者:SECOND  投稿日:2009年 7月 8日(水)09時34分5秒
返信・引用
  > No.438[元記事へ]

ご推察どうり、3600回目ぐらいで、同症状になります。
NEC PC9801 Win95版 では、アクセラレータ最大でも、何の異常もなくなりました。
かといって、Windows自体と異なり 、十進BASIC のバージョン・バックは、したく
ありませんので、文の書き方で、対処していきたいと思っています。たいへんな労力を
おかけし、ありがとうございました。
 

先生のが、むずかしいとき・・

 投稿者:SECOND  投稿日:2009年 7月 8日(水)10時07分26秒
返信・引用
  > No.436[元記事へ]

!カラー・ボール
!-------------------------------
OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES
DIM rotx(4,4)
MAT rotx=IDN

SET WINDOW -10,10,-10,10

! xy平面上の描点を、x軸で回転する行列 rotx
LET ar0=35
!(x,y,z,1)| 1,        0,        0, 0 |
!         | 0, cos(ar0), sin(ar0), 0 |
!         | 0,-sin(ar0), cos(ar0), 0 |
!         | 0,        0,        0, 1 |
LET rotx(2,2)=COS(ar0)
LET rotx(3,2)=-SIN(ar0)
LET rotx(2,3)=SIN(ar0)
LET rotx(3,3)=COS(ar0)

LET r=5 ! 半径5mのカラー・ボール
LET t0=TIME
DO
   LET t=TIME-t0
   SET DRAW mode hidden
   CLEAR
   LET y=5-4.9*t^2 ! 頂点が5mの放物線
   DRAW ball WITH SHIFT(0,y)
   SET DRAW mode explicit
   IF y< -4 THEN LET t0=t0+2*SQR((5+4)/4.9) !( 5m → -4m )時間の2倍で平行移動。
LOOP

PICTURE ball
   FOR i=-r*0.9 TO r*0.9 STEP r*0.1
      SET AREA COLOR MOD(i-0.6, 0.2*r)*5
      DRAW disk WITH SCALE( SQR(r^2-i^2) )*rotx*SHIFT(0, SIN(ar0)*i)
   NEXT i
END PICTURE

END
 

サンプル閲覧ツール

 投稿者:SECOND  投稿日:2009年 7月 8日(水)13時39分57秒
返信・引用  編集済
  ! サンプル閲覧ツール Ver.9
!----------------------------------------------------------
!テキスト・ウィンドウの、左上位置(x0,y0)と、幅(xw,yw)。
CALL SetWindowPos( WinHandle("TEXT" ),0, 10,100,500,550, 0)

SUB SetWindowPos( handle, C2, x0,y0,xw,yw, nFLG ) ! nFLG, 0=x0y0xwyw 1=x0y0 2=xwyw
   ASSIGN "user32.dll","SetWindowPos"
END SUB

!----------------------------------------------------------
SET BITMAP SIZE 501,501
LET V=5 ! 表示列数 3~5
SET WINDOW 0, V, 27,-6
SET AREA COLOR 5
DIM p$(5*V),wild$(5*V),names$(200)

!下の DATA 文は、各フォルダーが配下に見える場所(BASIC.EXE と同じ場所)に
!このプログラムを置いて起動する場合の例。

DATA TEXTFILE\, TUTORIAL\, USERLIB\, COMM\
DATA COMPLEX\,  FRACTAL\, FUNCTION\, GUIDE\
DATA LIBRARY\, MATH\, MICROSFT\, "Q&A\"
DATA SAMPLE\, STATEMEN\, ".\", "C:\My Documents\*.txt"

FOR f=1 TO 25
   READ IF MISSING THEN EXIT FOR: w$
   FILE splitname(w$) p$(f), name$, ext$ ! ext$は語頭に"."含む。
   IF ext$="" THEN LET wild$(f)="*.*" ELSE LET wild$(f)=name$& ext$
NEXT f

LET w=13 !最初に開くフォルダー、1〜?番目
CALL basfiles
OPEN #9 : TextWindow2
ERASE #9
CALL SetWindowPos( WinHandle("TEXTWINDOW2" ),0, 515, 0,509,172, 0)
PRINT #9 :"フォルダーを、選んで"
PRINT #9 :"ファイル名を、左クリックすると、内容表示する。"
PRINT #9 :"※重ねて再度、左クリックすると、(.BAS ならば、)"
PRINT #9 :" BASIC を、新しく起動、実行できます。閉じると、続行。"& CHR$(0)
DO
   MOUSE POLL mx,my,mlb,mrb
   IF mrb=1 THEN EXIT DO !右クリック
   IF mlb=1 THEN !左クリック
      IF -1< my THEN
         IF 0< my THEN LET b=INT(mx)*27+CEIL(my) ELSE LET b=bak+1
         IF b=< n THEN
            IF b<>bak THEN
               CALL sampdisp
            ELSEIF UCASE$(right$(names$(b),4))=".BAS" THEN
               execute "BASIC.EXE" WITH("/NR",p$(m)& names$(b))
            END IF
         END IF
      ELSEIF my< -1 THEN
         LET w=INT(my+6)*V+CEIL(mx)
         IF w< f THEN CALL basfiles
      END IF
      LET i=0
      DO
         WAIT DELAY .02
         MOUSE POLL mx,my,mlb,mrb
         IF mlb=0 AND mrb=0 THEN LET i=i+1 ELSE LET i=0
      LOOP UNTIL 5< i !マウスボタンが離れるまで待つ。
   END IF
   WAIT DELAY 0 !クロックアップを押える
LOOP
PLOT AREA:0,-1;V,-1;V,0;0,0
SET TEXT BACKGROUND "TRANSPARENT" ! background none
PLOT TEXT,AT V*.3,0 :"終了しました。"

SUB basfiles
   LET m=w
   CLEAR
   PLOT AREA:0,-1;V,-1;V,0;0,0
   SET TEXT BACKGROUND "TRANSPARENT" ! background none
   PLOT TEXT,AT V*.17,0 :"ココを左クリックすると順送り。 右クリックで、終了。"
   FOR i=0 TO 4
      FOR j=1 TO V
         LET w=i*V+j
         IF w=m THEN PLOT AREA:j-1,i-5;j,i-5;j,i-6;j-1,i-6
         IF wild$(w)="*.*" THEN LET w$=p$(w) ELSE LET w$=p$(w)& wild$(w)
         PLOT TEXT,AT j-1+0.03,i-5 :w$ !p$(w)& wild$(w)
      NEXT j
   NEXT i
   IF m>0 THEN LET n=files(p$(m)& wild$(m))
   IF n>0 THEN file list p$(m)& wild$(m), names$
   SET TEXT BACKGROUND "OPAQUE" ! background color 0
   FOR w=1 TO n
      PLOT TEXT,AT IP((w-1)/27)+0.03, MOD((w-1),27)+1 :"|"& names$(w)
   NEXT w
   LET bak=0
END SUB

SUB sampdisp
   LET x=IP((bak-1)/27)
   LET y=MOD((bak-1),27)
   SET LINE COLOR 0
   PLOT LINES:x,y; x+1-0.03,y; x+1-0.03,y+1; x,y+1; x,y
   LET x=IP((b-1)/27)
   LET y=MOD((b-1),27)
   SET LINE COLOR 2
   PLOT LINES:x,y; x+1-0.03,y; x+1-0.03,y+1; x,y+1; x,y
   PRINT
   PRINT "!*******************************"
   PRINT "!"& p$(m)& names$(b)
   PRINT "!*******************************"
   WHEN EXCEPTION IN
      OPEN #1: NAME p$(m)& names$(b),ACCESS INPUT
      FOR L=1 TO 500 ! 最大表示行数
         LINE INPUT #1,IF MISSING THEN EXIT FOR :w$
         FOR i=1 TO LEN(w$)
            IF w$(i:i)< " " AND w$(i:i)<>CHR$(9) THEN CAUSE EXCEPTION 1
         NEXT i
         PRINT w$
      NEXT L
   USE
      PRINT "******* テキストではない、表示の中止。"
   END WHEN
   CLOSE #1
   LET bak=b
END SUB

END
 

Re: 球体を描くプログラム

 投稿者:9mm  投稿日:2009年 7月 8日(水)14時14分57秒
返信・引用
  > No.439[元記事へ]

ありがとうございます。


作っていただき本当に申し訳ないんですが、球体だけを書きたいときはどうすればいいんでしょうか?
球面にせずに4つの座標をつないでなるべく球体に見えるようなものがいいんですが…

それがx軸周りで回転しているようなプログラムとか作れますかね?

初心者用の課題なんであまり高度なプログラミングをすると…(>_<)


何度も申し訳ないですm(。。)m
 

Re: 球体を描くプログラム

 投稿者:SECOND  投稿日:2009年 7月 8日(水)18時19分34秒
返信・引用
  > No.443[元記事へ]

差し出がましいとは、思いますが、先生は、たいへん多忙で、ご負担の大きい作業など
ありますので、できれば、この先は、sample\ フォルダーの方で、対処される事を期待
いたします。でしゃばりで、もうしわけないです。
 

Re: 球体を描くプログラム

 投稿者:9mm  投稿日:2009年 7月 8日(水)18時37分16秒
返信・引用
  > No.444[元記事へ]

SAMPLEフォルダはどこにあるんでしょうか?

わからないんですが…
 

Re: 球体を描くプログラム

 投稿者:SECOND  投稿日:2009年 7月 8日(水)18時50分8秒
返信・引用  編集済
  > No.445[元記事へ]

BASIC.EXE の有る所と同じフォルダーに同包されています。
大文字の、SAMPLE かもしれません。windows は、大小を区別しませんので。
 

Re: 球体を描くプログラム

 投稿者:9mm  投稿日:2009年 7月 8日(水)19時19分4秒
返信・引用
  > No.446[元記事へ]

ありました。ありがとうございます。

ただ球面にしないようにするにはどうしたらいいんでしょうか?

点を結んで球体っぽく見せたいのですが、それらしいフォルダが見つかりません…。
何度も申し訳ないです。初心者過ぎて申し訳ないです。
 

Re: 球体を描くプログラム

 投稿者:山中和義  投稿日:2009年 7月 8日(水)20時01分52秒
返信・引用  編集済
  > No.443[元記事へ]

9mmさんへのお返事です。

>三次元座標にたくさん座標をとって球体を作りたいんですが、

>球面にせずに4つの座標をつないでなるべく球体に見えるようなものがいいんですが…


一般に3Dグラフィックスでは、多面体を重ねます。
サッカーボールを想像するとよいでしょう。
6角形と5角形。(今のサッカーボールは違うかも!?)

サンプル http://www.urban.ne.jp/home/kz4ymnk/seminar/basic/3dmodel.html


また、地球の緯度と経度で台形分割(北極、南極は三角形)することもできます。
一般によくみるメルカトル図法の世界地図です。
これを地球儀にマップすることを想像してください。

!経線と緯線と使って、球体をワイヤーフレームで描画する

SET WINDOW -2,2,-2,2

FOR t=0 TO 90 STEP 15 !角度を等分割する
   LET a=SIN(RAD(t)) !端付近:密、中央付近:疎
   LET b=1
   FOR i=0 TO 360 !経線 ※楕円を描く
      LET x=a*COS(RAD(i))
      LET y=b*SIN(RAD(i))
      PLOT LINES: x,y;
   NEXT i
   PLOT LINES
NEXT t

FOR i=-180 TO 180 STEP 10 !緯線 ※水平線を描く
   LET y=SIN(RAD(i)) !角度を等分割する
   LET x=SQR(1-y^2) !極付近:密、0度付近:疎
   PLOT LINES: -x,y; x,y
NEXT i
PLOT LINES

END


私からサンプルとして、美術的手法(なぜ平面の画像が立体にみえるのか?)で表示したものです。
上記と合わせて考察してみてください。
!楕円を重ねると球体に見える!?

SET WINDOW -2,2,-2,2

LET b=1
FOR a=0 TO 1 STEP 0.25

   FOR i=0 TO 360 !楕円を描く
      LET x=a*COS(RAD(i))
      LET y=b*SIN(RAD(i))
      PLOT LINES: x,y;
   NEXT i
   PLOT LINES

NEXT a

LET a=1
FOR b=0 TO 1 STEP 0.25

   FOR i=0 TO 360 !楕円を描く
      LET x=a*COS(RAD(i))
      LET y=b*SIN(RAD(i))
      PLOT LINES: x,y;
   NEXT i
   PLOT LINES

NEXT b

END
 

Re: 球体を描くプログラム

 投稿者:9mm  投稿日:2009年 7月 8日(水)21時29分47秒
返信・引用
  > No.448[元記事へ]

山中和義さんへのお返事です。

ありがとうございます。

この図形が動いたりしませんかね?

できればこのサッカーボールのような図形が動いたらおもしろいと思うんですが・・
 

Re: 球体を描くプログラム

 投稿者:山中和義  投稿日:2009年 7月 9日(木)16時28分37秒
返信・引用
  > No.443[元記事へ]

9mmさんへのお返事です。

> 球面にせずに4つの座標をつないでなるべく球体に見えるようなものがいいんですが…
> それがx軸周りで回転しているようなプログラムとか作れますかね?
> 初心者用の課題なんであまり高度なプログラミングをすると…(>_<)

この質問がはっきりしませんので、正確な回答ができませんが、、、
!ワイヤーフレームで曲面を描く SAMPLE\3DPLOT.BASを改修。

SUB rotx(x,y,z,a)
   LET y0=y*cos(a)-z*sin(a)
   LET z0=y*sin(a)+z*cos(a)
   LET y=y0
   LET z=z0
END SUB
SUB roty(x,y,z,a)
   LET x0=x*cos(a)+z*sin(a)
   LET z0=-x*sin(a)+z*cos(a)
   LET x=x0
   LET z=z0
END SUB
SUB rotz(x,y,z,a)
   LET x0=x*cos(a)-y*sin(a)
   LET y0=x*sin(a)+y*cos(a)
   LET x=x0
   LET y=y0
END SUB
SUB convert(x,y,z)
   CALL rotz(x,y,z,RAD(-30))
   CALL rotx(x,y,z,RAD(-70))
END SUB
SUB plotTo(x,y,z)
   LET x1=x
   LET y1=y
   LET z1=z
   CALL convert(x1,y1,z1)
   PLOT LINES:x1,y1;
END SUB
SUB PenUp
   PLOT LINES
END SUB
SUB PlotText(x,y,z,s$)
   CALL convert(x,y,z)
   PLOT TEXT ,AT x,y: s$
END SUB

!媒体変数表示
DEF fx(u,v)=COS(u)*SIN(v) !球 u=[0,2*PI],v=[0,PI] ※球座標(r,θ,φ)
DEF fy(u,v)=SIN(u)*SIN(v)
DEF fz(u,v)=COS(v)

SET WINDOW -2,2,-2,2

FOR f=0 TO 360 !フレーム・アニメーション
   SET DRAW mode hidden !ちらつき防止(開始)
   CLEAR

   ! 軸を描く
   CALL PlotTo(0,0,0)
   CALL PlotTo(2,0,0)
   CALL PlotTo(0,0,0)
   CALL PlotTo(0,2,0)
   CALL PlotTo(0,0,0)
   CALL PlotTo(0,0,2)
   CALL PenUp
   CALL PlotText(2,0,0,"x")
   CALL PlotText(0,2,0,"y")
   CALL PlotText(0,0,2,"z")

   ! 曲面を描く
   FOR u=0 TO 360 STEP 15
      FOR v=0 TO 180 STEP 15
         LET x=fx(RAD(u),RAD(v))
         LET y=fy(RAD(u),RAD(v))
         LET z=fz(RAD(u),RAD(v))
         CALL rotx(x,y,z,RAD(f))
         CALL PlotTo(x,y,z)
      NEXT v
      CALL PenUp
   NEXT u
   FOR v=0 TO 180 STEP 30
      FOR u=-1 TO 360 STEP 30
         LET x=fx(RAD(u),RAD(v))
         LET y=fy(RAD(u),RAD(v))
         LET z=fz(RAD(u),RAD(v))
         CALL rotx(x,y,z,RAD(f))
         CALL PlotTo(x,y,z)
      NEXT u
      call PenUp
   NEXT v

   SET DRAW mode explicit !ちらつき防止(終了)
   !WAIT DELAY 0.1
NEXT f

END
 

GIF ファイル

 投稿者:SECOND  投稿日:2009年 7月10日(金)17時45分47秒
返信・引用  編集済
  !十進 BASIC の GIF ファイルが、過去の イメージング などで、
!「ドキュメントを開けませんでした。」で、読めない事についての、参考。
!-------
! Private_パレット だけが有って Common_パレット の無いのが、原因でした。
! Private は、無くても支障ないので、Common へ転送するプログラムです。

OPTION CHARACTER BYTE
SET ECHO "OFF"
! LET file$="decGIForg.GIF" ! 入力ファイル名。

!入力ファイル名を、全く書かない場合、マウス入力。
!入力ファイル名を、書く場合、
!起動したファイル( BASIC.EXE、又は このプログラム自身) の有った所と、
!同じフォルダーが、( カレントdir.) になる。( 出力ファイル共 )

ASK DIRECTORY s$
PRINT "カレントdir.:"& s$
IF file$="" THEN
   FILE GETNAME file$, "gif" ! マウスで、入力。
   IF file$="" THEN
      PRINT "入力ファイル名が、ありません。"
      STOP
   END IF
END IF
PRINT "入力ファイル:"& file$& " (変化しません)"
OPEN #1: NAME file$, ACCESS INPUT
CALL readCI( 6+2+2+1+1+1 +1+2+2+2+2+1 )
IF db$(1:6)<>"GIF87a" THEN
   PRINT "対象GIFファイルでない。"
   STOP
END IF
LET sflg=ORD(db$(11:11))
IF bitand8( sflg,BVAL("80",16) )>0 THEN
   PRINT "Common_パレット は、すでにあります。"
   STOP
END IF
LET pi$=db$(14:23)
LET pflg=ORD(pi$(10:10))
IF ORD( pi$(1:1) )<>BVAL("2C",16) OR bitand8( pflg,BVAL("80",16) )=0 THEN
   PRINT "十進 BASIC の GIFファイルでない。"
   STOP
END IF
FILE splitname(file$) path$, name$, ext$ ! ext$は語頭に"."含む。
PRINT "出力ファイル:"& path$& name$& "##"& ext$
PRINT "Ok?[Enter]"
CHARACTER INPUT k$
IF k$<>CHR$(13) THEN
   PRINT "中止"
   STOP
END IF
PRINT "処理中"
!----
OPEN #2: NAME path$& name$& "##"& ext$
ERASE #2
!----
PRINT "1)GIF_識別文字、スクリーン情報、"
PRINT "   common_パレット情報(修正)、の転送。"
LET j= bitor8( bitand8(sflg,BVAL("70",16)), bitand8(pflg,BVAL("87",16)) )
LET db$(11:11)=CHR$(j)
PRINT #2: db$(1:13);
!----
PRINT "2)private_パレット、から"
PRINT "   common_パレット、へ 転送。"
CALL readCI( 3*2^(MOD(pflg,8)+1) )
PRINT #2: db$;
!----
PRINT "3)画像情報(修正)、の転送。"
LET pi$(10:10)=CHR$(0)
PRINT #2: pi$;
PRINT "   private_パレット、の削除。"
!----
PRINT "4)画像データ 〜 GIF 終端ブロック、の転送中。"
CALL readCI( 1000000 )
PRINT #2: db$;
!----
CLOSE #2
CLOSE #1
PRINT "終了"

!-------read binary cx bytes
SUB readCI(cx) ! cx=bytes size
   LET db$=""
   FOR i=1 TO cx
      CHARACTER INPUT #1,IF MISSING THEN EXIT SUB :w9$
      LET db$=db$& w9$
   NEXT i
END SUB

!-------
FUNCTION bitand8(a,b)
   LET b9$="00000000"
   LET b8$=right$("0000000"& BSTR$(a,2),8)
   LET b7$=right$("0000000"& BSTR$(b,2),8)
   FOR b9=1 TO 8
      IF b8$(b9:b9)="1" AND b7$(b9:b9)="1" THEN LET b9$(b9:b9)="1"
   NEXT b9
   LET bitand8=BVAL(b9$,2)
END FUNCTION

FUNCTION bitor8(a,b)
   LET b9$="00000000"
   LET b8$=right$("0000000"& BSTR$(a,2),8)
   LET b7$=right$("0000000"& BSTR$(b,2),8)
   FOR b9=1 TO 8
      IF b8$(b9:b9)="1" OR b7$(b9:b9)="1" THEN LET b9$(b9:b9)="1"
   NEXT b9
   LET bitor8=BVAL(b9$,2)
END FUNCTION

END
!-------
!http://www.nikkeibp.co.jp/archives/251/251739.html
!LZW圧縮アルゴリズム特許、国内では2004年6月20日に失効 …
! …GIF画像ファイルを表示・生成するソフトの開発が自由に…なる。
 

n進法での循環小数の計算

 投稿者:山中和義  投稿日:2009年 7月11日(土)10時48分41秒
返信・引用  編集済
  進数変換は、n進⇔10進をベースに計算します。
各進法での数字は、0123456789ABCDEFGHIJKL … XYZ … です。(表示は36進法まで)
!n進法での整数、小数(有限小数、循環小数)、分数の計算

OPTION ARITHMETIC RATIONAL

FUNCTION ExBVAL(x$,RADIX) !(RADIX)進法の数値を表現する文字列を10進法数値に変換する
   IF RADIX<1 OR RADIX<>INT(RADIX) THEN
      PRINT "基数は2以上の整数を指定してください。"; RADIX
      STOP
   END IF

   CALL dec2frac(x$,RADIX, m,n) !小数を分数へ
   LET ExBVAL=m/n
END FUNCTION

FUNCTION ExVAL(x$) !数値を表現する文字列を10進法数値に変換する
   LET ExVAL=ExBVAL(x$,10)
END FUNCTION

!下位のルーチン
FUNCTION VAL1(x$,N) !N進法の数値  ※ASCIIコード表から
   IF x$>"9" THEN
      LET t=ORD(x$)-ORD("A")+10
   ELSE
      LET t=ORD(x$)-ORD("0") !※t=VAL(x$)でも可
   END IF
   IF t<0 OR t>=N THEN !0〜N-1の範囲かどうか確認する
      PRINT x$;"は範囲外の値です。"
      STOP
   END IF
   LET VAL1=t
END FUNCTION
SUB dec2frac(x$,RADIX, m,n) !(RADIX)進数数値を表現する文字列を10進法分数(m/n)に変換する
   LET L=LEN(x$) !文字列長を得る

   LET p=0 !有限小数の桁数
   LET k=0 !循環節の桁数。有限小数の場合、0
   LET A=0
   LET cSGN=1 !仮数の符号
   LET cSGN2=1 !指数部の符号
   LET flag=0 !「整数」  ※数値の型
   !書式  整数、小数: ±9{.}{E±9} | ±{9}.9{E±9}
   !      分数: ±9/9、循環小数: ±{9}.{9}[9]

   LET i=1 !数字列の読み込み位置
   DO WHILE i<=L !上位の桁から順に
      LET t$=UCASE$(x$(i:i))
      IF t$="." THEN !小数点なら
         IF flag<>0 THEN
            PRINT "小数点の位置が不正です。"; x$
            STOP
         END IF
         LET flag=1 !「有限小数」
      ELSEIF t$="+" THEN !+符号なら
         IF i<>1 THEN
            PRINT "+符号の位置が不正です。"; x$
            STOP
         END IF
      ELSEIF t$="-" THEN !−符号なら
         IF i<>1 THEN
            PRINT "−符号の位置が不正です。"; x$
            STOP
         END IF
         LET cSGN=-1
      ELSEIF (RADIX<14 AND t$="E") OR t$="@" THEN !指数部なら  ※14進法以上は、E.E@E(E.E*E^Eの意)
         IF flag>1 THEN !浮動小数点数か?
            PRINT "仮数は 9{.}|{9}.9 形式ではありません。"; x$
            STOP
         END IF

         IF i+1<=L THEN !指数部の符号を得る
            LET t$=UCASE$(x$(i+1:i+1))
            IF t$="+" THEN !+符号なら
               LET i=i+1
            ELSEIF t$="-" THEN !−符号なら
               LET cSGN2=-1
               LET i=i+1
            END IF
         END IF
         IF i=L THEN !右端か?
            PRINT "指数がありません。"; x$
            STOP
         END IF
         LET flag=2 !「指数部あり」
         LET B=A !save it as fraction
         LET A=0 !exponent
      ELSEIF t$="/" THEN !分数なら
         IF flag<>0 THEN !整数か?
            PRINT "分子は整数ではありません。"; x$
            STOP
         END IF
         LET flag=3 !「分数」
         LET B=A !save it as numerator
         LET A=0 !denominator
      ELSEIF t$="[" THEN !循環小数なら
         IF flag<>1 THEN !小数部か?
            PRINT "循環小数の開始位置が不正です。"; x$
            STOP
         END IF
         LET flag=4 !「循環小数」
      ELSEIF t$="]" THEN
         IF i<>L THEN !右端か?
            PRINT "循環小数の終了位置が不正です。"; x$
            STOP
         END IF
      ELSE
         LET A=A*RADIX+VAL1(t$,RADIX) !多項式(( … ((a[1]*RADIX+a[2])*RADIX+a[3])*RADIX … +a[i-2])*RADIX+a[i-1])*RADIX+a[i]  ※左シフト
         IF flag=1 THEN LET p=p+1
         IF flag=4 THEN LET k=k+1
      END IF

      LET i=i+1 !次へ
   LOOP

   !PRINT A;B; flag;cSGN;cSGN2;p;k !debug
   IF flag<2 THEN !有限小数(整数も含む)の場合
      LET m=cSGN * A
      LET n=RADIX^p
   ELSEIF flag=2 THEN !指数部あり小数の場合
      IF cSGN2*A< p THEN
         LET m=cSGN * B
         LET n=RADIX^(p-cSGN2*A)
      ELSE
         LET m=cSGN * B*RADIX^(cSGN2*A-p)
         LET n=1
      END IF
   ELSEIF flag=3 THEN !分数の場合
      IF A=0 THEN
         PRINT "0で割ることはできません。"; x$
         STOP
      END IF
      LET m=cSGN * B
      LET n=A
   ELSE !循環小数の場合
      LET B=INT(A/RADIX^k)
      LET m=cSGN * (A-B)
      LET n=(RADIX^(k+p)-RADIX^p)
   END IF

   LET B=GCD(m,n) !最大公約数で分子と分母を約分する
   LET m=m/B
   LET n=n/B
END SUB
FUNCTION GCD(a,b) !最大公約数を求める
   DO UNTIL b=0
      LET r=MOD(a,b)
      LET a=b
      LET b=r
   LOOP
   LET GCD=a
END FUNCTION


LET Precision=1000 !循環節の最大桁数 ※必要に応じて変更のこと
DIM s(Precision) !循環節の候補

FUNCTION ExBSTR$(x,RADIX) !10進法数値式を(RADIX)進法で小数表示するときの文字列に変換する
   IF RADIX<1 OR RADIX<>INT(RADIX) THEN
      PRINT "基数は2以上の整数を指定してください。"; RADIX
      STOP
   END IF

   CALL dec2frac(STR$(x),10, m,n) !小数を分数へ
   LET b$=frac2dec$(m,n,RADIX) !分数を小数へ
   IF RADIX<>10 THEN LET b$=b$&"("&STR$(RADIX)&")" !進法(RADIX)をつける
   LET ExBSTR$=b$
END FUNCTION

FUNCTION ExSTR$(x) !10進法数値式を小数表示するときの文字列に変換する
   LET ExSTR$=ExBSTR$(x,10) !指数つき小数と分数は、STR$を使う

   !!!LET b$=ExBSTR$(x,10)
   !!!IF POS(b$,"[")>0 THEN LET ExSTR$=b$ ELSE LET ExSTR$=STR$(x) !循環小数のみ採用する
END FUNCTION

!下位のルーチン
FUNCTION STR1$(x) !N進法の数字記号  ※ASCIIコード表から
   IF x>9 THEN
      LET STR1$=CHR$(x-10+ORD("A")) !ABCD…XYZ  ※N88系はASC("A")
   ELSE
      LET STR1$=CHR$(x+ORD("0")) !0123…789  ※STR$(x)でも可
   END IF
END FUNCTION

つづく
 

Re: n進法での循環小数の計算

 投稿者:山中和義  投稿日:2009年 7月11日(土)10時50分12秒
返信・引用
  > No.453[元記事へ]

つづき
FUNCTION frac2dec$(m,n,RADIX) !10進法分数(m/n)を(RADIX)進数で小数表示するときの文字列に変換する
   IF SGN(m)*SGN(n)<0 THEN LET cSGN$="-" ELSE LET cSGN$="" !符号を得る

   LET aa=ABS(m)
   LET b=ABS(n)

   LET t=GCD(aa,b) !最大公約数で分子と分母を約分する
   LET aa=aa/t
   LET b=b/t
   !!!PRINT aa;b;t !debug


   !整数部
   LET a=INT(aa/b) !小数部を削除する

   LET b$="" !変換後の数

   DO WHILE a>=RADIX !a=b[k]*RADIX^k+b[k-1]*RADIX^(k-1)+ … +b[1]*RADIX^1+b[0]*RADIX^0より
      LET b$=STR1$(MOD(a,RADIX))&b$ !一の位から求まる

      LET a=INT(a/RADIX) !次の桁へ  ※右シフト
   LOOP
   LET b$=STR1$(a)&b$


   !小数部
   LET aa=MOD(aa,b) !整数部を削除する

   LET k=0 !小数部の桁数

   DO UNTIL aa=0 !小数第1位から順に
      LET k=k+1
      IF k>MIN(b,Precision) THEN !循環小数によるループを回避する
         PRINT "変換を打ち切りました。"
         EXIT DO
      END IF

      IF k=1 THEN !初回のみ
         LET b$=b$&"." !小数点をつける
         LET p=LEN(b$) !位置を記録しておく
      ELSE
         FOR i=1 TO k-1 !循環したかどうか確認する
            IF s(i)=aa THEN EXIT DO !循環節なら、終了!
         NEXT i
      END IF
      LET s(k)=aa !小数第k位以降(未展開の小数部)の数を記録する

      LET aa=aa*RADIX !左シフトして、商を求める
      LET a=INT(aa/b)
      LET b$=b$&STR1$(a) !a=S[-1]*RADIX^(-1)+S[-2]*RADIX^(-2)+ … +S[-(k-1)]*RADIX^(-(k-1))+S[-k]*RADIX^(-k)より

      LET aa=MOD(aa,b) !剰余を求めて、次の桁へ
   LOOP

   IF aa=0 THEN !有限小数(整数も含む)なら
      LET p=k !有限小数の桁数
      LET k=0 !循環節の桁数
   ELSE !循環小数なら
      LET b$(i+p:i+p)="["&b$(i+p:i+p) !開始記号を挿入
      LET b$=b$&"]" !終了記号

      LET p=i-1 !有限小数の桁数
      LET k=k-i !循環節の桁数
   END IF

   LET frac2dec$=cSGN$&b$ !-9.9[9] 形式
END FUNCTION
!------------------------------ ここまでがサブルーチン



!● 0.[13](4)を10進法の分数で表現する  答え 7/15

!※等比数列の和  初項 0.13(4)=1/4^1+3/4^2、公比 0.01(4)=1/4^2
!  LET a = 0. + (1/4^1+3/4^2)/(1-1/4^2)
!  PRINT a

PRINT ExBVAL("0.[13]",4)




!● 1/7を3進法の小数(循環する)で表現する  答え 0.[010212](3)

PRINT ExBSTR$(1/7,3)




!● 0.1[23] ÷ 0.[14] の結果を循環小数で表せ。  答え 0.8[714285]

!筆算
!  x=0.1[23]とすると
!  100*x-x=12.3[23]-0.1[23]=12.2  ∴99*x=122/10  ∴x=61/495

LET t=ExVAL("0.1[23]") / ExVAL("0.[14]")
PRINT t, ExSTR$(t)




!● 3/7 を小数で表したとき、小数第800位の数字を求めよ。  答え 2

LET x$=ExSTR$(3/7) !0.[428571]
LET y$=x$(POS(x$,"[")+1:POS(x$,"]")-1) !循環節を切り出す
LET x=MOD(800,LEN(y$)) !800/6=133 余り 2
PRINT y$(x:x)



END


10進15桁モードの場合

先頭の OPTION ARITHMETIC RATIONAL をコメントアウトして、
計算部分のプログラムは以下のものに置き換えて、(小数⇔分数のルーチンを直接呼び出す)
10進15桁モードで実行します。
!● 0.[13](4)を10進法の分数で表現する  答え 7/15

!※等比数列の和  初項 0.13(4)=1/4^1+3/4^2、公比 0.01(4)=1/4^2
!  LET a = 0. + (1/4^1+3/4^2)/(1-1/4^2)
!  PRINT a

CALL dec2frac("0.[13]",4, m,n) !小数を分数へ
PRINT m;"/";n




!● 1/7を3進法の小数(循環する)で表現する  答え 0.[010212](3)

PRINT frac2dec$(1,7, 3) !分数を小数へ




!● 0.1[23] ÷ 0.[14] の結果を循環小数で表せ。  答え 0.8[714285]

!筆算
!  x=0.1[23]とすると
!  100*x-x=12.3[23]-0.1[23]=12.2  ∴99*x=122/10  ∴x=61/495

CALL dec2frac("0.1[23]",10, m,n)
CALL dec2frac("0.[14]",10, x,y)
PRINT frac2dec$(m*y,n*x,10) !(m/n)÷(x/y)=(m*y)÷(n*x)




!● 3/7 を小数で表したとき、小数第800位の数字を求めよ。  答え 2

LET x$=frac2dec$(3,7,10)
LET y$=x$(POS(x$,"[")+1:POS(x$,"]")-1) !循環節を切り出す
LET x=MOD(800,LEN(y$)) !800/6=133 余り 2
PRINT y$(x:x)
 

GIF ファイルの解析ツール

 投稿者:SECOND  投稿日:2009年 7月13日(月)02時17分25秒
返信・引用  編集済
  ! GIF ファイルの解析ツール
!-------
OPTION CHARACTER BYTE
!
FILE GETNAME file$, "gif"
IF file$="" THEN
   PRINT "入力ファイル名が、ありません。"
   STOP
END IF
PRINT "入力ファイル:"& file$
!
OPEN #1: NAME file$, ACCESS INPUT
PRINT "---------"
CALL gif_head
DO
   CALL blocks_main
LOOP UNTIL b1$=CHR$(BVAL("3B",16))
PRINT "GIF 終端ブロック"
CALL dump(b1$,16,"block label")
PRINT "---------"
CLOSE #1
IF c_p$>"" OR p_p$="" OR im$>"" OR ap$>"" OR co$>"" OR tx$>"" THEN STOP
PRINT "十進BASIC 出力の GIF ファイルのようです。"

!----
SUB gif_head
   LET h$=""
   CALL readb( h$,13 )
   IF h$(1:3)="GIF" THEN PRINT "GIF ヘッダー" ELSE CALL error
   LET Xsw=   ORD(h$( 8: 8))*256+ORD(h$(7:7))
   LET Ysw=   ORD(h$(10:10))*256+ORD(h$(9:9))
   LET sflg=  ORD(h$(11:11)) ! スクリーン情報のフラグ
   LET aspect=ORD(h$(13:13))
   LET b$=right$("0000000"& BSTR$(sflg,2) ,8)
   LET colpix=2^(BVAL(b$(2:4),2)+1)
   LET compal=2^(BVAL(b$(6:8),2)+1)
   CALL dumpASC(h$(1:6),8) ! GIF識別文字
   CALL dump(h$( 7: 8),16,"screen X_width "& STR$(Xsw))
   CALL dump(h$( 9:10),16,"screen Y_width "& STR$(Ysw))
   CALL dump(h$(11:11),16,"flags "& b$ )
   PRINT TAB(12);b$(1:1);":common_palette on=1/off=0"
   PRINT TAB(10);b$(2:4);":colors/pixel 2^(";b$(2:4);"b+1)= ";STR$(colpix)
   PRINT TAB(12);b$(5:5);":sort on=1/off=0  頻度の色順( outer use)"
   PRINT TAB(10);b$(6:8);":common_palette colors 2^(";b$(6:8);"b+1)= ";STR$(compal)
   CALL dump(h$(12:12),16,"back_ground color_code")
   IF aspect=0 THEN LET b$=".." ELSE LET b$=STR$(aspect)
   CALL dump(h$(13:13),16,"アスペクト比 pixel H:V=("& b$& "+15):64 =1:1( 00)" )
   CALL palette("common_パレット", c_p$, sflg)
END SUB

!----
SUB blocks_main
   LET b1$=""
   CALL readb( b1$, 1)
   IF     b1$=CHR$(BVAL("21",16)) THEN !追加データ・ブロック
      CALL option_block
   ELSEIF b1$=CHR$(BVAL("2C",16)) THEN !画像ブロック
      CALL picture_block
   ELSEIF b1$=CHR$(BVAL("3B",16)) THEN !GIF 終端ブロック
   ELSE
      CALL error
   END IF
END SUB

!---追加データ・ブロック。
SUB option_block
   PRINT "追加データ・ブロック"
   CALL readb( b1$,1) ! w9$= readb_last_byte
   IF     w9$=CHR$(BVAL("F9",16)) THEN
      LET im$=b1$
      CALL dump(im$,16,"イメージコントロール・ブロック")
      CALL blocksNP1(im$)
      LET iflg=ORD(im$(4:4)) ! フラグ
      LET imtm=ORD(im$(6:6))*256+ORD(im$(5:5))
      LET tcol=ORD(im$(7:7))
      LET b$=right$("0000000"& BSTR$(iflg,2),8)
      CALL dump(im$(4:4),16,"flags "& b$ )
      PRINT TAB(10);b$(1:3);":blank"
      PRINT TAB(10);b$(4:6);":"
      PRINT TAB(14);"000=none( OR )"
      PRINT TAB(14);"001= OR( same as 000)"
      PRINT TAB(14);"010=remove all before( paint screen_BG before)"
      PRINT TAB(14);"011=remove last picture before"
      PRINT TAB(12);b$(7:7);":user click on=1/off=0"
      PRINT TAB(12);b$(8:8);":透過GIFの透明色のスイッチ on=1/off=0"
      CALL dump(im$(5:6),16,"アニメーションGIFのフレーム表示時間(10ms単位) "& STR$(imtm) )
      CALL dump(im$(7:7),16,"透過GIFの透明色 "& STR$(tcol) )
      CALL blocks(im$)
   ELSEIF w9$=CHR$(BVAL("FE",16)) THEN
      LET co$=b1$
      CALL dump(co$,16,"コメント・ブロック")
      CALL blocksASC(co$,100)
   ELSEIF w9$=CHR$(BVAL("FF",16)) THEN
      LET ap$=b1$
      CALL dump(ap$,16,"アプリケーション・ブロック")
      CALL blocksASC(ap$,1)
      IF ap$(4:11)="NETSCAPE" THEN
         CALL blocksNP1(ap$)
         CALL dump(ap$(16:16),16,"constant 1")
         LET rept=ORD(ap$(18:18))*256+ORD(ap$(17:17))
         CALL dump(ap$(17:18),16,"animation repeat number "& STR$(rept)& " (0=endless)" )
      END IF
      CALL blocksASC(ap$,100)
   ELSEIF w9$=CHR$(BVAL("01",16)) THEN
      LET tx$=b1$
      CALL dump(tx$,16,"テキスト・イメージ・ブロック")
      CALL blocksASC(tx$,100)
   ELSE
      CALL error
   END IF
END SUB

SUB blocksNP1(d$)
   CALL readb(d$,1)             ! w9$= readb_last_byte ! =block Size
   CALL dump(w9$,16,"block size")
   IF w9$=CHR$(0) THEN EXIT SUB ! block End
   CALL readb(d$,ORD(w9$))      ! block data
END SUB

SUB blocks(d$)
   DO
      CALL readb(d$,1)             ! w9$= readb_last_byte ! =block Size
      CALL dump(w9$,16,"block size")
      IF w9$=CHR$(0) THEN EXIT SUB ! block End
      LET s=LEN(d$)
      CALL readb(d$,ORD(w9$))      ! block data
      CALL dump(d$(s+1:LEN(d$)),16,"")
   LOOP
END SUB

SUB blocksASC(d$,n) !n=ブロック数の上限
   FOR n=1 TO n
      CALL readb(d$,1)             ! w9$= readb_last_byte ! =block Size
      CALL dump(w9$,16,"block size")
      IF w9$=CHR$(0) THEN EXIT SUB ! block End
      LET s=LEN(d$)
      CALL readb(d$,ORD(w9$))      ! block data
      CALL dumpASC(d$(s+1:LEN(d$)),8)
   NEXT n
END SUB

SUB readb(d$,cx) !cx=bytes size
   FOR i=1 TO cx
      CHARACTER INPUT #1,IF MISSING THEN EXIT FOR :w9$
      LET d$=d$& w9$
   NEXT i
   IF i<=cx THEN CALL error
END SUB

SUB picture_block
   PRINT "画像ブロック"
   LET pi$=b1$
   CALL readb( pi$,9) ! w9$= readb_last_byte
   CALL dump(pi$(1:1),16,"block label")
   LET Xp0=ORD(pi$(3:3))*256+ORD(pi$(2:2))
   LET Yp0=ORD(pi$(5:5))*256+ORD(pi$(4:4))
   LET Xpw=ORD(pi$(7:7))*256+ORD(pi$(6:6))
   LET Ypw=ORD(pi$(9:9))*256+ORD(pi$(8:8))
   CALL dump(pi$(2:3),16,"picture.X0_position left "& STR$(Xp0))
   CALL dump(pi$(4:5),16,"picture.Y0_position top "& STR$(Yp0))
   CALL dump(pi$(6:7),16,"picture.X_width "& STR$(Xpw))
   CALL dump(pi$(8:9),16,"picture.Y_width "& STR$(Ypw))
   LET pflg=ORD(pi$(10:10)) ! 画像情報のフラグ
   LET b$=right$("0000000"& BSTR$(pflg,2),8)
   LET pripal=2^(BVAL(b$(6:8),2)+1)
   CALL dump(pi$(10:10),16,"flags "& b$ )
   PRINT TAB(12);b$(1:1);":private_palette on=1/off=0"
   PRINT TAB(12);b$(2:2);":interrace on=1/off=0, 1~step8 5~step8 3~step4 2~step2"
   PRINT TAB(12);b$(3:3);":sort on=1/off=0  頻度の色順( outer use)"
   PRINT TAB(11);b$(4:5);":blank"
   PRINT TAB(10);b$(6:8);":private_palette colors 2^(";b$(6:8);"b+1)= ";STR$(pripal)
   CALL palette("private_パレット", p_p$, pflg)
   !---
   PRINT "画像データ"
   LET pda$=""
   CALL readb( pda$,1)
   CALL dump(pda$,16,"最小データ・ビット長")
   !--- LZW データ(size:data, size:data, … 0 )
   CALL blocks(pda$)
END SUB

SUB palette(n$, p$, pf)
   PRINT n$;
   LET p$=""
   IF INT(pf/128)>0 THEN ! pf AND 0x80
      PRINT
      CALL readb(p$, 3*2^(MOD(pf,8)+1)) ! pf AND 0x07
      CALL dump(p$,3,"R G B")
   ELSE
      PRINT "は、有りません。"
   END IF
END SUB

SUB error
   beep
   PRINT "File Error Stop"
   STOP
END SUB

!-------
FUNCTION bitand8(a,b)
   LET b9$="00000000"
   LET b8$=right$("0000000"& BSTR$(a,2),8)
   LET b7$=right$("0000000"& BSTR$(b,2),8)
   FOR b9=1 TO 8
      IF b8$(b9:b9)="1" AND b7$(b9:b9)="1" THEN LET b9$(b9:b9)="1"
   NEXT b9
   LET bitand8=BVAL(b9$,2)
END FUNCTION

FUNCTION bitor8(a,b)
   LET b9$="00000000"
   LET b8$=right$("0000000"& BSTR$(a,2),8)
   LET b7$=right$("0000000"& BSTR$(b,2),8)
   FOR b9=1 TO 8
      IF b8$(b9:b9)="1" OR b7$(b9:b9)="1" THEN LET b9$(b9:b9)="1"
   NEXT b9
   LET bitor8=BVAL(b9$,2)
END FUNCTION

!-------
SUB dump(d$,m,t$)
   FOR j=1 TO LEN(d$) STEP m
      LET ww$=right$("000"& BSTR$(adr,16),4)& " "
      FOR i=j TO MIN(j+m-1, LEN(d$))
         LET ww$=ww$& " "& right$("0"& BSTR$( ORD(d$(i:i)),16),2)
         LET adr=adr+1
      NEXT i
      IF t$>"" AND j<=m THEN LET ww$=ww$& " ;"& t$
      PRINT ww$ !行単位、テキスト画面のピカつき減少、高速。
   NEXT j
END SUB

SUB dumpASC(d$,m)
   FOR j=1 TO LEN(d$) STEP m
      LET ww$=right$("000"& BSTR$(adr,16),4)& " "
      FOR i=j TO MIN(j+m-1, LEN(d$))
         LET ww$=ww$& " "& right$("0"& BSTR$( ORD(d$(i:i)),16),2)
         LET adr=adr+1
      NEXT i
      LET ww$=ww$& REPEAT$(" ",3*m+6-LEN(ww$))& ";"""
      FOR i=j TO MIN(j+m-1, LEN(d$))
         IF " "<=d$(i:i) THEN LET ww$=ww$& d$(i:i) ELSE LET ww$=ww$& "."
      NEXT i
      LET ww$=ww$& """"
      PRINT ww$
   NEXT j
END SUB

END
 

論理式の計算

 投稿者:山中和義  投稿日:2009年 7月15日(水)16時08分13秒
返信・引用  編集済
  +、・演算子は、OR、AND関数で記述する。
各変数に真理値表のビットパターンを設定して、式を計算して真理値表を得る。
!論理式の計算

DEF AND3(a,b,c)=AND(AND(a,b),c) !3変数以上の場合
DEF AND4(a,b,c,d)=AND(AND(a,b),AND(c,d))
DEF OR3(a,b,c)=OR(OR(a,b),c)
DEF OR4(a,b,c,d)=OR(OR(a,b),OR(c,d))

LET C1=NT(0) !1 ※−1のビットパターン
!------------------------------ ここまでがマクロの定義

LET N=3 !変数の数 ※1〜5

LET A=BOOL(N,1) !N個の変数の1番目
LET B=BOOL(N,2)
LET C=BOOL(N,3)
!LET D=BOOL(N,4)
!LET E=BOOL(N,5)

LET nA=NT(A) !A' 補元
LET nB=NT(B)
LET nC=NT(C)
!LET nD=NT(D)
!LET nE=NT(E)


!●論理式の真理値表をつくる

PRINT BitPTN$(N, A); ":A"
PRINT BitPTN$(N, B); ":B"
PRINT BitPTN$(N, C); ":C"

LET f=OR3(AND3(A,B,C), AND3(A,nB,C), AND3(A,B,nC))
PRINT BitPTN$(N, f); ":ABC+AB'C+ABC'"
PRINT


!●論理式を主加法標準展開、主乗法標準展開する

LET f=OR(A,AND(B,C))
!PRINT BitPTN$(N, f); ":A+BC"

CALL PrintPDCF(N,f)
CALL PrintPCCF(N,f)
PRINT


!●クワイン・マクラスキー法(Quine-McCluskey algorithm)で式を簡単化する

!ステップ0 論理式の真理値表をつくる

LET f=OR4(AND3(nA,B,C),AND3(A,nB,C),AND3(A,B,nC),AND3(A,B,C))
!PRINT BitPTN$(N, f); ":A'BC+AB'C+ABC'+ABC"


!ステップ1 論理式を最小項で記述する(主加法標準展開)

DIM Term$(2^N) !最小項のビットパターン
LET CntOfTerm=0 !最小項の数
FOR i=0 TO 2^N-1 !真理値表を2進法の数とみなして小さい順に
   IF Bit(f,i)=1 THEN !最小項なら
      LET CntOfTerm=CntOfTerm+1
      LET Term$(CntOfTerm)=right$(REPEAT$("0",N-1)&BSTR$(i,2),N) !ビットパターンは、…DCBA順
   END IF
NEXT i
!FOR i=1 TO CntOfTerm !debug
!   PRINT Term$(i)
!NEXT i

IF CntOfTerm=0 THEN !すべて0なら、終了!
   PRINT "0"
   STOP
ELSEIF CntOfTerm=2^N THEN !すべての1なら、終了!
   PRINT "1"
   STOP
END IF


!ステップ2 AB+AB'=Aを使って、最小項の変数を減らす

DIM wTerm$(100) !作業用にコピーする
FOR i=1 TO CntOfTerm
   LET wTerm$(i)=Term$(i)
NEXT i
LET wCntOfTerm=CntOfTerm

DIM Term9$(2^N) !主項のビットパターン
LET CntOfTerm9=0 !主項の数

DO
   DIM CHK(100) !圧縮の有無
   MAT CHK=ZER

   LET CntOfCompTRM=0 !圧縮された項の数

   FOR i=1 TO wCntOfTerm-1 !すべての組合せで考慮する
      FOR j=i+1 TO wCntOfTerm

         LET CntOf1=0 !「1」の数
         FOR k=1 TO N !ビット単位の排他的論理和を求める
            LET t1$=wTerm$(i)(k:k)
            LET t2$=wTerm$(j)(k:k)
            IF (t1$="1" AND t2$="0") OR (t1$="0" AND t2$="1") THEN !「1」とする
               LET CntOf1=CntOf1+1
               LET PosOf1=k !消去される変数の位置
            ELSEIF (t1$="0" AND t2$="0") OR (t1$="1" AND t2$="1") THEN !「0」とする
            !skip it
            ELSEIF (t1$="-" AND t2$="-") THEN !マスク・ビットなら
            !skip it
            ELSE !片方がマスク・ビットなら、候補ではない!
               LET CntOf1=N
               EXIT FOR
            END IF
         NEXT k

         IF CntOf1=1 THEN !AB+AB'=A(ハミング距離が1)より、消去する
            LET t$=wTerm$(i) !ビットパターン
            LET t$(PosOf1:PosOf1)="-" !その変数を消去する

            LET CHK(i)=1 !圧縮あり
            LET CHK(j)=1

            DIM CompTRM$(100)
            FOR k=1 TO CntOfCompTRM !同じ項があるか確認する
               IF t$=CompTRM$(k) THEN EXIT FOR
            NEXT k
            IF k>CntOfCompTRM THEN !なけらば、新規に登録する
               LET CntOfCompTRM=CntOfCompTRM+1
               LET CompTRM$(CntOfCompTRM)=t$

               !PRINT i;j; t$ !debug
            END IF
         END IF

      NEXT j
   NEXT i

   LET Cnt=0 !今回圧縮できなかった項の数
   FOR i=1 TO wCntOfTerm !圧縮されないものは、主項となる
      IF CHK(i)=0 THEN
         LET Cnt=Cnt+1

         LET CntOfTerm9=CntOfTerm9+1 !主項として記録する
         LET Term9$(CntOfTerm9)=wTerm$(i)
      END IF
   NEXT i

   IF Cnt=wCntOfTerm THEN EXIT DO !すべて圧縮できなければ、終了!


   FOR i=1 TO CntOfCompTRM !次へ
      LET wTerm$(i)=CompTRM$(i) !copy it
   NEXT i
   LET wCntOfTerm=CntOfCompTRM

LOOP


!ステップ3 主項表を使って冗長な主項を削除する

!ステップ3−1 主項表をつくる

DIM TT(CntOfTerm9,CntOfTerm) !主項表(図) ※TT(主項,最小項)
MAT TT=ZER

FOR i=1 TO CntOfTerm9 !最小項を包含する主項にチェックを入れる
   FOR j=1 TO CntOfTerm
      FOR k=1 TO N
         LET t$=Term9$(i)(k:k)
         IF t$<>"-" THEN !マスク・ビット以外が不一致なら、終了!
            IF t$<>Term$(j)(k:k) THEN EXIT FOR
         END IF
      NEXT k
      IF k>N THEN LET TT(i,j)=1 !すべてのビットが一致すれば、包含する
   NEXT j
NEXT i
!MAT PRINT TT; !debug


!ステップ3−2 主項表から必須項を探す

DIM CHK2(CntOfTerm9) !必須項としてチェックする
MAT CHK2=ZER

MAT CHK=ZER
FOR j=1 TO CntOfTerm !主項表から必須項を探す
   LET Cnt=0
   FOR i=1 TO CntOfTerm9 !列で走査して、「1」が1つの列を見つける
      IF TT(i,j)=1 THEN
         LET Cnt=Cnt+1
         LET PosOf1=i !行位置
      END IF
   NEXT i
   IF Cnt=1 THEN !1つのものは、必須項とする
      LET CHK2(PosOf1)=1
      FOR k=1 TO CntOfTerm !必須項だけで最小項を包含するか(冗長性)
         LET CHK(k)=OR(CHK(k),TT(PosOf1,k))
      NEXT k
   END IF
NEXT j
!MAT PRINT CHK; !debug
!MAT PRINT CHK2;


つづく
 

Re: 論理式の計算

 投稿者:山中和義  投稿日:2009年 7月15日(水)16時09分38秒
返信・引用
  > No.456[元記事へ]

つづき
!ステップ3−3 必須項と選択項の組み合わせで過不足なく項を選ぶ

DO
   FOR j=1 TO CntOfTerm !包含されていない箇所を探す
      IF CHK(j)=0 THEN EXIT FOR
   NEXT j
   IF j>CntOfTerm THEN EXIT DO !必須項+選択項で最小項を包含するなら、終了!

   FOR i=1 TO CntOfTerm9 !その箇所を選択項で埋める
      IF TT(i,j)=1 THEN !行位置
         LET CHK(j)=2
         LET CHK2(i)=2 !選択項に加える
         EXIT FOR
      END IF
   NEXT i
   !MAT PRINT CHK; !debug
   !MAT PRINT CHK2;
LOOP



!結果を表示する

FOR i=1 TO CntOfTerm9
   IF CHK2(i)>0 THEN !必須項または選択項なら
      PRINT "+";
      FOR k=0 TO N-1 !変数へ
         SELECT CASE Term9$(i)(N-k:N-k) !ビットパターンを得る ※…DCBA順
         CASE "0"
            PRINT CHR$(k+ORD("A"));"'"; !否定
         CASE "1"
            PRINT CHR$(k+ORD("A"));
         CASE ELSE !"-"
         END SELECT
      NEXT k
   END IF
NEXT i
PRINT


END


EXTERNAL FUNCTION BOOL(N,i) !真理値表での変数A〜Zのビットパターン(2^N 桁)を求める
LET t$=REPEAT$("1",2^(i-1))&REPEAT$("0",2^(i-1)) !11…100…0
LET BOOL=BVAL(REPEAT$(t$,2^(N-i)),2) !A,B,C,…
END FUNCTION


!出力関連
EXTERNAL SUB PrintPDCF(N,f) !真理値表を主加法標準形(選言標準形)で出力する
FOR i=0 TO 2^N-1
   IF Bit(f,i)=1 THEN !最小項
      PRINT "+";
      FOR x=0 TO N-1
         PRINT CHR$(x+ORD("A")); !変数名
         IF Bit(i,x)=0 THEN PRINT "'"; !否定記号
      NEXT x
   END IF
NEXT i
PRINT
END SUB

EXTERNAL SUB PrintPCCF(N,f) !真理値表を主乗法標準形(連言標準形)で出力する
FOR i=0 TO 2^N-1
   IF Bit(f,i)=0 THEN !最大項
      PRINT "(";
      FOR x=0 TO N-1
         PRINT "+";
         PRINT CHR$(x+ORD("A")); !変数名
         IF Bit(i,x)=1 THEN PRINT "'"; !否定記号
      NEXT x
      PRINT ")";
   END IF
NEXT i
PRINT
END SUB


!補助ルーチン
EXTERNAL FUNCTION Bit(x,m) !mビット目を得る 0,1
LET Bit=MOD(INT(x/2^m),2)
END FUNCTION

EXTERNAL FUNCTION BitPTN$(N,a) !ビットパターン(2^N 桁)を求める
IF a>=0 THEN
   LET a$=REPEAT$("0",2^N-1)&BSTR$(a,2)
ELSE
   LET a$=BSTR$(a+2^32,2)
END IF
LET BitPTN$=right$(a$,2^N)
END FUNCTION


!論理演算
EXTERNAL FUNCTION AND(a,b) !整数a,bのビット単位での論理積を求める
LET c=0
FOR i=0 TO 31
   LET aa=MOD(a,2)
   LET a=(a-aa)/2
   LET bb=MOD(b,2)
   LET b=(b-bb)/2
   LET c=c+MIN(aa,bb)*2^i
NEXT i
IF c>=2^31 THEN LET c=c-2^32
LET AND=c
END FUNCTION

EXTERNAL FUNCTION OR(a,b) !整数a,bのビット単位での論理和を求める
LET c=0
FOR i=0 TO 31
   LET aa=MOD(a,2)
   LET a=(a-aa)/2
   LET bb=MOD(b,2)
   LET b=(b-bb)/2
   LET c=c+MAX(aa,bb)*2^i
NEXT i
IF c>=2^31 THEN LET c=c-2^32
LET OR=c
END FUNCTION

EXTERNAL FUNCTION NT(a) !整数aのビット単位での論理否定を求める ※NOTは予約語のため
LET NT=-1-a
END FUNCTION
 

GIF アニメ−ション を作る。

 投稿者:SECOND  投稿日:2009年 7月16日(木)03時59分38秒
返信・引用  編集済
  ! GIF Animation を作る。
!-------

OPTION CHARACTER BYTE
SET ECHO "OFF"

LET ofile$="DecAnima.GIF" ! 削除すると、ダイアログ・ボックス入力。
ASK DIRECTORY s$
IF ofile$>"" THEN PRINT "カレント DIR:"& s$ ELSE file getname ofile$, "gif"
PRINT "出力ファイル:"& ofile$
IF ofile$>"" THEN PRINT "上書き。又は作成されます。…"& "Ok?[Enter]"
IF ofile$>"" THEN CHARACTER INPUT k$
IF ofile$="" OR k$<>CHR$(13) THEN
   PRINT "中止"
   STOP
END IF

!-------
!http://www.nikkeibp.co.jp/archives/251/251739.html
!LZW圧縮アルゴリズム特許、国内では2004年6月20日に失効 …
! …GIF画像ファイルを表示・生成するソフトの開発が自由に…なる。

!-----------
! 射影変換 ( SAMPLE\TRANSFO9.BAS から、拝借)
DIM T(4,4),m(501,501)
MAT T=IDN

PICTURE House
   SET AREA COLOR 15
   PLOT AREA:    0, 1;   0,  0;   2,  0;   2,  1 !壁
   SET AREA COLOR 2
   PLOT AREA:  -0.6,1;  2.6, 1;   2,  2;   0,  2 !屋根
   SET AREA COLOR 10
   PLOT AREA:  0.1, 0; 0.1,0.8; 0.5,0.8; 0.5,  0 !ドア
   SET AREA COLOR 5
   PLOT AREA: 1.4,0.4; 1.9,0.4; 1.9,0.8; 1.4,0.8 !窓
   SET AREA COLOR 12
   PLOT AREA:  1.7, 2; 1.7,2.3; 1.5,2.3; 1.5,  2 !煙突
END PICTURE

SET WINDOW -5,5,-5,5
ASK PIXEL SIZE (-1.1,4.3 ; 4.6,-.5) Xw,Yw
MAT m=ZER(Xw,Yw)
!screen& picture.xw =Xw
!screen& picture.yw =Yw
LET obits0=4 !( 2= 2色~4色, 3= 8色, 4=16色, … 8=256色)
!
CALL gif_header
CALL applica_blk(0) !repeat number, 0=end less
!
LET N000=2^obits0 !encoder colors max.  …予約登録番号最大値+1
LET t_max= 2000   ! 表示のthead より大きい程度に、小さいと辞書クリアー頻度増。
DIM dic_0(0 TO t_max, 0 TO N000-1), dic_1(0 TO t_max, 0 TO N000-1) !逆引き辞書
!
FOR i9=-PI TO 0*PI+.01 STEP PI/2
   LET a=(1+COS(i9))/2
   LET T(1,4)= .1*a
   LET T(2,4)=-.1*a
   SET DRAW mode hidden
   CLEAR
   DRAW axes
   SET AREA COLOR 6 !透過色に使用
   PLOT AREA: -1.1,-.5; 4.6,-.5; 4.6,4.3; -1.1,4.3
   DRAW House WITH T*ROTATE(-PI/20*a)*SCALE(1.72)
   ASK PIXEL ARRAY (-1.1,4.3) m
   SET DRAW mode explicit
   !----
   READ dly
   DATA 140,20,100
   !CALL img_ctl_blk( dly,BVAL("00001000",2), 6) !透過させない、全表示
   CALL img_ctl_blk( dly,BVAL("00001001",2), 6) !表示時間(x10ms),iflg,透過色
   CALL picture_blk
   CALL picture_data
   !----
NEXT i9
CALL gif_terminater

!---------
!画像配列 m(1~Xw,1~Yw) !! 注意 x,y の順 mat read m(y,x)
SUB inppix             !! ask pixel array(x0,y0) m(x,y)
   LET lx=lx+1
   IF Xw< lx THEN
      LET lx=1
      LET ly=ly+1
   END IF
   IF ly<=Yw THEN LET bx=m(lx,ly) ! data on bx
END SUB

SUB picture_data
   PRINT #1: CHR$(obits0); !最小データービット長 …予約登録番号の最大ビット長
   LET blkfull=255         !block size max.(~~255)
   LET bitfull=12          !  LZW bits max.(~~ 12)
   CALL LZW_encoder
   CALL outcode       !flush registered dic.number on ax
   LET ax=N000+1      !code end
   CALL outcode
   CALL out_flush
   PRINT #1: CHR$(0); !block size 0 (end)
END SUB

SUB LZW_encoder
   LET lx=1 -1 !画像配列 m(1~Xw,1~Yw)
   LET ly=1
   CALL inppix             !data on bx
   LET pdata$=""           !clear output bytes buffer
   LET oacc$=""            !clear output bits buffer
   LET owidth=obits0+1     !starting bit width
   DO
      LET ax=N000          !reset code
      CALL outcode
      MAT dic_0=ZER        !clear dic.number
      MAT dic_1=ZER        !clear dic.chain
      LET thead=1          !reset make_table pointer
      LET dicnum=N000+2    !reset dictionary new number
      LET owidth=obits0+1  !starting bit width
      DO
         LET di=0                  !top table
         LET dic_0(di,bx)=bx
         DO
            LET ax=dic_0(di,bx)    !---latch last chained register
            IF dic_1(di,bx)>0 THEN LET di=dic_1(di,bx) ELSE CALL make_table
            CALL inppix            ! next bx
            IF Yw< ly THEN EXIT SUB
         LOOP UNTIL dic_0(di,bx)=0 !---until no register
         LET dic_0(di,bx)=dicnum   ! new register, bx=tail
         CALL outcode              !write last register
         LET owidth=LEN( BSTR$(dicnum,2) ) ! remake owidth
         LET dicnum=dicnum+1
      LOOP UNTIL dicnum>2^bitfull-1 OR thead>t_max !bits full or dic.full
   LOOP
END SUB

SUB make_table
   LET dic_1(di,bx)=thead !chained table pointer
   LET di=thead           !new table head
   LET thead=thead+1
END SUB

SUB outcode
   LET oacc$=right$("00000000000"& BSTR$(ax,2),owidth)& oacc$
   DO WHILE LEN(oacc$)>=8
      LET pdata$=pdata$& CHR$(BVAL(right$(oacc$,8),2))
      LET oacc$=oacc$(1:LEN(oacc$)-8)
      IF LEN(pdata$)=blkfull THEN CALL bw_sub
   LOOP
END SUB

SUB bw_sub
   PRINT #1: CHR$(LEN(pdata$)); pdata$;
   LET pdata$=""
   PRINT "thead=";thead;" dicnum=";dicnum  !--monitor
END SUB

SUB out_flush
   IF oacc$<>"" THEN LET pdata$=pdata$& CHR$(BVAL(oacc$,2) )
   LET oacc$=""
   IF pdata$>"" THEN CALL bw_sub
   PRINT "------"  !--monitor
END SUB

!=============
SUB gif_header
   PRINT "処理中"
   OPEN #1: NAME ofile$
   ERASE #1
   PRINT #1: "GIF89a";
   CALL prt_2dw( Xw,Yw )
   ! ---sflg---
   !  1: common-palet-ON
   !xxx: colors_bits/pixel 2^(xxxb+1)
   !  0: sort-OFF
   !xxx: colors_bits/common-palet 2^(xxxb+1)
   LET sflg=BVAL("10000000",2)+(obits0-1)*16+(obits0-1)
   PRINT #1: CHR$(sflg);
   PRINT #1: CHR$(0); ! back ground color
   PRINT #1: CHR$(0); ! アスペクト比 if n=0 then 1:1 else H:V=(n+15):64
   ! common_palette
   FOR i=0 TO 2^obits0-1
      ASK COLOR MIX(i) r,g,b
      PRINT #1: CHR$(r*255);CHR$(g*255);CHR$(b*255); ! R G B
   NEXT i
END SUB

SUB applica_blk(rp)
   CALL prt_BVAL16("21,FF") ! アプリケーション・ブロック
   PRINT #1: CHR$(11);            !block size
   PRINT #1: "NETSCAPE2.0";       !アプリケーション名(8) バージョン(3)
   PRINT #1: CHR$(3);             !block size
   PRINT #1: CHR$(1);             !constant 1
   PRINT #1: CHR$(MOD(rp,256));CHR$(IP(rp/256)); !repeat number  0=endless
   PRINT #1: CHR$(0);             !block size 0 (end)
END SUB

SUB img_ctl_blk( Dtm,iflg,tco )
   CALL prt_BVAL16("21,F9") ! イメージコントロール・ブロック
   PRINT #1: CHR$(4);       !block size
   ! ---iflg---
   !000:blank
   !010: 000=none( OR )
   !     001= OR( same as 000)
   !     010=remove all before( paint screen-BG before)
   !     011=remove last picture before
   !  0:user click-OFF
   !  0:透過GIFの透明色のスイッチ 1=ON 0=OFF
   PRINT #1: CHR$(iflg);
   PRINT #1: CHR$(MOD(Dtm,256));CHR$(IP(Dtm/256)); !表示時間(x10ms)
   PRINT #1: CHR$(tco);  !透過GIFの透明色
   PRINT #1: CHR$(0);    !block size 0 (end)
END SUB

SUB picture_blk
   CALL prt_BVAL16("2C") ! 画像・ブロック
   CALL prt_2dw( 0,0 )   !picture.x0=0,y0=0
   CALL prt_2dw( Xw,Yw ) !picture.xw,yw =screen.xw,yw
   ! ---pflg---
   !  0:private-palet-OFF
   !  0:interrace-OFF
   !  0:sort-OFF
   ! 00:blank
   !xxx:private-palette-bits 2^(xxxb+1)
   LET pflg=BVAL("00000000",2)
   PRINT #1: CHR$(pflg);
END SUB

SUB gif_terminater
   PRINT #1: CHR$(BVAL("3B",16));
   CLOSE #1
   PRINT "終了"
END SUB

!-----------
SUB prt_2dw( dw1,dw2 )
   PRINT #1: CHR$(MOD(dw1,256));CHR$(IP(dw1/256));
   PRINT #1: CHR$(MOD(dw2,256));CHR$(IP(dw2/256));
END SUB

SUB prt_BVAL16(h$)
   FOR i=1 TO LEN(h$) STEP 3
      PRINT #1: CHR$(BVAL(h$(i:i+1),16));
   NEXT i
END SUB

END
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 7月20日(月)07時23分26秒
返信・引用  編集済
  > No.413[元記事へ]

!問題1 自然数nに対して、その約数の和を求める
!60の場合
PRINT 1+2+3+4+5+6+10+12+15+20+30+60


!●実際に求めて、その和を計算する
LET n=60 !求める数

LET s=0 !和
LET c=0 !個数

FOR f=1 TO SQR(n) !個数の半分まで
   IF MOD(n,f)=0 THEN !割り切れるなら
      IF n/f=f THEN !商と割った数が同じとき、1つ
      !PRINT f
         LET s=s+f
         LET c=c+1
      ELSE !商と割った数が異なるとき、ペアで求まる
      !PRINT f; n/f
         LET s=s+f+n/f
         LET c=c+2
      END IF
   END IF
NEXT f

PRINT "和=";s, "個数=";c



!●素因数分解
! n=p^a*q^b*r^c* … 、素数p,q,r,…、整数a,b,c,… なら
! 和 (p^0+p^1+p^2+ … +p^a)*(q^0+q^1+q^2+ … +q^b)*(r^0+r^1+r^2+ … +r^c)* …
! 個数 (a+1)*(b+1)*(c+1)* …

!60=2^2*3^1*5^1 より
PRINT (2^0+2^1+2^2)*(3^0+3^1)*(5^0+5^1) !和
PRINT (2+1)*(1+1)*(1+1) !個数

!また、カッコの中は等比数列より ※和Sn=a*(1-r^n)/(1-r)、初項a、公比r、項数n
LET t1=1*(1-2^3)/(1-2) !2^0+2^1+2^2
LET t2=1*(1-3^2)/(1-3) !3^0+3^1
LET t3=1*(1-5^2)/(1-5) !5^0+5^1
PRINT t1*t2*t3



!●素因数分解のプログラムに上記の算出方法を組込む
LET n=60 !求める数

LET s=1 !和
LET c=1 !個数

LET f=2
DO UNTIL f>SQR(n)
   LET k=0
   DO WHILE MOD(n,f)=0 !割り切れるなら
   !PRINT f;
      LET k=k+1 !個数
      LET n=n/f
   LOOP
   LET s=s * 1*(1-f^(k+1))/(1-f) !等比数列の和 Σ[i=0,k+1]f^i
   LET c=c * (k+1) !0,1,2,…,k

   LET f=f+1 !次へ
LOOP
IF n>1 THEN !残りの因数
!PRINT n
   LET s=s * 1*(1-n^(1+1))/(1-n)
   LET c=c * (1+1)
END IF

PRINT "和=";s, "個数=";c



!問題2 自然数nに対して、その約数の逆数の和を求める
!60の場合
PRINT 1/1+1/2+1/3+1/4+1/5+1/6+1/10+1/12+1/15+1/20+1/30+1/60 !題意より

PRINT (60+30+20+15+12+10+6+5+4+3+2+1)/60 !通分すると、約数の和÷元の数



!問題3 自然数nに対して、その約数の積を求める
!60の場合
PRINT 1*2*3*4*5*6*10*12*15*20*30*60


!●素因数分解
! n=p^a*q^b*r^c* … 、素数p,q,r,…、整数a,b,c,… なら
! 積 SQR( n^{(a+1)*(b+1)*(c+1)* … } )
! 積 p^{a*(a+1)*(b+1)*(c+1)* … /2} * q^{b*(a+1)*(b+1)*(c+1)* … /2} * r^{c*(a+1)*(b+1)*(c+1)* … /2} * …

!60=2^2*3^1*5^1 より
PRINT SQR(60^12) !SQR(元の数^約数の個数)

LET t1=2*(2+1)*(1+1)*(1+1)/2
LET t2=1*(2+1)*(1+1)*(1+1)/2
LET t3=1*(2+1)*(1+1)*(1+1)/2
PRINT 2^t1 * 3^t2 * 5^t3


END
 

LZW エンコーダーと、デコーダー

 投稿者:SECOND  投稿日:2009年 7月21日(火)18時32分53秒
返信・引用  編集済
  > No.458[元記事へ]

! LZW エンコーダーと、デコーダー
!-----------
OPTION CHARACTER byte
DIM m(501,501)
LET obits0=2             !( 2= 2色~4色, 3= 8色, 4=16色, … 8=256色)
LET N000=2^obits0        ! 色数(予約の登録番号最大+1)
!
LET t_max= 1000  !=使われた色数x辞書への登録文字の長さ。(不詳)【逆引き辞書】
!                !  小さいと辞書クリアー頻度増し、圧縮出力サイズは、悪化するが、
!                ! その分、復元側も、辞書のメモリー消費は、減る。
DIM dic_0(0 TO t_max, 0 TO N000-1), dic_1(0 TO t_max, 0 TO N000-1) !encoder 辞書
!
LET blkfull=255          ! block size max.(~~255)
LET bitfull=12           ! LZW bits max.(~~ 12)
DIM dic$(0 TO 2^bitfull) ! decoder 辞書、収納は、新規の登録番号最大まで。
!
!------------------- テスト原画の作成 -----------------------------------
LET Xw=4
LET Yw=3
MAT m=ZER(Yw,Xw)
MAT READ m
!MAT m=BVAL("03",16)*CON(Yw,Xw)
!     4色(2bits) 横:4 縦:3 の、テスト・パターン
DATA  0,1,2,3
DATA  0,1,2,3
DATA  0,1,2,3
!
PRINT "******************* 原画パターン"; Xw;"x";Yw
FOR j=1 TO Yw
   LET ww$=""
   FOR i=1 TO Xw
      LET ww$=ww$& right$("0"& BSTR$(m(j,i),16),2)& " "
   NEXT i
   PRINT ww$
NEXT j
!
CALL picture_data ! 上記パターンを 実際に、Encode する。原画→ LZW$
CALL decomp_data  ! 上のEncode 出力を 実際に、Decode する。LZW$→ 原画

!------------------------------------------------------------------------
!上のパターンの例
! 02              ! 最小データービット長 … 予約登録番号(0~n-1) のビット長
! 05              ! block size(バイト)
! 44 34 86 3A 05  !…LZW compression bit stream
! 00              ! block end 0
!
!復元側 LZW_decoder 入力は、下の様に並べて、左 ← 右 へ向かって読み取る。
!開始は、辞書 初期化コード(n+0) のビット長で、始める為に、1ビット長い=3

!0~n-1= (0,1,2,3):予約登録番号 ←最小データービット長=2 の意味。
! n+0= 4        :入力開始ビット長を、初期値=3 に戻す。辞書のクリア
! n+1= 5        :処理の終了
! n+2= 6        :辞書、スタートの新規登録番号
!(登録番号) から辞書を読んだ時は、次の番号、
!(登録番号+1) の先頭1data も後に付加する。
!                                 <--------
!                     05       3A       86       34       44
!               00000101 00111010 10000110 00110100 01000100
!         0000 0101 0011 1010 1000 0110 0011 010 001 000 100
!LZW12V           5    3    A    8    6    3   2   1   0   4
!登録番 号              D    C    B    A    9   8   7   6
!--------------------------------------------------------------
!復元data      (n+1)   3    0    2    0    3   2   1   0  (n+0)
!           code end        1    3    1                  reset
!                           2
!------------------------------------------------------------------------
! LZW12Vコードの桁幅は、直前の登録番号と同じ幅で連動、12bitまで増大する。
!------------------------------------------------------------------------
!原 始  |        |Encorder|        |GIF    |Decorder
!データ|バッファ|辞書内容|登録番号|LZW12V |辞書内容 …復元データでもある
!                         110b     100b    …初期化コード4(n)
!0      0
!1      01       01       110b     000b    0
!2      12       12       111b     001b    1
!3      23       23       1000b    010b    2
!0      30       30       1001b    0011b   3
!1      01
!2      012      012      1010b    0110b   01
!3      23
!0      230      230      1011b    1000b   23
!1      01
!2      012
!3      0123     0123     1100b    1010b   012
!       3                 1101b    0011b   3
!                                  0101b   …終了コード5(n+1)
!最小データービット長の範囲は2〜8で、1は無く2色4色の区別無し。
!LZW_encoder は 最小データービット長の値だけが 支配的で、2色でも、
!LZW コードは、2ビット1画素(0,1,2,3) で処理、(,,2,3) は、空席。


!------------------- 原画から、画像データ LZW$ の作成。------------------
!画像配列 m(1~Yw,1~Xw) !! 注意 x,y の順 mat read m(y,x)
SUB inppix             !! ask pixel array(x0,y0) m(x,y)
   LET lx=lx+1
   IF Xw< lx THEN
      LET lx=1
      LET ly=ly+1
   END IF
   IF ly<=Yw THEN LET bx=m(ly,lx) ! data on bx
END SUB

SUB picture_data
   PRINT "******************* 圧縮( LZW エンコード )"
   LET LZW$=CHR$(obits0)
   CALL prthex(CHR$(obits0),"最小データービット長") !予約登録番号最大のビット長
   !---
   CALL LZW_encoder
   CALL outcode            !flush last chained dic.number on ax
   LET ax=N000+1
   CALL outcode            !code end
   CALL out_flush
   !---
   LET LZW$=LZW$& CHR$(0)  !block end
   CALL prthex(CHR$(0),"block size") !モニター
END SUB

SUB LZW_encoder
   LET lx=1 -1 !画像配列 start pointer
   LET ly=1
   CALL inppix             !data on bx
   LET pdata$=""           !clear output byte buffer
   LET oacc$=""            !clear output bit buffer
   LET owidth=obits0+1     !starting bit width
   DO
      LET ax=N000          !reset code
      CALL outcode
      MAT dic_0=ZER        !clear dic.number
      MAT dic_1=ZER        !clear dic.chain
      LET thead=1          !reset make_table pointer
      LET dicnum=N000+2    !reset new dic.number
      LET owidth=obits0+1  !starting bit width
      DO
         LET di=0                  !top table
         LET dic_0(di,bx)=bx       !bx as reserved dic.number
         DO
            LET ax=dic_0(di,bx)    !---latch last chained dic.number
            IF dic_1(di,bx)>0 THEN LET di=dic_1(di,bx) ELSE CALL make_table
            CALL inppix            ! next bx
            IF Yw< ly THEN EXIT SUB
         LOOP UNTIL dic_0(di,bx)=0 !---until no dic.number
         LET dic_0(di,bx)=dicnum   ! new dic.number, bx as tail& next top
         CALL outcode              ! write ax, last chained dic.number
         LET owidth=LEN( BSTR$(dicnum,2) ) ! remake owidth
         LET dicnum=dicnum+1
      LOOP UNTIL dicnum>2^bitfull-1 OR thead>t_max !bits full or dic.full
   LOOP
END SUB

SUB make_table
   LET dic_1(di,bx)=thead !chained table pointer
   LET di=thead           !new table head
   LET thead=thead+1
END SUB

SUB outcode
   LET oacc$=right$("00000000000"& BSTR$(ax,2),owidth)& oacc$
   DO WHILE LEN(oacc$)>=8
      LET pdata$=pdata$& CHR$(BVAL(right$(oacc$,8),2))
      LET oacc$=oacc$(1:LEN(oacc$)-8)
      IF blkfull=LEN(pdata$) THEN CALL bw_sub
   LOOP
END SUB

SUB bw_sub
   LET LZW$=LZW$& CHR$(LEN(pdata$))& pdata$
   CALL prthex( CHR$(LEN(pdata$)),"block size")      !モニター
   CALL prthex( pdata$,"LZW compression bit stream") !モニター
   LET pdata$=""
END SUB

SUB out_flush
   IF oacc$<>"" THEN LET pdata$=pdata$& CHR$(BVAL(oacc$,2) )
   LET oacc$=""
   IF pdata$>"" THEN CALL bw_sub
END SUB

!---------------- モニター共通パーツ
SUB prthex(d$,w$)
   LET ww$=""
   FOR ii=1 TO LEN(d$)
      LET ww$=ww$& right$("0"& BSTR$(ORD(d$(ii:ii)),16),2)& " "
   NEXT ii
   IF w$>"" THEN LET ww$=ww$& "; "& w$
   PRINT ww$
END SUB


!------------------- 画像データ LZW$ から、原画へ戻す。------------------
SUB decomp_data
   PRINT "******************* 復元( LZW デコード )"
   LET obits0=ORD(LZW$(1:1))
   CALL prthex(CHR$(obits0),"最小データービット長") !モニター
   LET N000=2^obits0
   LET li=2                               !start input pointer
   LET blkend=0                           !clear input block pointer
   LET iacc$=""                           !clear input bit buffer
   LET pdata$=""                          !clear output byte buffer
   CALL LZW_decoder
   FOR i=1 TO LEN(pdata$) STEP Xw
      CALL prthex(pdata$(i:i+Xw-1),"")    !モニター
   NEXT i
   !--- check block_end
   CALL prthex( LZW$(li:li),"block size") !モニター
END SUB

SUB LZW_decoder
   DO
      LET dicnum=N000+2-1                   !start dic.number-1
      DO
         LET iwidth=LEN( BSTR$(dicnum,2) )  !remake iwidth
         IF  bitfull< iwidth THEN LET iwidth=bitfull !to handle BAD encode
         LET dicnum=dicnum+1
         CALL inpcode                       !data on bx
         IF bx=-1 OR bx=N000+1 THEN
            EXIT SUB
         ELSEIF bx=N000 THEN
            EXIT DO
         ELSE
            IF bx< N000 THEN
               LET dic$(dicnum)=CHR$(bx)
            ELSE
               LET dic$(dicnum)=dic$(bx)
               LET dic$(dicnum)=dic$(dicnum)& dic$(bx+1)(1:1)
            END IF
            LET pdata$=pdata$& dic$(dicnum)
         END IF
      LOOP
   LOOP
END SUB

SUB inpcode
   LET bx=-1
   DO WHILE LEN(iacc$)< iwidth
      IF blkend<=li THEN
         LET blksize=ORD(LZW$(li:li))
         CALL prthex(CHR$(blksize),"block size") !モニター
         IF blksize=0 THEN EXIT SUB
         LET li=li+1
         LET blkend=li+blksize
      END IF
      LET iacc$=right$("0000000"& BSTR$(ORD(LZW$(li:li)),2),8)& iacc$
      LET li=li+1
   LOOP
   LET bx=BVAL(right$(iacc$,iwidth),2)
   LET iacc$=iacc$(1:LEN(iacc$)-iwidth)
END SUB

END
 

修正メモ

 投稿者:SECOND  投稿日:2009年 7月22日(水)21時24分21秒
返信・引用  編集済
  > No.460[元記事へ]

LZW_decoder 内に大きなバグが、有りました。すみません、全リスト交換して下さい。
IF bx=999 〜、LET bx=999  (訂正)→IF bx=-1 〜、LET bx=-1

<追記>
一般の GIF ファイルの中には、12bit幅の登録番号が、(0~4095)を越えて、 2^12(4096)
13bit まで行くものが、少ないですが、有りました。
(後続の符号が、13bit の
 リセット・コードになって、間に合わない所を、無理に、12bitで、デコードさせる。)

  IF  bitfull< iwidth THEN LET iwidth=bitfull !to handle BAD encode

LZW_decoder 中、この行の追加は、その対策です。その代わり、
LZW_decoder の持つ柔軟で、任意の bit幅への 追従性が失われ、bitfull=12 でないと、
12bit のデコードが、出来ません。
上記の様な(不正?)エンコード対応、が 無ければ、bitfull=15 でも、それ以上でも、
エンコーダーに従属して、12bit も兼用で、デコード出来ます。
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 7月23日(木)11時11分48秒
返信・引用  編集済
  > No.459[元記事へ]

自然数nを2つ以上の連続する自然数の和に分解する
!●数列によるアプローチ

!例. n=9の場合
! 1+2+3+4+5+ … +9 4で条件を満たさない
!  2+3+4+5+ … +9 4で条件を満たす
!   3+4+5+ … +9 5で条件を満たさない
!    4+5+ … +9 5で条件を満たす
!     :
!       7+8+9 8で条件を満たさない
!        8+9 9で条件を満たさない
!高々nまでの和を求めて、元の数に等しくなるか確認する

LET n=9 !求める数

FOR a=1 TO n-1 !初項
   LET s=0
   FOR m=a TO n !高々nまでの和
      LET s=s+m

      IF s=n THEN !等しいなら
         FOR k=a TO m !結果を表示する
            PRINT "+";k;
         NEXT k
         PRINT "=";s !検算
      END IF

      IF s>=n THEN EXIT FOR !これ以降は条件を満たさないので、次へ
   NEXT m
NEXT a


!●別解

LET n=9 !求める数

FOR a=1 TO n-1 !初項
   LET d=1 !初項a、公差dの等差数列の第m項までの和
   FOR m=1 TO n !高々n項まで
      LET s=m*(2*a+(m-1)*d)/2 !和の公式

      IF s=n THEN !等しいなら
         FOR k=1 TO m !結果を表示する
            PRINT "+";a+(k-1)*d; !一般項の公式
         NEXT k
         PRINT "=";s !検算
      END IF

      IF s>=n THEN EXIT FOR !これ以降は条件を満たさないので、次へ
   NEXT m
NEXT a



!●2次方程式の解によるアプローチ

!例. n=9の場合
!  1+2+3+4+5+ … +t a=1、t=3.772…
! 1+ 2+3+4+5+ … +t a=2、t=4
! 1+2+ 3+4+5+ … +t a=3、t=4.424…
! 1+2+3+ 4+5+ … +t a=4、t=5
!     :
! 1+2+3+4+5+6+ 7+8+t a=7、t=7.262…
! 1+2+3+4+5+6+7+ 8+t a=8、t=8.116…
!1〜kまでの和はk*(k+1)/2より、a,a+1,…,tまでの和は、t*(t+1)/2-(a-1)*a/2となる。
!これがnと等しい。aを固定すると、2次方程式 t^2+t-(2*n+(a-1)*a)=0 の解となる。

LET n=9 !求める数

FOR a=1 TO n-1 !aを固定する
   LET D=1*1-4*1*(-(2*n+(a-1)*a)) !判別式
   IF D>=0 THEN !実数解なら
      LET t=(-1+SQR(D))/2 !1つ目の解
      !PRINT a;t !debug
      IF t>0 AND INT(t)=t THEN !tは自然数なら
         FOR k=a TO t !結果を表示する
            PRINT "+";k;
         NEXT k
         PRINT "=";t*(t+1)/2-(a-1)*a/2 !検算
      END IF

      LET t=(-1-SQR(D))/2 !2つ目の解 ※こちらが条件を満たすことはない
      !PRINT a;t !debug
      IF t>0 AND INT(t)=t THEN
         FOR k=a TO t
            PRINT "+";k;
         NEXT k
         PRINT "=";t*(t+1)/2-(a-1)*a/2
      END IF
   END IF
NEXT a



!●約数によるアプローチ

!例. n=9の場合
! 約数は1,3,9。1を除く奇数の約数に着目する。
! たとえば、nが3で割り切れることより、3等分できる。すなわち、n=9=3+3+3となる。
! 3のとき、n=3+(3)+3=(3-1)+3+(3+1)=2+3+4 と真ん中の3を基準に、変形する。
! 9のとき、n=1+1+1+1+(1)+1+1+1+1
!       =(1-4)+(1-3)+(1-2)+(1-1)+1+(1+1)+(1+2)+(1+3)+(1+4)
!       =(-3)+(-2)+(-1)+0+1+2+3+4+5
!       =4+5

LET n=9 !求める数

FOR f=2 TO n !1を除く約数をみつける
   IF MOD(n,f)=0 THEN

      IF MOD(f,2)=1 THEN !奇数に着目する
         LET c=INT(f/2)+1 !真ん中の位置を得て、それを基準に変形する

         LET s=0 !相殺部分の範囲を得る
         FOR i=1 TO f
            LET k=n/f + (i-c) !f等分±1,2,3,…
            !PRINT i;k !debug
            LET s=s+k
            IF s>0 THEN PRINT "+";k;
         NEXT i
         PRINT "=";s !検算
      END IF

   END IF
NEXT f


!●別解 奇数が連続する2つの自然数の和で表される

!例. n=9の場合
! 約数は1,3,9。1を除く奇数の約数に着目する。
! たとえば、nが3で割り切れることより、3は倍数となる。すなわち、n=3*3=3+3+3。
! この3を連続する2つの自然数の和で表すと、3=1+2。
! 残りの3も、これを基準に1−1,2,3,…、2+1,2,3,…の和で表す。
! 3のとき、n=3*3=3+3+3=(1+2)+(0+3)+(-1+4)=-1+0+1+2+3+4=2+3+4 と変形する。
! 9のとき、n=9*1=9=(4+5)

LET n=9 !求める数

FOR f=2 TO n !約数をみつける
   IF MOD(n,f)=0 THEN

      IF MOD(f,2)=1 THEN !奇数に着目する
         LET c=(f-1)/2 !連続する2つの自然数c,c+1の和にする

         LET s=0 !相殺部分の範囲を得る
         FOR k=c-n/f+1 TO c+n/f !変形した式を計算する
         !PRINT k !debug
            LET s=s+k
            IF s>0 THEN PRINT "+";k;
         NEXT k
         PRINT "=";s !検算
      END IF

   END IF
NEXT f


END
 

GIF ファイルの解析ツール Ver.2(画像付)

 投稿者:SECOND  投稿日:2009年 7月31日(金)00時29分15秒
返信・引用
  !Page-2 の始め
!------------------- 画像データ LZW$ から、原画を見る。------------------
SUB decomp_data
   PRINT "******************* 復元( LZW デコード )"
   LET obits0=ORD(LZW$(1:1))
   CALL prthex(CHR$(obits0),"最小データービット長") !モニター
   LET N000=2^obits0
   LET li=2                               !start input pointer
   LET blkend=0                           !clear input block pointer
   LET iacc$=""                           !clear input bit buffer
   LET pdata$=""                          !clear output byte buffer
   CALL LZW_decoder
   PRINT "Last_code LEN(LZW$) LEN(pdata$)=";bx;LEN(LZW$);LEN(pdata$) !モニター
   !---
   IF tmod=3 THEN MAT m3=m
   LET ii=1
   IF interl=0 THEN
      CALL intlace( 0, 1) ! start_raster, step !---NO interlace
   ELSE
      CALL intlace( 0, 8) ! start_raster, step !---0~7step8
      WAIT DELAY .5
      CALL intlace( 4, 8) ! start_raster, step !---4~7step8
      WAIT DELAY .5
      CALL intlace( 2, 4) ! start_raster, step !---2~3step4
      WAIT DELAY .5
      CALL intlace( 1, 2) ! start_raster, step !---1~1step2
   END IF
   IF tmod=2 THEN MAT m=ncp(256)*CON ! 256= システム背景色
   IF tmod=3 THEN MAT m=m3
   !--- check block_end
   CALL prthex( LZW$(li:li),"block size") !モニター
   PRINT "******************* 復元終り"
END SUB

SUB intlace( ss, stp)
   FOR j=Yp0 TO Yp0+Ypw-1
      IF MOD(j-Yp0, stp) >=ss THEN
         IF MOD(j-Yp0, stp) >ss THEN LET ii=ii-Xpw
         FOR i=Xp0 TO Xp0+Xpw-1
            WHEN EXCEPTION IN
               LET col=ORD(pdata$(ii:ii))
               IF t_on<>1 OR tcol<>col THEN LET m(i,j)=ncp(col)
               LET ii=ii+1
            USE
            END WHEN
         NEXT i
      END IF
   NEXT j
   MAT PLOT CELLS,IN 0,0; Xsw-1,Ysw-1 :m
END SUB

!-------------
SUB LZW_decoder
   DO
      LET dicnum=N000+2-1                   !start dic.number-1
      DO
         LET iwidth=LEN( BSTR$(dicnum,2) )  !remake iwidth
         IF  bitfull< iwidth THEN LET iwidth=bitfull !to handle BAD file
         LET dicnum=dicnum+1
         CALL inpcode                       !data on bx
         IF bx=-1 OR bx=N000+1 THEN
            EXIT SUB
         ELSEIF bx=N000 THEN
            EXIT DO
         ELSE
            IF bx< N000 THEN
               LET dic$(dicnum)=CHR$(bx)
            ELSE
               LET dic$(dicnum)=dic$(bx)
               LET dic$(dicnum)=dic$(dicnum)& dic$(bx+1)(1:1)
            END IF
            LET pdata$=pdata$& dic$(dicnum)
         END IF
      LOOP
   LOOP
END SUB

SUB inpcode
   LET bx=-1
   DO WHILE LEN(iacc$)< iwidth
      IF blkend<=li THEN
         LET blksize=ORD(LZW$(li:li))
         CALL prthex(CHR$(blksize),"block size") !モニター
         IF blksize=0 THEN EXIT SUB
         LET li=li+1
         LET blkend=li+blksize
      END IF
      LET iacc$=right$("0000000"& BSTR$(ORD(LZW$(li:li)),2),8)& iacc$
      LET li=li+1
   LOOP
   LET bx=BVAL(right$(iacc$,iwidth),2)
   LET iacc$=iacc$(1:LEN(iacc$)-iwidth)
END SUB

SUB prthex(d$,w$)
   LET ww$=""
   FOR ii=1 TO LEN(d$)
      LET ww$=ww$& right$("0"& BSTR$(ORD(d$(ii:ii)),16),2)& " "
   NEXT ii
   IF w$>"" THEN LET ww$=ww$& "; "& w$
   PRINT ww$
END SUB

END
 

GIF ファイルの解析ツール Ver.2(画像付)

 投稿者:SECOND  投稿日:2009年 7月31日(金)00時31分57秒
返信・引用  編集済
  > No.463[元記事へ]

! GIF ファイルの解析ツール Ver.2(画像付)
!-------
! リスト左端アドレスを5桁にした。リスト注釈を大幅修正。復元画像も、
! 表示する様にした。IE6 は、スクリーン背景色を無視して、ブラウザ背景
! のみを、代用するようなので、GIF仕様から外れるが、それに合せた。
! Disposal Method 0,1,2,3 、インタレース画像などが、モニター出来る。
!
OPTION CHARACTER BYTE
LET bitfull=12           ! LZW max.bits (~~ 12)
DIM dic$(0 TO 2^bitfull) ! decoder 辞書
!
FILE GETNAME file$, "gif"
IF file$="" THEN
   PRINT "入力ファイル名が、ありません。"
   STOP
END IF
!
PRINT "入力ファイル:"& file$
OPEN #1: NAME file$, ACCESS INPUT
PRINT "---------"
SET COLOR mode "native"
DIM ncp(0 TO 256)              ! native color palette
LET ncp(256)=BVAL("eeeedd",16) ! 256= システム背景色 BGR
SET AREA COLOR ncp(256)
PLOT AREA: 0,0;1,0;1,1;0,1
CALL gif_head
LET i=MAX( Xsw,Ysw )
SET WINDOW -.1*i,1.1*i, 1.1*i,-.1*i
SET LINE STYLE 3
PLOT LINES:-1,-1;Xsw+.5,-1;Xsw+.5,Ysw+.5;-1,Ysw+.5;-1,-1
DIM m(0 TO Xsw-1,0 TO Ysw-1), m3(0 TO Xsw-1,0 TO Ysw-1)
MAT m=ncp(256)*CON
DO
   CALL blocks_main
LOOP UNTIL b1$=CHR$(BVAL("3B",16))
PRINT "GIF 終端ブロック"
CALL dump(b1$,2,"block label")
PRINT "---------"
CLOSE #1

!----
SUB gif_head
   LET h$=""
   CALL readb( h$,13 )
   IF h$(1:3)="GIF" THEN PRINT "GIF ヘッダー" ELSE CALL error
   LET Xsw= ORD(h$( 8: 8))*256+ORD(h$(7:7))
   LET Ysw= ORD(h$(10:10))*256+ORD(h$(9:9))
   LET sflg=ORD(h$(11:11)) ! スクリーン情報のフラグ
   LET BGco=ORD(h$(12:12))
   LET aspect=ORD(h$(13:13))
   LET b$=right$("0000000"& BSTR$(sflg,2) ,8)
   LET colpix=2^(BVAL(b$(2:4),2)+1)
   LET compal=2^(BVAL(b$(6:8),2)+1)
   CALL dump(h$( 1: 6),6,"Asc") ! GIF識別文字
   CALL dump(h$( 7: 8),2,"screen X_width= "& STR$(Xsw))
   CALL dump(h$( 9:10),2,"screen Y_width= "& STR$(Ysw))
   CALL dump(h$(11:11),2,"flags= "& b$ )
   PRINT TAB(13);b$(1:1);":common_palette on=1/off=0"
   PRINT TAB(11);b$(2:4);":colors/pixel 2^(";b$(2:4);"b+1)= ";STR$(colpix)
   PRINT TAB(13);b$(5:5);":sort on=1/off=0 パレットの、重要度 色順ソート"
   PRINT TAB(11);b$(6:8);":common_palette colors 2^(";b$(6:8);"b+1)= ";STR$(compal)
   CALL dump(h$(12:12),2,"back_ground color= "& STR$(BGco))
   IF aspect=0 THEN LET b$=".." ELSE LET b$=STR$(aspect)
   CALL dump(h$(13:13),2,"アスペクト比 H:V=, 0 は 1:1 その他("& b$& "+15):64" )
   CALL palette("common_パレット", c_p$, sflg)
END SUB

!----
SUB blocks_main
   LET b1$=""
   CALL readb( b1$, 1)
   IF     b1$=CHR$(BVAL("21",16)) THEN !追加データ・ブロック
      CALL option_block
   ELSEIF b1$=CHR$(BVAL("2C",16)) THEN !画像ブロック
      CALL picture_block
   ELSEIF b1$=CHR$(BVAL("3B",16)) THEN !GIF 終端ブロック
   ELSE
      CALL error
   END IF
END SUB

!---追加データ・ブロック。
SUB option_block
   PRINT "追加データ・ブロック"
   CALL readb( b1$,1)        ! w9$= readb_last_byte
   IF w9$=CHR$(BVAL("F9",16)) THEN
      LET im$=b1$
      CALL dump(im$,2,"イメージコントロール・ブロック")
      CALL blocks(im$,0,"",1) ! non print (data, byte/行, 注釈, 要求blocks)
      LET iflg=ORD(im$(4:4)) ! フラグ
      LET imtm=ORD(im$(6:6))*256+ORD(im$(5:5))
      LET tcol=ORD(im$(7:7))
      LET b$=right$("0000000"& BSTR$(iflg,2),8)
      LET t_on=VAL(b$(8:8))
      LET tmod=BVAL(b$(4:6),2)
      CALL dump(im$(4:4),2,"flags= "& b$ )
      PRINT TAB(11);b$(1:3);":blank"
      PRINT TAB(11);b$(4:6);":"
      PRINT TAB(15);"000= 描画後、そのまま、次の背景へ渡す"
      PRINT TAB(15);"001= 描画後、そのまま、次の背景へ渡す"
      PRINT TAB(15);"010= 描画後、back_ground color と取替、次の背景へ渡す"
      PRINT TAB(15);"011= 描画後、描画前の画像を、次の背景へ渡す"
      PRINT TAB(13);b$(7:7);":user click on=1/off=0"
      PRINT TAB(13);b$(8:8);":透明色のスイッチ on=1/off=0"
      CALL dump(im$(5:6),2,"フレーム表示時間= "& STR$(imtm)& " x10ms" )
      CALL dump(im$(7:7),2,"透明色= "& STR$(tcol) )
      CALL blocks(im$,16,"",999) ! (data, byte/行, 注釈, 要求blocks)
   ELSEIF w9$=CHR$(BVAL("FE",16)) THEN
      LET co$=b1$
      CALL dump(co$,2,"コメント・ブロック")
      CALL blocks(co$,8,"Asc",999) ! (data, byte/行, 注釈, 要求blocks)
   ELSEIF w9$=CHR$(BVAL("FF",16)) THEN
      LET ap$=b1$
      CALL dump(ap$,2,"アプリケーション・ブロック")
      CALL blocks(ap$,8,"Asc",1) ! (data, byte/行, 注釈, 要求blocks)
      IF ap$(4:11)="NETSCAPE" THEN
         CALL blocks(ap$,0,"",1) ! non print (data, byte/行, 注釈, 要求blocks)
         CALL dump(ap$(16:16),2,"extension code= 01~07 next data type")
         IF MOD(ORD(ap$(16:16)),8)=1 THEN
            LET rept=ORD(ap$(18:18))*256+ORD(ap$(17:17))
            CALL dump(ap$(17:18),2,"繰返し回数= "& STR$(rept)& " (0=endless)")
         ELSE
            CALL dump(ap$(17:LEN(ap$)),2,"02= 32bit buffering size, 03~07= ?")
         END IF
      END IF
      CALL blocks(ap$,8,"Asc",999) ! (data, byte/行, 注釈, 要求blocks)
   ELSEIF w9$=CHR$(BVAL("01",16)) THEN
      LET tx$=b1$
      CALL dump(tx$,2,"テキスト・イメージ・ブロック")
      CALL blocks(d$,8,"Asc",999) ! (data, byte/行, 注釈, 要求blocks)
   ELSE
      CALL error
   END IF
END SUB

!-------
SUB blocks(d$,m,t$,n)     ! d$=data, m=byte/行, t$=注釈, n=要求blocks
   FOR n=1 TO n
      CALL readb(d$,1)             ! w9$= readb_last_byte ! =block Size
      CALL dump(w9$,1,"block size")
      IF w9$=CHR$(0) THEN EXIT SUB ! block End
      LET s=LEN(d$)
      CALL readb(d$,ORD(w9$))      ! block data
      IF 0< m THEN CALL dump(d$(s+1:LEN(d$)),m,t$)
   NEXT n
END SUB

SUB readb(d$,cx) !cx=bytes size
   FOR i=1 TO cx
      CHARACTER INPUT #1,IF MISSING THEN EXIT FOR :w9$
      LET d$=d$& w9$
   NEXT i
   IF i<=cx THEN CALL error
END SUB

SUB dump(d$,m,t$)   ! t$="comment" →;comment  t$="Asc" →;"ascii.dump"
   FOR j=1 TO LEN(d$) STEP m
      LET ww$=right$("0000"& BSTR$(adr,16),5)& " "
      FOR i=j TO MIN(j+m-1, LEN(d$))
         LET ww$=ww$& " "& right$("0"& BSTR$( ORD(d$(i:i)),16),2)
         LET adr=adr+1
      NEXT i
      IF t$>"" THEN
         LET ww$=ww$& REPEAT$(" ",6+3*m-LEN(ww$))
         IF t$="Asc" THEN                                ! ascii.dump
            LET ww$=ww$& " ;"""
            FOR i=j TO MIN(j+m-1, LEN(d$))
               IF " "<=d$(i:i) THEN LET ww$=ww$& d$(i:i) ELSE LET ww$=ww$& "."
            NEXT i
            LET ww$=ww$& """"
         ELSE
            IF m=3 THEN LET ww$=ww$& " ;"& STR$(IP(j/3)) ! パレット色番号
            IF j=1 THEN LET ww$=ww$& " ;"& t$            ! comment
         END IF
      END IF
      PRINT ww$ ! 行単位、テキスト画面のピカつき減少、高速。
   NEXT j
END SUB

!-------
SUB picture_block
   PRINT "画像ブロック"
   LET pi$=b1$
   CALL readb( pi$,9)
   CALL dump(pi$(1:1),2,"block label")
   LET Xp0=ORD(pi$(3:3))*256+ORD(pi$(2:2))
   LET Yp0=ORD(pi$(5:5))*256+ORD(pi$(4:4))
   LET Xpw=ORD(pi$(7:7))*256+ORD(pi$(6:6))
   LET Ypw=ORD(pi$(9:9))*256+ORD(pi$(8:8))
   CALL dump(pi$(2:3),2,"picture.X0_position left= "& STR$(Xp0))
   CALL dump(pi$(4:5),2,"picture.Y0_position top= "& STR$(Yp0))
   CALL dump(pi$(6:7),2,"picture.X_width= "& STR$(Xpw))
   CALL dump(pi$(8:9),2,"picture.Y_width= "& STR$(Ypw))
   LET pflg=ORD(pi$(10:10)) ! 画像情報のフラグ
   LET b$=right$("0000000"& BSTR$(pflg,2),8)
   CALL dump(pi$(10:10),2,"flags= "& b$ )
   LET interl=VAL(b$(2:2))
   LET pripal=2^(BVAL(b$(6:8),2)+1)
   PRINT TAB(13);b$(1:1);":private_palette on=1/off=0"
   PRINT TAB(13);b$(2:2);":interlace on=1/off=0, 1~step8 5~step8 3~step4 2~step2"
   PRINT TAB(13);b$(3:3);":sort on=1/off=0 パレットの、重要度 色順ソート"
   PRINT TAB(12);b$(4:5);":blank"
   PRINT TAB(11);b$(6:8);":private_palette colors 2^(";b$(6:8);"b+1)= ";STR$(pripal)
   CALL palette("private_パレット", p_p$, pflg)
   !---
   PRINT "画像データ"
   LET LZW$=""
   CALL readb( LZW$,1)
   CALL dump(LZW$,1,"最小データ・ビット長")
   !--- LZW データ(size:data, size:data, … 0 )
   CALL blocks(LZW$,16,"",9999) ! (data, byte/行, 注釈, 要求blocks)
   CALL decomp_data
END SUB

SUB palette(n$, p$, pf)
   PRINT n$;
   LET p$=""
   IF IP(pf/128)>0 THEN ! pf AND 0x80
      PRINT
      CALL readb(p$, 3*2^(MOD(pf,8)+1)) ! pf AND 0x07
      CALL dump(p$,3,"R G B")
      CALL palette10(n$, p$, pf)
   ELSE
      LET ww$=" 無し。"
      IF n$(1:1)="p" AND c_p$>"" THEN
         LET ww$=ww$& "→ common_パレット 使用。"
         IF bk_p$(1:1)<>"c" THEN CALL palette10("common", c_p$, sflg)
      END IF
      PRINT ww$
   END IF
END SUB

SUB palette10(n$, p$, pf)
   FOR i=1 TO 3*2^(MOD(pf,8)+1) STEP 3
      LET ncp(IP(i/3))= ORD(p$(i:i))+256*ORD(p$(i+1:i+1))+65536*ORD(p$(i+2:i+2))
   NEXT i
   LET bk_p$=n$
END SUB

SUB error
   beep
   PRINT "File Error Stop"
   STOP
END SUB

!
Page-2 へ続く
 

本年度慶応大学入試問題について

 投稿者:北摂三太郎  投稿日:2009年 8月 2日(日)01時52分57秒
返信・引用
  本年度大学入試プログラミングの問題
 慶応・環境情報
フィボナッチ数列の最初の20項を出力する問題で
模範解答とは異なる
150 let b=a-b
160 let a=a+b
としても、正しい出力が得られます。
問題文には、「もっとも適切なものを選び・・・」と
書かれているので、これは不正解なのでしょうか?
みなさまのご意見をお聞かせください。
数研、旺文社の正解は、次です。
100 LET a=1
110 LET b=0
120 LET n=0
130 IF n=20 THEN GOTO 190
140 LET n=n+1
150 LET b=a+b
160 LET a=b-a
170 PRINT b
180 GOTO 130
190 END
 

Re: 本年度慶応大学入試問題について

 投稿者:山中和義  投稿日:2009年 8月 2日(日)15時03分48秒
返信・引用  編集済
  > No.465[元記事へ]

北摂三太郎さんへのお返事です。


模範解答の変数a,bの意味を考えてみます。

第1項と第2項も漸化式に吸収して解釈すると
a[1]=a[-1]+a[0]                         =1+0          =1
a[2]=      a[0]+a[1]                    =  0+1        =1
a[3]=           a[1]+a[2]               =    1+1      =2
a[4]=                a[2]+a[3]          =      1+2    =3
a[5]=                     a[3]+a[4]     =        2+3  =5
                                │   ┌────────┘
            一般化すると、  古いb↓   ↓
                                a  + b  → b
a[6]=                          a[4]+a[5]=          3+5=8
   :
   :

これをプログラムにすると
100 LET a=1 !古いb
110 LET b=0 !A[0]
120 LET n=0 !項
130 IF n=20 THEN GOTO 190 !第20項まで
140 LET n=n+1
150 LET b=a+b !=a[n-2]+a[n-1]=A[n](=古いb+b)
160 LET a=b-a !a=b-a=A[n]-a[n-1]=a[n-2]=古いb
170 PRINT n; a; b !第n項を表示する
180 GOTO 130
190 END


a-bが、選択肢にはあるようですので、計算手順(アルゴリズム)が説明できれば
正解と言えると思います。


問題文
 http://www.yozemi.ac.jp/nyushi/sokuho/recent/keio/kankyo/index.html 内「数学 V」を選択
 

Re: 本年度慶応大学入試問題について

 投稿者:SECOND  投稿日:2009年 8月 2日(日)16時10分59秒
返信・引用  編集済
  > No.465[元記事へ]

!同じ出力の得られる方法は、常に、未知な方法も、含んでいるはずで、
!それを探せる事は、とても大切な事だと、思います。(個人的には それが楽しみ)
!採点側の利便を優先される弊害は、仕方がないですね・・・気になるのは、
!模範解答が、for~next を、なぜ使用しなかったのか?2行分が無駄。
!ついでに。私自身、こんな番号合せの試験されたら、0点になりそう。(笑えません)

LET a=1
LET b=0
FOR n=1 TO 20
   LET b=a+b
   LET a=b-a
   PRINT b
NEXT n
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 8月 3日(月)10時49分9秒
返信・引用  編集済
  > No.462[元記事へ]

出力される数列に心当たりが、、、あると思います!?
!ユークリッドの互除法で、4181と6765との最大公約数を求める

LET a=4181 !※a< b
LET b=6765

PRINT b

DO WHILE a<>b !a=bなら終了
   IF a>b THEN
      LET a=a-b !「a-bとbとの最大公約数を求める」に置き換える
      PRINT b !trace
   ELSE
      LET b=b-a
      PRINT a !trace
   END IF
LOOP

PRINT a !最大公約数




!その2 剰余を使った場合

LET a=4181 !※bを出力するためには、a< bとする
LET b=6765

DO UNTIL b=0
   LET t=b
   LET b=MOD(a,b)
   LET a=t
   PRINT a !trace
LOOP

PRINT a !最大公約数


END
 

修正メモ

 投稿者:SECOND  投稿日:2009年 8月 4日(火)09時07分27秒
返信・引用
  > No.464[元記事へ]

大きな GIF ファイルの処理速度が、あまりに遅いので(229KB で18分くらい)
一括処理を止め、文字列変数 LZW$ 、pdata$ の長さが、大きくならないよう、
細切れに処理するようにした。結果は(229KB で3分30秒)になった。反面、
1フレーム分が、セットになっていた LZW$ と pdata$ は、断片のデータが
流れるだけで、保存されなくなった。また、シーケンスが、煩雑でみにくい。
オーバーフローする事が無いので、どんなに大きな GIF でも、処理速度が、
落ちていかない利点はありますが・・
上書き変更するには、良し悪しがあるため、ご希望の方は、下記。
( 直接テキストのリンクで、文字化けしそうです。シフトJIS 手動切換お願い)
http://homepage2.nifty.com/neutro/asm/GIFana21.BAS
 

Re: 本年度慶応大学入試問題について

 投稿者:山中和義  投稿日:2009年 8月 5日(水)15時11分14秒
返信・引用  編集済
  > No.466[元記事へ]

質問への回答ではありませんが、
模範解答の手法を発展されると、項を2数の組で求めることができます。
100 LET a=1 !奇数の項: a[-1]
110 LET b=0 !偶数の項: a[0]
120 LET n=0 !組
130 IF n=10 THEN GOTO 190 !10組まで
140 LET n=n+1
150 LET a=a+b !=a[k-1]+a[k]=a[k+1]
160 LET b=b+a !=b+(a+b)=2*b+a=2*a[k]+a[k-1]=a[k]+(a[k-1]+a[k])=a[k]+a[k+1]=a[k+2]
170 PRINT a; b !2数
180 GOTO 130
190 END
 

Re: 複素数モードの使い方。

 投稿者:白石 和夫  投稿日:2009年 8月10日(月)11時13分37秒
返信・引用  編集済
  > No.471[元記事へ]

SQR関数は,偏角が−π/2より大でπ/2以下である平方根を返すようになっています。
次のように平方根関数sqrtを定義すれば,偏角が0以上π未満であるようになります。
FUNCTION sqrt(x)
   LET x=SQR(x)
   IF x<>0 AND ARG(x)<0 THEN
      LET x=x*(-1)
   END IF
   LET sqrt=x
END FUNCTION
! 以下,使用例
LET x=COMPLEX(-1/2,-SQR(3)/2)
PRINT SQR(x),sqrt(x)
END
複素関数の詳細は,ヘルプの複素関数のページを見てください。
 

Re: 複素数モードの使い方。

 投稿者:山中和義  投稿日:2009年 8月10日(月)16時04分43秒
返信・引用
  > No.471[元記事へ]

大熊 正さんへのお返事です。


複素数の平方根

iを虚数単位とする。複素数z=x+y*iの平方根a+b*iを考える。

(a+b*i)^2=zより、(a^2-b^2)+2*a*b*i=x+y*iとなる。
したがって、連立方程式 a^2-b^2=x、2*a*b=y を解けばよい。

 解く過程は省略

SQR(x+y*i)=±{ SQR((SQR(x^2+y^2)+x)/2) + i*SGN(y)*SQR((SQR(x^2+y^2)-x)/2) }



3番目の式の場合、
W=1 / SQR(x+y*i)
 上式を代入する
 =1 / ±{ SQR((SQR(x^2+y^2)+x)/2) + i*SGN(y)*SQR((SQR(x^2+y^2)-x)/2) }
 共役な数をかけて分母を有理化する
 =±{ SQR((SQR(x^2+y^2)+x)/2) - i*SGN(y)*SQR((SQR(x^2+y^2)-x)/2) } / {(SQR(x^2+y^2)+x)/2 + (SQR(x^2+y^2)-x)/2}
 整理する
 =±{ SQR((SQR(x^2+y^2)+x)/2) - i*SGN(y)*SQR((SQR(x^2+y^2)-x)/2) } / SQR(x^2+y^2)

 

FACT,PERM,COMB関数のバグ

 投稿者:荒田浩二  投稿日:2009年 8月12日(水)22時27分59秒
返信・引用
  階乗,順列,組合せの組込み関数FACT(x),PERM(n,r),COMB(n,r)に不具合を発見したので報告します。

(1) FACT(x)を2進モード,複素数モードで実行した場合、xが小数のとき例外とならず誤った値を返す。
100 OPTION ARITHMETIC NATIVE
110 FOR x=-1 TO 4
120    WHEN EXCEPTION IN
130       PRINT x;FACT(x) ! 整数では問題ない
140    USE
150    END WHEN
160 NEXT x
170 PRINT
180 FOR x=-1 TO 4.0001 STEP 0.1
190    WHEN EXCEPTION IN
200       PRINT x;FACT(x) ! x<-0.5では例外が発生
210    USE
220    END WHEN
230 NEXT x
240 END
上記プログラムを10進15桁,1000桁,有理数の各モードで実行した場合、xが小数のときは例外が発生する。


(2) PERM(n,r);COMB(n,r)を2進モード,複素数モードで実行した場合、rが小数のとき例外とならずrを整数に丸めて得た値を返す。
400 OPTION ARITHMETIC NATIVE
410 LET n=6
420 FOR r=-2 TO 3.0001 STEP 0.1
430    WHEN EXCEPTION IN
440       PRINT n;r;" ---> ";PERM(n,r);COMB(n,r) ! r<-0.5では例外が発生
450    USE
460    END WHEN
470 NEXT r
480 END
上記プログラムを10進15桁,1000桁,有理数の各モードで実行した場合、rが小数のときは例外が発生する。


(3) PERM(n,r),COMB(n,r)でnが負数,小数のとき例外とならず誤った値を返す。
600 LET r=3
610 FOR n=-4 TO 5 STEP 0.2
620    WHEN EXCEPTION IN
630       PRINT n;r;" ===> ";PERM(n,r);COMB(n,r)
640    USE
650    END WHEN
660 NEXT n
670 END
 

Re: FACT,PERM,COMB関数のバグ

 投稿者:白石 和夫  投稿日:2009年 8月13日(木)07時45分46秒
返信・引用  編集済
  > No.475[元記事へ]

ご報告ありがとうございます。
FACT,PERM,COMBの各組込関数は規格外の機能なので,「定義域外の引数に対する動作は不定」が仕様です。(仕様は未確定ともいえます。)
なお,PERM(n,r)の定義域は,rが正の整数です。nは負数や小数でもかまいません。
PERM(n,r)=n(n-1)(n-2)…(n-r+1) で定義されます。
COMB(n,r)は,nが負整数またはrより大きい整数のとき0になります。
なお,COMB(n,r)=PERM(n,r)/FACT(r)で定義すると都合のよいこともあるのですが,内部の処理の都合でそうならないことがあります。
 

Re: FACT,PERM,COMB関数のバグ

 投稿者:荒田浩二  投稿日:2009年 8月13日(木)19時25分32秒
返信・引用
  > No.476[元記事へ]

ご回答いただきありがとうございます。
WHEN〜END WHENの中でFACT関数を使ったところ、10進モードと2進モードでまったく違う結果が出たので、これはバグであろうと思ってしまいました。
どの数値モードでも同じ挙動をするプログラムにするには、これらの関数を使う前に引数の判定をするif文を入れる必要があるようですね。
詳しくご説明していただき理解することができました。ありがとうございました。
 

検証のお願い

 投稿者:GAI  投稿日:2009年 8月14日(金)11時17分50秒
返信・引用
  52枚のトランプをよくシャッフルした後、1〜10の数字を一つ決める。
その数字に従い、まずデックのトップからその枚数だけテーブルに一枚ずつテーブルへ表向きに重ねていく。そして最後に出したカードの数字に従い(ただし絵 札は数字5とする。)手元のパケットから再びカードを最後にカードが出せなくなるまでテーブルへ重ねていくことを繰り返していくとする。この最後のカード に当たるもの(テーブルに表向きに重ねたカードのトップのカード)が、最初に選択した数字の1〜10に関わらず常に一定のカードになるという確率が 5/6(約83%)という法則(クルスカル原理)が成り立つ書かれている書物を読みました。
このことをコンピュータでソフト的に実証して頂けませんか?
 

Re: 検証のお願い

 投稿者:山中和義  投稿日:2009年 8月14日(金)13時39分2秒
返信・引用
  > No.478[元記事へ]

GAIさんへのお返事です。
!クルスカル・カウント(Kruskal count)

LET N=52 !カードの枚数

LET mk$="SCHD" !カードのマーク
LET nm$="A234567890JQK" !カードの番号

DEF s2n(s)=MOD(s-1,13)+1 !連番をカードの番号へ
DEF s2m(s)=INT((s-1)/13)+1 !連番をカードのマークへ


DIM c(N) !カードの並び

SUB card_initialize(c(),N) !カードを整列する
   FOR i=1 TO N
      LET c(i)=i
      !!!PRINT i;s2m(i);s2n(i)
   NEXT i
END SUB

RANDOMIZE
SUB shuffle_randomize(c(),N) !ランダムにシャッフルする
   FOR i=N TO 2 STEP -1
      LET j=INT(RND*(i-1))+1 !1〜i-1
      swap c(i),c(j)
   NEXT i
END SUB
!------------------------------ ここまでがサブルーチン

CALL card_initialize(c,N)
CALL shuffle_randomize(c,N)
MAT PRINT c;

FOR r=1 TO 10 !好きな数字

   LET p=r !その数字の枚数分、トランプを上から順に表向きにして机の上に重ねて配る(順番を崩さないため)

   DO WHILE p<=N !手持ちのトランプの残りがなければ、終了。
      PRINT c(p); !表向きの一番上のトランプの数字

      LET t=s2n(c(p)) !1〜13
      IF t>10 THEN LET t=5 !絵札はすべて5とする

      LET p=p+t !次へ
   LOOP
   PRINT

NEXT r !机の上の表向きのトランプを全て取り上げて裏向きにし、手持ちのトランプの上に戻す

END
 

お礼

 投稿者:GAI  投稿日:2009年 8月15日(土)08時11分9秒
返信・引用
  即座の検証のプログラム何度も動かしてみました。
思ったより同一のカードに辿り着くものなんですね。これはマジックに十分利用できる可能性があります。
この法則を利用する手順を構成したいと思います。
いつも山中さんの腕前には感心させられます。ありがとうございました。
 

do while 〜 loop until

 投稿者:SECOND  投稿日:2009年 8月15日(土)13時18分58秒
返信・引用
  !次の様に、do while と、loop until 両方書いても、期待どうりに なります。が、
!help には、片方の例しか探せません、使ってよいでしょうか。

DEF f(x,y)=SQR(x*y)

CALL while_until( 1,  6 )
CALL while_until( 0, 100)

SUB while_until( x, y)
   PRINT "  x   y  f(x,y)"
   DO WHILE f(x,y)< 20
      PRINT USING "### ###  ##.###":x,y,f(x,y)
      LET x=x+1
      LET y=y-1
   LOOP UNTIL y<=x
END SUB

END
 

Re: do while 〜 loop until

 投稿者:白石 和夫  投稿日:2009年 8月16日(日)07時36分49秒
返信・引用  編集済
  > No.481[元記事へ]

Full BASIC規格は,do文かloop文の一方にしか「出口条件」を書けないというような規定を含みません。
なので,do文とloop文の両方にWHILEまたはUNTILを書いても規格外のプログラムではありません。
ついでに言うと,これにさらにEXIT DO文を追加することもできます。
 

Re: do while 〜 loop until

 投稿者:荒田浩二  投稿日:2009年 8月16日(日)09時28分45秒
返信・引用
  > No.481[元記事へ]

白石先生も書かれてますが,JIS規格を読むと禁止はしていないですね。
"WHILE 論理式"や"UNTIL 論理式"を出口条件と呼ぶらしいですが,do行とloop行の出口条件は独立しているようです。

------------------------------------------------------------------------------------------
8.3 繰返し構造

8.3.4 意味
(1) 出口条件は,機能語WHILEに続く論理式の値が偽であるか,又は機能語UNTILに続く論理式の値が
    真であれば,繰返し区から出ることを指示する。
(2) プログラムの実行がdo行に達した時,do行の中に出口条件があれば,それが評価される。出口条件
    がないとき,又は出口条件が繰返し区から出ることを指示しないときには,次の行から実行を続ける。
    出口条件が繰返し区から出ることを指示するときには,対応するloop行の次の行から実行を続ける。
     プログラムの実行がloop行に達した時,loop行の中に出口条件があれば,それが評価される。出口
    条件がないとき,又は出口条件が繰返し区から出ることを指示しないときには,対応するdo行から
    実行を続ける。出口条件が繰返し区から出ることを指示するときには,loop行の次の行から実行を続
    ける。
------------------------------------------------------------------------------------------

下記の「JIS検索」のページから規格の閲覧が可能です。

http://www.jisc.go.jp/app/JPS/JPSO0020.html

「JIS規格名称からJISを検索」に「BASIC」と入力。("basic"は不可)
 

do while 〜 loop until

 投稿者:SECOND  投稿日:2009年 8月16日(日)11時02分43秒
返信・引用
  白石先生、荒田さん たいへん時間のかかる調査を、ありがとうございました。  

答えが知りたい

 投稿者:GAI  投稿日:2009年 8月18日(火)18時04分28秒
返信・引用
  <問題>
整数nが与えられたとき、0〜nの間の全ての数を書くのに必要とされる「1」の数を返す関数をf(n)とする。(例 f(13)=6 )
f(1)=1であるが、一般にf(n)=n
となるような、2番目に大きいnを求めよ。
なる問題の答えを知るプログラムをお教えください。
 

Re: 答えが知りたい

 投稿者:山中和義  投稿日:2009年 8月18日(火)20時22分41秒
返信・引用
  > No.485[元記事へ]

GAIさんへのお返事です。

> f(1)=1であるが、一般にf(n)=nとなるような、2番目に大きいnを求めよ。

!n=13の場合
!0,1,2,3,4,5,6,7,8,9,10,11,12,13より、「1」の数は6個となる。
!∴f(13)=6

OPTION ARITHMETIC NATIVE

LET fn=0 !1の数

FOR n=0 TO 2^31-1 !範囲

   LET t=n !0〜nを表現する

   DO WHILE t>0 !各桁が1の数をかぞえる
      IF MOD(t,10)=1 THEN LET fn=fn+1
      LET t=INT(t/10)
   LOOP

   IF fn=n THEN PRINT "f(";n;")=";fn !f(n)=nのなら

NEXT n

END


実行結果
f( 0 )= 0
f( 1 )= 1
f( 199981 )= 199981 ← これ?
f( 199982 )= 199982
f( 199983 )= 199983
f( 199984 )= 199984
f( 199985 )= 199985
f( 199986 )= 199986
f( 199987 )= 199987
f( 199988 )= 199988
f( 199989 )= 199989
f( 199990 )= 199990
f( 200000 )= 200000
f( 200001 )= 200001
f( 1599981 )= 1599981
f( 1599982 )= 1599982
f( 1599983 )= 1599983
f( 1599984 )= 1599984
 :
 :
 

ヘ〜なるほど!!

 投稿者:GAI  投稿日:2009年 8月18日(火)21時04分4秒
返信・引用
  実験的に1000位まで調べていたが、なかなか見つからずお手上げ状態でした。
こんなことをして見つけ出すことは答えの199981をみてとても不可能であることが分かりました。
こんなにも次の数が離れているのが不思議です。
これは計算機がなければ分からない(気づかない)ことなんでしょうね。
でも誰がこんな問題を考え出すのか(気づく)不思議です。
 

追伸

 投稿者:GAI  投稿日:2009年 8月19日(水)07時59分5秒
返信・引用
  このプログラムを長時間動かしていたら、次のことが判明しました。
1から1111111111までの数字を全て書き連ねたとすると、
「1」を1111111111回書くことになる。
(だからなんなんねん・・・という声が聞こえてきそうですが)
 

Re: 答えが知りたい

 投稿者:山中和義  投稿日:2009年 8月20日(木)10時17分38秒
返信・引用
  > No.486[元記事へ]

●各桁での調査範囲はあるか?

前出のプログラムでは、すべての数を検証しているが、次のプログラムを実行することで、
その結果の推測より、範囲が限定できそうだ。
OPTION ARITHMETIC NATIVE

LET fn=0 !1の数

FOR k=1 TO 12 !範囲

   LET n=10^k-1 !9,99,999,9999,…
   PRINT "f(";n;")=";

   FOR i=INT(n/10)+1 TO n !0〜nを表現する

      LET t=i !各桁の1の数をかぞえる
      DO WHILE t>0
         IF MOD(t,10)=1 THEN LET fn=fn+1
         LET t=INT(t/10)
      LOOP

   NEXT i

   PRINT fn !結果を表示する

NEXT k

END

実行結果
f( 9 )= 1
f( 99 )= 20
f( 999 )= 300
f( 9999 )= 4000
f( 99999 )= 50000
f( 999999 )= 600000
f( 9999999 )= 7000000
f( 99999999 )= 80000000
 :
 :
たとえば、3桁はf( 999 )= 300 より、n=100〜300の範囲を調べればよいことになる。
(証明)
1桁の場合、自明。
2桁の場合、一の位が1は、10通り。十の位が1は、10通り。2*10=20通り。
k桁の場合、1つの桁を1に固定したとき、残りの桁の場合の数は、10^(k-1)通り。
これがk桁あるので、k*10^(k-1)通りとなる。
(証明終り)
したがって、0〜10^k-1(kは桁数)では、「1」の数は f(10^k-1)=k*10^(k-1) となる。

また、f(10^10-1)=10^10から、f(10,000,000,000)=10,000,000,001となる。
これより、n=10^10以降はf(n)>nが予想される。


 0〜10^10の範囲で見つかる1,111,111,110は、「最大の数?」
なら

  > f(1)=1であるが、一般にf(n)=nとなるような、2番目に大きいnを求めよ。
は、
 535,200,001
 

勘違いでした

 投稿者:GAI  投稿日:2009年 8月20日(木)12時14分40秒
返信・引用
  最大が1,111,111,110でした。
次の1,111,111,111での「1」の個数は
1,111,111,120(個)になるんでした。
ちなみに途中13,199,998や117,463,825などが前後のnに何の関連も無く解の中に含まれてくるのが面白いです。
 

Re: 答えが知りたい

 投稿者:荒田浩二  投稿日:2009年 8月21日(金)12時03分41秒
返信・引用
  > No.489[元記事へ]

p進法についても10進法と同様のことが言えそうです。
『各数値をp進法で表現したとき,f(n)=nとなる最大のnは n=p^(p-1)+p^(p-2)+…+p^2+p』
つまり「末位が0で他の桁が1であるp桁の数」ということです。p=4ならばn=1110
山中和義さんの投稿記事にある"10"を"p"に置き換えれば,ほとんどの場合p進法に一般化できそうです。

OPTION ARITHMETIC NATIVE
DECLARE FUNCTION change
DIM sum1(2 TO 10),max_n(2 TO 10)
MAT sum1=ZER
PRINT USING "##### ############(=>#########)":"p進法","f(n)=n最大値","10進数"
FOR n=1 TO 7^7
   FOR p=2 TO 7  ! p=8以上は個々に計算しないと時間がかかる
      LET x=n
      DO
         IF MOD(x,p)=1 THEN LET sum1(p)=sum1(p)+1
         LET x=INT(x/p)
      LOOP UNTIL x=0
      IF sum1(p)=n THEN LET max_n(p)=n ! f(n)=n
   NEXT p
NEXT n
FOR p=2 TO 10
   PRINT USING "  ## ###########  (=##########)":p,change(max_n(p),p),max_n(p)
NEXT p
!
FUNCTION change(x,p) ! 10進数をp進数に変換
   LET s,k=0
   DO
      LET s=MOD(x,p)*10^k+s
      LET k=k+1
      LET x=INT(x/p)
   LOOP UNTIL x=0
   LET change=s
END FUNCTION
END
 

バグ?INT関数

 投稿者:山中和義  投稿日:2009年 8月23日(日)19時12分28秒
返信・引用
  10進モードと2進モードで値が異なります。
これらは有効桁数による計算誤差でしょうか?
!LET p=10 !例1
!LET n=1000
!LET p=5 !例2
!LET n=625
LET p=7 !例3
LET n=49
LET x1=LOG(n)/LOG(p) !整数部分が異なる
LET x2=INT(LOG(n)/LOG(p)) !
PRINT x1; x2; INT(x1)
END
 

Re: バグ?INT関数

 投稿者:荒田浩二  投稿日:2009年 8月24日(月)07時37分8秒
返信・引用
  > No.492[元記事へ]

下のプログラムを[オプション][数値][表示桁数を多く]にチェックをいれて実行してみてください。

ヘルプの[操作][オプションメニュー][数値]によると、実際に計算される数値と表示される数値の精度に違いがあるようです。
例1では、2進モードでx1は19桁目までは 2.999999999999999555 の値を持ちますが通常表示では15桁に丸められ 3 と表示されます。
例2例3は「10進15桁モードでは数値式とその値を代入した変数とでは精度が異なる」ことに起因すると思われます。
たとえば次の小プログラムでも、10進モードでは a/7 と b は異なる値になります。
   10 LET a=1
   20 LET b=a/7
   30 PRINT a/7 ; b
   40 END


OPTION ARITHMETIC DECIMAL
!LET p=10 !例1
!LET n=1000
!LET p=5 !例2
!LET n=625
LET p=7 !例3
LET n=49
LET x1=LOG(n)/LOG(p) !整数部分が異なる
LET x2=INT(LOG(n)/LOG(p)) !
PRINT "LOG(n)/LOG(p) =";LOG(n)/LOG(p)
PRINT "x1 =";x1
PRINT "INT(LOG(n)/LOG(p)) =";INT(LOG(n)/LOG(p))
PRINT "INT(x1) =";INT(x1)
PRINT "x2 =";x2
PRINT
CALL binary(STR$(p),STR$(n))
PRINT
CALL thousand(STR$(p),STR$(n))
END

EXTERNAL SUB binary(p$,n$)
OPTION ARITHMETIC NATIVE
LET p=VAL(p$)
LET n=VAL(n$)
LET x1=LOG(n)/LOG(p) !整数部分が異なる
LET x2=INT(LOG(n)/LOG(p)) !
PRINT "LOG(n)/LOG(p) =";LOG(n)/LOG(p)
PRINT "x1 =";x1
PRINT "INT(LOG(n)/LOG(p)) =";INT(LOG(n)/LOG(p))
PRINT "INT(x1) =";INT(x1)
PRINT "x2 =";x2
END SUB

EXTERNAL SUB thousand(p$,n$)
OPTION ARITHMETIC DECIMAL_HIGH
LET p=VAL(p$)
LET n=VAL(n$)
LET x1=LOG(n)/LOG(p) !整数部分が異なる
LET x2=INT(LOG(n)/LOG(p)) !
PRINT "LOG(n)/LOG(p) =";LOG(n)/LOG(p)
PRINT "x1 =";x1
PRINT "INT(LOG(n)/LOG(p)) =";INT(LOG(n)/LOG(p))
PRINT "INT(x1) =";INT(x1)
PRINT "x2 =";x2
END SUB
 

Re: バグ?INT関数

 投稿者:山中和義  投稿日:2009年 8月24日(月)13時42分56秒
返信・引用  編集済
  > No.493[元記事へ]

自然数nのp進法表記での桁数を求めるプログラムをつくるときに気づきました。
思わぬ落とし穴です。直接、進数変換して桁数を求めることにします。
ありがとうございます。
LET STR1$="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" !p進法の数字
FUNCTION ExBSTR$(n,p) !非負の整数nをp進法で表記する
   LET s$=""
   DO
      LET nn=INT(n/p)
      LET t=n-nn*p !MOD(n,p)
      LET s$=STR1$(t+1:t+1)&s$ !下の位から
      LET n=nn
   LOOP UNTIL n=0
   LET ExBSTR$=s$
END FUNCTION


LET p=5 !進数

FOR n=1 TO p^p !自然数

   LET x=INT(LOG(n)/LOG(p))+1 !桁数
   LET x2=INT(LOG2(n)/LOG2(p))+1
   LET x10=INT(LOG10(n)/LOG10(p))+1
   LET k=g(n,p) !進数変換による
   IF k<>x OR k<>x2 OR k<>x10 THEN PRINT n; STR$(p);"#";ExBSTR$(n,p), k; x; x2; x10

NEXT n


FUNCTION g(n,p) !自然数nのp進法での桁数 ※p^c=n
   LET t=1
   LET c=0 !桁数
   DO
      LET t=t*p
      LET c=c+1
   LOOP WHILE t<=n
   LET g=c
END FUNCTION

END
 

Re: 答えが知りたい

 投稿者:山中和義  投稿日:2009年 8月24日(月)16時03分16秒
返信・引用
  > No.491[元記事へ]

「場合の数」を算出することで、f(n)の値を再帰処理で求めます。
直接求めるので、個々の(大きな)値を得る場合はこちらの方が早いです。
前出のように0から順に求める場合は、0〜nを毎回計算することになるので遅くなります。
!例 f(123)の場合
!100と23に分解する
! 3桁の数(最上位桁=1)
!  1xx形式の数 = k桁目に(23+1)=24、(k-1)〜1桁目にf(_99)=20
! 端数23
!  f(23)
! ⇒
!  20と3に分解する
!   2桁の数(最上位桁=2)
!    1x形式の数 = k桁目に10^(2-1)=10、(k-1)〜1桁目にf(_9)=1
!    2x形式の数 = k〜1桁目にf(_9)=1
!   端数3
!    f(3)
!   ⇒
!    3と0に分解する
!     1桁の数(最上位桁=3)
!      1形式の数 = 1桁目に10^(1-1)=1、(1-1)桁目にf(_)=0
!      2形式の数 = 1桁目にf(_)=0
!      3形式の数 = 1桁目にf(_)=0
!     端数0
!      f(0)=0
!∴(24+20) + (10+1 +1) + (1+0 +0 +0) +0 = 57

FUNCTION f(n$,p) !0〜nまでを列記したときの「1」の数 ※n$は非負のp進法の数値
   local k,m,t$
   IF ExBVAL(n$,p)=0 THEN
      LET f=0
   ELSE
      LET k=LEN(n$) !桁数
      LET m=VAL1(n$(1:1)) !最上位桁に着目する
      LET t$=n$(2:LEN(n$)) !端数
      !PRINT n;k;m;t$ !debug

      IF m=1 THEN !(1xxx…x)の場合
         LET w=ExBVAL(t$,p)+1
      ELSE !(2xxx…x)、…、(9xxx…x)の場合
         LET w=p^(k-1)
      END IF
      LET f=( w + f(REPEAT$(STR1$(p:p),k-1),p)*m ) + f(t$,p) !k桁 + f(端数)
   END IF
END FUNCTION

LET STR1$="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" !p進法の数字
DEF VAL1(x$)=POS(STR1$,x$)-1

FUNCTION ExBVAL(n$,p) !n$を非負のp進法の数値とした値
   LET s=0
   FOR i=1 TO LEN(n$)
      LET s=s*p+VAL1(n$(i:i))
   NEXT i
   LET ExBVAL=s
END FUNCTION

FUNCTION ExBSTR$(n,p) !非負の整数nをp進法で表記する
   LET s$=""
   DO
      LET nn=INT(n/p)
      LET t=n-nn*p !MOD(n,p)
      LET s$=STR1$(t+1:t+1)&s$ !下の位から
      LET n=nn
   LOOP UNTIL n=0
   LET ExBSTR$=s$
END FUNCTION

!------------------------------ ここまでがサブルーチン


PRINT f("1111111110",10) !10進法

PRINT ExBVAL("111110",6); f("111110",6) !6進法


LET p=4 !4進法
FOR n=0 TO p^p
   LET w$=ExBSTR$(n,p)
   IF f(w$,p)=n THEN PRINT "f(";n;")=";n, STR$(p);"#";w$
NEXT n

END
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年 8月25日(火)20時27分52秒
返信・引用  編集済
  > No.468[元記事へ]

!2以上の整数nに対して、その素因数の和を求める。
!例 6=2*3より、2+3=5
!  8=2^3より、2+2+2=6
!2から30までの整数では、
! 2,3,4,5,5,7,6,6,7, 11,7,13,9,8,8,17,8,19,9, 10,13,23,9,10,15,9,11,29,10
!となる。

LET N=30 !2〜Nの範囲

DIM sf(N) !素因数の和
MAT sf=ZER

LET j=2 !素因数2
DO WHILE j<=N
   FOR i=j TO N STEP j !2,4,6,8,…、4,8,12,16,…、8,16,24,32,…、… 倍数
      LET sf(i)=sf(i)+2 !素因数を加算していく
   NEXT i
   LET j=j*2 !2,4,8,16,… べき乗
LOOP

FOR k=3 TO N STEP 2 !3以上の素因数
   IF sf(k)=0 THEN !「エラトステネスのふるい」と同じで素因数となる

      LET j=k
      DO WHILE j<=N !高々SQR(N)まで
         FOR i=j TO N STEP j !j*m、m=1,2,3,…
            LET sf(i)=sf(i)+k
         NEXT i
         LET j=j*k !k^m、m=1,2,3,…
      LOOP

   END IF
NEXT k


FOR i=2 TO N !結果を表示する
   PRINT i;":"; sf(i)
NEXT i


END


●「素因数分解(式を表示する)」を改修する場合
LET N=120 !正の整数

LET s=0 !素因数の和 <----- 追加

PRINT N;":"; !<----- 変更

LET x=N
LET f=2 !割る数
DO WHILE x>=f*f !SQR(N)≧f
   LET xx=INT(x/f)
   IF x-xx*f=0 THEN !割り切れれば
      LET x=xx
      PRINT f;"+"; !<----- 変更
      LET s=s+f !<----- 追加
   ELSE !割り切れなければ、次へ
      LET f=f+1
   END IF
LOOP
PRINT x;

LET s=s+x !<----- 追加
PRINT "="; s !結果を表示する <----- 追加

END
 

matrix の  使い方 ??

 投稿者:与坂  昇平  投稿日:2009年 8月28日(金)11時12分37秒
返信・引用
  full  basic  を 使用して 有限要素法で  構造解析ソフトを 作成しています
大規模の matrix 用に  仮想メモリ―を  増やそうと
basic 729   w32 の basic 構成設定の  FRAME  の 下に
RetrainVirtualMemory=0   と  記入して
以下の  プログラムを  作成しました

dim  tk(a,a) , atk(a,a)
a=20000

以上の  プログラムを run  させると
300 秒程度で  matrix  の 場所が  確定されるようです

しかし
この matrix を  使用しようと

dim tk(a,a),atk(a,a)
a=20000
for i=1 to a
  for  j=1  to a
      tk(i,j)=0.0
      atk(i,j)=0.0
  next j
next i

として run  させると

EXTYE 2001  添え字が 範囲外と
エラ― が でます

そこで
この エラ―が  出ないように
tk(a,a)    atk(a,a)  matrix  を  使用するには
どの様に  すれば  よいのでしょうか


ぜひ  教えて下さい

与坂  昇平
 

Re: matrix の  使い方 ??

 投稿者:白石 和夫  投稿日:2009年 8月28日(金)12時17分29秒
返信・引用  編集済
  > No.497[元記事へ]

与坂  昇平さんへのお返事です。
BASICでは,変数の値を変えたとき,その変数が与えた効果を過去にさかのぼって適用することはありません。
独自拡張構文のDIM文は実行時に配列の大きさを決定します。
10 LET a=10
20 DIM m(a,a)
のように,変数値を与えてからDIM文を実行してください。
なお,Full BASICのプログラムとして書きたいときは,DIM文に変数を含めず
10 DIM a(10,10)
のように数値定数で配列の大きさを宣言してください。
 

使用できる RAM memory 数

 投稿者:与坂  昇平  投稿日:2009年 8月28日(金)19時46分12秒
返信・引用
  有限要素法で  構造解析ソフトを  作成中の  与坂 昇平  です
疑問が  有ります

512 MB memory で

dim  a(40000000)
end

上の プログラムが  可能です
つまり
512 MB  で 40000000  個の
matrix  が  使用できます


今
[ FRAME ]
の  下に
virtualmemory=16
と
書くと

option arithmetic  native
dim  a(90000000)
end

が  可能です
つまり
90000000 の matrix  が  可能です

しかし
その 割合

90000000/40000000=2.25

つまり
memory  を  多く使用しても
実際は
512MB x 2.25 = 1.2 GRAM  程度しか
使用していません

私の パソコンは 3G RAM  なので
単純 計算では

dim a(270000000)

が  可能なはずです

どの様に  すれば  良いのでしょうか

解ける
未知数の  方程式の
大きさが  変わるので
非常に  重要です

ぜひ
教えて下さい
 

9100個の 未知数の 方程式の 解

 投稿者:与坂  昇平  投稿日:2009年 8月29日(土)06時15分32秒
返信・引用
  有限要素法で  構造解析ソフトを 作成している  与坂 昇平です

  option arithmetic native
       a(90000000)
    end

の 90000000 matrix  が  使用できるので
私の  ソフト に 応用してみました
一応 成功 しました

横 15ミリ
高さ 145 ミリ
の 鉄版を  1ミリ  の 三角形に
区切ると
接点数  4526 点
要素数  8700 個
になります

これは
a(4526x2,4526x2)  の matrix が  ひっようです
すなわち
4526x2 個の  未知数の 連立方程式を
gauss の 掃きだし方で  解きますが
full  basic  では  94時間かかります

まだ
最後までは  計算させません

私の  安物の  パソコンで
cpu  を 100%
使用して  93時間  稼動させると
故障  するかもしれません
 

9100 未知数 訂正

 投稿者:与坂  昇平  投稿日:2009年 8月29日(土)06時29分3秒
返信・引用
  9100個の  未知数方程式 に 関して
投稿した  与坂  です

訂正が  有ります

横 15ミリ と 言いましたが
正しくは

横 30ミリ
高さ  145 ミリ

です

この 計算を turbo C++  で すると
計算時間は  約 2時間の 予定です

しかし
C++ は グラヒックが  難しく
まだ
私は  できません
 

Re: matrix の  使い方 ??

 投稿者:山中和義  投稿日:2009年 8月29日(土)07時54分26秒
返信・引用
  > No.497[元記事へ]

与坂  昇平さんへのお返事です。

直接の回答ではありませんが、

有限要素法は、20年前は汎用機でFORTRANによるプログラムだと思いますが、
当時このプログラム程度の問題(未知数の数、処理速度)が解決されていたなら、
当時の汎用機と現在のパソコンの性能を比較すると、次の疑問があります。

「現在のパソコンではほんとうに扱えないのでしょうか!?」


実用性は検証してみないとわかりませんが、
検討案
・当時の文献をみる

・「未知数の個数の3乗に比例する計算時間がかかる」ようですので、
 連立方程式の未知数を減らす手法を使う →還元法

・配列a()(線形リスト)は、プログラム言語がつくったメモリモデルなので、
 他の等価モデルを導入する →ランダムファイル

  a(20000)なら
  FILE00、FILE01、〜、FILE19の20個のファイルで、各レコード数は1000個を用意して、
  a(i)をFILExxとレコードyyに対応させる

  LET A(10000)=A(1000)+A(1) を計算させる場合、
  CPUはA(1)〜A(20000)すべてが必要ではないはずです。
 

パソコン に 関して

 投稿者:与坂  昇平  投稿日:2009年 8月29日(土)16時09分45秒
返信・引用
  以前  有限要素法を  するのでと
良い パソコンを  探していますと
アメリカの  コンピュ―タ企業の 日本支社に  聞いたところ
中古の  安い物で  200万円 と 返事が  有りました

私の  所有する  数万円の  パソコンでは
数日間 計算させる  full basic での 有限要素法は  無理かもしれません


だから
解決法として
計算は  turbo C++  で
数時間 で 高速計算さして
その計算結果を
full  basic  の
コンピュ―タ―グラヒックで
表現できないでしょうか  ???
 

Re: 使用できる RAM memory 数

 投稿者:山中和義  投稿日:2009年 8月30日(日)13時35分23秒
返信・引用  編集済
  > No.499[元記事へ]

与坂  昇平さんへのお返事です。

>私のパソコンは3GRAMなので単純計算ではdim a(270000000)が可能なはずです

32bit XP/Vista では、アプリケーションは仮想で2GBまでしか利用できなかったと思います。

したがって、仮に十進BASIC本体(EXEコード、関数/サプルーチンのスタック、グラフィックス画面など)が
0バイトだとしても高々2GBとなります。 No.253[元記事へ]


>full basic では94時間かかります
>この計算をturbo C++ ですると計算時間は約2時間の予定です

「プログラムの実行」の実装の違いでしょうか。
いわゆる、「インタプリタ方式とコンパイラ方式」、また、コンパイラどうしでも「式の最適化」で
10〜50倍の処理速度が違います。


>計算はturbo C++で数時間で高速計算さしてその計算結果をfull basicのコンピュ―タ―グラヒックで表現できないでしょうか

TurboC++での計算結果のCSVファイルをつくり、これを十進BASICで読み込んでグラフィックスに
するといいでしょう。

参考サイト
「Full BASICと十進BASICの Q&A」内 「行列データの表計算ソフトとの連携」
 http://hp.vector.co.jp/authors/VA008683/SpreadSheet.htm
 

Vine5.で文字化け

 投稿者:島村1243  投稿日:2009年 8月30日(日)20時16分16秒
返信・引用
  Linux_Vineの最新版「Vine5.0」に十進BASICをインストールしたところ、Vine4.0で生じたメニュー文字化けと同じ現象が出ました。
BASICを端末から起動した場合のエラーメッセージは下記の通りで、Vine4.0の時と全く同じでした。

[@localhost basic]$ ./BASIC
Qt: missing charset ISO8859-1
Qt: missing charset JISX0208.1983-0
Qt: missing charset JISX0201.1976-0

Vine4.0の対策用として、白石先生が「Vine4ini.tar.gz」を作成しダウンロードページに掲載してくださったのですが、今は削除されています。
これを使用すればVine5.0の文字化けも治ると思います。再度「Vine4ini.tar.gz」をダウンロードページに掲載して頂けないでしょうか。
 

Re: Vine5.で文字化け

 投稿者:白石 和夫  投稿日:2009年 8月31日(月)09時32分35秒
返信・引用
  > No.505[元記事へ]

メニューフォント設定画面は,ALT-Oに続けてMを打てば表示できます。
Scriptに jisx0208 を含むフォントを選択して文字化けをなくすことができますか?
 

Re: Vine5.で文字化け

 投稿者:島村1243  投稿日:2009年 8月31日(月)16時50分37秒
返信・引用
  > No.506[元記事へ]

白石 和夫さんへのお返事です。

> メニューフォント設定画面は,ALT-Oに続けてMを打てば表示できます。
> Scriptに jisx0208 を含むフォントを選択して文字化けをなくすことができますか?

白石先生、ご回答ありがとうございます。

キー「Alt+O」に続いて「M」をプッシュしてメニューのフォント選択ダイアログ(英文字表
示)を出し下記種類を選択してみましたが、いずれもNGです。

Fixed[jis]  script[jisx0208,1983-0] -->結果NG
Fixed[misc] script[jisx0208,1983-0] -->結果NG
VLpgothic   script[jisx0208,1983-0] -->結果NG

BASICエディター画面をアクティブにして半角/全角キーをプッシュしても、Scim-Anthyの日本
語変換ツールバーが表示されない(他のアプリでは出ます)のでVine5.0のインストールCD1枚
の場合、Qt関連のパッケージが不足しているのかも知れません。
Qt-designerのパッケージをウェブインストールして、効果が有るか試してみます。
 

Re: Vine5.で文字化け

 投稿者:島村1243  投稿日:2009年 8月31日(月)20時10分0秒
返信・引用
  > No.507[元記事へ]

島村1243さんへのお返事です。

> BASICエディター画面をアクティブにして半角/全角キーをプッシュしても、Scim-Anthyの日本
> 語変換ツールバーが表示されない(他のアプリでは出ます)のでVine5.0のインストールCD1枚
> の場合、Qt関連のパッケージが不足しているのかも知れません。
> Qt-designerのパッケージをウェブインストールして、効果が有るか試してみます。

当てずっぽうで、qt-designerパッケージ一式とscim-bridge-qtパッケージをインストール
して様子みましたが、BASICの文字化けには効果無しでした。
 

Re: Vine5.で文字化け

 投稿者:白石 和夫  投稿日:2009年 8月31日(月)21時30分31秒
返信・引用
  > No.507[元記事へ]

iniファイルの編集は,表示可能なフォントが見つからなければ意味がないです。
Linuxでの文字化けの原因は多様で,対策も決めてがないのが実態です。
http://www.geocities.jp/thinking_math_education/Linux.htm
に対応例を掲載していますが,同じLinuxでもバージョンが違うとまったく異なることが珍しくありません。
 

Re: Vine5.で文字化け

 投稿者:島村1243  投稿日:2009年 9月 1日(火)07時05分19秒
返信・引用
  > No.509[元記事へ]

白石 和夫さんへのお返事です。

> iniファイルの編集は,表示可能なフォントが見つからなければ意味がないです。
> Linuxでの文字化けの原因は多様で,対策も決めてがないのが実態です。
> http://www.geocities.jp/thinking_math_education/Linux.htm
> に対応例を掲載していますが,同じLinuxでもバージョンが違うとまったく異なることが珍しくありません。

白石先生、重ねてのご回答ありがとうございます。
上記URLに記載されている対策例を行って、結果OKになりましたら、ここにご報告致します。
尚、それまでの間、Vine5.0上では英語版を使わせて頂くことにしました。
 

Full BASIC高速化の試み

 投稿者:白石 和夫  投稿日:2009年 9月 1日(火)09時32分21秒
返信・引用  編集済
  2進演算を選択したときのFull BASIC実行の高速化の試みを始めました。
Full BASICのプログラムをLazarusの拡張Pascal語に翻訳し,FPC+Lazarus
を利用して高速実行します。
現バージョンでは,例外処理にRETRY,CONTINUEが使えないなどの制約がありますが,単純な数値演算は十進BASICより2倍強,速くなります。
http://sourceforge.jp/projects/decimalbasic/
BASICAccをダウンロードしてください。

別途,FPC+Lazarusも必要です。
http://snapshots.lazarus.shikami.org/
 

NOT AND OR

 投稿者:SECOND  投稿日:2009年 9月 1日(火)21時53分0秒
返信・引用
  数値の NOT AND OR 、語頭 0x での16進数表記 → personal extension の希望です。
縁の下の計算機には、最終的な命令とデータ形式… のはずですが、
使用しないように努力する癖 がついて、振り返る時、学習テーマに 是か否か、
自分の身分で考える事ではないけれども、疑問からの提案です。
BASIC だから「このままでいい」の声も強く聞こえるが・・・
 

Re: NOT AND OR

 投稿者:白石 和夫  投稿日:2009年 9月 2日(水)07時29分20秒
返信・引用  編集済
  > No.512[元記事へ]

SECONDさんへのお返事です。

> 数値の NOT AND OR 、語頭 0x での16進数表記 → personal extension の希望です。
> 縁の下の計算機には、最終的な命令とデータ形式… のはずですが、
> 使用しないように努力する癖 がついて、振り返る時、学習テーマに 是か否か、
> 自分の身分で考える事ではないけれども、疑問からの提案です。
> BASIC だから「このままでいい」の声も強く聞こえるが・・・

作るのは簡単ですが,単に互換性を損ない,初心者を惑わすだけの拡張になると思います。
A=B AND B=C
などという代入文は世の中から消えてほしいです。
(この文は,Microsoft 互換モードで実行できます)
 

Re: NOT AND OR

 投稿者:SECOND  投稿日:2009年 9月 2日(水)10時01分26秒
返信・引用  編集済
  > No.513[元記事へ]

ビットの抽出が、LET A= B AND 0x30 と書ければ・・といつも思うのですが、
やはり、そうですね・・
上の文は、LET A= MOD(IP(B/16),4)*16 などで、置き換えるようにします。
ありがとうございました。
 

Re: NOT AND OR

 投稿者:白石 和夫  投稿日:2009年 9月 2日(水)16時17分39秒
返信・引用  編集済
  > No.514[元記事へ]

Windows限定ですが,
http://hp.vector.co.jp/authors/VA008683/BitOp.htm
を使えば,
LET A = AND( B, BVAL("30",16) )
あるいは,
LET A = AND(B, BVAL"00110000",2))
と書くことが可能です。
これらの関数はFull BASICの命令だけで定義することも可能なので,
互換性を損なうことはありません。

http://sourceforge.jp/projects/decimalbasic/

 

Re: NOT AND OR

 投稿者:SECOND  投稿日:2009年 9月 2日(水)16時54分22秒
返信・引用  編集済
  > No.515[元記事へ]

BITOP.DLLを使用する投稿プログラムが、訪問者も そのまま実行できるように、
適当なフォルダーに標準実装していただければ、ありがたいのですが、現状では、
その使用に抵抗があります。
 

覆面算はどう解くのか?

 投稿者:GAI  投稿日:2009年 9月 2日(水)19時47分39秒
返信・引用
  次の覆面算

  ONE
  TWO
+FOUR
___________
SEVEN

をプログラムで解けますか?
 

Re: 覆面算はどう解くのか?

 投稿者:SECOND  投稿日:2009年 9月 2日(水)22時44分9秒
返信・引用  編集済
  > No.517[元記事へ]

GAIさんへのお返事です。

!こんなものでは、だめですか。
!----------------------------------------------
LET NN$="ZERO  ONE   TWO   THREE FOUR  FIVE  SIX   SEVEN EIGHT NINE  TEN"

DEF num(I$)= (POS( NN$, UCASE$(I$) )-1)/6
DEF num$(I)= mid$( NN$, I*6+1, 5 )

PRINT numb$("ONE+TWO+FOUR")
PRINT numb$("-One-Two-Three")
PRINT numb$("Two+Seven")
PRINT numb$(" - one + two - seven + ten ")
PRINT numb$("- one+ two- seven+ ten ")
PRINT numb$(" -one +two -seven +ten ")

FUNCTION numb$(w$)
   LET n=0
   LET i=1
   DO WHILE i<=LEN(w$)
      LET p$=""
      DO WHILE w$(i:i)="+" OR w$(i:i)="-" OR w$(i:i)=" "
         LET p$=p$& w$(i:i)
         LET i=i+1
      LOOP
      LET n$=""
      DO WHILE w$(i:i)<>"+" AND w$(i:i)<>"-" AND w$(i:i)<>" "
         LET n$=n$& w$(i:i)
         LET i=i+1
      LOOP UNTIL LEN(w$)< i
      LET j=num(n$)
      IF POS(p$,"-")<>0 THEN LET j=-j
      LET n=n+j
   LOOP
   IF n< 0 THEN LET p$="-" ELSE LET p$=""
   LET numb$= p$& num$(ABS(n))
END FUNCTION

END


「追記」 覆面算の事を良く知らなくて、これは、違いますね。すみません。
     削除は、できないので、このまま、残します。山中さん助けて!

!「追記」あらっぽいですが、これで合ってますか。

OPTION ARITHMETIC NATIVE
DIM n0(0 TO 9),nn(0 TO 9)
MAT READ n0
DATA 0,1,2,3,4,5,6,7,8,9

CALL perm(n0,0)
PRINT "終了"

SUB perm(n0(),j)
   local i
   IF j<=9 THEN
      FOR i=0 TO 9-j
         LET nn(j)=n0(i)
         swap n0(i),n0(9-j)
         CALL perm(n0,j+1)
         swap n0(i),n0(9-j)
      NEXT i
   ELSE
      CALL check
   END IF
END SUB

SUB check
!MAT PRINT USING REPEAT$("# ",10):nn
   LET E=nn(0)
   LET O=nn(1)
   LET R=nn(2)
   LET N=nn(3)
   LET W=nn(4)
   LET U=nn(5)
   LET T=nn(6)
   LET V=nn(7)
   LET F=nn(8)
   LET S=nn(9)
   LET yy0= E+O+R
   IF N= MOD( yy0,10) THEN
      LET cy0= IP( yy0/10) !carry
      !---
      LET yy1= N+W+U +cy0
      IF E=MOD( yy1,10) THEN
         LET cy1= IP( yy1/10) !carry
         !---
         LET yy2= 2*O+T +cy1
         IF V=MOD( yy2,10) THEN
            LET cy2= IP( yy2/10) !carry
            !---
            LET yy3= F +cy2
            IF E=MOD( yy3,10) AND S=IP( yy3/10) THEN
            !---
               PRINT "       O  N  E"
               PRINT "       T  W  O"
               PRINT " +  F  O  U  R"
               PRINT "───────"
               PRINT " S  E  V  E  N"
               PRINT
               PRINT "      ";O ;N ;E
               PRINT "      ";T ;W ;O
               PRINT " + ";F ;O ;U ;R
               PRINT "───────"
               PRINT    S ;E ;V ;E ;N
               PRINT
            END IF
         END IF
      END IF
   END IF
END SUB

END
 

Re: 覆面算はどう解くのか?

 投稿者:山中和義  投稿日:2009年 9月 3日(木)06時39分9秒
返信・引用
  > No.517[元記事へ]

GAIさんへのお返事です。

10個(ONETWFURSV)の変数に10個(0〜9)の数字を割り当てるので、
「10個の数字を使ってできる順列」を生成して、式を確認すればよいでしょう。
場合の数は、comb(10,10)*10!=10!通り。
!覆面算 ※10個の変数の場合

LET t0=TIME

PUBLIC NUMERIC ANSWER_COUNT !解答数
LET ANSWER_COUNT=0

DIM a(10) !異なる文字 ※ONETWFURSVの順
FOR i=1 TO 10 !0〜9
   LET a(i)=i-1
NEXT i

CALL perm(a,1)

PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB perm(a(), i) !n個の数字を使ってできる順列(辞書式でない)
LET N=UBOUND(a) !文字数
IF i<N THEN
   FOR j=i TO N
      LET t=a(i) !swap a(i),a(j)
      LET a(i)=a(j)
      LET a(j)=t

      CALL perm(a,i+1)

      LET t=a(i) !swap a(i),a(j)
      LET a(i)=a(j)
      LET a(j)=t
   NEXT j

ELSE !すべてが確定したら、式を検証する
!!!MAT PRINT a; !debug

   IF a(1)>0 AND a(4)>0 AND a(6)>0 AND a(9)>0 THEN !最上位桁は0でない

      LET ONE  =                      a(1)*100+a(2)*10+a(3)
      LET TWO  =                      a(4)*100+a(5)*10+a(1)
      LET FOUR =           a(6)*1000+ a(1)*100+a(7)*10+a(8)
      LET SEVEN=a(9)*10000+a(3)*1000+a(10)*100+a(3)*10+a(2)

      IF ONE+TWO+FOUR=SEVEN THEN !式が成立するなら

         LET ANSWER_COUNT=ANSWER_COUNT+1 !解答数
         PRINT ANSWER_COUNT

         PRINT USING "    ONE   ####":ONE !結果の表示
         PRINT USING "    TWO   ####":TWO
         PRINT USING "+ FOUR   ####":FOUR
         PRINT "-------"
         PRINT USING "  SEVEN  #####":SEVEN
         PRINT

      END IF

   END IF

END IF
END SUB


実行結果
 1
    ONE    350
    TWO    673
+ FOUR   9382
-------
  SEVEN  10405

 2
    ONE    350
    TWO    683
+ FOUR   9372
-------
  SEVEN  10405

 3
    ONE    530
    TWO    625
+ FOUR   9548
-------
  SEVEN  10703

 4
    ONE    530
    TWO    645
+ FOUR   9528
-------
  SEVEN  10703

 5
    ONE    630
    TWO    526
+ FOUR   9647
-------
  SEVEN  10803

 6
    ONE    630
    TWO    546
+ FOUR   9627
-------
  SEVEN  10803

 7
    ONE    940
    TWO    729
+ FOUR   8935
-------
  SEVEN  10604

 8
    ONE    940
    TWO    739
+ FOUR   8925
-------
  SEVEN  10604

また、

   SEND
 + MORE
 -----
  MONEY

の場合は、8個の変数(SENDMORY)に10個の数字を割り当てることになります。

「10個から8個を選ぶ組合せ」で数字を選択して、「その数字を使ってできる順列」での検証。comb(10,8)*8!通り。

上記プログラムは、そのテンプレートになると思いますので改修してみてください。

参考
 フォルダ SAMPLE 内 PERMUTAT.BAS、COMBINAT.BAS
 

Re: NOT AND OR

 投稿者:白石 和夫  投稿日:2009年 9月 3日(木)07時44分56秒
返信・引用  編集済
  > No.516[元記事へ]

BITOP.DLLは,使わずにすむのなら,公開するプログラムには使わないほうがいいと思います。
(だから,標準装備になっていない....)
 

文字列の 分解  数値化

 投稿者:与坂  昇平  投稿日:2009年 9月 3日(木)09時24分49秒
返信・引用
  turbo c++  を  使用した  有限要素法の プログラムの 計算結果を
full  basic  の  グラヒックで  表そうと  考えています

turbo c++ の 計算結果を
例えば

  1    0.000     0.45

とすると
full  basic  では

      print  a$(n)

で

   1   0.00   0.45

  と  文字列で  現れます

これでは  full  basic  プログラムが  グラヒックを 描く為に

数値を  読み込めないので

これを

1

0.00

0.45

と  分解して
文字ではなく  数値に  変換できますか  ??

ぜひ
教えて下さい

よろしく
 

Re: 覆面算はどう解くのか?

 投稿者:荒田浩二  投稿日:2009年 9月 3日(木)10時08分25秒
返信・引用  編集済
  > No.517[元記事へ]

GAIさんへのお返事です。


投稿しようとしたらすでに山中和義さんの投稿があり、似たようなものですがせっかく作ったので公開します。
解法は、文字に数をしらみつぶしに入れていき計算を満たすか検証する方法です。
GAIさんが論理的に数値を求める方法を望んでいるのであれば、この方法ではだめですね。
GAIさんの提示された問題は複数の解答があるので、実行ごとに調査の開始する点をランダムにしました。
(山中さんのプログラムとは違い、ひとつの解を発見した時点で終了します)

他の覆面算にも応用できるようにしました。
次の3箇所を変更するだけで実行できると思います。
1.変数 k の値(LET k=4 ! 単語の個数)
2.各単語のDATA(DATA "ONE","TWO","FOUR","SEVEN")
3.IF文で判定する計算式
    (IF h0=0 AND change("ONE")+change("TWO")+change("FOUR")=change("SEVEN") THEN)

  SEND+MORE=MONEY で試してみてください。


OPTION ARITHMETIC NATIVE
DECLARE EXTERNAL SUB perm,charac,headset
DECLARE EXTERNAL FUNCTION random
PUBLIC NUMERIC k,num(10),head(30),check(0 TO 9)
PUBLIC STRING word$(30),c$(10)
LET k=4 ! 単語の個数
!LET k=3
FOR i=1 TO k
   READ word$(i)
NEXT i
DATA "ONE","TWO","FOUR","SEVEN"
!DATA "SEND","MORE","MONEY"
CALL charac(word$)
CALL headset
RANDOMIZE
MAT check=ZER
FOR i=1 TO 10
   LET num(i)=random
NEXT i
!
CALL perm(num,1)
END
!
!
REM 1〜nの順列を辞書式順序で生成する。
!十進BASIC添付"\BASICw32\SAMPLE\PERMUTAT.BAS"参照
EXTERNAL SUB perm(a(),n)
OPTION ARITHMETIC NATIVE
DECLARE FUNCTION change
IF n=10 THEN
   LET h0=0
   FOR ii=1 TO k
      IF num(head(ii))=0 THEN
         LET h0=1 ! 先頭文字が 0
         EXIT FOR
      END IF
   NEXT ii
   IF h0=0 AND change("ONE")+change("TWO")+change("FOUR")=change("SEVEN") THEN
   !IF h0=0 AND change("SEND")+change("MORE")=change("MONEY") THEN
      FOR ii=1 TO k
         PRINT word$(ii);" =";change(word$(ii))
      NEXT ii
      FOR ii=1 TO 10
         PRINT c$(ii);"=";STR$(num(ii));" ";
      NEXT ii
      PRINT
      STOP
   END IF
ELSE
   FOR i=n TO 10
      LET t=a(i)
      FOR j=i-1 TO n STEP -1
         LET a(j+1)=a(j)
      NEXT j
      LET a(n)=t
      CALL perm(a,n+1)
      LET t=a(n)
      FOR j=n TO i-1
         LET a(j)=a(j+1)
      NEXT j
      LET a(i)=t
   NEXT i
END IF
FUNCTION change(w$)
   LET l=LEN(w$)
   LET s=0
   FOR i=1 TO l
      FOR j=1 TO 10
         IF c$(j)=w$(i:i) THEN
            LET s=s+10^(l-i)*num(j)
            EXIT FOR
         END IF
      NEXT j
   NEXT i
   LET change=s
END FUNCTION
END SUB
!
EXTERNAL SUB charac(a$())
OPTION ARITHMETIC NATIVE
LET s=SIZE(a$)
LET c=1
LET c$(1)=a$(1)(1:1)
FOR i=1 TO s
   FOR j=1 TO LEN(a$(i))
      LET cc=0
      FOR kk=1 TO c
         IF a$(i)(j:j)<>c$(kk) THEN LET cc=cc+1
      NEXT kk
      IF cc=c THEN
         LET c=c+1
         LET c$(c)=a$(i)(j:j)
         IF c=10 THEN EXIT SUB
      END IF
   NEXT j
NEXT i
END SUB
!
EXTERNAL SUB headset
OPTION ARITHMETIC NATIVE
FOR i=1 TO k
   FOR j=1 TO 10
      IF word$(i)(1:1)=c$(j) THEN LET head(i)=j !先頭文字
   NEXT j
NEXT i
END SUB
!
EXTERNAL FUNCTION random
OPTION ARITHMETIC NATIVE
LET r=INT(10*RND)
IF check(r)=0 THEN
   LET random=r
   LET check(r)=1
ELSE
   LET random=random
END IF
END FUNCTION
 

Re: 文字列の 分解  数値化

 投稿者:山中和義  投稿日:2009年 9月 3日(木)10時13分7秒
返信・引用
  > No.521[元記事へ]

与坂  昇平さんへのお返事です。

カンマがない場合は、1行分の文字列として認識されると思います。
したがって、

   1,  0.00,   0.45

のように、カンマで区切られた数字列は数値として読み込まれます。(下記プログラムのTEST.TXTの内容)
これがいわゆるCSVファイルです。
OPEN #1: NAME "TEST.TXT"
DO
   INPUT #1, IF MISSING THEN EXIT DO: a,b,c
   PRINT a;b;c
LOOP
CLOSE #1

END

例
  1  0.00,   0.45
なら
  INPUT #1, IF MISSING THEN EXIT DO: a$,b
となる。a$="1  0.00"、b=0.45
 

Re: 覆面算はどう解くのか?

 投稿者:島村1243  投稿日:2009年 9月 3日(木)15時01分57秒
返信・引用
  > No.522[元記事へ]

荒田浩二さんへのお返事です。

> GAIさんへのお返事です。
>
>
> 投稿しようとしたらすでに山中和義さんの投稿があり、似たようなものですがせっかく作ったので公開します。

荒田さんの作成されたプログラムを、「コピー貼り付け」でFedora10 Linux上のBASIC-6.5.9で
走らせたら、BASIC本体がクラッシュ(何度行ってもダメ)してしまいましたのでご報告致しま
す。
パソコンのRAMは512MBですが、メモリが足りないのでしょうか。
 

C++ の 計算結果を full basic wo computer graphic

 投稿者:与坂  昇平  投稿日:2009年 9月 3日(木)15時47分58秒
返信・引用
  有限要素法の  プログラムを  作成していますが
計算は  60 倍の  速度の 高速の turbo C++  で  計算させ
その deta file  を  full  basic  に  移し
computer graphic  させる事に
ほぼ  成功しました

とても
簡単です

C++ Builder  等は  ひっよう  ないかも  知れません
 

Re: 覆面算はどう解くのか?

 投稿者:島村1243  投稿日:2009年 9月 3日(木)17時38分1秒
返信・引用
  > No.524[元記事へ]

荒田浩二さんへのお返事です。

> 荒田さんの作成されたプログラムを、「コピー貼り付け」でFedora10 Linux上のBASIC-6.5.9で
> 走らせたら、BASIC本体がクラッシュ(何度行ってもダメ)してしまいましたのでご報告致しま
> す。
> パソコンのRAMは512MBですが、メモリが足りないのでしょうか。

同一パソコンのWindowsXP上のBASIC-7.2.9で実行したらプログラムは異常なく走りました。
この結果から、Linux側の問題(OSの問題かBASIC-6.5.9の問題かは不明)で異常が出てしまうようです。
以上、ご報告です。
 

Re: 覆面算はどう解くのか?

 投稿者:白石 和夫  投稿日:2009年 9月 3日(木)20時58分3秒
返信・引用
  > No.526[元記事へ]

OPTION ARITHMETIC NATIVE
だとまずいみたいです。
調べてみます。

http://sourceforge.jp/projects/decimalbasic/

 

Re: 覆面算はどう解くのか?

 投稿者:荒田浩二  投稿日:2009年 9月 3日(木)23時03分29秒
返信・引用
  > No.524[元記事へ]

島村1243さんへのお返事です。

> 荒田さんの作成されたプログラムを、「コピー貼り付け」でFedora10 Linux上のBASIC-6.5.9で
> 走らせたら、BASIC本体がクラッシュ(何度行ってもダメ)してしまいましたのでご報告致しま
> す。
> パソコンのRAMは512MBですが、メモリが足りないのでしょうか。

それは申し訳ないことをしました。
私はLinuxはまったく知らないのですが、WindowsVista上で十進BASIC Ver.7.3.3では問題なく実行できました。

 可能性としては、実は最初に投稿したときに脱字がありました。10分後には修正して再投稿したのですが、島村1243さんが最初の投稿記事で実行されたのかもしれません。
修正箇所は外部副プログラムの宣言文です。

  誤) DECLARE EXTERNAL SUB perm,chara,headset
  正) DECLARE EXTERNAL SUB perm,charac,headset

ただし、ヘルプによると外部副プログラムの宣言は必須のものではないらしく、最初の誤った記事でもWindowsでは問題なく実行できました。

 また、512MBあれば「メモリー不足」ということも考えにくいですよね。
関数changeは確かに頻繁に呼び出されますが、最大でも 4*10! 回です。しかも先頭文字O,T,F,Sのいずれかが0のときは呼び出さないのでメモリーが不足するとは思えません。

 あるいは、十進BASICの独自拡張である「主プログラム内で変数のPUBLIC宣言」を利用していますが、この機能がLinuxでは上手く働かないのでしょうか?

ごめんなさい、まったくわかりません。
 

Re: 覆面算はどう解くのか?

 投稿者:白石 和夫  投稿日:2009年 9月 4日(金)08時11分10秒
返信・引用
  > No.527[元記事へ]

不具合箇所が特定できたので,修正版を作ります。

2進モードで次のプログラムを実行すると変な現象が起こります。
2進モードで文字列処理する人がいなかったのがバグ発覚が遅れた原因でしょうか。
OPTION ARITHMETIC NATIVE
DIM a$(4)
FOR i= 1 TO 4
   PRINT a$(i)
NEXT i
END

Linux版,Mac版はGPLなので「バグ報告の義務」を使用条件に書くことができないのですが,
不具合を見つけたときは報告くださるようお願いします。
 

C++ data を full basic で graphick

 投稿者:与坂  昇平  投稿日:2009年 9月 4日(金)10時00分41秒
返信・引用
  有限要素法で 構造解析ソフトを  作成しています

接点数  5511個の  6層の  フレ―ムを
私の ソフトで 解くと
full  basic  で  約 170時間  かかります
それを
turbo  C++  でとくと  約 3時間の  予定です

turbo C++  で  構造解析予定の
6層 フレ―ムの
turbo C++  で  作製した
input data  を
数字の  間に  コンマ 印を  入れるだけで
簡単に
full  basic  で  computer graphic  することに
成功しました

ファイル1  に  添付します

turbo C++  での  computer grahic  は
非常に  難しく
長い間  悩んでいました
 

turbo C++ and full basic

 投稿者:与坂  昇平  投稿日:2009年 9月 4日(金)14時52分42秒
返信・引用
  私が  作製した  有限要素法の  構造解析ソフトで
6層の  フレ―ムの  地震時の  曲がりを
解析しました

接点数  5511 個で
turbo c++  で  計算時間 1時間  です

その 接点の  変位量を
full  basic  に  移して
500  倍に  拡大して
グラヒックに  しました

添付します

full  basic  で  計算させると  80時間以上
かかる  予想です
 

2色の 応力図

 投稿者:与坂  昇平  投稿日:2009年 9月 4日(金)20時02分35秒
返信・引用
  turbo C++  で  6層フレ―ムを  下から  押し上げた時の
条件で  計算させ
full  basic  で  6層フレ―ムの  引っ張り 部分を  青
圧縮部分を  赤で  色ずけ  しました

これが
有限要素法の  人気のある
computer  graphic  だと  思います
 

Re: 2色の 応力図

 投稿者:山中和義  投稿日:2009年 9月 4日(金)20時55分57秒
返信・引用
  > No.532[元記事へ]

与坂  昇平さんへのお返事です。

横長の図形を表示するとき、501×501の正方形の画面では効率よく表示できないのでは?

グラフィックス画面も横長にすると良いでしょう。
SET bitmap SIZE 800,400
SET WINDOW -10,10,-5,5
DRAW grid
END
 

色を  変えて

 投稿者:与坂  昇平  投稿日:2009年 9月 4日(金)21時36分45秒
返信・引用
  前に  投稿した
有限要素法の  computer  grahic  の  色を
変えて  見ました

約 1万本の  線で  描いています

理論の  有る  理工科的  芸術です

赤色  圧縮部分
他    引っ張り  部分
 

Re: 覆面算はどう解くのか?

 投稿者:島村1243  投稿日:2009年 9月 5日(土)09時26分8秒
返信・引用
  > No.529[元記事へ]

白石 和夫さんへのお返事です。

> 不具合箇所が特定できたので,修正版を作ります。
> 2進モードで次のプログラムを実行すると変な現象が起こります。
> Linux版,Mac版はGPLなので「バグ報告の義務」を使用条件に書くことができないのですが,
> 不具合を見つけたときは報告くださるようお願いします。

Linux(i386)版 最新の「BASIC-6.5.A」をFedora10上にインストールし、荒田さん作成の
「覆面算」コードを、ウェブ画面からコピー貼り付けしてRUNしましたら、正常に計算が
完了しました。

白石先生、有難うございました。
荒田さん、コードの公開有難うございました。勉強になります。

以上、ご報告です。
 

エラー EXTYPE 5001

 投稿者:SECOND  投稿日:2009年 9月 5日(土)20時43分47秒
返信・引用  編集済
  OPTION ARITHMETIC NATIVE ! Native のみ、下記エラーになります。ver.7.3.3

DIM D(500,500)
MAT D=ZER(136,100)
!
MAT D=ZER(136,104) !<-- エラー EXTYPE 5001 配列の再定義に必要な要素数の不足

END
 

Re: エラー EXTYPE 5001

 投稿者:山中和義  投稿日:2009年 9月 5日(土)21時18分4秒
返信・引用  編集済
  > No.536[元記事へ]

小さくする場合はOK。大きくする場合にNG。
また、redimでも同様です。

DIM D(500)
MAT D=ZER(100)
redim D(300) !<-- エラー EXTYPE 5001 配列の再定義に必要な要素数の不足
END
 

Re: エラー EXTYPE 5001

 投稿者:白石 和夫  投稿日:2009年 9月 6日(日)06時50分14秒
返信・引用  編集済
  > No.536[元記事へ]

ご報告ありがとうございました。
MAXSIZEが書き換わっていました。

OPTION ARITHMETIC NATIVE
DIM D(500,500)
PRINT MAXSIZE(D)        ! 250000
MAT D=ZER(136,100)
PRINT MAXSIZE(D)        ! 13600に変わってしまう
END
 

覆面算、再考

 投稿者:山中和義  投稿日:2009年 9月 7日(月)11時18分38秒
返信・引用  編集済
  一般にr個の変数にn個の数を割り当てる「場合の数」は、perm(n,r)通り。
したがって、高々perm(10,10)=10!通りを検証すればよいことになるが、、、
実際、現状のパソコンでは負荷になるものでもない。
また、一度解答できればプログラムもそれっきりになる。(one write)

論理的要素を一部考慮して、
枝刈りをすること(バックトラック法)で「場合の数」を減らすことができる。

●アルゴリズムの概要
加算は、一の位から順に計算していくので、異なる文字を一の位から順に割り付ける。

一の位(E+O+R=N)を算出するには、
a(i):1234xxxxxx
c$="EORNWUTVFS"
まで数が埋まっていればよい。

そこで MOD(1+2+3,10)=4 ? を確認して、不成立ならxxxxxxはどう組替えてもこの「順列」は成立しない。
したがって、6!(xの数)通りは検証する必要がないことになる。

一つ下の位が成立したなら上の位で同じことを行う。
!覆面算(nPr順列+枝狩り)

DECLARE EXTERNAL SUB F.perm !外部手続き、変数を宣言する
DECLARE EXTERNAL NUMERIC F.ANSWER_COUNT

LET t0=TIME

CALL perm(0, 1) !キャリーは0、一の位から
IF ANSWER_COUNT=0 THEN PRINT "解なし"

PRINT "計算時間=";TIME-t0

END


MODULE F

SHARE STRING c$

!  ONE ↓※一の位からa()に順に割り付ける
!   TWO ↓
!+ FOUR ↓
!------
! SEVEN ↓
LET c$="EORNWUTVFS" !異なる文字 ←←←←← ※差し替え

IF LEN(c$)>10 THEN
   PRINT "指定できる文字は10文字以内です。"
   STOP
END IF

SHARE NUMERIC a(10) !文字に設定した数値(0〜9)
MAT a=ZER(LEN(c$)) !文字数と同数に調整する

SHARE NUMERIC f(0 TO 9) !文字に割り当てる数(0〜9)フラグ用 ※
MAT f=ZER

PUBLIC NUMERIC ANSWER_COUNT !解答数
LET ANSWER_COUNT=0


EXTERNAL FUNCTION fnVAL(w$) !文字表現の数を数値に換える
   LET v=0
   FOR i=1 TO LEN(w$)
      LET p=POS(c$,w$(i:i))
      LET v=v*10+a(p)
   NEXT i
   LET fnVAL=v
END FUNCTION

PUBLIC SUB perm
EXTERNAL SUB perm(cy, L) !nPr順列での数の組を生成する
   FOR nm=LBOUND(f) TO UBOUND(f) !重複を避けて、0〜9の数字を割り当てる
      IF f(nm)=0 THEN
         LET f(nm)=1 !使用中フラグをONにする

         LET a(L)=nm !L番目を数nmとする

         !----- ↓↓↓↓↓ ----- ※差し替え
         SELECT CASE c$(L:L)
         CASE "N" !一の位を確認する
            LET k=fnVAL("E")+fnVAL("O")+fnVAL("R")
            IF MOD(k,10)=fnVAL("N") THEN
               CALL perm(INT(k/10), L+1)
            END IF
         CASE "U" !十の位を確認する
            LET k=fnVAL("N")+fnVAL("W")+fnVAL("U") + cy
            IF MOD(k,10)=fnVAL("E") THEN
               CALL perm(INT(k/10), L+1)
            END IF
         CASE "V" !百の位を確認する
            LET k=fnVAL("O")+fnVAL("T")+fnVAL("O") + cy
            IF fnVAL("O")>0 AND fnVAL("T")>0 AND MOD(k,10)=fnVAL("V") THEN
               CALL perm(INT(k/10), L+1)
            END IF
         CASE "S" !万と千の位を確認する
            LET k=fnVAL("F") + cy
            IF fnVAL("F")>0 AND fnVAL("S")>0 AND k=fnVAL("SE") THEN

               LET ANSWER_COUNT=ANSWER_COUNT+1 !解答数
               PRINT ANSWER_COUNT

               PRINT USING "    ONE   ####":fnVAL("ONE") !結果の表示
               PRINT USING "    TWO   ####":fnVAL("TWO")
               PRINT USING "+ FOUR   ####":fnVAL("FOUR")
               PRINT "-------"
               PRINT USING "  SEVEN  #####":fnVAL("SEVEN")
               PRINT

               !STOP !1つだけならコメントをはずす
            END IF
         CASE ELSE
            IF L<LEN(c$) THEN CALL perm((cy), L+1) !次の文字へ ※cyは値渡し
         END SELECT
         !----- ↑↑↑↑↑ -----

         LET f(nm)=0 !未使用
      END IF
   NEXT nm
END SUB

END MODULE
 

最少手数は?

 投稿者:GAI  投稿日:2009年 9月 7日(月)13時31分4秒
返信・引用
  一二三四五六七八九
・・・・・・・・・
・・・・・・・・・
歩歩歩歩歩歩歩歩歩7
 角銀金香金銀飛 8
香桂銀金玉金銀桂香9

という将棋盤上の配置から、飛と角の位置を交換させる(ただし入れ替わった後の他の駒は
元の位置にあること。九8飛が1手目)
この入れ替えパズルの最少手数を求められますか?
 

Re: 最少手数は?

 投稿者:山中和義  投稿日:2009年 9月 8日(火)16時55分37秒
返信・引用
  > No.540[元記事へ]

GAIさんへのお返事です。

歩、香、桂は前方移動のみなので、ここでは移動できない。したがって、これらは壁となる。

 角銀金×金銀飛
××銀金玉金銀××

の盤と駒で考えればよい。

1 手
 角銀金×金銀 飛 ※1手のみ
××銀金玉金銀××
2 手
 角銀金×金銀銀飛 ※1手のみ
××銀金玉金 ××
3 手
 角銀金×金銀銀飛 ※1手のみ
××銀金玉 金××

次の4手目は2通りある。
4 手
 角銀金× 銀銀飛
××銀金玉金金××

4 手
 角銀金×金銀銀飛
××銀金 玉金××

 :
 :
 :

1手に平均して候補が2通りあるとすると、2^99通り(最小手がわかっているとしても)。
これは天文学的な値です。

単純なバックトラック法で、非力なパソコンを使って解を求めるのは無理でしょう。
 

疑問

 投稿者:GAI  投稿日:2009年 9月 8日(火)19時25分34秒
返信・引用
  どうして2^99を判断されたんですか?  

Re: 疑問

 投稿者:山中和義  投稿日:2009年 9月 8日(火)19時43分33秒
返信・引用
  > No.542[元記事へ]

GAIさんへのお返事です。

> どうして2^99を判断されたんですか?

最小が99手だからです。それを見つけるために虱潰しに探す「場合の数」です。
 

Re: 疑問

 投稿者:GAI  投稿日:2009年 9月 8日(火)21時51分48秒
返信・引用
  > No.543[元記事へ]

山中和義さんへのお返事です。


> 最小が99手だからです。それを見つけるために虱潰しに探す「場合の数」です。


99手かかることは、試行錯誤で見つけ出されたのですか?
それにしてもこんな短時間でどうやったら見つけられるのか呆気に取られます。
 

パズルの解が知りたい。

 投稿者:GAI  投稿日:2009年 9月11日(金)19時40分13秒
返信・引用
  次の2つのパズルに出くわし、どうしても解きたく1週間挑戦するも歯がたたず、サイトで調べてもどこにも解答らしきものに出会えず、でもどうしても解答が知りたい。
プログラムの力で見つけてもらえないでしょうか。
または、どなたか解答をご存じではないでしょうか?


Rolling Cube1
さいころが9個(3×3)入る箱があり、中央にはさいころがなく、周りに8個のさいころが1の目を下にして配置されている。
さいころを空き地に転がすことで、全てのさいころの目が1が出現するようにせよ。
Rolling Cube2
8×8のオセロ板の左上に1の目を上にしたさいころがある。全てのマス目を1の目が出現しないよう(上の面に1の目が出ない。)に転がしていき、最後に右上のマス目で終了する時初めて1の目が現れること。
 

Re: パズルの解が知りたい。

 投稿者:山中和義  投稿日:2009年 9月11日(金)20時51分23秒
返信・引用
  > No.545[元記事へ]

GAIさんへのお返事です。

「さいころを転がす」を参照のこと。 No.99[元記事へ]

2箇所(プログラムの中央あたり)

LET s$="RRRRRRR" !手順 1

SET WINDOW -1,9,9,-1 !表示領域

を修正してください。転がしていくと動きが見えてくると思います。
 

ヤッター!!

 投稿者:GAI  投稿日:2009年 9月11日(金)23時21分14秒
返信・引用
  Rolling Cube2が
LET s$="RRRDLDLULDDDDDDRURDRUULLUURDRUURDDRURDDLLDDRURDRUUUUUULDLULURRR"
で無事到着しました。
長いもやもやがスッキリした気分です。
そういえば、以前こんな問題を山中さんから出題されていましたね。
すっかり忘れていました。こんなところで繋がるとは思ってもいませんでした。
強力なプログラム有り難うございました。
 

Re: パズルの解が知りたい。

 投稿者:山中和義  投稿日:2009年 9月13日(日)09時56分11秒
返信・引用  編集済
  > No.545[元記事へ]

GAIさんへのお返事です。

> プログラムの力で見つけてもらえないでしょうか。

Rolling Cube 2 を解くプログラム

「マップの経路探索」と「置換」とを組み合わせました。
8×8は非力なパソコンでは一日作業になります。2進モードで実行してください。

!問題
! さいころが1つ、8×8の盤の左上隅に1の面を上に乗っています。
! このさいころを全てのマスを1度だけ通って右上隅に転がして移動させます。
! このとき、途中で1の面が上に来てはいけません。
! 最後に右上隅に来たときは、1の面が上になるようにしてください。

DECLARE EXTERNAL NUMERIC RollCube.A() !外部手続き、変数
DECLARE EXTERNAL NUMERIC Map.ANSWER_COUNT
DECLARE EXTERNAL SUB Map.visit

LET t0=TIME

CALL visit(2,2,1,A) !左上の座標(Y,X)=(1,1) ※外壁を考慮する
IF ANSWER_COUNT=0 THEN PRINT "解なし"

PRINT "実行時間=";TIME-t0

END


MODULE Map !マップの構築とその経路探索

SHARE NUMERIC SX,SY !マップの大きさ ※
LET SY=8 !縦
LET SX=8 !横


SHARE NUMERIC M(20,20) !マップ
MAT M=ZER(SY+2,SX+2)
FOR i=1 TO SX+2 !外壁をつくる ※番兵
   LET M(1,i)=-1
   LET M(SY+2,i)=-1
NEXT i
FOR i=1 TO SY+2
   LET M(i,1)=-1
   LET M(i,SX+2)=-1
NEXT i

!内壁をつくる ※

!!!MAT PRINT M; !debug


SHARE NUMERIC EX,EY !終点の座標 ※
LET EX=SX+1 !右上隅 ※外壁を考慮する
LET EY=1+1


SHARE NUMERIC DIST !経路を1度だけ通る最大距離
FOR i=2 TO SY+1
   FOR j=2 TO SX+1
      IF M(i,j)=0 THEN LET DIST=DIST+1
   NEXT j
NEXT i
!!!PRINT DIST !debug


PUBLIC NUMERIC ANSWER_COUNT !解答数
LET ANSWER_COUNT=0

SET WINDOW 0,1,1,0 !---------- trace


PUBLIC SUB vist
EXTERNAL SUB visit(yy,xx,Cnt,T()) !経路(1度だけ通る)を探索する
   DECLARE EXTERNAL SUB RollCube.PermMultiply,RollCube.PermPrintOut !外部手続き、変数
   DECLARE EXTERNAL NUMERIC RollCube.U(),RollCube.D(),RollCube.L(),RollCube.R()
   DECLARE EXTERNAL NUMERIC RollCube.DX(),RollCube.DY()
   DIM TT(UBOUND(T)) !作業用

   LET M(yy,xx)=Cnt !足跡

   SET DRAW mode hidden !---------- trace start
   CLEAR
   FOR i=1 TO SY+2
      FOR j=1 TO SX+2
         PLOT TEXT, AT 0.06*j,0.06*i: STR$(M(i,j))
      NEXT j
   NEXT i
   SET DRAW mode explicit !---------- trace end

   IF (xx=EX AND yy=EY) THEN !終点なら
      IF Cnt=DIST AND T(3)=1 THEN !すべてのマスを経由して、1の目なら
         LET ANSWER_COUNT=ANSWER_COUNT+1
         PRINT "No.";ANSWER_COUNT
         MAT PRINT USING(REPEAT$(" ##",UBOUND(M,2))): M
      END IF

   ELSE
      FOR i=1 TO 4 !上下左右の4近傍
         LET ty=yy+DY(i)
         LET tx=xx+DX(i)

         IF DIST=SY*SX AND Cnt<(SY-1)*(SX-1) AND (ty>SY OR tx>SX) THEN !マップを分割することを防ぐ
         ELSE !!!!!※開始位置が最下行以外

            IF M(ty,tx)=0 THEN !未踏なら

               SELECT CASE i !さいころを転がしてみる
               CASE 1
                  CALL PermMultiply(T,U,TT)
               CASE 2
                  CALL PermMultiply(T,D,TT)
               CASE 3
                  CALL PermMultiply(T,L,TT)
               CASE 4
                  CALL PermMultiply(T,R,TT)
               CASE ELSE
               END SELECT

               IF Cnt+1=DIST OR TT(3)<>1 THEN CALL visit(ty,tx,Cnt+1,TT) !1の目以外なら、次へ

            END IF

         END IF !!!!!

      NEXT i

   END IF

   LET M(yy,xx)=0 !元に戻す

END SUB

END MODULE


MODULE RollCube !さいころを転がす

PUBLIC NUMERIC DX(4),DY(4) !上下左右の4近傍
DATA  0,0,-1,1
DATA -1,1, 0,0
MAT READ DX
MAT READ DY


!展開図の配置と面番号(配列の添え字)との関係
! □    後    1
!□□□□ 左上右下 2345
! □    正    6

PUBLIC NUMERIC A(6)
DATA 5,4,1,3,6,2 !目の配置 ※展開図参照
MAT READ A


PUBLIC NUMERIC U(6),D(6),L(6),R(6) !置換
!    1,2,3,4,5,6
DATA 3,2,6,4,1,5 !上 ※正面を上面にする(図での水平軸)回転
!!!DATA 5,2,1,4,6,3 !下
DATA 1,3,4,5,2,6 !左
!!!DATA 1,5,2,3,4,6 !右

MAT READ U
CALL PermInverse(U,D)
!!!MAT READ D
MAT READ L
CALL PermInverse(L,R)
!!!MAT READ R


!置換(Permutation)の計算
PUBLIC SUB PermPrintOut
EXTERNAL SUB PermPrintOut(A()) !表示する
   MAT PRINT USING(REPEAT$(" ##",UBOUND(A))): A;
   PRINT
END SUB
PUBLIC SUB PermIdentity
EXTERNAL SUB PermIdentity(A()) !恒等置換
   FOR i=1 TO UBOUND(A)
      LET A(i)=i
   NEXT i
END SUB
PUBLIC SUB PermInverse
EXTERNAL SUB PermInverse(A(), iA()) !逆置換 ※iAはA以外の配列を指定すること
   FOR i=1 TO UBOUND(A)
      LET iA(A(i))=i
   NEXT i
END SUB
PUBLIC SUB PermMultiply
EXTERNAL SUB PermMultiply(A(),B(), AB()) !積AB ※ABはA以外かつB以外の配列を指定すること
   LET ua=UBOUND(A)
   LET ub=UBOUND(B)
   IF ua=ub THEN
      FOR i=1 TO ua
         LET AB(i)=A(B(i)) !※合成写像(AB)(i)=A(B(i))
      NEXT i
   ELSE
      PRINT "次元が違います。A=";ua;" B=";ub
      STOP
   END IF
END SUB

END MODULE


>サイトで調べてもどこにも解答らしきものに出会えず、

こちら に両方あります。
 

覆面算から小町算へ

 投稿者:GAI  投稿日:2009年 9月13日(日)19時21分53秒
返信・引用
  作って頂いた覆面算のプログラムを利用して次のような結果が可能なことが確認できました。

 7932  1
---------- = ---(他全部で12通り)
15864  2

 5832  1
---------- = ---(他2通り)
17496  3

 3942  1
---------- = ---(他4通り)
15768  4

 9723  1
---------- = ---(他12通り)
48615  5

 2943  1
---------- = ---(他3通り)
17658  6

 7614  1
---------- = ---(他7通り)
53298  7

 9321  1
---------- = ---(他46通り)
74568  8

 8361  1
---------- = ---(他3通り)
75249  9

分数が小町算型でこれだけ作れることに驚愕しました。
 

(無題)

 投稿者:GAI  投稿日:2009年 9月13日(日)22時23分9秒
返信・引用
  > No.548[元記事へ]

山中和義さんへのお返事です。

> Rolling Cube 2 を解くプログラム
>
> 「マップの経路探索」と「置換」とを組み合わせました。
> 8×8は非力なパソコンでは一日作業になります。2進モードで実行してください。

プログラムを2進法で10時間位走らせたら終了しましたが、
結果が
1234
 765
 8910
  131211
  141516
  191817
  202122
の転がす番号が付いたものを解答として示しましたが(23番以降の番号は出てきません。)、確かにこれで転がすと1の目は出現しませんが、この後全面のマス目を制覇しようとすると必ず1の目は出現してしまいます。
 私には原因がどこにあるのかまったく分かりませんので、ご検討をお願いします。
 

Re: パズルの解が知りたい。

 投稿者:山中和義  投稿日:2009年 9月13日(日)23時28分10秒
返信・引用  編集済
  > No.548[元記事へ]

ご迷惑をおかけします。
解も枝刈りしていましたので、正しい結果になりませんでした。

次のように修正してください。
!問題
! さいころが1つ、8×8の盤の左上隅に1の面を上に乗っています。
! このさいころを全てのマスを1度だけ通って右上隅に転がして移動させます。
! このとき、途中で1の面が上に来てはいけません。
! 最後に右上隅に来たときは、1の面が上になるようにしてください。

!その他では、1×1、1×5、2×2、4×2、4×6など

DECLARE EXTERNAL NUMERIC RollCube.A() !外部手続き、変数
DECLARE EXTERNAL NUMERIC Map.ANSWER_COUNT
DECLARE EXTERNAL SUB Map.visit

LET t0=TIME

CALL visit(2,2,1,A) !左上の座標(Y,X)=(1,1) ※外壁を考慮する
IF ANSWER_COUNT=0 THEN PRINT "解なし"

PRINT "実行時間=";TIME-t0;"秒"

END


MODULE Map !マップの構築とその経路探索

SHARE NUMERIC SX,SY !マップの大きさ ※
LET SY=8 !縦
LET SX=8 !横


SHARE NUMERIC M(20,20) !マップ
MAT M=ZER(SY+2,SX+2)
FOR i=1 TO SX+2 !外壁をつくる ※番兵
   LET M(1,i)=-1
   LET M(SY+2,i)=-1
NEXT i
FOR i=1 TO SY+2
   LET M(i,1)=-1
   LET M(i,SX+2)=-1
NEXT i

!内壁をつくる ※

!!!MAT PRINT M; !debug


SHARE NUMERIC EX,EY !終点の座標 ※
LET EX=SX+1 !右上隅 ※外壁を考慮する
LET EY=1+1


SHARE NUMERIC DIST !経路を1度だけ通る最大距離
FOR i=2 TO SY+1
   FOR j=2 TO SX+1
      IF M(i,j)=0 THEN LET DIST=DIST+1
   NEXT j
NEXT i
!!!PRINT DIST !debug


PUBLIC NUMERIC ANSWER_COUNT !解答数
LET ANSWER_COUNT=0

SET WINDOW 0,1,1,0 !---------- trace


PUBLIC SUB vist
EXTERNAL SUB visit(yy,xx,Cnt,T()) !経路(1度だけ通る)を探索する
   DECLARE EXTERNAL SUB RollCube.PermMultiply,RollCube.PermPrintOut !外部手続き、変数
   DECLARE EXTERNAL NUMERIC RollCube.U(),RollCube.D(),RollCube.L(),RollCube.R()
   DECLARE EXTERNAL NUMERIC RollCube.DX(),RollCube.DY()
   DIM TT(UBOUND(T)) !作業用

   LET M(yy,xx)=Cnt !足跡

   SET DRAW mode hidden !---------- trace start
   CLEAR
   FOR i=1 TO SY+2 !マップを表示する
      FOR j=1 TO SX+2
         PLOT TEXT, AT 0.06*j,0.06*i: STR$(M(i,j))
      NEXT j
   NEXT i
   SET DRAW mode explicit !---------- trace end

   IF (xx=EX AND yy=EY) THEN !終点なら
      IF Cnt=DIST AND T(3)=1 THEN !すべてのマスを経由して、1の目なら
         LET ANSWER_COUNT=ANSWER_COUNT+1 !解を表示する
         PRINT "No.";ANSWER_COUNT
         MAT PRINT USING(REPEAT$(" ##",UBOUND(M,2))): M
      END IF

   ELSE
      IF (Cnt>=DIST/5 AND Cnt<=DIST*4/5) AND MOD(Cnt,4)=0 THEN !孤立領域の有無 ※要調整
         IF ChkDivdRegion(M)<>0 THEN !あれば、終了!
            LET M(yy,xx)=0 !!!!!
            EXIT SUB
         END IF
      END IF


      FOR i=4 TO 1 STEP -1 !上下左右の4近傍 ※ケースバイケース
      !!FOR i=1 TO 4 !上下左右の4近傍 ※ケースバイケース
         LET ty=yy+DY(i)
         LET tx=xx+DX(i)

         IF M(ty,tx)=0 THEN !未踏なら

            SELECT CASE i !さいころを転がしてみる
            CASE 1
               CALL PermMultiply(T,U,TT)
            CASE 2
               CALL PermMultiply(T,D,TT)
            CASE 3
               CALL PermMultiply(T,L,TT)
            CASE 4
               CALL PermMultiply(T,R,TT)
            CASE ELSE
            END SELECT

            IF Cnt+1=DIST OR TT(3)<>1 THEN CALL visit(ty,tx,Cnt+1,TT) !1の目以外なら、次へ

         END IF

      NEXT i

   END IF

   LET M(yy,xx)=0 !元に戻す
END SUB

EXTERNAL FUNCTION ChkDivdRegion(M(,)) !マップが分割されたかどうか確認する
   LET ChkDivdRegion=0 !「なし」

   LET i=2 !first scan
   DO WHILE i<=SY+1
      FOR j=2 TO SX+1
         IF M(i,j)=0 THEN EXIT DO !1個目が見つかったら
      NEXT j
      LET i=i+1
   LOOP
   IF i>SY+1 AND j>SX+1 THEN EXIT FUNCTION !すべて埋まっている

   CALL PaintRegion(M,i,j) !その領域を埋める
   !!!MAT PRINT M; !debug

   LET ChkDivdRegion=1 !「あり」
   FOR i=2 TO SY+1 !second scan
      FOR j=2 TO SX+1
         IF M(i,j)=0 THEN EXIT FUNCTION !他にもあるなら、そこが孤立領域になる
      NEXT j
   NEXT i
   LET ChkDivdRegion=0 !すべて埋まっている
END FUNCTION

EXTERNAL SUB PaintRegion(M(,),i,j) !領域を塗りつぶす
   LET M(i,j)=-2
   IF M(i-1,j)=0 THEN CALL PaintRegion(M,i-1,j)
   IF M(i,j-1)=0 THEN CALL PaintRegion(M,i,j-1)
   IF M(i,j+1)=0 THEN CALL PaintRegion(M,i,j+1)
   IF M(i+1,j)=0 THEN CALL PaintRegion(M,i+1,j)
END SUB

END MODULE


MODULE RollCube !さいころを転がす

PUBLIC NUMERIC DX(4),DY(4) !上下左右の4近傍
DATA  0,0,-1,1
DATA -1,1, 0,0
MAT READ DX
MAT READ DY


!展開図の配置と面番号(配列の添え字)との関係
! □    後    1
!□□□□ 左上右下 2345
! □    正    6

PUBLIC NUMERIC A(6)
DATA 5,4,1,3,6,2 !目の配置 ※展開図参照
MAT READ A


PUBLIC NUMERIC U(6),D(6),L(6),R(6) !置換
!    1,2,3,4,5,6
DATA 3,2,6,4,1,5 !上 ※正面を上面にする(図での水平軸)回転
!!!DATA 5,2,1,4,6,3 !下
DATA 1,3,4,5,2,6 !左
!!!DATA 1,5,2,3,4,6 !右

MAT READ U
CALL PermInverse(U,D)
!!!MAT READ D
MAT READ L
CALL PermInverse(L,R)
!!!MAT READ R


!置換(Permutation)の計算
PUBLIC SUB PermPrintOut
EXTERNAL SUB PermPrintOut(A()) !表示する
   MAT PRINT USING(REPEAT$(" ##",UBOUND(A))): A;
   PRINT
END SUB
PUBLIC SUB PermIdentity
EXTERNAL SUB PermIdentity(A()) !恒等置換
   FOR i=1 TO UBOUND(A)
      LET A(i)=i
   NEXT i
END SUB
PUBLIC SUB PermInverse
EXTERNAL SUB PermInverse(A(), iA()) !逆置換 ※iAはA以外の配列を指定すること
   FOR i=1 TO UBOUND(A)
      LET iA(A(i))=i
   NEXT i
END SUB
PUBLIC SUB PermMultiply
EXTERNAL SUB PermMultiply(A(),B(), AB()) !積AB ※ABはA以外かつB以外の配列を指定すること
   LET ua=UBOUND(A)
   LET ub=UBOUND(B)
   IF ua=ub THEN
      FOR i=1 TO ua
         LET AB(i)=A(B(i)) !※合成写像(AB)(i)=A(B(i))
      NEXT i
   ELSE
      PRINT "次元が違います。A=";ua;" B=";ub
      STOP
   END IF
END SUB

END MODULE
 

将棋駒の入れ替え、再考

 投稿者:山中和義  投稿日:2009年 9月14日(月)16時15分59秒
返信・引用  編集済
  盤や駒を文字列で扱っているのを、数値に置き換えると2倍程度(経験則)速くなると思います。

サンプル・プログラム
!パズル - 将棋駒の入れ替え

!3×3 1行目と3行目を入れ替える
! 銀金銀   歩歩歩
! 角 飛 → 角 飛
! 歩歩歩   銀金銀
!答え 30手

LET t0=TIME

PUBLIC NUMERIC xSIZE,ySIZE !盤の大きさ
LET xSIZE=3
LET ySIZE=3

PUBLIC NUMERIC cSPACE !空白の数
LET cSPACE=1

DECLARE STRING INIT$ !初期の状態
LET INIT$="銀金銀角 飛歩歩歩"

PUBLIC STRING GOAL$ !完成の状態
LET GOAL$="歩歩歩角 飛銀金銀" !完全一致
!!LET GOAL$="歩歩歩○○○○○○" !部分一致


PUBLIC STRING KO$(6) !駒の種類と移動可能範囲 ※8近傍 動きは将棋と同じ
DATA "×○××歩××××"
DATA "○○○×銀×○×○"
DATA "○○○○金○×○×"
DATA "○×○×角×○×○"
DATA "×○×○飛○×○×"
DATA "○○○○玉○○○○"
FOR i=1 TO 6
   READ KO$(i)
NEXT i

PUBLIC NUMERIC LIM !手数の上限 →最少手数
LET LIM=200

PUBLIC STRING ANS$(0 TO 200) !上限までの手順
PUBLIC STRING STK$(0 TO 200) !局面の記録 ※スタック
FOR i=0 TO 200
   LET ANS$(i)=""
   LET STK$(i)=""
NEXT i

!PUBLIC NUMERIC LVL(0 TO 200) !----- trace -----
!MAT LVL=ZER


IF LEN(INIT$)<>ySIZE*xSIZE THEN
   PRINT "盤の大きさ(xSIZE,ySIZE)と駒の数(INIT$)が合いません。"
   STOP
END IF
IF LEN(GOAL$)<>ySIZE*xSIZE THEN
   PRINT "盤の大きさ(xSIZE,ySIZE)と駒の数(GOAL$)が合いません。"
   STOP
END IF

LET STK$(0)=INIT$
CALL backtrack(0) !0手目

IF ANS$(0)="" THEN
   PRINT "解なし"
ELSE
   PRINT
   FOR i=1 TO LIM !解を表示する
      PRINT ANS$(i)
   NEXT i
END IF

PRINT "計算時間=";TIME-t0;"秒"

END


EXTERNAL SUB backtrack(L) !1手ずつ打っていき、行き詰まれば元に戻ってやり直す
LET bd$=stk$(L) !現在の局面

!---------- ↓↓↓↓↓ ---------- trace
!SET DRAW mode hidden !ちらつき防止の開始
!CLEAR
!FOR i=1 TO L
!   PLOT TEXT ,AT 0.4+0.05*MOD(i-1,10),0.95-0.04*INT((i-1)/10): STR$(LVL(i))
!NEXT i
!FOR i=1 TO ySIZE
!   LET t=(i-1)*xSIZE
!   PLOT TEXT ,AT 0.1,0.50-i*0.05: bd$(t+1:t+xSIZE)
!NEXT i
!SET DRAW mode explicit !ちらつき防止の終了
!---------- ↑↑↑↑↑ ----------

LET C=0 !枝刈り ※「残りの手数」と「駒の位置が一致しない数」との関係より
FOR i=1 TO ySIZE*xSIZE
   SELECT CASE GOAL$(i:i)
   CASE "×"," ","○" !何でも良い
   CASE ELSE !完全一致
      IF GOAL$(i:i)<>bd$(i:i) THEN LET C=C+1 !C個の駒を一致させる必要があるが、
   END SELECT
NEXT i
IF L+C>LIM THEN EXIT SUB !残りの手数が足りないので、不可能!!!

IF C=0 THEN !完成なら、手順を記録しておく
   PRINT L;"手"
   FOR i=0 TO L
      LET ANS$(i)=STK$(i)
   NEXT i
   PRINT STK$(L) !debug
   LET LIM=L !上限を狭める
END IF

IF L>=LIM THEN EXIT SUB !上限まで


LET CntOfSP=0
FOR p=1 TO ySIZE*xSIZE !盤を走査して空白に駒を移動させる
   IF bd$(p:p)=" " THEN

      LET px=MOD(p-1,xSIZE)+1 !水平・垂直の座標へ
      LET py=INT((p-1)/xSIZE)+1

      !!!FOR d=1 TO 9 !隣接する駒を探す ※ケースバイケース
      FOR d=9 TO 1 STEP -1 !隣接する駒を探す ※ケースバイケース
         IF d=5 THEN
         ELSE
            LET mx=px + MOD(d-1,3)-1 !移動元の座標 ※dを水平・垂直の差分dx,dyへ
            LET my=py + INT((d-1)/3)-1
            IF (mx>=1 AND mx<=xSIZE) AND (my>=1 AND my<=ySIZE) THEN !盤内か確認する

               LET mp=(my-1)*xSIZE + mx !連番へ
               LET t$=bd$(mp:mp)
               IF t$="×" OR t$=" " THEN
               ELSE

                  FOR a=1 TO UBOUND(KO$) !駒の属性を得る
                     IF t$=KO$(a)(5:5) THEN EXIT FOR
                  NEXT a
                  IF KO$(a)(10-d:10-d)="×" THEN !移動可能範囲なら
                  ELSE

                     LET w$=bd$
                     LET w$(p:p)=KO$(a)(5:5) !移動させる
                     LET w$(mp:mp)=" "

                     FOR t=L TO 0 STEP -1 !最近の局面から順に新しい手かどうか確認する
                        IF STK$(t)=w$ THEN EXIT FOR
                     NEXT t
                     IF t<0 THEN
                     !LET LVL(L+1)=CntOfSP*10+d !----- trace -----
                        LET STK$(L+1)=w$ !記録して、次の局面へ
                        CALL backtrack(L+1)
                     END IF

                  END IF

               END IF

            END IF

         END IF
      NEXT d

      LET CntOfSP=CntOfSP+1
      IF CntOfSP=cSPACE THEN EXIT FOR !空白の数だけ
   END IF
NEXT p
END SUB


WindowsMe、Pentium��700MHz、192MBにて、十進BASIC 2進モードで実行。
 86 手
歩歩歩角 飛銀金銀
 84 手
歩歩歩角 飛銀金銀
 84 手
歩歩歩角 飛銀金銀
 82 手
歩歩歩角 飛銀金銀
 82 手
歩歩歩角 飛銀金銀
 79 手
歩歩歩角 飛銀金銀
 77 手
歩歩歩角 飛銀金銀
 76 手
歩歩歩角 飛銀金銀
 76 手
歩歩歩角 飛銀金銀
 75 手
歩歩歩角 飛銀金銀
 74 手
歩歩歩角 飛銀金銀
 74 手
歩歩歩角 飛銀金銀
 69 手
歩歩歩角 飛銀金銀
 67 手
歩歩歩角 飛銀金銀
 63 手
歩歩歩角 飛銀金銀
 61 手
歩歩歩角 飛銀金銀
 61 手
歩歩歩角 飛銀金銀
 59 手
歩歩歩角 飛銀金銀
 58 手
歩歩歩角 飛銀金銀
 58 手
歩歩歩角 飛銀金銀
 57 手
歩歩歩角 飛銀金銀
 56 手
歩歩歩角 飛銀金銀
 48 手
歩歩歩角 飛銀金銀
 48 手
歩歩歩角 飛銀金銀
 46 手
歩歩歩角 飛銀金銀
 46 手
歩歩歩角 飛銀金銀
 44 手
歩歩歩角 飛銀金銀
 44 手
歩歩歩角 飛銀金銀
 42 手
歩歩歩角 飛銀金銀
 42 手
歩歩歩角 飛銀金銀
 42 手
歩歩歩角 飛銀金銀
 42 手
歩歩歩角 飛銀金銀
 40 手
歩歩歩角 飛銀金銀
 40 手
歩歩歩角 飛銀金銀
 40 手
歩歩歩角 飛銀金銀
 40 手
歩歩歩角 飛銀金銀
 39 手
歩歩歩角 飛銀金銀
 39 手
歩歩歩角 飛銀金銀
 39 手
歩歩歩角 飛銀金銀
 39 手
歩歩歩角 飛銀金銀
 36 手
歩歩歩角 飛銀金銀
 32 手
歩歩歩角 飛銀金銀
 32 手
歩歩歩角 飛銀金銀
 32 手
歩歩歩角 飛銀金銀
 32 手
歩歩歩角 飛銀金銀
 32 手
歩歩歩角 飛銀金銀
 30 手
歩歩歩角 飛銀金銀
 30 手
歩歩歩角 飛銀金銀

銀金 角銀飛歩歩歩
銀 金角銀飛歩歩歩
銀銀金角 飛歩歩歩
銀銀金角歩飛歩 歩
銀銀金 歩飛歩角歩
銀 金銀歩飛歩角歩
銀歩金銀 飛歩角歩
銀歩金銀飛 歩角歩
銀歩金銀飛角歩 歩
銀歩金銀 角歩飛歩
 歩金銀銀角歩飛歩
銀歩金 銀角歩飛歩
銀歩金歩銀角 飛歩
銀歩金歩銀角飛 歩
銀歩金歩銀 飛角歩
銀歩 歩銀金飛角歩
銀歩銀歩 金飛角歩
 歩銀歩銀金飛角歩
歩歩銀 銀金飛角歩
歩歩銀角銀金飛 歩
歩歩銀角銀金 飛歩
歩歩銀角 金銀飛歩
歩歩銀角金 銀飛歩
歩歩銀角金歩銀飛
歩歩銀角金歩銀 飛
歩歩銀角 歩銀金飛
歩歩 角銀歩銀金飛
歩歩歩角銀 銀金飛
歩歩歩角銀飛銀金
歩歩歩角 飛銀金銀
計算時間= 45.0900000000001 秒
 

Re: Full BASIC高速化の試み

 投稿者:白石 和夫  投稿日:2009年 9月14日(月)18時29分58秒
返信・引用
  > No.511[元記事へ]

BASICAcc ver. 0.9.1公開しました。
いくらか限定がありますが,TRACE文以外の全Full BASIC(図形機能単位+モジュール機能単位)命令に対応しました。
今のところ2進演算限定ですが,単純な数値計算は(仮称)十進BASICの2進モードより数倍速くなるようです。

http://sourceforge.jp/projects/decimalbasic/

掲示板(新旧)に投稿されたプログラムを動作確認に利用させていただきました。
(仮称)十進BASICはチェックが甘く,主プログラムの外部から主プログラムの内部手続きを呼び出すことができてしまいますが,BASICAccではそれはできません。
また,識別名は英数字のみ使用可能です。
その他,細部で十進BASICとの差異がありますが,大方のプログラムはそのまま動くと思います。
 

Re: パズルの解が知りたい。

 投稿者:山中和義  投稿日:2009年 9月15日(火)16時09分21秒
返信・引用  編集済
  > No.551[元記事へ]

ベンチマークテスト WindowsME、Pentium��700MHz、RAM192MB にて

「Rolling Cube2を解くプログラム」

> !問題
> ! さいころが1つ、8×8の盤の左上隅に1の面を上に乗っています。
> ! このさいころを全てのマスを1度だけ通って右上隅に転がして移動させます。
> ! このとき、途中で1の面が上に来てはいけません。
> ! 最後に右上隅に来たときは、1の面が上になるようにしてください。

63行
   !SET WINDOW 0,1,1,0 !---------- trace

74行
   !SET DRAW mode hidden !---------- trace start
   !CLEAR
   !FOR i=1 TO SY+2 !マップを表示する
   !   FOR j=1 TO SX+2
   !      PLOT TEXT, AT 0.06*j,0.06*i: STR$(M(i,j))
   !   NEXT j
   !NEXT i
   !SET DRAW mode explicit !---------- trace end

の(トレースに使っている)グラフィックス命令をコメントアウトしてください。


●十進BASIC 10進モードによる
No. 1
 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
 -1  1  2  3  4 61 62 63 64 -1
 -1 10  9  6  5 60 59 56 55 -1
 -1 11  8  7 32 33 58 57 54 -1
 -1 12 27 28 31 34 37 38 53 -1
 -1 13 26 29 30 35 36 39 52 -1
 -1 14 25 24 23 42 41 40 51 -1
 -1 15 18 19 22 43 46 47 50 -1
 -1 16 17 20 21 44 45 48 49 -1
 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
実行時間= 359.27 秒


●十進BASIC 2進モードによる
No. 1
 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
 -1  1  2  3  4 61 62 63 64 -1
 -1 10  9  6  5 60 59 56 55 -1
 -1 11  8  7 32 33 58 57 54 -1
 -1 12 27 28 31 34 37 38 53 -1
 -1 13 26 29 30 35 36 39 52 -1
 -1 14 25 24 23 42 41 40 51 -1
 -1 15 18 19 22 43 46 47 50 -1
 -1 16 17 20 21 44 45 48 49 -1
 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
実行時間= 92.5999999999985 秒


●BASICAccによる
No. 1
 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
 -1  1  2  3  4 61 62 63 64 -1
 -1 10  9  6  5 60 59 56 55 -1
 -1 11  8  7 32 33 58 57 54 -1
 -1 12 27 28 31 34 37 38 53 -1
 -1 13 26 29 30 35 36 39 52 -1
 -1 14 25 24 23 42 41 40 51 -1
 -1 15 18 19 22 43 46 47 50 -1
 -1 16 17 20 21 44 45 48 49 -1
 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
実行時間= 15.1000000000009 秒
 

驚き

 投稿者:GAI  投稿日:2009年 9月17日(木)06時14分26秒
返信・引用
  BASICAccの威力恐るべしですね。
5〜6倍もスピードアップが可能なんだ!
 

Rolling Cube 1

 投稿者:山中和義  投稿日:2009年 9月17日(木)10時17分17秒
返信・引用  編集済
  簡単なGUIのパズルゲームプログラミングです。
プログラムの中断は、「中断」ボタン(メニュー)で行います。
!●問題
!8個のさいころが、3×3の盤に1の目を上にして他の目も同じ向きで配置されています。
!空いているマスに転がして、すべての目が6になるようにしてください。


!置換(Permutation)の計算
SUB PermPrintOut(A()) !表示する
   MAT PRINT USING(REPEAT$(" ##",UBOUND(A))): A;
   PRINT
END SUB
SUB PermIdentity(A()) !恒等置換
   FOR i=1 TO UBOUND(A)
      LET A(i)=i
   NEXT i
END SUB
SUB PermInverse(A(), iA()) !逆置換 ※iAはA以外の配列を指定すること
   FOR i=1 TO UBOUND(A)
      LET iA(A(i))=i
   NEXT i
END SUB
SUB PermMultiply(A(),B(), AB()) !積AB ※ABはAかつB以外の配列を指定すること
   FOR i=1 TO UBOUND(A)
      LET AB(i)=A(B(i)) !※合成写像(AB)(i)=A(B(i))
   NEXT i
END SUB
!-------------------- ここまでがサブルーチン


DIM U(6),D(6),L(6),R(6) !置換
!    1,2,3,4,5,6
DATA 3,2,6,4,1,5 !上 ※正面を上面にするの(図での水平軸)回転
!!!DATA 5,2,1,4,6,3 !下
DATA 1,3,4,5,2,6 !左
!!!DATA 1,5,2,3,4,6 !右

MAT READ U
CALL PermInverse(U,D)
!!!MAT READ D
MAT READ L
CALL PermInverse(L,R)
!!!MAT READ R
!---------- ↑↑↑↑↑ ----------


!展開図の配置と面番号(配列の添え字)との関係
! □    後    1
!□□□□ 左上右下 2345
! □    正    6

DIM T1(6),T2(6),T3(6),T4(6),T5(6),T6(6),T7(6),T8(6) !8個のさいころ
DATA 5,4,1,3,6,2 !目の配置 ※展開図参照
MAT READ T1
MAT T2=T1 !同じ向き
MAT T3=T1
MAT T4=T1
MAT T5=T1
MAT T6=T1
MAT T7=T1
MAT T8=T1

PICTURE dice(T()) !さいころを表示する ※原点基準
   SET TEXT JUSTIFY "CENTER","HALF"
   PLOT TEXT ,AT 0,-0.4: STR$(T(1)) !側面の目の数
   PLOT TEXT ,AT -0.4,0: STR$(T(2))
   PLOT TEXT ,AT 0.4,0: STR$(T(4))
   PLOT TEXT ,AT 0,0.4: STR$(T(6))

   LET nm=T(3) !上面の目の数
   IF nm=1 THEN DRAW eye(4) !中央
   IF nm=3 OR nm=5 THEN DRAW eye(1)

   IF nm=2 OR nm=4 OR nm=5 OR nm=6 THEN !左斜め
      DRAW eye(1) WITH SHIFT(0.25,0.25)
      DRAW eye(1) WITH SHIFT(-0.25,-0.25)
   END IF
   IF nm=3 OR nm=4 OR nm=5 OR nm=6 THEN !右斜め
      DRAW eye(1) WITH SHIFT(0.25,-0.25)
      DRAW eye(1) WITH SHIFT(-0.25,0.25)
   END IF
   IF nm=6 THEN !中段
      DRAW eye(1) WITH SHIFT(0.25,0)
      DRAW eye(1) WITH SHIFT(-0.25,0)
   END IF
END PICTURE

PICTURE eye(c) !1つの目を表示する
   SET AREA COLOR c
   DRAW disk WITH SCALE(0.1) !※要調整
END PICTURE
!---------- ↑↑↑↑↑ ----------


LET MY=3 !マップの大きさ
LET MX=3

DIM M(MY,MX) !さいころの配置 ※数字は番号、0は空き
DATA 1,2,3
DATA 4,0,5
DATA 6,7,8
MAT READ M

SUB dispMap !マップ上のさいころを表示する
   FOR y=1 TO 3 !左上から順に
      LET yy=y-0.5 !位置を算出する
      FOR x=1 TO 3
         LET xx=x-0.5

         SELECT CASE M(y,x) !配置されたさいころに応じて
         CASE 1
            DRAW dice(T1) WITH SHIFT(xx,yy) !上面
         CASE 2
            DRAW dice(T2) WITH SHIFT(xx,yy)
         CASE 3
            DRAW dice(T3) WITH SHIFT(xx,yy)
         CASE 4
            DRAW dice(T4) WITH SHIFT(xx,yy)
         CASE 5
            DRAW dice(T5) WITH SHIFT(xx,yy)
         CASE 6
            DRAW dice(T6) WITH SHIFT(xx,yy)
         CASE 7
            DRAW dice(T7) WITH SHIFT(xx,yy)
         CASE 8
            DRAW dice(T8) WITH SHIFT(xx,yy)
         CASE ELSE
         END SELECT

      NEXT x
   NEXT y
END SUB
!---------- ↑↑↑↑↑ ----------


SUB move(T(),OP(),x,y,dx,dy) !さいころを回転移動させる
   LET ANSWER_COUNT=ANSWER_COUNT+1
   PRINT ANSWER_COUNT;"手"

   DIM TT(6) !作業配列
   CALL PermMultiply(T,OP,TT) !回転
   MAT T=TT
   LET w=M(y,x) !移動
   LET M(y,x)=M(y+dy,x+dx)
   LET M(y+dy,x+dx)=w
END SUB

SUB CalcDirection(x,y, T()) !移動可能な方向へ回転移動させる
   IF y>=2 THEN !上に移動可能で
      IF M(y-1,x)=0 THEN !空きマスなら
         CALL move(T,U,x,y,0,-1) !回転移動させる
         PRINT "UP";y;x
      END IF
   END IF
   IF y<=2 THEN !下
      IF M(y+1,x)=0 THEN
         CALL move(T,D,x,y,0,1)
         PRINT "DOWN";y;x
      END IF
   END IF
   IF x>=2 THEN !左
      IF M(y,x-1)=0 THEN
         CALL move(T,L,x,y,-1,0)
         PRINT "LEFT";y;x
      END IF
   END IF
   IF x<=2 THEN !右
      IF M(y,x+1)=0 THEN
         CALL move(T,R,x,y,1,0)
         PRINT "RIGHT";y;x
      END IF
   END IF
   MAT PRINT M; !debug
END SUB


LET ANSWER_COUNT=0 !手数

SET WINDOW -1,MX+1,MY+1,-1 !表示領域

LET cx=1 !ポインタを左上に位置付ける
LET cy=1
DO
   mouse poll x,y,left,right !マウスの情報を得る
   LET xx=INT(x) !位置
   LET yy=INT(y)
   IF xx>=0 AND xx<MX AND yy>=0 AND yy<MY THEN !マップ内なら
      LET cx=xx+1 ![1,MX]
      LET cy=yy+1 ![1,MY]
   END IF

   IF left=1 THEN !左ボタンが押されたら
      SELECT CASE M(cy,cx) !さいころの番号を得る
      CASE 1
         CALL CalcDirection(cx,cy, T1) !回転移動させる
      CASE 2
         CALL CalcDirection(cx,cy, T2)
      CASE 3
         CALL CalcDirection(cx,cy, T3)
      CASE 4
         CALL CalcDirection(cx,cy, T4)
      CASE 5
         CALL CalcDirection(cx,cy, T5)
      CASE 6
         CALL CalcDirection(cx,cy, T6)
      CASE 7
         CALL CalcDirection(cx,cy, T7)
      CASE 8
         CALL CalcDirection(cx,cy, T8)
      CASE ELSE
      END SELECT
      WAIT DELAY 0.2 !※要調整
   END IF

   SET DRAW mode hidden !ちらつき防止開始
   CLEAR
   DRAW grid !目盛り

   SET LINE width 2 !ポインタを表示する
   PLOT LINES: cx-1,cy-1; cx,cy-1; cx,cy; cx-1,cy; cx-1,cy-1
   SET LINE width 1

   CALL dispMap !さいころを表示する

   SET TEXT JUSTIFY "LEFT","BOTTOM" !文字位置の調整
   PLOT TEXT ,AT -0.5,-0.5: "移動するさいころを左クリックしてください。"

   SET DRAW mode explicit !ちらつき防止終了
LOOP


END


!答え 38手
! URDL,DRUL,LDRR,UULD,RUL;LDR,ULDD,RRUL,LDRU,LURD
 

Rolling Cube 1の拡張

 投稿者:GAI  投稿日:2009年 9月18日(金)14時47分11秒
返信・引用
  > No.556[元記事へ]

山中和義さんへのお返事です。

> 簡単なGUIのパズルゲームプログラミングです。
> プログラムの中断は、「中断」ボタン(メニュー)で行います。
>

> !●問題
> !8個のさいころが、3×3の盤に1の目を上にして他の目も同じ向きで配置されています。
> !空いているマスに転がしてすべての目が2、すべての目が3、すべての目が4、すべての目が5、すべての目が6になるようにしてください。

と問題を拡張することができますね。
それぞれの手順を発見してもらいたい。
 

Re: Rolling Cube 1の拡張

 投稿者:山中和義  投稿日:2009年 9月19日(土)11時06分0秒
返信・引用
  > No.557[元記事へ]

GAIさんへのお返事です。

> それぞれの手順を発見してもらいたい。

「将棋駒の入れ替え」同様 Give up です。

偶然に次のようなものが見つかれば、、、

1→5と1→4は、
1→2と1→3を見つけて、(何手かは不明)
2→5と3→4と考えて、1→6同様の反転で完成、ただし最少手とは限らない。

ところで、1→2などはみつかるのか?
1手に候補が平均3弱あるので、「場合の数」は、1→6と同じと考えても3^36程度。

・枝刈りとしては、回転や反転の対称を削除。(1手、2手を固定する)


ちなみに、1→6は URDL,LDRR,ULDL,URDR,ULDL,UURD,RULD,RDLU,LDRU (36手)。


このような問題は、『いかに「場合の数」を減らすのか』ということです。
覆面算やRolling Cube 2のような論理的、解析的な手法があればいいのですが、、、
 

山中さん凄い!

 投稿者:GAI  投稿日:2009年 9月19日(土)11時48分20秒
返信・引用
  1→6の最少手数を36手で発見されたのは凄い!!!(ぜひ例のサイトへ報告して下さい。これは世界初ですよ。)
私も1→2を作って頂いたプログラムで350手ぐらいかけていじくり回してはみたもののあと1個がどうしても2にならず今だ解決に至っておりません。
これが出来ないという証明があれば諦めも尽きますが・・・
気長に挑戦し続けます。(すべてに解があればすばらしいパズルになるのですが・・・)
 

Re: Rolling Cube 1の拡張

 投稿者:山中和義  投稿日:2009年 9月20日(日)08時45分23秒
返信・引用
  > No.558[元記事へ]

1→2
UR,DLLURRDLLURRDLLDRULDRULURDRULLDRRDLU;R,DLLUURRD,DLLUURRD,DLLUURRD,DLLU,R

セミコロンの前半(38手)
 222
 5 2
 222

セミコロンの後半(30手)
 xxx
 o x ○の反転
 xxx
 

ワンダフル

 投稿者:GAI  投稿日:2009年 9月20日(日)12時15分7秒
返信・引用
  > No.560[元記事へ]

山中和義さんへのお返事です。

> 1→2
> UR,DLLURRDLLURRDLLDRULDRULURDRULLDRRDLU;R,DLLUURRD,DLLUURRD,DLLUURRD,DLLU,R
>
> セミコロンの前半(38手)
>  222
>  5 2
>  222
>
> セミコロンの後半(30手)
>  xxx
>  o x ○の反転
>  xxx

必死に手順を探していました。
どうしても壁にぶち当たり、たいがい脳みそがパンクしそうになっていました。
最後には運を天に任せるべく、転がす始末でした。
よくこんな手順が見えてきますね?(能力の違いをまざまざと感じてしまいます。)
2,6が発見できたから3,4,5も不可能ではなくなるのでしょうか?
 

Re: Rolling Cube 1の拡張

 投稿者:山中和義  投稿日:2009年 9月20日(日)12時35分26秒
返信・引用
  > No.560[元記事へ]

盤の対称性に気がつけば、、、

個々のさいころの向きは、

5   後   ※展開図、盤を上から見下ろしているので上面が見える
4136 左上右下
2   正

である。
前出の操作1→2は、正面(2の目)が上面に移動したことを意味する。

したがって、側面に着目すると
1→3は、盤の右(3の目)が下になるように盤を持ち替える。(時計まわりに90度回転)
その状態で、1→2の手順を行えばよい。

1→3
LU,RDDLUURDDLUURDDRULDRULDLURULDDRUURDL;U,RDDLLUUR,RDDLLUUR,RDDLLUUR,RDDL,U

※スクリプト記述は、盤が固定になるので、反時計まわりに90度回転になる。


1→4、1→5も同様。
 

完全に了解

 投稿者:GAI  投稿日:2009年 9月20日(日)19時16分50秒
返信・引用
  このパズルの奥深さがようやく理解できました。(自分の頭の固さが理解できました。)
世の中にルービックキューブなる商品が結構高価な値段で販売されていますが、それよりも
もっと低学年の年齢の子供にも安価で手作りできて、ルールがシンプルで簡単、でもその迷路的試行錯誤が刺激的で、なんとも言えぬもどかしさが心地よく作用します。
おもちゃの世界にも、こんな商品を置いておいてほしいものです。
世の中にもっと紹介して、全国の園児がこれで遊んでいる姿を想像しています。
 

奇数と偶数

 投稿者:kikiriri  投稿日:2009年 9月22日(火)19時43分37秒
返信・引用
  偶数は必ず2で割り切れるというか、2で割り切れるから偶数これは間違いではない?
けど奇数にはそんな決まった数はなく、(2n+1)、(2n−1)で表現することに決め
たりすることはありますねこれに違和感偶数って特別な数なんだと思ったことのある人はいませんか?
 

すみません編集させていただきました(素数)

 投稿者:kikiriri  投稿日:2009年 9月22日(火)19時51分41秒
返信・引用  編集済
  1とその数自身で割り切れない自然数
1は素数とはしない、このとき、
2,3,5,7,11,13,17,19,23,29,31,37は、
1から40までの素数ですが間違ってませんか
 

Re: 完全に了解

 投稿者:kikiriri  投稿日:2009年 9月22日(火)20時08分4秒
返信・引用
  > No.563[元記事へ]

GAIさんへのお返事です。

> このパズルの奥深さがようやく理解できました。(自分の頭の固さが理解できました。)
> 世の中にルービックキューブなる商品が結構高価な値段で販売されていますが、それよりも
> もっと低学年の年齢の子供にも安価で手作りできて、ルールがシンプルで簡単、でもその迷路的試行錯誤が刺激的で、なんとも言えぬもどかしさが心地よく作用します。
> おもちゃの世界にも、こんな商品を置いておいてほしいものです。
> 世の中にもっと紹介して、全国の園児がこれで遊んでいる姿を想像しています。

ハノイの塔円盤3枚〜4枚くらいも面白いと思いますよ。
 

編集させていただきました(プログラム作成について)

 投稿者:kikiriri  投稿日:2009年 9月22日(火)20時17分14秒
返信・引用  編集済
  画面上や、紙面上で、頭の中で、苦労を重ねて出来ものなんだと思っています
掲示板上のプログラムには、見ていて、目を見張るものがあります。
読めるわけではないのですが、印刷して眺めたりしてると、
自分で努力してプログラムを作ろうと構想を練ろうとするときに作ろうとするときに励みになると思われます。
 

プログラムの勉強をするとき

 投稿者:kikiriri  投稿日:2009年 9月22日(火)20時20分45秒
返信・引用
  プログラム入門書、問題集、アルゴリズムとデータ構造について、
の3冊の本があります、どの順で読み進んでいくのが良いと思われますか、
宜しければご助言等お願いします。
 

すみません

 投稿者:kikiriri  投稿日:2009年 9月23日(水)13時26分26秒
返信・引用  編集済
  あまり意味のない掲示すみません
しばらく様子を見てみます。
宜しければ、ご助言など、お願いします。
 

すみません

 投稿者:kikiriri  投稿日:2009年 9月23日(水)13時28分2秒
返信・引用  編集済
  誤変換のあった掲示を、

掲示板の編集機能より、

訂正させていただきました。

すみませんでした。
 

行番号の前後

 投稿者:荒田浩二  投稿日:2009年 9月24日(木)18時44分52秒
返信・引用
  十進BASICでは次のような行番号が未整列のプログラムも実行可能ですが、JIS規格では
『4.2.2 (26)  行は、行番号の値の昇順に並んでいなければならない(16.参照)。』
とあるので、エラーにするべきだと思うのですがいかがでしょうか。

10 LET a=3
20 LET b=4
30 LET b=a+b
25 PRINT b
50 END
 

Re: 行番号の前後

 投稿者:白石 和夫  投稿日:2009年 9月24日(木)20時27分44秒
返信・引用
  > No.571[元記事へ]

現状ではチェックが不十分で実行できてしまいますが,将来的にはエラーを出すようにしたいと思います。当面,そのようなプログラムを作らないようにお願いします。

> 十進BASICでは次のような行番号が未整列のプログラムも実行可能ですが、JIS規格では
> 『4.2.2 (26)  行は、行番号の値の昇順に並んでいなければならない(16.参照)。』
> とあるので、エラーにするべきだと思うのですがいかがでしょうか。
>
> 10 LET a=3
> 20 LET b=4
> 30 LET b=a+b
> 25 PRINT b
> 50 END
 

演算誤差強制修正

 投稿者:しばっち  投稿日:2009年 9月27日(日)13時27分23秒
返信・引用
  計算結果に演算誤差を含むとき、強制的に修正する。
但し、万能等ではなく、1.249999999999を1.25と修正できる程度。
使用には注意が必要です。(1000000/1000001を1としてしまう可能性がある)



PUBLIC NUMERIC FLG
LET X=8.99999999865/1.999999991572
PRINT "修正前";X;"修正後";NUM(X);"理想値";9/2
LET X=7.000000000357/3.000000001345*5.99999999993247
PRINT "修正前";X;"修正後";NUM(X);"理想値";14
LET X=-15/6.00000000352*10.000000034/2.999999999247
PRINT "修正前";X;"修正後";NUM(X);"理想値";-25/3
LET X=SQR(2.500000000354)*SQR(2.9999999999999871)
PRINT "修正前";X;"修正後";NUM(X);"理想値";SQR(7.5)
LET X=EXP(1.50000000321)*EXP(3.9999999999992417)
PRINT "修正前";X;"修正後";NUM(X);"理想値";EXP(5.5)
END

EXTERNAL  FUNCTION INTNUM(X)
LET EPS=1E-5 !'(要)調整
FOR I=0 TO 4 !'(要)調整
   FOR J=0 TO 1
      LET Y=ABS(X)*10^I+J*EPS
      IF ABS(Y)-INT(ABS(Y))<=EPS THEN
         LET INTNUM=SGN(X)*INT(ABS(Y))/10^I
         LET FLG=1
         EXIT FUNCTION
      END IF
   NEXT J
NEXT  I
LET INTNUM=X
LET FLG=0
END FUNCTION

EXTERNAL  FUNCTION NUM(X)
LET Y=INT(ABS(X))
LET P=ABS(X)-Y
LET K=INTNUM(X)
IF FLG=1 THEN
   LET NUM=K
   EXIT FUNCTION
END IF
LET K=INTNUM(1/P)
IF FLG=1 THEN
   LET NUM=(Y+1/K)*SGN(X)
   EXIT FUNCTION
END IF
LET K=INTNUM(X*X)
IF FLG=1 THEN
   LET NUM=SQR(K)*SGN(X)
   EXIT FUNCTION
END IF
IF X>0 THEN
   LET K=INTNUM(LOG(X))
   IF  FLG=1  THEN
      LET NUM=EXP(K)
      EXIT FUNCTION
   END IF
END IF
IF ABS(X)<228 THEN
   LET K=INTNUM(EXP(X))
   IF FLG=1  THEN
      LET NUM=LOG(K)*SGN(X)
      EXIT FUNCTION
   END IF
END IF
LET NUM=X
END FUNCTION
 

複素数ライブラリー

 投稿者:しばっち  投稿日:2009年 9月27日(日)13時29分39秒
返信・引用
  複素数モードで使用できる関数をいくつか定義してみました。
なお、作成には「Maxima」を利用しました。 {ex.   realpart(cos(x+%i*y));  }
                                         {      imagpart(cos(x+%i*y));  }
http://sourceforge.net/projects/maxima/files/


OPTION ARITHMETIC COMPLEX
LET X=COMPLEX(1,-2)
LET N=5
DIM A(N)
PRINT "X=";X;"(";REAL(X);IMAG(X);")"
PRINT "SIN=";CSIN(X);CSIN2(X)
PRINT "COS=";CCOS(X);CCOS2(X)
PRINT "TAN=";CTAN(X);CTAN2(X)
PRINT "COSEC=";CCOSEC(X);CCOSEC2(X)
PRINT "SEC=";CSEC(X);CSEC2(X)
PRINT "COTAN=";CCOTAN(X);CCOTAN2(X)
PRINT "SINH=";CSINH(X);CSINH2(X)
PRINT "COSH=";CCOSH(X);CCOSH2(X)
PRINT "TANH=";CTANH(X);CTANH2(X)
PRINT "COSECH=";CCOSECH(X);CCOSECH2(X)
PRINT "SECH=";CSECH(X);CSECH2(X)
PRINT "COTANH=";CCOTANH(X);CCOTANH2(X)
PRINT "平方根=";CSQR(X);CEXP(CLOG(X)/2)
CALL CNPOW(X,N,A)
PRINT N;"乗根"
FOR I=1 TO N
   PRINT I;":";A(I);A(I)^N
NEXT I
LET Y=COMPLEX(1,2)
PRINT "X^Y=";CPOW(X,Y);CEXP(Y*CLOG(X))
END

! 三角関数

EXTERNAL  FUNCTION CSIN(Z) !'sine
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET XR = SIN(X) * COSH(Y)
LET XI = COS(X) * SINH(Y)
LET CSIN=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CSIN2(Z)
OPTION ARITHMETIC COMPLEX
LET I=SQR(-1)
LET CSIN2=(CEXP(I*Z)-CEXP(-I*Z))/(2*I)
END FUNCTION

EXTERNAL  FUNCTION CCOS(Z) !'cosine
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET XR = COS(X) * COSH(Y)
LET XI = -SIN(X) * SINH(Y)
LET CCOS=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CCOS2(Z)
OPTION ARITHMETIC COMPLEX
LET I=SQR(-1)
LET CCOS2=(CEXP(I*Z)+CEXP(-I*Z))/2
END FUNCTION

EXTERNAL  FUNCTION CTAN(Z) !'tangent
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D = COS(2 * X) + COSH(2 * Y)
LET XR = SIN(2 * X) / D
LET XI = SINH(2 * Y) / D
LET CTAN=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CTAN2(Z)
OPTION ARITHMETIC COMPLEX
LET CTAN2=CSIN(Z)/CCOS(Z)
END FUNCTION

EXTERNAL  FUNCTION CCOSEC(Z) !'cosecant
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=COS(X)^2*SINH(Y)^2+SIN(X)^2*COSH(Y)^2
LET XR=SIN(X)*COSH(Y)/D
LET XI=-COS(X)*SINH(Y)/D
LET CCOSEC=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CCOSEC2(Z)
OPTION ARITHMETIC COMPLEX
LET CCOSEC2=1/CSIN(Z)
END FUNCTION

EXTERNAL  FUNCTION CSEC(Z) !'secant
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=SIN(X)^2*SINH(Y)^2+COS(X)^2*COSH(Y)^2
LET XR=COS(X)*COSH(Y)/D
LET XI=SIN(X)*SINH(Y)/D
LET CSEC=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CSEC2(Z)
OPTION ARITHMETIC COMPLEX
LET CSEC2=1/CCOS(Z)
END FUNCTION

EXTERNAL  FUNCTION CCOTAN(Z) !'cotangent
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=COSH(2*Y)+COS(2*X)
LET DD=SINH(2*Y)^2+SIN(2*X)^2
LET XR=SIN(2*X)*D/DD
LET XI=-SINH(2*Y)*D/DD
LET CCOTAN=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CCOTAN2(Z)
OPTION ARITHMETIC COMPLEX
LET CCOTAN2=1/CTAN(Z)
END FUNCTION

! 逆三角関数

EXTERNAL  FUNCTION CASIN(Z) !'arcsine
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=SQR((Y^2-X^2+1)^2+4*X^2*Y^2)
LET S=SQR(D-Y^2+X^2-1)/SQR(2)
LET SS=SQR(D+Y^2-X^2+1)/SQR(2)
IF X*Y>0 THEN
   LET XR=-ATAN2(S-X,SS-Y)
   LET XI=-LOG((SS-Y)^2+(X-S)^2)/2
ELSE
   LET XR=ATAN2(S+X,SS-Y)
   LET XI=-LOG((SS-Y)^2+(X+S)^2)/2
END IF
LET CASIN=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL FUNCTION CASIN2(Z)
OPTION ARITHMETIC COMPLEX
LET CASIN2=CATAN(Z/CSQR(1-Z*Z))
END FUNCTION

EXTERNAL  FUNCTION CASIN3(Z)
OPTION ARITHMETIC COMPLEX
LET I=SQR(-1)
LET CASIN3=-I*CLOG(CSQR(1-Z*Z)+Z*I)
END FUNCTION

EXTERNAL  FUNCTION CACOS(Z) !'arccosine
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=SQR((Y^2-X^2+1)^2+4*X^2*Y^2)
LET S=SQR(D+Y^2-X^2+1)/SQR(2)
LET SS=SQR(D-Y^2+X^2-1)/SQR(2)
IF X*Y>0 THEN
   LET XR=ATAN2(S+Y,X+SS)
   LET XI=-LOG((S+Y)^2+(SS+X)^2)/2
ELSE
   LET XR=ATAN2(S+Y,X-SS)
   LET XI=-LOG((S+Y)^2+(X-SS)^2)/2
END IF
LET CACOS=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CACOS2(Z)
OPTION ARITHMETIC COMPLEX
LET I=SQR(-1)
LET CACOS2=-I*CLOG(Z+I*CSQR(1-Z*Z))
END FUNCTION

EXTERNAL  FUNCTION CATAN(Z) !'arctangent
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET XR=(ATAN2(X,Y+1)+ATAN2(X,1-Y))/2
LET XI=-LOG((1-Y)^2+X^2)/4+LOG((Y+1)^2+X^2)/4
LET CATAN=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CATAN2(Z)
OPTION ARITHMETIC COMPLEX
LET I=SQR(-1)
LET CATAN2=I/2*CLOG((I+Z)/(I-Z))
END FUNCTION

EXTERNAL  FUNCTION CACOSEC(Z) !'arccosecant
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET S=X^2-Y^2
LET SS=4*X^2*Y^2
LET D=S^2+SS
LET E=S/D
LET DD=SS/D^2
LET EE=Y^2/D-X^2/D+1
IF X*Y>=0 THEN
   LET XR= ATAN2(SQR(SQR((1-E)^2+DD)+E-1)/SQR(2)+X/(X^2+Y^2),SQR(SQR((1-E)^2+DD)-E+1)/SQR(2)+Y/(X^2+Y^2))
   LET XI=-LOG((SQR(SQR(EE^2+DD)+EE)/SQR(2)+Y/(Y^2+X^2))^2+(X/(X^2+Y^2)+SQR(SQR(EE^2+DD)-EE)/SQR(2))^2)/2
ELSE
   LET XR=-ATAN2(SQR(SQR((1-E)^2+DD)+E-1)/SQR(2)-X/(X^2+Y^2),SQR(SQR((1-E)^2+DD)-E+1)/SQR(2)+Y/(X^2+Y^2))
   LET XI=-LOG((SQR(SQR(EE^2+DD)+EE)/SQR(2)+Y/(Y^2+X^2))^2+(X/(X^2+Y^2)-SQR(SQR(EE^2+DD)-EE)/SQR(2))^2)/2
END IF
LET CACOSEC=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CACOSEC2(Z)
OPTION ARITHMETIC COMPLEX
LET CACOSEC2=CASIN(1/Z)
END FUNCTION

EXTERNAL  FUNCTION CACOSEC3(Z)
OPTION ARITHMETIC COMPLEX
LET CACOSEC3=CATAN(1/CSQR(Z*Z-1))
END FUNCTION

EXTERNAL  FUNCTION CASEC(Z) !'arcsecant
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET S=X^2-Y^2
LET SS=4*X^2*Y^2
LET D=S^2+SS
LET E=S/D
LET DD=SS/D^2
LET EE=Y^2/D-X^2/D+1
IF X*Y>=0 THEN
   LET XR=ATAN2(SQR(SQR((1-E)^2+DD)-E+1)/SQR(2)-Y/(X^2+Y^2),X/(X^2+Y^2)-SQR(SQR((1-E)^2+DD)+E-1)/SQR(2))
   LET XI=-LOG((SQR(SQR(EE^2+DD)+EE)/SQR(2)-Y/(Y^2+X^2))^2+(X/(X^2+Y^2)-SQR(SQR(EE^2+DD)-EE)/SQR(2))^2)/2
ELSE
   LET XR=ATAN2(SQR(SQR((1-E)^2+DD)-E+1)/SQR(2)-Y/(X^2+Y^2),X/(X^2+Y^2)+SQR(SQR((1-E)^2+DD)+E-1)/SQR(2))
   LET XI=-LOG((SQR(SQR(EE^2+DD)+EE)/SQR(2)-Y/(Y^2+X^2))^2+(X/(X^2+Y^2)+SQR(SQR(EE^2+DD)-EE)/SQR(2))^2)/2
END IF
LET CASEC=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL FUNCTION CASEC2(Z)
OPTION ARITHMETIC COMPLEX
LET CASEC2=CATAN(CSQR(Z*Z-1))
END FUNCTION
 

Re: 複素数ライブラリー

 投稿者:しばっち  投稿日:2009年 9月27日(日)13時30分40秒
返信・引用
  > No.574[元記事へ]

続き


EXTERNAL FUNCTION CASEC3(Z)
OPTION ARITHMETIC COMPLEX
LET CASEC3=CACOS(1/Z)
END FUNCTION

EXTERNAL  FUNCTION CACOTAN(Z) !'arccotangent
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=X^2+Y^2
LET XR=(ATAN2(X/D,Y/D+1)+ATAN2(X/D,1-Y/D))/2
LET XI=-LOG((Y/D+1)^2+X^2/D^2)/4+LOG((1-Y/D)^2+X^2/D^2)/4
LET CACOTAN=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CACOTAN2(Z)
OPTION ARITHMETIC COMPLEX
LET CACOTAN2=CATAN(1/Z)
END FUNCTION

! 双曲線関数

EXTERNAL  FUNCTION CSINH(Z) !'hyperbolic sine
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET XR = SINH(X) * COS(Y)
LET XI = COSH(X) * SIN(Y)
LET CSINH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL FUNCTION CSINH2(Z)
OPTION ARITHMETIC COMPLEX
LET CSINH2=(CEXP(Z)-CEXP(-Z))/2
END FUNCTION

EXTERNAL  FUNCTION CCOSH(Z) !'hyperbolic cosine
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET  XR = COSH(X) * COS(Y)
LET  XI = SINH(X) * SIN(Y)
LET CCOSH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL FUNCTION CCOSH2(Z)
OPTION ARITHMETIC COMPLEX
LET CCOSH2=(CEXP(Z)+CEXP(-Z))/2
END FUNCTION

EXTERNAL  FUNCTION CTANH(Z) !'hyperbolic tangent
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET  D = COS(2 * Y) + COSH(2 * X)
LET  XR = SINH(2 * X) / D
LET  XI = SIN(2 * Y) / D
LET CTANH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL FUNCTION CTANH2(Z)
OPTION ARITHMETIC COMPLEX
LET CTANH2=CSINH(Z)/CCOSH(Z)
END FUNCTION

EXTERNAL  FUNCTION CTANH3(Z)
OPTION ARITHMETIC COMPLEX
LET CTANH3=-CEXP(-Z)/(CEXP(Z)+CEXP(-Z))*2+1
END FUNCTION

EXTERNAL  FUNCTION CCOSECH(Z) !'hyperbolic cosecant
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=COSH(X)^2*SIN(Y)^2+SINH(X)^2*COS(Y)^2
LET XR=SINH(X)*COS(Y)/D
LET XI=-COSH(X)*SIN(Y)/D
LET CCOSECH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CCOSECH2(Z)
OPTION ARITHMETIC COMPLEX
LET CCOSECH2=1/CSINH(Z)
END FUNCTION

EXTERNAL  FUNCTION CSECH(Z) !'hyperbolic secant
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=SINH(X)^2*SIN(Y)^2+COSH(X)^2*COS(Y)^2
LET XR=COSH(X)*COS(Y)/D
LET XI=-SINH(X)*SIN(Y)/D
LET CSECH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CSECH2(Z)
OPTION ARITHMETIC COMPLEX
LET CSECH2=1/CCOSH(Z)
END FUNCTION

EXTERNAL  FUNCTION CCOTANH(Z) !'hyperbolic cotangent
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=COS(2*Y)+COSH(2*X)
LET DD=SIN(2*Y)^2+SINH(2*X)^2
LET XR=SINH(2*X)*D/DD
LET XI=-SIN(2*Y)*D/DD
LET CCOTANH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CCOTANH2(Z)
OPTION ARITHMETIC COMPLEX
LET CCOTANH2=1/CTANH(Z)
END FUNCTION

EXTERNAL FUNCTION CCOTANH3(Z)
OPTION ARITHMETIC COMPLEX
LET CCOTANH3=CEXP(-Z)/(CEXP(Z)-CEXP(-Z))*2+1
END FUNCTION

! 逆双曲線関数

EXTERNAL  FUNCTION CASINH(Z) !'arc-hyperbolic sine
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=SQR((-Y^2+X^2+1)^2+4*X^2*Y^2)
IF X*Y>=0 THEN
   LET XR=LOG((SQR(D+Y^2-X^2-1)/SQR(2)+Y)^2+(SQR(D-Y^2+X^2+1)/SQR(2)+X)^2)/2
   LET XI=ATAN2(SQR(D+Y^2-X^2-1)/SQR(2)+Y,SQR(D-Y^2+X^2+1)/SQR(2)+X)
ELSE
   LET XR=LOG((Y-SQR(D+Y^2-X^2-1)/SQR(2))^2+(SQR(D-Y^2+X^2+1)/SQR(2)+X)^2)/2
   LET XI=-ATAN2(SQR(D+Y^2-X^2-1)/SQR(2)-Y,SQR(D-Y^2+X^2+1)/SQR(2)+X)
END IF
LET CASINH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL FUNCTION CASINH2(Z)
OPTION ARITHMETIC COMPLEX
LET CASINH2=CLOG(Z+CSQR(Z*Z+1))
END FUNCTION

EXTERNAL  FUNCTION CACOSH(Z) !'arc-hyperbolic cosine
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=SQR(Y^2+(X+1)^2)
LET DD=SQR(Y^2+(X-1)^2)
IF Y>=0 THEN
   LET XR=LOG((SQR(D+X+1)/2+SQR(DD+X-1)/2)^2+(SQR(D-X-1)/2+SQR(DD-X+1)/2)^2)
   LET XI=2*ATAN2(SQR(D-X-1)/2+SQR(DD-X+1)/2,SQR(D+X+1)/2+SQR(DD+X-1)/2)
ELSE
   LET XR=LOG((SQR(D+X+1)/2+SQR(DD+X-1)/2)^2+(-SQR(D-X-1)/2-SQR(DD-X+1)/2)^2)
   LET XI=-2*ATAN2(SQR(D-X-1)/2+SQR(DD-X+1)/2,SQR(D+X+1)/2+SQR(DD+X-1)/2)
END IF
LET CACOSH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL FUNCTION CACOSH2(Z)
OPTION ARITHMETIC COMPLEX
LET CACOSH2=CLOG(Z+CSQR(Z*Z-1))
END FUNCTION

EXTERNAL  FUNCTION CATANH(Z) !'arc-hyperbolic tangent
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET XR=LOG(Y^2+(X+1)^2)/4-LOG(Y^2+(1-X)^2)/4
LET XI=(ATAN2(Y,X+1)+ATAN2(Y,1-X))/2
LET CATANH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL FUNCTION CATANH2(Z)
OPTION ARITHMETIC COMPLEX
LET CATANH2=CLOG((1+Z)/(1-Z))/2
END FUNCTION

EXTERNAL  FUNCTION CACOSECH(Z) !'arc-hyperbolic cosecant
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET S=(X^2-Y^2)^2+4*X^2*Y^2
LET D=Y^2/S
LET DD=X^2/S
LET SS=4*X^2*Y^2/S^2
LET E=(X^2-Y^2)/S
IF X*Y>0 THEN
   LET XR=LOG((-SQR(SQR((-D+DD+1)^2+SS)+D-DD-1)/SQR(2)-Y/(X^2+Y^2))^2+(SQR(SQR((-D+DD+1)^2+SS)-D+DD+1)/SQR(2)+X/(X^2+Y^2))^2)/2
   LET XI=-ATAN2(SQR(SQR((E+1)^2+SS)-E-1)/SQR(2)+Y/(X^2+Y^2),SQR(SQR((E+1)^2+SS)+E+1)/SQR(2)+X/(X^2+Y^2))
ELSE
   LET XR=LOG((SQR(SQR((-D+DD+1)^2+SS)+D-DD-1)/SQR(2)-Y/(X^2+Y^2))^2+(SQR(SQR((-D+DD+1)^2+SS)-D+DD+1)/SQR(2)+X/(X^2+Y^2))^2)/2
   LET XI=ATAN2(SQR(SQR((E+1)^2+SS)-E-1)/SQR(2)-Y/(X^2+Y^2),SQR(SQR((E+1)^2+SS)+E+1)/SQR(2)+X/(X^2+Y^2))
END IF
LET CACOSECH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CACOSECH2(Z)
OPTION ARITHMETIC COMPLEX
LET CACOSECH2=CASINH(1/Z)
END FUNCTION

EXTERNAL FUNCTION CACOSECH3(Z)
OPTION ARITHMETIC COMPLEX
LET CACOSECH3=CLOG((CSQR(Z*Z+1)+1)/Z)
END FUNCTION

EXTERNAL  FUNCTION CASECH(Z) !'arc-hyperbolic secant
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=X/(X^2+Y^2)
LET DD=Y^2/(X^2+Y^2)^2
IF Y>0 THEN
   LET XR=LOG((SQR(SQR((D+1)^2+DD)+D+1)/2+SQR(SQR((D-1)^2+DD)+D-1)/2)^2+(-SQR(SQR((D+1)^2+DD)-D-1)/2-SQR(SQR((D-1)^2+DD)-D+1)/2)^2)
   LET XI=-2*ATAN2(SQR(SQR((D+1)^2+DD)-D-1)/2+SQR(SQR((D-1)^2+DD)-D+1)/2,SQR(SQR((D+1)^2+DD)+D+1)/2+SQR(SQR((D-1)^2+DD)+D-1)/2)
ELSE
   LET XR=LOG((SQR(SQR((D+1)^2+DD)+D+1)/2+SQR(SQR((D-1)^2+DD)+D-1)/2)^2+(SQR(SQR((D+1)^2+DD)-D-1)/2+SQR(SQR((D-1)^2+DD)-D+1)/2)^2)
   LET XI=2*ATAN2(SQR(SQR((D+1)^2+DD)-D-1)/2+SQR(SQR((D-1)^2+DD)-D+1)/2,SQR(SQR((D+1)^2+DD)+D+1)/2+SQR(SQR((D-1)^2+DD)+D-1)/2)
END IF
LET CASECH=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CASECH2(Z)
OPTION ARITHMETIC COMPLEX
LET CASECH2=CACOSH(1/Z)
END FUNCTION

EXTERNAL FUNCTION CASECH3(Z)
OPTION ARITHMETIC COMPLEX
LET CASECH3=CLOG((CSQR(1-Z*Z)+1)/Z)
END FUNCTION

EXTERNAL  FUNCTION CACOTANH(Z) !'arc-hyperbolic cotangent
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET D=X/(X^2+Y^2)
LET S=Y/(X^2+Y^2)
LET DD=S^2
LET XR=LOG((D+1)^2+DD)/4-LOG((1-D)^2+DD)/4
LET XI=(-ATAN2(S,D+1)-ATAN2(S,1-D))/2
LET CACOTANH=COMPLEX(XR,XI)
END FUNCTION
 

Re: 複素数ライブラリー

 投稿者:しばっち  投稿日:2009年 9月27日(日)13時32分37秒
返信・引用
  > No.575[元記事へ]

続き



EXTERNAL  FUNCTION CACOTANH2(Z)
OPTION ARITHMETIC COMPLEX
LET CACOTANH2=CATANH(1/Z)
END FUNCTION

EXTERNAL FUNCTION CACOTANH3(Z)
OPTION ARITHMETIC COMPLEX
LET CACOTANH3=CLOG((Z+1)/(Z-1))/2
END FUNCTION

! その他

EXTERNAL  FUNCTION CABS(Z) !'絶対値
OPTION ARITHMETIC COMPLEX
LET CABS=SQR(RE(Z)^2+IM(Z)^2)
END FUNCTION

EXTERNAL  FUNCTION CSQR(Z) !'平方根
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET R=SQR(X*X+Y*Y)
LET XR=SQR(R+X)/SQR(2)
IF Y>=0 THEN
   LET  XI=SQR(R-X)/SQR(2)
ELSE
   LET  XI=-SQR(R-X)/SQR(2)
END IF
LET CSQR=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CLOG(Z) !'対数
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET XR = LOG(X * X + Y * Y) / 2
LET XI = ATAN2(Y, X)
LET CLOG=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CEXP(Z) !'指数
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET XR = EXP(X) * COS(Y)
LET XI = EXP(X) * SIN(Y)
LET CEXP=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CARG(Z) !'偏角
OPTION ARITHMETIC COMPLEX
LET  CARG = ATAN2(IM(Z), RE(Z))
END FUNCTION

EXTERNAL  FUNCTION CPOW(X,Y) !'(A+Bi)^(C+Di)
OPTION ARITHMETIC COMPLEX
LET A=RE(X)
LET B=IM(X)
LET C=RE(Y)
LET D=IM(Y)
LET XR=(B^2+A^2)^(C/2)*EXP(-ATAN2(B,A)*D)*COS(LOG(B^2+A^2)*D/2+ATAN2(B,A)*C)
LET XI=(B^2+A^2)^(C/2)*EXP(-ATAN2(B,A)*D)*SIN(LOG(B^2+A^2)*D/2+ATAN2(B,A)*C)
LET CPOW=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  SUB CNPOW(Z, N, V()) !'(A+Bi)^(1/N)
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET  R = (X * X + Y * Y)^(1 / (2 * N))
LET TH = ATAN2(Y,X)
LET  A = R * COS(TH / N)
LET  B = R * SIN(TH / N)
FOR I = 1 TO N
   LET  C = COS(2 * PI / N * I)
   LET  S = SIN(2 * PI / N * I)
   LET  AA = A * C - B * S
   LET  BB = B * C + A * S
   LET  V(I) = COMPLEX(AA,BB)
NEXT I
END SUB

EXTERNAL  FUNCTION CRUIJYO(Z, N) !'(A+Bi)^N
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
LET  N = INT(N)
LET  R = (X * X + Y * Y)^(N / 2)
LET TH=ATAN2(Y,X)
LET  XR = R * COS(TH * N)
LET  XI = R * SIN(TH * N)
LET CRUIJYO=COMPLEX(XR,XI)
END FUNCTION

EXTERNAL  FUNCTION CCONJ(Z) !'共役数
OPTION ARITHMETIC COMPLEX
LET CCONJ=COMPLEX(RE(Z),-IM(Z))
END FUNCTION

EXTERNAL  FUNCTION REAL(Z) !'実部
OPTION ARITHMETIC COMPLEX
LET REAL=CABS(Z)*COS(CARG(Z))
END FUNCTION

EXTERNAL  FUNCTION IMAG(Z) !'虚部
OPTION ARITHMETIC COMPLEX
LET IMAG=CABS(Z)*SIN(CARG(Z))
END FUNCTION

EXTERNAL  SUB CPRINT(Z)
OPTION ARITHMETIC COMPLEX
LET X=RE(Z)
LET Y=IM(Z)
IF X=0 AND Y=0 THEN
   PRINT "0"
   EXIT SUB
END IF
IF Y=0 THEN
   IF X < 0 THEN PRINT "- ";
   PRINT STR$(ABS(X))
   EXIT SUB
END IF
IF X=0 THEN
   IF Y < 0 THEN PRINT "- ";
   IF ABS(Y)= 1 THEN
      PRINT "i"
      EXIT SUB
   END IF
   PRINT STR$(ABS(Y)); " i"
   EXIT SUB
END IF
IF X < 0 THEN PRINT "- ";
PRINT STR$(ABS(X)); " ";
IF Y < 0 THEN PRINT "- ";  ELSE PRINT "+ ";
IF ABS(Y)= 1 THEN
   PRINT "i"
   EXIT SUB
END IF
PRINT STR$(ABS(Y)); " i"
END SUB

EXTERNAL  FUNCTION ATAN2(Y,X) !'-π〜π
OPTION ARITHMETIC COMPLEX
IF ABS(IM(X))<1E-4 AND ABS(IM(Y))<1E-4 THEN
   LET X=RE(X)
   LET Y=RE(Y)
ELSE
   PRINT "ERROR!!"
   STOP
END IF
LET ATAN2=ANGLE(X,Y)
!' LET L=ACOS(X/SQR(X*X+Y*Y))
!' IF Y<0 THEN LET ATAN2=-L ELSE LET ATAN2=L
END FUNCTION

!EXTERNAL  FUNCTION ATAN2(Y,X) '0〜2π
!OPTION ARITHMETIC COMPLEX
!IF ABS(IM(X))<1E-4 AND ABS(IM(Y))<1E-4 THEN
!   LET X=RE(X)
!   LET Y=RE(Y)
!ELSE
!   PRINT "ERROR!!"
!   STOP
!END IF
!IF X<>0 THEN
!   LET TH=ATN(Y/X)
!   IF Y<>0 THEN
!      IF X>0 AND Y<0 THEN LET TH=TH+PI*2
!      IF X<0 THEN LET TH=TH+PI
!   ELSE
!      IF X<0 THEN LET TH=PI ELSE LET TH=0
!   END IF
!ELSE
!   LET TH=PI/2
!   IF Y<0 THEN LET TH=TH+PI
!END IF
!LET ATAN2=TH
!END FUNCTION
 

16元数

 投稿者:しばっち  投稿日:2009年 9月27日(日)13時39分21秒
返信・引用
  16元数の四則演算と関数をいくつか定義してみました。


PUBLIC NUMERIC MAXLEVEL
OPTION BASE 0
LET MAXLEVEL=50
DIM A(15),B(15),C(15)
MAT READ A
!'DATA 1,-1 ,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 !'2元数(複素数)
!'DATA 1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 !'4元数(クォータニオン)
DATA 1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0 !'8元数(オクトニオン)
!'DATA 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 !'16元数
MAT READ B
!'DATA 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
!'DATA 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
DATA 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
!'DATA 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
PRINT "A = ";
CALL CPRINT(A)
PRINT "B = ";
CALL CPRINT(B)
CALL CADD(A,B,C)
PRINT "A + B = ";
CALL CPRINT(C)
CALL CSUB(A,B,C)
PRINT "A - B = ";
CALL CPRINT(C)
CALL CMUL(A,B,C)
PRINT "A * B = ";
CALL CPRINT(C)
CALL CMUL(B,A,C)
PRINT "B * A = ";
CALL CPRINT(C) !' A×B≠B×A
CALL CDIV(A,B,C)
PRINT "A / B = ";
CALL CPRINT(C)
CALL CPOWER(A,B,C)
PRINT "A ^ B=";
CALL CPRINT(C)
CALL CSIN(A,B)
PRINT "SIN(A)=";
CALL CPRINT(B)
CALL CCOS(A,B)
PRINT "COS(A)=";
CALL CPRINT(B)
CALL CTAN(A,B)
PRINT "TAN(A)=";
CALL CPRINT(B)
END

EXTERNAL  SUB HORNER(X(),Y(),K())
MAT Y=ZER
LET Y(0)=K(MAXLEVEL)
FOR I=MAXLEVEL-1 TO 0 STEP -1
   CALL CMUL2(Y,X)
   LET Y(0)=Y(0)+K(I)
NEXT I
END SUB

EXTERNAL  SUB SMUL(A(),N)
MAT A=(N)*A
END SUB

EXTERNAL  SUB COPY(A(),B())
MAT A=B
END SUB

EXTERNAL  SUB CMUL(A(),B(),C())
OPTION BASE 0
DIM T$(15,15)
MAT C=ZER
MAT READ T$
FOR I=0 TO 15
   FOR J=0 TO 15
      IF A(I)<>0 AND B(J)<>0 THEN
         IF T$(I,J)="-0" THEN
            LET C(0)=C(0)-A(I)*B(J)
         ELSE
            LET D=VAL(T$(I,J))
            IF D>=0 THEN
               LET C(D)=C(D)+A(I)*B(J)
            ELSE
               LET C(-D)=C(-D)-A(I)*B(J)
            END IF
         END IF
      END IF
   NEXT J
NEXT I
DATA  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 !'16元数乗積表 (ウィキペディアより)
DATA  1, -0,  3, -2,  5, -4, -7,  6,  9, -8,-11, 10,-13, 12, 15,-14
DATA  2, -3, -0,  1,  6,  7, -4, -5, 10, 11, -8, -9,-14,-15, 12, 13
DATA  3,  2, -1, -0,  7, -6,  5, -4, 11,-10,  9, -8,-15, 14,-13, 12
DATA  4, -5, -6, -7, -0,  1,  2,  3, 12, 13, 14, 15, -8, -9,-10,-11
DATA  5,  4, -7,  6, -1, -0, -3,  2, 13,-12, 15,-14,  9, -8, 11,-10
DATA  6,  7,  4, -5, -2,  3, -0, -1, 14,-15,-12, 13, 10,-11, -8,  9
DATA  7, -6,  5,  4, -3, -2,  1, -0, 15, 14,-13,-12, 11, 10, -9, -8
DATA  8, -9,-10,-11,-12,-13,-14,-15, -0,  1,  2,  3,  4,  5,  6,  7
DATA  9,  8,-11, 10,-13, 12, 15,-14, -1, -0, -3,  2, -5,  4,  7, -6
DATA 10, 11,  8, -9,-14,-15, 12, 13, -2,  3, -0, -1, -6, -7,  4,  5
DATA 11,-10,  9,  8,-15, 14,-13, 12, -3, -2,  1, -0, -7,  6, -5,  4
DATA 12, 13, 14, 15,  8, -9,-10,-11, -4,  5,  6,  7, -0, -1, -2, -3
DATA 13,-12, 15,-14,  9,  8, 11,-10, -5, -4,  7, -6,  1, -0,  3, -2
DATA 14,-15,-12, 13, 10,-11,  8,  9, -6, -7, -4,  5,  2, -3, -0,  1
DATA 15, 14,-13,-12, 11, 10, -9,  8, -7,  6, -5, -4,  3,  2, -1, -0
END SUB

EXTERNAL  SUB CMUL2(A(),B())
OPTION BASE 0
DIM C(15)
CALL CMUL(A,B,C)
CALL COPY(A,C)
END SUB

EXTERNAL  SUB CADD(A(),B(),C())
MAT C=A+B
END SUB

EXTERNAL  SUB CSUB(A(),B(),C())
MAT C=A-B
END SUB

EXTERNAL  SUB CDIV(A(),B(),C())
OPTION BASE 0
DIM BB(15),S(15)
CALL CCONJ(B,BB)
CALL CMUL(B,BB,S)
CALL CMUL(A,BB,C)
CALL SMUL(C,1/S(0))
END SUB

EXTERNAL  SUB CCONJ(A(),B())
LET B(0)=A(0)
FOR I=1 TO 15
   LET B(I)=-A(I)
NEXT I
END SUB

EXTERNAL  SUB CPRINT(A())
FOR I=0 TO 15
   IF A(I)<>0 THEN
      IF A(I)<0 THEN
         PRINT " - ";
      ELSE
         IF I>0 AND A(0)<>0 THEN PRINT " + ";
      END IF
      IF ABS(A(I))<>1 OR I=0 THEN PRINT STR$(ABS(A(I)));
      IF I>0 THEN PRINT MID$("ijklmnopqrstuvw",I,1);
   END IF
NEXT I
PRINT
END SUB

EXTERNAL  SUB CSIN(X(),Y())
OPTION BASE 0
DIM V(MAXLEVEL)
CALL SINE(V)
CALL HORNER(X,Y,V)
END SUB

EXTERNAL  SUB CCOS(X(),Y())
OPTION BASE 0
DIM V(MAXLEVEL)
CALL COSINE(V)
CALL HORNER(X,Y,V)
END SUB

EXTERNAL  SUB CTAN(X(),Y())
OPTION BASE 0
DIM XX(15),YY(15)
CALL CSIN(X,XX)
CALL CCOS(X,YY)
CALL CDIV(XX,YY,Y)
END SUB

EXTERNAL  SUB CEXP(X(),Y())
OPTION BASE 0
DIM V(MAXLEVEL)
CALL EXPON(V)
CALL HORNER(X,Y,V)
END SUB

EXTERNAL  SUB CLOG(X(),Y())
OPTION BASE 0
DIM V(MAXLEVEL),A(15),B(15),C(15)
CALL LN(V)
CALL COPY(A,X)
CALL COPY(B,X)
LET A(0)=A(0)-1
LET B(0)=B(0)+1
CALL CDIV(A,B,C)
CALL HORNER(C,Y,V)
CALL SMUL(Y,2)
END SUB

EXTERNAL  SUB CPOWER(X(),Y(),A())
OPTION BASE 0
DIM XX(15),YY(15)
CALL COPY(YY,Y)
CALL CLOG(X,XX)
CALL CMUL2(YY,XX)
CALL CEXP(YY,A)
END SUB

EXTERNAL  SUB SINE(X())
!'SIN(X)
LET  X(1)=1
LET  T=1
FOR I=3 TO MAXLEVEL STEP 2
   LET T=-T/(I-1)/I
   LET  X(I)=T
NEXT I
END SUB

EXTERNAL  SUB COSINE(X())
!'COS(X)
LET  X(0)=1
LET  T=1
FOR I=2 TO MAXLEVEL STEP 2
   LET T=-T/(I-1)/I
   LET  X(I)=T
NEXT I
END SUB

EXTERNAL  SUB EXPON(X())
!'EXP(X)
LET  X(0)=1
LET  T=1
FOR I=1 TO MAXLEVEL
   LET  T=T/I
   LET  X(I)=T
NEXT I
END SUB

EXTERNAL  SUB LN(X())
!'LOG((X-1)/(X+1))
FOR I=1 TO MAXLEVEL
   IF MOD(I,2)=1 THEN LET  X(I)=1/I
NEXT I
END SUB
 

約数

 投稿者:しばっち  投稿日:2009年 9月27日(日)13時45分33秒
返信・引用
  約数を求める


OPTION ARITHMETIC COMPLEX
LET  N=10 !'探索範囲
DIM P(-N TO N,-N TO N)
FOR X=0 TO N
   FOR Y=0 TO N
      LET Z=COMPLEX(X,Y)
      PRINT Z;":";
      LET FL=0
      MAT P=ZER
      LET P(0,0)=1  !'0,±1,±iは約数(?)ではない
      LET P(1,0)=1
      LET P(0,1)=1
      LET P(-1,0)=1
      LET P(0,-1)=1
      IF P(RE(Z),IM(Z))=0 THEN
      !'IF ISGAUSSIANPRIME(Z)<>0 THEN
      !'   PRINT "素数";
      !'ELSE
         FOR A=0 TO N
            FOR B=0 TO N
               FOR I=1 TO -1 STEP -2
                  FOR J=1 TO -1 STEP -2
                     LET V=COMPLEX(A*I,B*J)
                     IF V<>0 THEN
                        LET S=Z/V
                        IF CMOD(Z,V)=0 AND P(RE(S),IM(S))=0 AND P(RE(V),IM(V))=0 THEN
                           PRINT "{";V;",";S;"}";
                           LET P(RE(S),IM(S))=1
                           LET P(RE(V),IM(V))=1
                           LET FL=1
                        END IF
                     END IF
                  NEXT J
               NEXT  I
            NEXT B
         NEXT A
         IF FL=0 THEN PRINT "素数";
         !' END IF
      END IF
      PRINT
   NEXT Y
NEXT X
END

EXTERNAL  FUNCTION CINT(Z)
OPTION ARITHMETIC COMPLEX
LET CINT=COMPLEX(INT(RE(Z)),INT(IM(Z)))
END FUNCTION

EXTERNAL  FUNCTION CMOD(X,Y)
OPTION ARITHMETIC COMPLEX
LET CMOD=X-CINT(X/Y)*Y
END FUNCTION

EXTERNAL  FUNCTION ISGAUSSIANPRIME(Z) !'ガウス素数
OPTION ARITHMETIC COMPLEX
LET  ISGAUSSIANPRIME=0
LET  A = ABS(RE(Z))
LET  B = ABS(IM(Z))
IF A = 0 THEN
   IF MOD(B, 4) = 3 AND ISPRIME(B)<>0 THEN LET  ISGAUSSIANPRIME=-1
END IF
IF B = 0 THEN
   IF MOD(A , 4) = 3 AND ISPRIME(A)<>0 THEN LET  ISGAUSSIANPRIME=-1
END IF
IF ISPRIME(A*A+B*B)<>0 THEN LET  ISGAUSSIANPRIME=-1
END FUNCTION

EXTERNAL  FUNCTION ISPRIME(X)
OPTION ARITHMETIC COMPLEX
IF X=0 OR X=1 THEN
   LET  ISPRIME=0
   EXIT FUNCTION
END IF
IF X=2 THEN
   LET  ISPRIME=-1
   EXIT FUNCTION
END IF
IF MOD(X,2)=0 THEN
   LET  ISPRIME=0
   EXIT FUNCTION
END IF
FOR I=3 TO INT(SQR(X)) STEP 2
   IF MOD(X,I)=0 THEN
      LET  ISPRIME=0
      EXIT FUNCTION
   END IF
NEXT I
LET  ISPRIME=-1
END FUNCTION
 

100までの素数

 投稿者:しばっち  投稿日:2009年 9月27日(日)13時52分56秒
返信・引用
  自然数100までの素数(?)を求める


PUBLIC NUMERIC N
LET N=10 !'探索範囲 (+n+ni+nj+nj+nk..)〜(-n-ni-nj-nj-nk..)  (i,j,k...は虚数単位)
DO
   READ L
   IF L=0 THEN STOP
   DATA 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97
   DATA 0
   PRINT L;":";
   IF CHECK(L)=1 THEN PRINT "素数"
LOOP
END

EXTERNAL  FUNCTION CHECK(L) !'オクトニオン(8元数)探索  (8重ループ)
OPTION BASE 0
DIM X(15),Y(15),Z(15)
LET X(0)=L
FOR H=0 TO N
   FOR S8=1 TO -1 STEP -2
      LET Y(7)=H*S8
      FOR G=0 TO N
         FOR S7=1 TO -1 STEP -2
            LET Y(6)=G*S7
            FOR F=0 TO N
               FOR S6=1 TO -1 STEP -2
                  LET Y(5)=F*S6
                  FOR E=0 TO N
                     FOR S5=1 TO -1 STEP -2
                        LET Y(4)=E*S5
                        FOR D=0 TO N
                           FOR S4=1 TO -1 STEP -2
                              LET Y(3)=D*S4
                              FOR C=0 TO N
                                 FOR S3=1 TO -1 STEP -2
                                    LET Y(2)=C*S3
                                    FOR B=0 TO N
                                       FOR S2=1 TO -1 STEP -2
                                          LET Y(1)=B*S2
                                          FOR A=0 TO N
                                             FOR S1=1 TO -1 STEP -2
                                                LET Y(0)=A*S1
                                                IF COMP(Y)=0 THEN
                                                   CALL CDIV(X,Y,Z)
                                                   IF COMP(Z)=0 THEN
                                                      LET FR=0
                                                      FOR I=0 TO 15
                                                         IF FRAC(Z(I))<>0 THEN
                                                            LET FR=1
                                                            EXIT FOR
                                                         END IF
                                                      NEXT I
                                                      IF FR=0 THEN
                                                         PRINT "{";
                                                         CALL CPRINT(Y)
                                                         PRINT ",";
                                                         CALL CPRINT(Z)
                                                         PRINT "}"
                                                         LET CHECK=0
                                                         EXIT FUNCTION !'見つけ次第ループ打ち切り
                                                      END IF
                                                   END IF
                                                END IF
                                             NEXT  S1
                                          NEXT  A
                                       NEXT  S2
                                    NEXT  B
                                 NEXT  S3
                              NEXT C
                           NEXT  S4
                        NEXT  D
                     NEXT  S5
                  NEXT  E
               NEXT  S6
            NEXT  F
         NEXT  S7
      NEXT  G
   NEXT   S8
NEXT  H
LET CHECK=1
END FUNCTION

EXTERNAL  FUNCTION COMP(Y())
OPTION BASE 0
DIM Z(15)
FOR I=1 TO 16
   LET FL=0
   MAT READ Z
   DATA  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 !'0
   DATA  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 !'1
   DATA -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
   DATA 0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 !'i
   DATA 0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
   DATA 0,0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0 !'j
   DATA 0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0
   DATA 0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0,0 !'k
   DATA 0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0
   DATA 0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0 !'l
   DATA 0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0
   DATA 0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0 !'m
   DATA 0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0
   DATA 0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0 !'n
   DATA 0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0
   DATA 0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0 !'o
   DATA 0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0
   !'DATA 0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0
   !'DATA 0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0
   !'DATA 0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0
   !'DATA 0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0
   !'DATA 0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0
   !'DATA 0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0
   !'DATA 0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0
   !'DATA 0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0
   !'DATA 0,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0
   !'DATA 0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0
   !'DATA 0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0,0
   !'DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0
   !'DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0
   !'DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0
   !'DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1
   !'DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1
   FOR J=0 TO 15
      IF Y(J)=Z(J) THEN LET FL=FL+1 !'0,±1,±i,±j,±k...は約数(?)ではない
   NEXT J
   IF FL=16 THEN
      LET COMP=1
      EXIT FUNCTION
   END IF
NEXT I
LET COMP=0
END FUNCTION

EXTERNAL  FUNCTION FRAC(X) !'小数部
LET FRAC=X-INT(X)
END FUNCTION

EXTERNAL  SUB CDIV(A(),B(),C())
OPTION BASE 0
DIM BB(15),S(15)
CALL CCONJ(B,BB)
CALL CMUL(B,BB,S)
CALL CMUL(A,BB,C)
MAT C=(1/S(0))*C
END SUB

EXTERNAL  SUB CCONJ(A(),B()) !'共役数
LET B(0)=A(0)
FOR I=1 TO 15
   LET B(I)=-A(I)
NEXT I
END SUB

EXTERNAL  SUB CPRINT(A())
FOR I=0 TO 15
   IF A(I)<>0 THEN
      IF A(I)<0 THEN
         PRINT " - ";
      ELSE
         IF I>0 THEN PRINT " + ";
      END IF
      IF ABS(A(I))<>1 OR I=0 THEN PRINT STR$(ABS(A(I)));
      IF I>0 THEN PRINT MID$("ijklmnopqrstuvw",I,1);
   END IF
NEXT I
END SUB

EXTERNAL  SUB CMUL(A(),B(),S())
LET S(0)=A(0)*B(0)-A(1)*B(1)-A(2)*B(2)-A(3)*B(3)-A(4)*B(4)-A(5)*B(5)-A(6)*B(6)-A(7)*B(7)-A(8)*B(8)-A(9)*B(9)-A(10)*B(10)-A(11)*B(11)-A(12)*B(12)-A(13)*B(13)-A(14)*B(14)-A(15)*B(15)
LET S(1)=A(0)*B(1)+A(1)*B(0)+A(2)*B(3)-A(3)*B(2)+A(4)*B(5)-A(5)*B(4)-A(6)*B(7)+A(7)*B(6)+A(8)*B(9)-A(9)*B(8)-A(10)*B(11)+A(11)*B(10)-A(12)*B(13)+A(13)*B(12)+A(14)*B(15)-A(15)*B(14)
LET S(2)=A(0)*B(2)-A(1)*B(3)+A(2)*B(0)+A(3)*B(1)+A(4)*B(6)+A(5)*B(7)-A(6)*B(4)-A(7)*B(5)+A(8)*B(10)+A(9)*B(11)-A(10)*B(8)-A(11)*B(9)-A(12)*B(14)-A(13)*B(15)+A(14)*B(12)+A(15)*B(13)
LET S(3)=A(0)*B(3)+A(1)*B(2)-A(2)*B(1)+A(3)*B(0)+A(4)*B(7)-A(5)*B(6)+A(6)*B(5)-A(7)*B(4)+A(8)*B(11)-A(9)*B(10)+A(10)*B(9)-A(11)*B(8)-A(12)*B(15)+A(13)*B(14)-A(14)*B(13)+A(15)*B(12)
LET S(4)=A(0)*B(4)-A(1)*B(5)-A(2)*B(6)-A(3)*B(7)+A(4)*B(0)+A(5)*B(1)+A(6)*B(2)+A(7)*B(3)+A(8)*B(12)+A(9)*B(13)+A(10)*B(14)+A(11)*B(15)-A(12)*B(8)-A(13)*B(9)-A(14)*B(10)-A(15)*B(11)
LET S(5)=A(0)*B(5)+A(1)*B(4)-A(2)*B(7)+A(3)*B(6)-A(4)*B(1)+A(5)*B(0)-A(6)*B(3)+A(7)*B(2)+A(8)*B(13)-A(9)*B(12)+A(10)*B(15)-A(11)*B(14)+A(12)*B(9)-A(13)*B(8)+A(14)*B(11)-A(15)*B(10)
LET S(6)=A(0)*B(6)+A(1)*B(7)+A(2)*B(4)-A(3)*B(5)-A(4)*B(2)+A(5)*B(3)+A(6)*B(0)-A(7)*B(1)+A(8)*B(14)-A(9)*B(15)-A(10)*B(12)+A(11)*B(13)+A(12)*B(10)-A(13)*B(11)-A(14)*B(8)+A(15)*B(9)
LET S(7)=A(0)*B(7)-A(1)*B(6)+A(2)*B(5)+A(3)*B(4)-A(4)*B(3)-A(5)*B(2)+A(6)*B(1)+A(7)*B(0)+A(8)*B(15)+A(9)*B(14)-A(10)*B(13)-A(11)*B(12)+A(12)*B(11)+A(13)*B(10)-A(14)*B(9)-A(15)*B(8)
LET S(8)=A(0)*B(8)-A(1)*B(9)-A(2)*B(10)-A(3)*B(11)-A(4)*B(12)-A(5)*B(13)-A(6)*B(14)-A(7)*B(15)+A(8)*B(0)+A(9)*B(1)+A(10)*B(2)+A(11)*B(3)+A(12)*B(4)+A(13)*B(5)+A(14)*B(6)+A(15)*B(7)
LET S(9)=A(0)*B(9)+A(1)*B(8)-A(2)*B(11)+A(3)*B(10)-A(4)*B(13)+A(5)*B(12)+A(6)*B(15)-A(7)*B(14)-A(8)*B(1)+A(9)*B(0)-A(10)*B(3)+A(11)*B(2)-A(12)*B(5)+A(13)*B(4)+A(14)*B(7)-A(15)*B(6)
LET S(10)=A(0)*B(10)+A(1)*B(11)+A(2)*B(8)-A(3)*B(9)-A(4)*B(14)-A(5)*B(15)+A(6)*B(12)+A(7)*B(13)-A(8)*B(2)+A(9)*B(3)+A(10)*B(0)-A(11)*B(1)-A(12)*B(6)-A(13)*B(7)+A(14)*B(4)+A(15)*B(5)
LET S(11)=A(0)*B(11)-A(1)*B(10)+A(2)*B(9)+A(3)*B(8)-A(4)*B(15)+A(5)*B(14)-A(6)*B(13)+A(7)*B(12)-A(8)*B(3)-A(9)*B(2)+A(10)*B(1)+A(11)*B(0)-A(12)*B(7)+A(13)*B(6)-A(14)*B(5)+A(15)*B(4)
LET S(12)=A(0)*B(12)+A(1)*B(13)+A(2)*B(14)+A(3)*B(15)+A(4)*B(8)-A(5)*B(9)-A(6)*B(10)-A(7)*B(11)-A(8)*B(4)+A(9)*B(5)+A(10)*B(6)+A(11)*B(7)+A(12)*B(0)-A(13)*B(1)-A(14)*B(2)-A(15)*B(3)
LET S(13)=A(0)*B(13)-A(1)*B(12)+A(2)*B(15)-A(3)*B(14)+A(4)*B(9)+A(5)*B(8)+A(6)*B(11)-A(7)*B(10)-A(8)*B(5)-A(9)*B(4)+A(10)*B(7)-A(11)*B(6)+A(12)*B(1)+A(13)*B(0)+A(14)*B(3)-A(15)*B(2)
LET S(14)=A(0)*B(14)-A(1)*B(15)-A(2)*B(12)+A(3)*B(13)+A(4)*B(10)-A(5)*B(11)+A(6)*B(8)+A(7)*B(9)-A(8)*B(6)-A(9)*B(7)-A(10)*B(4)+A(11)*B(5)+A(12)*B(2)-A(13)*B(3)+A(14)*B(0)+A(15)*B(1)
LET S(15)=A(0)*B(15)+A(1)*B(14)-A(2)*B(13)-A(3)*B(12)+A(4)*B(11)+A(5)*B(10)-A(6)*B(9)+A(7)*B(8)-A(8)*B(7)+A(9)*B(6)-A(10)*B(5)-A(11)*B(4)+A(12)*B(3)+A(13)*B(2)-A(14)*B(1)+A(15)*B(0)
END SUB

!EXTERNAL  SUB CMUL(A(),B(),C())
!OPTION BASE 0
!DIM T$(15,15)
!MAT C=ZER
!MAT READ T$
!FOR I=0 TO 15
!   FOR J=0 TO 15
!      IF A(I)<>0 AND B(J)<>0 THEN
!         IF T$(I,J)="-0" THEN
!            LET C(0)=C(0)-A(I)*B(J)
!         ELSE
!            LET D=VAL(T$(I,J))
!            IF D>=0 THEN
!               LET C(D)=C(D)+A(I)*B(J)
!            ELSE
!               LET C(-D)=C(-D)-A(I)*B(J)
!            END IF
!         END IF
!      END IF
!   NEXT J
!NEXT I
!DATA  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 '16元数乗積表
!DATA  1, -0,  3, -2,  5, -4, -7,  6,  9, -8,-11, 10,-13, 12, 15,-14
!DATA  2, -3, -0,  1,  6,  7, -4, -5, 10, 11, -8, -9,-14,-15, 12, 13
!DATA  3,  2, -1, -0,  7, -6,  5, -4, 11,-10,  9, -8,-15, 14,-13, 12
!DATA  4, -5, -6, -7, -0,  1,  2,  3, 12, 13, 14, 15, -8, -9,-10,-11
!DATA  5,  4, -7,  6, -1, -0, -3,  2, 13,-12, 15,-14,  9, -8, 11,-10
!DATA  6,  7,  4, -5, -2,  3, -0, -1, 14,-15,-12, 13, 10,-11, -8,  9
!DATA  7, -6,  5,  4, -3, -2,  1, -0, 15, 14,-13,-12, 11, 10, -9, -8
!DATA  8, -9,-10,-11,-12,-13,-14,-15, -0,  1,  2,  3,  4,  5,  6,  7
!DATA  9,  8,-11, 10,-13, 12, 15,-14, -1, -0, -3,  2, -5,  4,  7, -6
!DATA 10, 11,  8, -9,-14,-15, 12, 13, -2,  3, -0, -1, -6, -7,  4,  5
!DATA 11,-10,  9,  8,-15, 14,-13, 12, -3, -2,  1, -0, -7,  6, -5,  4
!DATA 12, 13, 14, 15,  8, -9,-10,-11, -4,  5,  6,  7, -0, -1, -2, -3
!DATA 13,-12, 15,-14,  9,  8, 11,-10, -5, -4,  7, -6,  1, -0,  3, -2
!DATA 14,-15,-12, 13, 10,-11,  8,  9, -6, -7, -4,  5,  2, -3, -0,  1
!DATA 15, 14,-13,-12, 11, 10, -9,  8, -7,  6, -5, -4,  3,  2, -1, -0
!END SUB
 

Re: 100までの素数

 投稿者:しばっち  投稿日:2009年 9月27日(日)13時55分0秒
返信・引用
  > No.579[元記事へ]

100までの自然数には約数が存在し、全て割り切れる。よって素数はない(?)。 チャン、チャン(笑)

(もしかすると、全ての自然数が割り切れるのかもしれない)

(注) 約数はまだ複数組存在すると思われる
2 :{1 + i,1 - i}
3 :{1 + i + j,1 - i - j}
5 :{2 + i,2 - i}
7 :{2 + i + j + k,2 - i - j - k}
11 :{3 + i + j,3 - i - j}
13 :{3 + 2i,3 - 2i}
17 :{4 + i,4 - i}
19 :{3 + 3i + j,3 - 3i - j}
23 :{3 + 3i + 2j + k,3 - 3i - 2j - k}
29 :{5 + 2i,5 - 2i}
31 :{5 + 2i + j + k,5 - 2i - j - k}
37 :{6 + i,6 - i}
41 :{5 + 4i,5 - 4i}
43 :{5 + 3i + 3j,5 - 3i - 3j}
47 :{6 + 3i + j + k,6 - 3i - j - k}
53 :{7 + 2i,7 - 2i}
59 :{7 + 3i + j,7 - 3i - j}
61 :{6 + 5i,6 - 5i}
67 :{7 + 3i + 3j,7 - 3i - 3j}
71 :{6 + 5i + 3j + k,6 - 5i - 3j - k}
73 :{8 + 3i,8 - 3i}
79 :{7 + 5i + 2j + k,7 - 5i - 2j - k}
83 :{9 + i + j,9 - i - j}
89 :{8 + 5i,8 - 5i}
97 :{9 + 4i,9 - 4i}
 

Re: 素数

 投稿者:kikiriri  投稿日:2009年 9月27日(日)15時23分21秒
返信・引用
  > No.565[元記事へ]

kikiririさんへのお返事です。

> 1とその数自身で割り切れない自然数
> 1は素数とする、このとき、
> 1,2,3,5,7,11,13,17,19,23,29,31,37は、
> 1から40までの素数ですが間違ってませんか


”> 1とその数自身で割り切れない自然数”

上は間違いで、

1とその数自身以外の数で割り切れない数でした

間違いを改め反省します
 

Re: 100までの素数

 投稿者:kikiriri  投稿日:2009年 9月27日(日)17時26分54秒
返信・引用
  > No.579[元記事へ]

しばっちさんへのお返事です。

しばっちさんへ、
kikiririより、
素数を求めるプログラムありがとうございます。
プログラムは読めないんですが。
100までの素数出ました。
意外と時間がかかりました

正誤の確認もしていないのですが(以下URLより確認しました)

”1”が出てこないですね”1”って素数ではないのですか?

(「”1”は素数ではない」中3の参考書より)

偶数について何か思うところはありますか?

http://members.jcom.home.ne.jp/sansuu/nyuushi/sosuuhyou/sosuu3000.html
 

Re: 100までの素数

 投稿者:しばっち  投稿日:2009年 9月27日(日)19時53分59秒
返信・引用
  > No.582[元記事へ]

kikiririさんへのお返事です。

実際に求めているのは(4元数での)約数です。(プログラムでは8元数で探索)
約数が存在しないとき、その数が素数だといえると思います。
100までの自然数には、全て約数(4元数)があるため、素数はないとしています。
題名を「100までの約数」とすれば良かったのかもしれません。
素数は「1とその数自身でしか割れない数」としているので1は含まないとしています。(ちなみに1=-i×iと分解できる)
同様に虚数単位の±i,±j,±k...も外しています。(i^2=-1,j^2=-1,k^2=-1...)
偶数については思いつくことはありません。
 

Re: 100までの素数

 投稿者:kikiriri  投稿日:2009年 9月27日(日)21時03分39秒
返信・引用
  > No.583[元記事へ]

しばっちさんへのお返事です。

しばっちさんへ

 kikiririより

早速のご返信ありがとうございました。

難しいことはよく分かりませんが、

i^2=-1 i=√(-1) はかろうじて思い出せました。

多次元というと、行列表記(線形代数「にがて」を思い出します.)

印刷したプログラムを見た感じでは、何ともいえませんが(解説なしのプログラムが読めない。)

多次元行列計算はプログラムではこう書くのですね?(あってますか?(的外れ?))

しかも素数を探索しながら。

こういうのアルゴリズムを考慮したプログラムというんですね?

もし宜しければ工夫した点なんて教えていただけないですか?(すみません)

僕にはプログラムは読めませんが(分かりやすく説明するには手間というかセンスが必要になったりして僕にそれがあるかどうかはなぞです。)


以上ありがとうございました
 

Re: 100までの素数(すみません)

 投稿者:kikiriri  投稿日:2009年 9月28日(月)18時48分58秒
返信・引用
  > No.584[元記事へ]

プログラムが読めない僕に、このプログラムの内容を解説して欲しいというのは、

しばっちさんにとって迷惑なことではないでしょうか。

しかもこの長文失礼しました、蛇足のようですね、(すみません)



しばっちさんへ


  kikiririより
 

Re: 100までの素数(すみません)

 投稿者:しばっち  投稿日:2009年 9月28日(月)20時19分27秒
返信・引用
  > No.585[元記事へ]

kikiririさんへのお返事です。

解説というはあまり得意ではないため、遠慮させていただきたいのですが
DATA文で自然数での「素数」を与え、それが8元数で割り切れるかを調べています。
CHECKルーチンで実際にループをつくり8元数を生成しています。
絶対値を小さい方から生成したいのでループ(S1,S2,S3..)で符号を反転させています。
COMPルーチンでは生成した8元数が 0,±1,±i,±j,±k...(i,j,k..は虚数単位)で割り算しないためのものです。
CDIVルーチンで実際に割り算を行います。結果を配列Zに返します。
計算結果が±1,±i,±j,±k..でないことをCOMPルーチンで調べます。(約数ではないため)
FRACルーチンは小数部を与え、これが0なら割り切れたとしてCPRINTルーチンで表示させループを脱出させています。
単純なループによる探索プログラムなので決して難しくはないと思います。
あとCCONJルーチンは共役数(A+Bi+Cj+DkならA-Bi-Cj-Dk)を与え、これは割り算する時に分母を実数化するため使います。
(A+Bi)/(C+Di)=(A+Bi)(C-Di)/{(C+Di)(C-Di)}=(AC-BD+BCi+ADi)/(C^2+D^2)
CMULルーチンは16元数での掛け算をします。その法則を乗積表でDATA文により与えています。
左上から右に1,i,j,k,...下方向にも1,i,j,k...(i,j,k..は虚数単位)と並んでいます。
交差した数字が±0なら実数、1以降ならi,j,k..と対応しています。i×jなら左上0から右に2番目と左上から下へ3番目で-3
つまりi×j=-kとなります。
CMULルーチンが2つありますが乗積表から数式に変換した方を実際の計算で使っています。
なお、ここでは S(8)以降は注釈でも構いません。
ループを増やし16元数で探索させることもできますし、(COMPルーチン内DATA分の注釈を外し、ループ回数を16から32に変更する)
ループを減らし4元数で探索させて高速化することもできます。(CHECKルーチン内ループE以降を注釈にする)
kikiririさんが思うように改造してみてください。(メインルーチンDATA文の数値を書き換えてみる,探索範囲Nの数値を変えてみる等)
そして、ぜひプログラムが読めて書けるようになってください。楽しみも倍増します。
特に他人が知らないような計算結果を得ることは「快感」です。(円周率などは既に多く計算されている)
ベタな文章ですみません。(by しばっち チャンチャン)
 

Re: 100までの素数(すみません)

 投稿者:kikiriri  投稿日:2009年 9月29日(火)07時40分42秒
返信・引用
  > No.586[元記事へ]

しばっちさんへのお返事です。

しばっちさんへ

  kikiririより

僕には分かりませんが、早速のご返信ありがとうございます。

印刷して何度か読み直そうかとは思いますが、

8元数って何ですか

すみません


kikiririより
 

Re: 100までの素数(すみません)

 投稿者:kikiriri  投稿日:2009年 9月29日(火)08時24分1秒
返信・引用
  > No.586[元記事へ]

しばっちさんへのお返事です。

しばっちさんへ

  kikiririより

>そして、ぜひプログラムが読めて書けるようになってください。楽しみも倍増します。

良いご助言等ありましたらお願いします。
 

素数の取り出し

 投稿者:GAI  投稿日:2009年 9月29日(火)12時36分51秒
返信・引用
      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

の表で次の11本の直線を引く
8−116
9−117
4−118
6−120   以上縦線4本

10−25
30−55
60−85
90−115 以上右上がり斜め線4本

14−42
49−84
91−119 以上左上がり斜め線3本

消されずに残った数字が素数です。(1は除外すること。)
 

Re: 100までの素数(すみません)

 投稿者:しばっち  投稿日:2009年 9月29日(火)19時33分31秒
返信・引用
  > No.588[元記事へ]

kikiririさんへのお返事です。

4元数、8元数、16元数とは、複素数の概念を拡張したものです。
詳しいことはネット上で調べられると思います。
私もウィキペディアで知りました。
他人が作ったプログラムは良い勉強になります。
私もこの掲示板上のプログラムやネット上のソースプログラムなど
大変参考にしています。
ネット上にはいろいろなプログラムコードが公開されていますから
それらを参考にし、自分なりに書き換えたり、作ってみることだと思います。
ネット上には情報が溢れていますから、その中から自分が参考にしたい情報を
うまく見つけていくことが大事だと思います。
 

御返信ありがとうございます

 投稿者:kikiriri  投稿日:2009年 9月30日(水)08時58分24秒
返信・引用
  > No.590[元記事へ]

しばっちさんへのお返事です。

しばっちさんへ

  kikiririより


> 他人が作ったプログラムは良い勉強になります。
> 私もこの掲示板上のプログラムやネット上のソースプログラムなど
> 大変参考にしています。
> ネット上にはいろいろなプログラムコードが公開されていますから
> それらを参考にし、自分なりに書き換えたり、作ってみることだと思います。
> ネット上には情報が溢れていますから、その中から自分が参考にしたい情報を
> うまく見つけていくことが大事だと思います。

ご助言ありがとう、ご・ざ・い・ま・す。(すみません)参考にしたいです。
 

Re: 素数の取り出し

 投稿者:kikiriri  投稿日:2009年 9月30日(水)13時12分28秒
返信・引用
  > No.589[元記事へ]

GAIさんへのお返事です。

GAIさんへ

  kikiririより

印刷して線を引いて、1を消して、残った数を○で囲み

下記 URLよりチェックして見ると、ちゃんと合ってました。


不思議だな〜の一言ですね。

http://members.jcom.home.ne.jp/sansuu/nyuushi/sosuuhyou/sosuu3000.html
 

すみません編集させていただきました(以下の用語について情報待つ)

 投稿者:kikiriri  投稿日:2009年 9月30日(水)16時34分8秒
返信・引用  編集済
  すでにご返答はありましたが分からないので
もし快くご返答できる方がいらっしゃれば
宜しくお願いします。


既知点
観測値
観測値、コアファクタ
未知数
自由度R ※条件方程式の数
条件方程式 UV=t
相関式 NK=t、N=UG(Ut)より、K=(Ni)tを求める
補正値の計算(mm) V=G(Ut)K
最確値 X~=X+V
精度の計算(mm^2) σ^2=(Kt)NK/r
分散行列(mm^2) σ^2*Gx、Gx=G-G(Ut)(Ni)UG

以上の用語について、
説明お願いできないでしょうか。
 

Re: 測量最小二乗法について

 投稿者:kikiriri  投稿日:2009年 9月30日(水)17時05分56秒
返信・引用  編集済
  > No.255[元記事へ]

山中和義さんへのお返事です。

山中和義さんへ

  kikiririより

以下のプログラムの解説お願いできないでしょうか、BASIC初心者で、数学に関しても高校

レベルだとして

実行させました結果の読み方が分かりません。

路線1〜5
点P
点Q

値の名前が出ていますが

路線1〜5は値が変わっていますね、四捨五入するとすれば(DATA値)

路線1=−6.224(−6.225)(+0.001) 高低差(m)以下同じ
路線2=−5.245(−5.245)(±0.000)
路線3= 0.277( 0.278)(−0.001)
路線4=−0.398(−0.399)(+0.001)
路線5= 5.880( 5.879)(+0.001)

求点PとQ(たぶん標高だと思うのですが)

点P 19.421 19.421 両方標高(m)以下同じ
点Q 25.301 25.301

2つ値が出ている意味が分かりません(四捨五入すれば同じ)

と、思うのですが、なにとぞご指導のほど宜しくお願いします。



> kikiririさんへのお返事です。
>
> 参考サイト http://hw001.gate01.com/kazuok/geodetic/leveling.html
>
> Full BASICの場合、行列が計算できるので、他の言語よりは簡単に計算できると思います。
> ただ、2項演算までですから、展開しながらこつこつ計算する必要があります。
>
> また、表計算の方がGUIを含めて実用化し易いかもしれません。
>
>
> 上記サイトの例題(PDFファイル内)のサンプルコーディング
>
> <PRE>
> !最小2乗法による測量網平均(条件方程式法)
>
> !H型
> !  A  C
> ! 1↓ 5 ↓3
> !  P → Q
> ! 2↑  ↑4
> !  B  D
>
> !既知点
> LET C=4 !数
>
> DATA 25.645 !A点の標高(m)
> DATA 24.666 !B点
> DATA 25.024 !C点
> DATA 25.699 !D点
> DIM Z(C)
> MAT READ Z
>
> !観測値
> LET P=5 !数
>
> DATA -6.225, 0.44 !路線1 高低差(m)、路線長(km)
> DATA -5.245, 0.25 !路線2
> DATA  0.278, 0.33 !路線3
> DATA -0.399, 0.26 !路線4
> DATA  5.879, 0.44 !路線5
>
> DIM X(P),G(P,P) !観測値、コアファクタ
> MAT G=ZER
> FOR i=1 TO P
>    READ X(i),G(i,i)
> NEXT i
> MAT PRINT X;
> MAT PRINT G;
>
>
> !未知数
> LET Px=2 !求点PとQ
>
>
> !------------------------------
>
> !自由度R ※条件方程式の数
> LET R=P-Px
>
>
> !条件方程式 UV=t
> DIM U(R,P)
> DATA 1,-1,0,0,0 !点Pについて HA+h1~=HB+h2~ より、(h1+v1)-(h2+v2)=HB-HA ∴v1-v2=-(h1+HA)+(h2+HB)
> DATA 0,0,1,-1,0 !点Qについて HC+h3~=HD+h4~
> DATA 1,0,0,-1,1 !点Pと点Qについて HA+h1~+h5~=HD+h4~
> MAT READ U
>
> DIM t(R,1)
> FOR i=1 TO R
>    LET s=0
>    FOR j=1 TO P
>       IF j>C THEN LET Zj=0 ELSE LET Zj=Z(j)
>       LET s=s-(X(j)+Zj)*U(i,j)
>    NEXT j
>    LET t(i,1)=s
> NEXT i
> !!!LET t(1,1)=-X(1)+X(2)-Z(1)+Z(2) !0.001
> !!!LET t(2,1)=-X(3)+X(4)-Z(3)+Z(4) !-0.002
> !!!LET t(3,1)=-X(1)+X(4)-X(5)-Z(1)+Z(4) !0.001
> MAT PRINT t;
>
>
> !------------------------------
>
> !相関式 NK=t、N=UG(Ut)より、K=(Ni)tを求める
> DIM Ut(P,R)
> MAT Ut=TRN(U)
> DIM TMP(P,R) !G(Ut) ※次でも使う
> MAT TMP=G*Ut
> DIM N(R,R)
> MAT N=U*TMP
> MAT PRINT N;
>
> DIM invN(R,R)
> MAT invN=INV(N)
> DIM K(R,1)
> MAT K=invN*t
>
> MAT PRINT K;
>
>
> !補正値の計算(mm) V=G(Ut)K
> DIM V(P,1)
> MAT V=TMP*K
>
> MAT PRINT V;
>
>
> !最確値 X~=X+V
> FOR i=1 TO P
>    PRINT "路線";STR$(i);"=";X(i)+V(i,1)
> NEXT i
> PRINT "点P";Z(1)+(X(1)+V(1,1)); Z(2)+(X(2)+V(2,1)) !有効桁数 ##.###
> PRINT "点Q";Z(3)+(X(3)+V(3,1)); Z(4)+(X(4)+V(4,1))
>
>
>
>
> !精度の計算(mm^2) σ^2=(Kt)NK/r
> DIM s2(1,1),Kt(1,R)
> MAT Kt=TRN(K)
> MAT s2=Kt*t !NK=t
> LET sigma2=s2(1,1)/R
>
> PRINT "σ^2=";sigma2
>
>
> !分散行列(mm^2) σ^2*Gx、Gx=G-G(Ut)(Ni)UG
> DIM Gx(P,P)
> MAT Gx=TMP*invN !G(Ut)(Ni)
> MAT Gx=Gx*U
> MAT Gx=Gx*G
> MAT Gx=G-Gx
> MAT Gx=sigma2*Gx
>
> MAT PRINT Gx;
>
>
> END
> </PRE>
 

座標軸数字位置自動調整

 投稿者:荒田浩二  投稿日:2009年10月 2日(金)22時15分55秒
返信・引用
  十進BASICの軸・格子を描く組込み絵定義 AXES(p,q),GRID(p,q)を、いつでも数字が描画されるように拡張しました。
描画領域内に座標軸がない場合、下端左端に数字を描きます。
(注意:数字の"0"の位置は必ずしも原点(0,0)を示しているわけではない)
数字文字列が長いときは小数部分をカットし、重なって描画されるのを回避します。(指数部のある場合を除く)
AXES0(p,q),AXES(p,q)では、座標軸が描画されないときには描画領域周囲に目盛線を描画するようにしました。
両軸とも描画されている場合は、組込み絵定義と同じ結果になります。

既存のプログラムに、140行END以下の外部絵定義を付加するだけで拡張できます。お試しください。
(注意:引数のないDRAW AXES,DRAW GRIDなどはエラーとなる)


100 SET WINDOW 2,10,5,13
    !SET WINDOW -4,4,-4,4
    !SET WINDOW -3,5,4,12
110 LET a=1  ! a=.425
120 LET b=1
130 DRAW AXES(a,b)
    !DRAW AXES0(a,b)
    !DRAW GRID(a,b)
    !DRAW GRID0(a,b) ! 組込み絵定義
140 END

REM ** 座標数字位置自動調整 **
EXTERNAL PICTURE AXES(p,q)
    DRAW axes_grid("on","ax",STR$(p),STR$(q))
END PICTURE
EXTERNAL PICTURE AXES0(p,q)
    DRAW axes_grid("off","ax",STR$(p),STR$(q))
END PICTURE
EXTERNAL PICTURE GRID(p,q)
    DRAW axes_grid("on","gr",STR$(p),STR$(q))
END PICTURE
!
!十進BASIC添付"\BASICw32\Library\Grid2.lib"参照
! num$="off"数字無,"on"数字有 , ag$="ax"軸,"gr"格子 , sx=x軸目盛間隔 , sy=y軸目盛間隔
EXTERNAL PICTURE axes_grid(num$,ag$,sx$,sy$)
    OPTION ARITHMETIC DECIMAL
    FUNCTION val_r(f$)  ! 有理数を小数に変換
       LET vrp=POS(f$,"/")
       IF vrp=0 THEN LET val_r=VAL(f$) ELSE LET val_r=VAL(f$(1:vrp-1))/VAL(f$(vrp+1:LEN(f$)))
    END FUNCTION
    FUNCTION round_cut$(a$,A,s)  ! 小数桁カット
       ASK TEXT WIDTH(a$) w
       LET d=LEN(a$)
       LET p=POS(a$,".")
       IF w>s AND p>0 AND POS(a$,"E")=0 AND d>2 AND NOT(d=3 AND a$(1:2)="-." OR a$(d:d)=".") THEN
          LET a$=STR$(SGN(A)*ROUND(ABS(A),d-p-1))
          ! LET a$=STR$(ROUND(A,d-p-1))
          IF POS(a$,".")>0 THEN LET a$=a$&"00000000" ELSE LET a$=a$&".00000000"
          LET a$=round_cut$(a$(1:d-1),A,s)
       END IF
       LET round_cut$=a$
    END FUNCTION
    LET sx=val_r(sx$)
    LET sy=val_r(sy$)
    ASK WINDOW L,R,B,T
    ASK LINE STYLE S
    ASK LINE COLOR C
    SET LINE COLOR 15   ! 銀色
    ASK TEXT COLOR TC
    SET TEXT COLOR 15   ! 銀色
    ASK TEXT JUSTIFY ts1$,ts2$
    SET LINE STYLE 1
    PLOT LINES:L,0;R,0  ! x軸
    PLOT LINES:0,B;0,T  ! y軸
    IF ag$="gr" THEN SET LINE STYLE 3
    IF sx<>0 THEN
       IF B*T<0 OR T=0 THEN SET TEXT JUSTIFY "RIGHT","TOP" ELSE SET TEXT JUSTIFY "RIGHT","BOTTOM"
       IF B*T<0 OR T=0 THEN LET y0=0 ELSE LET y0=B
       LET wy=WORLDY(PIXELY(0)+2)
       LET n=ABS(INT(LOG10(sx)-2))
       FOR X=CEIL(L/sx)*sx TO INT(R/sx)*sx+1.001*sx STEP sx
          IF ag$="gr" THEN PLOT LINES:X,B;X,T ELSE PLOT LINES:X,-wy;X,wy
          IF y0=B AND ag$="ax" THEN
             PLOT LINES:X,B-(T-B)/100;X,WORLDY(3)  ! 下端目盛線
             PLOT LINES:X,T+(T-B)/100;X,WORLDY(PIXELY(T)-3)  ! 上端目盛線
          END IF
          IF num$="on" THEN PLOT TEXT,AT X,y0 : round_cut$(STR$(ROUND(X,n)),X,sx)
       NEXT X
    END IF
    IF sy<>0 THEN
       IF L*R<0 OR R=0 THEN SET TEXT JUSTIFY "RIGHT","TOP" ELSE SET TEXT JUSTIFY "LEFT","TOP"
       IF L*R<0 OR R=0 THEN LET x0=0 ELSE LET x0=L
       LET wx=WORLDX(PIXELX(0)+2)
       LET n=ABS(INT(LOG10(sy)-2))
       FOR Y=CEIL(B/sy)*sy TO INT(T/sy)*sy+1.001*sy STEP sy
          IF ag$="gr" THEN PLOT LINES:L,Y;R,Y ELSE PLOT LINES:-wx,Y;wx,Y
          IF x0=L AND ag$="ax" THEN
             PLOT LINES:L-(R-L)/100,Y;WORLDX(3),Y  ! 左端目盛線
             PLOT LINES:R+(R-L)/100,Y;WORLDX(PIXELX(R)-3),Y  ! 右端目盛線
          END IF
          IF num$="on" THEN PLOT TEXT,AT x0,Y : STR$(ROUND(Y,n))
       NEXT Y
    END IF
    SET TEXT JUSTIFY "RIGHT","TOP"
    IF num$="on" AND sx=0 AND sy=0 THEN PLOT TEXT,AT 0,0:STR$(0)
    SET LINE COLOR C
    SET LINE STYLE S
    SET TEXT COLOR TC
    SET TEXT JUSTIFY ts1$,ts2$
END PICTURE
 

Re: 測量最小二乗法について

 投稿者:山中和義  投稿日:2009年10月 3日(土)11時46分59秒
返信・引用  編集済
  > No.594[元記事へ]

kikiririさんへのお返事です。


参考サイトのURLが変更されているようです。
手順および理論は、このサイトのPDFファイルを参照してください。

 http://hw001.gate01.com/kazuok/page03.html ※直リンクですので、変更される可能性はあります。

 デジタル写真測量 http://hw001.gate01.com/kazuok/index.html
 ※「ポケコンプログラムによる測量計算法(山海堂)」の著者のようです。


また、前回紹介した本の手計算部分をプログラムしたものを掲載します。参考にしてください。
!最小2乗法による測量網平均(観測方程式)

!参考文献 最小ニ乗法と測量網平均の基礎 東洋出版 p.170〜173(p.165〜177)

!既知点
LET H301=41.7065 !301点の標高(m)
LET H302=43.9632 !302点


!観測値
LET n=6 !数

DATA  5.1342, 4.6 !路線1 観測比高(高低差)(m)、路線距離(km)
DATA -2.0508, 5.2 !路線2
DATA -2.2287, 9.2 !路線3
DATA -0.0330, 6.3 !路線4
DATA -0.8601, 3.9 !路線5
DATA -0.8258, 8.3 !路線6

DIM Hb(n),P(n,n) !観測値、重量行列
MAT P=ZER
FOR i=1 TO n
   READ Hb(i),Wi
   LET P(i,i)=1/Wi
NEXT i

MAT PRINT Hb; !debug
MAT PRINT P; !debug


!新点(未知点)
LET m=3 !数
LET pnt$="123"


!------------------------------ 観測方程式の一般式 V=A*X+Lを組み立てる p.170〜171

DIM A(n,m) !係数行列 ※各路線の観測比高と新点標高との関係より
DATA -1, 1, 0
DATA  0,-1, 0
DATA  0, 0, 1
DATA  0, 0,-1
DATA  1, 0,-1
DATA  1, 0, 0
MAT READ A

DIM L(n,1) !定数項
LET L(1,1)=-Hb(1)
LET L(2,1)=-(Hb(2)-H302)
LET L(3,1)=-(H302+Hb(3))
LET L(4,1)=-(Hb(4)-H301)
LET L(5,1)=-Hb(5)
LET L(6,1)=-(H301+Hb(6))

MAT PRINT A; !debug
MAT PRINT L; !debug


!------------------------------ 方程式の解(X~)を求める p.172中

DIM TT(50,50),MM(50,50) !作業用

MAT TT=TRN(A) !TRN(A)*P*Aの計算
MAT TT=TT*P
MAT MM=TT !save it
MAT TT=TT*A
MAT PRINT TT; !debug

DIM Q(m,m) !重み係数行列 Q=INV(TRN(A)*P*A)の計算
MAT Q=INV(TT)
MAT PRINT Q; !debug


MAT TT=MM*L !TRN(A)*P*Lの計算
MAT PRINT TT; !debug


DIM Xb(m,1) !最確値 X~
MAT TT=Q*TT
MAT Xb=(-1)*TT
MAT PRINT Xb; !debug


!------------------------------ 網平均の最終結果 p.172中〜173

DIM Vb(n,1) !残差ベクトル V~=L-A*INV(TRN(A)*P*A)*TRN(A)*P*Lの計算
MAT TT=A*Xb !Xb=-INV(TRN(A)*P*A)*TRN(A)*P*Lより
MAT Vb=L+TT
MAT PRINT Vb; !debug

MAT TT=TRN(Vb) !単位重みの標準偏差σ0の推定値 m0=SQR(TRN(V~)*P*V~/(m-n))の計算
MAT TT=TT*P
MAT TT=TT*Vb
MAT PRINT TT; !debug
LET m0=SQR(TT(1,1)/(n-m))
PRINT "m0="; m0 !debug

FOR i=1 TO m
   PRINT pnt$(i:i); "点の標高"; Xb(i,1);"m"; !有効桁数 ##.####
   PRINT " ±"; m0*SQR(Q(i,i)); "mm" !有効桁数 #.#
NEXT i


END
 

ありがとうございました

 投稿者:kikiriri  投稿日:2009年10月 3日(土)14時38分57秒
返信・引用
  早速のご返信ありがとうございました。  

相関式の必要性について

 投稿者:kikiriri  投稿日:2009年10月 3日(土)16時55分14秒
返信・引用
  山中和義さんへ

  kikiririより

何度も質問してすみません。

今回のプログラムで相関式がないようですが
正の相関があるとか負の相関があるなどのように使うんですよね。
必要性の検討方法、プログラムの選択方法(どんなときにどちらのプログラムを使うと良い)とかありますか。
 

確率・統計 薩摩順吉著あり。

 投稿者:kikiriri  投稿日:2009年10月 3日(土)17時18分14秒
返信・引用
  山中和義さんへ

  kikiririより

当方手元に「確率・統計」薩摩順吉著あります。
ご指導中引用されても都合が良いです。
勝手な追加すみません。
 

学生時代の妄想

 投稿者:kikiriri  投稿日:2009年10月 3日(土)18時01分14秒
返信・引用
  山中和義さんへ

  kikiririより

工学部でしたが、パソコンが解決できない問題ならいくらでもあることも、
手計算や電卓で問題を解く手前、パソコンがどれだけ有用かも分かってたはずなんですが、
有限要素法についてもうほとんど忘れましたが、
パソコンで実際に問題と向きあい手を出すことに重みを感じます。
 

有効桁数と精度について

 投稿者:kikiriri  投稿日:2009年10月 3日(土)18時27分11秒
返信・引用
  山中和義さんへ

  kikiririより

有効桁数?16桁?で計算していますが、
答えは四捨五入すればあっていますが、
偶然の一致では、桁落ちはないのですか?
また、これも初学者の質問だと思いますが。
正規分布図はどの程度精度が信頼出来るのですか。
何桁出しても、精度は気にすることはないとか、
だったら16桁で計算している今回の計算方法も良いのではないのかとも思いますが、
純粋な理論上は完全に全桁信用して、出来るだけ多桁で計算して。
解答する時に、有効桁数、有効精度を調べるということですか。
この辺はぼかされているようにも見えます?
 

Re: 有効桁数と精度について

 投稿者:山中和義  投稿日:2009年10月 3日(土)19時36分30秒
返信・引用
  > No.601[元記事へ]

kikiririさんへのお返事です。

わかる範囲での回答です。

>有効桁数と精度について

式はあくまでも理論値ですが、パソコンが扱う数値計算(実数の扱い)は近似値ですから、
誤差は発生します。
この場合、標高の計測値は小数点4桁(301点なら41.7065)ですので、
計算結果は小数点5桁を四捨五入するのではないでしょうか。


>パソコンで実際に問題と向きあい手を出すことに重みを感じます。

他のページの計算部分をプログラムしてみてください。投稿を待っています。


>プログラムの選択方法

参考本のP.138下〜140中。
 

ご返信ありがとうございます(たびたびすみませんがまた編集させていただきました)

 投稿者:kikiriri  投稿日:2009年10月 3日(土)20時10分0秒
返信・引用  編集済
  山中和義さんへ

  kikiririより

早速のご返信ありがとうございました。

多少、うれしい興奮気味ですが、すみません
>式はあくまでも理論値ですが、パソコンが扱う数値計算(実数の扱い)は近似値ですか
>ら、
>誤差は発生します。

>この場合、標高の計測値は小数点4桁(301点なら41.7065)ですので、
>計算結果は小数点5桁を四捨五入するのではないでしょうか。

純粋数学(物理学)と工学的な数値計算との違いでしょうか。
41.7065は、有効桁数6桁では?4.17065*10^1
この辺は僕も疑問なんですが。
高校物理では、小数以下四桁では掛け算は、一桁多い五桁まで計算して四捨五入ですね。
五捨五入かもしれませんが、

他のページをプログラムしてみてください。投稿待っています。に答えがある気もするので
すが

ありがとうございました。
 

つづき4

 投稿者:SECOND  投稿日:2009年10月 4日(日)06時12分22秒
返信・引用
  !Page-4 の始め

!DQT
SUB FFDB
   DO WHILE 0< N
      CALL RED_D
      LET w= IP(ORD(D$)/16) !p=0(byte) p=1(word)
      LET J=MOD(ORD(D$),16) !J=0~3 (QT.number)
      FOR i=0 TO 63
         CALL RED_D
         LET DQ(U(i),V(i),J)=ORD(D$)
         IF w=1 THEN
            CALL RED_D
            LET DQ(U(i),V(i),J)=DQ(U(i),V(i),J)*256+ORD(D$)
         END IF
      NEXT i
      LET N=N-65-64*w ! remain size
   LOOP
END SUB

!SOF0
SUB FFC0
   CALL RED_D
   IF ORD(D$)<>8 THEN BREAK ! 8bit( 24bitColor ) at RGB.dimension
   CALL RED_D
   LET W=ORD(D$)*256
   CALL RED_D
   LET DY=W+ORD(D$) !V.pix.
   CALL RED_D
   LET W=ORD(D$)*256
   CALL RED_D
   LET DX=W+ORD(D$) !H.pix.
   CALL RED_D
   FOR i=0 TO ORD(D$)-1   !1~3 scan order items
      CALL RED_D
      LET CoID(ORD(D$))=i ! (Y=0, Cb=1, Cr=2)<-- CoID( ID=0~255)
      CALL RED_D
      LET MH(i)= IP(ORD(D$)/16) ! HV Y=11,12,21,22,41 Cb=11,11,11,11,11 Cr=11,11,11,11,11
      LET MV(i)=MOD(ORD(D$),16)
      CALL RED_D
      LET QS(i)=ORD(D$)   ! QT.number0~3 <-- QS( Y=0, Cb=1, Cr=2)
   NEXT i
   IF 2< i THEN LET CMO=2 ELSE LET CMO=0
END SUB

!DHT
SUB FFC4
   DO WHILE 0< N
      CALL RED_D
      LET J=ORD(D$)              ! 0?~1?=DC~AC  ?0~?3=ID0~ID3
      LET J=2*MOD(J,16)+IP(J/16) ! 0~1=ID0.DC~AC  2~3=ID1.DC~AC  4~5=ID2.…
      LET DH(0,J)=0 !!!for 2nd.use for clear
      FOR i=1 TO 16
         CALL RED_D
         LET DH(i,J)=ORD(D$)
         LET DH(0,J)=DH(0,J)+DH(i,J)
      NEXT i
      FOR i=0 TO DH(0,J)-1
         CALL RED_D
         LET DV(i,J)=ORD(D$)
      NEXT i
      !---
      FOR i=i TO 255
         LET DV(i,J)=0
      NEXT i
      CALL makeH0(J) ! make Huffman Code table B() L()
      CALL makeD0(J) ! make Huffman Decorder table A()
      !---
      LET N=N-1-16-DH(0,J) ! remain size
   LOOP
END SUB

!SOS
SUB FFDA
   CALL RED_D
   LET M2=ORD(D$)
   MAT HDC=(-2)*CON
   MAT HAC=(-2)*CON
   FOR i=1 TO M2
      CALL RED_D
      LET w=ORD(D$) !ID=0~255( normal 01~03)
      CALL RED_D    ! 00=Y 11=Cb 11=Cr
      LET HDC(CoID(w))= IP(ORD(D$)/16)*2   !DC 0~3-->0,2,4,6
      LET HAC(CoID(w))=MOD(ORD(D$),16)*2+1 !AC 0~3-->1,3,5,7
   NEXT i
   CALL RED_D
   LET Ss_=ORD(D$) ! low of spectral selection
   CALL RED_D
   LET Se_=ORD(D$) ! high of spectral selection
   CALL RED_D
   LET Al=MOD(ORD(D$),16) ! low bit of successive approximation
   LET Ah=IP(ORD(D$)/16)  !high bit of successive approximation
   !--- private controll M3(display timing)
   LET w=Ah-Al
   IF w=0 THEN LET w=1
   FOR i=0 TO 2
      IF 0<=HAC(i) THEN LET M3(i)=M3(i)+(Se_-Ss_+1)*w ! M3()= scan band sum
   NEXT i
   !--- next image data top
END SUB

SUB ROPEN
   OPEN #1 :NAME FL$ ,ACCESS INPUT
END SUB

SUB RED_D
   CHARACTER INPUT #1 :D$
   LET byt=byt+1 !!!
END SUB

END
 

つづき3

 投稿者:SECOND  投稿日:2009年10月 4日(日)06時13分51秒
返信・引用
  !Page-3 の始め

!============
! B(,J)L(,J)<-- DH(,J) for decorder table A(,J)
!
SUB makeH0(J)
   LET i=0   ! コード生成 順番(短い順)
   LET Hx=0
   LET Tx=BVAL("8000",16)
   FOR L_=1 TO 16
      FOR P=1 TO DH(L_,J)
         LET L(i,J)=L_
         LET B(i,J)=Hx ! コード(生成順), 座標DV(頻度降順) と同順。
         LET i=i+1
         LET Hx=Hx+Tx
      NEXT P
      LET Tx=Tx/2
   NEXT L_
   LET B(256,J)=0
   FOR i=i TO 255
      LET L(i,J)=0
      LET B(i,J)=0
   NEXT i
END SUB

!============
!A(,J)=output decorder table<-- B(,J) L(,J) DH(,J) DV(,J)
!
SUB makeD0(J)
   FOR LH=16 TO 1 STEP -1
      IF DH(LH,J)<>0 THEN EXIT FOR
   NEXT LH                 !length max. in huffman table
   LET LM=CEIL(LH/BST)*BST !length max. bound by BST
   !---
   LET I=0           !start huffman table adr.
   LET LA=0          !line adr.
   LET P=BST         !start Decord code width
   LET U_=2^(16-BST) !start Decord code step
   LET NC=0          !next start Decord code
   DO
      LET D_=NC !start Decord code
      LET NC=-1
      LET LB=LA+(65536-D_)/U_ !1st nest adr.
      DO
         CALL SERCH
         IF 0< L_ THEN
            LET A(LA,J)= BVAL("8000",16)+L_*256+DV(I,J) !b15=end. +L.+V.
         ELSEIF P=LM THEN
            LET A(LA,J)= BVAL("C000",16)+LH*256 !b15=end. b14=Unused. +L.
         ELSE
            IF NC=-1 THEN LET NC=D_
            LET A(LA,J)=LB ! nest adr.
            LET LB=LB+SHb  ! next nest adr.
         END IF
         LET D_=D_+U_
         LET LA=LA+1
      LOOP UNTIL IP(D_)=65536
      LET P=P+BST
      LET U_=U_/SHb        !shr(U_,BST)
   LOOP UNTIL P>LM
   !---
   FOR LA=LA TO 255
      LET A(LA,J)=0 !(0),table stop mark
   NEXT LA
END SUB

SUB SERCH
   FOR I=I TO DH(0,J)-1
      LET L_=L(I,J)
      IF L_<=P THEN LET w=IP(D_/2^(16-L_))*2^(16-L_) ELSE EXIT FOR
      IF w<=B(I,J) THEN
         IF w=B(I,J) THEN EXIT SUB ELSE EXIT FOR
      END IF
   NEXT I
   LET L_=-1
END SUB

!===========
! Inverse Fast Cosin Transform.( 8x8, iDCT-2 ) ← Inverse Quantization.DQ()
SUB IDDCT8X8
   FOR V0=0 TO DV_-1 STEP 8
      FOR U0=0 TO DU-1 STEP 8
         FOR P=0 TO CMO ! =0(mono) =2(color)
            FOR V_=0 TO 7
               FOR U_=0 TO 7
                  LET X(U_)=D2(U0+U_,V0+V_,P) *DQ(U_,V_,QS(P)) ! Inverse Quantization
               NEXT U_
               CALL IWANG
               FOR X_=0 TO 7
                  LET T(X_,V_)=X(X_)
               NEXT X_
            NEXT V_
            FOR X_=0 TO 7
               FOR V_=0 TO 7
                  LET X(V_)=T(X_,V_)
               NEXT V_
               CALL IWANG
               FOR Y_=0 TO 7
                  IF P=0 THEN LET D1(U0+X_,V0+Y_,P)=X(Y_)+128 ELSE LET D1(U0+X_,V0+Y_,P)=X(Y_)
               NEXT Y_
            NEXT X_
         NEXT P
      NEXT U0
   NEXT V0
END SUB

!----inverse Wang.( 8, iDCT-2 )
SUB IWANG
   LET XO(0)=SQR(2/8)*X(0)
   LET XO(1)=SQR(2/8)*X(4)
   LET XO(2)=SQR(2/8)*X(2)
   LET XO(3)=SQR(2/8)*X(6)
   LET XO(4)=SQR(1/8)*X(1)
   LET XO(5)=SQR(1/8)*X(5)
   LET XO(6)=SQR(1/8)*X(3)
   LET XO(7)=SQR(1/8)*X(7)
   !
   LET X(4)=(COS(PI  /16)*XO(4)+SIN(PI  /16)*XO(7))
   LET X(5)=(COS(PI*5/16)*XO(5)+SIN(PI*5/16)*XO(6))
   LET X(6)=(SIN(PI*5/16)*XO(5)-COS(PI*5/16)*XO(6))
   LET X(7)=(SIN(PI  /16)*XO(4)-COS(PI  /16)*XO(7))
   !
   LET XO(4)= X(4)+X(5)
   LET XO(5)= X(4)-X(5)
   LET XO(6)=-X(6)+X(7)
   LET XO(7)= X(6)+X(7)
   !
   LET X(0)=(COS(PI/4)*XO(0)+COS(PI  /4)*XO(1))
   LET X(1)=(COS(PI/4)*XO(0)-COS(PI  /4)*XO(1))
   LET X(2)=(SIN(PI/8)*XO(2)-SIN(PI*3/8)*XO(3))
   LET X(3)=(COS(PI/8)*XO(2)+COS(PI*3/8)*XO(3))
   LET X(4)=XO(4)
   LET X(5)=XO(6)
   LET X(6)=XO(5)
   LET X(7)=XO(7)
   !
   LET XO(0)=X(0)+X(3)
   LET XO(1)=X(1)+X(2)
   LET XO(2)=X(1)-X(2)
   LET XO(3)=X(0)-X(3)
   LET XO(4)=X(7)*SQR(2)
   LET XO(5)=X(6)-X(5)
   LET XO(6)=X(6)+X(5)
   LET XO(7)=X(4)*SQR(2)
   !
   LET X(0)=XO(0)+XO(7)
   LET X(1)=XO(1)+XO(6)
   LET X(2)=XO(2)+XO(5)
   LET X(3)=XO(3)+XO(4)
   LET X(4)=XO(3)-XO(4)
   LET X(5)=XO(2)-XO(5)
   LET X(6)=XO(1)-XO(6)
   LET X(7)=XO(0)-XO(7)
END SUB

!=============
SUB R_BIN31(M) ! decord(M) before new.search(M)
   DO
      IF M=BVAL("D8",16) THEN  ! SOI
         MAT DH=ZER   ! clear Huffman Table
         LET DRI=0    ! clear Restart Interval.value for RST0~7(restart marker)
         LET rct=-1   ! Interval.counter, valid (0<=rct), invalid (rct< 0)
         MAT M3=ZER   ! clear scan band sum
      ELSEIF M=BVAL("D9",16) THEN ! EOI
         EXIT DO      ! close & end_sub
      ELSEIF BVAL("D0",16)<=M AND M<=BVAL("D7",16) THEN ! RST0~7( restart marker)
         LET rct=DRI  ! set counter with Restart Interval
         EXIT SUB
      ELSEIF 0< M THEN     !M=0 is data"FF" in picture area
         CALL RED_D
         LET N=ORD(D$)*256
         CALL RED_D
         LET N=N+ORD(D$)-2 ! N=remain size
         !---
         IF BVAL("E0",16)<=M AND M<=BVAL("EF",16) THEN ! APP0~APP15
            CALL FFE0
         ELSEIF M=BVAL("DD",16) THEN
            CALL FFDD ! DRI  load DRI & rct=DRI
         ELSEIF M=BVAL("FE",16) THEN
            CALL FFFE ! COMMENT
         ELSEIF M=BVAL("C4",16) THEN
            CALL FFC4 ! DHT
         ELSEIF M=BVAL("DB",16) THEN
            CALL FFDB ! DQT
         ELSEIF M=BVAL("C0",16) OR M=BVAL("C2",16) THEN
            CALL FFC0 ! SOF0 SOF2
         ELSEIF M=BVAL("DA",16) THEN
            CALL FFDA ! SOS
            EXIT SUB  ! without close
         ELSE
            BREAK     ! new marker
         END IF
      END IF
      !---
      DO
         LET M=BVAL("D9",16) ! EOI, 256 ! end of file
         CHARACTER INPUT #1,IF MISSING THEN EXIT DO :D$
         LET byt=byt+1 !!!
         LET M=ORD(D$)
      LOOP UNTIL M=255       ! 1st.mark
      IF M<>255 THEN EXIT DO ! close & end_sub
      CALL RED_D
      LET M=ORD(D$)
   LOOP
   CLOSE #1
END SUB

!DRI
SUB FFDD
   CALL RED_D
   LET DRI=ORD(D$)*256
   CALL RED_D
   LET DRI=DRI+ORD(D$)
   LET rct=DRI
END SUB

!APP0
SUB FFE0
   FOR W=1 TO N
      CALL RED_D
   NEXT W
END SUB

!COMMENT
SUB FFFE
   FOR W=1 TO N
      CALL RED_D
   NEXT W
END SUB

!
Page-4 へ続く
 

つづき2

 投稿者:SECOND  投稿日:2009年10月 4日(日)06時15分40秒
返信・引用  編集済
  !Page-2 の始め

SUB frame
   PRINT "  Ss Se AhAl: ";Ss_;Se_;STR$(Ah);STR$(Al)
   PRINT "  Y  HDC HAC: ";IP(HDC(0)/2);IP(HAC(0)/2)
   PRINT "  Cb        : ";IP(HDC(1)/2);IP(HAC(1)/2)
   PRINT "  Cr        : ";IP(HDC(2)/2);IP(HAC(2)/2)
   CALL reset0
   !---
   FOR V09=0 TO DV_-1 STEP 8*MV(0)
      FOR U09=0 TO DU-1 STEP 8*MH(0)
         IF rct=0 THEN
            CALL R_BIN31(0)        ! read marker
            IF rct<>DRI THEN BREAK ! not RST0~7
            CALL reset0 ! Restart
         END IF
         CALL MCUxx11 ! read picture data
         LET rct=rct-1
         !---
         IF 0< ext THEN
            IF ext=103001 THEN
               PRINT "abort marker ";BSTR$(M,16)
               IF BVAL("D0",16)<=M AND M<=BVAL("D7",16) THEN ! RST0~7( restart marker)
                  LET rct=DRI ! set counter
                  CALL reset0 ! Restart
               ELSE
                  EXIT SUB ! others marker
               END IF
            ELSE
               PRINT "file error. display fragment"
               LET M=BVAL("D9",16) ! EOI
               EXIT SUB
            END IF
         END IF
      NEXT U09
   NEXT V09
   IF 0< EOB THEN PRINT "EOBn over frame";EOB !!!
END SUB

SUB MCUxx11
!---read MCU
   FOR P=0 TO CMO
      IF 0<=HDC(P) OR 0<=HAC(P) THEN
         FOR V0=V09 TO V09+8*MV(P)-1 STEP 8
            FOR U0=U09 TO U09+8*MH(P)-1 STEP 8
               WHEN EXCEPTION IN
                  IF EOB=0 THEN CALL R_BLK0 ELSE LET EOB=EOB-1
               USE
                  LET ext=EXTYPE
                  EXIT SUB
               END WHEN
               !---extend bitmap
               IF 0< Ah AND 0< Se_ THEN
                  FOR i=A_ TO Se_
                     IF D2(U0+U(i),V0+V(i),P)<>0 THEN
                        LET L_=1
                        WHEN EXCEPTION IN
                           CALL DEC1_EX
                        USE
                           LET ext=EXTYPE
                           EXIT SUB
                        END WHEN
                        LET V_=SGN(D2(U0+U(i),V0+V(i),P))*V_*2^Al
                        LET D2(U0+U(i),V0+V(i),P)=D2(U0+U(i),V0+V(i),P) +V_
                     END IF
                  NEXT i
                  LET A_=Ss_
               END IF
               !---
            NEXT U0
         NEXT V0
      END IF
   NEXT P
END SUB

!------
SUB R_BLK0
   IF Ss_=0 THEN
   !---D.C.part
      LET debug$="DC.huffman" !!!
      IF Ah=0 THEN  !-----baseline.progSS.progSA(1st.scan).
         LET J=HDC(P) !huffman D.C.table selection P( 0=Y 1=Cb 2=Cr)
         CALL DEC1_NS
         LET EL=V_     !extent length
         !---D.C.extent
         LET debug$="DC.huffman extend" !!!
         IF 0< EL THEN
            LET L_=EL
            CALL DEC1_EX   !keep EL, V_=extent value( length EL bits)
            LET W=2^(EL-1)                  !minimum in EL bits length
            IF V_< W THEN LET V_=V_-(W*2-1) !restore signed value
            LET B2(P)=B2(P)+V_*2^Al       !point transform, integrate to D.C.
         END IF
         LET D2(U0+U(0),V0+V(0),P)=B2(P)
      ELSE  !-----progSA(2st.scan).
         LET L_=1
         CALL DEC1_EX
         LET V_=SGN(D2(U0+U(0),V0+V(0),P))*V_
         LET D2(U0+U(0),V0+V(0),P)=D2(U0+U(0),V0+V(0),P) +V_*2^Al
      END IF
      LET Sa_=1
   ELSE
      LET Sa_=Ss_
   END IF
   !---A.C.parts
   IF Se_=0 THEN EXIT SUB !band Ss_~Se_
   LET J=HAC(P)          !huffman A.C.table selection P( 0=Y 1=Cb 2=Cr)
   LET debug$="AC.huffman"
   FOR A_=Sa_ TO Se_
      CALL DEC1_NS
      LET EL=MOD(V_,16)   !extent length
      LET RL= IP(V_/16)   !run length
      !---
      IF RL<=14 AND EL=0 THEN  !End Of Block(00). End Of Band(10,20,,E0)
      !---EOBn extend
         LET debug$="eobn extend"& STR$(RL)
         IF 0< RL THEN
            LET L_=RL         !extend= run_length
            CALL DEC1_EX      !keep RL, V_=run value( length RL bits)
            LET EOB=V_+2^RL-1 !RL= End Of Band(10,20,,E0) run length
         END IF
         EXIT SUB
         !---
      END IF
      !---RL=(0~15)EL=(1~10), RL=(15)EL=(0)
      LET debug$="AC.huffman extend" !!!
      IF Ah=0 THEN !-----baseline.progSS.progSA(1st.scan).
         LET A_=A_+RL        !skip zero_run_length 0~15
         !---A.C.extent
         IF 0< EL THEN       !ZRL(16) only skip
            LET L_=EL
            CALL DEC1_EX     !keep EL, V_=extent value( length EL bits)
            LET w=2^(EL-1)                  !minimum in EL bits length
            IF V_< w THEN LET V_=V_-(w*2-1) !restore signed value
            !---
            LET V_=V_*2^Al   !point transform
            LET D2(U0+U(A_),V0+V(A_),P)=V_
         END IF
      ELSE !-----progSA(2st.scan).
         IF 0< EL THEN       !ZRL(16) only skip
            LET L_=EL
            CALL DEC1_EX     !keep EL, V_=extent value( length EL bits)
            IF EL<>1 THEN PRINT "AC.2nd.=";EL;V_ !!!
            LET V01=V_
         END IF
         FOR i=A_ TO Se_
            IF D2(U0+U(i),V0+V(i),P)<>0 THEN !zz(k)=xxx_1?/0?
               LET L_=1
               CALL DEC1_EX
               LET V_=SGN(D2(U0+U(i),V0+V(i),P))*V_
               LET D2(U0+U(i),V0+V(i),P)=D2(U0+U(i),V0+V(i),P) +V_*2^Al
            ELSEIF RL=0 THEN                  !zz(k)=000_V01
               EXIT FOR
            ELSE                              !zz(k)=000_0  ,zero run
               LET RL=RL-1
            END IF
         NEXT i
         IF 0< EL THEN  !ZRL(16) skip
            IF V01=0 THEN LET V01=-1
            LET D2(U0+U(i),V0+V(i),P)=V01*2^Al
         END IF
         LET A_=i
      END IF
   NEXT A_
END SUB

!========================
! decorder
! J= huffman code table selection ( 0=YDC 1=YAC 2=CDC 3=CAC)
! V_= pickup RRRRssss <-- JPG.file

SUB DEC1_NS
   DO
      IF BC< BST THEN CALL DEC1_IN
      LET W=IP(Hx)           ! bits width BST
      !----
      LET W=A(NA+W,J)
      IF 32768<=W THEN EXIT DO
      LET NA=W               ! nest adr.  W=0 table end
      LET BC=BC-BST
      LET Hx=MOD(Hx*SHb,SHb)
   LOOP
   LET NA=0                  ! DU0L LLLL VVVV VVVV
   LET L_=MOD(IP(W/256),128) !  U0L LLLL
   LET V_=MOD(W,256)         !           VVVV VVVV
   IF 16< L_ THEN PRINT "unused code" !BREAK  !unused code ! LET V_=BVAL("8000",16)
   !----
   LET W=MOD(L_,BST)
   IF 0< W THEN
      LET BC=BC-W
      LET Hx=MOD(Hx*2^W,SHb)
   ELSE
      LET BC=BC-BST
      LET Hx=MOD(Hx*SHb,SHb)
   END IF
END SUB

SUB DEC1_IN
   CALL RED_D
   LET W=ORD(D$)
   IF W=255 THEN
      CALL RED_D
      LET M=ORD(D$)
      IF M<>0 THEN LET w=1/0 ! EXTYPE=3001, ffxx marker, abnormally break
   END IF
   LET Hx=Hx+W*2^(BST-8-BC)
   LET BC=BC+8
END SUB

!-------
SUB DEC1_EX
   LET V_=0
   DO
      IF L_< 1 THEN EXIT SUB
      IF BC< L_ THEN CALL DEC1_IN
      LET W=IP(Hx)
      !----
      IF BST>=L_ THEN EXIT DO
      LET V_=V_*SHb+W
      LET L_=L_-BST
      LET BC=BC-BST
      LET Hx=MOD(Hx*SHb,SHb)
   LOOP
   LET V_=V_*2^L_+IP(W*2^(L_-BST))
   !----
   LET BC=BC-L_
   LET Hx=MOD(Hx*2^L_,SHb)
END SUB

!
Page-3 へ続く
 

プログレッシブ JPG

 投稿者:SECOND  投稿日:2009年10月 4日(日)06時17分42秒
返信・引用
  !十進 BASIC による プログレッシブ JPG の展開と画像化。
!successive approximation subsequence 部分は、http://www.w3.org/Graphics/JPEG/itu-t81.pdf
!を見ても、説明が解りにくく、実際の例が、必要です。あくまで、個人的理解の範囲ですが、
!
!具体的、可視的なプログラムで、実行し画像化しますので、詳細事項の追跡と御参考に。
!再生できるファイルは、1000x1000 までの JPG だけで、
! baseline , spectral selection , successive approximation の3種類( web 上の、ほぼ全種)
!
!1)successive approximation AC.subsequence(Y,Cb,Cr 別々、1bit づつの処理)
!
!      0      1      1      0      0      0      0      0      0     ?
!      0      0      0      0      0      1      0      0      0     ?
!      0      1      0      0      0      0      0      1      0     ?
!      0      1      1      0      0      1      0      1      0     ?
!      0      1      1      0      0      1      0      1      0     ?
! --------------------------------------------------------------------------
!    ±1      b1     b2     0      0      b3     0      b4   ±1     ?
! 前の終 り                 RRRR   RRRR          RRRR        extend.   次の始め
!
!     huffman.
!     RRRRssss  extend.  b1 b2 b3 b4 …
!       3   1  (0 or 1)  bit_stream=?何個になるかは、上図で、上位桁 =0 の係数が
!              -1   +1   (0 or 1)     RRRR 個 になるまでに通過した上位桁 <>0 の個数。
!                         0  ±1
!                           0 → 無変化。
!                           1 → ±符号は上位桁に合せて加算。(絶対値が+1)
!
!2)successive approximation DC.subsequence(Y,Cb,Cr 別々、1bit づつの処理)
!
!  ハフマン・コード RRRRssss 部は、存在せず、
!  頭からの bit_stream.で、1bit づつ、全てのblock の DC係数 に加える。
!
!  AC と同様、0 → 無変化。1 → ±符号は上位桁に合せて加算。(絶対値が+1)
!
!※上記、successive approximation AC, DC とも、加える1は、
! 2^Al 倍の point transfer. としてから、加えます。
!
DEBUG ON
!------------------------
!JPG.decoder
! Baseline
! Progressive( spectral selection )( successive approximation )
!------------------------
OPTION ARITHMETIC NATIVE
OPTION BASE 0
OPTION CHARACTER byte
SET TEXT background "OPAQUE"
ASK BITMAP SIZE bmx,bmy
SET WINDOW 0,bmx, bmy,0
SET ECHO "OFF"
SET COLOR MODE "NATIVE"
!
DIM D8(1000,1000)   !GDISP DSPYbr
DIM D2(1000,1000,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
DIM D1(1000,1000,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
DIM MH(2),MV(2)     !R_BIN31  SOF0 MCU.Ybr.H()V()
DIM HDC(2),HAC(2)   !R_BIN31 hT.table selection
DIM QS(2),CoID(255) !R_BIN31 qT.table selection
DIM M3(2)
!
DIM U(63),V(63)         !zigzag
DIM DQ(7,7,3)           !blk8x8 DQT
DIM DH(16,7),DV(255,7)  !DHT
DIM B(255+1,7),L(255,7) !encorder & decorder's pre_table, length, ( MAKE_H2,MAKE_H0)
DIM A(2000,7)           !decorder
DIM B2(2)               !Ybr D.C.成分 starting & back_level for difference
DIM T(7,7),X(7),XO(7)   !DDCT8X8, IDDCT8X8
!
LET BST=2      !huffman decorder's bit step 1=8.5s 2=6.5s 4=8.0s 8=50.0s
LET SHb=2^BST  !huffman decorder  *SHb(shl BST) /SHb(shr BST)
!LET YDC0=1024  !prediction 128( 50%) * {SQR(2/8)^2 * SQR(1/2)^2 * (8*8)}
!
!---zigzag table
FOR V_=0 TO 7
   FOR U_=0 TO 7
      READ i
      LET U(i)=U_
      LET V(i)=V_
   NEXT U_
NEXT V_
DATA  0, 1, 5, 6,14,15,27,28
DATA  2, 4, 7,13,16,26,29,42
DATA  3, 8,12,17,25,30,41,43
DATA  9,11,18,24,31,40,44,53
DATA 10,19,23,32,39,45,52,54
DATA 20,22,33,38,46,51,55,60
DATA 21,34,37,47,50,56,59,61
DATA 35,36,48,49,57,58,62,63
!
DO
   FILE GETNAME FL$, "jpg"
   IF FL$="" THEN
      PRINT "入力ファイル名が、ありません。"
      STOP
   END IF
   PRINT "入力ファイル:"& FL$
   !---
   CLEAR
   CALL IZZRL0   ! D2()<-- decord JPG
   PRINT "次のファイル[ Any key ]"
   beep
   CHARACTER INPUT CLEAR: w$
LOOP UNTIL w$=CHR$(27) !ESC

!-------- IZZRL0 call here for display D2()
SUB MAIN65
   PRINT "画像の準備中、";
   CALL IDDCT8X8 ! D1()<-- iDCT<-- iDQT<-- D2()
   !---
   IF 1< MH(0) OR 1< MV(0) THEN ! Cb_Cr expand Blocks -->MCU scales
      FOR V09=0 TO DV_-1 STEP 8*MV(0)
         FOR U09=0 TO DU-1 STEP 8*MH(0)
         !---MCU part.Cb.Cr
            FOR V0=8*MV(0)-1 TO 0 STEP -1
               FOR U0=8*MH(0)-1 TO 0 STEP -1
                  LET D1(U09+U0,V09+V0,1)=D1(U09+IP(U0/MH(0)),V09+IP(V0/MV(0)),1)
                  LET D1(U09+U0,V09+V0,2)=D1(U09+IP(U0/MH(0)),V09+IP(V0/MV(0)),2)
               NEXT U0
            NEXT V0
            !---
         NEXT U09
      NEXT V09
   END IF
   ! END SUB
   !------ JPG 色空間 ----------------------------
   ! | Y |   | 0.2990   +0.5870   +0.1140  | | R |
   ! |B-Y| = |-0.1687   -0.3313   +0.5000  | | G |
   ! |R-Y|   | 0.5000   -0.4187   -0.0813  | | B |
   !
   ! | R |   | 1         0        +1.40200 | | Y |
   ! | G | = | 1        -0.34414  -0.71414 | |B-Y|
   ! | B |   | 1        +1.77200   0       | |R-Y|
   !----------------------------------------------
   ! SUB DSPYbr
   FOR V0=0 TO DY-1
      FOR U0=0 TO DX-1
         LET w1=IP(D1(U0,V0,0)                      +1.40200*D1(U0,V0,2)) !R
         LET w2=IP(D1(U0,V0,0) -0.34414*D1(U0,V0,1) -0.71414*D1(U0,V0,2)) !G
         LET w3=IP(D1(U0,V0,0) +1.77200*D1(U0,V0,1))                      !B
         IF w1< 0 THEN
            LET w1=0
         ELSEIF 255< w1 THEN
            LET w1=255
         END IF
         IF w2< 0 THEN
            LET w2=0
         ELSEIF 255< w2 THEN
            LET w2=255
         END IF
         IF w3< 0 THEN
            LET w3=0
         ELSEIF 255< w3 THEN
            LET w3=255
         END IF
         LET D8(U0,V0)=w3*65536+w2*256+w1 !(逆)BGR
      NEXT U0
   NEXT V0
   LET w=TRUNCATE(MIN( (bmx-1)/DX,(bmy-1)/DY),1)
   IF 1< w THEN LET w=IP(w)
   IF 4< w THEN LET w=4
   PRINT "描画の倍率=";w
   MAT PLOT CELLS,IN 1,1; DX*w, DY*w :D8
END SUB

!========================
!inverse haffman Transform.
SUB IZZRL0
   LET byt=0 !!!
   CALL ROPEN ! FL$
   !---
   CALL R_BIN31(0) !A() B(i,J)L(i,J)<-- DH(), return at img.top
   PRINT right$("000"& BSTR$(byt,16),4) !!!
   PRINT "(";STR$(DX);"x";STR$(DY);
   !---
   MAT D8=ZER(DX-1,DY-1) !DSPYbr
   LET i=8*MH(0) !MCU Y.Hsize
   LET j=8*MV(0) !MCU Y.Vsize
   LET DUM=CEIL(DX/i)*i      !Uwidth=bound by MCU Y.Hsize
   LET DVM=CEIL(DY/j)*j      !Vwidth=bound by MCU Y.Vsize
   MAT D1=ZER(DUM-1,DVM-1,2) !Y=D1(,,0)  Cb=D1(,,1)  Cr=D1(,,2)
   MAT D2=ZER(DUM-1,DVM-1,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
   LET MH_=MH(0)
   LET MV_=MV(0)
   LET DU =DUM               !Uwidth=bound by MCU Y.Hsize
   LET DV_=DVM               !Vwidth=bound by MCU Y.Vsize
   LET DU8=CEIL(DX/8)*8      !Uwidth=bound by block Y.Hsize
   LET DV8=CEIL(DY/8)*8      !Vwidth=bound by block Y.Vsize
   !---
   PRINT "/ ";STR$(DU8);",";STR$(DV8);"/ ";STR$(DUM);",";STR$(DVM);")"
   CALL frame
   !---
   CALL MAIN65
   !---
   IF 0< M THEN PRINT " (";STR$(DX);"x";STR$(DY);"/";STR$(U0);",";STR$(V0);") ";debug$;" abort by ";BSTR$(M,16) !!!
   PRINT right$("000"& BSTR$(byt-2*SGN(M),16),4) !!!
   CALL R_BIN31(M) ! return at img.top, or EOI
   !---
   DO WHILE M=BVAL("DA",16) !SOS
      IF 0<=HAC(0) THEN
         LET MV(0)=1
         LET MH(0)=1
         LET DU=DU8
         LET DV_=DV8
      END IF
      CALL frame
      LET MV(0)=MV_
      LET MH(0)=MH_
      LET DU=DUM
      LET DV_=DVM
      !---
      IF Ss_<>Se_ AND M3(0)=M3(1) AND M3(1)=M3(2) THEN CALL MAIN65
      !---
      IF 0< M THEN PRINT " (";STR$(DX);"x";STR$(DY);"/";STR$(U0);",";STR$(V0);") ";debug$;" abort by ";BSTR$(M,16) !!!
      PRINT right$("000"& BSTR$(byt-2*SGN(M),16),4) !!!
      CALL R_BIN31(M) ! return at img.top
   LOOP
   CLOSE #1 ! FL$
END SUB

SUB reset0
   LET B2(0)=0 !ROUND( YDC0/DQ(0,0,QS(0)) ) !prediction YDC.( 1st.reference level)
   LET B2(1)=0 !prediction CbDC.
   LET B2(2)=0 !prediction CrDC.
   LET Hx=0  !bits stream input buffer 0~(7+8)bits, use fraction
   LET BC=0  !stored bits in Hx
   LET NA=0  !nest adr. in A()
   LET EOB=0 !counter( end_of_band)
   LET M=0
   LET ext=0
END SUB

!
Page-2 へ続く
 

エラ― メッセイジ 無しの  計算ミス ???

 投稿者:与坂  昇平  投稿日:2009年10月 6日(火)09時03分51秒
返信・引用
  t.fem - 3dimension zzzz 6 face comme theory  2 element  trial 2 mit print

プログラム  に 関して


11 x 11 matrix  を  gauss  の  掃きだし方で  解く
プログラムで
計算 途中で  tk2 7  3   から  tk2  7  11
の  間で
コンピュ―タ―の  計算ミス の様な  箇所があり
エラ― メッセイジは  出ませんでした

例えば
print  分で
tk2  7  4    -1.5 E-15  の  回答が   有りますが
手計算では  5.5 E-9
になります

後ほど  手紙で  送ります
 

Re: エラ― メッセイジ 無しの  計算ミス ???

 投稿者:白石 和夫  投稿日:2009年10月 6日(火)09時58分1秒
返信・引用
  > No.608[元記事へ]

手紙でデバッグを依頼されてもお受けすることはできませんので,
あしからずご了承ください。
 

Re: エラ― メッセイジ 無しの  計算ミス ???

 投稿者:山中和義  投稿日:2009年10月 6日(火)10時25分10秒
返信・引用
  > No.608[元記事へ]

与坂  昇平さんへのお返事です。

> 例えば
> print  分で
> tk2  7  4    -1.5 E-15  の  回答が   有りますが
> 手計算では  5.5 E-9
> になります


単精度(有効桁数8桁程度)と倍精度(有効桁数16桁程度)での計算の違いでは?
どちらも、数値計算上での理論値0(近似値)と思います。
 

Re: Rolling Cube 1の拡張

 投稿者:山中和義  投稿日:2009年10月 6日(火)11時56分22秒
返信・引用  編集済
  > No.562[元記事へ]

1→2の解法 WindowsMe、Pentium��700MHz、192MBにて、十進BASIC 2進モードで実行。
 36 手
URDLURDDLURDLURDLULDRULDRURDLLUURRDL
-1 -1 -1 -1 -1
-1  3  5  2 -1
-1  6  0  8 -1
-1  1  7  4 -1
-1 -1 -1 -1 -1

  :省略
  :

計算時間= 5440.15 秒  ≒ 1.51 時間

サンプル・プログラム  ※2進モードで実行してください。
!Rolling Cube 1 の解法

!●問題
!3×3の盤に、8個のさいころが2の目が上(他の目も同じ向き)で配置されています。
!空いているマスに転がして、すべての目が1になるようにしてください。


LET t0=TIME


PUBLIC NUMERIC xSIZE,ySIZE !盤の大きさ
LET xSIZE=3
LET ySIZE=3

PUBLIC NUMERIC M(10,10) !さいころの配置 ※数字は番号、0は空き
MAT M=ZER(ySIZE+2,xSIZE+2)
DATA -1,-1,-1,-1,-1 !-1:壁 ※番兵
DATA -1, 1, 2, 3,-1 !←←←←← ※
DATA -1, 4, 0, 5,-1
DATA -1, 6, 7, 8,-1
DATA -1,-1,-1,-1,-1
MAT READ M

FOR SY=2 TO ySIZE+1 !空白の位置 ※番兵を考慮
   LET SX=2
   DO UNTIL SX=xSIZE+1
      IF M(SY,SX)=0 THEN EXIT FOR
      LET SX=SX+1
   LOOP
NEXT SY

PUBLIC NUMERIC LIM !手数の上限 →最少手数
LET LIM=36 !←←←←← ※

PUBLIC NUMERIC LVL(50) !手の記録
MAT LVL=ZER

LET L=0 !0手目
CALL backtrack(L,-1,SY,SX) !※番兵を考慮


PRINT "計算時間=";TIME-t0;"秒"

END


EXTERNAL SUB backtrack(L,D,SY,SX) !1手ずつ打っていき、行き詰まれば元に戻ってやり直す

DECLARE EXTERNAL SUB Dice.rolling !外部手続き、変数の定義
DECLARE EXTERNAL NUMERIC Dice.T1(),Dice.T2(),Dice.T3(),Dice.T4()
DECLARE EXTERNAL NUMERIC Dice.T5(),Dice.T6(),Dice.T7(),Dice.T8()
DECLARE EXTERNAL NUMERIC Dice.DX(),Dice.DY()


DIM TT(6) !1つ前の保存
SUB ROTATEandMOVE(d) !さいころを回転移動する
   SELECT CASE id !回転
   CASE 1
      MAT TT=T1
      CALL rolling(d,T1)
   CASE 2
      MAT TT=T2
      CALL rolling(d,T2)
   CASE 3
      MAT TT=T3
      CALL rolling(d,T3)
   CASE 4
      MAT TT=T4
      CALL rolling(d,T4)
   CASE 5
      MAT TT=T5
      CALL rolling(d,T5)
   CASE 6
      MAT TT=T6
      CALL rolling(d,T6)
   CASE 7
      MAT TT=T7
      CALL rolling(d,T7)
   CASE 8
      MAT TT=T8
      CALL rolling(d,T8)
   CASE ELSE
   END SELECT

   LET M(SY,SX)=id !移動
   LET M(TY,TX)=0
END SUB
SUB RESTORE !元に戻す
   SELECT CASE id !回転
   CASE 1
      MAT T1=TT
   CASE 2
      MAT T2=TT
   CASE 3
      MAT T3=TT
   CASE 4
      MAT T4=TT
   CASE 5
      MAT T5=TT
   CASE 6
      MAT T6=TT
   CASE 7
      MAT T7=TT
   CASE 8
      MAT T8=TT
   CASE ELSE
   END SELECT

   LET M(TY,TX)=id !移動
   LET M(SY,SX)=0
END SUB


LET C=0 !枝刈り ※「残りの手数」と「目の数が一致しないさいころの数」との関係より
IF T1(3)<>1 THEN !1:目の数 ←←←←← ※
   IF T1(5)=1 THEN LET C=C+2 ELSE LET C=C+1
END IF
IF T2(3)<>1 THEN
   IF T2(5)=1 THEN LET C=C+2 ELSE LET C=C+1
END IF
IF T3(3)<>1 THEN
   IF T3(5)=1 THEN LET C=C+2 ELSE LET C=C+1
END IF
IF T4(3)<>1 THEN
   IF T4(5)=1 THEN LET C=C+2 ELSE LET C=C+1
END IF
IF T5(3)<>1 THEN
   IF T5(5)=1 THEN LET C=C+2 ELSE LET C=C+1
END IF
IF T6(3)<>1 THEN
   IF T6(5)=1 THEN LET C=C+2 ELSE LET C=C+1
END IF
IF T7(3)<>1 THEN
   IF T7(5)=1 THEN LET C=C+2 ELSE LET C=C+1
END IF
IF T8(3)<>1 THEN
   IF T8(5)=1 THEN LET C=C+2 ELSE LET C=C+1
END IF
!C個のさいころを一致させる必要があるが、残りの手数が足りないので、不可能!!!
IF L+C>LIM THEN EXIT SUB

IF C=0 AND M(3,3)=0 THEN !完成? ※「空き」が中央
!!!IF C=0 THEN !完成? ※「空き」が中央以外も含む
   PRINT L;"手"
   FOR i=1 TO L !上限までの手順
      LET w$="LDRU" !※さいころにとっては逆となる
      LET t=LVL(i)+1
      PRINT w$(t:t);
   NEXT i
   PRINT
   MAT PRINT M; !盤の状態

   !!  LET LIM=L !上限を狭める ←←←←← ※
END IF


IF L>=LIM THEN EXIT SUB !上限まで


!!!IF L>=2 THEN !※「空き」を左下に位置付ける(3手以降) ←←←←← 1つ下のIF文に置き換える
IF D>=0 THEN !2手以降
   FOR i=D-1 TO D+1 !逆行(後ろ)を避けて、(右・前・左へ)前進する
      LET DD=MOD(i,4) !連番で方向を得る
      LET TX=SX+DX(DD+1) !「空き」の進路位置
      LET TY=SY+DY(DD+1)
      LET id=M(TY,TX) !壁、さいころの番号を得る
      IF id>0 THEN !盤内なら
         CALL ROTATEandMOVE(DD) !さいころを転がす
         LET LVL(L+1)=DD !手を記録する
         CALL backtrack(L+1,DD,TY,TX) !次へ
         CALL RESTORE !元に戻す
      END IF
   NEXT i

ELSE
   FOR i=3 TO 0 STEP -1 !※「空き」を左下に位置付ける ←←←←← 1つ下のFOR文に置き換える(そのままでも可)
   !!!FOR i=0 TO 3 !全方向 ※連番
      LET TX=SX+DX(i+1) !「空き」の進路位置
      LET TY=SY+DY(i+1)
      LET id=M(TY,TX) !壁、さいころの番号を得る
      IF id>0 THEN !盤内なら
         CALL ROTATEandMOVE(i) !さいころを転がす
         LET LVL(L+1)=i !手を記録する
         CALL backtrack(L+1,i,TY,TX) !次へ
         CALL RESTORE !元に戻す
         !!!EXIT FOR !※「空き」を左下に位置付ける ←←←←← 削除する
      END IF
   NEXT i

END IF

END SUB


MODULE Dice !さいころを転がす

!置換(Permutation)の計算

SHARE NUMERIC U(6),D(6),L(6),R(6) !置換
!    1,2,3,4,5,6
DATA 3,2,6,4,1,5 !上 ※正面を上面にする(図での水平軸)回転
DATA 1,3,4,5,2,6 !左
MAT READ U
CALL PermInverse(U,D)
MAT READ L
CALL PermInverse(L,R)

SHARE NUMERIC UU(6,6),DD(6,6),LL(6,6),RR(6,6) !置換行列
CALL PermToMatrix(U,UU)
CALL PermToMatrix(D,DD)
CALL PermToMatrix(L,LL)
CALL PermToMatrix(R,RR)

EXTERNAL SUB PermInverse(A(), iA()) !逆置換 ※iAはA以外の配列を指定すること
   FOR i=1 TO UBOUND(A)
      LET iA(A(i))=i
   NEXT i
END SUB
!EXTERNAL SUB PermMultiply(A(),B(), AB()) !積AB ※ABはA以外かつB以外の配列を指定すること
!   FOR i=1 TO UBOUND(A)
!      LET AB(i)=A(B(i)) !※合成写像(AB)(i)=A(B(i))
!   NEXT i
!END SUB
EXTERNAL SUB PermToMatrix(A(), M(,)) !置換の行列を得る
   MAT M=ZER
   FOR i=1 TO UBOUND(A)
      LET M(i,A(i))=1
   NEXT i
END SUB
!---------- ↑↑↑↑↑ ----------


!展開図の配置と面番号(配列の添え字)との関係
! □    後    1
!□□□□ 左上右下 2345
! □    正    6

PUBLIC NUMERIC T1(6),T2(6),T3(6),T4(6),T5(6),T6(6),T7(6),T8(6) !8個のさいころ
DATA   1 !目の配置 ※展開図参照
DATA 4,2,3,5
DATA   6
MAT READ T1
MAT T2=T1 !同じ向き
MAT T3=T1
MAT T4=T1
MAT T5=T1
MAT T6=T1
MAT T7=T1
MAT T8=T1

PUBLIC SUB rolling
EXTERNAL SUB rolling(i,T()) !さいころを回転させる
!DIM TT(6) !作業用

   SELECT CASE i !※DX(),DY()参照
   CASE 0
   !CALL PermMultiply(T,L,TT) !※さいころにとっては逆となる
      MAT T=T*LL !※さいころにとっては逆となる
   CASE 1
   !CALL PermMultiply(T,D,TT)
      MAT T=T*DD
   CASE 2
   !CALL PermMultiply(T,R,TT)
      MAT T=T*RR
   CASE 3
   !CALL PermMultiply(T,U,TT)
      MAT T=T*UU
   CASE ELSE
   END SELECT

   !MAT T=TT
END SUB
!---------- ↑↑↑↑↑ ----------


PUBLIC NUMERIC DX(4),DY(4) !4近傍 ※反時計まわりの連番 右:0、上:1、左:2、下:3
DATA 1, 0,-1,0
DATA 0,-1, 0,1
MAT READ DX
MAT READ DY

END MODULE
 

Rolling Cube 1の最短手順

 投稿者:GAI  投稿日:2009年10月 6日(火)16時59分55秒
返信・引用  編集済
  左右対称、上下対称、回転対称の他に、“前後対称”(手順を逆順にして同じになるもの)も除いて対称形を削除した場合の数。


中心空き他全部裏→中心空き他全部表:36手、1通り
↓←↑→↓→↑←↑→↓←↑←↓↓→↑→↓←↑←↓→↑→↓←←↑→→↑←↓

中心空き他全部裏→空き位置問わず全部表:34手、3通り
↓←↑↑→↓←↓→↑←↓→↑→↑←←↓→↓→↑←↑←↓↓→↑←↑→→
↓←↑↑→↓←↓→↑→↑←↓←↓→→↑←↑←↓→↑←↓↓→↑←↑→→
↓←↑↑→↓→↑←↓←↓→↑←↓→→↑←↑←↓→↑←↓↓→↑←↑→→

中心空き他全部手前向き→中心空き他全部表:36手、10通り
←↑→→↓←←↓→↑↑→↓↓←↑→↓←↑←↓→↑←↑→↓→↑←↓→↓←↑
←↑→↓←↓→↑→↓←↑←↓→↑↑←↓→→↓←←↑↑→↓←↑→↓→↑←↓
←↓→↑←↑→→↓↓←↑→↑←←↓↓→↑←↑→↓←↓→→↑↑←↓←↑→↓
←↓→↑←↑→↓←↓→↑←↓→↑→↓←↑→↑←↓←↑→↓←↑→↓←↑→↓
←↓→↑←↑→↓←↓→↑←↓→↑→↓←↑→↑←↓←↑→↓→↑←↓→↑←↓
←↓→↑←↓→↑←↑→↓→↑←←↓→→↓←←↑→→↑←↓←↑→↓→↑←↓
←↓→↑←↓→↑←↑→↓→↑←←↓→→↓←↑→↑←↓↓←↑↑→↓→↑←↓
←↓→↑←↓→↑←↑→↓→↑←←↓→→↑←↓→↓←←↑→→↑←↓←↑→↓
←↓→↑←↓→↑←↑→↓→↑←←↓→→↑←↓→↓←↑→↑←↓↓←↑↑→↓
↑←↓→↑←↓↓→↑←↓→↑←↓→↑→↓←↑→↓←↑←↓→→↑↑←←↓→

中心空き他全部前向き→空き位置問わず全部表:27手、1通り
←↓→↑←↑→↓←↓→↑←↓→↑→↓←↑→↑←↓←↑→

の結果が手に入りました。
 

Re: 有効桁数と精度について

 投稿者:kikiriri  投稿日:2009年10月 6日(火)17時45分6秒
返信・引用
  > No.602[元記事へ]

山中和義さんへのお返事です。

山中和義さんへ

  kikiririより

  倍精度、単制度以外で、有効桁数を考慮して計算する方法を知りませんか
 またそのようなプログラムを知りませんか。
 

ステップ動作で、1変数の内容を追う時

 投稿者:SECOND  投稿日:2009年10月 6日(火)17時55分26秒
返信・引用
  ステップ動作で、1変数の内容を追う時、ステップ度にスクロールされ、
何処へ行ったか見失いますので、スクロール位置をリストアー するよう
にして頂けないでしょうか。
 

Re: ステップ動作で、1変数の内容を追う時

 投稿者:白石 和夫  投稿日:2009年10月 6日(火)18時11分18秒
返信・引用
  > No.614[元記事へ]

デバッグウィンドウのサイズは可変なので,すべての変数が一覧できる程度にまで拡大しておくことで対応できると思います。変数の数が多いとむずかしいかもしれませんが。
 

超不思議

 投稿者:GAI  投稿日:2009年10月 7日(水)09時30分50秒
返信・引用
  プログラムとはまったく関係ないかもしれませんが、近頃次のことを知りました。
逆立ちゴマというものを見られたことがあると思いますが、私はコマが自然と逆立ちすることが不思議な現象であるとばかり思っておりましたが、このコマの本 当の不思議さは、もし右回りに回転をかけてコマを回しだし、逆立ちすれば当然上からは左回りに回転しておかなければならないはずですが、逆立ちした状態で もなんと右回りに回転している!!!
これって超不思議ではないですか?
 

Re: 超不思議

 投稿者:山中和義  投稿日:2009年10月 7日(水)10時41分35秒
返信・引用
  > No.616[元記事へ]

GAIさんへのお返事です。

指でこまに右回りの回転をかけた場合(赤の矢印)、
こまの軸部分(黒い部分)にも右回りの回転(緑の矢印)がかかります。
逆立ちは、こまが傾くことで起きます。(中央の絵:こまの軸部分で回転していない)
この指の回転は、こまが傾いたり、逆立ちしても変わりません。

逆立ちの前後では、こまの軸部分を基準に考えれば逆転していることになります。
 

Re: 有効桁数と精度について

 投稿者:山中和義  投稿日:2009年10月 7日(水)14時24分55秒
返信・引用
  > No.613[元記事へ]

kikiririさんへのお返事です。

>   倍精度、単制度以外で、有効桁数を考慮して計算する方法を知りませんか
>  またそのようなプログラムを知りませんか。

よくわかりませんが、、、このことですか?

12.34/10*10の計算

!##.##形式の固定小数点数
a=12.34 !12.34
a=a/10 !12.34/10.00=01.23
a=a*10 !01.23*10.00=12.30

!#.###形式の浮動小数点数
a=12.34 !1.234*10^1
a=a/10 !(1.234*10^1)/(1.000*10^1)=1.234*10^0
a=a*10 !(1.234*10^0)*(1.000*10^1)=1.234*10^1
 

早速のご返信ありがとうございます(すみませんがまた編集させていただきました)

 投稿者:kikiriri  投稿日:2009年10月 7日(水)16時06分40秒
返信・引用  編集済
  山中和義さんへ

  kikiririより


早速のご返信ありがとうございます。

浮動小数点数のことだと思います。

どちらもいつどんな風に利用するか使い分け方がわかりません。
固定小数点数こんなときに使う。(こんな意味がある)
浮動小数点数こんなときに使う。(こんな意味がある)

分かりやすいご助言お待ちます。
 

Re: 早速のご返信ありがとうございます(すみませんがまた編集させていただきました)

 投稿者:島村1243  投稿日:2009年10月 8日(木)10時54分21秒
返信・引用
  > No.619[元記事へ]

kikiririさんへのお返事です。

> 山中和義さんへ
>
>   kikiririより
>
>
> 早速のご返信ありがとうございます。
>
> 浮動小数点数のことだと思います。
>
> どちらもいつどんな風に利用するか使い分け方がわかりません。
> 固定小数点数こんなときに使う。(こんな意味がある)
> 浮動小数点数こんなときに使う。(こんな意味がある)
>
> 分かりやすいご助言お待ちます。

まずはネット検索したらどうでしょうか?
例えば下記が検索で出ますよ。
http://ja.wikipedia.org/wiki/%E5%9B%BA%E5%AE%9A%E5%B0%8F%E6%95%B0%E7%82%B9%E6%95%B0
 

エラ― メッセイジの 出ない  エラ―

 投稿者:与坂  昇平  投稿日:2009年10月 8日(木)12時08分17秒
返信・引用
  前の  投稿で
マトリックスを  ガウスの  掃きだし方で  解いた所
正確には  5.5 E-9   を  プログラムは
-1.5E-15  と  表示し  そのまま
計算を  つずけて   オカシナ  回答が  出ました

そこで
計算途中の   数値
TK(a)  に  以下のように  条件を  付け加えました

  if  abs(TK(a))<0.000001    then  goto 10  else  goto 20

      10
           TK(a)=0.000000000000000000000000000000

      20

それで
この プログラムは   一応  正確な  答えを  出しました


しかし
時々   計算された 数値に  -34298675431657
等と  一目に  プログラムの  暴走と  感じられる
数値が  計算されます

この場合
どの様に  プログラムを  止めるのでしょうか ???

例えば

   if  ABS(TK(a)>100000000  then  goto  30  else  goto 40

      30
          print " error "
          input xxx

      40



例えば  プログラムで  ロボットを  動かす場合
ロボットは   プログラムの  ミスが  解りませんので
異常の時は  止める  場合です
 

Re: エラ― メッセイジの 出ない  エラ―

 投稿者:白石 和夫  投稿日:2009年10月 8日(木)12時38分9秒
返信・引用
  > No.621[元記事へ]

BASICプログラムをを終了させる命令は
STOP
です。
STOP文は単純実行文なので,
IF ○○○ THEN STOP
のようにIF文と組み合わせても使えます。
 

Re: エラ― メッセイジの 出ない  エラ―

 投稿者:山中和義  投稿日:2009年10月 8日(木)12時39分35秒
返信・引用
  > No.621[元記事へ]

与坂  昇平さんへのお返事です。

> 時々   計算された 数値に  -34298675431657
> 等と  一目に  プログラムの  暴走と  感じられる
> 数値が  計算されます

ピボット選択は正しく行っていますか。
0に近い小さい値で各係数を割ると誤差が大きくなっていきます。


> この場合
> どの様に  プログラムを  止めるのでしょうか ???

それでいいと思います。


連立方程式を掲載していただければ、こちらでも検証できると思いますが、、、?
 

良いホームページのご紹介ありがとうございました。

 投稿者:kikiriri  投稿日:2009年10月 8日(木)16時41分8秒
返信・引用  編集済
  > No.620[元記事へ]

島村1243さんへのお返事です。

島村1243さんへ

  kikiririより

 良いホームページの紹介ありがとうございました。

早速、関連項目もまた、印刷して読んでいます。ご助言ありがとうございました。
 

良いホームページのご紹介ありがとうございました。NO2

 投稿者:kikiriri  投稿日:2009年10月 8日(木)17時46分46秒
返信・引用  編集済
  > No.624[元記事へ]

島村1243さんへ

  kikiririより

> 島村1243さんへのお返事です。
>
> 島村1243さんへ
>
>   kikiririより
>
>  良いホームページの紹介ありがとうございました。
>
> 早速、関連項目もまた、印刷して読んでいます。ご助言ありがとうございました。


関連項目ですが、「有効数字」
(中には、疑問を感じる点もありますが)12000だけを見れば、有効数字は1桁から5桁まで
のいずれにも受けとれるため。

のところで、12までは確定なので2桁から5桁までではないか。

またもや関連項目ですが、「正確度と精度」
矢が、的に向かって中心から同じ距離に当たったなら、

”高正確度だが低精度”

また矢が的からの距離が少しずれてても隣り合うくらい近い点に当たったなら

”高精度だが、低正確度”

など勉強になることもありました。


以上付け足し見たいですが、すみません。ありがとうございました。
 

エラー報告

 投稿者:五十嵐真人  投稿日:2009年10月 9日(金)20時16分47秒
返信・引用
  十進BASICのプログラムを有理数モードで実行した時に以下のようなエラーが発生しました。

1、プログラム

OPTION ARITHMETIC RATIONAL
LET n=1987829
!1987829は素数。したがってMOD(3^(n-1),n)=1のはずです。
PRINT MOD(3^(n-1),n)
END

2、実行結果

836640 !本来はフェルマーの小定理より1となるはずです。

べき指数は-2147483647〜2147483647の範囲の整数ならよいはずなのですが、

>
有理数モード
多桁の有理数の計算ができます。
計算結果は仮分数形で表示します。
ただし,入力やDATA文にこの形式は使えません。
べき乗演算では,べき指数は-2147483647〜2147483647の範囲の整数に限定されます。
 

Re: エラー報告

 投稿者:白石 和夫  投稿日:2009年10月10日(土)07時53分43秒
返信・引用
  > No.626[元記事へ]

ご報告ありがとうございます。
調べてみます。
 

Re: エラー報告

 投稿者:山中和義  投稿日:2009年10月10日(土)12時16分13秒
返信・引用  編集済
  > No.627[元記事へ]

次のプログラムでは、PRINT文で表示せずエラーとなります。
LET n=1987829
LET p=3^(n-1)
LET t=p-INT(p/n)*n
PRINT -1 !trace
PRINT t !←←←←← ここで実行時内部エラーが発生する
LET t=MOD(p,n)
PRINT -2 !trace
PRINT t
END

実行結果
-1
LET n=1987829
LET p=3^(n-1)
LET t=MOD(p,n)
PRINT -1 !trace
PRINT t !←←←←← 表示される数値が正しくない
LET t=p-INT(p/n)*n
PRINT -2 !trace
PRINT t !←←←←← ここで実行時内部エラーが発生する
END

実行結果
-1
 836640
-2
 

Re: エラー報告

 投稿者:白石 和夫  投稿日:2009年10月10日(土)20時56分29秒
返信・引用  編集済
  > No.627[元記事へ]

原因はアセンブラでjecxzとすべきところがjcxzになっていたことでした。
近日中に修正版を作ります。
 

Rolling Cube 1の研究

 投稿者:GAI  投稿日:2009年10月12日(月)06時35分17秒
返信・引用  編集済
  ある方の研究によると、最初のさいころと空き地の初期設定は任意(さいころの目と向きは勝手に選べ、空き地も中央に限らずどこでもOK)
であったとしても、最低49手以内で最終形(上面に1の目が揃い、中央が空き地)に到達可能になるそうです。
そこで、初期条件を入力したら、最終形までの最短手順を見つけ出せるプログラムを作って頂けませんか?
以前、山中さんが掲載されていた1→2の経路探索プログラムをいじればいいような気もするのですが、まだ自分では手直し箇所がわかりませんのでよろしくお願いいたします。
 

Re: Rolling Cube 1の研究

 投稿者:山中和義  投稿日:2009年10月12日(月)09時17分1秒
返信・引用  編集済
  > No.630[元記事へ]

GAIさんへのお返事です。

サンプル・プログラム  ※2進モードで実行してください。
!Rolling Cube 1 の解法

!●問題
!3×3の盤に、8個のさいころが1の目が上(他の目も同じ向き)で配置されています。
!空いているマスに転がして、すべての目が6になるようにしてください。


LET t0=TIME


PUBLIC NUMERIC xSIZE,ySIZE !盤の大きさ
LET xSIZE=3
LET ySIZE=3

!●さいころの盤上の配置を変更する場合

PUBLIC NUMERIC M(10,10) !さいころの配置 ※数字は番号、0は空き
MAT M=ZER(ySIZE+2,xSIZE+2)
DATA -1,-1,-1,-1,-1 !-1:壁 ※番兵
DATA -1, 1, 2, 3,-1 !←←←←← ※
DATA -1, 4, 0, 5,-1
DATA -1, 6, 7, 8,-1
DATA -1,-1,-1,-1,-1
MAT READ M
LET SY=3 !空白の位置 ※番兵を考慮
LET SX=3

!●手数の上限を変更する場合

PUBLIC NUMERIC LIM !手数の上限 →最少手数
LET LIM=49 !←←←←← ※
PUBLIC NUMERIC LVL(50) !手の記録
MAT LVL=ZER

LET L=0 !0手目
CALL backtrack(L,-1,SY,SX) !※番兵を考慮


PRINT "計算時間=";TIME-t0;"秒"

END


EXTERNAL SUB backtrack(L,D,SY,SX) !1手ずつ打っていき、行き詰まれば元に戻ってやり直す

DECLARE EXTERNAL SUB Dice.rolling !外部手続き、変数の定義
DECLARE EXTERNAL NUMERIC Dice.T1(),Dice.T2(),Dice.T3(),Dice.T4()
DECLARE EXTERNAL NUMERIC Dice.T5(),Dice.T6(),Dice.T7(),Dice.T8()
DECLARE EXTERNAL NUMERIC Dice.DX(),Dice.DY()


DIM TT(6)
SUB ROTATEandMOVE(d) !さいころを回転移動する
   SELECT CASE id !回転
   CASE 1
      MAT TT=T1
      CALL rolling(d,T1)
   CASE 2
      MAT TT=T2
      CALL rolling(d,T2)
   CASE 3
      MAT TT=T3
      CALL rolling(d,T3)
   CASE 4
      MAT TT=T4
      CALL rolling(d,T4)
   CASE 5
      MAT TT=T5
      CALL rolling(d,T5)
   CASE 6
      MAT TT=T6
      CALL rolling(d,T6)
   CASE 7
      MAT TT=T7
      CALL rolling(d,T7)
   CASE 8
      MAT TT=T8
      CALL rolling(d,T8)
   CASE ELSE
   END SELECT

   LET M(SY,SX)=id !移動
   LET M(TY,TX)=0
END SUB
SUB RESTORE !元に戻す
   SELECT CASE id !回転
   CASE 1
      MAT T1=TT
   CASE 2
      MAT T2=TT
   CASE 3
      MAT T3=TT
   CASE 4
      MAT T4=TT
   CASE 5
      MAT T5=TT
   CASE 6
      MAT T6=TT
   CASE 7
      MAT T7=TT
   CASE 8
      MAT T8=TT
   CASE ELSE
   END SELECT

   LET M(TY,TX)=id !移動
   LET M(SY,SX)=0
END SUB


LET C=0 !枝刈り ※「残りの手数」と「不一致なさいころの数」との関係より
IF T1(3)<>1 THEN LET C=C+1 !1:目の数 ←←←←← ※
IF T2(3)<>1 THEN LET C=C+1
IF T3(3)<>1 THEN LET C=C+1
IF T4(3)<>1 THEN LET C=C+1
IF T5(3)<>1 THEN LET C=C+1
IF T6(3)<>1 THEN LET C=C+1
IF T7(3)<>1 THEN LET C=C+1
IF T8(3)<>1 THEN LET C=C+1
IF L+C>LIM THEN EXIT SUB !不可能!!!

IF C=0 AND M(3,3)=0 THEN !完成? ※「空き」が中央
!!!IF C=0 THEN !完成? ※「空き」が中央以外も含む
   PRINT L;"手"
   FOR i=1 TO L !上限までの手順
      SELECT CASE LVL(i)
      CASE 0
         PRINT "L"; !※さいころにとっては逆となる
      CASE 1
         PRINT "D";
      CASE 2
         PRINT "R";
      CASE 3
         PRINT "U";
      CASE ELSE
      END SELECT
   NEXT i
   PRINT
   MAT PRINT M; !盤の状態

   LET LIM=L !上限を狭める
END IF


IF L>=LIM THEN EXIT SUB !上限まで

!!!IF L>=2 THEN !※「空き」を左下に位置付ける(3手以降) ←←←←← 1つ下のIF文に置き換える
IF D>=0 THEN !2手以降
   FOR i=D-1 TO D+1 !逆行(後ろ)を避けて、(右・前・左へ)前進する
      LET DD=MOD(i,4) !連番で方向を得る
      LET TX=SX+DX(DD+1) !「空き」の進路位置
      LET TY=SY+DY(DD+1)
      LET id=M(TY,TX) !壁、さいころの番号を得る
      IF id>0 THEN !盤内なら
         CALL ROTATEandMOVE(DD) !さいころを転がす
         LET LVL(L+1)=DD !手を記録する
         CALL backtrack(L+1,DD,TY,TX) !次へ
         CALL RESTORE !元に戻す
      END IF
   NEXT i

ELSE
   FOR i=3 TO 0 STEP -1 !※「空き」を左下に位置付ける ←←←←← 1つ下のFOR文に置き換える(そのままでも可)
   !!!FOR i=0 TO 3 !全方向 ※連番
      LET TX=SX+DX(i+1) !「空き」の進路位置
      LET TY=SY+DY(i+1)
      LET id=M(TY,TX) !壁、さいころの番号を得る
      IF id>0 THEN !盤内なら
         CALL ROTATEandMOVE(i) !さいころを転がす
         LET LVL(L+1)=i !手を記録する
         CALL backtrack(L+1,i,TY,TX) !次へ
         CALL RESTORE !元に戻す
         !!!EXIT FOR !※「空き」を左下に位置付ける ←←←←← 削除する
      END IF
   NEXT i

END IF

END SUB


MODULE Dice !さいころを転がす

!置換(Permutation)の計算

SHARE NUMERIC U(6),D(6),L(6),R(6) !置換
!    1,2,3,4,5,6
DATA 3,2,6,4,1,5 !上 ※正面を上面にする(図での水平軸)回転
DATA 1,3,4,5,2,6 !左
MAT READ U
CALL PermInverse(U,D)
MAT READ L
CALL PermInverse(L,R)

EXTERNAL SUB PermInverse(A(), iA()) !逆置換 ※iAはA以外の配列を指定すること
   FOR i=1 TO UBOUND(A)
      LET iA(A(i))=i
   NEXT i
END SUB
EXTERNAL SUB PermMultiply(A(),B(), AB()) !積AB ※ABはA以外かつB以外の配列を指定すること
   FOR i=1 TO UBOUND(A)
      LET AB(i)=A(B(i)) !※合成写像(AB)(i)=A(B(i))
   NEXT i
END SUB
!---------- ↑↑↑↑↑ ----------

!●さいころの目の配置(向き)を変更する場合

!展開図の配置と面番号(配列変数T1〜T8の添え字に対応)との関係
! □    後    1
!□□□□ 左上右下 2345
! □    正    6
PUBLIC NUMERIC T1(6),T2(6),T3(6),T4(6),T5(6),T6(6),T7(6),T8(6) !8個のさいころ
DATA   5 !目の配置 ※展開図参照
DATA 4,1,3,6
DATA   2
MAT READ T1

DATA   5
DATA 4,6,3,1
DATA   2
MAT READ T2

DATA   5
DATA 4,1,3,6
DATA   2
MAT READ T3

DATA   5
DATA 4,6,3,1
DATA   2
MAT READ T4

DATA   5
DATA 4,6,3,1
DATA   2
MAT READ T5

DATA   5
DATA 4,1,3,6
DATA   2
MAT READ T6

DATA   5
DATA 4,6,3,1
DATA   2
MAT READ T7

DATA   5
DATA 4,1,3,6
DATA   2
MAT READ T8
PUBLIC SUB rolling
EXTERNAL SUB rolling(i,T()) !さいころを回転させる
   DIM TT(6) !作業用

   SELECT CASE i !※DX(),DY()参照
   CASE 0
      CALL PermMultiply(T,L,TT) !※さいころにとっては逆となる
   CASE 1
      CALL PermMultiply(T,D,TT)
   CASE 2
      CALL PermMultiply(T,R,TT)
   CASE 3
      CALL PermMultiply(T,U,TT)
   CASE ELSE
   END SELECT

   MAT T=TT
END SUB
!---------- ↑↑↑↑↑ ----------


PUBLIC NUMERIC DX(4),DY(4) !4近傍 ※反時計まわりの連番 右:0、上:1、左:2、下:3
DATA 1, 0,-1,0
DATA 0,-1, 0,1
MAT READ DX
MAT READ DY

END MODULE
 

有効数字(有効桁数)の計算方法

 投稿者:山中和義  投稿日:2009年10月12日(月)10時12分9秒
返信・引用
  精度を落とさない計算方法を検討します。
電卓の機能と同等な関数を定義して、シミュレーションしてみました。
!有効数字(有効桁数)の計算方法
!参考サイト http://ja.wikipedia.org/wiki/%E6%9C%89%E5%8A%B9%E6%95%B0%E5%AD%97

!参考サイト http://hp.vector.co.jp/authors/VA008683/QA_JISROUND.htm
FUNCTION ROUND10(x,n) !最近接偶数への丸めの方法で、xを小数点以下n桁に丸める
   LET x=x*10^n
   IF MOD(x,1)<0.5 THEN
      LET x=INT(x)
   ELSEIF MOD(x,1)>0.5 THEN
      LET x=CEIL(x)
   ELSEIF MOD(INT(x),2)=0 THEN
      LET x=INT(x)
   ELSE
      LET x=CEIL(x)
   END IF
   LET ROUND10=x/10^n
END FUNCTION

!小数点以下桁数固定 FIX(数値,桁数)
DEF FIX(x,n)=ROUND10(x,n)
!DEF FIX(x,n)=ROUND(x,n) !=INT(x*10^n+0.5)/10^n
!DEF FIX(x,n)=TRUNCATE(x,n) !=IP(x*10^n)/10^n

FUNCTION SCI(x,n) !有効桁数指定 SCI(数値,桁数)
   LET m=0
   IF x>1 THEN !##.#なら
      DO UNTIL ABS(x)<1 !0.###形式へ
         LET x=x/10
         LET m=m+1
      LOOP
      LET SCI=FIX(x,n)*10^m !※JIS Z8401『数値の丸め方』、単純な四捨五入、切捨てなど
   ELSE !0.00###なら
      DO UNTIL ABS(x)>=1 !#.##形式へ
         LET x=x*10
         LET m=m+1
      LOOP
      LET SCI=FIX(x,n-1)/10^m
   END IF
   !PRINT "x=";x; "m=";m !debug
END FUNCTION


!例 12.3+50*0.650
PRINT FIX(12.3 + SCI(50*0.650,2), 0) !2=50の有効桁数、0=50の有効桁位置
PRINT 12.3+50*0.650 !べた
PRINT


!例 ( 2.234 * 5.67815 + 100.9049 ) * 4.60
PRINT SCI(FIX( SCI(2.234*5.67815,4) + 100.9049, 2) * 4.60, 3) !毎回丸めると精度が落ちる場合がある
PRINT SCI(FIX( SCI(2.234*5.67815,5) + 100.9049, 3) * 4.60, 3) !そこで有効数字+1桁で計算を進める
PRINT ( 2.234 * 5.67815 + 100.9049 ) * 4.60
PRINT


!例 8桁関数電卓のシミュレーション ※HPはJIS丸め、シャープとカシオは四捨五入

PRINT SCI(2+5E-8,8) !JIS Z8401『数値の丸め方』 2.0000000
PRINT SCI(2+5.1E-8,8) !2.0000001
PRINT SCI(5.0000002*5.0000003,8) !25.000003
PRINT 5.0000002*5.0000003
PRINT SCI(5.0000001*5,8) !25.000000 ※2進モードではNG
PRINT 5.0000001*5


END
 

MOD関数は10進以外は使えない?

 投稿者:島村1243  投稿日:2009年10月12日(月)11時28分33秒
返信・引用
  十進BASIC-7.3.5を使わせて頂いています。
下記プログラムをツールボタンで複素数モードと2進モードに変更(特別な意味は
なし)してRUNしたら、螺旋軌道を描くボールの位置(丸印)と半径線の描画がさ
れませんでした。10進モードでは正常です。1000桁モードは「cos関数をサポート
しない」と言うメッセージが出ます。

ボール位置と半径線の描画タイミングは、MOD関数を使って判断しているので、この関数は10進モード専用関数かな?と思いましたが、そうなのでしょうか。

SET WINDOW -25,5,-15,15

SET POINT STYLE 4

!DRAW grid

LET ydo=-20

LET xdo=-60

LET zdo=75

LET hrad=PI/180

LET xrad=xdo*hrad

LET yrad=ydo*hrad

LET zrad=zdo*hrad

LET R=8

LET f=0.1

LET w=2*PI*f

LET vz=0.6



CALL henkan(10,0,0,xrad,yrad,zrad,x3_,y3_,z3_)

PLOT LINES:0,0;x3_,y3_

CALL henkan(-10,0,0,xrad,yrad,zrad,x3_,y3_,z3_)

PLOT LINES:0,0;x3_,y3_



SET LINE COLOR "red"

CALL henkan(0,10,0,xrad,yrad,zrad,x3_,y3_,z3_)

PLOT LINES:0,0;x3_,y3_

CALL henkan(0,-10,0,xrad,yrad,zrad,x3_,y3_,z3_)

PLOT LINES:0,0;x3_,y3_



SET LINE COLOR "blue"

CALL henkan(0,0,28,xrad,yrad,zrad,x3_,y3_,z3_)

PLOT LINES:0,0;x3_,y3_



SET LINE COLOR "green"

CALL henkan(r,0,0,xrad,yrad,zrad,x3_,y3_,z3_)

FOR t=0 TO 10 STEP 0.05

   LET x=r*COS(w*t)

   LET y=r*SIN(w*t)

   LET z=0

   CALL henkan(x,y,z,xrad,yrad,zrad,x3,y3,z3)

   PLOT LINES:x3_,y3_;x3,y3

   LET x3_=x3

   LET y3_=y3

NEXT T



SET LINE COLOR "black"

FOR t=0 TO 41 STEP 0.05

   LET x=r*COS(w*t)

   LET y=r*SIN(w*t)

   LET z=vz*t

   CALL henkan(x,y,z,xrad,yrad,zrad,x3,y3,z3)

   PLOT LINES:x3_,y3_;x3,y3

   LET x3_=x3

   LET y3_=y3

   LET cnt=MOD(t,0.4)

   IF cnt=0 THEN

      LET x=0

      LET y=0

      CALL henkan(x,y,z,xrad,yrad,zrad,x0_,y0_,z0_)

      PLOT LINES:x0_,y0_;x3_,y3_

      PLOT POINTS:x3_,y3_

   END IF

NEXT T

END



EXTERNAL SUB henkan(x,y,z,xa,ya,za,x3,y3,z3)

LET x1=x*COS(ya)+z*SIN(ya)

LET y1=y

LET z1=-x*SIN(ya)+z*COS(ya)

LET x2=x1

LET y2=y1*COS(xa)-z1*SIN(xa)

LET z2=y1*SIN(xa)+z1*COS(xa)

LET x3=x2*COS(za)-y2*SIN(za)

LET y3=x2*SIN(za)+y2*COS(za)

LET z3=z2

END SUB
 

Re: MOD関数は10進以外は使えない?

 投稿者:白石 和夫  投稿日:2009年10月12日(月)11時50分18秒
返信・引用  編集済
  > No.633[元記事へ]

2進モードで
FOR t=0 TO 41 STEP 0.05
とすると誤差が発生します。

  IF cnt=0 THEN
のところを
  IF ABS(cnt)<=0.01 THEN
と変えてみたらいかがでしょうか。

なお,2進モードでは,0.05,0.4のいずれも誤差を持ちます。
2進モードで誤差を避けたいときは,0.5,0.25,0.125,0.0625など,
分数にしたとき分母が2のべきになる数を選んでください。
 

Re: MOD関数は10進以外は使えない?

 投稿者:島村1243  投稿日:2009年10月12日(月)17時22分11秒
返信・引用
  > No.634[元記事へ]

白石 和夫さんへのお返事です。

> 2進モードで
> FOR t=0 TO 41 STEP 0.05
> とすると誤差が発生します。
>
>   IF cnt=0 THEN
> のところを
>   IF ABS(cnt)<=0.01 THEN
> と変えてみたらいかがでしょうか。
>
> なお,2進モードでは,0.05,0.4のいずれも誤差を持ちます。
> 2進モードで誤差を避けたいときは,0.5,0.25,0.125,0.0625など,
> 分数にしたとき分母が2のべきになる数を選んでください。

白石先生、ご教示有難うございました。
2進、複素数の両モードで、0.125以上にセットすると、丸と線はダブりますが描かれました。
セット値を更に小さくすると描画されない範囲が生じます。

この結果を見て、改めて10進モードの強力さ、十進BASICと命名した意味合いを実感し
ました。
 

Re: MOD関数は10進以外は使えない?

 投稿者:山中和義  投稿日:2009年10月12日(月)17時54分3秒
返信・引用
  > No.635[元記事へ]

島村1243さんへのお返事です。

> 2進、複素数の両モードで、0.125以上にセットすると、丸と線はダブりますが描かれました。
> セット値を更に小さくすると描画されない範囲が生じます。

他の言語などでは、2進計算ですので通常はこのようにコーディングします。
最後のFOR文の修正を掲載します。他の部分も同様です。
SET LINE COLOR "black"

FOR tt=0 TO 4100 STEP 5 !カウンタ変数は整数型とする ←←←←
   LET t=tt/100 !実際の値に換算する ←←←←

   LET x=r*COS(w*t)
   LET y=r*SIN(w*t)
   LET z=vz*t

   CALL henkan(x,y,z,xrad,yrad,zrad,x3,y3,z3)

   PLOT LINES:x3_,y3_;x3,y3

   LET x3_=x3
   LET y3_=y3

   LET cnt=MOD(tt,40) !←←←←
   IF cnt=0 THEN
      LET x=0
      LET y=0

      CALL henkan(x,y,z,xrad,yrad,zrad,x0_,y0_,z0_)

      PLOT LINES:x0_,y0_;x3_,y3_
      PLOT POINTS:x3_,y3_

   END IF

NEXT tt !←←←←
 

Re: MOD関数は10進以外は使えない?

 投稿者:SECOND  投稿日:2009年10月12日(月)18時54分39秒
返信・引用
  > No.633[元記事へ]

!2進レジスター・イメージの、step に出来ますか?誤差が消えます。

FOR t=0 TO 41 STEP 2^(-5 ) !0.05
  (
     )
   LET cnt=MOD(t, 2^(-5) *8 ) ! 1,2,3,,,8,,,
   IF cnt=0 THEN
 

!なぜ、こうなるのか?

 投稿者:SECOND  投稿日:2009年10月13日(火)08時07分56秒
返信・引用  編集済
  !なぜ、こうなるのか?

OPTION ARITHMETIC NATIVE
OPTION BASE 0
DIM D8(500,500)
!
SET VIEWPORT 0, 0.4, 0.6, 1
CALL sample(DX$,DY$)
LET DX=VAL(DX$)
LET DY=VAL(DY$)
MAT D8=ZER(DX,DY)
!
SET VIEWPORT 0, 1, 0, 1
SET WINDOW 0, 500, 500, 0
!
! SET COLOR MODE "NATIVE" ! ←これを入れると正常にコピーされる。
!
ASK PIXEL ARRAY (0,0) D8
MAT PLOT CELLS,IN 250,250; 450,450: D8
!
!main00
!   (
!    )
END

EXTERNAL SUB sample(DX$,DY$)
! マンデルブロー(Complex\mandelbm.bas の着色改変)
OPTION ARITHMETIC COMPLEX
SET COLOR MODE "REGULAR"
SET POINT STYLE 1
FOR n=0 TO 50
   SET COLOR MIX(    n) 0   ,0     ,n/51   !BLACK =< < BLUE
   SET COLOR MIX( 51+n) 0   ,n/51  ,1      !BLUE =< < CYAN
   SET COLOR MIX(102+n) 0   ,1     ,1-n/51 !CYAN =< < GREEN
   SET COLOR MIX(153+n) n/51,1     ,0      !GREEN =< < YELLOW
   SET COLOR MIX(204+n) 1   ,1-n/51,0      !YELLOW =< < RED
NEXT n
LET XL=-2
LET XR=.8
LET w1=XR-XL
LET w2=w1/2
SET WINDOW XL, XR,-w2,w2
ASK PIXEL SIZE(XL,-w2; XR,w2) px,py
!
FOR x=XL TO XR STEP w1/(px-1)
   FOR y=-w2-.49*w1/(py-1) TO w2 STEP w1/(py-1) !故意に(x,0)を描点の間に挟む。
      LET z=0
      FOR n=1 TO 255
         LET z=z^2+COMPLEX(x,y)
         IF 2< ABS(z) THEN
            IF n< 64 THEN SET POINT COLOR n*4 ELSE SET POINT COLOR 255
            PLOT POINTS :x,y !上下の対象プロットをしない。
            EXIT FOR
         END IF
      NEXT n
   NEXT y
NEXT x
LET DX$=STR$(px-1)
LET DY$=STR$(py-1)
END SUB

!※色指標まで、複素数になるのでしょうか。
 

Re: MOD関数は10進以外は使えない?

 投稿者:島村1243  投稿日:2009年10月13日(火)10時19分21秒
返信・引用
  > No.636[元記事へ]

山中和義さんへのお返事です。

> 他の言語などでは、2進計算ですので通常はこのようにコーディングします。
> 最後のFOR文の修正を掲載します。他の部分も同様です。
> FOR tt=0 TO 4100 STEP 5 !カウンタ変数は整数型とする ←←←←
>    LET t=tt/100 !実際の値に換算する ←←←←

山中さん、ご教示有難うございました。
カウンタ変数に正統的な型を使えば問題が無いということなんですね。
十進BASICは容易に扱えるので、基本がすっかり頭から抜けてしまいました。
 

Re: !なぜ、こうなるのか?

 投稿者:白石 和夫  投稿日:2009年10月13日(火)10時29分29秒
返信・引用  編集済
  > No.638[元記事へ]

ASK PIXEL ARRAYは,該当する色指標が存在しないと-1を代入します。
もともとの背景色(白)に対応する色指標が失われてしまったので,その部分の色指標が-1として取得されています。
ASK PIXEL ARRAY (0,0) D8
の後に
MAT PRINT D8;
を追加してみるとわかると思います。
なお,MAT PLOT CELLS は-1に出会うとその行のそれ以後の描画をサボります。(修正すべき事項かもしれません)
 

Re: MOD関数は10進以外は使えない?

 投稿者:島村1243  投稿日:2009年10月13日(火)10時30分46秒
返信・引用
  > No.637[元記事へ]

SECONDさんへのお返事です。

> !2進レジスター・イメージの、step に出来ますか?誤差が消えます。

FOR文のSTEP値も2進イメージにしなければならないとは気付きませんでした。
MOD関数が挟まれているFOR NEXT文中の2行修正のみで問題解決しました。
SECONDさん、有難うございました。
 

Re: !なぜ、こうなるのか?

 投稿者:SECOND  投稿日:2009年10月13日(火)14時00分40秒
返信・引用  編集済
  > No.640[元記事へ]

解りました、ありがとうございました。描点しない範囲を、すっかり忘れていました。
 

つづき4

 投稿者:SECOND  投稿日:2009年10月13日(火)22時40分4秒
返信・引用
  !Page-4 の始め

!========================
SUB W_BIN31
!---SOI
   CALL WRT_H("FFD8")
   !---APP0
   CALL WRT_H("FFE0")
   CALL WRT_W( 2+14)  !size
   CALL WRT_M("JFIF"& CHR$(0))
   CALL WRT_H("0101") !ver 1.1
   CALL WRT_D(1)      !0=none 1=dpi 2=dpcm
   CALL WRT_W(72)     !Xd 72 アスペクト比 IE6(no) imaging(ok)
   CALL WRT_W(72)     !Yd 72 アスペクト比
   CALL WRT_D(0)      !Xt 0
   CALL WRT_D(0)      !Yt 0
   !---DQT.Y.C
   CALL WRT_H("FFDB")
   LET W=2           !start size
   FOR J=0 TO CMO/2  !CMO=0(mono.) CMO=2(color)
      LET W=W+1+64   !+ID +QT
   NEXT J
   CALL WRT_W( W)    !size
   FOR J=0 TO CMO/2  ! CMO=0(mono.) CMO=2(color)
      CALL WRT_D(J)  !J= (0)Y.DQ (1)C.DQ
      FOR I=0 TO 63
         CALL WRT_D( DQ(U(i),V(i),J) )
      NEXT I
   NEXT J
   !---SOF0
   CALL WRT_H("FFC0")
   IF CMO=0 THEN CALL WRT_W( 11) ELSE CALL WRT_W( 17) !size
   CALL WRT_D( 8)  !8bit at RGB
   CALL WRT_W( DY) !V.pixels
   CALL WRT_W( DX) !H.pixels
   IF CMO=0 THEN
      CALL WRT_H("01")     !1 items
      CALL WRT_H("011100") !Y MCU(H:V) DQT
   ELSE
      CALL WRT_H("03")     !3 items
      CALL WRT_H("01"& STR$(MH(0))& STR$(MV(0))& "0"& STR$(QS(0))) !Y  MCU(H:V) DQT
      CALL WRT_H("02"& STR$(MH(1))& STR$(MV(1))& "0"& STR$(QS(1))) !Cb - -
      CALL WRT_H("03"& STR$(MH(2))& STR$(MV(2))& "0"& STR$(QS(2))) !Cr - -
   END IF
   !---DHT
   CALL WRT_H("FFC4")
   LET W=2                 !start size
   FOR J=0 TO CMO+1        !CMO=0(mono.) CMO=2(color)
      LET W=W+1+16+DH(0,J) !+ID +HT +VT
   NEXT J
   CALL WRT_W( W)          !size
   FOR J=0 TO CMO+1                     !CMO=0(mono.) CMO=2(color)
      CALL WRT_D( 16*MOD(J,2)+IP(J/2) ) !   00h=YDC 10h=YAC 01h=CDC 11h=CAC
      FOR I=1 TO 16                     !(J) 0 =YDC  1 =YAC  2 =CDC  3 =CAC
         CALL WRT_D( DH(I,J))
      NEXT I
      FOR I=0 TO DH(0,J)-1
         CALL WRT_D( DV(I,J))
      NEXT I
   NEXT J
   !---SOS
   CALL WRT_H("FFDA")
   IF CMO=0 THEN
      CALL WRT_W(8)      !size
      CALL WRT_D(1)      !1 items
      CALL WRT_H("0100") !No.  Y.HDC/HAC
   ELSE
      CALL WRT_W(12)     !size
      CALL WRT_D( 3)     !3 items
      CALL WRT_H("0100") !No.  Y.HDC/HAC
      CALL WRT_H("0211") !No. Cb.HDC/HAC
      CALL WRT_H("0311") !No. Cr.HDC/HAC
   END IF
   CALL WRT_H("003F00") !band 0~63, AhAl=00
END SUB

!----------------
!open write binary
SUB WOPEN
   OPEN #1:NAME FL$
   ERASE #1
END SUB

!sequential write byte
SUB WRT_D( D)
   PRINT #1 :CHR$(D);
   LET byt=byt+1 !!!
END SUB

!sequential write word
SUB WRT_W( w)
   PRINT #1 :CHR$(IP(w/256));CHR$(MOD(w,256));
   LET byt=byt+2 !!!
END SUB

!sequential write binary massage W$
SUB WRT_M( w$)
   FOR w=1 TO LEN(w$)
      PRINT #1 :MID$(w$,w,1);
   NEXT w
   LET byt=byt+w-1 !!!
END SUB

!sequential write binary hex.massage w$
SUB WRT_H( w$)
   FOR w=1 TO LEN(w$) STEP 2
      PRINT #1 :CHR$(BVAL(MID$(w$,w,2),16));
   NEXT w
   LET byt=byt+LEN(w$)/2 !!!
END SUB

!=====================
! print huffman_table
SUB list_HT( m$,J)
   PRINT m$;" 頻度 座標 bit コード(";
   IF MOD(B(256,J),2)=1 THEN PRINT "座標順)" ELSE PRINT "生成順、頻度降順)"
   LET sum=0
   FOR i=0 TO 255
      IF L(i,J)<>0 THEN
         IF MOD(B(256,J),2)=1 THEN ! 1=Sort_value. Encorder
            LET V_=i
            LET w$="     "& RIGHT$("   "& STR$(SV(i,J)),4)& "  " ! times
            LET sum=sum+L(i,J)*SV(i,J)
         ELSE                      ! 0=Sort_length. Decorder
            LET V_=DV(i,J)
            LET w$="     "& RIGHT$("   "& STR$(S_(i,J)),4)& "  " ! times
            LET sum=sum+L(i,J)*S_(i,J)
         END IF
         LET w$=w$& RIGHT$("0"& BSTR$(V_,16),2)& "  " ! value
         LET w$=w$& RIGHT$(" "& STR$(L(i,J)),2)& "  " ! length
         !--- huffman code
         LET H_=B(i,J) ! code
         LET L_=L(i,J) ! length
         !--- bit_pattern
         LET w$=w$& left$(right$("0000000"& BSTR$(H_,2),16),L_)
         PRINT w$
      END IF
   NEXT i
   PRINT " 合計( 頻度 * bit)=";sum
END SUB

END

EXTERNAL SUB sample(DX$,DY$)
! マンデルブロー(Complex\mandelbm.bas の着色改変)
OPTION ARITHMETIC COMPLEX
SET COLOR MODE "REGULAR"
SET POINT STYLE 1
FOR n=1 TO 51
   SET COLOR MIX(    n) 0   ,0     ,n/51   !BLACK < < BLUE
   SET COLOR MIX( 51+n) 0   ,n/51  ,1      !BLUE  < < CYAN
   SET COLOR MIX(102+n) 0   ,1     ,1-n/51 !CYAN  < < GREEN
   SET COLOR MIX(153+n) n/51,1     ,0      !GREEN < < YELLOW
   SET COLOR MIX(204+n) 1   ,1-n/51,n/51   !YELLOW< < MAGENTA
NEXT n
LET XL=-2
LET XR=.8
LET w1=XR-XL
LET w2=w1/2
SET WINDOW XL, XR,-w2,w2
ASK PIXEL SIZE(XL,-w2; XR,w2) px,py
!
FOR x=XL TO XR+1e-6 STEP w1/(px-1)
   FOR y=-w2-.49*w1/(py-1) TO w2 STEP w1/(py-1) !故意に(x,0)を描点の間に挟む。
      LET z=0
      FOR n=1 TO 255
         LET z=z^2+COMPLEX(x,y)
         IF 2< ABS(z) THEN
            IF n< 64 THEN SET POINT COLOR n*4 ELSE SET POINT COLOR 253
            PLOT POINTS :x,y !上下の対象プロットをしない。
            EXIT FOR
         END IF
      NEXT n
   NEXT y
NEXT x
LET DX$=STR$(px)
LET DY$=STR$(py)
END SUB
 

つづき3

 投稿者:SECOND  投稿日:2009年10月13日(火)22時41分20秒
返信・引用
  !Page-3 の始め

!-------------------
! make huffman tree
SUB TREE3
   MAT Tr=ZER
   FOR i=0 TO SE
      LET F_(i)=S_(i,P)
   NEXT i
   !---minimum2
   DO
      LET w=1e8
      FOR i=0 TO SE
         IF F_(i)< w THEN
            LET w=F_(i)
            LET Ad1=i ! minimum1
         END IF
      NEXT i
      LET w=1e8
      FOR i=0 TO SE
         IF F_(i)< w AND i<>Ad1 THEN
            LET w=F_(i)
            LET Ad2=i ! minimum2
         END IF
      NEXT i
      IF w=1e8 THEN EXIT DO
      IF Ad1>Ad2 THEN swap Ad1,Ad2
      !---
      LET F_(Ad1)=F_(Ad1)+F_(Ad2)
      LET F_(Ad2)=1e9
      !---
      FOR Le1=16 TO 1 STEP -1
         IF Tr(Le1,Ad1,1)>0 OR Tr(Le1,Ad1,3)>0 THEN EXIT FOR
      NEXT Le1
      FOR Le2=16 TO 1 STEP -1
         IF Tr(Le2,Ad2,1)>0 OR Tr(Le2,Ad2,3)>0 THEN EXIT FOR
      NEXT Le2
      LET Le0=MAX( Le1,Le2 )+1
      !---
      LET Tr(Le0,Ad1,0)=Le1
      LET Tr(Le0,Ad1,1)=Ad1
      LET Tr(Le0,Ad1,2)=Le2
      LET Tr(Le0,Ad1,3)=Ad2
   LOOP
   !---make DH()
   LET DH(0,P)=SE+1
   LET k=0
   CALL bitl(Le0,Ad1)
   FOR Ad=0 TO SE
      LET DH(Tr(0,Ad,1),P)=DH(Tr(0,Ad,1),P)+1
   NEXT Ad
END SUB

SUB bitl(Le,Ad)
   IF 0< Le THEN
      LET k=k+1
      CALL bitl( Tr(Le,Ad,0), Tr(Le,Ad,1) )
      CALL bitl( Tr(Le,Ad,2), Tr(Le,Ad,3) )
      LET k=k-1
   ELSE
      LET Tr(Le,Ad,1)=k
   END IF
END SUB

!-------------------
! Quick Sort S_()
SUB Qsort(L,R) ! 降順にセット。
   local i,j
   LET i=L
   LET j=R
   LET Tx=S_(IP((L+R)/2),P)
   DO
      DO WHILE S_(i,P) >Tx ! 降順>、昇順<
         LET i=i+1
      LOOP
      DO WHILE Tx >S_(j,P) ! 降順>、昇順<
         LET j=j-1
      LOOP
      IF j< i THEN EXIT DO ! 等号付 j<=i は、暴走。
      SWAP S_(i,P),S_(j,P)
      SWAP DV(i,P),DV(j,P)
      LET i=i+1
      LET j=j-1
   LOOP UNTIL j< i  ! 等号付 j<=i は、低速。
   IF L< j THEN CALL Qsort(L,j)
   IF i< R THEN CALL Qsort(i,R)
END SUB

!===================================
! make encorder table B()L()<-- DH()
SUB MAKE_H2
   MAT L=ZER
   FOR J=0 TO CMO+1
      LET I=0        ! コード生成 順番(短い順)
      LET Hx=0
      LET Tx=BVAL("8000",16)
      FOR L_=1 TO 16
         FOR N=1 TO DH(L_,J)
            LET V_=DV(I,J)   ! 座標DV(頻度降順)
            LET L(V_,J)=L_
            LET B(V_,J)=Hx   ! コード(座標V_)
            LET I=I+1
            LET Hx=Hx+Tx
         NEXT N
         LET Tx=Tx/2
      NEXT L_
      LET B(256,J)=1
   NEXT J
END SUB

!==============================
!Fast Discrete Cosin Transform.( M=8x8, DCT-2 )
SUB DDCT8X8
   FOR P=0 TO CMO ! (0=Y,1=Cb,2=Cr)
      FOR V0=0 TO DV_-1 STEP 8*MV(0)/MV(P)
         FOR U0=0 TO DU-1 STEP 8*MH(0)/MH(P)
            FOR Y_=0 TO 7
               LET w=Y_*MV(0) !sampling pt.Y
               FOR X_=0 TO 7  !level shift, sampling CbCr from MCU
                  IF P=0 THEN LET X(X_)=D2(U0+X_,V0+Y_,P)-128 ELSE LET X(X_)=D2(U0+X_*MH(0),V0+w,P)
               NEXT X_
               CALL WANG
               FOR U_=0 TO 7
                  LET T(U_,Y_)=X(U_)
               NEXT U_
            NEXT Y_
            FOR U_=0 TO 7
               FOR Y_=0 TO 7
                  LET X(Y_)=T(U_,Y_)
               NEXT Y_
               CALL WANG
               FOR V_=0 TO 7
                  LET D2(U0+U_,V0+V_,P)=ROUND( X(V_)/DQ(U_,V_,QS(P)) ) ! Quantization
               NEXT V_
            NEXT U_
         NEXT U0
      NEXT V0
   NEXT P
END SUB

!=============================
!Fast Discrete Cosin Transform
!Wang.( M=8, DCT-2 )
SUB WANG
   LET XO(0)=X(0)+X(7)
   LET XO(1)=X(1)+X(6)
   LET XO(2)=X(2)+X(5)
   LET XO(3)=X(3)+X(4)
   LET XO(4)=X(3)-X(4)
   LET XO(5)=X(2)-X(5)
   LET XO(6)=X(1)-X(6)
   LET XO(7)=X(0)-X(7)
   !
   LET X(0)=XO(0)+XO(3)
   LET X(1)=XO(1)+XO(2)
   LET X(2)=XO(1)-XO(2)
   LET X(3)=XO(0)-XO(3)
   LET X(4)=XO(7)*SQR(2)
   LET X(5)=XO(6)-XO(5)
   LET X(6)=XO(6)+XO(5)
   LET X(7)=XO(4)*SQR(2)
   !
   LET XO(0)=(COS(PI/4)*X(0)+COS(PI/4)*X(1))
   LET XO(1)=(COS(PI/4)*X(0)-COS(PI/4)*X(1)) !fin 0(0),1(4)
   LET XO(2)=(COS(PI/8)*X(3)+SIN(PI/8)*X(2))
   LET XO(3)=(COS(PI*3/8)*X(3)-SIN(PI*3/8)*X(2)) !fin 2(2),3(6)
   LET XO(4)=X(4)
   LET XO(5)=X(6)
   LET XO(6)=X(5)
   LET XO(7)=X(7)
   !
   LET X(4)=XO(4)+XO(5)
   LET X(5)=XO(4)-XO(5)
   LET X(6)=-XO(6)+XO(7)
   LET X(7)=XO(6)+XO(7)
   !
   LET XO(4)=(COS(PI/16)*X(4)+SIN(PI/16)*X(7))
   LET XO(5)=(COS(PI*5/16)*X(5)+SIN(PI*5/16)*X(6))
   LET XO(6)=(SIN(PI*5/16)*X(5)-COS(PI*5/16)*X(6))
   LET XO(7)=(SIN(PI/16)*X(4)-COS(PI/16)*X(7))
   !
   LET X(0)=SQR(2/8)*XO(0)
   LET X(4)=SQR(2/8)*XO(1)
   LET X(2)=SQR(2/8)*XO(2)
   LET X(6)=SQR(2/8)*XO(3)
   LET X(1)=SQR(1/8)*XO(4)
   LET X(5)=SQR(1/8)*XO(5)
   LET X(3)=SQR(1/8)*XO(6)
   LET X(7)=SQR(1/8)*XO(7)
END SUB

!
Page-4 へ続く
 

つづき2

 投稿者:SECOND  投稿日:2009年10月13日(火)22時42分38秒
返信・引用
  !Page-2 の始め

! haffman Transform. main
SUB ZZRL0
!   ---pass-1 analize frequency SV(nnnn,ssss) -->DV( ,J) DH( ,J)
   IF 0< MHT OR DH(0,0)=0 THEN CALL ZFRE0
   !---pass-2
   CALL MAKE_H2 ! huffman code=B(V,J) len.=L(V,J) <-- DH( ,J) DV( ,J)
   !---
   LET byt=0 !!!
   CALL WOPEN
   CALL W_BIN31
   !---
   LET Hw=0 !bits stream buffer
   LET BC=0 !bits in Hw
   !---
   LET B2(0)=0 !  Y.DC( start prediction)
   LET B2(1)=0 ! Cb.DC
   LET B2(2)=0 ! Cr.DC
   !---
   FOR V09=0 TO DV_-1 STEP 8*MV(0)
      FOR U09=0 TO DU-1 STEP 8*MH(0)
      !---MCU
         FOR P=0 TO CMO    !( 0=Y 1=Cb 2=Cr)
            FOR V0=V09 TO V09+8*MV(P)-1 STEP 8
               FOR U0=U09 TO U09+8*MH(P)-1 STEP 8
                  CALL W_BLK0
               NEXT U0
            NEXT V0
         NEXT P
         !---
      NEXT U09
   NEXT V09
   CALL W_FLUSH
   !---EOI
   CALL WRT_H("FFD9")
   CLOSE #1
   PRINT "byte size:";byt
END SUB

!------
SUB F_BLK0
   LET J=2*SGN(P) ! ( 0=Y 1=Cb 2=Cr)
   !---D.C.part
   LET W=D2(U0+U(0),V0+V(0),P)
   LET SY=W-B2(P)
   LET B2(P)=W ! previous of D.C.difference
   IF SY<>0 THEN LET SS=LEN(BSTR$(ABS( SY),2)) ELSE LET SS=0 ! bit_length
   LET SV(SS,J)=SV(SS,J)+1
   !---A.C.parts
   FOR AE=63 TO 0 STEP -1
      IF 0<>D2(U0+U(AE),V0+V(AE),P) THEN EXIT FOR
   NEXT AE
   !---
   LET Z=0 !zero run counter
   FOR A_=1 TO AE
      LET SY=D2(U0+U(A_),V0+V(A_),P)
      IF SY=0 AND Z< 15 THEN
         LET Z=Z+1
      ELSE
         IF SY<>0 THEN LET SS=LEN(BSTR$(ABS(SY),2)) ELSE LET SS=0 ! bit_length
         LET W=Z*16+SS
         LET Z=0
         LET SV(W,J+1)=SV(W,J+1)+1
      END IF
   NEXT A_
   IF A_< 64 THEN LET SV(0,J+1)=SV(0,J+1)+1 !End Of Block
END SUB

SUB W_BLK0
   LET J=2*SGN(P) ! ( 0=Y 1=Cb 2=Cr)
   !---D.C.part absolute SY bits length
   LET W=D2(U0+U(0),V0+V(0),P)
   LET SY=W-B2(P)
   LET B2(P)=W ! previous of D.C.difference
   IF SY<>0 THEN LET SS=LEN(BSTR$(ABS( SY),2)) ELSE LET SS=0 ! bit_length
   LET L_=L(SS,J)
   LET Ww=B(SS,J)
   CALL W_HUFF
   !---D.C.extent
   IF SS<>0 THEN
      IF SY< 0 THEN LET SY=SY+2^SS-1 !add maxim. in same bit_length.
      LET L_=SS
      LET Ww=SY*2^(16-L_)
      CALL W_HUFF
   END IF
   !---A.C.parts
   FOR AE=63 TO 0 STEP -1
      IF 0<>D2(U0+U(AE),V0+V(AE),P) THEN EXIT FOR
   NEXT AE
   !---
   LET Z=0 !zero run counter
   FOR A_=1 TO AE
      LET SY=D2(U0+U(A_),V0+V(A_),P)
      IF SY=0 AND Z< 15 THEN
         LET Z=Z+1
      ELSE
         IF SY<>0 THEN LET SS=LEN(BSTR$(ABS(SY),2)) ELSE LET SS=0 ! bit_length
         LET W=Z*16+SS
         LET Z=0
         LET L_=L(W,J+1)
         LET Ww=B(W,J+1)
         CALL W_HUFF
         !---A.C.extent
         IF SS<>0 THEN
            IF SY< 0 THEN LET SY=SY+2^SS-1 !add maxim. in same bit_length.
            LET L_=SS
            LET Ww=SY*2^(16-L_)
            CALL W_HUFF
         END IF
      END IF
   NEXT A_
   IF A_< 64 THEN
      LET L_=L(0,J+1)
      LET Ww=B(0,J+1)
      CALL W_HUFF !End Of Block
   END IF
END SUB

!-----
!Ww:b15 ~0 左詰め 入力 bit_stream.  L_:bit長
SUB W_HUFF
   LET Hw=Hw+Ww*2^(-BC-8)
   LET BC=BC+L_
   DO WHILE 8<=BC
      CALL WRT_D( IP(Hw))
      IF IP(Hw)=255 THEN CALL WRT_D( 0)
      LET Hw=FP(Hw)*256
      LET BC=BC-8
   LOOP
END SUB

!flush bit buffer with byte_bound( fill"1"in blank)
SUB W_FLUSH
   IF BC<>0 THEN
      LET w=Hw +2^(8-BC)-1
      CALL WRT_D( w)
      IF w=255 THEN CALL WRT_D( 0)
   END IF
END SUB

!=====================
!pre hafman Transform.
!sort frequency S_() of nnnnssss( zero_run_length data)
!make DH() DV()

SUB MAKE_DHT
   MAT DH=ZER
   !---debug monitor
   PRINT "-----------------------------------------"
   FOR J=0 TO CMO+1  ! CMO =0=mono =2=color
      PRINT "Zero_Run_Length 頻度表 (→)画素bit幅0~15、(↓)直前0数0~15"
      PRINT W_$(J)
      CALL msg00( SV, 0,255,J, 5) ! SV( 0~255, J)
      PRINT "total=";Tx
   NEXT J
   PRINT
   !---
   FOR P=0 TO CMO+1 ! P(0~1=Y.DC~AC  2~3=C.DC~AC), CMO( 0=mono 2=color)
   !--- make S_(,)DV(,)<-- SV(,)
      LET SE=-1
      FOR i=0 TO 255
         IF SV(i,P)<>0 THEN
            LET SE=SE+1
            LET S_(SE,P)=SV(i,P)
            LET DV(SE,P)=i
         END IF
      NEXT i
      PRINT "===================================="
      PRINT W_$(P)
      PRINT "Zero Run Length 頻度表を詰めたもの"
      CALL msg00( S_, 0,SE,P, 5)  ! S_(0~SE, P)
      PRINT "表座標(0~F=直前0数:0~F=画素bit長)"
      CALL msg0x( DV, 0,SE,P, 5)  ! DV(0~SE, P)
      !---
      CALL Qsort(0,SE)
      CALL TREE3
      !---
      PRINT
      PRINT " Encoder DHT table"
      PRINT " (→)コード長1~16の、各個数"
      CALL msg0x( DH, 1,16  ,P, 3) ! DH(1~16, P)
      PRINT " 頻度順の、表座標(0~F=直前0数:0~F=画素bit長)"
      CALL msg0x( DV, 0,Tx-1,P, 3) ! DV(0~Tx-1, P)
      PRINT
   NEXT P
END SUB

SUB msg00( M(,), S,E,J, w)
   LET Tx=0
   LET w$=""
   FOR i=S TO E
      LET Tx=Tx+M(i,J)
      LET w$=w$& USING$( REPEAT$("#",w),M(i,J))
      IF MOD(i-S,16)=15 THEN LET w$=w$& crlf$
   NEXT i
   IF MOD(i-S,16)=0 THEN PRINT w$; ELSE PRINT w$
END SUB

SUB msg0x( M(,), S,E,J, w)
   LET Tx=0
   LET w$=""
   FOR i=S TO E
      LET Tx=Tx+M(i,J)
      LET w$=w$& REPEAT$(" ",w-2)& RIGHT$("0"& BSTR$(M(i,J),16),2)
      IF MOD(i-S,16)=15 THEN LET w$=w$& crlf$
   NEXT i
   IF MOD(i-S,16)=0 THEN PRINT w$; ELSE PRINT w$
END SUB

!
Page-3 へ続く
 

十進 BASIC で、JPG ファイルを作る。

 投稿者:SECOND  投稿日:2009年10月13日(火)22時43分48秒
返信・引用
  !十進 BASIC で、JPG ファイルを作る。
!
!先に投稿した、デコーダーと対を成すものですが、此方はベースラインのみです。
!DCT 変換、ハフマンコード化 …JPG ファイルまでを、見えるプログラムで、実行。

!ハフマン・コードについては、標準テーブルを使わず、
!ランレングス・頻度の測定と、ハフマン・ツリーの作成を行い、それによる
!専用ハフマン・テーブルで、コード化します。(本来のハフマン・コード。)

DEBUG ON
!------------------
!JPG.BAS  09.10.13
!------------------
!テキスト・ウィンドウの、左上位置(x0,y0)と、幅(xw,yw)。
CALL SetWindowPos( WinHandle("TEXT" ),0, 15,172,500,520, 0)

SUB SetWindowPos( handle,C2, x0,y0,xw,yw, nFLG) !nFLG: 0=x0y0xwyw 1=x0y0 2=xwyw
   ASSIGN "user32.dll","SetWindowPos"
END SUB
!----------------------------------------------------------
LET FL$="baseline.jpg" ! 削除すると、ダイアログ・ボックス入力。
SET ECHO "OFF"
ASK DIRECTORY s$
IF FL$>"" THEN PRINT "カレント DIR:"& s$ ELSE file getname FL$, "jpg"
PRINT "出力ファイル:"& FL$
IF FL$>"" THEN PRINT "上書き。又は作成されます。…"& "Ok?[Enter]"
IF FL$>"" THEN CHARACTER INPUT k$
IF FL$="" OR k$<>CHR$(13) THEN
   PRINT "中止"
   STOP
END IF

OPTION ARITHMETIC NATIVE
OPTION BASE 0
OPTION CHARACTER byte
SET TEXT background "OPAQUE"
ASK BITMAP SIZE bmx,bmy
SET WINDOW 0,bmx, bmy,0
!
DIM D8(1000,1000)   !sample picture
DIM D2(1000,1000,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
DIM MH(2),MV(2)     !MCU.Ybr.H()V()
DIM HDC(2),HAC(2)   !hT.table selection
DIM QS(2),CoID(255) !qT.table selection
!
DIM U(63),V(63)         !zigzag
DIM DQ(7,7,3)           !DQT
DIM DH(16,7),DV(255,7)  !DHT
DIM B(255+1,7),L(255,7) !huffman.code & length ( MAKE_H2 )
DIM B2(2)               !Ybr D.C.成分 starting
DIM T(7,7),X(7),XO(7)   !DDCT8X8
!
!---encorder
DIM SV(255,3)            !ZFRE0     頻度SV( 座標)
DIM S_(255,3)            !MAKE_DHT   頻度SV( 座標)--> 頻度S_( 降順No.) 座標DV( 降順No.)
DIM F_(255),Tr(16,255,3) !TREE3
!---lister
LET crlf$=CHR$(13)& CHR$(10)
DIM W_$(7)
LET W_$(0)="Y.DC"
LET W_$(1)="Y.AC"
LET W_$(2)="C.DC"
LET W_$(3)="C.AC"
!
SET VIEWPORT 0,0.4,0.6,1
CALL sample(DX$,DY$)     !サンプル画像。
LET DX=VAL(DX$)
LET DY=VAL(DY$)
MAT D8=ZER(DX-1,DY-1)
SET VIEWPORT 0, 1, 0, 1
SET WINDOW 0,bmx, bmy,0
SET COLOR MODE "NATIVE"
ASK PIXEL ARRAY (0,0) D8
! MAT PLOT CELLS,IN 250,250; 450,450: D8 ! check
!
LET CMO=2   !CMO=0(mono.) CMO=2(color)
LET SD=1    !encoder 量子化テーブル調整 1/SD
CALL DQTINI !DQ(,,0)~DQ(,,1)~{zigzag U()V()},MH(),MV()
LET DU =CEIL(DX/(8*MH(0)))*8*MH(0)  !Uwidth= (8X8)*2 bound by MCU size
LET DV_=CEIL(DY/(8*MV(0)))*8*MV(0)  !Vwidth= (8X8)*1
MAT D2=ZER(DU-1,DV_-1,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
!
CALL YbrRGB  ! Ybr D2()<--RGB D8()
LET MHT=1    ! flag. uncondition making huff.table
CALL DDCT8X8 ! D2() -->DCT -->Quantization
CALL ZZRL0   ! encoder
!---
PRINT "-------------------------"
PRINT "Encoder huffman Code"
FOR J=0 TO CMO+1
   CALL list_HT(W_$(J),J) ! value Sort !H2.LST
NEXT J
beep
PRINT "終了"

!---------
SUB YbrRGB
!--------- JPG 色空間 -------------------------
! | Y |   | 0.2990   +0.5870   +0.1140  | | R |
! |B-Y| = |-0.1687   -0.3313   +0.5000  | | G |
! |R-Y|   | 0.5000   -0.4187   -0.0813  | | B |
!
! | R |   | 1         0        +1.40200 | | Y |
! | G | = | 1        -0.34414  -0.71414 | |B-Y|
! | B |   | 1        +1.77200   0       | |R-Y|
!----------------------------------------------
   FOR V0=0 TO DY-1
      FOR U0=0 TO DX-1
         LET w1=   MOD(D8(U0,V0),256)      !R
         LET w2=MOD(IP(D8(U0,V0)/256),256) !G
         LET w3=    IP(D8(U0,V0)/65536)    !B
         LET D2(U0,V0,0)= 0.2990*w1+0.5870*w2+0.1140*w3 !Y
         LET D2(U0,V0,1)=-0.1687*w1-0.3313*w2+0.5000*w3 !Cb
         LET D2(U0,V0,2)= 0.5000*w1-0.4187*w2-0.0813*w3 !Cr
      NEXT U0
   NEXT V0
END SUB

!-----------
SUB DQTINI
   RESTORE
   !---DQT quantization
   FOR j=0 TO 1
      FOR V_=0 TO 7
         FOR U_=0 TO 7
            READ W
            LET DQ(U_,V_,j)=CEIL(W/SD) ! inhibit 0
         NEXT U_
      NEXT V_
   NEXT j
   !---zigzag-U()V()
   FOR V_=0 TO 7
      FOR U_=0 TO 7
         READ i
         LET U(i)=U_
         LET V(i)=V_
      NEXT U_
   NEXT V_
   !---HT selection
   MAT READ HDC !Y Cb Cr
   MAT READ HAC !Y Cb Cr
   !---QT selection
   MAT READ QS  !Y Cb Cr
   !---MCU size
   MAT MH=CON   !Y Cb Cr =1
   MAT MV=CON   !Y Cb Cr =1
   IF 0< CMO THEN
      LET MH(0)=2 !Y
      LET MV(0)=2 !Y
   END IF
END SUB

!---quantization table
!輝度( SMPTE 370M ).Y
!*DQTY
DATA 32, 16, 17, 18, 18, 19, 42, 44
DATA 16, 17, 18, 18, 19, 38, 43, 45
DATA 17, 18, 19, 19, 40, 41, 45, 48
DATA 18, 18, 19, 40, 41, 42, 46, 49
DATA 18, 19, 40, 41, 42, 43, 48,101
DATA 19, 38, 41, 42, 43, 44, 98,104
DATA 42, 43, 45, 46, 48, 98,109,116
DATA 44, 45, 48, 49,101,104,116,123

!---quantization table
!色差( SMPTE 370M ).Cb Cr
!*DQTC
DATA 32, 16, 17, 25, 26, 26, 42, 44
DATA 16, 17, 25, 25, 26, 38, 43, 91
DATA 17, 25, 26, 27, 40, 41, 91, 96
DATA 25, 25, 27, 40, 41, 84, 93,197
DATA 26, 26, 40, 41, 84, 86,191,203
DATA 26, 38, 41, 84, 86,177,197,209
DATA 42, 43, 91, 93,191,197,219,232
DATA 44, 91, 96,197,203,209,232,246

!---Zigzag table
DATA  0, 1, 5, 6,14,15,27,28
DATA  2, 4, 7,13,16,26,29,42
DATA  3, 8,12,17,25,30,41,43
DATA  9,11,18,24,31,40,44,53
DATA 10,19,23,32,39,45,52,54
DATA 20,22,33,38,46,51,55,60
DATA 21,34,37,47,50,56,59,61
DATA 35,36,48,49,57,58,62,63

!---HT selection
DATA 0,2,2 !DC. Y Cb Cr
DATA 1,3,3 !AC. Y Cb Cr

!---QT selection
DATA 0,1,1 ! Y Cb Cr

!==========================================
! analizing frequency SV(nnnn,ssss) for DHT
SUB ZFRE0
   MAT SV=ZER
   LET B2(0)=0 !  Y.DC( start prediction)
   LET B2(1)=0 ! Cb.DC
   LET B2(2)=0 ! Cr.DC
   !---
   FOR V09=0 TO DV_-1 STEP 8*MV(0)
      FOR U09=0 TO DU-1 STEP 8*MH(0)
      !---MCU
         FOR P=0 TO CMO ! ( 0=Y 1=Cb 2=Cr)
            FOR V0=V09 TO V09+8*MV(P)-1 STEP 8
               FOR U0=U09 TO U09+8*MH(P)-1 STEP 8
                  CALL F_BLK0
               NEXT U0
            NEXT V0
         NEXT P
         !---
      NEXT U09
   NEXT V09
   !---
   CALL MAKE_DHT !DH( ,J) DV( ,J) <--S_( ,J)
END SUB

!
Page-2 へ続く
 

Re: 十進 BASIC で、JPG ファイルを作る。

 投稿者:島村1243  投稿日:2009年10月14日(水)17時39分17秒
返信・引用
  > No.646[元記事へ]

SECONDさんへのお返事です。

> !十進 BASIC で、JPG ファイルを作る。

プログラムをBASIC-7.3.5でRUNすると、タイトルバーに

「IF FL$>"" THEN CHARACTER INPUT k$」

と記載された何も無い細長のダイアログが表示され、又、出力用テキストウインドウに

カレント DIR:C:\Program Files\Decimal BASIC\BASICw32
出力ファイル:baseline.jpg
上書き。又は作成されます。…Ok?[Enter]

と出ますが、jpeg化したいファイルの指定は、どの様にするのでしょうか?
 

Re: エラー報告

 投稿者:五十嵐真人  投稿日:2009年10月14日(水)18時42分41秒
返信・引用  編集済
  > No.629[元記事へ]

白石 和夫 先生、山中和義さんへのお返事です。

> 原因はアセンブラでjecxzとすべきところがjcxzになっていたことでした。
> 近日中に修正版を作ります。


先日、エラー報告したものです。早い回答ありがとうございました。
私は、数論の数値計算をするのが趣味で、それを簡単に計算できる十進BASICには大変、お世話になっています。
開発してくださった。白石 和夫 先生には本当に感謝してます。

追伸

mod(3^(p-1),p)の計算ですが、

let s=1
for k=1 to p-1
let s=mod(s*3,p)
next k

とすれば高々3(p-1)の大きさの数が計算できるコンピュータで計算できます.

そうすれば、時間はかかるものの、十進モードで計算が可能です。
もう少し、剰余計算の公式などを駆使すれば、1000桁モードで有理数モードよりも早く計算できます。

このような考慮が私にも必要だったと思います。
 

Re: エラー報告

 投稿者:山中和義  投稿日:2009年10月14日(水)19時08分17秒
返信・引用
  > No.648[元記事へ]

五十嵐真人さんへのお返事です。

> mod(3^(p-1),p)の計算ですが、

べき乗を2進展開して計算すれば、掛け算の回数が減ります。
LET t0=TIME
LET p=1987829
PRINT modpow(3,p-1,p)
PRINT "計算時間=";TIME-t0

LET t0=TIME
LET s=1
FOR k=1 TO p-1
   LET s=MOD(s*3,p)
NEXT k
PRINT s
PRINT "計算時間=";TIME-t0

END

EXTERNAL FUNCTION modpow(a,n,b) !a^n≡x mod b のxを返す ※nは非負整数
IF n<0 OR n<>INT(n) THEN !非負整数以外なら
   PRINT "modpow関数でパラメータが不適当です。"
   STOP
ELSE
   LET S=1
   DO WHILE n>0 !べき乗nを2進展開する
      IF MOD(n,2)=1 THEN LET S=MOD(S*a,b) !ビットが1なら計算する
      LET a=MOD(a*a,b)
      LET n=INT(n/2)
   LOOP
   LET modpow=S
END IF
END FUNCTION
 

Re: 十進 BASIC で、JPG ファイルを作る。

 投稿者:SECOND  投稿日:2009年10月14日(水)21時35分46秒
返信・引用
  > No.647[元記事へ]

島村1243さんへ

> と出ますが、jpeg化したいファイルの指定は、どの様にするのでしょうか?

このプログラムは、BMP などの他の画像ファイルを、JPG へ変換するような目的は、
持っていません。( 十進BASIC 自身で、簡単に出来ますので。)

END 以降に書かれている EXTERNAL SUB sample( ) 〜で作成された
! マンデルブロー(Complex\mandelbm.bas の着色改変)のグラフを、サンプルとして、
JPG ファイルを、見えるプログラムで作成する様に、したものです。(研究用です)

baseline.jpg なるファイルは、出来ましたでしょうか?

LET FL$="baseline.jpg" ! 削除すると、ダイアログ・ボックス入力。

 …この行を除くと、出力ファイル名の手入力変更は、できますが・・。
 

Re: 十進 BASIC で、JPG ファイルを作る。

 投稿者:島村1243  投稿日:2009年10月15日(木)10時33分59秒
返信・引用
  > No.650[元記事へ]

SECONDさんへのお返事です。

> END 以降に書かれている EXTERNAL SUB sample( ) 〜で作成された
> ! マンデルブロー(Complex\mandelbm.bas の着色改変)のグラフを、サンプルとして、
> JPG ファイルを、見えるプログラムで作成する様に、したものです。(研究用です)
>
> baseline.jpg なるファイルは、出来ましたでしょうか?

SECONDさん、ご回答有難うございます。
baseline.jpgは正常に作成されました。

「見えるプログラム」とは、BASICなのでコードが見える、と言う意味なんですね。
私は「jpeg変換の様子が画像的に見えるのかな?」と誤解していました。

また、全てのファイル、例えばWordのドキュメントファイルもjpeg画像化してしまう、凄い発想のプログラム、と誤解していました。

今まで、十進BASICで作成した画像を他のアプリケーションに使用する場合、出力ウィン
ドウ上でコピーし、それを他のアプリウィンドウ上に貼り付けていたのですが、このプログラ
ムを使うと、jpeg画像ファイルが別個に作成されるので便利ですね。

特にLinux版BASICでは画像出力を、他のアプリにコピー貼り付けが機能しないので、こ
れが有効になると大変便利です。早速、Linuxで試して見ます。
 

Re: 十進 BASIC で、JPG ファイルを作る。

 投稿者:SECOND  投稿日:2009年10月15日(木)14時34分29秒
返信・引用  編集済
  > No.651[元記事へ]

島村1243さんへ
Linux 配慮を、しませんでした。すみません。

(仮称)十進BASIC バージョン間の相違  http://hp.vector.co.jp/authors/VA008683/basi0000.htm
で見ると、WINHANDLE  ASSIGN が ダメなので、冒頭文の

!テキスト・ウィンドウの、左上位置(x0,y0)と、幅(xw,yw)。
CALL SetWindowPos( … )

SUB SetWindowPos( … )
   ASSIGN …
END SUB
!--------- 〜以上は、ただの飾りなので消して。あと、この表にありませんが、

SET COLOR MODE "NATIVE"  …これが、どうでしょうか。

JPG の解説については、次の方々が、正確で詳しいです。
http://hp.vector.co.jp/authors/VA032610/index.html
http://www.marguerite.jp/Nihongo/Labo/Image/PJPEG.html
でも、最終的に頼りになるのは、これ↓しかないようです。
http://www.w3.org/Graphics/JPEG/itu-t81.pdf


-----------------------------------------------
[追記] SET COLOR MODE "NATIVE"  …がダメな場合。

SET VIEWPORT 0, 1, 0, 1
SET WINDOW 0,bmx, bmy,0
! SET COLOR MODE "NATIVE"  ←取り去る
ASK PIXEL ARRAY (0,0) D8
  (
   )
!---------
SUB YbrRGB
   (
    )                    ↓これに、差替え。
   FOR V0=0 TO DY-1
      FOR U0=0 TO DX-1
         ASK COLOR MIX( D8(U0,V0)) w1,w2,w3 ! R,G,B (0~1)
         LET D2(U0,V0,0)= 255*( 0.2990*w1+0.5870*w2+0.1140*w3) !Y
         LET D2(U0,V0,1)= 255*(-0.1687*w1-0.3313*w2+0.5000*w3) !Cb
         LET D2(U0,V0,2)= 255*( 0.5000*w1-0.4187*w2-0.0813*w3) !Cr
      NEXT U0
   NEXT V0
 

Re: 十進 BASIC で、JPG ファイルを作る。

 投稿者:島村1243  投稿日:2009年10月16日(金)07時35分32秒
返信・引用
  > No.652[元記事へ]

SECONDさんへのお返事です。

SECONDさん、ご対応有難うございます。早速Linux上で

> SUB SetWindowPos( … )
>    ASSIGN …
> END SUB
> !--------- 〜以上は、ただの飾りなので消して。

この対策実施で、baseline.jpgファイルが作成されましたが、画像アプリ(GIMPやEye_of_GNOME)から
「jpgファイルではない」
というメッセージが出て読み込み不能でした。このため

> [追記] SET COLOR MODE "NATIVE"  …がダメな場合。
> ! SET COLOR MODE "NATIVE"  ←取り去る
>     )                    ↓これに、差替え。
>    FOR V0=0 TO DY-1
>
>    NEXT V0

を実施しましたところ、画像アプリから
「JPEG 画像ファイル (Bogus Huffman table definition) の解釈でエラー」
のメッセージが出て、残念ですがやはり開けませんでした。

念のため、このLinux上で作成されたbaseline.jpgをWin2000上で開いたら、キチンと開けました。と言うことは、Linux画像アプリの問題のようです。
 

Re: 十進 BASIC で、JPG ファイルを作る。

 投稿者:SECOND  投稿日:2009年10月16日(金)14時57分53秒
返信・引用  編集済
  > No.653[元記事へ]

島村1243さんへ
ハフマン標準テーブルにしか、対応していないのかも知れません。

JPG としてのサイズが、4683 --> 5140 byte と やゝ悪化しますが、
下は、標準を使う方法です。 ※ MHT を1に戻すと、専用テーブルを上書きする!
!
CALL YbrRGB  ! Ybr D2()<--RGB D8()
CALL standard_DHT( DH,DV) !   ←この行を挿入。
LET MHT=0                 !   ←1 を0に換える。!flag. uncondition making huff.table
CALL DDCT8X8 ! D2() -->DCT -->Quantization
CALL ZZRL0   ! encoder
!---
                ↓この文を最後尾に追加。

!------------------------
EXTERNAL SUB standard_DHT( DH(,),DV(,) )
OPTION ARITHMETIC NATIVE
FOR j=0 TO 3
   LET DH(0,j)=0
   FOR i=1 TO 16
      READ w$
      LET DH(i,j)=BVAL(w$,16)
      LET DH(0,j)=DH(0,j)+DH(i,j)
   NEXT i
   FOR i=0 TO DH(0,j)-1
      READ w$
      LET DV(i,j)=BVAL(w$,16)
   NEXT i
NEXT j
! standard DHT
! ISO/IEC 10918-1:1993(E) Huffman table-specification examples
!
!--Y.DC (K.3)
DATA  00,01,05,01,01,01,01,01,01,00,00,00,00,00,00,00
DATA  00,01,02,03,04,05,06,07,08,09,0A,0B
!--Y.AC (K.5)
DATA  00,02,01,03,03,02,04,03,05,05,04,04,00,00,01,7D
DATA  01,02,03,00,04,11,05,12,21,31,41,06,13,51,61,07
DATA  22,71,14,32,81,91,A1,08,23,42,B1,C1,15,52,D1,F0
DATA  24,33,62,72,82,09,0A,16,17,18,19,1A,25,26,27,28
DATA  29,2A,34,35,36,37,38,39,3A,43,44,45,46,47,48,49
DATA  4A,53,54,55,56,57,58,59,5A,63,64,65,66,67,68,69
DATA  6A,73,74,75,76,77,78,79,7A,83,84,85,86,87,88,89
DATA  8A,92,93,94,95,96,97,98,99,9A,A2,A3,A4,A5,A6,A7
DATA  A8,A9,AA,B2,B3,B4,B5,B6,B7,B8,B9,BA,C2,C3,C4,C5
DATA  C6,C7,C8,C9,CA,D2,D3,D4,D5,D6,D7,D8,D9,DA,E1,E2
DATA  E3,E4,E5,E6,E7,E8,E9,EA,F1,F2,F3,F4,F5,F6,F7,F8
DATA  F9,FA
!--C.DC (K.4)
DATA  00,03,01,01,01,01,01,01,01,01,01,00,00,00,00,00
DATA  00,01,02,03,04,05,06,07,08,09,0A,0B
!--C.AC (K.6)
DATA  00,02,01,02,04,04,03,04,07,05,04,04,00,01,02,77
DATA  00,01,02,03,11,04,05,21,31,06,12,41,51,07,61,71
DATA  13,22,32,81,08,14,42,91,A1,B1,C1,09,23,33,52,F0
DATA  15,62,72,D1,0A,16,24,34,E1,25,F1,17,18,19,1A,26
DATA  27,28,29,2A,35,36,37,38,39,3A,43,44,45,46,47,48
DATA  49,4A,53,54,55,56,57,58,59,5A,63,64,65,66,67,68
DATA  69,6A,73,74,75,76,77,78,79,7A,82,83,84,85,86,87
DATA  88,89,8A,92,93,94,95,96,97,98,99,9A,A2,A3,A4,A5
DATA  A6,A7,A8,A9,AA,B2,B3,B4,B5,B6,B7,B8,B9,BA,C2,C3
DATA  C4,C5,C6,C7,C8,C9,CA,D2,D3,D4,D5,D6,D7,D8,D9,DA
DATA  E2,E3,E4,E5,E6,E7,E8,E9,EA,F2,F3,F4,F5,F6,F7,F8
DATA  F9,FA
!
END SUB
 

Re: 十進 BASIC で、JPG ファイルを作る。

 投稿者:島村1243  投稿日:2009年10月16日(金)17時51分39秒
返信・引用
  > No.654[元記事へ]

SECONDさんへのお返事です。

> ハフマン標準テーブルにしか、対応していないのかも知れません。
> JPG としてのサイズが、4683 --> 5140 byte と やゝ悪化しますが、
> 下は、標準を使う方法です。 ※ MHT を1に戻すと、専用テーブルを上書きする!
> 以下省略

上記対策実施で、Linux上の十進BASICで動作成功です!!
これでLinux上でBASICを利用出来る範囲が広がりました。
SECONDさん、感謝します!!
 

Re: 十進 BASIC で、JPG ファイルを作る。

 投稿者:SECOND  投稿日:2009年10月17日(土)16時12分58秒
返信・引用  編集済
  > No.655[元記事へ]

島村1243さんへ
ハフマン符号木、全ての枝、オール 1111…11 まで使用すると、
民生ビューアの中に、デコード出来ないものが、見つかりました。
ひょっとすると、同じケースではないかと・・・?

以下は、空席を1つ作って、1111…10 で、符号が終るようにする応急措置ですが、
この状態で、MHT=1 の専用テーブルON にすると、どうなるでしょう?
Page-2 の SUB MAKE_DHT の下の方です。

      PRINT "表座標(0~F=直前0数:0~F=画素bit長)"
      CALL msg0x( DV, 0,SE,P, 5)  ! DV(0~SE, P)
      !---

      LET SE=SE+1             !←幽霊メンバーを1つ加える。

      CALL Qsort(0,SE)
      CALL TREE3

      LET SE=SE-1             !↓ここから、幽霊メンバーを取除いて空席を1つ作る。
      FOR w=16 TO 1 STEP -1
         IF DH(w,P)<>0 THEN EXIT FOR
      NEXT w
      LET DH(w,P)=DH(w,P)-1
      LET DH(0,P)=DH(0,P)-1   !←ここまで。

      !---
      PRINT
      PRINT " Encoder DHT table"
      PRINT " (→)コード長1~16の、各個数"
 

カードマジックのプログラム化へのお願い

 投稿者:GAI  投稿日:2009年10月17日(土)18時02分55秒
返信・引用
  一組のトランプを次の順序で構成する。
トップからの順番で
  1:ハート   8
  2:スペード 3
  3:ハート  6
  4:ダイア  9
  5:ダイア  6
* 6:ダイア  Q
  7:ダイア  J
* 8:スペード Q
  9:ハート  J
 10:スペード 9
*11:ハート  5
 12:ダイア  8
 13:スペード 6
*14:ハート  Q
*15:ダイア  7
 16:スペード K
 17:クラブ  K
 18:ハート  9
 19:ダイア  3
*20:ダイア  5
*21:ダイア 10
*22:スペード10
 23:クラブ  J
 24:クラブ  9
*25:ハート  2
 26:ダイア  A
*27:スペード 5
*28:ハート 10
 29:スペード 8
 30:クラブ  6
*31:ハート  K
*32:ダイア  K
*33:スペード 4
*34:クラブ 10
*35:クラブ  7
 36:クラブ  A
*37:クラブ  2
 38:ハート  A
*39:スペード 2
*40:ハート  4
*41:スペード 7
*42:クラブ  4
 43:クラブ  8
 44:クラブ  3
 45:ハート  3
*46:ダイア  2
*47:ダイア  4
 48:スペード J
*49:クラブ  Q
*50:ハート  7
 51:スペード A
*52:クラブ  5

ただし*印は表向きで、他は裏向きでセットする。
(組み上がった時、ハートの8が裏向きで一番上のある。)

(遊び方)
1.演者は目隠しか、後ろを向いておく。
2.客に、この仕込んだデックを数回カット(任意の位置で上、下2つに分けて上下の位置関係を入れ替える。)させる。
3.5人の客(A,B,C,D,E)に上から一枚ずつカードを取らせる。
   この時、そのカードが表向きか裏向きかを言ってもらう。
4.最後に残りのパケットの一番上にあるカードが表向きか裏向きかを尋ねる。
5.このことから、いまパケットの一番上にのっているカードの種類と数字を言い当てる。

<言い当てるカードの種類の判定方法>
客C,Dが言う表、裏の組み合わせで
(C,D) =(表、表)→クラブ
    =(表、裏)→ハート
        =(裏、表)→スペード
        =(裏、裏)→ダイア

<言い当てるカードの数字の算出方法>
3人の客(A,B,E)と最後に聞くパケットトップのカードに割り当てるキー数字を
客A・・・8点
客B・・・4点
客E・・・2点
パケットのトップカード・・・1点
としておき、裏向きであるカードに対応する位置のキー数字の合計をする。
(0〜15の合計値のいずれかになる。)このとき、
合計値が0か5か10か15なら、言い当てるカードの数字=K
0<合計値<5なら、言い当てるカードの数字=合計値
5<合計値<10なら、言い当てるカードの数字=合計値−1
10<合計値なら、言い当てるカードの数字=合計値−2
 

Re: 十進 BASIC で、JPG ファイルを作る。

 投稿者:島村1243  投稿日:2009年10月17日(土)19時06分54秒
返信・引用
  > No.656[元記事へ]

SECONDさんへのお返事です。

> 民生ビューアの中に、デコード出来ないものが、見つかりました。
> 以下は、空席を1つ作って、1111…10 で、符号が終るようにする応急措置ですが、
> MHT=1 の専用テーブルON にすると、どうなるでしょう?
>
>       LET SE=SE+1             !←幽霊メンバーを1つ加える。
>
>       LET SE=SE-1        !↓ここから、幽霊メンバーを取除いて空席を1つ作る。
>       ---省略---
>       LET DH(0,P)=DH(0,P)-1   !←ここまで。

上記コードを追加し、MHT=0をMHT=1に変更してLinux上BASICでRunしました。
結果は、正常にbaseline.jpgが作成されています。
以上、実施報告です。
 

baseline.jpg が開けない場合がありましたら

 投稿者:SECOND  投稿日:2009年10月17日(土)21時28分42秒
返信・引用
  島村さん、ご報告ありがとうございました。

他の方で、baseline.jpg が開けない場合がありましたら、ご紹介下さい。

ハフマン符号木に、1つ空席を残さないと、開けないビューアは、今の所、
フリーソフトに1つしか見つかりませんが、Linux にもあるようで、何故なのかが
解りません。ハフマン符号木の構築規則からは、空席は、出来ない筈なのですが?
 

Re: エラー報告

 投稿者:いがらしまなと  投稿日:2009年10月18日(日)04時37分23秒
返信・引用
  > No.649[元記事へ]

山中和義さんへのお返事です。

modpow関数はすばらしいですね。
ありがとうございます。

定理1

p<1373653の場合

modpow(2,p-1,p)=1 かつ modpow(3,p-1,p)=1ならばpは素数です。

定理2

p<25326001の場合

modpow(2,p-1,p)=1 かつ modpow(3,p-1,p)=1 かつ modpow(5,p-1,p)=1 ならばpは素数です。


modpow関数によって、高速に素数判定ができます。
早くそれがどの程度早いのかやってみたいです。
 

Linux用新バージョン

 投稿者:白石 和夫  投稿日:2009年10月18日(日)09時17分27秒
返信・引用
  Linux用にLazarusを利用した新版を公開しました。
文字コードはUTF-8です。
http://sourceforge.jp/projects/decimalbasic/releases/?package_id=8178
からbasic050Ja.tar.gzをダウンロードしてください。
若干の不具合もあるので,あらかじめリリースノートもお読みください。
 

Re: Linux用新バージョン

 投稿者:島村1243  投稿日:2009年10月18日(日)13時03分25秒
返信・引用
  > No.661[元記事へ]

白石 和夫さんへのお返事です。

> Linux用にLazarusを利用した新版を公開しました。
> 文字コードはUTF-8です。

白石先生、早速、新Linux版を試用させて頂きました。
従来版では満たされなかったメニュー機能が、Windows版と同様に機能しており、大変
使い易くなっていました。
特に他のLinuxアプリ(例えばOpenOffice)へ、出力データのコピー貼り付けが可能に
なったので、利用面で格段の効果 !! があります。

> 若干の不具合もあるので,あらかじめリリースノートもお読みください。

試したLinuxのOSは、Vine5.0、Fedora7、Fedora10ですが、日本語入力変換「Scim-Anthy」
との相性が悪いようで、日本語モードにしてキー入力すると、BASICウィンドウはキーを
全く受け付けてくれませんでした(英字はOKです)。
これが改善されると、BASICのプログラムエディターウィンドウだけでプログラムの編集
が完結するのですが。
取り敢えずの対応として、今は他のエディターで編集してから貼り付けています。
 

Re: baseline.jpg が開けない場合がありましたら

 投稿者:SECOND  投稿日:2009年10月19日(月)03時29分49秒
返信・引用  編集済
  > No.659[元記事へ]

ハフマン符号木の、最後尾に1つ使わない枝を設けると、その分、符号木の
枝ぶりが増え、全体のビット長も増え、圧縮コードとしては良くないですが、

反面、バイト・バインドされる画像データー中に、現れるオール1の形態(0xff)
が減って、全体のバイト数が少なくなるかもしれない。(0xff は marker コード
の先頭バイトと重なる為、画像データーの合図に 0x00 を後付する規則がある )

どちらを優先するかは、エンコーダー側の問題で、殆どは、0xff を押える方を、
優先し、符号木の枝ぶりに、犠牲を払っているようです。
だからと言って、デコーダー側が、符号木に空きが無い事を、否定する法は、
ないでしょう。

下は、ハフマン符号木を、作成する部分で、「baseline.jpg が開けない場合」に
差替えて下さい。Page-3  (そのソフトは、恐らくバグだと思います。)

!←(+1) 符号木の最下に、…の行、2つ。SE+1 を、SE に戻すと空席は無くなり、
元の状態にも、戻せます。

!-------------------
! make huffman tree
SUB TREE3
   MAT Tr=ZER
   FOR i=0 TO SE
      LET F_(i)=S_(i,P)    !数値を壊すので、コピー F_(i)で実行
   NEXT i
   LET F_(SE+1)=0          !← 空席用
   !---minimum pair
   DO
      LET w=1e8
      FOR i=0 TO SE+1      !←(+1) 符号木の最下に、空席を1つ作る。
         IF F_(i)< w THEN
            LET w=F_(i)
            LET Ad1=i ! minimum1   !頻度最小の分岐アドレスAd1
         END IF
      NEXT i
      LET w=1e8
      FOR i=0 TO SE+1      !←(+1) 符号木の最下に、空席を1つ作る。
         IF F_(i)< w AND i<>Ad1 THEN
            LET w=F_(i)
            LET Ad2=i ! minimum2   !頻度最小の分岐アドレスAd2
         END IF
      NEXT i
      IF w=1e8 THEN EXIT DO        !分岐の組が無くなるまで
      !---
      LET F_(Ad1)=F_(Ad1)+F_(Ad2)  !次の頻度最小の組探しは、2分岐合計を1つにし、
      LET F_(Ad2)=1e9              !他方を外して行なう
      !---
      FOR Le1=16 TO 1 STEP -1      !アドレスAd1の最上 節点レベルLe1 を探す(最初のLe1=0)
         IF Tr(Le1,Ad1,1)>0 OR Tr(Le1,Ad1,3)>0 THEN EXIT FOR
      NEXT Le1
      FOR Le2=16 TO 1 STEP -1      !アドレスAd2の最上 節点レベルLe2 を探す(最初のLe2=0)
         IF Tr(Le2,Ad2,1)>0 OR Tr(Le2,Ad2,3)>0 THEN EXIT FOR
      NEXT Le2
      LET Le0=MAX( Le1,Le2 )+1     !両者何れよりも1つ上の節点レベル(Le0,Ad1)に、
      !---
      LET Tr(Le0,Ad1,0)=Le1        !分岐先( 節点レベル,アドレス)として2組記入
      LET Tr(Le0,Ad1,1)=Ad1
      LET Tr(Le0,Ad1,2)=Le2
      LET Tr(Le0,Ad1,3)=Ad2
   LOOP
   !---make DH()
   LET k=0
   CALL bitl(Le0,Ad1)    !全アドレスの nested 段数を求める。
   FOR Ad=0 TO SE        !nested 段数が同じ Ad の総数を、段数毎に集計
      LET DH(Tr(0,Ad,1),P)=DH(Tr(0,Ad,1),P)+1
   NEXT Ad
   LET DH(0,P)=Ad
END SUB

SUB bitl(Le,Ad)          !最上 節点(Le0,Ad1)より全分岐を、底まで辿る
   IF 0< Le THEN
      LET k=k+1
      CALL bitl( Tr(Le,Ad,0), Tr(Le,Ad,1) ) !分岐 nested 1
      CALL bitl( Tr(Le,Ad,2), Tr(Le,Ad,3) ) !分岐 nested 2
      LET k=k-1
   ELSE
      LET Tr(0,Ad,1)=k   !最上 節点から底までの nested 段数kを書く
   END IF
END SUB

 

Re: Linux用新バージョン

 投稿者:白石 和夫  投稿日:2009年10月19日(月)11時27分56秒
返信・引用
  > No.662[元記事へ]

MAC用に配布しているVer. 0.4.2を微修正した版をVer.0.4.3として配布します。
SCIMによる日本語入力に対応しますが,入力時の機能語自動修正(小文字を大文字に変換)をオンにすると,エディタの動作がおかしくなります。
 

Re: Linux用新バージョン

 投稿者:島村1243  投稿日:2009年10月20日(火)07時21分39秒
返信・引用
  > No.664[元記事へ]

白石 和夫さんへのお返事です。

> MAC用に配布しているVer. 0.4.2を微修正した版をVer.0.4.3として配布します。

白石先生、度々のご教示有難うございます。
早速、Vine5.0  Fedora7  Fedora10 上で「BASIC-0.4.3」を試用させて頂きました。
日本語入力機能(Scim-Anthy)は正常に動作し、プロぐラムエディターでの入力も可能になりました。

ただ、Windows版BASICで作成した「.BASファイル」を、Linuxのテキストエディター(gedit)
で読み込み(プレーンテキストとして開ける)、読み込んだプロぐラムコードをコピーして
「BASIC-0.5.0」に貼り付けた場合は正常にRUN出来るのですが、「BASIC-0.4.3」に貼り付け
てRUNさせると

(1)全ての空白行に対して「文法の誤り:ここには書けません」
(2)Basicで自動インデントされた全てのコードに対して「制御文字(chr13)が含まれてい
      る」

と言うエラーメッセージが出て走りません。
エラーの出た行の終末位置でDELET,ENTERを行えばエラーは消えますが、プロぐラムの行数が
多いと、全行に対してこの作業を行うのは大変です。

ちなみに、BASIC-050では同じ操作をしてもエラーは出ずにRUN出来ます。
そこでgeditで読み込んだコードを最初に「BASIC-0.5.0」に貼り付けRUNした後に、
「BASIC-0.5.0」の画面上でプロぐラムコードをコピーして「BASIC-0.4.3」に貼り付けRUNす
ると、エラーは出ずに正常に完了します。
0.4.3での文字扱いが、0.5.0と同様の仕様に出来ると良いのですが。開発作業の参考情報と
してご報告致します。
 

Re: Linux用新バージョン

 投稿者:白石 和夫  投稿日:2009年10月20日(火)21時02分57秒
返信・引用
  > No.665[元記事へ]

Ver. 0.4.2と0.4.3は,ファイルメニューから読み込んだ場合,行末コードの調整を行います。Windows版十進BASICの最新版にはプログラムテ キストをUTF-8で保存する機能がついているので,これを利用すると,WindowsからMac,Linuxへプログラムを移行することができます。
コピー&ペーストで貼り付ける場合には,貼り付ける前に行末を調整しておいてください。
 

Re: カードマジックのプログラム化へのお願い

 投稿者:SECOND  投稿日:2009年10月21日(水)00時42分22秒
返信・引用
  > No.657[元記事へ]

GAIさんへ

!じつは、よくわからなくて、次のように勝手に想像してみましたが、
!合っているでしょうか。

!デックのトップから、A,B,C,D,E のパケット順に、最後の1枚を残して、配る。
!ただし*印は表向きで、他は裏向き。

!最後のパケットトップが、以下なら、最後の1枚の種類は、
!(C,D) =(表、表)→クラブ
!    =(表、裏)→ハート
!        =(裏、表)→スペード
!        =(裏、裏)→ダイア

!裏向きカードの場所ごとに、点数をつけて合計する。
!5つの、パケットトップは、C,D …0点
!A・・・8点
!B・・・4点
!E・・・2点
!最後のカード・・・1点

!合計値が
!0,5,10,15 なら、 K …13
!0<合計値<5なら、  合計値
!5<合計値<10なら、 合計値−1
!10<合計値なら、   合計値−2

!が、最後の1枚の、ナンバー

OPTION BASE 0
DIM s$(51),cd$(3)

LET cd$(0)="クラブ"
LET cd$(1)="ハート"
LET cd$(2)="スペード"
LET cd$(3)="ダイヤ"

! s$()(1:1) 先頭の数字= 1,0(裏,表)

LET s$( 0)="1ハート  8" !  1:ハート   8
LET s$( 1)="1スペード 3" !  2:スペード 3
LET s$( 2)="1ハート  6" !  3:ハート  6
LET s$( 3)="1ダイア  9" !  4:ダイア  9
LET s$( 4)="1ダイア  6" !  5:ダイア  6
LET s$( 5)="0ダイア  Q" !* 6:ダイア  Q
LET s$( 6)="1ダイア  J" !  7:ダイア  J
LET s$( 7)="0スペード Q" !* 8:スペード Q
LET s$( 8)="1ハート  J" !  9:ハート  J
LET s$( 9)="1スペード 9" ! 10:スペード 9
LET s$(10)="0ハート  5" !*11:ハート  5
LET s$(11)="1ダイア  8" ! 12:ダイア  8
LET s$(12)="1スペード 6" ! 13:スペード 6
LET s$(13)="0ハート  Q" !*14:ハート  Q
LET s$(14)="0ダイア  7" !*15:ダイア  7
LET s$(15)="1スペード K" ! 16:スペード K
LET s$(16)="1クラブ  K" ! 17:クラブ  K
LET s$(17)="1ハート  9" ! 18:ハート  9
LET s$(18)="1ダイア  3" ! 19:ダイア  3
LET s$(19)="0ダイア  5" !*20:ダイア  5
LET s$(20)="0ダイア 10" !*21:ダイア 10
LET s$(21)="0スペード10" !*22:スペード10
LET s$(22)="1クラブ  J" ! 23:クラブ  J
LET s$(23)="1クラブ  9" ! 24:クラブ  9
LET s$(24)="0ハート  2" !*25:ハート  2
LET s$(25)="1ダイア  A" ! 26:ダイア  A
LET s$(26)="0スペード 5" !*27:スペード 5
LET s$(27)="0ハート 10" !*28:ハート 10
LET s$(28)="1スペード 8" ! 29:スペード 8
LET s$(29)="1クラブ  6" ! 30:クラブ  6
LET s$(30)="0ハート  K" !*31:ハート  K
LET s$(31)="0ダイア  K" !*32:ダイア  K
LET s$(32)="0スペード 4" !*33:スペード 4
LET s$(33)="0クラブ 10" !*34:クラブ 10
LET s$(34)="0クラブ  7" !*35:クラブ  7
LET s$(35)="1クラブ  A" ! 36:クラブ  A
LET s$(36)="0クラブ  2" !*37:クラブ  2
LET s$(37)="1ハート  A" ! 38:ハート  A
LET s$(38)="0スペード 2" !*39:スペード 2
LET s$(39)="0ハート  4" !*40:ハート  4
LET s$(40)="0スペード 7" !*41:スペード 7
LET s$(41)="0クラブ  4" !*42:クラブ  4
LET s$(42)="1クラブ  8" ! 43:クラブ  8
LET s$(43)="1クラブ  3" ! 44:クラブ  3
LET s$(44)="1ハート  3" ! 45:ハート  3
LET s$(45)="0ダイア  2" !*46:ダイア  2
LET s$(46)="0ダイア  4" !*47:ダイア  4
LET s$(47)="1スペード J" ! 48:スペード J
LET s$(48)="0クラブ  Q" !*49:クラブ  Q
LET s$(49)="0ハート  7" !*50:ハート  7
LET s$(50)="1スペード A" ! 51:スペード A
LET s$(51)="0クラブ  5" !*52:クラブ  5

FOR i=0 TO 52
   LET A=MOD(i,52)
   LET B=MOD(i+1,52)
   LET C=MOD(i+2,52)
   LET D=MOD(i+3,52)
   LET E=MOD(i+4,52)
   LET r=MOD(i+5,52)
   LET sum= VAL(s$( A )(1:1))*8+VAL(s$( B )(1:1))*4+VAL(s$( E )(1:1))*2+VAL(s$( r )(1:1))
   IF MOD(sum,5)=0 THEN
      LET N=13
   ELSEIF sum< 5 THEN
      LET N=sum
   ELSEIF 5< sum AND sum< 10 THEN
      LET N=sum-1
   ELSEIF 10< sum THEN
      LET N=sum-2
   END IF
   PRINT "計算のカード:";cd$( VAL(s$( C )(1:1))*2+VAL(s$( D )(1:1)) );N
   PRINT "最後のカード:";s$( r )(2:7)
   PRINT
NEXT i

!連続する6枚が、デックの一番下に残れば、その6枚は、何番目のものでも、OK
!のようですが、細かくシャッフルしすぎると、6枚が、確保できないかも知れません。

END
 

Re: カードマジックのプログラム化へのお願い

 投稿者:GAI  投稿日:2009年10月21日(水)07時25分6秒
返信・引用  編集済
  > No.667[元記事へ]

SECONDさんへのお返事です。


製作ありがとうございます。


> !デックのトップから、A,B,C,D,E のパケット順に、最後の1枚を残して、配る。
> !ただし*印は表向きで、他は裏向き。


この部分はA,B,C,D,Eの人が一枚ずつカードをとることで、とった後はそれ以上はカードはとりません。そして残りのパケットはテーブルにあり、その一番上にのっているカードについて、表か裏かを聞きます。
5人の返事とこの情報(6つの表か裏かのデーター)から、パケットトップにあるカードを当てると言う仕組みです。
これは、元のデックを任意にカットしても同じく成立します。(別に6枚が連続する必要はなく、任意の位置でデックを2分し、上下を入れ替えることが可能)


そこで、任意の位置でデックをカットする部分と、6つのデーター(A,B,C,D,E,トップカードの裏、表)を表示してもらい、一応こちらがパケットトップにあるカードを予想しますから、この答えが正解になるかを確認できるプログラムを構成してもらいたいんですが・・・
 

Re: カードマジックのプログラム化へのお願い

 投稿者:SECOND  投稿日:2009年10月21日(水)11時06分38秒
返信・引用  編集済
  > No.668[元記事へ]

GAIさんへ

カードはド素人で、随分とんちんかんな、状況を想像していたようです。
申し訳ない!でも、プログラム自体は、

s$( 0),s$( 1),s$( 2),s$( 3),s$( 4),s$( 5) の裏表からの計算カード = s$( 5)のカードに一致
s$( 1),s$( 2),s$( 3),s$( 4),s$( 5),s$( 6) の裏表からの計算カード = s$( 6)のカードに一致
s$( 2),s$( 3),s$( 4),s$( 5),s$( 6),s$( 7) の裏表からの計算カード = s$( 7)のカードに一致
         :           :
         :           :
s$(50),s$(51),s$( 0),s$( 1),s$( 2),s$( 3) の裏表からの計算カード = s$( 3)のカードに一致
s$(51),s$( 0),s$( 1),s$( 2),s$( 3),s$( 4) の裏表からの計算カード = s$( 4)のカードに一致
s$( 0),s$( 1),s$( 2),s$( 3),s$( 4),s$( 5) の裏表からの計算カード = s$( 5)のカードに一致

このように、ぐるぐると、何度回っても、連続の6枚でありさえすれば、
一致する確認の計算をしていますので、

兼用できるような気がします。
少しくらいは、シャッフルしてもトップの6枚は、上記の何れかだと思います、
上下を、中ほどで、入替えても、サークル順序は同じで、崩れませんが、
途中から抜き取ったり、1枚毎に織り込むシャッフルだと、どこで崩れるか、
運、になりますね。
あとは、ご自身で工夫してみてください。すみません。

   ------------------------
  ※例えば、23枚目で上下入換えたとすると

  for i=0+23 to 52+23
      (
       )
    next i

    とした状態です、23枚目から始まる他、何も変りません。
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年10月21日(水)16時58分14秒
返信・引用
  > No.496[元記事へ]

パスカルの三角形
 累乗根表、対数表、三角関数表のようにこの表を使った計算

通常は、数字が山の形に配置されているが、
計算機を使う場合は、下に紹介するパターンの2次元配列で表現する。
式を直接適用することができるが、ここでは表計算(Excelなど)での設定方式で行う。
!●パターン1 段と右斜めが、行や列に置き換わる

LET N=6 !段数
DIM P(0 TO N,0 TO N) !2次元配列

MAT P=ZER
LET P(0,0)=1 !左詰め
FOR i=1 TO N
   LET P(i,0)=1 !comb(n,n)=comb(n,0)=1
   FOR j=1 TO i !comb(n,r)=comb(n-1,r-1)+comb(n-1,r)
      LET P(i,j)=P(i-1,j-1)+P(i-1,j) !左上+上
   NEXT j
NEXT i

MAT PRINT USING(REPEAT$("#### ",N+1)): P !※桁数が多い場合、#を増やす
PRINT


!例. パターン1の表探索によるΣ[k=1,N-1]{k}の計算
FOR k=1 TO N-1 !右斜め1番目の数列は「自然数」
   PRINT "+";P(k,1);
NEXT k
PRINT "=";P(K,2) !右下(K=k+1)


!例. 円周上にN個の点を取り、互いに結線して分割される領域の数
FOR i=1 TO N+1
   LET s=0
   FOR k=0 TO 4 !左から5個まで
      LET s=s+P(i-1,k)
   NEXT k
   PRINT i;"点="; s;"個"
NEXT i

!別解
DIM T(0 TO N)
FOR i=0 TO 4 !ベクトル(1,1,1,1,1,0,…)
   LET T(i)=1
NEXT i
MAT T=P*T
MAT PRINT T;


!例. フィボナッチ数列
FOR i=0 TO N !右斜めの和
   LET s=0
   FOR j=0 TO i
      LET s=s+P(i-j,j)
   NEXT j
   PRINT s;
NEXT i
PRINT


END

!●パターン2 左斜めと右斜めが、行や列に置き換わる

LET N=4 !段数
DIM P(0 TO N,0 TO N) !2次元配列

MAT P=ZER
FOR j=0 TO N !反時計まわりに45度回転
   LET P(0,j)=1 !comb(n,n)=comb(n,0)=1
NEXT j
FOR i=1 TO N
   LET P(i,0)=1 !comb(n,n)=comb(n,0)=1
   FOR j=1 TO N-i !comb(n,r)=comb(n-1,r-1)+comb(n-1,r)
      LET P(i,j)=P(i,j-1)+P(i-1,j) !左+上
   NEXT j
NEXT i

MAT PRINT USING(REPEAT$("#### ",N+1)): P !※桁数が多い場合、#を増やす
PRINT


!例. N人をi個のグループに分ける場合の数
!
!3人で競走する場合
! 3人が1位              1通り(=comb(3,3))
! 2人が1位、1人が2位        3通り(=comb(3,2)*comb(1,1))
! 1人が1位、2人が2位        3通り(=comb(3,1)*comb(2,2))
! 1人が1位、1人が2位、1人が3位  6通り(=comb(3,1)*comb(2,1)*comb(1,1))
! したがって、13通り。

LET c=0
FOR i=0 TO N
   LET r=0 !左斜めの和
   FOR j=0 TO N-i
      LET r=r+(-1)^j*P(i,j) !各段の左から偶数番目を負にする
   NEXT j
   LET c=c+r*i^N !重み
NEXT i
PRINT c


!別解
DIM B(0 TO N,0 TO N) !各段の左から偶数番目を負にする基本行列
MAT B=ZER
FOR i=0 TO N
   LET B(i,i)=(-1)^i
NEXT i
MAT B=P*B
MAT PRINT B;

DIM T(0 TO N)
MAT T=CON !左斜めの数列を合計する
MAT T=B*T

DIM W(1,0 TO N) !重み 0^N,1~N,2^N,3^N,…
FOR i=0 TO N
   LET W(1,i)=i^N
NEXT i
MAT PRINT W;
MAT T=W*T

MAT PRINT T; !=W*P*F*CON



!補足. N人をi個のグループに分ける場合の数

LET N=4 !人数

!指数型母関数を用いての解法
! 数列{a0,a1,a2,…,aN,…}に対して、この数列の指数型母関数G(x)は
!  G(x)=a0*x^0/0!+a1*x^1/1!+a2*x^2/2!+ … +aN*x^N/N!+ …
!
!N人が順番の違うi個のグループに分かれてゴールしたものとし、各グループについて考える。
!場合の数(順列の数)を指数型計数子として表現すると
!グループ内はN人以下なら何人でも許され、その内での並び方は問題としないので
! x^0/0!+x^1/1!+x^2/2!+ … +x^N/N!+ … = EXP(x)
!しかし、グループ内には少なくとも1人はいるので
! x^1/1!+x^2/2!+ … +x^N/N!+ … = EXP(x)-1
!i個のグループでは指数型計数子は
! (EXP(x)-1)^i
! =Σ[j=0,i]{comb(i,j)*EXP(x)^(i-j)*(-1)^j} //二項定理
! =Σ[j=0,i]{comb(i,j)*(-1)^j*EXP((i-j)*x)} //EXP関数の指数部分をまとめる
! =Σ[j=0,i]{comb(i,j)*(-1)^j*Σ[N=0,∞]{(i-j)^N*x^N/N!}} //EXP関数を級数展開する
! =Σ[N=0,∞]{x^N/N!*Σ[j=0,i]{comb(i,j)*(-1)^j*(i-j)^N}}
!求める値は、x^N/N!の係数なので
! Σ[j=0,i]{comb(i,j)*(-1)^j*(i-j)^N}}
!j=iのとき、comb(i,j)*(-1)^j*(i-j)^N = 0 より
! Σ[j=0,i-1]{comb(i,j)*(-1)^j*(i-j)^N}}
!グループは、1〜Nまであるので
! Σ[i=1,N]{Σ[j=0,i-1]{comb(i,j)*(-1)^j*(i-j)^N}}}

LET f=0 !一般項 Σ[i=1,N]{Σ[j=0,i-1]{(-1)^j*comb(i,j*(i-j)^j}}
FOR i=1 TO N
   FOR j=0 TO i-1
      LET f=f+(-1)^j*comb(i,j)*(i-j)^N
   NEXT j
NEXT i
PRINT f !結果を表示する


!上式を展開して、i^Nでまとめると
! Σ[i=1,N]{Σ[j=0,N-i]{(-1)^j*comb(i+j,j)*i^N}}

LET f=0 !一般項 Σ[i=1,N]{Σ[j=0,N-i]{(-1)^j*comb(i+j,j)*i^N}}
FOR i=1 TO N
   FOR j=0 TO N-i
      LET f=f+(-1)^j*comb(i+j,j)*i^N
   NEXT j
NEXT i
PRINT f !結果を表示する


!この式をよく見ると、パスカルの三角形による解法へ
!  :
!  :

END
 

Re: センター試験程度のプログラム演習

 投稿者:GAI  投稿日:2009年10月21日(水)22時39分39秒
返信・引用
  > No.670[元記事へ]

山中和義さんへのお返事です。



> !例. N人をi個のグループに分ける場合の数
> !
> !3人で競走する場合
> ! 3人が1位              1通り(=comb(3,3))
> ! 2人が1位、1人が2位        3通り(=comb(3,2)*comb(1,1))
> ! 1人が1位、2人が2位        3通り(=comb(3,1)*comb(2,2))
> ! 1人が1位、1人が2位、1人が3位  6通り(=comb(3,1)*comb(2,1)*comb(1,1))
> ! したがって、13通り。
すなわち、同順を許す順列の総数を求めることですよね。


この計算は以前次の問題を考えていたものと繋がることに気付きました。

<ツアー旅行企画>
3人(A,B,C)の客がツアー旅行を希望しています。
旅行会社は次の企画が可能です。
1.A,B,Cで一緒に行く。
2.A,Bで第1陣、Cだけで第2陣
3.B,Cで第1陣、Aだけで第2陣
4.C,Aで第1陣、Bだけで第2陣
5.Aで第1陣、B,Cで第2陣
6.Bで第1陣、C,Aで第2陣
7.Cで第1陣、A,Bで第2陣
8.Aで第1陣、Bで第2陣、Cで第3陣
9.Aで第1陣、Cで第2陣、Bで第3陣
10.Bで第1陣、Aで第2陣、Cで第3陣
11.Bで第1陣、Cで第2陣、Aで第3陣
12.Cで第1陣、Aで第2陣、Bで第3陣
13.Cで第1陣、Bで第2陣、Aで第3陣

以上13通りの可能性が生まれる。

では、4人の客が現れたら何通りが考えられるでしょうか?
一般にn人の客ならどうなるでしょう?

ここに紹介されているプログラムが
この問題に解答をあたえるものであり、またその一般化を可能にする。




> !この式をよく見ると、パスカルの三角形による解法へ
> !  :
> !  :


<手計算による機械的算出方法>
1.まずパスカルの三角形から、1番右端の(1)は取り除く。
2.左端から右に偶数番目の数に−をつける。
3.各段目の左端から右斜め下に順々に表示されている数字をすべて加える。
4.この合計段の数の左から順に4^4、3^4、2^4、1^4を掛け、すべてを加える。


すなわち

1.      1 (1)
    1  2 (1)
   1  3  3 (1)
 1  4  6  4 (1)

2.          1
     1 −2
    1 −3 3
   1 −4 6 −4
        a     b    c     d

3.  a=1,b=1-4=-3,c=1-3+6=4,d=1-2+3-4=-2

4. a*4^4+b*3^4+c*2^4+d*1^4
  =1*4^4-3*3^4+4*2^4-2*1^4
  =256-243+64-2
  =75


5人の場合も同様に計算してみると、541通りで、1人、2人の場合も含めると、次のような数列となるのが手計算で手に入る。(6人はちょっと大変)

   1 , 3 , 13 , 75 , 541 ,4683、 ・・・・・
 

Re: センター試験程度のプログラム演習

 投稿者:SECOND  投稿日:2009年10月22日(木)19時50分51秒
返信・引用  編集済
  > No.670[元記事へ]

山中さん LET f=0 !一般項 Σ[i=1,N]{Σ[j=0,i-1]{(-1)^j*comb(i,j*(i-j)^j}}
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年10月23日(金)09時00分36秒
返信・引用
  > No.672[元記事へ]

SECONDさんへのお返事です。

ケアレスミスです。
実行部分は、プログラムを実行すれば、その結果で間違いがわかりますが
注釈部分は、如何せん、、、
!別解
!A={a1,a2,a3,・・・,an}、B={b1,b2,b3,…,bm}のとき、AからBへの全射の数
! Σ[k=0,m]{(-1)^k*comb(m,k)*(m-k)^n}
!
!上式は、包除原理より求められる。
!求める値は、m=1〜nより。
! Σ[m=1,n]{Σ[k=0,m]{(-1)^k*comb(m,k)*(m-k)^n}}

LET n=5

LET f=0
FOR m=1 TO n
   FOR k=0 TO m
      LET f=f+(-1)^k*comb(m,k)*(m-k)^n
   NEXT k
NEXT m
PRINT f

END
 

Re: センター試験程度のプログラム演習

 投稿者:SECOND  投稿日:2009年10月23日(金)12時39分38秒
返信・引用  編集済
  > No.673[元記事へ]

山中さんへ
このシリーズ、いつもありがとうございます。目的外の受講生ですが、
高校時代、数学の点数が、私は極めて悪くて、怖い数学の先生に、追いかけられる思いです。
再履修させて、頂いています。新たな発想の授業を感謝します。
書物の方程式と異なり、「実行文には未定義シンボルが無い」のが、助かります。

大槻教授のブログに、私の戯言が載りました。2009.10.22
http://ohtsuki-yoshihiko.cocolog-nifty.com/blog/
 

順列、組合せの番号付けと復元

 投稿者:山中和義  投稿日:2009年10月23日(金)15時25分41秒
返信・引用  編集済
  パズルの解法で、局面をコード化するためにつくってみました。
ハッシュ関数のサブルーチンです。

参考
 フォルダ SAMPLE 内 PERMUTAT.BAS、COMBINAT.BAS


●順列型
!順列 perm(n,r) 通りのパターンに、0 〜 perm(n,r)-1 の番号をつける方法

LET N=4 !1〜Nまでの数字を使う
LET R=4

DATA 1,2,3,4 !順列 PERM(N,N)=FACT(N) のテスト・データ
DATA 1,2,4,3
DATA 1,3,2,4
DATA 1,3,4,2
DATA 1,4,2,3
DATA 1,4,3,2
DATA 2,1,3,4
DATA 2,1,4,3
DATA 2,3,1,4
DATA 2,3,4,1
DATA 2,4,1,3
DATA 2,4,3,1
DATA 3,1,2,4
DATA 3,1,4,2
DATA 3,2,1,4
DATA 3,2,4,1
DATA 3,4,1,2
DATA 3,4,2,1
DATA 4,1,2,3
DATA 4,1,3,2
DATA 4,2,1,3
DATA 4,2,3,1
DATA 4,3,1,2
DATA 4,3,2,1

DIM A(R),B(R)
FOR d=1 TO PERM(N,R) !データを読み込む
   MAT READ A

   LET h=Perm2Num(A,N,R)
   PRINT h !結果を表示する

   CALL Num2Perm(h, B,N,R) !復元する
   MAT PRINT B;
   MAT PRINT A; !検算
NEXT d

END


!最小完全ハッシュ関数

EXTERNAL FUNCTION Perm2Num(A(),N,R) !順列パターンに番号を付ける ※辞書式順序
LET v=0
FOR j=1 TO R
   LET t=A(j)
   LET v=v+perm(N-j,R-j)*(t-1)
   FOR k=j+1 TO R
      IF A(k)>t THEN LET A(k)=A(k)-1
   NEXT k
NEXT j
LET Perm2Num=v
END FUNCTION

EXTERNAL SUB Num2Perm(h, A(),N,R) !番号から順列パターンを生成する ※辞書式順序
LET v=h
FOR j=1 TO R
   LET fac=perm(N-j,R-j)
   LET t=INT(v/fac)
   LET A(j)=t+1 !1〜N
   LET v=v-fac*t
NEXT j
FOR j=R TO 1 STEP -1
   FOR k=j+1 TO R
      IF A(j)<=A(k) THEN LET A(k)=A(k)+1
   NEXT k
NEXT j
END SUB


●組合せ型
!組合せ comb(n,r) 通りのパターンに、0 〜 comb(n,r)-1 の番号をつける方法

LET N=6 !1〜Nまでの数字を使う
LET R=3

DATA 1,2,3 !組合せ comb(6,3)=20 のテスト・データ
DATA 1,2,4 !※数字は小さい順
DATA 1,2,5
DATA 1,2,6
DATA 1,3,4
DATA 1,3,5
DATA 1,3,6
DATA 1,4,5
DATA 1,4,6
DATA 1,5,6
DATA 2,3,4
DATA 2,3,5
DATA 2,3,6
DATA 2,4,5
DATA 2,4,6
DATA 2,5,6
DATA 3,4,5
DATA 3,4,6
DATA 3,5,6
DATA 4,5,6

DIM A(R),B(R)
FOR d=1 TO comb(N,R) !データを読み込む
   MAT READ A

   LET h=Comb2Num(A,N,R)
   PRINT h !結果を表示する

   CALL Num2Comb(h, B,N,R) !復元する
   MAT PRINT B;
   MAT PRINT A; !検算
NEXT d

END


!最小完全ハッシュ関数

EXTERNAL FUNCTION Comb2Num(A(),N,R) !組合せパターンに番号を付ける ※辞書式順序
LET v=0
FOR i=R TO 1 STEP -1 !組合せをビット位置とする
   LET t=N-A(i)
   LET v=v+COMB(t,R-i+1)
NEXT i
LET Comb2Num=(comb(N,R)-1)-v
END FUNCTION

EXTERNAL SUB Num2Comb(h, A(),N,R) !番号から組合せパターンを生成する ※辞書式順序
LET v=comb(N,R)-h
LET m=R
FOR i=N-1 TO 0 STEP -1 !組合せをビット位置とする
   LET t=COMB(i,m)
   IF v>t THEN
      LET A(R-m+1)=N-i !ビット位置(N-i-1)を1とする
      LET m=m-1
      LET v=v-t
   END IF
NEXT i
END SUB


EXTERNAL FUNCTION Comb2Num2(A(),N,R) !組合せパターンに番号を付ける ※辞書式順序ではない
LET v=0
FOR i=R TO 1 STEP -1
   LET t=A(i)-1 !組合せをビット位置とする
   LET v=v+COMB(t,i)
NEXT i
LET Comb2Num2=v
END FUNCTION

EXTERNAL SUB Num2Comb2(h, A(),N,R) !番号から組合せパターンを生成する ※辞書式順序ではない
LET v=h
LET m=R
FOR i=N-1 TO 0 STEP -1 !組合せをビット位置とする
   LET t=COMB(i,m)
   IF t<=v THEN
      LET A(m)=i+1 !ビット位置iを1とする
      LET m=m-1
      LET v=v-t
   END IF
NEXT i
END SUB
 

挑戦状

 投稿者:GAI  投稿日:2009年10月25日(日)13時15分46秒
返信・引用  編集済
   *48   *90    16   59   *68   38    76
  15   57   *49   *92     *79   27    65
 *81   35   *71   26    13   *93    43
  36   78   *28   69    56   *50   *88
 *39   77    25     *72    55   47   *89
  33   *83    23   66   *61   45   *91

*印は赤色で印字されているものとする。(無いのは黒色)

(遊び方)
1.相手にこの中の一つの数字を心に思ってもらう。
2.その数字のある列の数字の色を上から言ってもらう。
 ただし、心に決めた数字では、あえて逆の色を言うことにする。
 (例:78(4行2列目)→赤、黒、黒、赤(逆)、黒、赤と答えることになる。)
3.この答えの色の配列を聞いて、即座に相手の心に思った数字を当てる。
  (このカードは相手に渡しておき、このカードは見ないで当てる。)

この遊びを可能ならしめる数字の配列が如何なる法則で構成されているか、解明されたし。
(あえてウソの情報を含ませる点が重要)

どなたか、心に一つ数字を思い、色の報告をして下さい。
あなたの数字をピタリと当ててしんぜましょう。
 

Re: 挑戦状

 投稿者:荒田浩二  投稿日:2009年10月26日(月)07時21分20秒
返信・引用
  > No.676[元記事へ]

GAIさんへのお返事です

赤と黒の文字列からもとの数字を求めるには、次のようにします。
先頭から11,22,44,1,2,4をベースとして、黒ならその数を加え最後に10を加えます。
黒、赤、黒、黒、赤、赤 ならば  1*11+0*22+1*44+1*1+0*2+0*4+10=66

100 DEF base(j)=2^MOD(j+2,3)+2^MOD(j+2,3)*10*(1-INT(j/3.01)) ! 11,22,44,1,2,4
110 FUNCTION change(p$)
120    IF UCASE$(p$)="R" THEN
130       LET c=0
140    ELSEIF UCASE$(p$)="B" THEN
150       LET c=1
160    ELSE
170       PRINT "ERROR-2 !!"
180    END IF
190    LET change=c
200 END FUNCTION
210 INPUT PROMPT "赤を""R"",黒を""B""とした文字列 = ":rb$ ! 例) brbbrr
220 IF LEN(rb$)<>6 THEN PRINT "ERROR-1 !!"
230 LET d=10
240 FOR j=1 TO 6
250    LET d=d+change(rb$(j:j))*base(j)
260 NEXT j
270 PRINT "解答 =";d
280 END


次はタテの数字の列の構成をすべて記述するプログラムです。
ここからどのような規則により7個の数列を抽出したのかは、私にはわかりませんでした。
たぶん数字が重複しないように選んでいるのだと思いますが、次の数列は採用されていません。
   *21
   *32
   *54  (すべて赤なのでこれを含むとヒントになってしまうから?)
   *11
   *12
   *14
生成できる数字は10〜94のうちの64個(=2^6)ですが、他にも表に現れない数字があります。

DIM base(6),dwn(6),check(6)
MAT READ base,dwn
FUNCTION number(q)
   LET dd=10
   FOR jj=1 TO 6
      IF jj<>q THEN
         LET dd=dd+check(jj)*base(jj)
      ELSE
         LET dd=dd+((check(jj)-1)^2)*base(jj)
      END IF
   NEXT jj
   LET number=dd
END FUNCTION
FOR n=10 TO 94
   MAT check=ZER
   LET d=10
   LET nn=n-d
   FOR j=1 TO 6 ! baseの大きい数から引いていく
      IF nn-base(dwn(j))>=0 THEN
         LET check(dwn(j))=1
         LET d=d+base(dwn(j))
         LET nn=nn-base(dwn(j))
      END IF
   NEXT j
   IF n=d THEN
      LET check(1)=(check(1)-1)^2 ! 0,1の入れ換え
      FOR j=1 TO 6
         PRINT number(j);
      NEXT j
      PRINT
      FOR j=1 TO 6
         IF check(j)=0 THEN PRINT " 赤 "; ELSE PRINT " 黒 ";
      NEXT j
      PRINT
   ELSE
      PRINT n;" この数は生成できません"
   END IF
NEXT n
DATA 11,22,44,1,2,4  ! base
DATA 3,2,1,6,5,4  ! baseの降順
END
 

Re: 挑戦状

 投稿者:山中和義  投稿日:2009年10月26日(月)16時57分39秒
返信・引用  編集済
  > No.676[元記事へ]

GAIさんへのお返事です。

!2^6通りのビットパターンは、通常0〜2^6-1の数に対応させる。
!この問題では、2^n 部分(重み)が、ビット位置と32,16,8,4,2,1の順番で対応いていない。
!だが、これをもとに生成されているものと仮定して、どのビットに対応しているか、グラフで確認する。

!6!通りの順列を生成して、より直線になるものが求める割付けとなる。
!まだ、この段階では重みは予想(近似値)となる。

!正解の重みを推測するためにグラフを検証する。(下図)
!重みは、(8,16,32,1,2,4)=(1*8,2*8,4*8,1,2,4) → (1*(8+3),2*(8+3),4*(8+3),1,2,4)=(11,22,44,1,2,4)
!げたは、10。
DIM W(6) !重み
DATA 32,16,8,4,2,1 !正解 11,22,44,1,2,4
MAT READ W

!1列目 010101 0:赤、1:黒
100 DATA 1,1,0,1,0,1, 48 !客が答えた赤黒のパターン、思っていた数
    DATA 0,0,0,1,0,1, 15
    DATA 0,1,1,1,0,1, 81
    DATA 0,1,0,0,0,1, 36
    DATA 0,1,0,1,1,1, 39
    DATA 0,1,0,1,0,0, 33

    !2列目 011110
    DATA 1,1,1,1,1,0, 90
    DATA 0,0,1,1,1,0, 57
    DATA 0,1,0,1,1,0, 35
    DATA 0,1,1,0,1,0, 78
    DATA 0,1,1,1,0,0, 77
    DATA 0,1,1,1,1,1, 83

    !3列目 100011
    DATA 0,0,0,0,1,1, 16
    DATA 1,1,0,0,1,1, 49
    DATA 1,0,1,0,1,1, 71
    DATA 1,0,0,1,1,1, 28
    DATA 1,0,0,0,0,1, 25
    DATA 1,0,0,0,1,0, 23

    !4列目 101101
    DATA 0,0,1,1,0,1, 59
    DATA 1,1,1,1,0,1, 92
    DATA 1,0,0,1,0,1, 26
    DATA 1,0,1,0,0,1, 69
    DATA 1,0,1,1,1,1, 72
    DATA 1,0,1,1,0,0, 66

    !5列目 001110
    DATA 1,0,1,1,1,0, 68
    DATA 0,1,1,1,1,0, 79
    DATA 0,0,0,1,1,0, 13
    DATA 0,0,1,0,1,0, 56
    DATA 0,0,1,1,0,0, 55
    DATA 0,0,1,1,1,1, 61

    !6列目 110011
    DATA 0,1,0,0,1,1, 38
    DATA 1,0,0,0,1,1, 27
    DATA 1,1,1,0,1,1, 93
    DATA 1,1,0,1,1,1, 50
    DATA 1,1,0,0,0,1, 47
    DATA 1,1,0,0,1,0, 45

    !7列目 111000
    DATA 0,1,1,0,0,0, 76
    DATA 1,0,1,0,0,0, 65
    DATA 1,1,0,0,0,0, 43
    DATA 1,1,1,1,0,0, 88
    DATA 1,1,1,0,1,0, 89
    DATA 1,1,1,0,0,1, 91

    SET WINDOW -5,100,-5,100

    DIM P(6)
    FOR t=0 TO fact(6)-1 !重みの順列を生成する
       CALL Num2Perm(t,P,6)

       RESTORE 100
       CLEAR
       DRAW grid(10,10)
       FOR d=1 TO 6*7 !サンプル・データより
          DIM B(6) !客が答えた赤黒のパターン
          MAT READ B
          READ y !思っていた数

          LET x=0 !線形写像
          FOR i=1 TO 6
             LET x=x+W(P(i))*B(i)
          NEXT i

          PLOT POINTS: x,y !より直線になるのが候補!
       NEXT d
       FOR i=1 TO 6 !重みの順列を表示する
          PRINT W(P(i));
       NEXT i
       PRINT

       WAIT DELAY 0.3 !※調整が必要

    NEXT t

 END


 !n!の順列パターン ⇔ 0〜(n!-1)の番号

 EXTERNAL FUNCTION Perm2Num(A(),N) !順列パターンに番号を付ける ※辞書式順序
    LET v=0
    FOR j=1 TO N-1 !※Nでは0
       LET t=A(j)
       LET v=v+fact(N-j)*(t-1)
       FOR k=j+1 TO N
          IF A(k)>t THEN LET A(k)=A(k)-1
       NEXT k
    NEXT j
    LET Perm2Num=v
 END FUNCTION

 EXTERNAL SUB Num2Perm(h, A(),N) !番号から順列パターンを生成する ※辞書式順序
    LET v=h
    FOR j=1 TO N
       LET fac=fact(N-j)
       LET t=INT(v/fac)
       LET A(j)=t+1 !1〜N
       LET v=v-fac*t
    NEXT j
    FOR j=N TO 1 STEP -1
       FOR k=j+1 TO N
          IF A(j)<=A(k) THEN LET A(k)=A(k)+1
       NEXT k
    NEXT j
 END SUB
 

Hamming Code の利用方法

 投稿者:GAI  投稿日:2009年10月26日(月)18時47分43秒
返信・引用  編集済
  見事に見破られてしまいました。
11,22,44,1,2,4
を生み出す関数として、よくもまあ
base(j)=2^MOD(j+2,3)+2^MOD(j+2,3)*10*(1-INT(j/3.01)) (j=1,2,3,4,5,6)
なるものをつくられましたね〜

現在この数字をトランプの札に置き換えてできる構成を思案中です。
できたらアップしたいと思います。

間違った部分を検出する方法としてハミングコードという概念が情報通信工学にあると聞いたことがありますが、これはこの問題を解析する上で利用できないものなんでしょうか?
またこのコードを利用する適当な例を紹介して頂けないでしょうか?
 

トランプでの試み

 投稿者:GAI  投稿日:2009年10月26日(月)21時30分52秒
返信・引用  編集済
  ♦8 (3,5) ♥3 (7,3) ♣Q (0,6) ♣9 (4,5) ♥8 (5,3) ♣8 (2,6) ♠Q (6,0)
♣10(0,5) ♠7 (4,3) ♦9 (3,6) ♥5 (7,5) ♥9 (6,3) ♣J (1,6) ♠10(5,0)
♥J (6,5) ♣A (2,3) ♦J (5,6) ♣4 (1,5) ♣K (0,3) ♥6 (7,6) ♠K (3,0)
♣6 (2,4) ♠8 (6,2) ♦A (1,7) ♠9 (5,4) ♠6 (4,2) ♦3 (3,7) ♥A (7,1)
♦2 (2,7) ♠J (6,1) ♣5 (1,4) ♦5 (5,7) ♠5 (4,1) ♣7 (3,4) ♥2 (7,2)
♠3 (2,1) ♦6 (6,7) ♣3 (1,2) ♠4 (5,1) ♦4 (4,7) ♠A (3,2) ♥4 (7,4)





と並べたカードから
1.客に一つのカードを心に思ってもらう。
2.そのカードがある列のカードの色を上から報告してもらうが、あえて自分のカードでは反対の色で報告する。
3.この客の報告を聞き終えて、即座に客が心に思ったカードを当てる。



(システム)
客が報告する6個の色のうち、最初の3個に1,2,4の重みをつけ、黒と報告された部分だけをこのキー数字を掛けて加えた値をaとする。
同じく後半の3個の色で黒と報告があった部分に同じく1,2,4の重みを掛けて加えた値をbとする。
上の表の中の(*、*)がこの計算で決まる(a,b)になる。


<選んだカードのマークの判定>
♦: (3,5),(3,6),(5,6),(*,7)

♥: (5,3),(6,3),(6,5),(7,*)

♣: 上の組み合わせ以外の (a,b)でa<bの時

♠:                         (a,b)でa>bの時

<選んだカードの数字の算出>
ほとんどは(a,b)の和a+bから決める。
(7,*)と(*,7)に関しては*にある方の数字。
(2,3),(3,2),(1,5),(5,1)は差|a-b|から1(=A)と4
(0,5),(5,0)→10(5の2倍で覚える)
(1,6),(6,1)→J(少し特殊)
(0,6),(6,0)→Q(6の2倍で覚える)
(0,3),(3,0)→K(3で13と覚える)
 

面白いものが、あった。

 投稿者:SECOND  投稿日:2009年10月27日(火)08時06分29秒
返信・引用
  !これだけで、Web 上の 十進BASIC プログラムが走る。

execute "sysya.exe" WITH("/G","/C-","http://homepage2.nifty.com/neutro/asm/bitop3.asm" )
execute "sysya.exe" WITH("/G","/C-","http://homepage2.nifty.com/neutro/asm/bitop3.dll" )
execute "sysya.exe" WITH("/G","/C-","http://homepage2.nifty.com/neutro/asm/bitop3.bas" )
!
execute "basic.exe" WITH("/NR","bitop3.bas") !ファイルを開いて起動。"/OR" …起動、実行。

END
!sysya.exe のダウンロード先
!http://www.vector.co.jp/soft/win95/net/se394679.html
 

Re: 面白いものが、あった。

 投稿者:GAI  投稿日:2009年10月27日(火)19時24分30秒
返信・引用
  > No.681[元記事へ]

SECONDさんへのお返事です。

この使い方を詳しく説明して頂けませんか?
一応ダウンロードして使おうとしたのですが、どうしてよいのか分かりませんでした。
従来の十進BASICとなにがどう違うのでしょうか?
 

BMPファイルから切出し表示

 投稿者:哲  投稿日:2009年10月28日(水)08時20分1秒
返信・引用
  時々、掲示板を見ているのですが最近の内容の広さと深さに驚いています。
そこで、深い理解を持っておられる方々の知恵をお借りしたいのですが

5000×4500のBMPファイルがあるのですが
このファイルからXからX+500,YからY+450の部分を切出してグラフィック画面に表示したいのですがで、きますでしょうか?
これができると必要な部分だけを利用して処理できるようになるので非常に助かるのですが、よろしくお願いします。
 

Re: 面白いものが、あった。

 投稿者:SECOND  投稿日:2009年10月28日(水)17時11分24秒
返信・引用  編集済
  > No.682[元記事へ]

GAIさんへ

これは、プログラム自身が、インターネット上の十進BASICブログラムや、テキスト、その他
を、自動で読み取って実行する例で、遠隔制御などの、応用が期待できるものです。
サイトから、手で、コピー貼りつけ実行できる状況下では、あまり意味の無いツールです。

bitop3.bas は、画面に出てきましたでしょうか?

ダウンロード解凍された SYSYA.EXE は、パス名を省略したため、
BASIC を起動したフォルダ(多くは、BASIC.EXE の有る場所)
に同居している必要があります。レジストリーは、汚さないようです。
 

Re: BMPファイルから切出し表示

 投稿者:山中和義  投稿日:2009年10月28日(水)20時31分50秒
返信・引用  編集済
  > No.683[元記事へ]

哲さんへのお返事です。

速度の検証など(改善は期待できない)のプロトタイプとして掲載します。
!BMPファイル(圧縮なし)画像の部分領域(切り出し)を表示する
!参考 http://www.kk.iij4u.or.jp/~kondo/bmp/

OPTION CHARACTER byte


LET CX1=0 !切り出す画像領域の左上座標(ピクセル単位)
LET CY1=0
LET CX2=640 !右下座標
LET CY2=480

SET COLOR mode "NATIVE"
SET bitmap SIZE CX2-CX1,CY2-CY1 !スクリーン座標へ
SET WINDOW 0,CX2-CX1-1,CY2-CY1-1,0 !画面を画像サイズへ
SET POINT STYLE 1 !ドット形式


LET BFile$=REPEAT$(CHR$(0),14) !Dim BFile As BITMAPFILEHEADER
LET BInfo$=REPEAT$(CHR$(0),40) !Dim BInfo As BITMAPINFOHEADER
LET BPalt$=REPEAT$(CHR$(0),4) !Dim BPalt As RGBQUAD


file getname f$,"BMPファイル|*.BMP" !ファイル名を得る
IF f$="" THEN STOP


OPEN #1: NAME f$, ACCESS INPUT
LET cp=0 !読み込み現在位置

!---------- ファイルヘッダ部
LET p=0 !読み込み位置
CALL fseek(p) !Get #1,0,BFile ※VisualBasic
CALL fread(BFile$,p)

IF BFile$(1:2)="MB" THEN !BFile.bfType
   PRINT "BMPファイルではありません。"
   STOP
END IF
LET bfOffBits=CVI(BFile$,10,4) !BFile.bfOffBits
PRINT "bfOffBits=";bfOffBits
PRINT


!---------- 情報ヘッダ部(Windows Bitmap)
CALL fread(BInfo$,p) !Get #1, ,BInfo

LET biWidth=CVI(BInfo$,4,4) !BInfo.biWidth
PRINT "biWidth=";biWidth
LET biHeight=CVI(BInfo$,8,4) !BInfo.biHeight
PRINT "biHeight=";biHeight
LET biBitCount=CVI(BInfo$,14,2) !BInfo.biBitCount
PRINT "biBitCount=";biBitCount
LET biCompression=CVI(BInfo$,16,4) !BInfo.biCompression
PRINT "biCompression=";biCompression
PRINT


!---------- 情報ヘッダ部(パレット部)
DIM PAL(0 TO 255,4)
IF biBitCount<=8 THEN
   FOR k=0 TO 2^biBitCount-1
      CALL fread(BPalt$,p) !Get #1, ,BPalt

      !!PRINT USING "### 番 ": k;
      !!PRINT CVI2(BPalt$,0,1), !BPalt.rgbBlue ※符号なし
      !!PRINT CVI2(BPalt$,1,1), !BPalt.rgbGreen
      !!PRINT CVI2(BPalt$,2,1), !BPalt.rgbRed
      !!PRINT CVI2(BPalt$,3,1) !BPalt.rgbReserved

      LET PAL(k,3)=CVI2(BPalt$,0,1)/255 !BPalt.rgbBlue ※符号なし
      LET PAL(k,2)=CVI2(BPalt$,1,1)/255 !BPalt.rgbGreen
      LET PAL(k,1)=CVI2(BPalt$,2,1)/255 !BPalt.rgbRed
      LET PAL(k,4)=CVI2(BPalt$,3,1)/255 !BPalt.rgbReserved
   NEXT k
END IF
PRINT


IF biCompression<>0 THEN
   PRINT "圧縮形式は未サポートです。"
   STOP
END IF


!---------- 画像データ部
!SET DRAW mode hidden !ちらつき防止の開始

LET p=bfOffBits !ファイル内の画像データの先頭位置
CALL fseek(p)

LET L1=biWidth*biBitCount/8
LET L1b=(INT((L1-1)/4)+1)*4 !4バイト境界

FOR y=1 TO biHeight
   LET BData$=REPEAT$(CHR$(0),L1b) !1行分の画像データ
   CALL fread(BData$,p) !Get #1, ,BData

   IF y>=biHeight-CY2 AND y<=biHeight-CY1 THEN !切り出し領域内なら ※下から格納されている

      SELECT CASE biBitCount
      CASE 1 !2色

         FOR x=MAX(INT((CX1-1)/8),0) TO L1b-1 !1行分の画像データ(切り出し領域内左端から)

         !!PRINT "(";8/biBitCount*x+1;",";y;")",
            LET b=CVI2(BData$,x,1)
            !!!PRINT right$("0000000"&BSTR$(b,2),8)

            LET t$=right$("0000000"&BSTR$(b,2),8)
            LET bb=1
            DO UNTIL bb>8
               LET xx=x*8+bb-1
               IF xx>CX2 THEN EXIT FOR !切り出し領域内右端なら
               IF xx>=CX1 THEN
                  IF xx<=biWidth THEN
                     LET t=VAL(t$(bb:bb))
                     SET POINT COLOR colorindex(PAL(t,1),PAL(t,2),PAL(t,3))
                     PLOT POINTS: xx - CX1, biHeight-y - CY1 !※下から格納されている
                  END IF
               END IF
               LET bb=bb+1
            LOOP

         NEXT x

      CASE 4 !16色

         FOR x=MAX(INT((CX1-1)/2),0) TO L1b-1 !1行分の画像データ(切り出し領域内左端から)

         !!PRINT "(";8/biBitCount*x+1;",";y;")",
            LET b=CVI2(BData$,x,1)
            !!PRINT INT(b/16); !上4bit
            !!PRINT MOD(b,16) !下4bit

            LET xx=8/biBitCount*x+1

            IF xx>CX2 THEN EXIT FOR !切り出し領域内右端なら
            IF xx>=CX1 THEN
               IF xx<=biWidth THEN
                  LET t=INT(b/16) !上4bit
                  SET POINT COLOR colorindex(PAL(t,1),PAL(t,2),PAL(t,3))
                  PLOT POINTS: xx - CX1, biHeight-y - CY1 !※下から格納されている
               END IF
            END IF
            IF xx+1>CX2 THEN EXIT FOR !切り出し領域内なら
            IF xx+1>=CX1 THEN
               IF xx<=biWidth THEN
                  LET t=MOD(b,16) !下4bit
                  SET POINT COLOR colorindex(PAL(t,1),PAL(t,2),PAL(t,3))
                  PLOT POINTS: xx+1 - CX1, biHeight-y - CY1 !※下から格納されている
               END IF
            END IF

         NEXT x

      CASE ELSE !256色、24ビット色、32ビット色

         FOR x=MAX(CX1,1) TO MIN(CX2,biWidth) !切り出し領域内

            LET t=(x-1)*biBitCount/8

            !!PRINT "(";x;",";y;")",
            !!FOR k=0 TO biBitCount/8-1
            !!   PRINT CVI2(BData$,t+k,1); !BData ※符号なし
            !!NEXT k
            !!PRINT

            IF biBitCount=8 THEN !256色なら
               LET tt=CVI2(BData$,t+0,1)
               SET POINT COLOR colorindex(PAL(tt,1),PAL(tt,2),PAL(tt,3))
            ELSE
               LET bb=CVI2(BData$,t+0,1) !BData ※符号なし
               LET gg=CVI2(BData$,t+1,1)
               LET rr=CVI2(BData$,t+2,1)
               SET POINT COLOR colorindex(rr/255,gg/255,bb/255)
            END IF
            PLOT POINTS: x - CX1, biHeight-y - CY1 !※下から格納されている

         NEXT x

      END SELECT

   END IF

NEXT y

!SET DRAW mode explicit !ちらつき防止の終了


CLOSE #1


!ファイル関連
SUB fseek(p) !読み込み位置を設定する
   IF p<cp THEN !前へ
      SET #1: POINTER BEGIN
      LET cp=0
   END IF
   FOR i=1 TO p-cp !skip it
      CHARACTER INPUT #1: tmp$
   NEXT i
   LET cp=p !現在位置の更新
END SUB
SUB fread(r$,p) !レコードを読み込む
   FOR i=1 TO LEN(r$) !read it
      CHARACTER INPUT #1: r$(i:i)
   NEXT i
   LET p=p+LEN(r$) !現在位置の更新
   LET cp=p
END SUB

END


EXTERNAL FUNCTION CVI(s$,p,m) !文字列に埋め込まれたm*8ビット符号付き整数を取り出す
OPTION CHARACTER byte
LET n=0
FOR i=1 TO m
   LET n=n+256^(i-1)*ORD(s$(p+i:p+i))
NEXT i
IF n<2^(m*8-1) THEN LET CVI=n ELSE LET CVI=n-2^(m*8)
END FUNCTION
EXTERNAL FUNCTION CVI2(s$,p,m) !文字列に埋め込まれたm*8ビット符号なし整数を取り出す
OPTION CHARACTER byte
LET n=0
FOR i=1 TO m
   LET n=n+256^(i-1)*ORD(s$(p+i:p+i))
NEXT i
LET CVI2=n
END FUNCTION
 

Re: BMPファイルから切出し表示

 投稿者:SECOND  投稿日:2009年10月29日(木)03時05分54秒
返信・引用  編集済
  > No.683[元記事へ]

哲さんへ

!十進BASIC のグラフ機能だけでの処理ですが、5000 x 4500 は、どんなでしょう。

OPTION ARITHMETIC NATIVE
SET COLOR mode "NATIVE"
OPTION BASE 0
DIM D(1000,1000)
ASK directory currentD$
!
SET directory "C:\WINDOWS\デスクトップ" !最初に開くdirectory(削除:マイドキュメント)
FILE GETNAME file$, "BMP"
IF file$="" THEN
   PRINT "入力ファイル名無しで、中止。"
   STOP
END IF
PRINT "入力ファイル:"& file$
!
!---原画をロード、グラフ座標を、左上から右下方向へ画素単位に設定
gload file$
ASK PIXEL SIZE xw,yw
SET WINDOW 0,xw,yw,0
PRINT xw+1;"*";yw+1;"画素の原画"
!
!---原画から、切出したい画素の範囲を書く
LET X0=10   !左
LET Y0=20   !上
LET X1=200  !右
LET Y1=200  !下
!
!---切り出し
MAT D=ZER(X1-X0,Y1-Y0)
ASK PIXEL ARRAY (X0,Y0) D
!
!---切り出し画像の表示
SET bitmap SIZE X1-X0+1,Y1-Y0+1
MAT PLOT CELLS,IN 0,1;1,0 :D
PRINT "(";X0;",";Y0;")から、";"(";X1;",";Y1;")までの切り出し画像"
!
!---切り出し画像の保存と、再表示
SET directory currentD$
gsave "sample.bmp"
gload "sample.bmp"
SET bitmap SIZE 501,501

END
 

FILE GETNAME について

 投稿者:SECOND  投稿日:2009年10月29日(木)03時39分42秒
返信・引用
  FILE GETNAME で、「すべてのピクチャ ファイル」を設定する方法は、ありますか?  

Re: FILE GETNAME について

 投稿者:山中和義  投稿日:2009年10月29日(木)07時16分22秒
返信・引用  編集済
  > No.687[元記事へ]

SECONDさんへのお返事です。

> FILE GETNAME で、「すべてのピクチャ ファイル」を設定する方法は、ありますか?

すべての画像ファイルは指定できませんので、必要なものを列挙してください。
記述は、Win32APIに準拠します。
!フィルタ部分の記述
file getname s$, "画像ファイル|*.BMP;*.GIF;*.JPG"

!file getname s$, "*.BMP;*.GIF" !「ファイルの種類」の名称がないので、NG
!file getname s$, "BMP;GIF" !個々の「ファイル名」(拡張子付きファイル指定)がないので、NG

END
!ファイルの種類を分類したフィルタ部分の記述
file getname s$, "画像ファイル|*.BMP;*.GIF|ピクチャファイル|*.JPG"

END
 

Re: BMPファイルから切出し表示

 投稿者:哲  投稿日:2009年10月29日(木)08時23分15秒
返信・引用
  > No.686[元記事へ]

山中さんへ
見事な調査と解析をしてくださってありがとうございます。
残念ながら処理時間が掛かり過ぎるようなので使うことができませんでした。

SECONDへ
正にこれです!!!
見事に指定範囲が表示できました。
切出し方法がわからず悩んでいたのですがこんな使い方があったとは知りませんでした。
色々、調べていたのですがAPIでBMPの指定範囲を呼び出すことができそうだったのですが使用例が見つからず扱いきれませんでした。

これで短時間で処理が可能となって非常に助かりました。
本当にありがとうございました。
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年10月29日(木)10時19分2秒
返信・引用
  > No.670[元記事へ]

補習 二項係数、二項定理、パスカルの三角形
!●パターン2 左斜めと右斜めが、行と列に置き換わる

!※格子状経路の経路の数などを求める場合など、配列全体を埋めておくのがよい。

LET M=20 !行
LET N=6 !列

DIM P(0 TO M,0 TO N) !2次元配列

MAT P=ZER
FOR j=0 TO N !反時計まわりに45度回転
   LET P(0,j)=1 !comb(n,n)=comb(n,0)=1
NEXT j
FOR i=1 TO M
   LET P(i,0)=1 !comb(n,n)=comb(n,0)=1
   FOR j=1 TO N !comb(n,r)=comb(n-1,r-1)+comb(n-1,r)
      LET P(i,j)=P(i,j-1)+P(i-1,j) !左+上 ※表計算Excelでは、オートフィル機能
   NEXT j
NEXT i

MAT PRINT USING(REPEAT$("###### ",N+1)): P !※桁数が多い場合、#を増やす
PRINT


!例. 連続する自然数の積和
! 1*2+2*3+3*4+ … +n*(n+1)=Σ[k=1,n]{k*(k+1)}
! 1*2*3+2*3*4+3*4*5+ … +n*(n+1)*(n+2)=Σ[k=1,n]{k*(k+1)*(k+2)}
!   :
!   :
!
! comb(n,r)=n*(n-1)*(n-2)* … *(n-r+1)/r!より、r!*comb(n+r-1,r)=n*(n+1)*(n+2)* … *(n+r-1)
!
!パスカルの三角形では、
!             ↓R
! comb(n-1,0) comb(n,1) comb(n+1,2) comb(n+2,3) comb(n+4,4) …
! 1      1     1      1      1
! 1      2     3      4      5
! 1      3     6      10     15
! 1      4     10 N-1 → 20     35
! 1      5     15     35     70
! 1      6     21     56     126
! 1      7     28     84     210
!
! 右斜めr段の数列 comb(n+(r-1),r) の和は、r+1段。

LET N=15
LET R=2 !2つの場合
PRINT fact(R)*P(N-1,R+1)


LET s=0 !検算
FOR k=1 TO N
   LET s=s+k*(k+1) !Σ[k=1,n]{k*(k+1)}
NEXT k
PRINT s


END

!●7^2009の下4桁

OPTION ARITHMETIC RATIONAL !多桁整数

!7*7=49=50-1より、7^2000=(50-1)^1000
!これを二項定理で展開すると、
! 項 comb(1000,r)*50^r*(-1)^(1000-r)、r=0,1,2,3,…
!の和となる。

!r=4以上、50^rが10000で割り切れるから、下4桁はすべて0となる。
LET s=0

!r=3,2,1,0のとき
FOR r=3 TO 0 STEP -1
   LET s=s + comb(1000,r)*50^r*(-1)^(1000-r)
NEXT r

PRINT MOD(s*7^9,10^5) !残り7^9を加味して

END
 

Re: FILE GETNAME について

 投稿者:SECOND  投稿日:2009年10月29日(木)13時16分28秒
返信・引用
  > No.688[元記事へ]

山中さんへ

助かりました、半ばあきらめていましたので、感激です。ありがとうございました。
今後もおねがいします。
 

挑戦状2

 投稿者:GAI  投稿日:2009年10月30日(金)13時40分17秒
返信・引用
  0〜15から一つの数を心に決めてもらう。
A〜Eカードを見せて、その数がある、なしを答えてもらう。
さてそのカードを当てる仕組みとは?


<Aカード>
11  10  12
15   4   0
11   7  10

<Bカード>
 3   9   7
 8   2  12
13   9  14

<Cカード>
 7   9   0
12   1   3
11   8  14

<Dカード>
12  14   5
13   5  15
 8   0  14

<Eカード>
 9  10  11
10   6  14
13   0  15
 

Re: 挑戦状2

 投稿者:山中和義  投稿日:2009年10月30日(金)15時01分36秒
返信・引用
  > No.692[元記事へ]

GAIさんへのお返事です。

重み(A,B,C,D,E)=(4,2,1,5,6)、「ある」の場合に加算する。ただし、合計16→0とする。
A,B,C,D,E
1,0,1,1,1, 0
0,0,1,0,0, 1 ←
0,1,0,0,0, 2 ←
0,1,1,0,0, 3
1,0,0,0,0, 4 ←
0,0,0,1,0, 5 ←
0,0,0,0,1, 6 ←
1,1,1,0,0, 7
0,1,1,1,0, 8
0,1,1,0,1, 9
1,0,0,0,1, 10
1,0,1,0,1, 11
1,1,1,1,0, 12
0,1,0,1,1, 13
0,1,1,1,1, 14
1,0,0,1,1, 15
 

Hamming Code

 投稿者:SECOND  投稿日:2009年10月30日(金)15時56分37秒
返信・引用  編集済
  !GAIさんの、投稿にありました ハミング・コード についての実験。

! コード自身が、1bit までの誤りビットを、特定する仕組みを、動かしてみます。
! http://www1.seaple.ne.jp/tomizawa/err-correct.doc  に詳しい説明があります。

! データーが縦に伸びる 列ベクトルは、表示の難があり、行列は、逆にしています。
! プログラムは、冗長ビット4での最大全長14ビット の場合の例です。

DIM M(1,14), h(14,4), bcc(1,4)

PRINT "--- パリティ 行列 h"
MAT READ h
DATA 0,0,0,1  !  1  ! 0 は エラー無しの予約値。
DATA 0,0,1,0  !  2
DATA 0,0,1,1  !  3
DATA 0,1,0,0  !  4
DATA 0,1,0,1  !  5
DATA 0,1,1,0  !  6
DATA 0,1,1,1  !  7
DATA 1,0,0,0  !  8
DATA 1,0,0,1  !  9
DATA 1,0,1,0  ! 10
DATA 1,0,1,1  ! 11
DATA 1,1,0,0  ! 12
DATA 1,1,0,1  ! 13
DATA 1,1,1,0  ! 14  !オール1の、15 も使用できない。(※注)

MAT PRINT h;
PRINT "上の、14 x 4 の行列 h を、"
PRINT
PRINT "メッセージ・データー 14bit長"
PRINT "     (1行 14 列 のベクトル)に乗ずると、"
PRINT "  チェック・データー  4bit長"
PRINT "      (1行 4 列 のベクトル)が出来る。"
PRINT

MAT READ M                        ! メッセージ・データー 14bit長
DATA 1,1,0,1,0,0,1,1,0,1, 0,0,0,0 ! 左 10bit長 が、任意で、適当に変えてみるとよい。

! メッセージ・データー 14bit長 を、行ベクトル( m1,m2,m3,,,m14 ) として、
! 行列 h を右に置いて乗ずると、bcc1,bcc2,bcc3,bcc4 …4要素の行ベクトル、
! チェック・データー ができる。この時の積和の計算は、
! 1ビット幅の桁上り無し。 排他的論理和 xor や、Modulo2 の和 =MOD( … ,2)
! で行い、4要素は、4bit として求める。これが常に、0000 となる条件が必要です。
!
! そのために、次のような代数式を解く。加算は、桁上り無しの1ビット幅( modulo 2)
!「行列乗算で計算する過程、右(左?)90度回した状態」
!
!(1) 0= m1   +m3   +m5   +m7   +m9    +m11    +m13
!(2) 0=    m2+m3      +m6+m7      +m10+m11        +m14
!(3) 0=          m4+m5+m6+m7              +m12+m13+m14
!(4) 0=                      m8+m9+m10+m11+m12+m13+m14
!
!(3)+(4)     0=m4+m5+m6+m7+m8+m9+m10 +m11   (同じものを加算すると0になる。)
!(1)+(2)+(3) 0=m1+m2+m4+m7+m9+m10    +m12
!(1)+(3)+(4) 0=m1+m3+m4+m6+m8+m10    +m13
!(2)+(3)+(4) 0=m2+m3+m4+m5+m8+m9     +m14
!
! 14 bit の右端 4bit を、下の様に従属させると、左 10bit は、自由に
! 選んでも、上の、0000 となる条件を、満たす事ができる。

LET M(1,11)=MOD( M(1,4)+M(1,5)+M(1,6)+M(1,7)+M(1,8)+M(1,9)+M(1,10) ,2)
LET M(1,12)=MOD( M(1,1)+M(1,2)+M(1,4)+M(1,7)+M(1,9)+M(1,10) ,2)
LET M(1,13)=MOD( M(1,1)+M(1,3)+M(1,4)+M(1,6)+M(1,8)+M(1,10) ,2)
LET M(1,14)=MOD( M(1,2)+M(1,3)+M(1,4)+M(1,5)+M(1,8)+M(1,9) ,2)

!-----エラー・ビットを、順番に置いてみる。0:エラー無しから1〜14まで
FOR j=0 TO 14
   CALL error(j)
NEXT j

SUB error(j)
   PRINT "-------------------------------------"
   PRINT "原形のメッセージ・データー"
   MAT PRINT M;
   IF j<>0 THEN
      LET back=M(1,j)
      PRINT "左から";j;"番目のビットが、反転すると"
      IF M(1,j)=1 THEN LET M(1,j)=0 ELSE LET M(1,j)=1
   ELSE
      PRINT "全ビット反転なければ、"
   END IF
   MAT PRINT M;
   !---
   CALL check
   !---
   PRINT "チェック・データーも";bcc(1,1)*8+bcc(1,2)*4+bcc(1,3)*2+bcc(1,4);"になる。2進数"
   MAT PRINT bcc;
   IF j<>0 THEN LET M(1,j)=back !元へ戻す
END SUB

SUB check
   MAT bcc=M*h
   FOR i=1 TO 4
      LET bcc(1,i)=MOD( bcc(1,i), 2)
   NEXT i
END SUB

END

!(※注)
! 書物の、2^(m:冗長ビット) >= (n:データービット)+(m:冗長ビット)+1 の式からは、
! m=4 の場合、n=11 までとなるが、文中の「!オール1の、15」を使用する事に相当し、
! メッセージ・データーの中に m4+m5+m6+m7+m8+m9+m10+m11=0 の条件が発生する。
! (m:冗長ビット)を越えて、制約が入り、11bit が、自由に選べない結果となった。
! 式の等号は、外すべきではないか?
 

どこまでも精度を高めて

 投稿者:GAI  投稿日:2009年10月30日(金)23時43分8秒
返信・引用
  計算機にて
((log(640320^3+744))/π)^2
は計算できますか?
そしてまた、その値を信じますか?

さらにe^(π*√163)も計算できますか?(eは自然対数の底)
 

Re: どこまでも精度を高めて

 投稿者:山中和義  投稿日:2009年10月31日(土)07時36分45秒
返信・引用  編集済
  > No.695[元記事へ]

GAIさんへのお返事です。

1000桁モードで実行してください。
DECLARE EXTERNAL FUNCTION LOG
DECLARE EXTERNAL FUNCTION EXP

PRINT ((LOG(640320^3+744))/PI)^2 !163 ?
PRINT EXP(PI*SQR(163)) !640320^3+744 ?

END

MERGE "log.lib"
MERGE "exp.lib"

!((LOG(640320^3+744))/PI)^2=163.000000000000000000000000000023216777…
!EXP(PI*SQR(163))=262537412640768743.999999999999250072…
 

完全覆面算

 投稿者:GAI  投稿日:2009年10月31日(土)17時48分17秒
返信・引用
       ☐☐☐
 ☓  ☐☐☐
  -------------
    ☐☐☐
   ☐☐☐
 +☐☐☐
 ---------------
    ☐☐☐☐☐

の覆面算で☐には0〜9の数字が各々2回ずつ入ります。
この3桁どうしの掛け算はなにか探せますか?
 

Re: 完全覆面算

 投稿者:山中和義  投稿日:2009年10月31日(土)19時32分26秒
返信・引用  編集済
  > No.697[元記事へ]

GAIさんへのお返事です。
No. 1
 179
×224
-----
 716
 358
358
-----
40096

解析に使ったプログラムを掲載します。参考にしてください。
!虫食い算

!  □□□ ← i 被乗数
! x□□□ ← j 乗数
! --------
!  □□□ ← a 途中結果1
! □□□  ← b 途中結果2
!□□□   ← c 途中結果3
!----------
!□□□□□ ← d 結果


LET t0=TIME


DEF fnFIG(x,n)=MOD(INT(x/10^n),10) !n桁目の数を得る ※0:一の位、1:十の位、2:百の位、…

LET ANSWER_COUNT=0 !解答数

DIM nm(0 TO 9),nm_sav(0 TO 9) !0〜9の数字の重複を確認する

FOR i=100 TO 999 !被乗数
   MAT nm=ZER

   FOR k=0 TO 2 !重複チェック ※2つずつ
      LET t=fnFIG(i,k) !各桁の数字を得る
      IF nm(t)=2 THEN GOTO 200 !既に2つある!
      LET nm(t)=nm(t)+1
   NEXT k


   FOR j=100 TO 999 !乗数
      MAT nm_sav=nm !save it

      FOR k=0 TO 2 !重複チェック
         LET t=fnFIG(j,k)
         IF nm(t)=2 THEN GOTO 100
         LET nm(t)=nm(t)+1
      NEXT k


      LET a=i*MOD(j,10) !乗数の一の位との積
      IF a<100 OR a>999 THEN GOTO 100 !途中結果1は3桁の数?
      FOR k=0 TO 2 !重複チェック
         LET t=fnFIG(a,k)
         IF nm(t)=2 THEN GOTO 100
         LET nm(t)=nm(t)+1
      NEXT k


      LET b=i*MOD(INT(j/10),10) !乗数の十の位との積
      IF b<100 OR b>999 THEN GOTO 100 !途中結果2は3桁の数?
      FOR k=0 TO 2 !重複チェック
         LET t=fnFIG(b,k)
         IF nm(t)=2 THEN GOTO 100
         LET nm(t)=nm(t)+1
      NEXT k


      LET c=i*INT(j/100) !乗数の百の位との積
      IF c<100 OR c>999 THEN GOTO 100 !途中結果3は3桁の数?
      FOR k=0 TO 2 !重複チェック
         LET t=fnFIG(c,k)
         IF nm(t)=2 THEN GOTO 100
         LET nm(t)=nm(t)+1
      NEXT k


      LET d=i*j !被乗数*乗数=乗算結果
      IF d<10000 OR d>99999 THEN GOTO 100 !結果は5桁の数?
      FOR k=0 TO 4 !重複チェック
         LET t=fnFIG(d,k)
         IF nm(t)=2 THEN GOTO 100
         LET nm(t)=nm(t)+1
      NEXT k


      LET ANSWER_COUNT=ANSWER_COUNT+1 !解答数
      PRINT "No.";ANSWER_COUNT

      PRINT USING " ###":i !結果の表示
      PRINT USING "×###":j
      PRINT "-----"
      PRINT USING " ###":a
      PRINT USING " ### ":b
      PRINT USING "###  ":c
      PRINT "-----"
      PRINT USING "#####":d
      PRINT


100       !continue
          MAT nm=nm_sav !restore it
       NEXT j

200    !continue
    NEXT i


    PRINT "計算時間=";TIME-t0

 END
 

グッドスタインの定理の検証

 投稿者:GAI  投稿日:2009年10月31日(土)20時10分12秒
返信・引用  編集済
  覆面算はすぐに見破られてしまいました。
そこで、次の定理がどこまで計算機で確認可能かお願いします。

任意の自然数を一つ選ぶ(例:1077)
これを2進数で表す。(1077=2^10+2^5+2^4+2^2+1)
さらに指数も2進表示する。(=2^(2^3+2)+2(2^2+1)+2^(2^2)+2^2+1)
指数部分に残る3もさらに2の累乗形で表す。(=2^(2^(2+1)+2)+2(2^2+1)+2^(2^2)+2^2+1)・・��

こうして書き換えた形�,紡个靴董⊆,竜�則を交互に繰り返す。
(A) 基底を1大きくする。
(B) (A)で出来た数から1を引く。

例を用いると
(A):3^(3^(3+1)+3)+3^(3^3+1)+3^(3^3)+3^3+1
(B): 3^(3^(3+1)+3)+3^(3^3+1)+3^(3^3)+3^3
(A): 4^(4^(4+1)+4)+4^(4^4+1)+4^(4^4)+4^4
(B): 4^(4^(4+1)+4)+4^(4^4+1)+4^(4^4)+3*4^3+3*4^2+3*4+3
(A): 5^(5^(5+1)+5)+5^(5^5+1)+5^(5^5)+3*5^3+3*5^2+3*5+3
(B): 5^(5^(5+1)+5)+5^(5^5+1)+5^(5^5)+3*5^3+3*5^2+3*5+2
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
と繰り返していくと数は無限に大きくなる印象をあたえるが、いつかは最大値に達し、その後はどんどん小さくなっていき最後はゼロになるらしい。
(グッドスタインの定理)
これを確かめてもらいたい。
 

Re: グッドスタインの定理の検証

 投稿者:山中和義  投稿日:2009年11月 1日(日)10時10分0秒
返信・引用
  > No.699[元記事へ]

GAIさんへのお返事です。
!グッドスタインの定理(R.L.Goodstein)

!ウィキペディアより
!http://www.cwi.nl/~tromp/pearls.html#goodstein のRuby版を移植

FUNCTION s(b,e,n)
   IF n=0 THEN LET s=0 ELSE LET s=MOD(n,b)*(b+1)^s(b,0,e)+s(b,e+1,INT(n/b))
END FUNCTION
FUNCTION g(b,n)
   IF n=0 THEN LET g=b ELSE LET g=g(b+1,s(b,0,n)-1)
END FUNCTION
DEF f(n)=g(2,n) !自然数nに対する0になるときの底を返す

PRINT f(0) !f(0)=2,f(1)=3,f(2)=5,f(3)=7
PRINT f(1)
PRINT f(2)
PRINT f(3)

PRINT f(4) !f(4)=3*2^402653211-1 ※スタック・オーバーフロー

END

スタック・オーバーフローが回避できればいいのですが、、、(再帰処理を繰り返し処理に置き換える)

また、数値計算だと巨大な数を扱うことになるので、数式計算(代数計算)を行えば可能かと思います。
 

マジックへの原理を求めて

 投稿者:GAI  投稿日:2009年11月 1日(日)12時48分46秒
返信・引用
  次々と出題して申し訳ありませんが、次の現象についての調査をお願いします。

1からnまでの数字が書かれたn枚のカードがあり、これを十分にシャッフルする。
トップあるカードを調べその数字だけカードを抜き出し、順番を逆にして元に戻す。
これを繰り返していくと、必ず1がトップに出現する。
これまでにかかる手数が最長になるのは何手かかるかを調べたい。
また、最長手数がかかる初期順列が知りたい。
n枚の場合に分けて(少なくとも13枚までは)結果が知りたいのでよろしくお願いします。
 

Re: マジックへの原理を求めて

 投稿者:山中和義  投稿日:2009年11月 1日(日)14時46分51秒
返信・引用  編集済
  > No.701[元記事へ]

GAIさんへのお返事です。

13の階乗は、マシンパワーがいりますが、、、
LET t0=TIME


LET N=9 !枚数

DIM P(N) !1〜Nまでのカード

LET cmax=0
FOR i=N*fact(N-2) TO fact(N)-1 !順列を生成する ※0〜N*(N-2)!-1番目の順列は、1*****、21****
!FOR i=0 TO fact(N)-1 !順列を生成する

   CALL Num2Perm(i, P,N)
   !!!MAT PRINT P; !debug

   LET c=0 !回数
   DO UNTIL P(1)=1 !トップのカードが「1」まで
      CALL reverse(P,(P(1))) !トップのカードの数字だけカードを抜き出し、順番を逆にして元に戻す
      LET c=c+1
   LOOP
   !!!PRINT "回数=";c !debug
   IF c>cmax THEN !最大のものを記録する
      LET cmax=c
      LET i_sav=i
   END IF

NEXT i

PRINT "最大の回数=";cmax
CALL Num2Perm(i_sav, P,N) !順列を再現する
MAT PRINT P;


PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB reverse(A(),N) !1〜Nまでの並びを逆順にする
FOR i=1 TO INT(N/2) !交換位置は半分まで ※全部すると元に戻る
   swap A(i),A(N-i+1) !中央から対称な位置どうし
NEXT i
END SUB

EXTERNAL SUB Num2Perm(h, A(),N) !番号から順列パターンを生成する ※辞書式順序
LET v=h
FOR j=1 TO N
   LET fac=fact(N-j)
   LET t=INT(v/fac)
   LET A(j)=t+1 !1〜N
   LET v=v-fac*t
NEXT j
FOR j=N-1 TO 1 STEP -1
   FOR k=j+1 TO N
      IF A(j)<=A(k) THEN LET A(k)=A(k)+1
   NEXT k
NEXT j
END SUB
 

Re: マジックへの原理を求めて

 投稿者:GAI  投稿日:2009年11月 2日(月)06時07分35秒
返信・引用
  > No.702[元記事へ]

山中和義さんへのお返事です。

N=11まで調査しましたが、N=12,13では極端に時間がかかっているようです。
(全パターンを調査しているからなんでしょうね)
調べ物をしていたら、最長手数が判明しました。
そこでこのデータを利用して、その手数がかかる初期順列が知りたいのでプログラムを修正して頂けないでしょうか?
多分時間の節約が可能になると思うんですが。

     <最長手数>
N=12・・・・65回
N=13・・・・80回
N=14・・・101回
N=15・・・113回
N=16・・・139回
 

Re: マジックへの原理を求めて

 投稿者:山中和義  投稿日:2009年11月 2日(月)08時07分3秒
返信・引用  編集済
  > No.703[元記事へ]

GAIさんへのお返事です。

先のプログラムは、すべてのパターンの「開始(乱列)→終了(整列)」を調べています。
これを「終了→開始」に変更しました。
いわゆる幅優先探索で、「どこまで手数が増やせるか(最多手数)」ということです。

本問題では「逆の操作」が可能で、完全整列 1,2,3,4,… から交換を始めます。

これでも13枚は、、、

ところで、12枚は65回ですか?

LET t0=TIME


LET N=13 !1〜Nのカード

DIM P(N)
FOR i=1 TO N !完全整列 1,2,3,4,…
   LET P(i)=i
NEXT i

LET cmax=0 !最多手数
DIM P_sav(N) !その並び
MAT P_sav=P
CALL try(P,N,0,cmax,P_sav)

PRINT "最大の回数=";cmax
MAT PRINT P_sav;


PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB reverse(A(),N) !1〜N番目までの並びを逆順にする
FOR i=1 TO INT(N/2) !交換位置は半分まで ※全部すると元に戻る
   swap A(i),A(N-i+1) !中央から対称な位置どうし
NEXT i
END SUB

EXTERNAL SUB try(P(),N,c,cmax,P_sav())
DIM W(N)
MAT W=P
FOR i=2 TO N !交換できなくなるまで
   MAT P=W
   IF P(i)=i THEN !i番目のカードが数字iなら交換可能! ※逆の操作
      CALL reverse(P,i) !トップのカードの数字だけカードを抜き出し、順番を逆にして元に戻す
      IF c+1>cmax THEN !最大のものを記録する
         LET cmax=c+1
         MAT P_sav=P
      END IF
      CALL try(P,N,c+1,cmax,P_sav) !次へ
   END IF
NEXT i
END SUB



!WindowsMe、Pentium��700MHz、192MBにて、十進BASIC 2進モードで実行。
!
!最大の回数= 80
! 2  9  4  5  11  12  10  1  8  13  3  6  7
!
!計算時間= 1528.79  ←約25.5分
 

間違いの発見

 投稿者:GAI  投稿日:2009年11月 2日(月)09時03分13秒
返信・引用
  http://www.research.att.com/~njas/sequences/index.html?q=0%2C1%2C2%2C4%2C7%2C10%2C16%2C22%2C30%2C38%2C51%2C&language=japanese&go=%E6%A4%9C%E7%B4%A2
のサイトで調べたのですが、N=12の時の値が間違っていますよね。
ここは63回であるべきことになりますね。
このプログラムは格段に調査時間が短縮されています。
知りたいことが解ってうれしいです。
どうもありがとうございました。
 

Re: 間違いの発見

 投稿者:山中和義  投稿日:2009年11月 2日(月)12時52分42秒
返信・引用  編集済
  > No.705[元記事へ]

GAIさんへのお返事です。

12枚は65手が正しいみたい?!

最多手数になる場合は、この操作の結果として、「完全整列」になるのが多いです。
しかし、そうでない場合もあるようです。
2回目のプログラムは、完全整列からの展開ですから、抜けがあると思います。

こちらに6枚の場合が記載されています。
参考サイト http://www.research.att.com/~njas/sequences/A000376

(少し改修して)2回目のプログラムでは、最後の1つを見つけることはできません。

したがって、12、15、16枚などもそうなるのでは、、、?  全パターン検索中!
 

!◆続「パソコンが相手のオセロ・ゲーム」Ver7.0

 投稿者:SECOND  投稿日:2009年11月 3日(火)02時12分8秒
返信・引用  編集済
  !◆続「パソコンが相手のオセロ・ゲーム」Ver7.0

!コンピューターの打つ手をゆっくり確認する、に加え、
!対局の保存、途中の放置、再現継続、などが、出来るようにした。
!起動すると、これまでの経過を プレイバックし、
!
!前回の終了点まで走ってから、入力状態となります。同時に追記記録を始めます。
!新規に始めたい時は、経過ファイル(oth_70.log)を、削除してから、起動する。

!文が長く掲示板を圧迫しますので、ダウンロードして下さい。
!sysya.exe をお持ちの方は、このまま、走らせると、自動ダウンロード、保存、実行します。

!sysya.exe を使わない方は、手で、下の URL・ファイルを、ダウンロード。
!KOMA76.bas  oth35p.dll の2ファイル。ソース.asm が入用な方は、oth35p.asm まで。
!oth35p.dll は、KOMA76.bas と同じフォルダーに置きます。
!レジストリーは使用せず、汚しません。DownLoad 時の警告は、ご心配なく。

! Level 5 で、勝てた御方は、LOG ファイルを掲示して頂くと、他の人も、
! 対局のプレイバックを、体験できます。
! 指し手を、戻す「待った!」は、経過ファイルを、部分削除し、起動しなおすと、
! いくらでも、戻せますが、反則です。

!このプログラムは、uBASIC 用の、小山オセロを、十進BASIC に移植し、手入れしたもの。


execute "sysya.exe" WITH("/G","/C-","http://homepage2.nifty.com/neutro/asm/oth35p.asm" )
execute "sysya.exe" WITH("/G","/C-","http://homepage2.nifty.com/neutro/asm/oth35p.dll" )
execute "sysya.exe" WITH("/G","/C-","http://homepage2.nifty.com/neutro/asm/KOMA76.bas" )
!
execute "basic.exe" WITH("/OR","KOMA76.bas") !ファイルを開いて起動 実行。"/NR" 起動まで。

END
!sysya.exe のダウンロード先
!http://www.vector.co.jp/soft/win95/net/se394679.html
 

虫食い算

 投稿者:山中和義  投稿日:2009年11月 3日(火)14時33分34秒
返信・引用  編集済
  割り算のサンプル・プログラムです。

アルゴリズム
・「除数」場合の数×「商」場合の数 の検算を行います。
・除数、商、被除数が揃ったところで、筆算で途中結果を検証していきます。
!虫食い算

! a 除数    □□8□□ ← b 商
!     ------------------
!  □□ )□□□□□□□ ← c 被除数
!      □□□     ← d
!      ----------
!         □□   ← e
!         □□   ← f
!        ----------
!          □□□ ← g
!          □□□ ← h
!         --------
!            4 ← 余り


LET t0=TIME


DEF fnFIG(x,n)=MOD(INT(x/10^n),10) !n桁目の数を得る ※0:一の位、1:十の位、2:百の位、…

LET ANSWER_COUNT=0 !解答数

FOR a=10 TO 99 !除数

   FOR b=10000 TO 99999 !商

      IF fnFIG(b,2)<>8 THEN GOTO 100 !商の百の位は8か?

      LET c=b*a + 4 !※余りを加算する
      IF c<1000000 OR c>9999999 THEN GOTO 100 !被除数cは7桁の数?


      LET d=fnFIG(b,4)*a !途中結果d
      IF d<100 OR d>999 THEN GOTO 100 !3桁の数?

      LET w=INT(c/10000) !※筆算を参照

      LET e=(w-d)*100+fnFIG(c,3)*10+fnFIG(c,2) !途中結果e
      IF e<10 OR e>99 THEN GOTO 100 !2桁の数?

      LET f=fnFIG(b,2)*a !途中結果f
      IF f<10 OR f>99 THEN GOTO 100 !2桁の数?

      LET g=(e-f)*100+fnFIG(c,1)*10+fnFIG(c,0) !途中結果g
      IF g<100 OR g>999 THEN GOTO 100 !3桁の数?

      LET h=fnFIG(b,0)*a !途中結果h
      IF h<100 OR h>999 THEN GOTO 100 !3桁の数?

      IF g-h<>4 THEN GOTO 100 !余りは4か?


      LET ANSWER_COUNT=ANSWER_COUNT+1 !解答数
      PRINT "No.";ANSWER_COUNT

      !結果の表示
      PRINT USING "    #####": b !商
      PRINT       "  -----------"
      PRINT USING " ## ) #######": a,c !除数、被除数
      PRINT USING "   ###": d
      PRINT       "   -----"
      PRINT USING "     ##": e
      PRINT USING "     ##": f
      PRINT       "    ----"
      PRINT USING "     ###": g
      PRINT USING "     ###": h
      PRINT       "    ------"
      PRINT       "      4"
      PRINT

100       !continue
       NEXT b

200    !continue
    NEXT a


    PRINT "計算時間=";TIME-t0

 END

参考 かけ算 
No.698 [元記事へ]
 

平方小町算

 投稿者:山中和義  投稿日:2009年11月 5日(木)08時43分58秒
返信・引用
  1〜9の数の順列だから、9!通り。これはパソコンでも、あまり無理のない計算回数である。
場合の数を減らして、マシンパワーに頼らない、負荷の少ない処理を検討してみよう。

●平方小町
 □□□^2=□□□□□□  ただし、□は1〜9が1個ずつ
LET t0=TIME


DEF fnFIG(x,n)=MOD(INT(x/10^n),10) !n桁目の数を得る ※0:一の位、1:十の位、2:百の位、…

LET N=9 !1〜9の数字
LET R=3 !左辺の桁数

DIM P(R),NM(0 TO 9)
FOR i=0 TO perm(N,R)-1
   CALL Num2Perm(i, P,N,R) !左辺を算出する
   LET x=0
   FOR k=1 TO R !ホーナー法
      LET x=x*10+P(k)
   NEXT k

   LET y=x*x !右辺を算出する ※x^2=yより

   MAT NM=ZER !重複していないか確認する
   LET NM(0)=1 !0
   FOR k=1 TO R !左辺側
      LET NM(P(k))=1 !使用中
   NEXT k
   FOR k=0 TO N-R-1 !右辺側
      LET t=fnFIG(y,k)
      IF NM(t)=1 THEN EXIT FOR !重複!
      LET NM(t)=1
   NEXT k
   IF k>N-R-1 THEN PRINT x;"^ 2 =";y !結果を表示する

NEXT i


PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB Num2Perm(h, A(),N,R) !番号から順列パターンを生成する ※辞書式順序
LET v=h
FOR j=1 TO R
   LET fac=PERM(N-j,R-j)
   LET t=INT(v/fac)
   LET A(j)=t+1 !1〜N
   LET v=v-fac*t
NEXT j
FOR j=R-1 TO 1 STEP -1
   FOR k=j+1 TO R
      IF A(j)<=A(k) THEN LET A(k)=A(k)+1
   NEXT k
NEXT j
END SUB

その他の例
 分数小町
  □□□□/□□□□□=1/○  ただし、□は1〜9が1個ずつ、○は2〜9

 ヒント 9! → 4!。 分母=○×分子。


●平方小町
 □□□□□□□□□=○○○○○^2  ただし、□は1〜9が1個ずつ、○は0〜9
LET t0=TIME


DEF fnFIG(x,n)=MOD(INT(x/10^n),10) !n桁目の数を得る ※0:一の位、1:十の位、2:百の位、…

LET N=9 !1〜9の数字

DIM NM(0 TO 9)
FOR i=INT(SQR(123456789)) TO INT(SQR(987654321))
   LET x=i*i !右辺を算出する ※x=i^2より

   MAT NM=ZER !重複していないか確認する
   LET NM(0)=1
   FOR k=1 TO N !左辺側
      LET t=fnFIG(x,k-1)
      IF NM(t)=1 THEN EXIT FOR !重複!
      LET NM(t)=1
   NEXT k
   IF k>N THEN PRINT x;"=";i;"^ 2" !結果を表示する

NEXT i


PRINT "計算時間=";TIME-t0

END
 

小町分数の探索

 投稿者:GAI  投稿日:2009年11月 5日(木)19時45分16秒
返信・引用
  1
    bunnsi   7932
------------------  =  1/2
    bunnbo  15864

2
    bunnsi   7692
------------------  =  1/2
    bunnbo  15384

3
    bunnsi   6792
------------------  =  1/2
    bunnbo  13584

4
    bunnsi   7923
------------------  =  1/2
    bunnbo  15846

5
    bunnsi   9273
------------------  =  1/2
    bunnbo  18546

6
    bunnsi   7293
------------------  =  1/2
    bunnbo  14586

7
    bunnsi   9327
------------------  =  1/2
    bunnbo  18654

8
    bunnsi   6927
------------------  =  1/2
    bunnbo  13854

9
    bunnsi   9267
------------------  =  1/2
    bunnbo  18534

10
    bunnsi   7329
------------------  =  1/2
    bunnbo  14658

11
    bunnsi   6729
------------------  =  1/2
    bunnbo  13458

12
    bunnsi   7269
------------------  =  1/2
    bunnbo  14538



1
    bunnsi   5832
------------------  =  1/3
    bunnbo  17496

2
    bunnsi   5823
------------------  =  1/3
    bunnbo  17469



1
    bunnsi   3942
------------------  =  1/4
    bunnbo  15768

2
    bunnsi   4392
------------------  =  1/4
    bunnbo  17568

3
    bunnsi   7956
------------------  =  1/4
    bunnbo  31824

4
    bunnsi   5796
------------------  =  1/4
    bunnbo  23184



1
    bunnsi   9723
------------------  =  1/5
    bunnbo  48615

2
    bunnsi   2973
------------------  =  1/5
    bunnbo  14865

3
    bunnsi   9627
------------------  =  1/5
    bunnbo  48135

4
    bunnsi   9237
------------------  =  1/5
    bunnbo  46185

5
    bunnsi   2937
------------------  =  1/5
    bunnbo  14685

6
    bunnsi   2967
------------------  =  1/5
    bunnbo  14835

7
    bunnsi   2697
------------------  =  1/5
    bunnbo  13485

8
    bunnsi   6297
------------------  =  1/5
    bunnbo  31485

9
    bunnsi   3297
------------------  =  1/5
    bunnbo  16485

10
    bunnsi   7629
------------------  =  1/5
    bunnbo  38145

11
    bunnsi   3729
------------------  =  1/5
    bunnbo  18645

12
    bunnsi   2769
------------------  =  1/5
    bunnbo  13845
 

小町分数の探索の続き

 投稿者:GAI  投稿日:2009年11月 5日(木)19時49分2秒
返信・引用
  1
    bunnsi   2943
------------------  =  1/6
    bunnbo  17658

2
    bunnsi   4653
------------------  =  1/6
    bunnbo  27918

3
    bunnsi   5697
------------------  =  1/6
    bunnbo  34182



1
    bunnsi   7614
------------------  =  1/7
    bunnbo  53298

2
    bunnsi   5274
------------------  =  1/7
    bunnbo  36918

3
    bunnsi   2394
------------------  =  1/7
    bunnbo  16758

4
    bunnsi   5976
------------------  =  1/7
    bunnbo  41832

5
    bunnsi   4527
------------------  =  1/7
    bunnbo  31689

6
    bunnsi   2637
------------------  =  1/7
    bunnbo  18459

7
    bunnsi   5418
------------------  =  1/7
    bunnbo  37926




1
    bunnsi   9321
------------------  =  1/8
    bunnbo  74568

2
    bunnsi   7421
------------------  =  1/8
    bunnbo  59368

3
    bunnsi   9421
------------------  =  1/8
    bunnbo  75368

4
    bunnsi   5921
------------------  =  1/8
    bunnbo  47368

5
    bunnsi   9531
------------------  =  1/8
    bunnbo  76248

6
    bunnsi   9541
------------------  =  1/8
    bunnbo  76328

7
    bunnsi   6741
------------------  =  1/8
    bunnbo  53928

8
    bunnsi   7941
------------------  =  1/8
    bunnbo  63528

9
    bunnsi   5371
------------------  =  1/8
    bunnbo  42968

10
    bunnsi   4591
------------------  =  1/8
    bunnbo  36728

11
    bunnsi   4691
------------------  =  1/8
    bunnbo  37528

12
    bunnsi   5791
------------------  =  1/8
    bunnbo  46328

13
    bunnsi   6791
------------------  =  1/8
    bunnbo  54328

14
    bunnsi   7312
------------------  =  1/8
    bunnbo  58496

15
    bunnsi   8932
------------------  =  1/8
    bunnbo  71456

16
    bunnsi   8942
------------------  =  1/8
    bunnbo  71536

17
    bunnsi   9352
------------------  =  1/8
    bunnbo  74816

18
    bunnsi   9182
------------------  =  1/8
    bunnbo  73456

19
    bunnsi   5892
------------------  =  1/8
    bunnbo  47136

20
    bunnsi   7123
------------------  =  1/8
    bunnbo  56984
 

小町分数の探索の続き(2)

 投稿者:GAI  投稿日:2009年11月 5日(木)19時50分56秒
返信・引用
  21
    bunnsi   9523
------------------  =  1/8
    bunnbo  76184

22
    bunnsi   8953
------------------  =  1/8
    bunnbo  71624

23
    bunnsi   8954
------------------  =  1/8
    bunnbo  71632

24
    bunnsi   7364
------------------  =  1/8
    bunnbo  58912

25
    bunnsi   8174
------------------  =  1/8
    bunnbo  65392

26
    bunnsi   8394
------------------  =  1/8
    bunnbo  67152

27
    bunnsi   7894
------------------  =  1/8
    bunnbo  63152

28
    bunnsi   9156
------------------  =  1/8
    bunnbo  73248

29
    bunnsi   9316
------------------  =  1/8
    bunnbo  74528

30
    bunnsi   7416
------------------  =  1/8
    bunnbo  59328

31
    bunnsi   9416
------------------  =  1/8
    bunnbo  75328

32
    bunnsi   5916
------------------  =  1/8
    bunnbo  47328

33
    bunnsi   5237
------------------  =  1/8
    bunnbo  41896

34
    bunnsi   3187
------------------  =  1/8
    bunnbo  25496

35
    bunnsi   9158
------------------  =  1/8
    bunnbo  73264

36
    bunnsi   8439
------------------  =  1/8
    bunnbo  67512

37
    bunnsi   5839
------------------  =  1/8
    bunnbo  46712

38
    bunnsi   6839
------------------  =  1/8
    bunnbo  54712

39
    bunnsi   4769
------------------  =  1/8
    bunnbo  38152

40
    bunnsi   6479
------------------  =  1/8
    bunnbo  51832

41
    bunnsi   8179
------------------  =  1/8
    bunnbo  65432

42
    bunnsi   4589
------------------  =  1/8
    bunnbo  36712

43
    bunnsi   4689
------------------  =  1/8
    bunnbo  37512

44
    bunnsi   5789
------------------  =  1/8
    bunnbo  46312

45
    bunnsi   6789
------------------  =  1/8
    bunnbo  54312

46
    bunnsi   8419
------------------  =  1/8
    bunnbo  67352




1
    bunnsi   8361
------------------  =  1/9
    bunnbo  75249

2
    bunnsi   6471
------------------  =  1/9
    bunnbo  58239

3
    bunnsi   6381
------------------  =  1/9
    bunnbo  57429


を発見しました。
 

アラビア数字を漢数字に変換する

 投稿者:山中和義  投稿日:2009年11月 7日(土)20時08分30秒
返信・引用
 
!アラビア数字(1,2,3,…)を漢数字(一,二,三,…)に変換する(Excel準拠)

LET n1$="〇一二三四五六七八九" !漢数字
LET f1$="千百十 " !位
LET f2$="垓京兆億万 " !4桁ずつの位

LET n2$="〇壱弐参四伍六七八九" !大字
LET f3$="阡百拾 " !位
LET f4$="垓京兆億萬 " !4桁ずつの位

LET n3$="0123456789" !数字

FUNCTION NumberString$(x,p) !アラビア数字(1,2,3,…)を漢数字(一,二,三,…)に変換する
   IF x<0 OR x<>INT(x) THEN
      PRINT "非負の整数ではありません。"; x
      STOP
   ELSE
      LET w$=""

      SELECT CASE p
      CASE 1 !漢数字で表記する
         LET a=x
         IF a=0 THEN
            LET w$="〇"
         ELSE
            LET i=LEN(f2$)
            DO UNTIL a=0 !上位の数字がなくなるまで
               LET aa=MOD(a,10000) !「…兆億万 」の4桁ずつ
               IF aa<>0 THEN
                  LET ww$=f2$(i:i)
                  IF ww$<>" " THEN LET w$=ww$&w$

                  LET k=LEN(f1$)
                  DO UNTIL aa=0 !各「千百十 」の位
                     LET ww$=f1$(k:k)
                     IF ww$=" " THEN LET ww$=""

                     LET t=MOD(aa,10) !一の位から
                     IF t=0 THEN !ゼロ・サプレス
                     ELSEIF k<LEN(f1$) AND t=1 THEN !1・サプレス
                        LET w$=ww$&w$
                     ELSE
                        LET w$=n1$(t+1:t+1)&ww$&w$
                     END IF

                     LET aa=INT(aa/10) !次へ
                     LET k=k-1
                  LOOP
               END IF

               LET a=INT(a/10000) !次へ
               LET i=i-1
            LOOP
         END IF

      CASE 2 !大字の漢数字で表記する
         LET a=x
         IF a=0 THEN
            LET w$="〇"
         ELSE
            LET i=LEN(f4$)
            DO UNTIL a=0 !上位の数字がなくなるまで
               LET aa=MOD(a,10000) !「…兆億万 」の4桁ずつ
               IF aa<>0 THEN
                  LET ww$=f4$(i:i)
                  IF ww$<>" " THEN LET w$=ww$&w$

                  LET k=LEN(f3$)
                  DO UNTIL aa=0 !各「千百十 」の位
                     LET ww$=f3$(k:k)
                     IF ww$=" " THEN LET ww$=""

                     LET t=MOD(aa,10) !一の位から
                     IF t=0 THEN !ゼロ・サプレス
                     !!!ELSEIF k<LEN(f3$) AND t=1 THEN !1・サプレス
                     !!!   LET w$=ww$&w$
                     ELSE
                        LET w$=n2$(t+1:t+1)&ww$&w$
                     END IF

                     LET aa=INT(aa/10) !次へ
                     LET k=k-1
                  LOOP
               END IF

               LET a=INT(a/10000) !次へ
               LET i=i-1
            LOOP
         END IF

      CASE 3 !数値をそのまま漢数字で表記する
         LET a=x
         IF a=0 THEN
            LET w$="0"
         ELSE
            DO UNTIL a=0 !上位の桁がなくなるまで
               LET t=MOD(a,10)+1 !一の位から
               LET w$=n1$(t:t)&w$
               LET a=INT(a/10) !次へ
            LOOP
         END IF

      CASE 4 !十,百,千,万などを漢数字で表記する
         LET a=x
         IF a=0 THEN
            LET w$="〇"
         ELSE
            LET i=LEN(f2$)
            DO UNTIL a=0 !上位の数字がなくなるまで
               LET aa=MOD(a,10000) !「…兆億万 」の4桁ずつ
               IF aa<>0 THEN
                  LET ww$=f2$(i:i)
                  IF ww$<>" " THEN LET w$=ww$&w$

                  LET k=LEN(f1$)
                  DO UNTIL aa=0 !各「千百十 」の位
                     LET ww$=f1$(k:k)
                     IF ww$=" " THEN LET ww$=""

                     LET t=MOD(aa,10) !一の位から
                     IF t=0 THEN !ゼロ・サプレス
                     ELSEIF k<LEN(f1$) AND t=1 THEN !1・サプレス
                        LET w$=ww$&w$
                     ELSE
                        LET w$=n3$(t+1:t+1)&ww$&w$
                     END IF

                     LET aa=INT(aa/10) !次へ
                     LET k=k-1
                  LOOP
               END IF

               LET a=INT(a/10000) !次へ
               LET i=i-1
            LOOP
         END IF

      CASE ELSE
      END SELECT

      LET NumberString$=w$ !結果を返す
   END IF
END FUNCTION


!!!PRINT NumberString$(1732050807568877,2) !※1000桁モード、有理数モード

PRINT NumberString$(1234567890,1) !十二億三千四百五十六万七千八百九十
PRINT NumberString$(1234567890,2) !壱拾弐億参阡四百伍拾六萬七阡八百九拾
PRINT NumberString$(1234567890,3) !一二三四五六七八九〇
PRINT NumberString$(1234567890,4) !十2億3千4百5十6万7千8百9十

END
 

ベッセル関数

 投稿者:SECOND  投稿日:2009年11月 9日(月)01時52分53秒
返信・引用  編集済
  !ベッセル関数ですが、このリストは、xの範囲が、実数までで、
!複素数が使用できません。拡張できる方、お願いします。
!
!※十進BASIC にも ベッセル関数、変形ベッセル関数1種を内包出来ないでしょうか。
!-------------------------------
OPTION ARITHMETIC NATIVE
OPTION BASE 0
SET TEXT background "opaque"
DIM col(5)
MAT READ col
DATA 4,10,2, 8,8,8 !Red darkGreen Blue  Gray Gray Gray

!-----
CALL window_i
CALL G_besseli !変形ベッセル関数1種 In(x)
WAIT DELAY .5
CALL window_j
CALL G_besselj !ベッセル関数1種 Jn(x)

SUB window_i
   CLEAR
   LET h=4
   LET l=-1.5
   LET xr=4
   SET WINDOW -.1*xr,xr, l,h
   DRAW grid(xr/8,h/8)
   ASK PIXEL SIZE (0,0; xr,0) j,i
   LET dx=xr/j !pitch
END SUB

SUB window_j
   CLEAR
   LET h=1
   LET l=-1
   LET xr=20
   SET WINDOW -.1*xr,xr, l,h
   DRAW grid(xr/4,h/5)
   ASK PIXEL SIZE (0,0; xr,0) j,i
   LET dx=xr/j !pitch
END SUB

!-------
SUB G_besseli
   FOR n=0 TO 2
      SET LINE COLOR col(n)
      SET TEXT COLOR col(n)
      PLOT TEXT,AT .13*xr,h-.08*(h-l)-.04*(h-l)*n :"変形ベッセル関数1種 "& STR$(n)& "次"
      FOR x=dx TO xr+dx STEP dx
         LET y=besseli(n,x)
         PLOT LINES: x,y; ! PEN-on
         IF FP(x)< dx THEN PRINT USING"##.## ###.######":x,y
      NEXT x
      PLOT LINES !PEN-off
      PRINT
   NEXT n
END SUB

SUB G_besselj
   FOR n=0 TO 2
      SET LINE COLOR col(n)
      SET TEXT COLOR col(n)
      PLOT TEXT,AT .13*xr,h-.08*(h-l)-.04*(h-l)*n :"ベッセル関数1種 "& STR$(n)& "次"
      FOR x=dx TO xr+dx STEP dx
         LET y=besselj(n,x)
         PLOT LINES: x,y; ! PEN-on
         IF FP(x)< dx THEN PRINT USING"##.## ###.######":x,y
      NEXT x
      PLOT LINES !PEN-off
      PRINT
   NEXT n
END SUB

!-------
FUNCTION besseli(n,x)
   LET m=2*INT( (6+MAX(n,1.5*x)+9*1.5*x/(1.5*x+2))/2)
   LET w=0
   FOR k=1 TO m
      LET w=w+Tki(k)
   NEXT k
   LET besseli=EXP(x)*Tki(n)/(Tki(0)+2*w)
END FUNCTION

FUNCTION Tki(i)
   LET t2=0
   LET t1=1e-9
   LET t0=2*(m+1)/x*t1+t2
   FOR kp1=m TO i+1 STEP -1
      LET t2=t1
      LET t1=t0
      LET t0=2*kp1/x*t1+t2
   NEXT kp1
   LET Tki=t0
END FUNCTION

!-------
FUNCTION besselj(n,x)
   LET m=2*INT( (6+MAX(n,1.5*x)+9*1.5*x/(1.5*x+2))/2)
   LET w=0
   FOR k=1 TO m/2
      LET w=w+Tk(k*2)
   NEXT k
   LET besselj=Tk(n)/(Tk(0)+2*w)
END FUNCTION

FUNCTION Tk(i)
   LET t2=0
   LET t1=1e-9
   LET t0=2*(m+1)/x*t1-t2
   FOR kp1=m TO i+1 STEP -1
      LET t2=t1
      LET t1=t0
      LET t0=2*kp1/x*t1-t2
   NEXT kp1
   LET Tk=t0
END FUNCTION

END
 

辞書式順序で次の順列を返す

 投稿者:山中和義  投稿日:2009年11月10日(火)09時11分43秒
返信・引用
  > No.675[元記事へ]

!辞書式順序で次の順列を返す

LET N=4
DIM A(N)
DATA 1,2,3,4
!!!DATA 4,3,2,1 ! ※前の順列 ←←←←←
MAT READ A
MAT PRINT A;

FOR i=1 TO fact(N)
   CALL NextPerm(A,N,rc)
   PRINT i
   IF rc=0 THEN
      PRINT "ありません。"
      STOP
   END IF
   MAT PRINT A;
NEXT i

END


EXTERNAL SUB NextPerm(A(),N, rc) !辞書式順序で次の順列を返す
LET i=N-1 !順列を右から左にみて、増加列から減少列に変わる位置iを探す
DO WHILE i>0 AND A(i)>=A(i+1) !0は番人
!!!DO WHILE i>0 AND A(i)<=A(i+1) !0は番人 ※前の順列 ←←←←←
   LET i=i-1
LOOP
IF i=0 THEN !A(1)>A(2)>A(3)> … >A(N)なら 例. N=4、4,3,2,1
   LET rc=0 !完了
   EXIT SUB
END IF

LET j=N !その位置iより右で、A(i)以上で最小の数A(j)を探す
DO WHILE A(i)>=A(j)
!!!DO WHILE A(i)<=A(j) ! ※前の順列 ←←←←←
   LET j=j-1
LOOP
LET t=A(i) !A(i)とA(j)を交換する
LET A(i)=A(j)
LET A(j)=t

LET i=i+1 !(i+1)からNまでの範囲を逆順にする
LET j=N
DO WHILE i<j
   LET t=A(i) !swap it
   LET A(i)=A(j)
   LET A(j)=t
   LET i=i+1
   LET j=j-1
LOOP
LET rc=1 !未了
END SUB
2箇所修正することで、1つ前の順列を生成することもできます。
 

反転操作によるブロック移動

 投稿者:山中和義  投稿日:2009年11月10日(火)09時29分32秒
返信・引用
  あれ〜ぇ! カードの並び順を反転しているのに、、、

!反転操作によるブロック移動

LET N=15 !枚数
DIM A(N) !カードの並び

PRINT "2分割の場合"
FOR i=1 TO N !整列
   LET A(i)=i
NEXT i
MAT PRINT A;

LET p=5 !位置
CALL reverse(A,1,p-1) !前半部分のみ
MAT PRINT A;
CALL reverse(A,p,N) !後半部分のみ
MAT PRINT A;
CALL reverse(A,1,N) !全体で
MAT PRINT A;

PRINT



PRINT "3分割の場合"

FOR i=1 TO N !整列
   LET A(i)=i
NEXT i
MAT PRINT A;

LET p=7 !位置
LET q=12
CALL reverse(A,1,p-1) !前半部分のみ
MAT PRINT A;
CALL reverse(A,p,q-1) !中央部分のみ
MAT PRINT A;
CALL reverse(A,q,N) !後半部分のみ
MAT PRINT A;
CALL reverse(A,1,N) !全体で
MAT PRINT A;


END


EXTERNAL SUB reverse(A(),L,R) !指定された範囲の並びを逆順にする
LET i=L !左端
LET j=R !右端

DO WHILE i<j !交換位置は半分まで ※全部すると元に戻る
   LET t=A(i) !swap it
   LET A(i)=A(j)
   LET A(j)=t

   LET i=i+1 !次へ
   LET j=j-1
LOOP
END SUB
 

Re: ベッセル関数

 投稿者:山中和義  投稿日:2009年11月11日(水)11時19分29秒
返信・引用  編集済
  > No.714[元記事へ]

SECONDさんへのお返事です。

サイトを検索してみましたが、複素変数での実例(説明、サンプルなど)がほとんどありません。
本格的な計算はわかりません、、、
!Jn(z)=(1/π)*∫[0,π]{cos(n*θ-z*sinθ)}dθ 積分表示より、数値積分で求める

!(検算に使った)参考サイト http://keisan.casio.jp/

OPTION ARITHMETIC COMPLEX

LET j=SQR(-1) !虚数単位

DEF SIN(z)=(EXP(j*z)-EXP(-j*z))/(2*j) !三角関数
DEF COS(z)=(EXP(j*z)+EXP(-j*z))/2

FUNCTION complexbessel(n,z) !1種ベッセル関数 Jn(x+i*y)
   LET div=1000 !分割数
   LET u=0
   LET h=PI/div
   LET a=0
   FOR i=1 TO div !数値積分の台形公式
      LET u=u+( COS(n*a-z*SIN(a)) + COS(n*(a+h)-z*SIN(a+h)) )/2
      LET a=h*i
   NEXT i
   LET complexbessel=h*u/PI
END FUNCTION


SET WINDOW -0.1*20,20, -1,1 !表示範囲
DRAW grid(20/4,1/5)

LET dx=0.2 !グラフの描画間隔
FOR n=0 TO 2
   SET LINE COLOR n+2
   SET TEXT COLOR n+2
   PLOT TEXT,AT .13*20,1-.08*2-.04*2*n :"ベッセル関数1種 "& STR$(n)& "次"
   FOR x=0 TO 20 STEP dx
      LET y=Re( complexbessel(n,COMPLEX(x,0)) ) !実数
      PLOT LINES: x,y;
      IF FP(x)< dx THEN PRINT USING"##.## ###.######": x,y
   NEXT x
   PLOT LINES
   PRINT
NEXT n

END
 

Re: ベッセル関数

 投稿者:SECOND  投稿日:2009年11月11日(水)11時56分51秒
返信・引用
  > No.714[元記事へ]

!前回のベッセル関数について、変数 m を、
!絶対値処理するだけで、xの範囲を、複素数まで拡張できる事が分った。
!
! Jn( complex(x,0) )= complex(0,1)^(-n) *In( complex(0,x) )
! In( complex(x,0) )= complex(0,1)^(-n) *Jn( complex(0,x) ) !←文はこのテスト状態。
!-------------------------------

OPTION ARITHMETIC COMPLEX
OPTION BASE 0
SET TEXT background "opaque"
DIM col(5)
MAT READ col
DATA 4,10,2, 8,8,8 !Red darkGreen Blue  Gray Gray Gray

!-----
CALL window_i
CALL G_besselj !ベッセル関数1種 Jn(x) …虚数入力
WAIT DELAY .5
CALL G_besseli !変形ベッセル関数1種 In(x)

SUB window_i
   CLEAR
   LET h=4
   LET l=-1.5
   LET xr=4
   SET WINDOW -.1*xr,xr, l,h
   DRAW grid(xr/8,h/8)
   ASK PIXEL SIZE (0,0; xr,0) j,i
   LET dx=xr/j !pitch
END SUB

SUB window_j
   CLEAR
   LET h=1
   LET l=-1
   LET xr=20
   SET WINDOW -.1*xr,xr, l,h
   DRAW grid(xr/4,h/5)
   ASK PIXEL SIZE (0,0; xr,0) j,i
   LET dx=xr/j !pitch
END SUB

!-------
SUB G_besseli
   FOR n=0 TO 2
      SET LINE COLOR col(n)
      SET TEXT COLOR col(n)
      PLOT TEXT,AT .13*xr,h-.08*(h-l)-.04*(h-l)*n :"変形ベッセル関数1種 "& STR$(n)& "次"
      FOR t=dx TO xr+dx STEP dx
         LET x=t
         LET y=besseli(n,x)
         ! LET x=COMPLEX(0,t)
         ! LET y=COMPLEX(0,1)^(-n)*besseli(n,x)
         PLOT LINES: ABS(x),y; ! PEN-on
         IF FP(t)< dx THEN PRINT x;y
      NEXT t
      PLOT LINES !PEN-off
      PRINT
   NEXT n
END SUB

SUB G_besselj
   FOR n=0 TO 2
      SET LINE COLOR col(n+3)
      SET TEXT COLOR col(n+3)
      PLOT TEXT,AT .13*xr,h-.08*(h-l)-.04*(h-l)*n :"ベッセル関数1種 "& STR$(n)& "次  "
      FOR t=dx TO xr+dx STEP dx
      ! LET x=t
      ! LET y=besselj(n,x)
         LET x=COMPLEX(0,t)
         LET y=COMPLEX(0,1)^(-n)*besselj(n,x)
         PLOT LINES: ABS(x),y; ! PEN-on
         IF FP(t)< dx THEN PRINT x;y
      NEXT t
      PLOT LINES !PEN-off
      PRINT
   NEXT n
END SUB

!-------
FUNCTION besseli(n,x)
   IF x=0 THEN LET x=1e-32 !0の保護( 場合により外す)
   LET m=2*INT( (6+MAX(n,1.5*ABS(x))+9*1.5*ABS(x)/(1.5*ABS(x)+2))/2 )
   LET w=0
   FOR k=1 TO m
      LET w=w+Tki(k,x)
   NEXT k
   LET besseli=EXP(x)*Tki(n,x)/(Tki(0,x)+2*w)
END FUNCTION

FUNCTION Tki(i,x)
   LET t2=0
   LET t1=1e-9
   LET t0=2*(m+1)/x*t1+t2
   FOR kp1=m TO i+1 STEP -1
      LET t2=t1
      LET t1=t0
      LET t0=2*kp1/x*t1+t2
   NEXT kp1
   LET Tki=t0
END FUNCTION

!-------
FUNCTION besselj(n,x)
   IF x=0 THEN LET x=1e-32 !0の保護( 場合により外す)
   LET m=2*INT( (6+MAX(n,1.5*ABS(x))+9*1.5*ABS(x)/(1.5*ABS(x)+2))/2 )
   LET w=0
   FOR k=1 TO m/2
      LET w=w+Tk(k*2,x)
   NEXT k
   LET besselj=Tk(n,x)/(Tk(0,x)+2*w)
END FUNCTION

FUNCTION Tk(i,x)
   LET t2=0
   LET t1=1e-9
   LET t0=2*(m+1)/x*t1-t2
   FOR kp1=m TO i+1 STEP -1
      LET t2=t1
      LET t1=t0
      LET t0=2*kp1/x*t1-t2
   NEXT kp1
   LET Tk=t0
END FUNCTION

END
 

Re: ベッセル関数

 投稿者:SECOND  投稿日:2009年11月11日(水)12時05分34秒
返信・引用
  > No.717[元記事へ]

山中さんへ
いれちがいになったようで… ありがとうございました。問題は解決していました。ほっとしました
 

!導線の表皮効果による電流分布

 投稿者:SECOND  投稿日:2009年11月11日(水)15時55分47秒
返信・引用
  !導線の表皮効果による電流分布

!電波時計などに使うバーアンテナの巻線について、エナメル線と、リッツ線
!( 細線を多数束ねた絹巻線)で、損失に、どのくらい差があるかを、調べます。

!変形ベッセル関数1種0次を使用して、導体断面の半径ごとの電流密度分布の
!グラフを書きます。これを見ると、40kHzぐらいなら、0.5φmm 単線の
!エナメル線でも、大して違わないようです。
!
!---------------
OPTION ARITHMETIC COMPLEX

!半径r(m)の電流密度Ir(A/m^2) / 表皮半径a(m)の電流密度Ia(A/m^2)

!Ir/Ia= I0( k*r )/ I0( k*a )  ・・・I0(z) 変形ベッセル関数1種0次
! k=√(j*2*π*周波数*u*g)     ・・・j=虚数
LET u=PI*4*1e-7 !H/m 透磁率 !銅
LET g=58*1e6    !S/m 導電率 !銅

SET bitmap SIZE 640, 400
CLEAR
SET COLOR MIX(15) .4, .4, .4
SET COLOR MIX( 0) .4, .4, .4
SET AREA COLOR 1
DIM col(6),frq(6)
MAT READ col
DATA 4,   6,   2,   7,    3,     5 ! red yellow blue magenta green cyan
MAT READ frq
DATA 10e3,40e3,60e3,100e3,1e6,10e6
!
LET a=0.5*1e-3  !m   導線半径.(1mmφ)
SET VIEWPORT 100/640,300/640, 100/640,300/640
CALL msub00
LET a=a/2       !m   導線半径.(.5mmφ)
SET VIEWPORT 350/640,550/640, 100/640,300/640
CALL msub00
!
SET VIEWPORT 0/640,640/640, 0/640,400/640
SET WINDOW 0,16, 10,0
SET TEXT COLOR 1
PLOT TEXT,AT 4,.5:"表皮効果によるエナメル線(銅)の電流密度分布"
PLOT TEXT,AT 4,1.3 ,USING"φ= %.##mm": a*4000
PLOT TEXT,AT 10.25,1.3 ,USING"φ= %.##mm": a*2000
PLOT TEXT,AT     3,2:"表皮 ← 中心 → 表皮"
PLOT TEXT,AT 9.25,2:"表皮 ← 中心 → 表皮"
PLOT AREA:.5,2.5;2,2.5;2,7.5;.5,7.5
FOR ch=1 TO 6
   SET TEXT COLOR col(ch)
   IF frq(ch)< 1e6 THEN LET w$=STR$(frq(ch)/1e3)& "KHz" ELSE LET w$=STR$(frq(ch)/1e6)& "MHz"
   PLOT TEXT,AT .8, 3+.6*ch: w$
NEXT ch

!------
SUB msub00
   SET WINDOW -a*1.01,a*1.01, -0.01,+1.01
   PLOT AREA:-a*1.01,-0.01;a*1.01,-0.01;a*1.01,1.01;-a*1.01,1.01
   DRAW axes0( a/5, 0.2)
   ASK PIXEL SIZE(-a,0;a,0) j,i
   LET dr=2*a/j
   PRINT USING "φ= %.##mm": a*2000
   FOR ch=1 TO 6
      CALL skin
   NEXT ch
END SUB

SUB skin
   SET LINE COLOR col(ch)
   LET k=SQR( COMPLEX(0,1)*2*PI*frq(ch)*u*g )
   LET Iaa= ABS( besseli(0,k*a) ) !表面電流密度 A/m^2
   !---
   FOR r=dr TO a STEP dr
      LET ra= ABS( besseli(0,k*r))/Iaa
      IF r=dr THEN
         IF frq(ch)< 1e6 THEN LET w$=STR$(frq(ch)/1e3)& "KHz" ELSE LET w$=STR$(frq(ch)/1e6)& "MHz"
         PRINT right$("  "& w$,6);" ";
         PRINT USING$("###.########",ra*100);"%" !電流密度比(中心/表面)
      ELSE
         PLOT LINES:xb,yb; r,ra
         PLOT LINES:-xb,yb;-r,ra
      END IF
      LET xb=r
      LET yb=ra
   NEXT r
END SUB

!------ 変形ベッセル関数1種0次
FUNCTION besseli(n,x)
   LET m=2*INT( (6+MAX(n,1.5*ABS(x))+9*1.5*ABS(x)/(1.5*ABS(x)+2))/2)
   LET w=0
   FOR kk=1 TO m
      LET w=w+Tki(kk,x)
   NEXT kk
   LET besseli=EXP(x)*Tki(n,x)/(Tki(0,x)+2*w)
END FUNCTION

FUNCTION Tki(i,x)
   LET t2=0
   LET t1=1e-9
   LET t0=2*(m+1)/x*t1+t2
   FOR kp1=m TO i+1 STEP -1
      LET t2=t1
      LET t1=t0
      LET t0=2*kp1/x*t1+t2
   NEXT kp1
   LET Tki=t0
END FUNCTION

END

!※十進BASIC にも ベッセル関数、変形ベッセル関数1種を内蔵出来ないでしょうか。
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年11月12日(木)10時40分28秒
返信・引用
  > No.690[元記事へ]

階乗進数と順列との関係

通常の進数変換では、各桁の重みは一定となる。
たとえば、2進数なら2となるので、各桁の数は「2で割った余りと商」を繰り返すことで求まる。
これが、j=1〜N とすることで同様に算出できる。

この関係を使って、(パズルの解法などで)
・順列の符号化、復号化 - 局面などのパターンの記録、生成
・乱数列の生成 - 0〜(N!-1)の範囲の乱数から、順列を復号化する
と利用できる。
LET N=4 !N桁の階乗進数

DIM A(N) !各桁の値、順列

FOR i=0 TO FACT(N)-1 !場合の数
   PRINT "i="; i !結果を表示する

   CALL Num2Factoradic(i, A,N) !階乗進数へ
   MAT PRINT A;
   PRINT Factoradic2Num(A,N) !検算


   CALL Num2PermFactorial(i,A,N) !順列へ
   MAT PRINT A;
   PRINT PermFactorial2Num(A,N) !検算
NEXT i

END


EXTERNAL FUNCTION Factoradic2Num(A(),N) !N桁の階乗進数に対して、非負整数を求める
FOR j=N TO 1 STEP -1
   LET v=v*j+A(N-j+1) !階乗進数の各桁の値 A[1..N]=(N-1)! … 3! 2! 1! 0!
NEXT j
LET Factoradic2Num=v
END FUNCTION

EXTERNAL SUB Num2Factoradic(K, A(),N) !非負整数Kに対して、N桁の階乗進数を求める
LET v=K
FOR j=1 TO N
   LET A(N-j+1)=MOD(v,j) !階乗進数の各桁の値 A[1..N]=(N-1)! … 3! 2! 1! 0!
   LET v=INT(v/j)
NEXT j
END SUB



!n!の順列パターン ⇔ 0〜(n!-1)の番号

EXTERNAL FUNCTION PermFactorial2Num(A(),N) !順列パターンに番号を付ける ※辞書式順序
FOR j=1 TO N-1 !階乗進数の各桁の値+1 A[1..N]=(N-1)! … 3! 2! 1! 0!
   FOR k=j+1 TO N
      IF A(k)>=A(j) THEN LET A(k)=A(k)-1
   NEXT k
NEXT j
LET v=0
FOR j=N TO 1 STEP -1 !非負の10進数整数へ
   LET v=v*j+A(N-j+1)-1
NEXT j
LET PermFactorial2Num=v
END FUNCTION

EXTERNAL SUB Num2PermFactorial(h, A(),N) !番号から順列パターンを生成する ※辞書式順序
LET v=h !非負の10進数整数を階乗進数へ
FOR j=1 TO N
   LET A(N-j+1)=MOD(v,j)+1 !階乗進数の各桁の値+1 A[1..N]=(N-1)! … 3! 2! 1! 0!
   LET v=INT(v/j)
NEXT j
FOR j=N-1 TO 1 STEP -1 !順列パターンへ
   FOR k=j+1 TO N
      IF A(k)>=A(j) THEN LET A(k)=A(k)+1
   NEXT k
NEXT j
END SUB


前出の「順列、組合せの番号付けと復元 」のプログラムでは、毎回FACT(N)やPERM(N,R)を計算していた。
かけ算を高速に計算できるが、「より適切な処理」ということで修正しておく。
いくつかのパズルの解法で多少計算が速くなる。
EXTERNAL FUNCTION Perm2Num(A(),N,R) !順列パターンに番号を付ける ※辞書式順序
FOR j=1 TO R-1 !(階乗)進数の各桁の値+1 A[1..R]=PERM(N-1,R-1) … PERM(N-j,R-j) … PERM(N-R,0)
   FOR k=j+1 TO R
      IF A(k)>=A(j) THEN LET A(k)=A(k)-1
   NEXT k
NEXT j
LET v=0
FOR j=R TO 1 STEP -1 !非負の10進数整数へ
   LET v=v*(N-R+j)+A(R-j+1)-1
NEXT j
LET Perm2Num=v
END FUNCTION

EXTERNAL SUB Num2Perm(h, A(),N,R) !番号から順列パターンを生成する ※辞書式順序
LET v=h !非負の10進数整数を(階乗)進数へ
FOR j=1 TO R
   LET A(R-j+1)=MOD(v,N-R+j)+1 !(階乗)進数の各桁の値+1 A[1..R]=PERM(N-1,R-1) … PERM(N-j,R-j) … PERM(N-R,0)
   LET v=INT(v/(N-R+j))
NEXT j
FOR j=R-1 TO 1 STEP -1 !順列パターンへ
   FOR k=j+1 TO R
      IF A(k)>=A(j) THEN LET A(k)=A(k)+1
   NEXT k
NEXT j
END SUB
 

Re: アラビア数字を漢数字に変換する

 投稿者:荒田浩二  投稿日:2009年11月14日(土)13時43分40秒
返信・引用
  > No.713[元記事へ]

漢数字に変換する関数を拡張させていただきました。
p=5 として、12億3456万7800という形式を付加しました。
また、小数の漢数字変換もできるようにしました。

!アラビア数字(1,2,3,…)を漢数字(一,二,三,…)に変換する NumberString2$(x,p)(Excel準拠ではない)
!アラビア数字小数部(.123…)を漢数字(一分二厘三毛…)に変換する NumberString3$(x,p)(独立して利用可)

LET n1$="〇一二三四五六七八九" !漢数字
LET f1$="千百十 " !位
LET f2$="垓京兆億万 " !4桁ずつの位

LET n2$="〇壱弐参四伍六七八九" !大字
LET f3$="阡百拾 " !位
LET f4$="垓京兆億萬 " !4桁ずつの位

LET n3$="0123456789" !数字

DIM ff$(25)
FOR i=1 TO 25
   READ IF MISSING THEN EXIT FOR : ff$(i)
NEXT i
!DATA 割,分,厘,毛,糸,忽,微,繊,沙,塵,埃,渺,漠,模糊,逡巡,須臾,瞬息,弾指,刹那,六徳,虚空,清浄,阿頼耶,阿摩羅,涅槃寂静 !割合表記
DATA 分,厘,毛,糸,忽,微,繊,沙,塵,埃,渺,漠,模糊,逡巡,須臾,瞬息,弾指,刹那,六徳,虚空,清浄,阿頼耶,阿摩羅,涅槃寂静 !本来表記
!"埃"以降は諸説あり

FUNCTION NumberString2$(x,p) !アラビア数字(1,2,3,…)を漢数字(一,二,三,…)に変換する
   IF x<0 THEN
      PRINT "非負ではありません。"; x
      STOP
   ELSE
      LET w$=""

      SELECT CASE p
      CASE 1 !漢数字で表記する
         LET a=INT(x) !!
         IF a=0 THEN
            LET w$="〇"
         ELSE
            LET i=LEN(f2$)
            DO UNTIL a=0 !上位の数字がなくなるまで
               LET aa=MOD(a,10000) !「…兆億万 」の4桁ずつ
               IF aa<>0 THEN
                  LET ww$=f2$(i:i)
                  IF ww$<>" " THEN LET w$=ww$&w$

                  LET k=LEN(f1$)
                  DO UNTIL aa=0 !各「千百十 」の位
                     LET ww$=f1$(k:k)
                     IF ww$=" " THEN LET ww$=""

                     LET t=MOD(aa,10) !一の位から
                     IF t=0 THEN !ゼロ・サプレス
                     ELSEIF k<LEN(f1$) AND t=1 THEN !1・サプレス
                        LET w$=ww$&w$
                     ELSE
                        LET w$=n1$(t+1:t+1)&ww$&w$
                     END IF

                     LET aa=INT(aa/10) !次へ
                     LET k=k-1
                  LOOP
               END IF

               LET a=INT(a/10000) !次へ
               LET i=i-1
            LOOP
         END IF

      CASE 2 !大字の漢数字で表記する
         LET a=INT(x) !!
         IF a=0 THEN
            LET w$="〇"
         ELSE
            LET i=LEN(f4$)
            DO UNTIL a=0 !上位の数字がなくなるまで
               LET aa=MOD(a,10000) !「…兆億万 」の4桁ずつ
               IF aa<>0 THEN
                  LET ww$=f4$(i:i)
                  IF ww$<>" " THEN LET w$=ww$&w$

                  LET k=LEN(f3$)
                  DO UNTIL aa=0 !各「千百十 」の位
                     LET ww$=f3$(k:k)
                     IF ww$=" " THEN LET ww$=""

                     LET t=MOD(aa,10) !一の位から
                     IF t=0 THEN !ゼロ・サプレス
                     !!!ELSEIF k<LEN(f3$) AND t=1 THEN !1・サプレス
                     !!!   LET w$=ww$&w$
                     ELSE
                        LET w$=n2$(t+1:t+1)&ww$&w$
                     END IF

                     LET aa=INT(aa/10) !次へ
                     LET k=k-1
                  LOOP
               END IF

               LET a=INT(a/10000) !次へ
               LET i=i-1
            LOOP
         END IF

      CASE 3 !数値をそのまま漢数字で表記する
         LET a=INT(x) !!
         IF a=0 THEN
            LET w$="〇" !!
         ELSE
            DO UNTIL a=0 !上位の桁がなくなるまで
               LET t=MOD(a,10)+1 !一の位から
               LET w$=n1$(t:t)&w$
               LET a=INT(a/10) !次へ
            LOOP
         END IF

      CASE 4 !十,百,千,万などを漢数字で表記する
         LET a=INT(x) !!
         IF a=0 THEN
            LET w$="0" !!
         ELSE
            LET i=LEN(f2$)
            DO UNTIL a=0 !上位の数字がなくなるまで
               LET aa=MOD(a,10000) !「…兆億万 」の4桁ずつ
               IF aa<>0 THEN
                  LET ww$=f2$(i:i)
                  IF ww$<>" " THEN LET w$=ww$&w$

                  LET k=LEN(f1$)
                  DO UNTIL aa=0 !各「千百十 」の位
                     LET ww$=f1$(k:k)
                     IF ww$=" " THEN LET ww$=""

                     LET t=MOD(aa,10) !一の位から
                     IF t=0 THEN !ゼロ・サプレス
                     ELSEIF k<LEN(f1$) AND t=1 THEN !1・サプレス
                        LET w$=ww$&w$
                     ELSE
                        LET w$=n3$(t+1:t+1)&ww$&w$
                     END IF

                     LET aa=INT(aa/10) !次へ
                     LET k=k-1
                  LOOP
               END IF

               LET a=INT(a/10000) !次へ
               LET i=i-1
            LOOP
         END IF

      CASE 5 !! 兆,億,万などを漢数字で表記する
         LET a=INT(x)
         IF a=0 THEN
            LET w$="0"&w$
         ELSE
            LET i=LEN(f2$)
            DO UNTIL a=0 !上位の数字がなくなるまで
               LET aa=MOD(a,10000) !「…兆億万 」の4桁ずつ
               IF aa<>0 THEN
                  LET ww$=f2$(i:i)
                  IF ww$<>" " THEN LET w$=ww$&w$
                  DO UNTIL aa=0 !各「千百十 」の位
                     LET t=MOD(aa,10) !一の位から
                     LET w$=n3$(t+1:t+1)&w$
                     LET aa=INT(aa/10) !次へ
                  LOOP
               END IF
               LET a=INT(a/10000) !次へ
               LET i=i-1
            LOOP
         END IF !!

      CASE ELSE
      END SELECT

      IF x<>INT(x) THEN !!
         IF INT(x)=0 THEN
            LET w$=""
         ELSEIF p=1 OR p=2 OR p=4 THEN
            LET w$=w$&"・"
         END IF
         LET w$=w$&NumberString3$(FP(x),p) ! 小数部変換
      END IF !!

      LET NumberString2$=w$ !結果を返す
   END IF
END FUNCTION

!続く
 

Re: アラビア数字を漢数字に変換する

 投稿者:荒田浩二  投稿日:2009年11月14日(土)13時45分21秒
返信・引用
  > No.713[元記事へ]

!続き
FUNCTION NumberString3$(x,p) !アラビア数字小数部(.123…)を漢数字(一分二厘三毛…)に変換する
   IF x<=0 OR x>=1 THEN
      PRINT "正の小数(0<x<1)ではありません。"; x
      STOP
   END IF
   LET b=x
   LET ww$=""
   LET k=1
   SELECT CASE p
   CASE 1 !漢数字で表記する(一分二厘三毛)
      DO UNTIL b=0 !小数がなくなるまで
         LET t=INT(10*b)
         WHEN EXCEPTION IN
            LET ff2$=ff$(k) ! 配列添字オーバーで例外発生
            IF t<>0 THEN LET ww$=ww$&n1$(t+1:t+1)&ff2$
         USE
            LET ww$=ww$&n1$(t+1:t+1) ! t=0を表記
         END WHEN
         LET b=10*b-t !次へ
         LET k=k+1
      LOOP
   CASE 2 !大字の漢数字で表記する(壱分弐厘参毛)
      DO UNTIL b=0 !小数がなくなるまで
         LET t=INT(10*b)
         WHEN EXCEPTION IN
            LET ff2$=ff$(k)
            IF t<>0 THEN LET ww$=ww$&n2$(t+1:t+1)&ff$(k)
         USE
            LET ww$=ww$&n2$(t+1:t+1)
         END WHEN
         LET b=10*b-t !次へ
         LET k=k+1
      LOOP
   CASE 3 !数値をそのまま漢数字で表記する(・一二三)
      LET ww$="・" ! 中黒
      DO UNTIL b=0 !小数がなくなるまで
         LET t=INT(10*b)
         LET ww$=ww$&n1$(t+1:t+1)
         LET b=10*b-t !次へ
      LOOP
   CASE 4 !分,厘,毛,糸などを漢数字で表記する(1分2厘3毛)
      DO UNTIL b=0 !小数がなくなるまで
         LET t=INT(10*b)
         WHEN EXCEPTION IN
            LET ff2$=ff$(k)
            IF t<>0 THEN LET ww$=ww$&n3$(t+1:t+1)&ff$(k)
         USE
            LET ww$=ww$&n3$(t+1:t+1)
         END WHEN
         LET b=10*b-t !次へ
         LET k=k+1
      LOOP
   CASE 5 !全角数字で表記する(.123)
      LET ww$="." ! 全角ピリオド
      DO UNTIL b=0 !小数がなくなるまで
         LET t=INT(10*b)
         LET ww$=ww$&n3$(t+1:t+1)
         LET b=10*b-t !次へ
      LOOP
   CASE ELSE
   END SELECT
   LET NumberString3$=ww$ !結果を返す
END FUNCTION

!!!PRINT NumberString2$(1732050807568877,2) !※1000桁モード、有理数モード

PRINT NumberString2$(1234567890.1204,1) !十二億三千四百五十六万七千八百九十・一分二厘四糸
PRINT NumberString2$(1234567890.1204,2) !壱拾弐億参阡四百伍拾六)萬七阡八百九拾・壱分弐厘四糸
PRINT NumberString2$(1234567890.1204,3) !一二三四五六七八九〇・一二〇四
PRINT NumberString2$(1234567890.1204,4) !十2億3千4百5十6万7千8百9十・1分2厘4糸
PRINT NumberString2$(1234567890.1204,5) !12億3456万7890.1204
PRINT
DIM x(4)
FOR p=1 TO 5
   PRINT NumberString2$(PI,p)
NEXT p
PRINT
LET x(1)=5000021007
LET x(2)=.023006
LET x(3)=48130000000
LET x(4)=7.31650080029041875E23 !※1000桁モード、有理数モード
FOR p=1 TO 5
   FOR ii=1 TO 4
      PRINT NumberString2$(x(ii),p),
   NEXT ii
   PRINT
NEXT p
END
 

漢数字をアラビア数字に変換する

 投稿者:荒田浩二  投稿日:2009年11月15日(日)10時23分21秒
返信・引用  編集済
  > No.722[元記事へ]

前出の関数NumberString2$(x,p)の逆関数として、漢数字を数値にして返す関数です。(行番号は削除可)
様々な形式の漢数字を判別します。引数の文字列には漢数字、全角半角算用数字が使えます。
小数点には、全角半角のピリオドと全角中点が使えます。
エラー処理は十分ではなく、誤った文字列でもエラーにならず適当な数値を返してしまうことがあります。

!漢数字を数値に変換する関数 String_to_Num(a$)
10 DIM nk$(4,0 TO 9),f1$(3),f2$(5),ff$(25)
20 DATA 0,1,2,3,4,5,6,7,8,9  ! nk$
30 DATA 〇,一,二,三,四,五,六,七,八,九  ! nk$
40 DATA 零,壱,弐,参,肆,伍,陸,漆,捌,玖  ! nk$
50 DATA ○,壹,貳,參,4,5,6,質,8,9  ! nk$
60 DATA 千,百,十        ! f1$
70 DATA 垓,京,兆,億,万  ! f2$(5)
80 !DATA 割,分,厘,毛,糸,忽,微,繊,沙,塵,埃,渺,漠,模糊,逡巡,須臾,瞬息,弾指,刹那,六徳,虚空,清浄,阿頼耶,阿摩羅,涅槃寂静 !割合表記
90 DATA 分,厘,毛,糸,忽,微,繊,沙,塵,埃,渺,漠,模糊,逡巡,須臾,瞬息,弾指,刹那,六徳,虚空,清浄,阿頼耶,阿摩羅,涅槃寂静 !本来表記
   ! "埃"以降は諸説あり
100 MAT READ nk$,f1$,f2$
110 FOR i=1 TO 25
120    READ IF MISSING THEN EXIT FOR : ff$(i)
130 NEXT i

140 LET a$="十七億五千二十八万三百四十六" ! NumberString2$(x,p)でp=1の場合
    !LET a$="壱拾弐億六萬七阡八百九拾・伍分六厘七毛八糸" ! p=2
    !LET a$="一二三四五六七八九〇・一二〇四" ! p=3
    !LET a$="8百3万9千6百十・4糸5忽8沙" ! p=4
    !LET a$="12億3456万7890.1204" ! p=5
    !LET a$="3百2十4万9千5十7"  ! 半角数字も可
    !LET a$="-420.18"  ! 通常のVAL関数としても機能する
    !LET a$="八分参厘六糸壱忽"
    !LET a$=".7厘8毛9逡巡"
    !LET a$="0.6474"
    !LET a$="参・壱分四厘壱毛伍糸九忽弐微六繊伍沙参塵伍埃八渺九漠七模糊九逡巡" !π(10進15桁モード)
    !LET a$=a$&"参須臾弐瞬息参弾指八刹那四六徳六虚空弐清浄六阿頼耶四阿摩羅参涅槃寂静参八参弐七" !π続き(1000桁モード)

150 PRINT a$
160 PRINT String_to_Num(a$)

170 FUNCTION String_to_Num(w$)
180    DO
190       LET i=MAX(POS(w$," "),POS(w$," "))
200       LET w$(i:i)=""
210    LOOP UNTIL i=0
220    FOR i=1 TO LEN(w$)
230       FOR p=1 TO 4  ! 全角数字/漢数字を半角算用数字に
240          FOR j=0 TO 9
250             IF w$(i:i)=nk$(p,j) THEN LET w$(i:i)=STR$(j)
260          NEXT j
270       NEXT p
280       IF w$(i:i)="阡" OR w$(i:i)="仟" THEN LET w$(i:i)="千"
290       IF w$(i:i)="陌" OR w$(i:i)="佰" THEN LET w$(i:i)="百"
300       IF w$(i:i)="拾" THEN LET w$(i:i)="十"
310    NEXT i
320    LET i=POS(w$,"萬")
330    IF i>0 THEN LET w$(i:i)="万"
340    LET i=POS(w$,"6徳")
350    IF i>0 THEN LET w$(i:i+1)="六徳"
360    LET pt=POS(w$,".")+POS(w$,".")+POS(w$,"・")
370    IF pt>0 THEN
380       LET w$(pt:pt)="."
390       LET len_int=pt-1  ! 整数部文字数
400    ELSE
410       LET len_int=LEN(w$)
420    END IF
       ! print w$
       !
430    WHEN EXCEPTION IN
440       LET num=VAL(w$)
450       LET String_to_Num=num ! "一二三四五・六七"(数字のみ)
460       EXIT FUNCTION
470    USE
480    END WHEN
       !
490    LET num=i_val(w$)  ! 整数部変換
       !
500    IF pt>0 THEN
510       LET f$=w$(pt:LEN(w$))
520       WHEN EXCEPTION IN
530          LET num=num+VAL(f$)
540          LET String_to_Num=num ! "12万3456.78"(小数部が数字のみ)
550       USE
560          LET String_to_Num=num+f_val(f$(2:LEN(f$))) ! "十二・三分四厘"(整数小数あり)
570       END WHEN
580    ELSEIF num=0 AND LEN(w$)>=2 THEN
590       LET String_to_Num=f_val(w$) ! "一分二厘三毛四糸"(小数部のみ)
600    ELSE
610       LET String_to_Num=num ! "百二十三"(整数部のみ)
620    END IF
630 END FUNCTION
    !
640 FUNCTION i_val(w$)  ! 整数部変換
650    LET num=0
660    LET k0=1
670    FOR i=1 TO SIZE(f2$)
680       LET k2=POS(w$,f2$(i),k0+1)  ! 垓,京,兆,億,万
690       IF k2>0 THEN
700          LET num=num+val1000(w$(k0:k2-1))*10000^(SIZE(f2$)-i+1) ![千百十一]の4桁
710          LET k0=k2+1
720       END IF
730    NEXT i
740    IF k0<=len_int THEN  ! 最下位4桁
750       LET num=num+val1000(w$(k0:len_int))
760    END IF
770    LET i_val=num
780 END FUNCTION
    !
790 FUNCTION val1000(aa$)  ! [千百十一]の4桁変換
800    WHEN EXCEPTION IN
810       LET aa=VAL(aa$)
820       LET val1000=aa
830       EXIT FUNCTION
840    USE
850    END WHEN
860    LET aa=0
870    LET kk=1
880    FOR j=1 TO 3
890       LET k1=POS(aa$,f1$(j),kk) ! 千,百,十
900       IF k1>0 THEN
910          WHEN EXCEPTION IN
920             LET aa=aa+VAL(aa$(k1-1:k1-1))*10^(4-j)
930          USE
940             LET aa=aa+10^(4-j)  ! 係数"1"の省略時(3千百4十5など)
950          END WHEN
960          LET kk=k1+1
970       END IF
980    NEXT j
990    IF kk=LEN(aa$) THEN LET aa=aa+VAL(aa$(kk:kk)) ! 一
1000    LET val1000=aa
1010 END FUNCTION
     !
1020 FUNCTION f_val(f$)  ! 小数部変換
1030    LET frac=0
1040    LET k0=1
1050    FOR i=1 TO SIZE(ff$)
1060       IF ff$(i)<>"" THEN
1070          LET fd=POS(f$,ff$(i),k0+1)
1080          IF fd>0 THEN
1090             LET frac=frac+VAL(f$(fd-1:fd-1))*10^(-i)
1100             LET k0=fd+LEN(ff$(i))
1110             LET k3=i
1120          END IF
1130       END IF
1140    NEXT i
1150    WHEN EXCEPTION IN
1160       IF k0<=LEN(f$) THEN
1170          LET frac=frac+VAL(f$(k0:LEN(f$)))*10^(-(k3+LEN(f$)-k0+1))
1180       END IF
1190    USE
1200    END WHEN
1210    LET f_val=frac
1220 END FUNCTION
     !
1230 END
 

Ubasicから十進BASICへのお願い

 投稿者:GAI  投稿日:2009年11月16日(月)15時45分28秒
返信・引用
  220   point -10:word -40:M=1850:dim C(M):C(0)=1:S=1/2+14#i
250   for K=1 to M:for J=K to 1 step -1:C(J)=(C(J)+C(J-1))/2:next:next
300   ' find zeta zero
330   repeat
350     Z=fnZeta(S):H=Z/S:W=fnZeta(S+H):S+=H/(1-W/Z)
360     print using(8,20),S
380   until abs(Z)<1/10^18
390   end
800   ' zeta function
810   fnZeta(X)
820   local J,U
830   for J=1 to M:U+=(-1)^(J-1)*C(J)/J^X:next:U/=1-2^(1-X)
880   return(U)



のUbasicプログラムを十進BASICへ書き直して頂けませんか?
 

Re: Ubasicから十進BASICへのお願い

 投稿者:SECOND  投稿日:2009年11月16日(月)17時45分59秒
返信・引用  編集済
  > No.725[元記事へ]

GAIさんへ

!直訳です。精度は、かなり落ちます。uBASIC の有効桁(約2600桁)

OPTION ARITHMETIC COMPLEX
OPTION BASE 0
!                                 !point -10 !変数の小数部 10*4.8桁  設定不可。
!                                 !word -40  !変数の長さ   40*4.8桁  設定不可。
LET M=1850                                   !※短くても内部計算は常に2600桁。
DIM C(M)
LET C(0)=1
LET S=COMPLEX(1/2,14)             !S=1/2+14#i
FOR K=1 TO M
   FOR J=K TO 1 STEP -1
      LET C(J)=(C(J)+C(J-1))/2
   NEXT J
NEXT K
!' find zeta zero
DO                                !repeat
   LET Z=Zeta(S)                  !Z=fnZeta(S)
   LET H=Z/S
   LET W=Zeta(S+H)                !W=fnZeta(S+H)
   LET S=S+H/(1-W/Z)              !S+=H/(1-W/Z)
   PRINT S                        !print using(8,20),S
   ! PRINT USING "########.#################### ########.####################":re(S),im(S);
   ! PRINT "#i"
LOOP UNTIL ABS(Z)< 1e-12 ! 1e-14  !until abs(Z)< 1/10^18  !十進BASICで ^18は無理。
STOP                              !END

!' zeta function
FUNCTION Zeta(X)                  !fnZeta(X) ※'fn'は、ユーザー定義関数 接頭語
   local J,U
   FOR J=1 TO M
      LET U=U+(-1)^(J-1)*C(J)/J^X !U+=(-1)^(J-1)*C(J)/J^X
   NEXT J
   LET U=U/(1-2^(1-X))            !U/=1-2^(1-X)
   LET Zeta=U                     !return(U)
END FUNCTION

END

! uBASIC での実行結果。
!run
!       0.50758974993024427495     +14.13558444989598483799#i
!       0.49997720386661645733     +14.13471625740151952033#i
!       0.49999999984206884658     +14.13472514154016738957#i
!       0.50000000000000000001     +14.13472514173469379043#i
!       0.50000000000000000000     +14.13472514173469379046#i
!OK
 

Re: Ubasicから十進BASICへのお願い

 投稿者:荒田浩二  投稿日:2009年11月17日(火)10時33分24秒
返信・引用
  > No.725[元記事へ]

1000桁モードで実行できるようにしました。
複素数は実部と虚部を分けて計算しています。超越関数は50桁の精度で計算しています。

結果
        .50844135172596863716       14.13022666245748735689
        .49997302379385895921       14.13474225141619583149
        .49999999977346757559       14.13472514196906007421
        .50000000000000000000       14.13472514173469379049
        .50000000000000000000       14.13472514173469379046
745 秒

OPTION ARITHMETIC DECIMAL_HIGH
220 ! point -10:word -40
    DECLARE EXTERNAL FUNCTION LOG,EXP
    DECLARE FUNCTION SIN,COS
    PUBLIC NUMERIC prec
    print time$
    LET t0=time
    LET prec=50 ! 精度
    LET M=1850
    DIM C(0 TO M),L(M),inv_fac(0 TO prec+1),S(2),Z(2),H(2),W(2),SH(2)
    LET C(0)=1
    LET S(1)=1/2
    LET S(2)=14
250 for K=1 to M
       LET L(K)=LOG(K)
       for J=K to 1 step -1
          LET C(J)=(C(J)+C(J-1))/2 ! C(K)=2^(-K)?
       next J
    next K
    LET inv_fac(0)=1 ! 階乗の逆数
    FOR i=1 TO prec+1
       LET inv_fac(i)=inv_fac(i-1)/i
    NEXT i
300 !' find zeta zero
330 DO ! repeat
350    CALL fnZeta(S,Z)
       LET H(1)=(Z(1)*S(1)+Z(2)*S(2))/(S(1)^2+S(2)^2) ! H=Z/S
       LET H(2)=(Z(2)*S(1)-Z(1)*S(2))/(S(1)^2+S(2)^2)
       MAT SH=S+H
       CALL fnZeta(SH,W) ! W=fnZeta(S+H)
       LET SH(1)=1-(W(1)*Z(1)+W(2)*Z(2))/(Z(1)^2+Z(2)^2)
       LET SH(2)=-(W(2)*Z(1)-W(1)*Z(2))/(Z(1)^2+Z(2)^2)
       LET S(1)=S(1)+(H(1)*SH(1)+H(2)*SH(2))/(SH(1)^2+SH(2)^2) ! S+=H/(1-W/Z)
       LET S(2)=S(2)+(H(2)*SH(1)-H(1)*SH(2))/(SH(1)^2+SH(2)^2)
360    print using "-"&REPEAT$("#",7)&"."&REPEAT$("#",20)&" -"&REPEAT$("#",7)&"."&REPEAT$("#",20):S(1),S(2)
380 LOOP until SQR(Z(1)^2+Z(2)^2)<1/10^18
    print int(time-t0);"秒"
390 ! end
800 !' zeta function
810 SUB fnZeta(X(),U())
820    local J
       MAT U=ZER
830    for J=1 to M
          LET p1=EXP(X(1)*L(J))*COS(X(2)*L(J))
          LET p2=EXP(X(1)*L(J))*SIN(X(2)*L(J))
          LET pp=1/(p1^2+p2^2)
          LET U(1)=U(1)+(-1)^(J-1)*C(J)*p1*pp ! U+=(-1)^(J-1)*C(J)/J^X
          LET U(2)=U(2)-(-1)^(J-1)*C(J)*p2*pp
       next J
       LET p1=1-EXP((1-X(1))*L(2))*COS(-X(2)*L(2))
       LET p2=-EXP((1-X(1))*L(2))*COS(-X(2)*L(2))
       LET pp=1/(p1^2+p2^2)
       LET u1=(U(1)*p1+U(2)*p2)*pp
       LET U(2)=(U(2)*p1-U(1)*p2)*pp ! U/=1-2^(1-X)
       LET U(1)=u1
880 END SUB ! return(U)
    !
    FUNCTION SIN(x)
       LET x=MOD(x,2*PI)
       LET sum=0
       FOR i=0 TO prec/2
          LET sum=sum+(-1)^i*x^(2*i+1)*inv_fac(2*i+1)
       NEXT i
       LET SIN=sum
    END FUNCTION
    FUNCTION COS(x)
       LET x=MOD(x,2*PI)
       LET sum=0
       FOR i=0 TO prec/2
          LET sum=sum+(-1)^i*x^(2*i)*inv_fac(2*i)
       NEXT i
       LET COS=sum
    END FUNCTION
END
!
! 1000桁モードで利用する対数関数(十進BASIC添付"\BASICw32\Library\log.LIB"参照)
EXTERNAL FUNCTION LOG(x)
    OPTION ARITHMETIC DECIMAL_HIGH
    IF x<=0 THEN
       CAUSE EXCEPTION 3004
    ELSEIF x<1 THEN
       LET log=-log(1/x)
    ELSEIF x>3 THEN
       LET log=2*log(SQR(x))
    ELSE         ! 1<=x<=3
       LET h=(x-1)/(x+1)   ! 0<=h<=0.5
       LET t=0
       LET n=1
       LET k=h
       LET h2=H^2
       DO
          LET t=t+k/n
          LET n=n+2
          LET k=k*h2
       LOOP UNTIL k<=eps(0)*10^(1000-prec) ! 精度prec
       LET log=2*t
    END IF
END FUNCTION
!
! 1000桁モードで利用する指数関数(十進BASIC添付"\BASICw32\Library\exp.LIB"参照)
EXTERNAL FUNCTION EXP(x)
    OPTION ARITHMETIC DECIMAL_HIGH
    FUNCTION s(y,n)
       LET t=y*x/n
       IF ABS(t)<=EPS(0)*10^(1000-prec) THEN ! 精度prec
          LET s=y+t
       ELSE
          LET s=y+s(t,n+1)
       END IF
    END FUNCTION
    LET EXP=s(1,1)
END FUNCTION
 

Re: Ubasicから十進BASICへのお願い

 投稿者:山中和義  投稿日:2009年11月17日(火)11時36分42秒
返信・引用
  > No.725[元記事へ]

みなさん、リーマン予想にはまっていますね?!
!リーマンのゼータ関数
!ζ(s)=1/(1-2^(1-s))*��[m=0,∞]{2^(-(m+1))*��[j=0,m]{(-1)^j*comb(m,j)*(j+1)^(-s)}}

LET t0=TIME


LET M=50 !1850
DIM C(0 TO M) !��2^(-(M+1))*��comb(M,J)
LET C(0)=1
FOR K=1 TO M !パスカルの三角形のM段より、二項係数comb(m,j)を求める
   FOR J=K TO 1 STEP -1
      LET C(J)=(C(J)+C(J-1))/2 !※2^(-(m+1))も加味する
   NEXT J
NEXT K
FUNCTION fnZeta(S) !リーマンのゼータ関数
   local J,U
   LET U=0
   FOR J=0 TO M
      LET U=U+(-1)^J*C(J)/(J+1)^S
   NEXT J
   LET U=U/(1-2^(1-S))
   LET fnZeta=U
END FUNCTION


PRINT C(M) !debug

PRINT fnZeta(2) - PI*PI/6


PRINT "計算時間=";TIME-t0

END

私も、実数の範囲で計算させてみて、多桁の複素数計算の実装を考えようとしたのですが、
荒田浩二さんがすでに着手されたようで、、、

1000桁モードでは二項係数を求めるのに、苦戦しているようで時間がかかっています。

10進モードや2進モードや複素数モードの17桁程度では、M=50で十分でしょう。
50桁精度の場合は、M=100で十分でしょう。
 

第2掲示板投稿記事リストのスレッド作成

 投稿者:荒田浩二  投稿日:2009年11月19日(木)11時50分30秒
返信・引用  編集済
  スレッドが使えるようになったので、第2掲示板の投稿記事リストを作成しました。
投稿記事の古い順に並べたリストです。
タイトル部分をクリックすれば、その投稿記事にリンクします。

掲示板のソースをテキストファイルにし、下のプログラムで投稿表題部分を抽出し作成しました。

参考情報……スレッドへの投稿記事は、投稿者本人でも後から編集はできないようです。
訂正……スレッドへの投稿記事も、投稿者本人による編集・削除が可能です。

LET t1$="<H2><A NAME=""CID" ! ID No.
LET t1=LEN(t1$)
LET t2$=""" HREF=""http://6317.teacup.com/basic/bbs/" ! ID No.
LET t2=LEN(t2$)
LET t3$=""" CLASS=""Kiji_Title"">" ! タイトル
LET t3=LEN(t3$)
LET t4$="</A></H2>"
LET t4=LEN(t4$)
!
LET p1$="&nbsp;投稿者:<SPAN CLASS=""Kiji_Author"">" ! 投稿者
LET p1=LEN(p1$)
LET p2$="</SPAN>"
LET p2=LEN(p2$)
LET p3$="<A HREF=" ! mailto
LET p3=LEN(p3$)
LET p4$=""">"
LET p4=LEN(p4$)
LET p5$="</A>"
LET p5=LEN(p4$)
!
LET d1$="&nbsp;投稿日:" ! 投稿日時
LET d1=LEN(d1$)
LET d2$="日(" ! 曜日
LET d2=LEN(d2$)
!
LET l1$="&gt; <A HREF=""http://6317.teacup.com/basic/bbs/" ! 元記事 No.
LET l1=LEN(l1$)
LET l2$=">No." ! 元記事 No.
LET l2=LEN(l2$)
LET l3$="[元記事へ]</A><BR><BR>"
LET l3=LEN(l3$)
!
LET finput$="source.txt"
LET foutput$="boardlist.txt"
OPEN #1 : NAME finput$ ,ACCESS INPUT
!
DIM c$(1000)
LET k=0
DO
   LINE INPUT #1 , IF MISSING THEN EXIT DO : a$
   IF a$(1:l1)=l1$ THEN  ! 元記事あり
      LET ps=POS(a$,l2$,l1+1)
      LET ps2=POS(a$,l3$,ps+l2)
      LET s$=s$&" "&a$(ps:ps2-1)
   ELSEIF a$(1:t1)=t1$ THEN
      IF s$<>"" THEN
         LET k=k+1
         LET c$(k)=s$&"</SMALL>"
      END IF
      CALL title
   END IF
LOOP
IF s$<>"" THEN
   LET k=k+1
   LET c$(k)=s$&"</SMALL>"
END IF
CLOSE #1
!
OPEN #2 : NAME foutput$ ,ACCESS OUTPUT
SET #2 : POINTER END
FOR i=k TO 1 STEP -1
   PRINT #2 : c$(i)
NEXT i
CLOSE #2
!
SUB title
   LET s$="<A HREF=""http://6317.teacup.com/basic/bbs/"
   LET id$=a$(t1+1:POS(a$,"""",t1+1)-1)
   LET s$=id$&"  "&s$&id$&"""><B><BIG>"
   LET ps=POS(a$,t3$,t1+2)
   LET ps2=POS(a$,t4$,ps+t3)
   LET s$=s$&a$(ps+t3:ps2-1)&"</BIG></B></A>   投稿者:<FONT COLOR=""#555555""><STRONG>"
   LINE INPUT #1 : a$
   IF a$(1:p1)=p1$ THEN
      IF a$(p1+1:p1+p3)=p3$ THEN
         LET s$=s$&a$(POS(a$,p4$,p1+p3+1)+p4:POS(a$,p5$,p1+p3+3)-1)&"</STRONG></FONT><SMALL>"
      ELSE
         LET s$=s$&a$(p1+1:POS(a$,p2$,p1+1)-1)&"</STRONG></FONT><SMALL>"
      END IF
   END IF
   LINE INPUT #1 : a$
   LINE INPUT #1 : a$
   IF a$(1:d1)=d1$ THEN
      LET s$=s$&"   "&a$(d1+1:POS(a$,d2$,d1+2))
   END IF
END SUB
END
 

この現象を再現して下さい

 投稿者:GAI  投稿日:2009年11月19日(木)14時15分35秒
返信・引用
  http://web2.incl.ne.jp/yaoki/psychic.swf
で起こる現象をbasic版でプログラムを組んで欲しいんです。
原理は簡単ですが、最初はとてもびっくりしました。
すこしずつ手直ししながら、もっと面白いものにしていきたいので・・・
 

Re: この現象を再現して下さい

 投稿者:山中和義  投稿日:2009年11月19日(木)17時37分23秒
返信・引用  編集済
  > No.745[元記事へ]

GAIさんへのお返事です。

●現象の確認
FOR i=10 TO 99 !2桁の数を念じる
   LET a=INT(i/10) !十の位と一の位の2つの数字を足す
   LET b=MOD(i,10) !2桁の数字から足した答えを引く
   LET s=i-(a+b) !答え s=(10*a+b)-(a+b)=9*a ∴9の倍数

   PRINT i;s !9の倍数は同じマークにして、常にこのマークを表示すればよい。
   !ただ、多少はずれるように異なるマークも表示する
NEXT i

END


●占星術のシンボルマークが表示できるか
 ワープロWordがインストールされていれば、フォントWingdingsはあると思います。
RANDOMIZE
SET bitmap SIZE 501,501
SET WINDOW -0.5,10.5,10,-1

LET z$="c" !9の倍数は同じマーク

!!!SET TEXT font "MS明朝",12
FOR y=0 TO 9 !数字
   FOR x=0 TO 9
      PLOT TEXT ,AT x,y: STR$(10*y+x)
   NEXT x
NEXT y
SET TEXT font "Wingdings",18 !※大きさは調整が必要である
FOR y=0 TO 9 !占星術のシンボル
   FOR x=0 TO 9
      IF MOD(10*y+x,9)=0 THEN !9の倍数なら
         PLOT TEXT ,AT x+0.3,y+0.3: z$
      ELSE
         PLOT TEXT ,AT x+0.3,y+0.3: CHR$(INT(RND*40)+ORD("T")) !T〜z
      END IF
   NEXT x
NEXT y


INPUT PROMPT "何か文字を入力してください。":t$ !ダミー入力!!!


SET TEXT font "Wingdings",256 !※大きさは調整が必要である
SET TEXT JUSTIFY "center","half"
PLOT TEXT ,AT 5,4.5: z$

END
 

複素数の計算

 投稿者:山中和義  投稿日:2009年11月20日(金)09時17分31秒
返信・引用
  複素数モードをサポートする十進BASICでは、あまり必要性はないと思いますが、
アルゴリズムの勉強として参考にしてください。

サンプルは1000桁モードですが、収束判定の精度を落とすことで、
10進や2進モードでも実行できます。その場合は、複素数モードと同じことになりますが、、、

サンプル リーマンのゼータ関数の零点
!複素数の計算

LET t0=TIME


!リーマンのゼータ関数
! ζ(s)=1/(1-2^(1-s))*��[m=0,∞]{2^(-(m+1))*��[j=0,m]{(-1)^j*comb(m,j)*(j+1)^(-s)}}

LET M=100 !精度20桁程度  ※精度1000桁程度は、3000

DIM C(0 TO M) !��2^(-(M+1))*��comb(M,J)
LET C(0)=1
FOR K=1 TO M !パスカルの三角形のM段より、二項係数comb(m,j)を求める
   FOR J=K TO 1 STEP -1
      LET C(J)=(C(J)+C(J-1))/2 !※2^(-(m+1))も加味する
   NEXT J
NEXT K
PRINT C(M) !debug

SUB fnZeta(ReS,ImS, ReZ,ImZ) !リーマンのゼータ関数
   local J
   local ReU,ImU,ReT1,ImT1,ReT2,ImT2
   LET ReU=0 !LET U=0
   LET ImU=0
   FOR J=M TO 0 STEP -1
      CALL CompPow(J+1,0, ReS,ImS, ReT1,ImT1) !LET U=U+(-1)^J*C(J)/(J+1)^S
      CALL CompDiv((-1)^J*C(J),0, ReT1,ImT1, ReT2,ImT2)
      CALL CompAdd(ReU,ImU, ReT2,ImT2, ReU,ImU)
   NEXT J
   CALL CompPow(2,0, 1-ReS,-ImS, ReT1,ImT1) !LET fnZeta=U/(1-2^(1-S))
   CALL CompDiv(ReU,ImU, 1-ReT1,ImT1, ReZ,ImZ)
END SUB


!ゼータ関数の零点の計算(Riemann zeta zeros)

LET ReS=1/2 !非自明な零点 1/2+14*i
LET ImS=14 !1/2+t*i t=14, 21, 25, 30, 33, 38, 41, 43, 48, 50, … 付近

!ニュートン法で零点を求める
! sn+1 = sn-ζ(sn)/ζ'(sn)、ζ'(sn)≒(ζ(sn+h)-ζ(sn))/h  hは微小な値より
! sn+1 = sn-ζ(sn)*h/(ζ(sn+h)-ζ(sn)) = sn+h/(1-ζ(sn+h)/ζ(sn)) となる。
! h=ζ(sn)/sn として、収束の判定にはζ(s)の絶対値を使用する。
DO
   CALL fnZeta(ReS,ImS, ReZ,ImZ) !LET Z=fnZeta(S)
   CALL CompDiv(ReZ,ImZ,ReS,ImS, ReH,ImH) !LET H=Z/S
   CALL fnZeta(ReS+ReH,ImS+ImH, ReW,ImW) !LET W=fnZeta(S+H)
   CALL CompDiv(ReW,ImW, ReZ,ImZ, ReT1,ImT1) !LET S=S+H/(1-W/Z)
   CALL CompDiv(ReH,ImH, 1-ReT1,-ImT1, ReT2,ImT2)
   CALL CompAdd(ReS,ImS, ReT2,ImT2, ReS,ImS)

   PRINT USING "####.####################   ####.####################": ReS,ImS !PRINT S
LOOP UNTIL CompABS(ReZ,ImZ)<1/10^18 !LOOP UNTIL ABS(Z)<1/10^18
!収束するまで ※精度は調整が必要である。10進モード、2進モードでは1/10^8程度


PRINT "計算時間=";TIME-t0

END


!複素数の計算

EXTERNAL FUNCTION CompRe(x,y) !実部 (x+y*i)、x,yは実数、iは虚数単位
LET CompRe=x
END FUNCTION

EXTERNAL FUNCTION CompIm(x,y) !虚部 Im(x+y*i)
LET CompIm=y
END FUNCTION

EXTERNAL SUB CompConj(x1,y1, x,y) !共役複素数
LET xx=x1
LET yy=-y1
LET x=xx
LET y=yy
END SUB

EXTERNAL FUNCTION CompABS(x,y) !絶対値 |x+y*i|
!a'=MAX(ABS(a),ABS(b))、b'=MIN(ABS(a),ABS(b))として、SQR(a*a+b*b)=a'*SQR(1+(b'/a')^2)を求める。
IF x=0 THEN
   LET r=ABS(y)
ELSEIF y=0 THEN
   LET r=ABS(x)
ELSEIF ABS(y)>ABS(x) THEN
   LET t=x/y
   LET r=ABS(y)*SQR(1+t*t)
ELSE
   LET t=y/x
   LET r=ABS(x)*SQR(1+t*t)
END IF
LET CompABS=r
END FUNCTION

EXTERNAL FUNCTION CompARG(x,y) !偏角θ (-π,π]
IF x>0 THEN !第1象限、第4象限
   LET r=ATN2(y/x)
ELSE
   IF x<0 THEN
      IF y>=0 THEN !第2象限
         LET r=ATN2(y/x)+PI
      ELSE !第3象限
         LET r=ATN2(y/x)-PI
      END IF
   ELSE !x=0
      IF y>0 THEN !∞
         LET r=PI/2
      ELSE
         IF y<0 THEN !-∞
            LET r=-PI/2
         ELSE !y=0
            PRINT "ARG関数は不定です。"
            STOP
         END IF
      END IF
   END IF
END IF
LET CompARG=r
END FUNCTION


!演算関連 べき乗

EXTERNAL SUB CompPow(x1,y1, x2,y2, x,y) !べき乗 (x1+y1*i) ^ (x2+y2*i) → x+y*i
CALL CompLOG(x1,y1, s,t) !z1^z2=exp(log(z1)*z2)より
CALL CompMul(s,t, x2,y2, a,b)
CALL CompEXP(a,b, x,y)
END SUB


!演算関連 四則演算、関数など

EXTERNAL SUB CompAdd(x1,y1, x2,y2, x,y) !加算 (x1+y1*i) + (x2+y2*i) → x+y*i
LET xx=x1+x2 !実部
LET yy=y1+y2 !虚部
LET x=xx
LET y=yy
END SUB

EXTERNAL SUB CompSub(x1,y1, x2,y2, x,y) !減算 (x1+y1*i) - (x2+y2*i) → x+y*i
LET xx=x1-x2
LET yy=y1-y2
LET x=xx
LET y=yy
END SUB

EXTERNAL SUB CompMul(x1,y1, x2,y2, x,y) !乗算 (x1+y1*i) * (x2+y2*i) → x+y*i
LET xx=x1*x2-y1*y2 !丸め誤差対策
LET yy=x1*y2+y1*x2
LET x=xx
LET y=yy
END SUB

EXTERNAL SUB CompDiv(x1,y1, x2,y2, x,y) !除算 (x1+y1*i) / (x2+y2*i) → x+y*i
IF x2=0 AND y2=0 THEN
   PRINT "0では割れません。"
   STOP
END IF
IF ABS(x2)>=ABS(y2) THEN !上位桁あふれ対策
   LET w=y2/x2
   LET tt=x2+y2*w
   LET xx=(x1+y1*w)/tt
   LET yy=(y1-x1*w)/tt
ELSE
   LET w=x2/y2
   LET tt=x2*w+y2
   LET xx=(x1*w+y1)/tt
   LET yy=(y1*w-x1)/tt
END IF
LET x=xx
LET y=yy
END SUB


EXTERNAL SUB CompSQR(x1,y1, x,y) !平方根
LET SQRT05=SQR(1/2) !0.707106781186547524
LET r=CompABS(x1,y1) !r=SQR(x1*x1+y1*y1)
LET w=SQR(r+ABS(x1))
IF x1>=0 THEN
   LET x=SQRT05*w
   LET y=SQRT05*y1/w
ELSE
   LET x=SQRT05*ABS(y1)/w
   IF y1>=0 THEN LET y=SQRT05*w ELSE LET y=-SQRT05*w
END IF
END SUB

EXTERNAL SUB CompEXP(x1,y1, x,y) !指数関数
DECLARE EXTERNAL FUNCTION EXP,SIN,COS !関数のオーバーロード
LET t=EXP(x1) !EXP(x+i*y)=EXP(x)*EXP(i*y)=EXP(x)*(COS(y)+i*SIN(y))
LET xx=t*COS(y1)
LET yy=t*SIN(y1)
LET x=xx
LET y=yy
END SUB

EXTERNAL SUB CompLOG(x1,y1, x,y) !対数関数
DECLARE EXTERNAL FUNCTION LOG !関数のオーバーロード
LET xx=0.5*LOG(x1*x1+y1*y1) !LOG(r)+i*θ、-π<θ<=π
LET yy=CompARG(x1,y1)
LET x=xx
LET y=yy
END SUB


!補助ルーチン ※多桁の関数

EXTERNAL FUNCTION ATN2(x) !アークタンジェント (-π/2,π/2)
IF x>1 THEN
   LET cSGN=1
   LET x=1/x
ELSEIF x<-1 THEN
   LET cSGN=-1
   LET x=1/x
ELSE
   LET cSGN=0
END IF
LET a=0
FOR i=1500 TO 1 STEP -1 !※繰り返し回数は調整が必要である
   LET a0=a
   LET a=(i*i*x*x)/(2*i+1 + a)
   IF ABS(a-a0)<=EPS(0) THEN EXIT FOR
NEXT i
IF cSGN>0 THEN
   LET ATN2=PI/2-x/(1+a)
ELSEIF cSGN<0 THEN
   LET ATN2=-PI/2-x/(1+a)
ELSE
   LET ATN2=x/(1+a)
END IF
END FUNCTION


MERGE "EXP.LIB" !指数関数 ※級数展開で関数を計算する
MERGE "LOG.LIB" !対数関数
MERGE "TRIGONOM.LIB" !三角関数(正弦,余弦,正接)
 

Re: 複素数の計算

 投稿者:山中和義  投稿日:2009年11月20日(金)09時21分31秒
返信・引用
  > No.747[元記事へ]

続き  ※必要に応じて追加してください。
!演算関連 べき乗、関数など

EXTERNAL SUB CompPowN(x1,y1, n, x,y) !べき乗 (x1+y1*i) ^ n → x+y*i
DECLARE EXTERNAL FUNCTION SIN,COS !関数のオーバーロード
LET r=CompABS(x1,y1) !r,θ
LET th=CompARG(x1,y1)
LET t=r^n !z^n=r^n*(COS(n*θ)+i*SIN(n*θ))、r=SQR(x1*x1+y1*y1)
LET x=t*COS(n*th)
LET y=t*SIN(n*th)
END SUB

EXTERNAL SUB CompNPow(n, x1,y1, x,y) !べき乗 n ^ (x1+y1*i) → x+y*i
DECLARE EXTERNAL FUNCTION LOG !関数のオーバーロード
CALL CompMul(LOG(n),0, x1,y1, a,b) !n^z1=exp(log(n)*z1)より
CALL CompEXP(a,b, x,y)
END SUB


EXTERNAL SUB CompSIN(x1,y1, x,y) !三角関数 正弦
DECLARE EXTERNAL FUNCTION EXP,SIN,COS !関数のオーバーロード
!sin(x+yi)
!={exp(x*i-y)-exp(-x*i+y)}/(2*i)  ※sin(z)=(exp(i*z)-exp(-i*z))/(2*i)より
!={exp(-y)*(cos(x)+i*sin(x))-exp(y)*(cos(x)-i*sin(x))}/(2*i) ※exp(i*x)=cos(x)+i*sin(x)より
!={(exp(y)-exp(-y))*(-cos(x)) + (exp(y)+exp(-y))*sin(x)*i}/(2*i)
!={(exp(y)-exp(-y))*cos(x)*i + (exp(y)+exp(-y))*sin(x)}/2

LET e=EXP(y1)
LET f=1/e
LET yy=0.5*(e-f)*COS(x1)
LET xx=0.5*(e+f)*SIN(x1)
LET x=xx
LET y=yy
END SUB

EXTERNAL SUB CompCOS(x1,y1, x,y) !三角関数 余弦
DECLARE EXTERNAL FUNCTION EXP,SIN,COS !関数のオーバーロード
LET e=EXP(y1) !(exp(i*z)+exp(-i*z))/2
LET f=1/e
LET yy=0.5*(f-e)*SIN(x1)
LET xx=0.5*(f+e)*COS(x1)
LET x=xx
LET y=yy
END SUB

EXTERNAL SUB CompTAN(x1,y1, x,y) !三角関数 正接
DECLARE EXTERNAL FUNCTION EXP,SIN,COS !関数のオーバーロード
LET e=EXP(2*y1)
LET f=1/e
LET d=COS(2*x1)+0.5*(e+f)
LET x=SIN(2*x1)/d
LET y=(e-f)/d
END SUB

!逆三角関数
! ArcSin(z)=-i*LOG(SQR(1-z^2)+z*i)
! ArcCos(z)=-i*LOG(z+i*SQR(1-z^2))
! ArcTan(z)=i/2*LOG((i+z)/(i-z))


EXTERNAL SUB CompSinh(x1,y1, x,y) !双曲線正弦
DECLARE EXTERNAL FUNCTION EXP,SIN,COS !関数のオーバーロード
LET e=EXP(x1)
LET f=1/e
LET xx=0.5*(e-f)*COS(y1)
LET yy=0.5*(e+f)*SIN(y1)
LET x=xx
LET y=yy
END SUB

EXTERNAL SUB CompCosh(x1,y1, x,y) !双曲線余弦
DECLARE EXTERNAL FUNCTION EXP,SIN,COS !関数のオーバーロード
LET e=EXP(x1)
LET f=1/e
LET xx=0.5*(e+f)*COS(y1)
LET yy=0.5*(e-f)*SIN(y1)
LET x=xx
LET y=yy
END SUB

EXTERNAL SUB ComppTanh(x1,y1, x,y) !双曲線正接
DECLARE EXTERNAL FUNCTION EXP,SIN,COS !関数のオーバーロード
LET e=EXP(2*x1)
LET f=1/e
LET d=0.5*(e+f)+COS(2*y1)
LET y=SIN(2*y1)/d
LET x=0.5*(e-f)/d
END SUB
 

Re: この現象を再現して下さい

 投稿者:山中和義  投稿日:2009年11月20日(金)10時59分13秒
返信・引用
  > No.746[元記事へ]

十進BASICで扱える半角文字です。フォントを切り替えることで絵文字が表示できます。
登録させているフォントに依存します。
!ASCII,JISコード表

SET bitmap SIZE 501,501
SET WINDOW -1.5,16.5,16,-2

FOR i=0 TO 15 !行番号
   PLOT TEXT ,AT -1,i: BSTR$(i,16)
NEXT i
FOR i=0 TO 15 !列番号
   PLOT TEXT ,AT i,-1: BSTR$(i,16)
NEXT i

SET TEXT COLOR 4
FOR c=32 TO 255 !文字の表示
   WHEN EXCEPTION IN
      PLOT TEXT ,AT MOD(c,16),INT(c/16): CHR$(c)
   USE
      PRINT c !使用不可コード ※MS漢字(2バイト文字)の先頭
   END WHEN
NEXT c

SET TEXT font "Wingdings",12
!SET TEXT font "symbol",12
SET TEXT COLOR 1
FOR c=32 TO 255 !フォントの表示
   WHEN EXCEPTION IN
      PLOT TEXT ,AT MOD(c,16)+0.2,INT(c/16)+0.4: CHR$(c)
   USE
      PRINT c
   END WHEN
NEXT c

END
 

!2階微分方程式の、ルンゲクッタ描画。

 投稿者:SECOND  投稿日:2009年11月21日(土)09時27分17秒
返信・引用
  !2階微分方程式の、ルンゲクッタ描画。

!ベッセルの微分方程式の場合。

!x^2*(d2y/dx2)+x*(dy/dx)+(x^2-a^2)*y=0 …ベッセル
!x^2*(d2y/dx2)+x*(dy/dx)-(x^2+a^2)*y=0 …変形ベッセル
!-------------------------------
OPTION ARITHMETIC NATIVE
OPTION BASE 0
SET TEXT background "opaque"
DIM col(4), y0(4)
MAT READ col
DATA 4,10,2,14, 12 ! 0次 〜4次の色分け
!-----------------------------------------------------------------------
!0白 1黒   2青      3 緑      4赤    5水 色    6黄 色        7赤紫
!    8灰色 9濃い青 10濃い緑 11青緑 12えび茶 13オリーブ色 14濃い紫 15銀色
!-----------------------------------------------------------------------

SUB Dji( oddy,ody, iddy,idy,y)
   LET oddy=-( x*idy +(sj*x^2-a^2)*y)/x^2 ! ddy=(d2y/dx2) :sj=1(ベッセル)
   LET ody=-(x^2*iddy+(sj*x^2-a^2)*y)/x   ! dy=  (dy/dx)  :sj=-1(変形ベッセル)
END SUB

SUB RungeKutta
   CALL Dji( oddy1,ody1, iddy, idy, y)
   CALL Dji( oddy2,ody2, iddy, idy+oddy1*dx/2, y+ody1*dx/2)
   CALL Dji( oddy3,ody3, iddy, idy+oddy2*dx/2, y+ody2*dx/2)
   CALL Dji( oddy4,ody4, iddy, idy+oddy3*dx  , y+ody3*dx  )
   LET  y=y+(ody1+2*ody2+2*ody3+ody4)*dx/6
   LET idy=idy+(oddy1+2*oddy2+2*oddy3+oddy4)*dx/6
   LET iddy=oddy4
END SUB

LET dx=.0005               !pitch
LET y0(0)=1                !yの初期値
LET y0(1)= 0.708248*dx
LET y0(2)=-1.2017  *dx^2
LET y0(3)=-0.015   *dx^3
LET y0(4)= 0.00615 *dx^4
!-----
LET sj=-1
LET m$="変形"
CALL window_
CALL Rk_bessel  !変形ベッセルの微分方程式( ルンゲクッタ描画 )
CALL fn_bessel  !変形ベッセル関数1種 In(x)
WAIT DELAY 2
!-----
LET sj=1
LET m$=""
CALL window_
CALL Rk_bessel  !  ベッセルの微分方程式( ルンゲクッタ描画 )
CALL fn_bessel  !  ベッセル関数1種 Jn(x)

SUB window_
   CLEAR
   IF sj=1 THEN  !----ベッセル
      LET h=1
      LET l=-1
      LET xr=20
      SET WINDOW -3,xr, l, h
      DRAW grid(xr/4,h/5)
   ELSEIF sj=-1 THEN  !----変形ベッセル
      LET h=4
      LET l=-1.5
      LET xr=4
      SET WINDOW -0.3,xr, l, h
      DRAW grid(xr/8,h/8)
   END IF
   ASK PIXEL SIZE(0,0;xr,0) px,py
   LET ss=Xr/px
END SUB

!-------------------- 微分方程式のルンゲクッタ描画
SUB Rk_bessel
   SET TEXT COLOR 4
   PLOT TEXT,AT (.325+.225*sj)*xr,.9*h-(.2-.04*sj)*(h-l) :"ルンゲクッタ描画"
   FOR a=0 TO 4
      LET y=y0(a)
      LET idy=0
      LET iddy=0
      SET LINE COLOR "gray" !col(a+4)
      SET TEXT COLOR "gray" !col(a+4)
      PLOT TEXT,AT .1*xr,.9*h-.04*(h-l)*a :m$& "ベッセルの微分方程式 "& STR$(a)& "次"
      !------------
      FOR x=dx TO xr+dx STEP dx
         PLOT LINES: x,y; ! PEN-on
         IF FP(x)< dx THEN PRINT USING"##.## ###.######":x,y
         CALL RungeKutta
      NEXT x
      !------------
      PLOT LINES !PEN-off
      PRINT
   NEXT a
END SUB

!********************* 解のベッセル関数を重ねて照合する。
SUB fn_bessel
   SET TEXT COLOR 1
   PLOT TEXT,AT (.325+.225*sj)*xr,.9*h-(.2-.04*sj)*(h-l) :"関数で、重ね書き"
   FOR n=0 TO 4
      SET LINE COLOR col(n)
      SET TEXT COLOR col(n)
      PLOT TEXT,AT .1*xr,.9*h-.04*(h-l)*n :m$& "ベッセル関数1種 "& STR$(n)& "次  "
      !------------画素間隔のStep
      FOR x=dx TO xr+ss STEP ss
         PLOT LINES: x,bessel(n,x); ! PEN-on
         IF FP(x)< ss AND dx< x THEN PRINT USING"##.## ###.######":IP(x),bessel(n,IP(x))
      NEXT x
      !------------
      PLOT LINES !PEN-off
      PRINT
   NEXT n
END SUB

!------- ベッセル関数 変形ベッセル関数
FUNCTION bessel(n,x)
   LET m=2*INT( (6+MAX(n,1.5*ABS(x))+9*1.5*ABS(x)/(1.5*ABS(x)+2))/2)
   LET w=0
   IF sj=1 THEN      !---- ベッセル関数 Jn(x)
      FOR k=1 TO m/2
         LET w=w+Tk(k*2,x)
      NEXT k
      LET bessel=Tk(n,x)/(Tk(0,x)+2*w)
   ELSEIF sj=-1 THEN !---- 変形ベッセル関数 In(x)
      FOR k=1 TO m
         LET w=w+Tk(k,x)
      NEXT k
      LET bessel=EXP(x)*Tk(n,x)/(Tk(0,x)+2*w)
   END IF
END FUNCTION

FUNCTION Tk(i,x)
   LET t2=0
   LET t1=1e-9
   LET t0=2*(m+1)/x*t1-sj*t2
   FOR kp1=m TO i+1 STEP -1
      LET t2=t1
      LET t1=t0
      LET t0=2*kp1/x*t1-sj*t2
   NEXT kp1
   LET Tk=t0
END FUNCTION

END
 

ちょっと不思議

 投稿者:GAI  投稿日:2009年11月22日(日)23時23分1秒
返信・引用
  LET s=0
FOR  k=1 TO 100
   LET s=s+1/k^2
   LET t=s+1/k
   PRINT USING "#.##########" : s;
   PRINT USING "####.##########" : t
NEXT K
END



!Sは単調増加であるのに対し、Tが単調減少であるのがなんか不思議に感じてしまう?
 

広義積分の計算のプログラム

 投稿者:GAI  投稿日:2009年11月22日(日)23時33分53秒
返信・引用
  ∫0〜∞(e^(-t)/(1-e^(-t))-e^(-t)/t)dt
の計算をするのは、どうやったらいいか教えてください。
 

Re: 広義積分の計算のプログラム

 投稿者:山中和義  投稿日:2009年11月23日(月)10時37分28秒
返信・引用  編集済
  > No.752[元記事へ]

GAIさんへのお返事です。

数値積分
 0.5772156649015328606… オイラーの定数γ

!半無限区間積分 ∫[0,∞]{EXP(-x)*f(x)}dx
DEF F(X)=1/(1-EXP(-X)) - 1/X
LET S=0
FOR I=1 TO 20
   READ X,W
   LET  S=S+W*F(X)
NEXT I
PRINT S
DATA   .0705398896919888, 1.6874680185111386E-01 !ガウス・ラゲール則の係数(分点、重み)
DATA   .3721268180016114, 2.9125436200606828E-01 !20次ラゲール多項式より
DATA   .9165821024832736, 2.6668610286700129E-01
DATA  1.7073065310283439, 1.6600245326950684E-01
DATA  2.7491992553094321, 7.4826064668792371E-02
DATA  4.0489253138508869, 2.4964417309283221E-02
DATA  5.6151749708616165, 6.2025508445722368E-03
DATA  7.4590174536710633, 1.1449623864769082E-03
DATA  9.5943928695810968, 1.5574177302781197E-04
DATA 12.0388025469643163, 1.5401440865224916E-05
DATA 14.8142934426307400, 1.0864863665179824E-06
DATA 17.9488955205193760, 5.3301209095567148E-08
DATA 21.4787882402850110, 1.7579811790505820E-09
DATA 25.4517027931869055, 3.7255024025123209E-11
DATA 29.9325546317006120, 4.7675292515781905E-13
DATA 35.0134342404790000, 3.3728442433624384E-15
DATA 40.8330570567285711, 1.1550143395003988E-17
DATA 47.6199940473465021, 1.5395221405823436E-20
DATA 55.8107957500638989, 5.2864427255691578E-24
DATA 66.5244165256157538, 1.6564566124990233E-28
END
 

これがそうだったのか!

 投稿者:GAI  投稿日:2009年11月23日(月)21時05分4秒
返信・引用
  こんな積分の値をプログラムで計算させる理論がGauss-Laguerre公式で、他のタイプには
Gauss-Legendre公式やGauss-Hermite公式、などもあり、それぞれの多項式の零点と適当な重み関数との組み合わせで定積分の値を数値積分できることを知りました。
(名前は聞いたことはありましたが、これがいつどんな場面で使うものか検討もつきませんでした。この例で初めてそれが何たるのかが、おぼろげに感じることができました。)
専門家の方にとっては常識的な事かもしれませんが、私にとってはグッと世界が広がった感覚でした。
それにしても、コンピュータが出現する遥か前からその計算手段を考えついている先人の知恵の凄さに驚嘆します。
つまらない質問にも丁寧に対応してもらえていつもありがとうございます。

http://公式

 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年11月24日(火)11時33分59秒
返信・引用
  > No.721[元記事へ]

イルミネーション(電飾)の季節になりました。 そこで、N個の電球で遊んでみましょう。
!N個の電球

!1〜Nの番号の付いた電球がある。
!各電球にはスイッチがあり、点灯/消灯(ON/OFF)させることができる。
!1≦i≦Nに対して、i回目にiの倍数の電球の点灯/消灯(ON/OFF)させる。
!すべて消灯の状態から始めて、最後に点灯(ON)している電球の数は?

!倍数、約数の個数、エラトステネスの篩、素数

SET bitmap SIZE 601,601
SET WINDOW -1,50,50,-1

LET N=2009 !個数

DIM A(N)
MAT A=ZER !全消灯 ⇒倍数、約数の個数
!!!MAT A=CON !全点灯 ⇒エラトステネスの篩、素数

FOR i=1 TO N !i回目

   FOR k=1 TO N !倍数にあたる電球に対して
      LET t=k*i
      IF t>N THEN EXIT FOR

      LET A(t)=MOD(A(t)+1,2) !点灯/消灯
      !!!LET A(t)=A(t)+1 !カウンタ ⇒約数の個数
      !!!LET A(t)=0 !消灯のみ ⇒エラトステネスの篩、素数
   NEXT k

   !MAT PRINT A; !debug
   SET DRAW mode hidden !ちらつき防止開始
   CLEAR
   FOR p=0 TO N-1
      IF A(p+1)=1 THEN
         DRAW disk WITH SCALE(0.5)*SHIFT(MOD(p,50),INT(p/50))
      ELSE
         DRAW circle WITH SCALE(0.5)*SHIFT(MOD(p,50),INT(p/50))
      END IF
   NEXT p
   PLOT TEXT ,AT 2,48: STR$(i)&"の倍数"
   SET DRAW mode explicit !ちらつき防止終了
NEXT i


LET c=0 !点灯している個数
FOR i=1 TO N
   IF A(i)=1 THEN LET c=c+1
NEXT i
PRINT c;"個"


PRINT INT(SQR(N)) !検算 平方数の数

END


また、時刻ごとに電飾を(正弦波、不等式の領域などの)数理的操作が可能です。
電子工作ふ〜にプログラムしてみました。
!定数
LET Vcc=1 !プラス電源
LET GND=0 !GND電位

LET ON_=GND !アノード:Vcc
LET OFF_=Vcc

LET h=8 !行方向の電球の数
LET w=5*h !列方向

DIM L(h,w) !電球の状態
MAT L=ZER !全消灯

SET bitmap SIZE w*20+1,h*20+1 !基盤の大きさ
SET WINDOW 0,w+1,h+1,0
DRAW grid(2,2)

DIM P(h,w)

!●フロー、シフト型
LET m=8
FOR x=1 TO w !初期状態
   LET v=(m-1)-MOD(x-1,m) !のこぎり波
   FOR y=1 TO h
      LET L(y,x)=v
   NEXT y
NEXT x
MAT PRINT L;

FOR t=1 TO 50 !駆動回路
   FOR y=1 TO h !0と1に復号化する
      FOR x=1 TO w
         LET L(y,x)=MOD(L(y,x)+1,m) !右方向へ移動させる (k+1) mod m

         !!!IF L(y,x)=m-1 THEN LET P(y,x)=ON_ ELSE LET P(y,x)=OFF_ !道路工事
         IF L(y,x)>=m-3 THEN LET P(y,x)=ON_ ELSE LET P(y,x)=OFF_ !道路工事2
      NEXT x
   NEXT y

   DRAW LEDmatrix(P,h,w) !電球を光らせる
   WAIT DELAY 0.3
NEXT t


!●シャッター型
LET m=8
FOR x=1 TO w !初期状態
!!!LET v=(m-1)-MOD(x-1,m) !パターン1
   LET v=(m-1)-MOD(x-1,m)-INT((x-1)/m) + INT(m/2) !パターン2
   FOR y=1 TO h
      LET L(y,x)=v
   NEXT y
NEXT x
MAT PRINT L;

!!!LET m=m+1!パターン1
LET m=m+1 + INT(m/2) !パターン2
LET n=m
FOR t=1 TO 50 !駆動回路
   LET n=MOD(n-1,m)
   FOR y=1 TO h !0と1に復号化する
      FOR x=1 TO w
         IF L(y,x)>=n THEN LET P(y,x)=ON_ ELSE LET P(y,x)=OFF_ !閾値
      NEXT x
   NEXT y

   DRAW LEDmatrix(P,h,w) !電球を光らせる
   WAIT DELAY 0.3
NEXT t


!電子部品(配置と配線)

PICTURE LEDmatrix(L(,),m,n) !m行n列マトリクス
   SET DRAW mode hidden !ちらつき防止開始
   CLEAR
   FOR x=1 TO n !ダイナミック点灯(個々に点灯させる)
      FOR y=1 TO m
         DRAW LED(Vcc,L(y,x)) WITH SHIFT(x,y)
      NEXT y
   NEXT x
   SET DRAW mode explicit !ちらつき防止終了
END PICTURE

!電子部品(下位)

!  a │
!  ▼→
! k T
!  │
PICTURE LED(a,k) !発光ダイオードを表示する
   IF a=1 AND k=0 THEN
      DRAW disk WITH SCALE(0.5) !点灯
   ELSE
      DRAW circle WITH SCALE(0.5) !消灯
   END IF
END PICTURE

END
 

Re: 広義積分の計算のプログラム

 投稿者:山中和義  投稿日:2009年11月25日(水)14時14分32秒
返信・引用
  > No.753[元記事へ]

二重指数関数型で数値積分してみました。
OPTION ARITHMETIC NATIVE

!2重指数関数型数値積分(Double Exponential formula)
! ∫[0,∞]f(x)dx 半無限領域(0,∞)の積分
!
! x=EXP(t-EXP(-t))とすると、dx/dt=EXP(t-EXP(-t))*(1+EXP(-t))
! 与式=∫[-∞,∞]{f(EXP(t-EXP(-t)))*EXP(t-EXP(-t))*(1+EXP(-t))}dt

DEF f(x)=EXP(-x)/(1-EXP(-x)) - EXP(-x)/x !∫[0,∞]f(x)dx = 0.5772156649015328606… オイラーの定数γ

LET N=36 !分割数
LET h=1/6

LET s=0
FOR j=-N/2 TO N/2
   LET t=j*h
   LET v=EXP(-t)
   LET x=EXP(t-v)
   LET s=s + f(x)*x*(1+v)
NEXT j
LET s=h*s

PRINT s !結果を表示する



!2重指数関数型数値積分(Double Exponential formula)
! ∫[0,∞]f(x)dx 半無限領域(0,∞)の積分
!
! x=EXP(PI*SINH(t))とすると、dx/dt=EXP(PI*SINH(t))*PI*COSH(t)
! 与式=PI*∫[-∞,∞]{f(EXP(PI*SINH(t)))*EXP(PI*SINH(t))*COSH(t)}dt

DEF g(x)=1/(1+x^6) !∫[0,∞]g(x)dx = PI/3

LET N=64 !分割数
LET h=1/8

LET s=0
FOR j=-N/2 TO N/2
   LET t=j*h
   LET x=EXP(PI*SINH(t))
   LET s=s + g(x)*x*COSH(t)
NEXT j
LET s=h*PI*s

PRINT s !結果を表示する

PRINT PI/3 !検算



!2重指数関数型数値積分(Double Exponential formula)
! ∫[-1,1]f(x)dx
!
! x=TANH(PI/2*SINH(t))とすると、dx/dt=PI/2*COSH(t)/COSH(PI/2*SINH(t))^2
! 与式=PI/2*∫[-∞,∞]{f(TANH(PI/2*SINH(t)))*COSH(t)/COSH(PI/2*SINH(t))^2}dt

DEF f2(x)=SQR(1-x^2)/(2-x) !∫[-1,1]f(x)dx = PI*(2-SQR(3))

LET N=64 !分割数
LET h=1/8

LET s=0
FOR j=-N/2 TO N/2
   LET t=j*h
   LET v=PI/2*SINH(t)
   LET s=s + f2(TANH(v))*COSH(t)/COSH(v)^2
NEXT j
LET s=h*PI/2*s

PRINT s !結果を表示する

PRINT PI*(2-SQR(3)) !検算


END
 

ハイウェイ

 投稿者:SECOND  投稿日:2009年11月25日(水)19時06分2秒
返信・引用  編集済
  !大幅に 改訂し、特に路面の描画を改善した、が、次の問題が解けない。
!見え隠れする路面の裏側を、別な色で塗るには、どうすれば、よいか?
!------------
! ハイウェイ
!------------
!SET bitmap SIZE 671,671
DIM Mp(4,4)         !視点からの被写体の相対座標(一点投影用)
DIM Xz(4,4),zY(4,4) !XY_Xz変換, XY_zY変換
DIM XYz(4,4)        !XY平面のz平行移動
!
!※投影面の裏側に、操作対象が有るので、座標は左手系(Z軸が裏向き)です。
! 投影面を、車両前縁d に置き、Z=1.5 、視点 Z=0 が 手前。
! 視点 Z=0 を頂点に、投影面 Z=1.5 へ 一点投影。面中心から±1を画面とし、
! 外界面を、投影面 前方+170 から、投影面 Z=1.5 までを、奥から描く。
!-------------------------------------------------------------------------
!      一点投影用 Mp
!
!原画_行ベクトル     Mp           表示_行ベクトル
!     (X,Y,Z,1)|1   0   0   0| →(X+x,Y+y, * ,Z+z) の4列目 Z+z で縮小。
!              |0   1   0   0|                               ↓
!              |0   0   0   1|      座標 (X+x)/(Z+z),(Y+y)/(Z+z) の描点群。
!              |x   y   0   z|      * 印は「最終的表示で無効」のz座標。
MAT READ Mp
DATA 1,0,0,0   !小文字 x y z は、視点から、道路左端の相対座標。
DATA 0,1,0,0
DATA 0,0,0,1   !変形指示 MAT 文で効果する。
DATA 0,0,0,0
!-------------------------------------------------------------------------
! 道路など、画面に垂直な広がりは、以下の Xz zY XYz 行列を、先に通します。
! 上の原画の Z は通常0ですが、以下の様に 変形を行なうと、発生します。
!-------------------------------------------------------------------------
!<路面>の原画用 Xz    XY平面→ XZ平面として描く。
!
!原画_行ベクト ル                   新しい原画_行ベクトル
!     (X,Y,0,1)|1    0    0   0| →(X+Y*dxdz, Y*dydz, Y, 1)
!              |dxdz dydz 1   0|
!              |0    0    0   0|    dxdz: Z軸カーブの微分 dx/dz
!              |0    0    0   1|    dydz: Z軸ピッチの微分 dy/dz
MAT READ Xz
DATA 1,0,0,0
DATA 0,0,1,0
DATA 0,0,0,0
DATA 0,0,0,1
!-------------------------------------------------------------------------
!<建物>の原画用 zY     XY平面→ ZY平面として描く。
!
!原画_行ベクト ル                   新しい原画_行ベクトル
!     (X,Y,0,1)|dxdz 0    1   0| →(X*dxdz+x, Y, X, 1)
!              |0    1    0   0|
!              |0    0    0   0|    dxdz: Z軸カーブの微分 dx/dz
!              |x    0    0   1|       x: ZY平面のx座標
MAT READ zY
DATA 0,0,1,0
DATA 0,1,0,0
DATA 0,0,0,0
DATA 0,0,0,1
!-------------------------------------------------------------------------
!<建物>の原画用 XYz     XY平面の Z軸移動。
!
!原画_行ベクト ル                       新しい原画_行ベクトル
!     (X,Y,0,1)|1        0    0   0| →(X+(dxdz)*z, Y, z, 1)
!              |0        1    0   0|
!              |0        0    0   0|    dxdz: Z軸カーブの微分 dx/dz
!              |(dxdz)*z 0    z   1|       z: Z軸 移動差分
MAT READ XYz
DATA 1,0,0,0
DATA 0,1,0,0
DATA 0,0,0,0
DATA 0,0,0,1
!-------------------------------------------------------------------------
!
DEF v(t)=v0+a*t                   !速度
DEF I_v(t)=v0*t+a*t*t/2           !移動距離 ∫v(t)dt
!
DEF yaw(z)= 10*SIN((z-2)*0.1)      !カーブ、横の偏差  x(z)
DEF d_yaw(z)= COS((z-2)*0.1)      !カーブ、微分係数 dx/dz
DEF pitch(z)= 5*SIN(z*0.1)         !ピッチ、縦の偏差  y(z)
DEF d_pitch(z)= 0.5*COS(z*0.1)     !ピッチ、微分係数 dy/dz
!
SET WINDOW -1,1,-1,1              !画面スケール±1
LET v0=15                         !初速度
LET a=-v0^2/2/100                 !減速加速度, -v0^2/2/移動距離
LET t0=TIME
DO
   LET t=TIME-t0
   IF t>tb+0.15 THEN
      LET tb=t
      LET d=I_v(t)                !車両前縁d のz座標
      PRINT USING "時間=###.## 速度=###.##  走行距離=###.##":t,v(t),d
      SET DRAW mode hidden        !裏ページに書く
      CALL Animation              ! 描画
      SET DRAW mode explicit      !裏ページの表示
   END IF
   MOUSE POLL msx,msy,mlb,mrb
LOOP UNTIL v(t)<=0 OR mrb=1

SUB Animation
!----sky
   SET AREA COLOR 17
   PLOT AREA:-1,0; 1,0; 1,1; -1,1
   !----ground
   SET AREA COLOR 42
   PLOT AREA:-1,0; 1,0; 1,-1; -1,-1
   !----guide message
   SET TEXT COLOR 1
   SET TEXT FONT "",11
   PLOT TEXT,AT.35,.9:"右クリック保持 Stop"
   SET TEXT COLOR 0
   SET TEXT FONT "",90
   !----
   LET ss=5/2
   FOR i=IP((d+170)/ss)*ss TO d STEP -ss
      LET Mp(4,1)=  yaw(i)-yaw(d)  -1.5 !投影面中心線から    道路左端のx座標
      LET Mp(4,2)=pitch(i)-pitch(d)-1.5 !投影面中心線から    道路左端のy座標
      LET Mp(4,4)=       i-d       +1.5 !投影面の後方1.5 から道路左端のz座標
      !----
      ! 1                 ,0                     ,0         ,      0|
      ! 0                 ,1                     ,0         ,      0|
      ! 0                 ,0                     ,0         ,      1|
      ! yaw(i)-yaw(d)-1.5 ,pitch(i)-pitch(d)-1.5 ,0         ,i-d+1.5|
      !----
      IF MOD(i,10)=0 THEN
         DRAW Building( 0-2,-9, -3,20,-2  ) WITH Mp   !x,y, W,H,D
         DRAW Building( 6+2,-9, -3,19, 2.5) WITH Mp   !x,y, W,H,D
         DRAW Sign WITH Mp
      END IF
      IF MOD(i,10)=5 THEN DRAW Tree WITH Mp
      DRAW Road(-.993*ss) WITH Mp
   NEXT i
END SUB

!パーツのサイズ。
!画面( 投影面 Z=1.5:車両前縁d )で、表示倍率 1/Z ( 実幅3→ 描画幅2)

!原画座標で、道路左端xyz( 0 ,  0  ,1.5)= 画面左下角(-1,-1)
!原画座標で、左車線上xyz(1.5, 1.5 ,1.5)= 画面中心点( 0, 0) …投影中心

PICTURE Building(x,y,w,h,d1)
   IF d-i<=w THEN
   !---back plane
      LET zY(1,1)=d_yaw(i+w/2)     !Z軸カーブの微分 dx/dz
      LET zY(4,1)=x+d1             !ZY平面のx座標
      DRAW Wall((y),w,h) WITH zY
      !---facade
      LET zY(4,1)=x                !ZY平面のx座標
      DRAW Wall((y),w,h) WITH zY
      !---side plane
      LET XYz(4,1)=d_yaw(i+w/2)*w  !Z軸カーブによるx移動差分
      LET XYz(4,3)=w               !Z軸 移動差分
      DRAW Side(x,y,h,d1) WITH XYz
   END IF
END PICTURE
!
PICTURE Wall(y,w,h)
   SET AREA COLOR 8  !gray
   PLOT AREA: 0,y; w,y; w,y+h; 0,y+h       !(Z,Y)平面として描く。
   FOR y=y+h-.5 TO y+1 STEP -2.5
      PLOT LINES: 0,y; w,y                    ! (Z,Y)平面として描く。
   NEXT y
END PICTURE
!
PICTURE Side(x,y,h,d1)
   SET AREA COLOR 16 !dark gray
   PLOT AREA: x,y; x+d1,y; x+d1,y+h; x,y+h !移動前(X,Y)平面として描く。
END PICTURE

PICTURE Road(e)
   IF e< d-i THEN LET e=d-i
   LET Xz(2,1)=d_yaw(i+e/2)     !Z軸カーブの微分 dx/dz
   LET Xz(2,2)=d_pitch(i+e/2)   !Z軸ピッチの微分 dy/dz
   DRAW Surface(e) WITH Xz
END PICTURE
!
PICTURE Surface(e)
   SET AREA COLOR 15
   PLOT AREA: 0,0; 6,0; 6,e; 0,e           !(X,Z)平面として描く。
   !---center line
   SET AREA COLOR 0
   PLOT AREA: 2.9,0; 2.9,e; 3.1,e; 3.1,0   !(X,Z)平面として描く。
   !---joint line
   PLOT LINES: 0  ,0; 2.9,0
   PLOT LINES: 3.1,0; 6  ,0
END PICTURE

PICTURE Tree
   SET AREA COLOR 12 !幹
   PLOT AREA:-0.075,0; 0.075,0; 0.025,3;-0.025,3
   SET AREA COLOR 10
   FOR w=1 TO 7      !葉
      DRAW disk WITH SCALE(0.3+0.05-RND*0.1)*SHIFT(0.4-RND*0.8, 2.7+0.325-RND*0.75)
   NEXT W
END PICTURE

PICTURE Sign
   IF MOD(i,50)=0 THEN SET AREA COLOR 2 ELSE SET AREA COLOR 4
   PLOT AREA:-0.025,0; 0.025,0; 0.025,2;-0.025,2 !pole
   DRAW disk WITH SCALE(0.5)*SHIFT(0,2)          !plate
   !PLOT TEXT,AT -.35,1.74,USING ">%%":STR$(i)    !sign
   CALL Plot_7segment(0 ,2 ,0.15 ,STR$(i))       !sign( PLOT TEXT が重い時)
END PICTURE

SUB Plot_7segment(x,y,s,i$)   !文字列中心(x,y) 文字の横幅(s) 数字の文字列(i$)
   SET LINE COLOR 0
   SET LINE width 9/(i-d+1.5) !一点投影・縮小の補償。(線幅は MAT 文で縮まない)
   LET w=LEN(i$)
   LET s1=s      ! y軸↑:s1=s  y軸↓:s1=-s
   LET s2=s/2
   LET x=x-(w-1)*s2*1.6
   FOR p=1 TO w
      SELECT CASE VAL(i$(p:p))
      CASE 0
         PLOT LINES:x-s2,y+s;x-s2,y-s;x+s2,y-s;x+s2,y+s;x-s2,y+s
      CASE 1
         PLOT LINES:x,y-s;x,y+s
      CASE 2
         PLOT LINES:x-s2,y+s1;x+s2,y+s1;x+s2,y;x-s2,y;x-s2,y-s1;x+s2,y-s1
      CASE 3
         PLOT LINES:x-s2,y-s;x+s2,y-s;x+s2,y+s;x-s2,y+s
         PLOT LINES:x-s2,y;x+s2,y
      CASE 4
         PLOT LINES:x-s2,y+s1;x-s2,y;x+s2,y
         PLOT LINES:x+s2,y+s1;x+s2,y-s1
      CASE 5
         PLOT LINES:x+s2,y+s1;x-s2,y+s1;x-s2,y;x+s2,y;x+s2,y-s1;x-s2,y-s1
      CASE 6
         PLOT LINES:x+s2,y+s1;x-s2,y+s1;x-s2,y-s1;x+s2,y-s1;x+s2,y;x-s2,y
      CASE 7
         PLOT LINES:x-s2,y+s1;x+s2,y+s1;x+s2,y-s1
      CASE 8
         PLOT LINES:x-s2,y;x-s2,y-s;x+s2,y-s;x+s2,y+s;x-s2,y+s;x-s2,y;x+s2,y
      CASE 9
         PLOT LINES:x+s2,y;x-s2,y;x-s2,y+s1;x+s2,y+s1;x+s2,y-s1;x-s2,y-s1
      CASE ELSE
      END SELECT
      LET x=x+s*1.6
   NEXT p
   SET LINE width 1
   SET LINE COLOR 1
END SUB

END
 

SECONDさんへありがとう

 投稿者:kikiriri  投稿日:2009年11月25日(水)20時36分1秒
返信・引用
  kikiririより

面白いプログラムありがとうございます。
早速実行してみました。
良かったです。
 

訂正:スレッドへの投稿も編集可能

 投稿者:荒田浩二  投稿日:2009年11月26日(木)12時19分0秒
返信・引用
  > No.744[元記事へ]

以前に投稿した記事で『スレッドへの投稿記事は、投稿者本人でも後から編集はできないようです。』と書きましたが間違えてました。

スレッドへの投稿記事も、投稿者本人による編集・削除が可能です。

また参考情報として、投稿記事には投稿順に記事番号が付加されますが、その番号はスレッドへの投稿も含んで付加されます。
 

Re: 広義積分の計算のプログラム

 投稿者:GAI  投稿日:2009年11月26日(木)17時57分39秒
返信・引用  編集済
  > No.757[元記事へ]

山中和義さんへのお返事です。

2重指数関数型数値積分
というテクニックとても参考になります。
歴史を読んでいたら、伊理、森口、高澤によるIMT公式が発展の端緒であると書いてありました。
この中の森口(たぶん森口繁一氏のことか?)さんは、ずっと前にNHKコンピュータ講座をされていた方ではないかと思われますが、私が高校時代(もう30 数年も前になりますが・・・)この番組をみてこの人の本質を的確に説明される話し方にとても魅力を抱いたことを思いだします。
よくもまあこんな置換構造を発見し、従来の方法では求めにくい積分値を計算機という道具を十二分に活用できる道筋を開くことができるものだと感心いたします。
まだまだ、われわれが知らない構造が隠れており、誰かがその秘密を暴くことで今までにないブレイクスルーの近道を提供できるのでしょうね。
つくづく研究者の知識と探究心の凄さに驚愕するばかりです。
 

レトロ・ゲームのからくり

 投稿者:山中和義  投稿日:2009年11月27日(金)13時02分5秒
返信・引用  編集済
  インベーダーの移動、攻撃を再現してみました。(改修版)
速度調整が必要なら、WAIT命令を実行してください。
また、マウスの左ボタンの押下でインベーダーを消滅できます。
!インベーダー・ゲーム

DEF V2W(x)=4*x !仮想画面の座標を物理画面の座標へ
DEF W2V(x)=INT(x/4) !その逆

PICTURE DOT !物理画面にドットを表示する
   PLOT AREA: -2,-2; 2,-2; 2,2; -2,2 !4x4
END PICTURE

LET vx=180 !仮想画面の大きさ 150×180ドット
LET vy=150

SET bitmap SIZE V2W(vx)+1,V2W(vy)+1 !物理画面の大きさ
SET WINDOW 0,V2W(vx),V2W(vy),0 !スクリーン座標

RANDOMIZE


!------------------------------ 弾
DATA "* " !コマ1 弾1
DATA " *"
DATA "* "

DATA " *" !コマ2
DATA "* "
DATA " *"

DIM bm$(1,2) !弾 3×2ドット
CALL ReadPattern(1,3, bm$)

LET NumOfBeam=5 !弾 最大数5
DIM BM(NumOfBeam,3)
MAT BM=(-1)*CON

!------------------------------ インベーダー
LET m=8 !m×nドット
LET n=11

DATA "**       **" !コマ1 機体0
DATA "*         *"
DATA "           "
DATA "           "
DATA "           "
DATA "           "
DATA "*         *"
DATA "**       **"

DATA "           " !コマ2
DATA "*  *   *  *"
DATA " *  * *  * "
DATA "  *     *  "
DATA "**       **"
DATA "  *     *  "
DATA " *  * *  * "
DATA "*  *   *  *"

DATA "  *     *  " !コマ1 機体1
DATA "*  *   *  *"
DATA "* ******* *"
DATA "*** *** ***"
DATA "***********"
DATA " ********* "
DATA "  *     *  "
DATA " *       * "

DATA "  *     *  " !コマ2
DATA "   *   *   "
DATA "  *******  "
DATA " ** *** ** "
DATA "***********"
DATA "* ******* *"
DATA "* *     * *"
DATA "   ** **   "

DATA "    ***    " !コマ1 機体2
DATA "   *****   "
DATA "  *******  "
DATA " ** *** ** "
DATA " ********* "
DATA "   *   *   "
DATA "  * * * *  "
DATA " * *   * * "

DATA "    ***    " !コマ2
DATA "   *****   "
DATA "  *******  "
DATA " ** *** ** "
DATA " ********* "
DATA "  * *** *  "
DATA " *       * "
DATA "  *     *  "

DATA "           " !コマ1 機体3
DATA "    ***    "
DATA " ********* "
DATA "**  ***  **"
DATA "***********"
DATA "   *****   "
DATA "  ** * **  "
DATA "**       **"

DATA "           " !コマ2
DATA "    ***    "
DATA " ********* "
DATA "**  ***  **"
DATA "***********"
DATA "   ** **   "
DATA "  *     *  "
DATA "   *   *   "

DIM ptn$(4,2) !パターン(1機×2コマ)で読み込む
CALL ReadPattern(4,m, ptn$)

SUB ReadPattern(n,l, ptn$(,))
   FOR k=1 TO n !各機体
      FOR j=1 TO 2 !各コマ
         LET v$=""
         FOR i=1 TO l
            READ s$
            LET v$=v$&s$
         NEXT i
         LET ptn$(k,j)=v$ !登録する
      NEXT j
   NEXT k
END SUB

!------------------------------ 編隊
LET p=6 !p×q
LET q=8
DIM F(p+1,q) !0以上:生存フラグ、パターン番号
MAT F=ZER
DATA  4, 4, 4, 4, 4, 4, 4, 4 !パターン番号 ※偶数
DATA  4, 4, 4, 4, 4, 4, 4, 4
DATA  6, 6, 6, 6, 6, 6, 6, 6
DATA  6, 6, 6, 6, 6, 6, 6, 6
DATA  2, 2, 2, 2, 2, 2, 2, 2
DATA  2, 2, 2, 2, 2, 2, 2, 2
DATA  6, 6, 6, 6, 6, 6, 6, 6 !先頭の番号
MAT READ F

LET ox=n+2 !機体の間隔
LET oy=m+2
LET lx=vx-ox*q !編隊の左上位置
LET ly=4


PICTURE BLOCK(v$,m,n) !インベーダーなどを位置(0,0)-(n,m)に表示する
   FOR i=0 TO m-1 !m×nドット
      FOR j=0 TO n-1
         LET k=i*n+j+1
         IF v$(k:k)<>" " THEN DRAW DOT WITH SHIFT(V2W(j),V2W(i))
      NEXT j
   NEXT i
END PICTURE


LET DX=-1 !移動方向
LET FLG=0 !機体の動作
LET Invaded=0 !侵略状況
DO !ゲームループ

!------------------------------ 当り判定(仮)
   MOUSE POLL mx,my,left,right !マウスの状態を得る
   IF left=1 THEN !左ボタン押下なら
      LET x=W2V(mx)-lx !編隊の領域内なら
      LET y=W2V(my)-ly
      IF x<0 OR x>=ox*q OR y<0 OR y>=oy*p THEN
      ELSE
         LET xx=MOD(x,ox) !機体内なら
         LET yy=MOD(y,oy)
         IF xx<n AND yy<m THEN
            LET xx=INT(x/ox)+1 !該当する機体を爆発→消滅する
            LET yy=INT(y/oy)+1
            IF F(yy,xx)>=2 THEN LET F(yy,xx)=1
         END IF
      END IF
   END IF


   !------------------------------ 描画処理毎(フレームを表示する)
   SET DRAW mode hidden !ちらつき防止開始
   CLEAR
   LET CntOfEnemy=0
   FOR x=1 TO q !インベーダー群を表示する
      IF F(p+1,x)>0 THEN !この列に機体が存在するなら

         LET xx=lx+ox*(x-1)

         LET F(p+1,x)=0
         FOR y=1 TO p
            LET ptn=F(y,x) !生存なら
            IF ptn>=0 THEN
               LET idx=INT(ptn/2) !パターンを選択する
               LET koma=MOD(ptn,2)
               DRAW BLOCK(ptn$(idx+1,koma+1),m,n) WITH SHIFT(V2W(xx),V2W(ly+oy*(y-1)))
               IF ptn=1 THEN
                  LET F(y,x)=-1 !爆発→消滅
               ELSE
                  LET F(y,x)=MOD(ptn+1,2)+idx*2 !ぱたぱたアニメーション

                  LET F(p+1,x)=y !先頭の番号を更新する

                  IF ly+oy*(y-1)>vy*2/3 THEN LET Invaded=1 !侵略したなら
               END IF
               LET CntOfEnemy=CntOfEnemy+1 !機体の数
            END IF
         NEXT y

         IF F(p+1,x)>0 THEN !この列に機体があれば
            IF FLG=0 THEN !折り返しを確認する
               IF xx<=0 OR xx+n>=vx THEN LET FLG=1 !左端、右端なら
            END IF

            IF RND<0.1 THEN !弾を発射する
               FOR y=1 TO NumOfBeam !未発射を探す
                  IF BM(y,3)<0 THEN
                     LET BM(y,1)=xx+INT(n/2)
                     LET BM(y,2)=ly+oy*(F(p+1,x)-1)+INT(m/2)
                     LET BM(y,3)=0 !使用中

                     EXIT FOR !1列に1つずつ
                  END IF
               NEXT y
            END IF
         END IF

      END IF
   NEXT x

   FOR y=1 TO NumOfBeam !弾を表示する
      LET ptn=BM(y,3)
      IF ptn>=0 THEN !使用中なら
         DRAW BLOCK(bm$(1,ptn+1),3,2) WITH SHIFT(V2W(BM(y,1)),V2W(BM(y,2)))
         LET BM(y,3)=MOD(ptn+1,2) !ぱたぱたアニメーション
      END IF
   NEXT y
   SET DRAW mode explicit !ちらつき防止終了


   !------------------------------ 移動処理(次のフレームへ)
   SELECT CASE FLG !インベーダーを移動させる
   CASE 0
      LET lx=lx+DX !横へ移動させる
   CASE 1
      LET ly=ly+2 !折り返しの動作(降下させる)
      LET FLG=2
   CASE ELSE
      LET DX=-DX !降下後、1つ離す
      LET lx=lx+DX
      LET FLG=0
   END SELECT

   FOR i=1 TO NumOfBeam !弾を移動させる
      IF BM(i,3)>=0 THEN !使用中なら
         LET BM(i,2)=BM(i,2)+3 !降下させる
         IF BM(i,2)>vy THEN LET BM(i,3)=-1 !下端なら
      END IF
   NEXT i

   !!!WAIT DELAY 0.3

LOOP UNTIL CntOfEnemy=0 OR Invaded=1 !機体全滅まで


END
 

Re: レトロ・ゲームのからくり

 投稿者:荒田浩二  投稿日:2009年11月27日(金)14時48分15秒
返信・引用
  > No.762[元記事へ]

懐かしいゲームです。「クリックしても弾が発射されない」と思いましたが、インベーダーを直接クリックするのですね。
編隊のすぐ右側をクリックすると「添字が範囲外」のエラーが生じることがあります。
当り判定のルーチンで xx=9 のとき IF F(yy,xx)>=2 THEN LET F(yy,xx)=1 がエラーとなるようです。
x=104 を回避すればよいので、IF x<0 OR x>ox*q OR y<0 OR y>oy*p THEN を
IF x<0 OR x>=ox*q OR y<0 OR y>oy*p THEN とするのはどうでしょうか。
 

Re: レトロ・ゲームのからくり

 投稿者:山中和義  投稿日:2009年11月27日(金)15時57分17秒
返信・引用
  > No.763[元記事へ]

荒田浩二さんへのお返事です。

> x=104 を回避すればよいので、IF x<0 OR x>ox*q OR y<0 OR y>oy*p THEN を
> IF x<0 OR x>=ox*q OR y<0 OR y>oy*p THEN とするのはどうでしょうか。

Xの値は[0,ox*q)ですね。
Yの値についても、同じことが言えると思いますので、
 IF x<0 OR x>=ox*q OR y<0 OR y>=oy*p THEN
としてください。
 

この映像を見てほしい。

 投稿者:GAI  投稿日:2009年11月28日(土)11時55分54秒
返信・引用
  なつかしいゲームがこんな仕組みで作られていたのかと思いました。
インターネットを見ていたら、下記のところの映像に驚きました。
こんなものがプログラムで組めないでしょうか?
一部の部分の構成でも作ってほしいです。

http://vimeo.com/5595869
 

レトロ・ゲームのからくり(ブロック崩し)

 投稿者:山中和義  投稿日:2009年11月28日(土)19時14分17秒
返信・引用  編集済
  > No.762[元記事へ]

!ブロック崩し

DEF V2W(x)=4*x !仮想画面の座標を物理画面の座標へ
DEF W2V(x)=INT(x/4) !その逆

PICTURE DOT !物理画面にドットを表示する
   PLOT AREA: -2,-2; 2,-2; 2,2; -2,2 !4x4
END PICTURE

LET vx=100 !仮想画面の大きさ 120×100ドット
LET vy=120

SET bitmap SIZE V2W(vx)+1,V2W(vy)+1 !物理画面の大きさ
SET WINDOW 0,V2W(vx),V2W(vy),0 !スクリーン座標

RANDOMIZE


!------------------------------ ブロック
LET lx=5 !左上の座標
LET ly=20

LET ox=10 !間隔
LET oy=6

LET p=5 !p×q個
LET q=INT(vx/ox)-2

DIM B(0 TO p-1,0 TO q-1) !1:有、0:無
MAT B=2*CON
DIM BC(2) !衝突回数の色(ルックアップテーブル)
DATA 4,10
MAT READ BC


!------------------------------ 壁
LET wx1=lx-1 !左上の座標
LET wy1=ly-15
LET wx2=wx1+ox*q !右下の座標
LET wy2=vy-5


!------------------------------ パッド
LET px=x !左上の座標
LET pw=5 !幅の半分


!------------------------------ ボール
LET dx=3 !移動方向
LET dy=5

LET x1=INT((wx2-wx1)/2) !発射位置
LET y1=ly+oy*p + 10

LET x=x1 !現在の位置
LET y=y1


LET k=0
LET NumOfBlock=p*q !ブロックの総数
LET NumOfPad=3 !パッドの残り数

DO !ゲームループ

!------------------------------ 当り判定
   IF (x<=wx1 AND x1<>wx1) THEN !左側の壁 ※2重衝突防止
   !!!IF x<=wx1 THEN !左側の壁
      LET k=0 !ボールの起点
      LET x1=wx1
      LET y1=y-INT((wx1-x)*dy/dx) !位置を補正 ※壁のすり抜け
      LET x=x1 !ボールの位置
      LET y=y1
      LET dx=-dx !ボールの反射
   END IF
   IF (x>=wx2 AND x1<>wx2) THEN !右側の壁
   !!!IF x>=wx2 THEN !右側の壁
      LET k=0
      LET x1=wx2
      LET y1=y-INT((x-wx2)*dy/dx)
      LET x=x1
      LET y=y1
      LET dx=-dx
   END IF

   LET xx=x-lx !ブロックの領域外なら
   LET yy=y-ly
   IF xx<0 OR xx>=ox*q OR yy<0 OR yy>=oy*p THEN

      IF (y<=wy1 AND y1<>wy1) THEN !上側の壁
      !!!IF y<=wy1 THEN !上側の壁
         LET k=0
         LET x1=x-INT((wy1-y)*dx/dy)
         LET y1=wy1
         LET x=x1
         LET y=y1
         LET dy=-dy
      END IF

      IF ABS(x-px)<=pw AND (y>=wy2 AND y1<>wy2) THEN !パッド
      !!!IF ABS(x-px)<=pw AND y>=wy2 THEN !パッド
         LET k=0
         LET x1=x-INT((y-wy2)*dx/dy)
         LET y1=wy2
         LET x=x1
         LET y=y1
         LET dy=-dy
      END IF
      IF y>=vy THEN !ミス!!!
         LET NumOfPad=NumOfPad-1
         LET x=x1 !ボールの位置
         LET y=y1
         LET px=x !パッドの位置
         WAIT DELAY 1
      END IF

   ELSE !領域内なら

   !※ブロックを厚くするとボールが内部に入った状態になって、何重にも衝突したことになる。
      LET xx=INT(xx/ox) !該当するブロックの位置を算出する
      LET yy=INT(yy/oy)
      IF B(yy,xx)>0 THEN !消滅させる
         LET B(yy,xx)=B(yy,xx)-1
         IF B(yy,xx)=0 THEN LET NumOfBlock=NumOfBlock-1

         LET k=0
         LET x1=x
         LET y1=y
         LET dy=-dy
      END IF

   END IF


   !------------------------------ 描画処理毎(フレームを表示する)
   SET DRAW mode hidden !ちらつき防止開始
   CLEAR

   SET AREA COLOR 1
   FOR xx=wx1 TO wx2 !上側の壁を表示する
      DRAW DOT WITH SHIFT(V2W(xx),V2W(wy1))
   NEXT xx
   FOR yy=wy1 TO wy2
      DRAW DOT WITH SHIFT(V2W(wx1),V2W(yy)) !左側、
      DRAW DOT WITH SHIFT(V2W(wx2),V2W(yy)) !右側
   NEXT yy

   FOR yy=0 TO p-1 !ブロック
      FOR xx=0 TO q-1
         LET c=B(yy,xx)
         IF c>0 THEN !存在するなら
            SET AREA COLOR BC(c) !ルックアップテーブルを参照する
            DRAW BLOCK(oy-1,ox-1) WITH SHIFT(V2W(lx+ox*xx),V2W(ly+oy*yy))
         END IF
      NEXT xx
   NEXT yy

   SET AREA COLOR 1
   DRAW BLOCK(2,2*pw) WITH SHIFT(V2W(px-pw),V2W(wy2)) !パッド ※中心の座標で

   SET AREA COLOR 2
   DRAW BLOCK(3,3) WITH SHIFT(V2W(x-1),V2W(y-1)) !ボール ※中心の座標で

   SET DRAW mode explicit !ちらつき防止終了


   !------------------------------ 移動処理(次のフレームへ)
   IF ABS(dy)<ABS(dx) THEN !xの方が増分が多い
   !□□□■
   !□■■□  y=l*x+m の式として考える
   !■□□□
      LET k=k+SGN(dx) !±1 移動量 ※低解像度だとカクカク動くように見える
      !!!LET k=k+SGN(dx)*3 !±3 移動量
      LET x=x1+k
      LET y=y1+INT(k*dy/dx)
   ELSE !yの方が増分が多い
   !□□■
   !□■□  x=l*y+m の式として考える
   !□■□
   !■□□
      LET k=k+SGN(dy) !±1 移動量
      !!!LET k=k+SGN(dy)*3 !±3 移動量
      LET x=x1+INT(k*dx/dy)
      LET y=y1+k
   END IF

   LET px=x !パッド位置はボールの真下


   !!!WAIT DELAY 0.2

LOOP UNTIL NumOfPad=0 OR NumOfBlock=0 !パッド、ブロックがなくなるまで


PICTURE BLOCK(m,n) !ブロックなどを位置(0,0)-(n,m)に表示する
   PLOT AREA: -2,-2; 4*n-2,-2; 4*n-2,4*m-2; -2,4*m-2
END PICTURE
!PICTURE BLOCK(m,n) !ブロックなどを位置(0,0)-(n,m)に表示する
!   FOR i=0 TO m-1 !m×nドット
!      FOR j=0 TO n-1
!         DRAW DOT WITH SHIFT(V2W(j),V2W(i))
!      NEXT j
!   NEXT i
!END PICTURE

END
 

Re: ハイウェイ

 投稿者:SECOND  投稿日:2009年11月30日(月)03時47分38秒
返信・引用  編集済
  > No.758[元記事へ]

!次の問題が解けなかったが、
!「見え隠れする路面の裏側を、別な色で塗る方法」が、見つかった。
!------------
! ハイウェイ
!------------
!SET bitmap SIZE 671,671 !← 大きい画面にするとき。(1024x768 にぴったり)
DIM Mp(4,4)         !視点からの被写体の相対座標(一点投影用)
DIM Xz(4,4),zY(4,4) !XY_Xz変換, XY_zY変換
DIM XYz(4,4)        !XY平面のz平行移動
!
!※投影面の裏側に、操作対象が有るので、座標は左手系(Z軸が裏向き)です。
! 投影面を、車両前縁d に置き、Z=1.5 、視点 Z=0 が 手前。
! 視点 Z=0 を頂点に、投影面 Z=1.5 へ 一点投影。面中心から±1を画面とし、
! 外界面を、投影面 前方+150 から、投影面 Z=1.5 までを、奥から描く。
!-------------------------------------------------------------------------
!      一点投影用 Mp
!
!原画_行ベクトル     Mp           表示_行ベクトル
!     (X,Y,Z,1)|1   0   0   0| →(X+x,Y+y, * ,Z+z) の4列目 Z+z で縮小。
!              |0   1   0   0|                               ↓
!              |0   0   0   1|      座標 (X+x)/(Z+z),(Y+y)/(Z+z) の描点群。
!              |x   y   0   z|      * 印は「最終的表示で無効」のz座標。
MAT READ Mp
DATA 1,0,0,0   !小文字 x y z は、視点から、道路左端の相対座標。
DATA 0,1,0,0
DATA 0,0,0,1   !変形指示 MAT 文で効果する。
DATA 0,0,0,0
!-------------------------------------------------------------------------
! 道路など、画面に垂直な広がりは、以下の Xz zY XYz 行列を、先に通します。
! 上の原画の Z は通常0ですが、以下の様に 変形を行なうと、発生します。
!-------------------------------------------------------------------------
!<路面>の原画用 Xz    XY平面→ XZ平面として描く。
!
!原画_行ベクト ル                   新しい原画_行ベクトル
!     (X,Y,0,1)|1    0    0   0| →(X+Y*dxdz, Y*dydz, Y, 1)
!              |dxdz dydz 1   0|
!              |0    0    0   0|    dxdz: Z軸カーブの微分 dx/dz
!              |0    0    0   1|    dydz: Z軸ピッチの微分 dy/dz
MAT READ Xz
DATA 1,0,0,0
DATA 0,0,1,0
DATA 0,0,0,0
DATA 0,0,0,1
!-------------------------------------------------------------------------
!<建物>の原画用 zY     XY平面→ ZY平面として描く。
!
!原画_行ベクト ル                   新しい原画_行ベクトル
!     (X,Y,0,1)|dxdz 0    1   0| →(X*dxdz+x, Y, X, 1)
!              |0    1    0   0|
!              |0    0    0   0|    dxdz: Z軸カーブの微分 dx/dz
!              |x    0    0   1|       x: ZY平面のx座標
MAT READ zY
DATA 0,0,1,0
DATA 0,1,0,0
DATA 0,0,0,0
DATA 0,0,0,1
!-------------------------------------------------------------------------
!<建物>の原画用 XYz     XY平面の Z軸移動。
!
!原画_行ベクト ル                       新しい原画_行ベクトル
!     (X,Y,0,1)|1        0    0   0| →(X+(dxdz)*z, Y, z, 1)
!              |0        1    0   0|
!              |0        0    0   0|    dxdz: Z軸カーブの微分 dx/dz
!              |(dxdz)*z 0    z   1|       z: Z軸 移動差分
MAT READ XYz
DATA 1,0,0,0
DATA 0,1,0,0
DATA 0,0,0,0
DATA 0,0,0,1
!-------------------------------------------------------------------------
!
DEF yaw(z)= 10*SIN((z-2)*0.1)     !カーブ、横の偏差  x(z)
DEF d_yaw(z)= COS((z-2)*0.1)      !カーブ、微分係数 dx/dz
DEF pitch(z)= 5*SIN(z*0.1)        !ピッチ、縦の偏差  y(z)
DEF d_pitch(z)= 0.5*COS(z*0.1)    !ピッチ、微分係数 dy/dz
!
DEF v(t)=v0+a*t                   !速度
DEF I_v(t)=v0*t+a*t*t/2           !移動距離 ∫v(t)dt
!
LET v0=15                         !初速度
LET a=-v0^2/2/100                 !減速加速度, -v0^2/2/移動距離
!
LET Zs=1.5                        ! 透視面のz座標( 視点 Z=0)
SET WINDOW -1,1,-1,1              !画面スケール±1
LET t0=TIME
DO
   LET t1=TIME-t0
   IF t1>tb+0.15 THEN
      LET tb=t1
      LET d=I_v(t)                !車両前縁d のz座標
      PRINT USING "時間=###.## 速度=###.##  走行距離=###.##":t,v(t),d
      SET DRAW mode hidden        !裏ページに書く
      CALL Animation              ! 描画
      SET DRAW mode explicit      !裏ページの表示
      LET t=t+.15
   END IF
   MOUSE POLL msx,msy,mlb,mrb
LOOP UNTIL v(t)<=0 OR mrb=1

SUB Animation
!----sky
   SET AREA COLOR 17
   PLOT AREA:-1,0; 1,0; 1,1; -1,1
   !----ground
   SET AREA COLOR 42
   PLOT AREA:-1,0; 1,0; 1,-1; -1,-1
   !----guide message
   SET TEXT COLOR 1
   SET TEXT FONT "",11
   PLOT TEXT,AT.35,.9:"右クリック保持 Stop"
   SET TEXT COLOR 0
   SET TEXT FONT "",90
   !----
   LET ss=5/2
   FOR i=IP((d+150)/ss)*ss TO d STEP -ss
      LET z=i-d+Zs !視点 Z=0 〜iのz座標。
      LET Mp(4,1)=  yaw(i)-yaw(d)  -1.5 !投影面中心線から道路左端のx座標
      LET Mp(4,2)=pitch(i)-pitch(d)-1.5 !投影面中心線から道路左端のy座標
      LET Mp(4,4)= z
      !----
      ! 1                 ,0                     ,0         ,0|
      ! 0                 ,1                     ,0         ,0|
      ! 0                 ,0                     ,0         ,1|
      ! yaw(i)-yaw(d)-1.5 ,pitch(i)-pitch(d)-1.5 ,0         ,z|
      !----
      IF MOD(i,10)=0 THEN
         DRAW Building( 0-2,-9, -3,20,-2  ) WITH Mp   !x,y, W,H,D
         DRAW Building( 6+2,-9, -3,19, 2.5) WITH Mp   !x,y, W,H,D
         DRAW Sign WITH Mp
      END IF
      IF MOD(i,10)=5 THEN DRAW Tree WITH Mp
      DRAW Road(-.993*ss) WITH Mp
   NEXT i
END SUB

!パーツのサイズ。
!画面( z=投影面Zs 1.5:車両前縁d )で、表示倍率 1/z ( 実幅3→ 描画幅2)
!原画座標で、道路左端xyz( 0 ,  0  ,1.5)= 画面左下角(-1,-1)
!原画座標で、左車線上xyz(1.5, 1.5 ,1.5)= 画面中心点( 0, 0) …投影中心

PICTURE Building(x,y,w,h,d1)
   IF Zs-z<=w THEN
   !---back plane
      LET zY(1,1)=d_yaw(i+w/2)     !Z軸カーブの微分 dx/dz
      LET zY(4,1)=x+d1             !ZY平面のx座標
      DRAW Wall((y),w,h) WITH zY
      !---facade
      LET zY(4,1)=x                !ZY平面のx座標
      DRAW Wall((y),w,h) WITH zY
      !---side plane
      LET XYz(4,1)=d_yaw(i+w/2)*w  !Z軸カーブによるx移動差分
      LET XYz(4,3)=w               !Z軸 移動差分
      DRAW Side(x,y,h,d1) WITH XYz
   END IF
END PICTURE
!
PICTURE Wall(y,w,h)
   SET AREA COLOR 8  !gray
   PLOT AREA: 0,y; w,y; w,y+h; 0,y+h       !(Z,Y)平面として描く。
   FOR y=y+h-.5 TO y+1 STEP -2.5
      PLOT LINES: 0,y; w,y                 !(Z,Y)平面として描く。
   NEXT y
END PICTURE
!
PICTURE Side(x,y,h,d1)
   SET AREA COLOR 16 !dark gray
   PLOT AREA: x,y; x+d1,y; x+d1,y+h; x,y+h !移動前(X,Y)平面として描く。
END PICTURE

PICTURE Road(e)
   IF e< Zs-z THEN LET e=Zs-z
   LET Xz(2,1)=d_yaw(i+e/2)     !Z軸カーブの微分 dx/dz
   LET Xz(2,2)=d_pitch(i+e/2)   !Z軸ピッチの微分 dy/dz
   DRAW Surface(e) WITH Xz
END PICTURE
!
PICTURE Surface(e)
   IF Mp(4,2)/z<=d_pitch(i+e/2) THEN
      SET AREA COLOR 15
      PLOT AREA: 0,0; 6,0; 6,e; 0,e           !(X,Z)平面として描く。
      !---center line
      SET AREA COLOR 0
      PLOT AREA: 2.9,0; 2.9,e; 3.1,e; 3.1,0   !(X,Z)平面として描く。
   ELSE
   !---back side
      SET AREA COLOR 2
      PLOT AREA: 0,0; 6,0; 6,e; 0,e           !(X,Z)平面として描く。
   END IF
   !---joint line
   PLOT LINES: 0  ,0; 2.9,0
   PLOT LINES: 3.1,0; 6  ,0
END PICTURE

PICTURE Tree
   SET AREA COLOR 12 !幹
   PLOT AREA:-0.075,0; 0.075,0; 0.025,3;-0.025,3
   SET AREA COLOR 10
   FOR w=1 TO 7      !葉
      DRAW disk WITH SCALE(0.3+0.05-RND*0.1)*SHIFT(0.4-RND*0.8, 2.7+0.325-RND*0.75)
   NEXT W
END PICTURE

PICTURE Sign
   IF MOD(i,50)=0 THEN SET AREA COLOR 2 ELSE SET AREA COLOR 4
   PLOT AREA:-0.025,0; 0.025,0; 0.025,2;-0.025,2 !pole
   DRAW disk WITH SCALE(0.5)*SHIFT(0,2)          !plate
   !PLOT TEXT,AT -.35,1.74,USING ">%%":STR$(i)    !sign
   CALL Plot_7segment(0 ,2 ,0.15 ,STR$(i))       !sign( PLOT TEXT が重い時)
END PICTURE

SUB Plot_7segment(x,y,s,i$) !文字列中心(x,y) 文字の横幅(s) 数字の文字列(i$)
   SET LINE COLOR 0
   SET LINE width 9/z       !一点投影・縮小の補償。(線幅は MAT 文で縮まない)
   LET w=LEN(i$)
   LET s1=s      ! y軸↑:s1=s  y軸↓:s1=-s
   LET s2=s/2
   LET x=x-(w-1)*s2*1.6
   FOR p=1 TO w
      SELECT CASE VAL(i$(p:p))
      CASE 0
         PLOT LINES:x-s2,y+s;x-s2,y-s;x+s2,y-s;x+s2,y+s;x-s2,y+s
      CASE 1
         PLOT LINES:x,y-s;x,y+s
      CASE 2
         PLOT LINES:x-s2,y+s1;x+s2,y+s1;x+s2,y;x-s2,y;x-s2,y-s1;x+s2,y-s1
      CASE 3
         PLOT LINES:x-s2,y-s;x+s2,y-s;x+s2,y+s;x-s2,y+s
         PLOT LINES:x-s2,y;x+s2,y
      CASE 4
         PLOT LINES:x-s2,y+s1;x-s2,y;x+s2,y
         PLOT LINES:x+s2,y+s1;x+s2,y-s1
      CASE 5
         PLOT LINES:x+s2,y+s1;x-s2,y+s1;x-s2,y;x+s2,y;x+s2,y-s1;x-s2,y-s1
      CASE 6
         PLOT LINES:x+s2,y+s1;x-s2,y+s1;x-s2,y-s1;x+s2,y-s1;x+s2,y;x-s2,y
      CASE 7
         PLOT LINES:x-s2,y+s1;x+s2,y+s1;x+s2,y-s1
      CASE 8
         PLOT LINES:x-s2,y;x-s2,y-s;x+s2,y-s;x+s2,y+s;x-s2,y+s;x-s2,y;x+s2,y
      CASE 9
         PLOT LINES:x+s2,y;x-s2,y;x-s2,y+s1;x+s2,y+s1;x+s2,y-s1;x-s2,y-s1
      CASE ELSE
      END SELECT
      LET x=x+s*1.6
   NEXT p
   SET LINE width 1
   SET LINE COLOR 1
END SUB

END
 

Ver. 7.4.0

 投稿者:白石 和夫  投稿日:2009年11月30日(月)15時24分4秒
返信・引用  編集済
  Ver. 7.4.0で,図形変形が有効なときにPLOT TEXT文を実行した場合には,字形自体を変形の対象に含めます。 JIS規格(=ANSI,ISO)ではテキストは問題座標で定義されることになっていますが,その通りにしてしまうと多くの場合に文字が読めなくなってし まうので,完全にJISに合致させることは保留としておきます。
なお,旧来のPLOT TEXT文の動作を新設のPLOT LETTERS文に引き継ぎます。
また,図形変形が表向き相似変換である場合には,従来どおりの描画とします。
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年12月 1日(火)09時42分32秒
返信・引用
  > No.756[元記事へ]

ピンポンの数理

問題 壁に何回かバウンドさせて、命中されるには?


元の図形を、縦と横に鏡面コピーして万華鏡をつくる。
ここでは第一象限で考える。ボールの発射位置と方向により、選択すればよい。
プログラムを実行して表示される各長方形の
中央の数字は、バウンド回数。 左下の数字は、テーブル番号。 目標(ターゲット)を黒点とする。

A点からボールを発射させる場合、たとえば3回のバウンドで命中させるには、
3、6、9、12番のテーブルでの、原点と黒点を結ぶ線分がその軌跡となる。
この線分と縦線や横線との交点の数が、バウンド回数となる。

実際のボールの動きは、9番の場合、折り紙のように9、8、4、0番の順に、
辺が重なったところを折り線として折り重ねていく。(山折り、谷折りどちらでもよい)
一片となったその線を透かして見ればよい。
SET bitmap SIZE 601,601
SET WINDOW -1,21,-1,21 !バウンドを検討する象限を選ぶ
DRAW grid

LET w=5 !テーブル(コート)の大きさ
LET h=4

FOR y=0 TO 5 !縦方向へ鏡面コピー
   FOR x=0 TO 4 !横方向
      LET cx=x*w+w/2
      LET cy=y*h+h/2
      DRAW rect WITH SCALE(1-2*MOD(x,2),1-2*MOD(y,2))*SHIFT(cx,cy) !倍率SCALE変換で鏡面コピーする

      PLOT TEXT ,AT cx,cy: STR$(ABS(x)+ABS(y)) !バウンドの回数(中央)

      PLOT TEXT ,AT x*w+1,y*h+1: STR$(y*(w-1)+x) !テーブル番号(左下)
      PLOT TEXT ,AT x*w+0.1,y*h+0.1: mid$("ABCD",MOD(x,2)+2*MOD(y,2)+1,1) !頂点
   NEXT x
NEXT y


LET ex=6 !目標の位置
LET ey=11
PLOT LINES: 0,0; ex,ey !上、下、右でバウンドする

!FOR i=1 TO 50-1
!   DRAW disk WITH SCALE(0.1)*SHIFT(i*ex/50,i*ey/50)
!NEXT i


PICTURE rect !原点で対称な長方形を描く
   PLOT LINES: -w/2,-h/2; w/2,-h/2; w/2,h/2; -w/2,h/2; -w/2,-h/2
   DRAW disk WITH SCALE(0.1)*SHIFT(w/2-1,h/2-1) !目標
END PICTURE

END

バウンド回数の偶数は、折り紙を折り畳んだときの表のままの部分。奇数は、裏返る部分となる。
 

曲線(パス)上に文字を表示する

 投稿者:山中和義  投稿日:2009年12月 6日(日)20時58分45秒
返信・引用  編集済
  ●陽関数表示
!曲線上に文字を表示する

SET WINDOW -5,5,-5,5
DRAW grid

SET TEXT HEIGHT 0.5
SET TEXT JUSTIFY "CENTER","BOTTOM"
DRAW TextOnPath("Abcあい漢",1.5) WITH SHIFT(-2,-1)

END


EXTERNAL FUNCTION f(x) !曲線 y=f(x) ※陽関数表示
!LET f=ABS(x-3)
!LET f=x^3
LET f=SIN(x)
END FUNCTION


EXTERNAL PICTURE TextOnPath(s$,L) !曲線上に文字を表示する
IF LEN(s$)=0 OR L<=0 THEN EXIT PICTURE

LET k=1 !k文字目

LET S=0 !曲線y=f(x)の区間[a,b]の長さ S=∫[a,b]SQR(1+f'(x)^2)dx
LET H=0.05
LET i=0
DO
   LET t=H*i !リーマン和、区分求積

   LET Ft=f(t)
   LET df=(f(t+H)-Ft)/H !導関数 f'(x) ※微分係数による
   LET S=S+H*SQR(1+df*df)

   IF S>=(k-1)*L THEN !文字間隔ごとに
      DRAW disk WITH SCALE(0.05)*SHIFT(t,Ft) !位置を印す
      SET TEXT ANGLE ANGLE(1,df) !角度を調整する
      PLOT TEXT ,AT t,Ft: s$(k:k) !k文字目

      LET k=k+1 !次の文字へ
      IF k>LEN(s$) THEN EXIT PICTURE !すべての文字を表示したなら
   ELSE
      PLOT LINES: t,Ft; !曲線の軌跡
   END IF

   LET i=i+1
LOOP
END PICTURE


●媒介変数表示
!曲線上に文字を表示する

SET WINDOW -5,5,-5,5
DRAW grid

SET TEXT HEIGHT 0.5
SET TEXT JUSTIFY "CENTER","BOTTOM"
DRAW TextOnPath("Abcあい漢",1.5) WITH SHIFT(-2,-1)

END


EXTERNAL FUNCTION x(t) !曲線 x=f(t)、y=f(t) ※媒介変数表示
!!!LET x=t !y=sin(x)
LET x=3*COS(t) !半径3の円
END FUNCTION
EXTERNAL FUNCTION y(t)
!!!LET y=SIN(t) !y=sin(x)
LET y=3*SIN(t) !半径3の円
END FUNCTION


EXTERNAL PICTURE TextOnPath(s$,L) !曲線上に文字を表示する
IF LEN(s$)=0 OR L<=0 THEN EXIT PICTURE

LET k=1 !k文字目

LET S=0 !曲線x=f(t),y=g(t)の区間[a,b]の長さ S=∫[a,b]SQR((dx/dt)^2+(dy/dt)^2)dx
LET H=0.05
LET i=0
DO
   LET t=H*i !リーマン和、区分求積

   LET Xt=x(t)
   LET Yt=y(t)
   LET dx=(x(t+H)-Xt)/H !導関数 dx/dt、dy/dt ※微分係数による
   LET dy=(y(t+H)-Yt)/H
   LET w=dx*dx+dy*dy
   LET S=S+H*SQR(w)

   IF S>=(k-1)*L THEN !文字間隔ごとに
      DRAW disk WITH SCALE(0.05)*SHIFT(Xt,Yt) !位置を印す
      IF w<>0 THEN !角度を調整する
         SET TEXT ANGLE ANGLE(dx,dy)
      ELSE
         SET TEXT ANGLE 0
      END IF
      PLOT TEXT ,AT Xt,Yt: s$(k:k) !k文字目

      LET k=k+1 !次の文字へ
      IF k>LEN(s$) THEN EXIT PICTURE !すべての文字を表示したなら
   ELSE
      PLOT LINES: Xt,Yt; !曲線の軌跡
   END IF

   LET i=i+1
LOOP
END PICTURE


●極座標表示
!曲線上に文字を表示する

SET WINDOW -5,5,-5,5
DRAW grid

SET TEXT HEIGHT 0.5
SET TEXT JUSTIFY "CENTER","BOTTOM"
DRAW TextOnPath("Abcあい漢",3.5) WITH SHIFT(-2,-1)

END


EXTERNAL FUNCTION r(t) !曲線 r=f(θ) ※極座標表示
LET r=3*(1+COS(t))
END FUNCTION


EXTERNAL PICTURE TextOnPath(s$,L) !曲線上に文字を表示する
IF LEN(s$)=0 OR L<=0 THEN EXIT PICTURE

LET k=1 !k文字目

LET S=0 !曲線r=f(θ)の区間[a,b]の長さ S=∫[a,b]SQR(r(θ)^2+r'(θ)^2)dx
LET H=0.05
LET i=0
DO
   LET t=H*i !リーマン和、区分求積

   LET Rt=r(t)
   LET dr=(r(t+H)-Rt)/H !導関数 r'(θ) ※微分係数による
   LET w=Rt*Rt+dr*dr
   LET S=S+H*SQR(w)

   LET x=Rt*COS(t) !極座標(r,θ)→直交座標(x,y)
   LET y=Rt*SIN(t)

   IF S>=(k-1)*L THEN !文字間隔ごとに
      DRAW disk WITH SCALE(0.05)*SHIFT(x,y) !位置を印す
      IF w<>0 THEN !角度を調整する
         SET TEXT ANGLE ANGLE(dr,Rt)+t
         !SET TEXT ANGLE ANGLE(dr-Rt*TAN(t),Rt+dr*TAN(t))
      ELSE
         SET TEXT ANGLE 0
      END IF
      PLOT TEXT ,AT x,y: s$(k:k) !k文字目

      LET k=k+1 !次の文字へ
      IF k>LEN(s$) THEN EXIT PICTURE !すべての文字を表示したなら
   ELSE
      PLOT LINES: x,y; !曲線の軌跡
   END IF

   LET i=i+1
LOOP
END PICTURE
 

Re: Ver. 7.4.0

 投稿者:SECOND  投稿日:2009年12月 7日(月)03時35分32秒
返信・引用  編集済
  > No.769[元記事へ]

!以下の2例で、文字の大きさが 1.5倍、実行速度が200倍ほど違いますが、
!私の環境(Win98SE)だけでしょうか?  (Ver.7.4.0 の PLOT TEXT)
!
SET TEXT font "",14
SET TEXT background "OPAQUE"
SET WINDOW -1,1,-1,1
DIM m(4,4)
!
MAT m=IDN
!
LET t0=TIME
FOR i=1 TO 5000
   DRAW new_text WITH m
NEXT i
PRINT USING"###.###sec":TIME-t0
!
LET m(1,1)=-1
!
LET t0=TIME
FOR i=1 TO 5000
   DRAW new_text WITH m
NEXT i
PRINT USING"###.###sec":TIME-t0

PICTURE new_text
   PLOT TEXT,AT 0,0,USING"#####":STR$(i)
END PICTURE

END
 

Re: Ver. 7.4.0

 投稿者:白石 和夫  投稿日:2009年12月 7日(月)08時45分55秒
返信・引用
  > No.772[元記事へ]

SECONDさんへのお返事です。

> !以下の2例で、文字の大きさが 1.5倍、実行速度が200倍ほど違いますが、
> !私の環境(Win98SE)だけでしょうか?  (Ver.7.4.0 の PLOT TEXT)

実行速度は遅くなります。
Windows APIは文字の射影変換に対応しないので,
別に確保したビットマップに描かせた文字を逆写像を利用して
描画領域に戻しています。
Windows版は比較的速いほうで,Linux,Macだとさらに遅くなります。
(Mac版,Linux版は現在,進行中)

文字の大きさは,今後の調整で差が目立たないように修正します。
 

Re: Ver. 7.4.0

 投稿者:SECOND  投稿日:2009年12月 7日(月)15時26分48秒
返信・引用
  > No.773[元記事へ]

白石 先生へ
プログラムの互換性から、LETTERS と TEXT の機能を入換えて頂くと助かりますが・・
 

Re: Ver. 7.4.0

 投稿者:白石 和夫  投稿日:2009年12月 7日(月)16時24分30秒
返信・引用
  > No.774[元記事へ]

SECONDさんへのお返事です。

> プログラムの互換性から、LETTERS と TEXT の機能を入換えて頂くと助かりますが・・

PLOT TEXTの動作を規格に合わせるのが意図なので,それは無理です。
 

改行の仕方

 投稿者:H.T  投稿日:2009年12月 8日(火)09時58分18秒
返信・引用
  十進BASICでプログラムをくんでいます。IF   A=B  AND   C=D  AND.......THEN
という構文を使わなくてはいけない場面がでてきたのですがC=D  の後にANDが100個ほど
続くのですがここの所を複数行に分けて記述するにはどうしたらよいのでしょうか。
入門的なことですみませんが、教えてください。
 

Re: 改行の仕方

 投稿者:山中和義  投稿日:2009年12月 8日(火)10時53分46秒
返信・引用
  > No.776[元記事へ]

H.Tさんへのお返事です。

!「ヘルプ」-「目次」-「基本」-「行継続」より

! 行末と行頭に&をつける

IF A=B AND &
&  C=D AND &
&  E=F THEN
   PRINT "OK"
END IF

END
 

再帰関数の不具合

 投稿者:山中和義  投稿日:2009年12月 8日(火)11時04分8秒
返信・引用  編集済
  (外部、内部)再帰関数を定義した場合、以前の値がクリアされず今回に反映される。
LET t=fnV("1234",10)
PRINT t
LET t=fnV("567",10)
PRINT t

LET s$=fnS$(11,2)
PRINT s$
LET s$=fnS$(14,2)
PRINT s$

END

EXTERNAL FUNCTION fnV(s$,p)
LET L=LEN(s$)
IF L=0 THEN EXIT FUNCTION
LET fnV=fnV(s$(1:L-1),p)*p + VAL(s$(L:L))
END FUNCTION

EXTERNAL FUNCTION fnS$(n,p)
IF n=0 THEN EXIT FUNCTION
LET fnS$=fnS$(INT(n/p),p) & STR$(MOD(n,p))
END FUNCTION

実行結果
 1234
 1234567
1011
10111110
 

Re: 再帰関数の不具合

 投稿者:白石 和夫  投稿日:2009年12月 8日(火)16時52分24秒
返信・引用
  > No.778[元記事へ]

もっと単純な例です。
10 DECLARE EXTERNAL FUNCTION f
20 PRINT f(0)
30 PRINT f(1)
40 PRINT f(0)
50 END
60 EXTERNAL  FUNCTION f(x)
70 IF x=0 THEN EXIT FUNCTION
80 LET f=1
90 END FUNCTION
十進BASICを作り始めたころ(たぶん現在配布しているWindows95版まで)は関数定義の戻り値をスタック上に確保していましたが,それでは規格に合わないので,現在のバージョンは静的な変数を用いています。
規格では,「定義関数名に最後に代入された値」となっています。また,定義関数名は文法上,変数ではありません(だから局所変数でもない)。したがって,今回の呼び出しで値を設定しないと,前回設定した値を返すことになります。
 

Re: 再帰関数の不具合

 投稿者:白石 和夫  投稿日:2009年12月 8日(火)18時26分27秒
返信・引用
  > No.779[元記事へ]

最後に定義関数名に代入された値を関数値とするため,
10 DECLARE EXTERNAL FUNCTION f
20 PRINT f(2)
30 END
40 EXTERNAL FUNCTION f(x)
50 LET f=x
60 IF x=2 THEN LET y=f(x-1)
70 END FUNCTION
の実行結果は2でなく1になります。

これは,たとえば,再帰処理を行うとき,デフォルト値を定義関数名に与えておいて,再帰がうまくいかないときは定義関数名への代入をせずに関数から抜けるとその値が返ると想定すると,予期しない結果が得られることになります。
 

Re: 再帰関数の不具合

 投稿者:山中和義  投稿日:2009年12月 8日(火)20時11分24秒
返信・引用
  > No.780[元記事へ]

了解しました。 、、、と言う事は、BASICAccが(FullBASIC準拠なら)不具合となります。
 

Re: 再帰関数の不具合

 投稿者:白石 和夫  投稿日:2009年12月 8日(火)21時01分22秒
返信・引用  編集済
  > No.781[元記事へ]

BASICAccは,定義関数名への代入をDelphi語のresult変数への代入に変換しているので,厳密にはFull BASIC規格とは異なる動作をすることになります。
 

Re: 再帰関数の不具合

 投稿者:白石 和夫  投稿日:2009年12月 9日(水)17時39分53秒
返信・引用  編集済
  > No.782[元記事へ]

「最後に代入された値」にこだわる規格の意図が読めません。
定義関数名への代入の形で関数の結果を返す言語で関数の結果を広域的に保持することを要求するのは不可解な仕様で,「各回の呼び出しにおいて」という限定 を書き損ねた,規格のバグである可能性も考えられるので,JIS合致にするためのオプションを新設し,通常の動作は関数の結果を局所変数に保持するように 変更します。
 

Re: 再帰関数の不具合

 投稿者:SECOND  投稿日:2009年12月 9日(水)23時13分10秒
返信・引用  編集済
  > No.778[元記事へ]

!釈迦に説法で恐縮ですが、戻り値は、漏らさずセットが原則だと思います、すみません。

LET t=fnV("1234",10)
PRINT t
LET t=fnV("567",10)
PRINT t

LET s$=fnS$(11,2)
PRINT s$
LET s$=fnS$(14,2)
PRINT s$

END

EXTERNAL FUNCTION fnV(s$,p)
LET L=LEN(s$)
IF 0< L THEN LET fnV=fnV(s$(1:L-1),p)*p + VAL(s$(L:L)) ELSE LET fnV=0
END FUNCTION

EXTERNAL FUNCTION fnS$(n,p)
IF 0< n THEN LET fnS$=fnS$(INT(n/p),p) & STR$(MOD(n,p)) ELSE LET fnS$=""
END FUNCTION

!  1234
!  567
! 1011
! 1110
 

7.4.1版の不具合

 投稿者:山中和義  投稿日:2009年12月11日(金)18時49分30秒
返信・引用  編集済
  修正ありがとうございます。

射影変換のPLOT TEXT文で、「添字が範囲外」エラーとなります。7.4.0版では描画できていました。
! 射影変換 sample\transfo9.bas追加
DIM T(4,4)
MAT READ T
DATA 1,  0,  0, -0.25
DATA 0,  1,  0,  0.2
DATA 0,  0,  1,  0
DATA 0,  0,  0,  1
PICTURE House
   SET AREA COLOR 15
   PLOT AREA:    0, 1;   0,  0;   2,  0;   2,  1         ! 壁
   SET AREA COLOR 2
   PLOT AREA:  -0.6,1;  2.6, 1;   2,  2;   0,  2         ! 屋根
   SET AREA COLOR 10
   PLOT AREA:  0.1, 0; 0.1,0.8; 0.5,0.8; 0.5,  0         ! ドア
   SET AREA COLOR 5
   PLOT AREA: 1.4,0.4; 1.9,0.4; 1.9,0.8; 1.4,0.8         ! 窓
   SET AREA COLOR 12
   PLOT AREA:  1.7, 2; 1.7,2.3; 1.5,2.3; 1.5,  2         ! 煙突

   SET TEXT HEIGHT 2 !<----- 大きくするとNG
   PLOT TEXT ,AT 0,0: "屋根"

END PICTURE
SET WINDOW -5,5,-5,5
DRAW axes
DRAW House WITH T
END


「常に物理座標」では、これを有効にした表示は正しいのでしょうか?
SET WINDOW -5,5,-5,5
DRAW grid

!2つの消失点
DATA  4,1 !水平線(X軸に平行)の消失点(x1,y1)
DATA -3,4 !垂直線(Y軸に平行)の消失点(x2,y2)
READ x1,y1, x2,y2
DRAW vp WITH SHIFT(x1,y1)
DRAW vp WITH SHIFT(x2,y2)

PICTURE vp !マーカーを描く
   LET a=0.125
   PLOT AREA: -a,-a; a,-a; a,a; -a,a
END PICTURE


DIM M(4,4) !消失点になるように台形変形する
MAT M=IDN
LET M(1,4)=1/(x1-x2) !消失点(x,0)なら、1/x。 x→∞なら、0
LET M(2,4)=1/(y2-y1) !消失点(0,y)なら、1/y。 y→∞なら、0

DIM Mp(4,4)
MAT Mp=SHIFT(-x2,-y1)*M*SHIFT(x2,y1)


DRAW t WITH Mp

PICTURE t !変形された図形を描く
   PLOT LINES: -1,-1; 1,-1; 1,1; -1,1; -1,-1 !境界線を描く
   PLOT LINES: -1,0; 1,0 !軸
   PLOT LINES: 0,-1; 0,1

   SET TEXT HEIGHT 1 !正規座標内の図形 ←←←← ここ
   !※「問題座標(JIS)」では、既定値が0.01のため SET TEXT HEIGHT はほぼ必須となる。
   PLOT TEXT ,AT  0, 0: "F"
   PLOT TEXT ,AT -1, 0: "2"
   PLOT TEXT ,AT -1,-1: "@"
   PLOT TEXT ,AT  0,-1: "M"
END PICTURE

END
 

掲示板過去ログへのリンク許可願い

 投稿者:荒田浩二  投稿日:2009年12月11日(金)18時52分35秒
返信・引用
  白石先生にお願いです。

先日"「十進BASIC第2掲示板」投稿記事リスト"というスレッドを作成しましたが、事前に管理者である白石先生の許可を得るべきでした。ご容赦ください。
新たに、白石先生の個人サイト「数学教育を考える」にある「十進BASIC掲示板過去ログ」のインデックスの一覧を例のようにまとめましたので、スレッドへの掲載許可をお願いいたします。
過去ログには4000件もの記事が保存されていますが、あまり活用されていないのではないでしょうか。第2掲示板に一覧のリンクを置くことにより、多くの方に記事を閲覧する機会を与えられると思います。
また、スレッドのトップには2005年3月11日に公開された『掲示板利用規定(暫定版)』を掲載したいのであわせて許可をお願いいたします。

あらためて許可は出せないが黙認はするということであれば、特に回答をいただかなくとも一週間ほど待ったのち作業に入りたいと思います。
よろしくお願いいたします。

例)
Page : 12 (このインデックスはコピーです) → 元のインデックス
  ダイレクトモードの説明について  浅野幸紀  2002/08/20
  └十進BASICにはダイレクトモードは存在しませ...  白石和夫  2002/08/20
   └そうなんですか。たいへん参考になりました...  浅野幸紀  2002/08/21
  浮動小数点の取り扱い  ぽんた  2002/08/17
  ├(仮称)十進BASICを十進モードで使う限り,有...  白石和夫  2002/08/20
  └お金を扱うのが目的であるのならば,固定小...  白石和夫  2002/08/23
  プリンタ・グラフィックス  白石和夫  2002/08/14
  はじめまして  ゆうきの父  2002/07/17
  └意図のとおりに動作するようであれば,特に...  白石和夫  2002/07/18
 

Re: 7.4.1版の不具合

 投稿者:白石 和夫  投稿日:2009年12月12日(土)09時29分17秒
返信・引用
  > No.785[元記事へ]

> 射影変換のPLOT TEXT文で、「添字が範囲外」エラーとなります。7.4.0版では描画できていました。
ご報告ありがとうございました。
修正します(若干の速度向上の試みの失敗です)。


「常に物理座標」にするとバージョン7.3以前と同じ描画になります。
基点付近の情報に基づいて描きます。
 

Re: 掲示板過去ログへのリンク許可願い

 投稿者:白石 和夫  投稿日:2009年12月12日(土)09時32分9秒
返信・引用  編集済
  > No.786[元記事へ]

特に問題はないと思います。
ただし,投稿規程(暫定版)は記述が古くなっているので転載しないでください。
(現在,GPL版の十進BASICもあります)

ついでに,目的別(カテゴリーごと)のインデックスも作っていただけると助かります。
 

テトロミノ

 投稿者:永野護  投稿日:2009年12月12日(土)10時25分14秒
返信・引用
  随分以前の本ですが昭晃堂より出版された、「はじめて学ぶBASIC」(木下氏、玉井氏共著)
という本があります。この本の135ページにテトロミノの問題があり、143ページで箱の形を
4×5の長方形にするにはプログラムをどう変えればよいか、という問題があります。
これができなくて悩んでいます。十進BASICと直接は関係ないのですが、よろしければ
プログラムをどう変更すればよいか教えてください。何卒よろしくお願いします。
 

Re: テトロミノ

 投稿者:山中和義  投稿日:2009年12月12日(土)20時24分30秒
返信・引用
  > No.789[元記事へ]

永野護さんへのお返事です。

> 随分以前の本ですが昭晃堂より出版された、「はじめて学ぶBASIC」(木下氏、玉井氏共著)
> という本があります。

この本を持っている人はたぶんいないと思います。
(元または自分が修正中の)プログラムを掲載するなどしないと回答はないと思います。
 

Re: 掲示板過去ログへのリンク許可願い

 投稿者:荒田浩二  投稿日:2009年12月12日(土)21時51分3秒
返信・引用
  > No.788[元記事へ]

回答ありがとうございます。さっそくとりかかります。


> ついでに,目的別(カテゴリーごと)のインデックスも作っていただけると助かります。

あれば便利なので作りたいのですが、私個人の能力では十分なレベルのものはできません。白石先生や他の方の協力をいただければ可能だと思います。
まずはカテゴリーの設定をする必要があります。
各カテゴリーの名称を提示していただけないでしょうか。お願いします。
 

Re: 掲示板過去ログへのリンク許可願い

 投稿者:白石 和夫  投稿日:2009年12月13日(日)07時41分54秒
返信・引用  編集済
  > No.791[元記事へ]

> まずはカテゴリーの設定をする必要があります。
> 各カテゴリーの名称を提示していただけないでしょうか。お願いします。
目的の記事を探しやすいように分類ができればいいと思います。
すべての記事を網羅する必要はないと思いますし,
逆に複数のカテゴリーに属する記事が出てきてもかまわないのではないでしょうか。
 

テトロミノの箱詰めパズル

 投稿者:山中和義  投稿日:2009年12月14日(月)10時56分39秒
返信・引用
  「C言語による最新アルゴリズム事典」より tetromin.c -- テトロミノの箱詰めパズル
LET Pieces=5 !駒の数
LET Col=5 !盤の短辺の長さ ※5は固定
LET Row=8 !盤の長辺の長さ
LET PieceSize=4 !駒の大きさ
LET MaxSymmetry=8 !駒の置き方の最大数
LET MaxSite=(Col+1)*Row-1
LET LimSite=(Col+1)*(Row+1)

DIM board$(0 TO LimSite-1)
DIM NAME$(0 TO 2-1, 0 TO Pieces-1)
DIM symmetry(0 TO Pieces-1)
DIM shape(0 TO Pieces-1, 0 TO MaxSymmetry-1, 0 TO (PieceSize-1)-1)
DIM REST(0 TO Pieces-1)

LET count=0 !解答数
CALL initialize
CALL try(0)

SUB initialize
   local site, piece, state

   FOR site=0 TO MaxSite-1 !盤をつくる
      IF MOD(site,Col+1)=Col THEN LET board$(site)="*" ELSE LET board$(site)=""
   NEXT site
   FOR site=MaxSite TO (LimSite-1)-1
      LET board$(site)="*"
   NEXT site
   LET board$(LimSite-1)="" !番人
   ! ┌─┐Col+1
   !      * ┐
   !      * │
   !      * │
   !      * │
   !      * │Row+1
   !      * │
   !      * │
   !      * │← MaxSite-1
   ! *****  ┘
   !      ↑ LimSite-1

   FOR piece=0 TO Pieces-1 !駒を読み込む
      LET REST(piece)=2 !2枚ずつ
      READ NAME$(1,piece),NAME$(0,piece), symmetry(piece) !名称、個数
      FOR state=0 TO symmetry(piece)-1
         FOR site=0 TO (PieceSize-1)-1
            READ shape(piece,state,site) !形状
         NEXT site
      NEXT state
   NEXT piece
END SUB

SUB found !解の表示
!!!local i,j
   LET count=count+1
   PRINT "解";count
   FOR i=0 TO Col-1
      FOR j=i TO MaxSite-1 STEP Col+1
         PRINT board$(j);
      NEXT j
      PRINT
   NEXT i
END SUB

SUB try(site) !再帰的に試みる
   local piece,state,s0,s1,s2

   LET piece=0
   DO WHILE piece<Pieces !未使用の駒に対して
      IF REST(piece)=0 THEN
      ELSE

         LET REST(piece)=REST(piece)-1 !この駒を使用する

         LET state=0
         DO WHILE state<symmetry(piece) !すべての向きに置いてみる
            LET s0=site+shape(piece,state,0)

            IF board$(s0)<>"" THEN !ここに四角1が置ければ
            ELSE
               LET s1=site+shape(piece,state,1)

               IF board$(s1)<>"" THEN !四角2
               ELSE
                  LET s2=site+shape(piece,state,2)

                  IF board$(s2)<>"" THEN !四角3
                  ELSE
                     LET board$(site),board$(s0),board$(s1),board$(s2)=NAME$(REST(piece),piece)

                     LET temp=site !次の空き位置を探す
                     DO
                        LET temp=temp+1
                     LOOP WHILE board$(temp)<>""
                     IF temp<MaxSite THEN CALL try((temp)) ELSE CALL found

                     LET board$(site),board$(s0),board$(s1),board$(s2)=""

                  END IF !continue
               END IF
            END IF

            LET state=state+1
         LOOP

         LET REST(piece)=REST(piece)+1 !未使用

      END IF !continue

      LET piece=piece+1
   LOOP
END SUB


! tetromin.dat -- テトロミノの駒の形のデータ

!配列borad$()の要素番号と盤上配置との関係
!    site
!     ↓
!      * 1 2 3
!  4 5 6 7 8 9
! 101112131415
! 161718192021
! └ Col+1 ┘ ※Col=5

DATA "O","o", 1 !名称、個数
DATA 1,6,7 !形状 s0,s1,s2

DATA "I","i", 2
DATA 1,2,3
DATA 6,12,18

DATA "T","t", 4
DATA 1,2,7
DATA 5,6,7
DATA 5,6,12
DATA 6,7,12

DATA "Z","z", 4
DATA 1,5,6
DATA 1,7,8
DATA 5,6,11 !裏
DATA 6,7,13

DATA "L","l", 8
DATA 1,2,6
DATA 1,2,8
DATA 1,6,12
DATA 1,7,13
DATA 4,5,6 !裏
DATA 6,7,8
DATA 6,11,12
DATA 6,12,13


END


!投稿(記述例)、情報、アルゴリズム、パズル、移植
 

Re: 掲示板過去ログへのリンク許可願い

 投稿者:山中和義  投稿日:2009年12月14日(月)11時42分3秒
返信・引用  編集済
  > No.791[元記事へ]

荒田浩二さんへのお返事です。

> まずはカテゴリーの設定をする必要があります。
> 各カテゴリーの名称を提示していただけないでしょうか。お願いします。
●記事の種別
質問
 回答
投稿(記述例)
 初版、改訂版、新版
仕様・不具合


●Tips(小技、コツ)
トラブルシュート
技術メモ


●学習分野(学校、図書など)
数学
 おもしろ数学
 高校数学
  〜の公式
  関数とグラフ、図形と方程式
  集合と命題と論理演算
  順列、組合せ、確率
  数値計算とコンピュータ
   センター試験
  統計とコンピュータ
  −
 整数論
情報
 アルゴリズム
  整列(ソート)
  探索(サーチ)
  数理
  グラフ
  パズル
 情報、工業基礎
  n進法
  チューリングマシン
  ビット演算
  置換
 言語処理
  数式処理
工業
 電気・電子
  電気回路
   4端子回路
   フィルタ回路
   合成抵抗
   −
  電磁気
  論理回路
   演算回路
   電子工作
   −
 計測・制御
  ラダーロジック
  制御理論
 測量
商業


●実例
ユーティリティー、ライブラリ、ツール
 OLE、Win32API
 −
教材
グラフィックス
 画像処理
 −
数値計算
 行列
  固有値と固有ベクトル
  −
 微分
 積分
 連立1次方程式
 非線形方程式
 特殊関数
 多桁(多倍長)
 −
シミュレーション
 ゲーム
 

Win版7.4.2インストールファイル

 投稿者:島村1243  投稿日:2009年12月14日(月)12時04分18秒
返信・引用
  昨14日にBASIC-7.4.2のsetup.exeをダウンロードしてインストールしました。
BASICウィンドウのメニュー「ヘルプ」でバージョン情報を見ましたら「7.4.1」になっていました。
ヘルプ内容の変更漏れで、実際の内容は7.4.2なのでしょうか。
 

Re: Win版7.4.2インストールファイル

 投稿者:白石 和夫  投稿日:2009年12月14日(月)15時40分29秒
返信・引用  編集済
  > No.827[元記事へ]

> 昨14日にBASIC-7.4.2のsetup.exeをダウンロードしてインストールしました。
> BASICウィンドウのメニュー「ヘルプ」でバージョン情報を見ましたら「7.4.1」になっていました。
> ヘルプ内容の変更漏れで、実際の内容は7.4.2なのでしょうか。

申し訳ありません。
HELPの修正忘れです。
12月12日9時39分の日付があれば修正済みの版です。
 

テトロミノ

 投稿者:永野護  投稿日:2009年12月14日(月)15時46分31秒
返信・引用
  山中さん、丁寧な回答ありがとうございました。
感謝します。テトロミノには解がないことを知りませんでした。
ペントミノの場合はできました。
 

Re: 掲示板過去ログへのリンク許可願い

 投稿者:荒田浩二  投稿日:2009年12月14日(月)17時08分1秒
返信・引用
  > No.826[元記事へ]

山中和義さんへのお返事です。

例を提示していただきありがとうございます。
私が考えた分類は次のようなものです。
他の方も、何か良い案があればお寄せください。お願いします。

数値計算[サブカテゴリー]
    [関数]
    [微積分]
    [複素数]
    [π/三角関数]
    [方程式/多項式]
    [素数]
    [順列組合せ]
    [グラフ]
    [その他]
物理計算(波動/回路等)
データ処理(ソート/サーチ/文字列等)
グラフィック(アニメ/3D)
シミュレーション/フラクタル
ゲーム/パズル/マジック
ユーティリティ(GUI/ファイル/画像/音声/通信等)
OS別(Linux/Mac)
十進BASICについて
Q&A/掲示板について/その他
 

ご苦労さまです

 投稿者:SECOND  投稿日:2009年12月14日(月)18時23分25秒
返信・引用
  荒田さんへ
ほんとうにご苦労さまです。私を含む古株の面々も本来は、手伝わないといけない所、
それを、しない、後ろめたさもあり、意見はどうかと思いましたが、
率直な期待を言ってみますと・・思い切り、独断と偏見でやられたらいかがでしょう。
大変な御仕事、感謝いたします。 2009.12.14 諏訪 雄治
 

旧掲示板過去ログのトピックをスレッドにしました

 投稿者:荒田浩二  投稿日:2009年12月14日(月)19時58分27秒
返信・引用
  旧掲示板の過去ログインデックスからトピックタイトルのみを抜き出して一覧にしたスレッドを作成しました。
「十進BASIC掲示板過去ログ」インデックス(トピック)
ツリー形式の枝部分のレスをカットしたので一覧性が高くなり視認による検索がしやすいと思います。ご活用ください。


SECONDさんへのお返事です。
ありがとうございます。そう言っていただけるとやる気もおきます。
できるだけ良いものを作りたいので、できればSECONDさんにも手伝っていただけないでしょうか。
現在、作業計画を構想していますが、カテゴーリーが決定次第「一次分類」としてまず投稿者本人に分類をお願いしようかと考えています。これほど確実な分類はないでしょう。
残った記事を「二次分類」としてカテゴリーごとに協力者を募り分類作業をお願いします。
私が知識を持たない分野も多いので、ここでSECONDさんや投稿常連の方に手を挙げていただけるととても助かります。
最後に残った記事を私が分類し、リンクを付けてアップします。
以上のような構想です。
ぜひ、ご協力をお願いします。
 

PLOT TEXT

 投稿者:SECOND  投稿日:2009年12月14日(月)21時35分26秒
返信・引用
  ! PLOT TEXT 文字の、鏡像テスト。
!
!-------------------
LET N=1  !0,1,2, 通常の万華鏡は2にする。
LET NN=2^N
SET TEXT JUSTIFY "center","half"
SET TEXT BACKGROUND "OPAQUE"
ASK PIXEL SIZE (0,0;1,1) xx,yy
LET xx=xx/2
LET yy=yy/2
SET WINDOW -xx/NN,xx/NN, -yy/NN,yy/NN

LET φ=0
LET stp=-PI/180*6
DO
   LET t=INT(TIME)
   IF t0<>t THEN
      LET t0=t
      IF 2*PI<=ABS(φ) THEN LET stp=-stp
      LET φ=REMAINDER(φ, 2*PI) +stp
      !-----
      SET DRAW mode hidden
      CLEAR
      SET TEXT font "Century",12*NN
      DRAW D4(N) WITH SHIFT(-300/2,-300/2/SQR(3))*ROTATE(φ*(-1)^N)*SCALE(1,(-1)^N)
      SET TEXT font "Century",12
      PLOT TEXT,AT (xx-80)/NN,(yy-10)/NN:"Right Click to Stop"
      DRAW center WITH SHIFT(-300/2/NN,-300/2/SQR(3)/NN)*ROTATE(φ)
      SET DRAW mode explicit
   END IF
   WAIT DELAY 0 ! 省電力効果
   MOUSE POLL mx,my,mlb,mrb
LOOP UNTIL mrb>=1 ! 右クリックで停止

PICTURE center
   SET LINE COLOR 2
   SET LINE width 2
   PLOT LINES:0,0; 300/NN,0; 300/2/NN,300*SQR(3)/2/NN; 0,0
   SET LINE width 1
   SET LINE COLOR 1
END PICTURE

!------
PICTURE D4(k)
   IF 0< k THEN
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*SHIFT(300/4,SQR(3)*300/4) ! 内側の上
      DRAW D4(k-1) WITH SCALE(1/2,-1/2)*SHIFT(300/4,SQR(3)*300/4) ! 内側の中
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(-PI*2/3)*SHIFT(300/4,SQR(3)*300/4) !内側の左
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(PI*2/3)*SHIFT(300,0) ! 内側の右
   ELSE
      DRAW A_Clock WITH ROTATE(-φ)*SHIFT(300/2,300/2/SQR(3))
      PLOT LINES:0,0; 300,0; 300/2,300*SQR(3)/2; 0,0 ! 外側の基準三角形
   END IF
END PICTURE

!------
PICTURE A_Clock
   SET AREA COLOR 1
   FOR i=1 TO 60
      LET a=-PI/30*(i-15)
      IF MOD(i,5)=0 THEN
         PLOT TEXT,AT 60*COS(a)+.5, 60*SIN(a) :STR$(i/5)           !数字
         ! CALL Plot_7segment( 60*COS(a) ,60*SIN(a) ,5.5 ,STR$(i/5)) !数字(代替)
      END IF
      DRAW disk WITH SCALE(1-.5*SGN(MOD(i,5)))*SHIFT(72*COS(a),72*SIN(a)) !分目盛り
   NEXT i
   !---
   DRAW hand(1) WITH SCALE(2.5, 0.75)*ROTATE(-t*PI/21600) !時針
   DRAW hand(1) WITH ROTATE(-t*PI/1800)                   !分針
   DRAW hand(1) WITH SCALE(0, 1.1)*ROTATE(-t*PI/30)       !秒針
   DRAW disk WITH SHIFT(0,0)*SCALE(4)                     !中心の飾り
END PICTURE

PICTURE hand(c)
   SET AREA COLOR c
   PLOT AREA: -1,-15; 1,-15; 1,60; -1,60    !3針共用、0時位置の針
END PICTURE

!--------------------------------------------------------------------------
SUB Plot_7segment(x,y,s,i$) !文字列中心(x,y) 文字の横幅(s) 数字の文字列(i$)
   LET w=LEN(i$)
   LET s1=s      ! y軸↑:s1=s  y軸↓:s1=-s
   LET s2=s/2
   LET x=x-(w-1)*s2*1.6
   FOR p=1 TO w
      SELECT CASE VAL(i$(p:p))
      CASE 0
         PLOT LINES:x-s2,y+s;x-s2,y-s;x+s2,y-s;x+s2,y+s;x-s2,y+s
      CASE 1
         PLOT LINES:x,y-s;x,y+s
      CASE 2
         PLOT LINES:x-s2,y+s1;x+s2,y+s1;x+s2,y;x-s2,y;x-s2,y-s1;x+s2,y-s1
      CASE 3
         PLOT LINES:x-s2,y-s;x+s2,y-s;x+s2,y+s;x-s2,y+s
         PLOT LINES:x-s2,y;x+s2,y
      CASE 4
         PLOT LINES:x-s2,y+s1;x-s2,y;x+s2,y
         PLOT LINES:x+s2,y+s1;x+s2,y-s1
      CASE 5
         PLOT LINES:x+s2,y+s1;x-s2,y+s1;x-s2,y;x+s2,y;x+s2,y-s1;x-s2,y-s1
      CASE 6
         PLOT LINES:x+s2,y+s1;x-s2,y+s1;x-s2,y-s1;x+s2,y-s1;x+s2,y;x-s2,y
      CASE 7
         PLOT LINES:x-s2,y+s1;x+s2,y+s1;x+s2,y-s1
      CASE 8
         PLOT LINES:x-s2,y;x-s2,y-s;x+s2,y-s;x+s2,y+s;x-s2,y+s;x-s2,y;x+s2,y
      CASE 9
         PLOT LINES:x+s2,y;x-s2,y;x-s2,y+s1;x+s2,y+s1;x+s2,y-s1;x-s2,y-s1
      CASE ELSE
      END SELECT
      LET x=x+s*1.6
   NEXT p
END SUB

END
 

三角箱で、跳ねるボール

 投稿者:SECOND  投稿日:2009年12月19日(土)16時24分33秒
返信・引用  編集済
  !三角箱で、跳ねるボール
!-----------------------
!ボールの方向を、適当な無理数にすると、周期がなくなり、
!ベルヌーイ・シフト写像( 無理数の小数下位を、無限に読み進む構造で、周期を失うカオス )
!に、似たカオスが現れる。

LET si=11   !正三角形(x1,y1)(x2,y2)(x3,y3) の一辺。
LET x1=1.5
LET y1=2.5
!----       !必ずしも、等辺でなくてよいが、外壁表示はズレる。
LET x2=x1+si
LET y2=y1
LET x3=x1+si/2
LET y3=y1+SQR(3)*si/2
!----                    !       3
LET A12=(y2-y1)/(x2-x1)  ! f13 /  \ f23
LET A13=(y3-y1)/(x3-x1)  !   1───2
LET A23=(y3-y2)/(x3-x2)  !      f12
DEF f12(x)=A12*(x-x1)+y1 ! ─
DEF f13(x)=A13*(x-x1)+y1 ! /
DEF f23(x)=A23*(x-x2)+y2 ! \
!
!ボール位置(bx,by)の前歴の線 y=my/mx*(x-bx)+by と壁の
!
!  直線f12 y=A12*(x-x1)+y1 との交点の式 A12*(x-x1)+y1=my/mx*(x-bx)+by
!  x=(A12*x1-y1-bx*my/mx+by)/(A12-my/mx)
!  y=f12(x)
!  直線f13 y=A13*(x-x1)+y1 との交点の式 A13*(x-x1)+y1=my/mx*(x-bx)+by
!  x=(A13*x1-y1-bx*my/mx+by)/(A13-my/mx)
!  y=f13(x)
!  直線f23 y=A23*(x-x2)+y2 との交点の式 A23*(x-x2)+y2=my/mx*(x-bx)+by
!  x=(A23*x2-y2-bx*my/mx+by)/(A23-my/mx)
!  y=f23(x)
!
LET px12= (x2-x1)/SQR((y2-y1)^2+(x2-x1)^2)
LET py12= (y2-y1)/SQR((y2-y1)^2+(x2-x1)^2) !直線f12 に平行な、単位ベクトル
LET px13= (x3-x1)/SQR((y3-y1)^2+(x3-x1)^2)
LET py13= (y3-y1)/SQR((y3-y1)^2+(x3-x1)^2) !直線f13 に平行な、単位ベクトル
LET px23= (x3-x2)/SQR((y3-y2)^2+(x3-x2)^2)
LET py23= (y3-y2)/SQR((y3-y2)^2+(x3-x2)^2) !直線f23 に平行な、単位ベクトル
LET ox12= py12
LET oy12=-px12   !直線f12 に垂直な、単位ベクトル
LET ox13= py13
LET oy13=-px13   !直線f13 に垂直な、単位ベクトル
LET ox23= py23
LET oy23=-px23   !直線f23 に垂直な、単位ベクトル
!
LET bx=X1            !ボールの初期位置
LET by=Y1
LET mx=SQR(5)/8      !ボールのX速度、ステップ��X
LET my=SQR(3)/20     !ボールのY速度、ステップ��Y
!
SET WINDOW 0,14, 0,14
! DRAW grid(1,1)
SET DRAW MODE NOTXOR  !2度書きで消える NOTXOR モード
LET r=0.7             !ボールの半径
!----
PLOT LINES: x1-r*SQR(3),y1-r; x2+r*SQR(3),y2-r; x3,y3+r*2; x1-r*SQR(3),y1-r !表示壁面
SET LINE COLOR 15     !銀
PLOT LINES: x1,y1; x2,y2; x3,y3; x1,y1 ! 計算壁面
SET LINE COLOR 2      !青
SET AREA COLOR 2      !青
!
PLOT TEXT,AT 10,13: "右クリック:停止"
DO
   DRAW disk WITH SCALE(r)*SHIFT(bx,by) !ボールを書く
   ! SET DRAW mode explicit
   WAIT DELAY 0.02              !省電力効果と、速度
   ! SET DRAW mode hidden
   DRAW disk WITH SCALE(r)*SHIFT(bx,by) !ボールだけを消す
   PLOT LINES : bx,by;                  ! 履歴線を(書く・消す)
   LET bx=bx+mx
   LET by=by+my
   IF f23(bx)<=by THEN LET bx23=(A23*x2-y2-bx*my/mx+by)/(A23-my/mx)
   IF f13(bx)<=by THEN LET bx13=(A13*x1-y1-bx*my/mx+by)/(A13-my/mx)
   IF f12(bx)>=by THEN LET bx12=(A12*x1-y1-bx*my/mx+by)/(A12-my/mx)
   !----
   IF f23(bx)<=by AND x3<=bx23 AND bx23<=x2 THEN
      LET bx=bx23
      LET by=f23(bx)
      LET wy=(mx*px23+my*py23)*py23-(mx*ox23+my*oy23)*oy23
      LET mx=(mx*px23+my*py23)*px23-(mx*ox23+my*oy23)*ox23 !mx,my の、壁に平行成分−壁に垂直成分
      LET my=wy
   ELSEIF f13(bx)<=by AND x1<=bx13 AND bx13<=x3 THEN
      LET bx=bx13
      LET by=f13(bx)
      LET wy=(mx*px13+my*py13)*py13-(mx*ox13+my*oy13)*oy13
      LET mx=(mx*px13+my*py13)*px13-(mx*ox13+my*oy13)*ox13
      LET my=wy
   ELSEIF f12(bx)>=by AND x1<=bx12 AND bx12<=x2 THEN
      LET bx=bx12
      LET by=f12(bx)
      LET wy=(mx*px12+my*py12)*py12-(mx*ox12+my*oy12)*oy12
      LET mx=(mx*px12+my*py12)*px12-(mx*ox12+my*oy12)*ox12
      LET my=wy
   END IF
   MOUSE POLL mox,moy,mlb,mrb
LOOP UNTIL 0< mrb

END
 

散歩コースの探索願い

 投稿者:GAI  投稿日:2009年12月19日(土)20時24分57秒
返信・引用
  ある点から東西南北いずれの方向でもいいから1進む。
そこで直角に曲がり2進む。
さらにそこで直角に曲がり3進む。
これを繰り返していき、直角に曲がってから4,5,6,7の距離進んでいき最後8の距離進んだ時に元の出発点に戻るコースどり(前のコースは横切らないこと。)のパターンを調べてほしい。(これを位数8の散歩コースと呼ぶことにします。)
同じく位数16の散歩コース
位数24の散歩コースでは何種類が可能か知りたい。
 

Re: 散歩コースの探索願い

 投稿者:山中和義  投稿日:2009年12月20日(日)11時08分38秒
返信・引用  編集済
  > No.900[元記事へ]

GAIさんへのお返事です。

「横切る」や「同一」の判定は、図形が表示されるので、それを見て確認してください。
!散歩コースの探索

PUBLIC NUMERIC N !歩数
LET N=16

DIM d(N),x(0 TO N),y(0 TO N) !各歩数での方向と位置
MAT d=ZER
MAT x=ZER !原点
MAT y=ZER

LET x(1)=1 !1歩目は東へ ※0:東、1:北、2:西、3:南

CALL search(2,d,x,y) !2歩目以降

END


EXTERNAL SUB search(s,d(),x(),y()) !バックトラックで検索する
FOR i=-1 TO 1 STEP 2 !右と左のみ
   LET dd=MOD(d(s-1)+i,4) !1つ前を基準にする

   LET xx=x(s-1) !現在の位置
   LET yy=y(s-1)
   SELECT CASE dd !s歩目の移動距離
   CASE 0 !E
      LET xx=xx+s
   CASE 1 !N
      LET yy=yy+s
   CASE 2 !W
      LET xx=xx-s
   CASE 3 !S
      LET yy=yy-s
   CASE ELSE
   END SELECT
   LET x(s)=xx !進める
   LET y(s)=yy

   LET d(s)=dd !s歩目の方向

   IF s=N THEN !指定の歩数に達したら
      IF x(N)=x(0) AND y(N)=y(0) THEN !元の位置に戻ったら
         MAT PRINT d;

         SET bitmap SIZE 600,600 !作画して交差などを確認する
         SET WINDOW -40,40,-40,40
         CLEAR
         DRAW grid(5,5)
         SET LINE width 2
         SET TEXT HEIGHT 1.5 !※調整が必要である
         SET TEXT JUSTIFY "center","half"
         FOR k=1 TO N
            SET LINE COLOR 1 !奇数と偶数で色分け
            IF MOD(k,2)=0 THEN SET LINE COLOR 4
            PLOT LINES: x(k-1),y(k-1); x(k),y(k) !軌跡
            PLOT TEXT ,AT (x(k-1)+2*x(k))/3,(y(k-1)+2*y(k))/3: STR$(k)
         NEXT k
         SET LINE width 1 !restore it

         pause !OK?
         !INPUT PROMPT "OKかNGを入力してください。": y$

      END IF
   ELSE
      CALL search(s+1,d,x,y) !次へ
   END IF
NEXT i
END SUB

!回答、情報、アルゴリズム、パズル

!1歩目を東(水平方向)へ固定すると
!奇数目は水平方向(東西方向)、偶数目は垂直方向(南北方向)になる。
!式で表現すると
! x=±1±3±5±7
! y=±2±4±6±8
!プラスマイナスの組合せで0になるかどうかの検証になる。
 

跳ねるボールを、N角形 の壁面へ 拡張

 投稿者:SECOND  投稿日:2009年12月22日(火)04時55分8秒
返信・引用  編集済
  > No.899[元記事へ]

! 跳ねるボールを、N角形 の壁面へ 拡張
!--------------------------------------
!ボールの方向を、適当な無理数にすると、周期がなくなり、
!ベルヌーイ・シフト写像( 無理数の小数下位を、無限に読み進む構造で、周期を失うカオス )
!に、似たカオスが現れる。

OPTION BASE 0
SET WINDOW -7,7, -7,7
DRAW axes
!----
LET ma=9                    !多角形の 角数 3,4,5,6,7,8,,,,
DIM x(ma),y(ma),A(ma),px(ma),py(ma)
LET r=0.7                   !ボールの半径
LET r0=5.5                  !計算で使用の 多角形、外接円の半径
LET r1=r0+r/SIN(PI/2-PI/ma) !ボールの当る 多角形、外接円の半径
!
!LET a0=PI*(1.5-1/ma)        !(x1,y1)の角。
LET a0=PI*(1.5-3/ma)        !(x1,y1)の1つ手前の角。
FOR i=0 TO ma
   LET x(i)=r0*COS(a0)
   LET y(i)=r0*SIN(a0)
   IF 0< i THEN
      SET LINE COLOR "silver"
      PLOT LINES: x(i-1),y(i-1); x(i),y(i) !計算壁面
      SET LINE COLOR "black"
      PLOT LINES: r1/r0*x(i-1),r1/r0*y(i-1); r1/r0*x(i),r1/r0*y(i) !ボール壁面
   END IF
   LET a0=a0+2*PI/ma
NEXT i
!                      A3         A4  4  A3
!       3          4──3      5/  \3
!  A3 /  \ A2   A4│    │A2   A5\    /A2   ・・・
!   1───2      1──2        1─2
!       A1             A1             A1
!
FOR i=1 TO ma
   LET j=MOD(i,ma)+1
   LET A(i)=(y(j)-y(i))/(x(j)-x(i))                         !直線ij の勾配
   LET px(i)=(x(j)-x(i))/SQR((y(j)-y(i))^2+(x(j)-x(i))^2)
   LET py(i)=(y(j)-y(i))/SQR((y(j)-y(i))^2+(x(j)-x(i))^2)   !直線ij に平行な、単位ベクトル
NEXT i
!
LET a0=ANGLE(x(1),y(1))
LET bx=r0*COS(a0)*0.999 ! ボールの初期位置X
LET by=r0*SIN(a0)*0.999 ! ボールの初期位置Y
LET a0=ANGLE(x(2)-x(1),y(2)-y(1))+SQR(2)*PI/ma/1.1313 !ボールの初期角度
LET m0=.23        !ボールの速さ��
LET mx=m0*COS(a0) !ボールの初期��X
LET my=m0*SIN(a0) !ボールの初期��Y

SUB Cross   !各辺への衝突検出と反射
   LET ok=0
   IF ABS(A(n))< 1 THEN
   !---壁の直線(y-y0)=(x-x0)*A ,ボール位置と図中心を結ぶ線 y=x*by/bx の交点(xw,yw)。
      LET xw=(x(n)*A(n)-y(n))/(A(n)-by/bx)                  !xw 優先
      LET yw=(xw-x(n))*A(n)+y(n)
      IF 0< xw*bx+yw*by AND xw^2+yw^2<=bx^2+by^2 THEN       !壁の外
      !---壁の直線(y-y0)=(x-x0)*A, ボール軌跡線(y-by)=(x-bx)*my/mx の交点(xc,yc)。
         LET xc=(x(n)*A(n)-y(n)-bx*my/mx+by)/(A(n)-my/mx)   !xc 優先
         LET yc=(xc-x(n))*A(n)+y(n)
         !---壁の一辺内なら、反射処理
         IF (x(n)<=xc AND xc<=x(MOD(n,ma)+1) OR x(MOD(n,ma)+1)<=xc AND xc<=x(n)) THEN CALL Mirror
      END IF
   ELSE
   !---壁の直線(y-y0)=(x-x0)*A ,ボール位置と図中心を結ぶ線 y=x*by/bx の交点(xw,yw)。
      LET yw=(y(n)/A(n)-x(n))/(1/A(n)-bx/by)                !yw 優先
      LET xw=(yw-y(n))/A(n)+x(n)
      IF 0< xw*bx+yw*by AND xw^2+yw^2<=bx^2+by^2 THEN       !壁の外
      !---壁の直線(y-y0)=(x-x0)*A, ボール軌跡線(y-by)=(x-bx)*my/mx の交点(xc,yc)。
         LET yc=(y(n)/A(n)-x(n)-by*mx/my+bx)/(1/A(n)-mx/my) !yc 優先
         LET xc=(Yc-y(n))/A(n)+x(n)
         !---壁の一辺内なら、反射処理
         IF (y(n)<=yc AND yc<=y(MOD(n,ma)+1) OR y(MOD(n,ma)+1)<=yc AND yc<=y(n)) THEN CALL Mirror
      END IF
   END IF
END SUB

SUB Mirror   !ベクトル(mx,my)の反射を、同じ(mx,my)に上書。
   LET bx=xc !ボールを衝突点に置く
   LET by=yc                                ! 単位ベクトル:壁に平行( px(n), py(n) )
   !----                                                       垂直(-py(n), px(n) )
   LET wy=(mx*px(n)+my*py(n))*py(n)+(mx*py(n)-my*px(n))*px(n)
   LET mx=(mx*px(n)+my*py(n))*px(n)-(mx*py(n)-my*px(n))*py(n)
   LET my=wy                     !                             内積 *方向        内積 *方向
   LET ok=1  !反射報告           !ball速度ベクトルm= (mx*px+my*py)*p−(mx*ox+my*oy)*o
END SUB                          !                     平行単位vect.p   垂直単位vect.o

SET LINE COLOR "blue"
SET AREA COLOR "blue"
SET DRAW MODE NOTXOR !2度書きで消える NOTXOR モード
!
PLOT TEXT,AT 3.7, 6.4: "右クリック:停止"
DO
   DRAW disk WITH SCALE(r)*SHIFT(bx,by) !ボールを書く
   ! SET DRAW mode explicit             !ちらつき防止。| かなりな負荷が、かかります。遅い|
   ! SET DRAW mode hidden               !ちらつき防止。| パソコンや省電力なら使わないが良|
   WAIT DELAY 0.02                      ! 省電力効果と、速度
   DRAW disk WITH SCALE(r)*SHIFT(bx,by) !ボールだけを消す
   PLOT LINES : bx,by;                  ! 履歴線を(書く・消す)
   LET bx=bx+mx
   LET by=by+my
   !----
   FOR n=1 TO ma
      CALL Cross  !衝突検出と反射
      IF ok=1 THEN EXIT FOR
   NEXT n
   MOUSE POLL mox,moy,mlb,mrb
LOOP UNTIL 0< mrb

END
 

Re: 跳ねるボールを、N角形 の壁面へ 拡張

 投稿者:山中和義  投稿日:2009年12月22日(火)14時00分24秒
返信・引用  編集済
  > No.940[元記事へ]

先のブロック崩しのボールの軌道の解析プログラムです。
ベクトルと図形方程式で記述してみました。
LET cEps=1e-13 !精度

DIM t(2) !作業用

SET bitmap SIZE 600,600
SET WINDOW -5,5,-5,5
DRAW grid

LET iter=200 !繰り返し回数

LET M=3 !m角形 ※3以上の整数

DIM Pw(M,4) !壁面の端
!DATA  3,-4,  3, 4 !正方形 始点(x1,y1)、終点(x2,y2)
!DATA  3, 4, -3, 4
!DATA -3, 4, -3,-4
!DATA -3,-4,  3,-4
!MAT READ Pw
!MAT PRINT Pw;

LET R=4 !外接円の半径
FOR i=1 TO M !X軸上の点(R,0)から反時計まわりに頂点を得る
   LET th=2*PI*(i-1)/M !始点(x1,y1)
   LET Pw(i,1)=R*COS(th)
   LET Pw(i,2)=R*SIN(th)
   LET th=2*PI*i/M !終点(x2,y2)
   LET Pw(i,3)=R*COS(th)
   LET Pw(i,4)=R*SIN(th)
NEXT i
MAT PRINT Pw;

DIM w(M,2) !壁面の法線ベクトル
FOR i=1 TO M !線分の方向ベクトルから算出する
   LET t(1)=-(Pw(i,4)-Pw(i,2)) !X方向
   LET t(2)=  Pw(i,3)-Pw(i,1)  !Y方向
   CALL Vec2Normalize(t,t) !正規化
   MAT PRINT t;
   LET w(i,1)=t(1)
   LET w(i,2)=t(2)
NEXT i

FOR i=1 TO M !壁面を表示する
   PLOT LINES: Pw(i,1),Pw(i,2); Pw(i,3),Pw(i,4)
NEXT i


!ボールの軌道 直線p(t)=Pa+t*a
DIM a(2) !ボールの移動方向ベクトル
DATA 1,2
MAT READ a
CALL Vec2Normalize(a,a) !|a|=1
MAT PRINT a;

DIM Pa(2) !ボールの発射位置
DATA 1,0
MAT READ Pa


DIM Pc(2) !衝突位置
DIM aa(2) !反射方向ベクトル
FOR k=1 TO iter !バウンドさせる
   CALL CalcCollision(Pc,aa)
   MAT PRINT Pc; !debug
   PLOT LINES: Pa(1),Pa(2); Pc(1),Pc(2) !軌跡を描く

   MAT Pa=Pc !次へ
   MAT a=aa
NEXT k


!衝突する平面の法線ベクトルをn、入射方向ベクトルをaとする。
!反射方向ベクトルbは、b=a-2*(a・n)*n
!
!また、平面上の任意の点をPs、入射方向ベクトルaの始点をPaとすると、
!衝突位置Pcは、Pc=Pa+{n・(Ps-Pa)/(a・n)}*a

SUB CalcReflection(a(),n(), b()) !反射ベクトルを計算する
   MAT t=(2*DOT(a,n))*n !ベクトルaをベクトルnに射影して、その2倍のベクトル
   MAT b=a-t
   MAT PRINT b; !debug
END SUB

SUB CalcCollision(Pc(),b()) !壁面との衝突位置と反射方向ベクトルを計算する
   DIM n(2),Ps(2),Pe(2)
   FOR i=1 TO M
      CALL Vec2Set(w(i,1),w(i,2), n) !法線ベクトル
      CALL Vec2set(Pw(i,1),Pw(i,2), Ps) !平面上の任意の点
      PRINT "壁面=";i !debug

      LET an=DOT(a,n) !ベクトルaとベクトルnとのなす角を得る |a||n|cosθ<0
      IF an<0 THEN !衝突する壁面の表裏判定
         MAT t=Ps-Pa
         LET nT=DOT(n,t)
         IF nT<0 THEN !壁面との位置関係から
            MAT t=(nT/an)*a
            MAT Pc=Pa+t !交点

            CALL Vec2Set(Pw(i,3),Pw(i,4), Pe) !直線の終点
            LET v=InRange(Pc, Ps,Pe)
            IF v>=0 AND v<=1 THEN !線分上なら
               MAT PRINT Pc; !debug

               CALL CalcReflection(a,n, b) !反射方向ベクトル

               EXIT SUB !1つ見つかれば
            ELSE
               PRINT "壁面の延長上で衝突する"
               MAT PRINT Pc; !debug
            END IF
         ELSEIF nT=0 THEN
            PRINT "衝突中"
            MAT PRINT Pa; !debug

            MAT Pc=Pa
            CALL CalcReflection(a,n, b) !反射方向ベクトル

            EXIT SUB !1つ見つかれば
         ELSE
            PRINT "衝突しない"
         END IF

      ELSE
         PRINT "衝突しない..."
         IF i=M THEN
            PRINT "すべての壁面と衝突しません。"
            STOP
         END IF
      END IF
   NEXT i
END SUB

!PsとPeを結ぶ線分を延長した直線上の点Pcと線分との位置関係
!0≦t≦1なら、線分上
FUNCTION InRange(Pc(), Ps(),Pe())
   DIM t1(2),t2(2)
   MAT t1=Pe-Ps
   MAT t2=Pc-Ps
   IF ABS(t1(1))>=cEps THEN !t1(1)<>0
      LET v=t2(1)/t1(1) !X方向の比
   ELSE !垂直線
      IF ABS(t1(2))>=cEps THEN !t1(2)<>0
         LET v=t2(2)/t1(2) !Y方向の比
      ELSE !1点
         LET v=0
      END IF
   END IF
   LET InRange=v
END FUNCTION


END


!ベクトル
EXTERNAL FUNCTION Vec2Length(a()) !長さ |a|
LET Vec2Length=SQR(a(1)*a(1)+a(2)*a(2))
END FUNCTION

EXTERNAL SUB Vec2Normalize(a(),n()) !正規化 n=a/|a|
LET L=Vec2Length(a)
IF L>0 THEN MAT n=(1/L)*a
END SUB

!その他
EXTERNAL SUB Vec2Set(x,y, v())
LET v(1)=x
LET v(2)=y
END SUB
 

簡易ゲームで

 投稿者:Night  投稿日:2009年12月22日(火)15時08分25秒
返信・引用
  はじめまして

今、10進Basicで簡易ダンジョンRPGを作ろうと思っています
そこで質問なのですが
・グラフィックスを重ねずどんどん表示する方法
・ダンジョンを移動する際のキーを矢印にする方法
・歩く場所を決められるかどうか
の3点をお願いします

本当は大まかなプログラムを教えていただきたいのですが
自分でやらなければ意味はないので、がんばれるだけやってみようと思います

よろしくお願いします
 

Re: 簡易ゲームで

 投稿者:山中和義  投稿日:2009年12月22日(火)19時17分46秒
返信・引用
  > No.942[元記事へ]

Nightさんへのお返事です。

十進BASICは、リアルタイム系ゲームの作成には不向きです。
・ビットマップ画像を高速に処理できない。(切り出し表示など)
・3Dは自前で処理する必要がある。また、他のライブラリを利用できない。

以前作成したものです。参考にしてください。
!ファミコン時代の2D RPGを作る

!マップの構成
! 「正面見下ろし」形式のチップ画像を用意して、タイル状に配置する。
! フィールド、オブジェクトの2層で構成される。
! オブジェクト層が移動可能判定の対象とする。
!チップ画像
! 十進BASICはビットマップ画像を扱うのが苦手のため、ベクトル図形(PLOT文)で描画する。
! X、Yとも−1〜1の範囲の座標で表現して、描画単位はPICTURE文でまとめる。
!
!マップの展開
! 十進BASICの問題座標にマップ全体をDRAW文で描画する。
! フィールド、オブジェクトの順に描画する。
!マップの表示(ビュー)
! SET WINDOWS文でビューを構成して、マップの一部を画面に表示する。
!ビューのスクロール
! PC(Player Character)の「中央固定」で追従する。
!キャラクタの移動
! チップ単位、上下左右の4方向。
! 仮想ゲームパッドからの入力をサポートする。
!  移動キー:カーソルキー
!  Aボタン:SPACEキー
!  Bボタン:


!マップの定義
DATA 15,12 !マップの大きさ
READ msx,msy !マップ情報を読み込む

DATA 1,1,1,2,2, 2,1,1,1,1, 2,2,2,1,1 !チップ配置情報(フィールド)
DATA 1,1,1,2,2, 2,1,1,1,1, 2,2,2,1,1
DATA 1,1,1,2,2, 2,1,1,1,1, 1,1,1,1,1
DATA 1,1,1,1,2, 1,1,1,1,1, 1,1,1,1,1
DATA 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1
DATA 1,2,2,1,1, 1,1,1,1,1, 1,1,1,1,1
DATA 1,2,2,1,1, 1,2,2,2,1, 1,1,1,1,1
DATA 2,2,1,1,1, 1,2,2,2,1, 3,3,1,1,1
DATA 2,2,1,1,1, 1,2,2,2,1, 3,2,2,1,1
DATA 2,2,2,2,1, 1,1,1,1,1, 3,2,2,1,1
DATA 2,2,2,2,1, 1,1,1,1,1, 3,3,2,1,1
DATA 1,1,1,1,1, 1,1,1,1,1, 3,3,3,1,1
DIM mapFld(msy,msx)
MAT READ mapFld

DATA 0, 0, 0, 0,12,  0, 0, 0, 0,11,   0,12,12, 0, 0 !チップ配置情報(オブジェクト)
DATA 0, 0, 0, 0,12,  0, 0, 0, 0,11,   0, 0,12, 0, 0
DATA 0, 0, 0, 0,12,  0, 0, 0, 0,11,  11, 0, 0, 0, 0
DATA 0, 0, 0, 0, 0,  0, 0, 0,11,11,   0, 0, 0, 0, 0
DATA 0, 0 ,0, 0, 0,  0, 0, 0, 0, 0,   0, 0, 0, 0, 0
DATA 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,   0, 0, 0, 0, 0
DATA 0,12,12, 0, 0,  0, 0, 0,12, 0,   0, 0, 0, 0, 0
DATA 0, 0,11,11, 0,  0, 0,21,12, 0,  13,13, 0, 0, 0
DATA 0,12,11,11, 0,  0, 0, 0,12, 0,  13,12, 0, 0, 0
DATA 0,12,12,12, 0,  0, 0, 0, 0, 0,  13,12,12, 0, 0
DATA 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  13, 0, 0, 0, 0
DATA 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,   0, 0, 0, 0, 0
DIM mapObj(msy,msx)
MAT READ mapObj


!ゲーム画面の定義
LET GAME_TITLE=1 !タイトル
LET GAME_MOVE=2 !移動
LET GAME_TALK=3 !会話
LET GAME_BATTLE=4 !戦闘

LET gs=GAME_TITLE !タイトル画面から


!ビューポートの定義
LET vsx=15 !ビューポートの大きさ(1/2チップ単位)
LET vsy=15
LET vx=0 !位置(左下。※問題座標)
LET vy=0


!移動方向の定義
LET MOVE_NONE=-1 !なし
LET MOVE_RIGHT=0 !右
LET MOVE_UP=2 !上
LET MOVE_LEFT=4 !左
LET MOVE_DOWN=6 !下


!会話文の定義
DATA "はじめる:Aボタン(SPACEキー)" !#1 ※4行単位
DATA "おわる:ESCキー"
DATA ""
DATA "移動:十字(カーソルキー)、OK:Aボタン"
DATA "" !#2
DATA ""
DATA ""
DATA ""
DATA "コーヒータイム♪" !#3
DATA ""
DATA "「休憩をとったら出発だ!」"
DATA ""
DATA "「残念、ぼくは泳げないんだ。」" !#4
DATA "「飛び越えられないぞ...」"
DATA ""
DATA ""
DATA "" !#5
DATA ""
DATA ""
DATA ""
DIM ms$(4*5)
MAT READ ms$

DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 !イベント配置情報
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 4,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,4,4, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,3,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DIM mapEvt(msy,msx)
MAT READ mapEvt
LET evt=0

!ゲームの初期化
LET x=6 !キャラクタの位置(チップ単位)
LET y=5
LET d=MOVE_DOWN !向き

CALL SetViewPort !ビューポート移動


LET t0=TIME
LET fRun=-1 !ゲーム開始
DO WHILE fRun<0 !ゲームループ

   IF gs=GAME_TITLE THEN !タイトル画面なら
      SET DRAW mode hidden !ちらつき防止(開始)
      CLEAR
      DRAW Hiro(6,d) WITH SHIFT(vx+8,vy+8) !キャラクタ
      PLOT TEXT ,AT vx+6,vy+11: "チョコボの冒険"
      CALL DrawSpeak(0,0)
      SET DRAW mode explicit !ちらつき防止(終了)

      CALL GetAButton(t0) !Aボタンの入力
   END IF
   IF gs=GAME_MOVE THEN !移動画面なら
      CALL GetMoveKey(dx,dy,dr,t0) !移動キーの入力

      IF dx<>0 OR dy<>0 THEN !移動なら
         LET d=dr !移動方向に向く

         LET xx=x+dx !仮に移動する(チップ単位)
         LET yy=y+dy
         IF xx>0 AND xx<=msx AND yy>0 AND yy<=msy THEN !マップ内で
            IF mapObj(yy,xx)=0 THEN !障害物がなければ
               LET x=xx !実際に移動させる
               LET y=yy
            END IF
         END IF

         CALL SetViewPort !ビューポート移動

         LET evt=CheckEvent(mapEvt,x,y) !フィールド上のイベントを確認
      END IF

      CALL DrawView !ビュー表示
   END IF
   IF gs=GAME_TALK THEN !会話画面なら
      CALL DrawView !ビュー表示

      CALL GetAButton(t0) !Aボタンの入力
   END IF


   IF GetKeyState(27)<0 THEN LET fRun=0 !ESCキーで終了
LOOP

SUB GetMoveKey(dx,dy,dr,t0) !移動キーの入力を確認する
   LET dx=0 !移動量
   LET dy=0
   LET dr=MOVE_NONE !移動方向
   IF TIME-t0>0.2 THEN !200ミリ秒ごとに
      IF GetKeyState(37)<0 THEN !いずれか1つのみ
         LET dx=-1
         LET dr=MOVE_LEFT !左カーソルキー
      ELSE
         IF GetKeyState(38)<0 THEN
            LET dy=-1
            LET dr=MOVE_UP !上
         ELSE
            IF GetKeyState(39)<0 THEN
               LET dx=1
               LET dr=MOVE_RIGHT !右
            ELSE
               IF GetKeyState(40)<0 THEN
                  LET dy=1
                  LET dr=MOVE_DOWN !下
               END IF
            END IF
         END IF
      END IF

      LET t0=TIME !次へ
   END IF
END SUB

SUB GetAButton(t0) !Aボタンの入力を確認する
   IF TIME-t0>0.2 THEN !200ミリ秒ごとに
      IF GetKeyState(32)<0 THEN LET gs=GAME_MOVE !SPACEキー
      LET t0=TIME !次へ
   END IF
END SUB

SUB SetViewPort !ビューポートの設定する
   LET vx=2*x-vsx/2-1 !「キャラクタの中央固定」でビューポートを追従させる
   LET vy=2*(msy-y)-vsy/2+1
   SET WINDOW vx,vx+vsx,vy,vy+vsy
END SUB

SUB DrawView !マップ、キャラクタを表示する
   SET DRAW mode hidden !ちらつき防止(開始)
   CLEAR

   CALL DrawLayer(mapFld,msx,msy) !フィールド
   CALL DrawLayer(mapObj,msx,msy) !オブジェクト
   DRAW Hiro(6,d) WITH SHIFT(2*x-1,2*(msy-y)+1) !キャラクタ
   IF gs=GAME_TALK THEN CALL DrawSpeak(evt,0) !会話文

   SET DRAW mode explicit !ちらつき防止(終了)
END SUB

SUB DrawSpeak(n,v) !会話文を表示する
   SET AREA COLOR 199 !ふきだし
   PLOT AREA: vx+1,vy+1; vx+vsx-1,vy+1; vx+vsx-1,vy+5; vx+1,vy+5
   SET LINE COLOR 1
   SET LINE width 3
   PLOT LINES: vx+1,vy+1; vx+vsx-1,vy+1; vx+vsx-1,vy+5; vx+1,vy+5; vx+1,vy+1

   SET TEXT HEIGHT 0.4
   FOR i=1 TO 4 !4行単位
      PLOT TEXT ,AT vx+2,vy+4.75-i*0.75: ms$(n+i)
   NEXT i
END SUB

FUNCTION CheckEvent(e(,),x,y) !フィールド上のイベントを確認する
   LET a=e(y,x)
   IF a>0 THEN LET gs=GAME_TALK !会話画面へ
   LET CheckEvent=4*(a-1)
END FUNCTION

END

続く
 

Re: 簡易ゲームで

 投稿者:山中和義  投稿日:2009年12月22日(火)19時18分57秒
返信・引用  編集済
  > No.943[元記事へ]

続き
EXTERNAL SUB DrawLayer(m(,),sx,sy) !レイヤを表示する
FOR j=1 TO sy !奥から順に(正面見下ろし)
   LET y=2*(sy-j)+1 !左上を原点、右方向がX軸の正、下方向がY軸の正
   FOR i=1 TO sx
      LET x=2*i-1
      DRAW PutChip(m(j,i)) WITH SHIFT(x,y) !チップ情報をもとに配置する
   NEXT i
NEXT j
END SUB


EXTERNAL PICTURE PutChip(i) !番号に対応したチップ画像を描く
IF i=1 THEN DRAW Ground
IF i=2 THEN DRAW Grass
IF i=3 THEN DRAW Rock
IF i=11 THEN DRAW Pool
IF i=12 THEN DRAW Tree
IF i=13 THEN DRAW Mount
IF i=21 THEN DRAW House
END PICTURE


!※作成基準 - X、Y座標とも範囲は-1〜1とする。少しはみ出てもよい。

!キャラクタ
EXTERNAL PICTURE Hiro(c,d) !チョコボ
SET AREA COLOR 8
DRAW disk WITH SCALE(0.8,0.2)*SHIFT(0,-0.9) !影
SET LINE width 2
SET LINE COLOR 1
PLOT LINES: -0.2,-0.3; -0.3,-0.9; -0.1,-0.9 !足
SET AREA COLOR c
DRAW disk WITH SCALE(0.6) !体
PLOT LINES: 0.3,-0.3; 0.4,-0.9; 0.6,-0.8 !足
DRAW disk WITH SCALE(0.45)*SHIFT(0.4,0.4) !頭
SET AREA COLOR 2
PLOT AREA: 0.7,0.5; 1,0.7; 0.7,0.7 !くちばし
SET AREA COLOR 1
DRAW disk WITH SCALE(0.08)*SHIFT(0.5,0.7) !目
END PICTURE

!フィールド
EXTERNAL PICTURE Ground !平地
SET AREA COLOR 27
PLOT AREA: -1,-1; 1,-1; 1,1; -1,1
END PICTURE

EXTERNAL PICTURE Grass !草地
SET AREA COLOR 3
PLOT AREA: -1,-1; 1,-1; 1,1; -1,1
END PICTURE

EXTERNAL PICTURE Rock !岩地
SET AREA COLOR 50
PLOT AREA: -1,-1; 1,-1; 1,1; -1,1
END PICTURE

!オブジェクト
EXTERNAL PICTURE Tree !木
SET AREA COLOR 10
DRAW disk WITH SCALE(0.5)*SHIFT(0,0.5) !葉
DRAW disk WITH SCALE(0.5)*SHIFT(-0.4,0) !葉
DRAW disk WITH SCALE(0.4)*SHIFT(0.5,-0.2) !葉
SET AREA COLOR 12
PLOT AREA: -0.2,-1; 0.2,-1; 0,0 !幹
END PICTURE

EXTERNAL PICTURE Pool !池
SET AREA COLOR 5
PLOT AREA: -1,-1; 1,-1; 1,1; -1,1
END PICTURE

EXTERNAL PICTURE Mount !山
SET AREA COLOR 240
PLOT AREA: -0.6,-1; 1,-1; 0.2,1
PLOT AREA: -1,-1; 0,-1; -0.5,0
END PICTURE

EXTERNAL PICTURE House !家
SET AREA COLOR 15
PLOT AREA: -1,0; -1,-1; 1,-1; 1,0 !壁
SET AREA COLOR 2
PLOT AREA: -1.6,0; 1.6,0; 1,1; -1,1 !屋根
SET AREA COLOR 10
PLOT AREA: -0.9,-1; -0.9,-0.2; -0.5,-0.2; -0.5,-1 !ドア
SET AREA COLOR 5
PLOT AREA: 0.4,-0.6; 0.9,-0.6; 0.9,-0.2; 0.4,-0.2 !窓
SET AREA COLOR 12
PLOT AREA: 0.7,1; 0.7,1.3; 0.5,1.3; 0.5,1 !煙突
END PICTURE
 

バクが、ありました。

 投稿者:SECOND  投稿日:2009年12月24日(木)04時05分10秒
返信・引用
  > No.940[元記事へ]


N |mod(N,3)+1|mod(N+1,3)|    1つ先の角を求めるとき、左の表のように、mod(N,3)+1 と
1 |    2     |    2     |    しなければならない所、mod(N+1,3) になっていました。
2 |    3     |    0     |    作図の都合上、x(0)y(0)にも、x(3)y(3) と同じ内容を、
3 |    1     |    1     |    入れていたため、外見には、出ませんでしたが、大バクです。

                               冒頭の作図部分で、0 to ma を、1 to ma にすると、図が
変るだけでなく、関係無い動作状態まで、おかしくなっていたのは、このためです。現在は、
その他も、修正しました。

 

ベクトルによる平面幾何の計算

 投稿者:山中和義  投稿日:2009年12月24日(木)10時49分37秒
返信・引用
 
!ベクトルによる平面幾何の計算 - 点、直線(線分)

LET cEps=1e-13 !精度

!ベクトル(a1,a2)とベクトル(b1,b2)との演算
DEF fnDot(a1,a2, b1,b2)=a1*b1+a2*b2 !内積
DEF fnCross(a1,a2, b1,b2)=fnDot(-a2,a1,b1,b2) !擬似外積、パープ内積 a1*b2-a2*b1
DEF fnABS(a,b)=SQR(a*a+b*b) !絶対値、大きさ

DIM a(2),b(2),c(2),d(2) !点A、B、C、D

DATA  4, 4 !A
DATA -1, 1 !B
DATA -3, 2 !C
DATA  3,-4 !D

MAT READ A
MAT READ B
MAT READ C
MAT READ D

SET WINDOW -5,5,-5,5 !グラフを描く
DRAW grid
SET TEXT HEIGHT 0.4
PLOT LINES: A(1),A(2); B(1),B(2) !線分AB
PLOT TEXT ,AT A(1),A(2): "A"
PLOT TEXT ,AT B(1),B(2): "B"
PLOT LINES: C(1),C(2); D(1),D(2) !線分CD
PLOT TEXT ,AT C(1),C(2): "C"
PLOT TEXT ,AT D(1),D(2): "D"


DIM s(2),t(2),u(2),v(2) !作業用

!点Aと点Bを通る直線と点Cと点Dを通る直線との直交・平行判定
!内積が0なら、直交。 外積が0なら、平行。

MAT s=b-a
MAT t=d-c
IF fnDot(s(1),s(2),t(1),t(2))=0 THEN PRINT "直交"
IF fnCross(s(1),s(2),t(1),t(2))=0 THEN PRINT "平行"


!点Aと点Bを通る直線と点Cと点Dを通る直線との交点

MAT s=b-a
MAT t=d-c
LET DD=fnCross(t(1),t(2),s(1),s(2))
IF DD<>0 THEN
   MAT u=c-a
   MAT v=( fnCross(t(1),t(2),u(1),u(2))/DD ) * s
   MAT v=a+v
   MAT PRINT v; !交点
ELSE
   PRINT "平行です。"
END IF


!点Aと点Bを結ぶ線分と点Cと点Dを結ぶ線分との交点

MAT s=b-a
MAT t=c-a
LET d1=fnCross(s(1),s(2),t(1),t(2))
!MAT s=b-a
MAT t=d-a
LET d2=fnCross(s(1),s(2),t(1),t(2))
MAT s=d-c
MAT t=a-c
LET d3=fnCross(s(1),s(2),t(1),t(2))
!MAT s=d-c
MAT t=b-c
LET d4=fnCross(s(1),s(2),t(1),t(2))
IF d1*d2<=0 AND d3*d4<=0 THEN
   MAT u=b-a
   MAT u=( ABS(d3)/(ABS(d3)+ABS(d4)) ) * u
   MAT u=a+u
   MAT PRINT u; !交点
ELSE
   PRINT "交差なし"
END IF


!点Cと、点Aと点Bを通る直線との位置関係

MAT s=b-a
MAT t=c-a
LET DD=fnCross(s(1),s(2),t(1),t(2))
IF DD=0 THEN
   PRINT "線上"
ELSEIF DD>0 THEN
   PRINT "左側"
ELSE
   PRINT "右側"
END IF


!点Cが、点Aと点Bを結ぶ線分上にあるかどうかの判定
!三角不等式 |a-b|≦|a-c|+|c-b|

MAT s=a-c
MAT t=c-b
MAT u=a-b
IF fnABS(s(1),s(2))+fnAbs(t(1),t(2))<fnABS(u(1),u(2))+cEps THEN PRINT "線上"


!点Cと、点Aと点Bを通る直線との距離

MAT s=b-a
MAT t=c-a
PRINT ABS(fnCross(s(1),s(2),t(1),t(2))) / fnABS(s(1),s(2))


!点Cと、点Aと点Bを結ぶ線分との距離(最近接点)

MAT s=b-a
MAT t=c-a
MAT u=c-b
IF fnDot(s(1),s(2),t(1),t(2))<cEps THEN !点A外側
   PRINT fnABS(t(1),t(2)) !点Aとの距離
ELSEIF fnDot(-s(1),-s(2),u(1),u(2))<cEps THEN !点B外側
   PRINT fnABS(u(1),u(2)) !点Bとの距離
ELSE !線分AB内
   PRINT ABS(fnCross(s(1),s(2),u(1),u(2))) / fnABS(s(1),s(2)) !垂線
END IF


END

!投稿(記述例)、数学、ベクトルと図形方程式、アルゴリズム、ゲーム、当たり判定
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2009年12月24日(木)12時54分51秒
返信・引用  編集済
  > No.770[元記事へ]

十進BASICでベクトル成分の計算を行う場合、
MAT文(行列)の和差、実数倍の計算を対応させるのが一般的だろう。

次のような問題で、電卓代わりに活用するなら、、、
!複素数による平面上のベクトルの計算

OPTION ARITHMETIC COMPLEX

DEF v(a,b)=COMPLEX(a,b) !複素数の和差、実数倍の計算を対応させる

DEF fnDOT(a,b)=Re(a)*Re(b)+Im(a)*Im(b) !内積 a1*b1+a2*b2
DEF fnCROSS(a,b)=Re(a)*Im(b)-Im(a)*Re(b) !擬似外積 a1*b2-a2*b1
!DEF fnDOT(a,b)=Re(a*conj(b)) !内積 a1*b1+a2*b2
!DEF fnCROSS(a,b)=Im(conj(a)*b) !擬似外積 a1*b2-a2*b1
!DEF fnDOT(a,b)=( a*conj(b) + conj(a)*b ) / 2 !内積 a1*b1+a2*b2

DEF fnANGLE(a,b)=ANGLE(Re(b/a),Im(b/a)) !なす角

DEF fnROTATE(a,th)=v(COS(th),SIN(th))*a !回転
! 複素数 cosΘ+i*sinΘ を行列表現すると
! ┌ cosΘ -sinΘ ┐
! └ sinΘ  cosΘ ┘


!問題 成分の計算 (-3,4)-(2,-1)=

PRINT v(-3,4)-v(2,-1)


!問題 成分の計算 -2(1,-2)=

PRINT (-2)*v(1,-2)


!問題 成分の計算 a=(1,1)、b=(1,-1)のとき、3(2a-b)-2(3a+b) ※a,bの上に→が付く

LET a=v(1,1)
LET b=v(1,-1)
PRINT 3*(2*a-b)-2*(3*a+b)


!問題 a=(√3,1)、b=(0,2)のとき、a、bのなす角 ※a,bの上に→が付く

LET a=v(SQR(3),1)
LET b=v(0,2)
PRINT DEG(ACOS( fnDOT(a,b)/(ABS(a)*ABS(b)) )); "°" !a・b=|a||b|cosΘより
PRINT DEG(ATN(fnCROSS(a,b)/fnDOT(a,b))); "°"
PRINT DEG(fnANGLE(a,b)); "°"


!問題 |a|=2、|b|=3、|a+b|=3のとき、a・b ※a,bの上に→が付く

LET absA=2
LET absB=3
LET absAB=3
PRINT (absAB^2-(absA^2+absB^2))/2 !|a+b|^2=|a|^2+2*a・b+|b|^2より


!問題 点(0,1)を反時計まわりに90°回転する

LET a=v(0,1)
PRINT fnROTATE(a,RAD(90))


!問題 支点がら左1mに15kg、右3mに10kgが載ったシーソーはどちらに傾くか(モーメント)

LET a=v(-1,0)
LET Fa=v(0,15*9.8)
LET b=v(3,0)
LET Fb=v(0,10*9.8)
PRINT fnCROSS(a,Fa)+fnCROSS(b,Fb) !正なら右


END

!投稿(記述例)、数学、ベクトル、複素数
 

POKE

 投稿者:めろん  投稿日:2009年12月24日(木)19時44分56秒
返信・引用
  POKEがつかいたいのですが使えない場合は何をつかえばいいんですか?  

Re: POKE

 投稿者:山中和義  投稿日:2009年12月24日(木)19時54分40秒
返信・引用
  > No.948[元記事へ]

めろんさんへのお返事です。

> POKEがつかいたいのですが使えない場合は何をつかえばいいんですか?

N88,MSX系のPEEK/POKE命令はありません。代替命令もありません。
 

Re: POKE

 投稿者:哲  投稿日:2009年12月25日(金)10時21分28秒
返信・引用
  > No.948[元記事へ]

めろんさんへのお返事です。

> POKEがつかいたいのですが使えない場合は何をつかえばいいんですか?
WindowsではPOKEのような直接メモリーに書き込むような命令を使用すると間違ってシステムを壊し暴走する恐れがあるのでこのような命令はありません。

どうしてもPOKEを使ったプログラムを実行したい場合は99BASICを使ってください。
99BASICではメモリーを確保してその領域、仮想領域内でPOKE命令を実行しますのでシステムを壊すことは無く安全です。
 

Re:Re:POKE

 投稿者:めろん  投稿日:2009年12月25日(金)13時14分53秒
返信・引用
  返信ありがとうございます!わかりました。  

3段構えの魔方陣は可能か?

 投稿者:GAI  投稿日:2009年12月28日(月)20時19分13秒
返信・引用
    5  22  18
 28  15   2
 12   8  25

はもちろん各行、各列、対角線が和45の魔方陣であるが

この数字の語を英語にして

   five      twenty-two   eighteen
twenty-eight  fifteen       two
  twelve       eight     twenty-five

と綴ればその文字数が
  4   9   8
 11   7   3
  6   5  10

となり、これがまた和21の魔方陣を構成している。

そこでもう一つ、更にこれを綴って第3の魔方陣が構成できるパターンが存在できるか知りたい。
何らかの検索で可能ですか?
 

正月用マジック

 投稿者:GAI  投稿日:2009年12月30日(水)09時28分57秒
返信・引用
  今年もあと僅か。もうすぐお正月です。
そこで、お正月に集まった時にできるマジックを一つ紹介します。

新品のカード(マーク毎に数字が揃っている状態)を相手に渡し、デックを大体2分して
2つのパケットでリフルシャッフルを3回させる。
その後デックをカット(適当な場所で上下の位置を交換する)させ、一番上にきたカードを覚えてもらい、このカードをデックの中程に差し込んでもらってから、返してもらう。
ここで数回デックをカットして客のカードの位置をわからなくしてもよい。
この状態からカードを当てる。




<客のカードの探し方>
客からデックを受け取り、
演者だけが表が見えるようにして持ち、赤のカードをアップジョグ(上に半分位上げる)
していき、順番を狂わさないようにして全て抜き取り後ろへ回す。
次に黒のカードの一方のマーク(例えばクラブ)と赤のカードの一方のマーク(例えばダイヤ)をアップジョグして全て抜き取り後ろへ回す。
(これでマーク毎にカードがかたまる)
同じマークの部分に着目し、Aから2,3,4、・・・と順番に見ていく。
右端まできたら、左端につなげて見ていく。
このとき、順番通りにカードが存在していたらそのマークのカードは違う。
AからKまでの順番が相対的に崩れていたら、崩れた部分のカードが客が見たカードになる。
あとは適当な演出でカードを出現させて下さい。

<原理>
リフルシャッフルは見た目は混ぜているように見えて実は相対的位置関係は以外に保存されていることを利用したものです。
乱数とは以外に厄介な代物であることを教えてくれます。
 

Re: 3段構えの魔方陣は可能か?

 投稿者:山中和義  投稿日:2009年12月30日(水)09時54分59秒
返信・引用  編集済
  > No.952[元記事へ]

GAIさんへのお返事です。

a,b,cは整数、M,A,B,Cは行列として「M+a*A+b*B+c*C による変形」で検索しました。
0〜999の数字を使った場合、重複を除いて存在しません。
しかも、提示された魔方陣が唯一重複なし2段階のものです。
!3×3魔方陣で3段階になるものを検索する

OPTION ARITHMETIC NATIVE !CPUパワー

DIM nm$(0 TO 19) !0〜19
DATA "Zero" !0
DATA "One" !1
DATA "Two" !2
DATA "Three" !3
DATA "Four" !4
DATA "Five" !5
DATA "Six" !6
DATA "Seven" !7
DATA "Eight" !8
DATA "Nine" !9
DATA "Ten" !10
DATA "Eleven" !11
DATA "Twelve" !12
DATA "Thirteen" !13
DATA "Fourteen" !14
DATA "Fifteen" !15
DATA "Sixteen" !16
DATA "Seventeen" !17
DATA "Eighteen" !18
DATA "Nineteen" !19
MAT READ nm$

DIM nm2$(2 TO 9) !20以上
DATA "Twenty" !20
DATA "Thirty" !30
DATA "Fourty" !40
DATA "Fifty" !50
DATA "Sixty" !60
DATA "Seventy" !70
DATA "Eigthy" !80
DATA "Ninety" !90
MAT READ nm2$

FUNCTION f(x) !数値を英語読みに変換する ※0〜999
   LET v=0
   IF x>=100 THEN LET v=LEN(nm$(INT(x/100))) + LEN("hundred") !百の位

   LET xx=MOD(x,100) !0〜99の部分
   IF xx<>0 THEN
      IF xx<20 THEN !0〜19なら
         LET v=v+LEN(nm$(xx))
      ELSE
         LET v=v+LEN(nm2$(INT(xx/10))) !十の位
         LET w=MOD(xx,10) !一の位
         IF w<>0 THEN LET v=v+LEN(nm$(w))
      END IF
   END IF
   LET f=v
END FUNCTION
!------------------------------


DIM M(9) !3×3基本形
!DATA 2,9,4 !合計は、15
!DATA 7,5,3
!DATA 6,1,8
!MAT READ M
MAT M=ZER

! M+a*A+b*B+c*C による変形 合計は、15+3*a となる。

DIM A(9)
DATA +1,+1,+1
DATA +1,+1,+1
DATA +1,+1,+1
MAT READ A

DIM B(9)
DATA  0,-1,+1
DATA +1, 0,-1
DATA -1,+1, 0
MAT READ B

DIM C(9) !※Bを90°回転
DATA +1,-1, 0
DATA -1, 0,+1
DATA  0,+1,-1
MAT READ C

LET cTRUE=-1 !真
LET cFALSE=0 !偽

FUNCTION CheckRange(T()) !1〜999
   LET CheckRange=cFALSE
   FOR i=1 TO 9
      IF T(i)<0 OR T(i)>999 THEN EXIT FUNCTION
   NEXT i
   LET CheckRange=cTRUE
END FUNCTION
FUNCTION CheckUnique(T()) !同じ数字かどうか
   LET CheckUnique=cFALSE
   FOR i=1 TO 8
      FOR j=i+1 TO 9
         IF T(i)=T(j) THEN EXIT FUNCTION
      NEXT j
   NEXT i
   LET CheckUnique=cTRUE
END FUNCTION
FUNCTION CheckSum(T()) !合計
   LET CheckSum=cFALSE
   LET v=3*T(5)
   IF v<>T(1)+T(2)+T(3) THEN EXIT FUNCTION !横
   IF v<>T(4)+T(5)+T(6) THEN EXIT FUNCTION
   IF v<>T(7)+T(8)+T(9) THEN EXIT FUNCTION

   IF v<>T(1)+T(4)+T(7) THEN EXIT FUNCTION !縦
   IF v<>T(2)+T(5)+T(8) THEN EXIT FUNCTION
   IF v<>T(3)+T(6)+T(9) THEN EXIT FUNCTION

   IF v<>T(1)+T(5)+T(9) THEN EXIT FUNCTION !斜め
   IF v<>T(3)+T(5)+T(7) THEN EXIT FUNCTION
   LET CheckSum=cTRUE
END FUNCTION
!------------------------------


DIM T(9),TT(9)
!FOR aa=111 TO 0 STEP -1
FOR aa=0 TO 111 !※
   DIM Ta(9)
   MAT TT=aa*A
   MAT Ta=M+TT
   PRINT "合計=";3*M(5)+3*aa; aa

   FOR bb=0-Ta(8) TO 999-Ta(8) !※
      DIM Tb(9)
      MAT TT=bb*B
      MAT Tb=Ta+TT

      FOR cc=0-Ta(8) TO 999-Ta(8) !※
         MAT TT=cc*C
         MAT T=Tb+TT !1段階目

         !IF CheckRange(T)=cTRUE AND CheckUnique(T)=cTRUE THEN !重複なし
         IF CheckRange(T)=cTRUE THEN !重複あり
            DIM T1(9)
            MAT T1=T !save it

            FOR i=1 TO 9 !2段階目
               LET T(i)=f(T(i))
            NEXT i
            !IF CheckUnique(T)=cTRUE AND CheckSum(T)=cTRUE THEN
            IF CheckSum(T)=cTRUE THEN
               DIM T2(9)
               MAT T2=T !save it
               !!!MAT PRINT T; !debug

               FOR i=1 TO 9 !3段階目
                  LET T(i)=f(T(i))
               NEXT i
               !IF CheckUnique(T)=cTRUE AND CheckSum(T)=cTRUE THEN
               IF CheckSum(T)=cTRUE THEN

                  MAT PRINT T1;T2;T; !魔方陣を表示する
                  PRINT

               END IF
            END IF
         END IF

      NEXT cc
   NEXT bb
NEXT aa


END
 

合成パズル

 投稿者:GAI  投稿日:2009年12月31日(木)10時35分43秒
返信・引用
  3段とは、そう上手くいくことはありえなく不可能なんですね。
自分でなんとかプログラムを作ろうとあれこれやるんですが、全ての知識の欠如を思い知るだけで、全く歯が立ちません。

以前の散歩コースのルート探しと、文字数での魔方陣構成を上手く組み合わせたもので
次の構成作品を目にしましたので紹介します。

TFOURTEEN
H       F
I       I
R       F
T       T   OTWO
E       E   N  T
E       E   E  H
N       NZERO  R
TWELVEE        E
      L    FOURE
      E    F
      V    I
      E    V
      N SIXE
   NTEN S
   I    E
   N    V
   E    E
   EIGHTN


(16辺が0〜15までの数詞によって決定されたポリオミノ)
凄いの一言です。
 

創作パズルに必要

 投稿者:GAI  投稿日:2009年12月31日(木)11時40分17秒
返信・引用
  n個の異なる数字を全て使って並べてn桁の整数を作り、小さい順に並べたとする時、
一般にk番目に並ぶ順列が何になるかや、
逆に指定の整数が何番目に並んでいるかを計算するためにfactorial base(factoradic?)
と言う表記法が有効であると読んだ。
例:47=1*4!+3*3!+2*2!+1*1!
これより47の表記を
1(4)3(3)2(2)1(1)
などと表すことにする。

n: f(n)
0  0
1  1
2  10
3  11
4  20
5  21
6  100
7  101
8  110
9  111
10 120
11 121
12 200
13 201
14 210
15 211
16 220
17 221
18 300
19 301
20 310
21 311
22 320
23 321
24 1000
・・・・
などなど

n(少なくとも10桁でも可能であるようにしてもらいたい。)
を入力したら、そのfactoradicでの表記が出力されるようにお願いしたい。
よろしくお願いします。
 

Re: 創作パズルに必要

 投稿者:山中和義  投稿日:2009年12月31日(木)12時07分7秒
返信・引用
  > No.956[元記事へ]

GAIさんへのお返事です。

No.721[元記事へ] の手続き Num2Factoradic、Factoradic2Num を参照のこと。

配列A()は、 1(4!),3(3!),2(2!),1(1!),0(0!) の順で表示されます。
 

Re: 合成パズル

 投稿者:山中和義  投稿日:2009年12月31日(木)16時06分15秒
返信・引用  編集済
  > No.955[元記事へ]

GAIさんへのお返事です。

かなり答えがあるようです。検証はO(2^n)ですから、24あたりが妥当かと、、、

F2$(x)を使ったものは、前回の「数値の数だけ進む」の交差判定を含んだ回答となります。
(F$(x)を使った4箇所のコメントを入れ替える)
!散歩コースの探索

DECLARE EXTERNAL FUNCTION F.F$ !外部関数の宣言
DECLARE EXTERNAL FUNCTION F2$ !外部関数の宣言

LET t0=TIME

PUBLIC NUMERIC ANSWER_COUNT !解答数
LET ANSWER_COUNT=0

PUBLIC NUMERIC N !歩数
LET N=16

PUBLIC NUMERIC M !マップの大きさ
LET M1=0
LET M2=0
FOR i=0 TO N !※2+4+6+ … +(N-2)+Nより大きく
   LET t=LEN(F$(i)) !歩数
   !!!LET t=LEN(F2$(i)) !歩数 ←←←←←
   IF MOD(i,2)=1 THEN
      LET M1=M1+t
   ELSE
      LET M2=M2+t
   END IF
NEXT i
LET M=MAX(M1,M2)
PRINT M;M1;M2

DIM map(-M TO M,-M TO M) !散歩したコース(足跡)
MAT map=(ORD("."))*CON !未踏

LET x=0 !現在位置
LET y=0

!※1歩目と2歩目を固定して、回転と鏡面を排除する
CALL walk(F$(0),map,0,x,y, ok) !1歩目は東へ ※0:東、1:北、2:西、3:南
!!!CALL walk(F2$(1),map,0,x,y, ok) !1歩目は東へ ※0:東、1:北、2:西、3:南 ←←←←←

LET d=MOD(0-1,4) !進行方向
CALL walk(F$(1),map,d,x,y, ok) !2歩目は北へ
!!!CALL walk(F2$(2),map,d,x,y, ok) !2歩目は北へ ←←←←←


CALL search(3,map,d,x,y) !3歩目以降

IF ANSWER_COUNT=0 THEN PRINT "解答なし"

PRINT "計算時間=";time-t0

END


EXTERNAL SUB walk(s$,map(,),d,x,y, ok) !コースに足跡を残す
LET ok=0

LET L=LEN(s$)
SELECT CASE d !進行方向に応じて
CASE 0 !E
   FOR i=1 TO L
      IF map(y,x+i)<>ORD(".") THEN EXIT SUB !未踏以外なら
      LET map(y,x+i)=ORD(s$(i:i))
   NEXT i
   LET x=x+L !移動先
CASE 1 !N
   FOR i=1 TO L
      IF map(y+i,x)<>ORD(".") THEN EXIT SUB !未踏以外なら
      LET map(y+i,x)=ORD(s$(i:i))
   NEXT i
   LET y=y+L !移動先
CASE 2 !W
   LET x=x-L !移動先 ※予め先に
   FOR i=1 TO L
      IF map(y,x+i-1)<>ORD(".") THEN EXIT SUB !未踏以外なら
      LET map(y,x+i-1)=ORD(s$(i:i))
   NEXT i
CASE 3 !S
   LET y=y-L !移動先 ※予め先に
   FOR i=1 TO L
      IF map(y+i-1,x)<>ORD(".") THEN EXIT SUB !未踏以外なら
      LET map(y+i-1,x)=ORD(s$(i:i))
   NEXT i
CASE ELSE
END SELECT

LET ok=1 !成功
END SUB


EXTERNAL SUB search(s,map(,),d,x,y) !バックトラックで検索する
DECLARE EXTERNAL FUNCTION F.F$ !外部関数の宣言
DECLARE EXTERNAL FUNCTION F2$ !外部関数の宣言

LET s$=F$(s-1) !歩数を算出する
!!!LET s$=F2$(s) !歩数を算出する ←←←←←

LET L=LEN(s$)
DIM mmm(-L TO L) !save map
IF MOD(s,2)=0 THEN
   FOR i=-L TO L !1列分のみ(メモリ使用の節約)
      LET mmm(i)=map(y+i,x)
   NEXT i
ELSE
   FOR i=-L TO L !1行分のみ
      LET mmm(i)=map(y,x+i)
   NEXT i
END IF

FOR k=-1 TO 1 STEP 2 !右と左のみ
   LET dd=MOD(d+k,4) !1つ前を基準にして、s歩目の方向を決める

   LET xx=x
   LET yy=y
   CALL walk(s$,map,dd,xx,yy, ok) !s歩目の移動
   IF ok=1 THEN

      IF s=N THEN !指定の歩数に達したら
         IF xx=0 AND yy=0 THEN !元の位置に戻ったら

            LET ANSWER_COUNT=ANSWER_COUNT+1 !解答数
            PRINT ANSWER_COUNT

            FOR i=-M TO M !コースを表示する
               LET t$=""
               FOR j=-M TO M
                  LET t$=t$ & CHR$(map(i,j))
               NEXT j
               PRINT t$ !1行分をまとめて出力する(高速)
            NEXT i
            PRINT

         END IF
      ELSE
         CALL search(s+1,map,dd,xx,yy) !次へ
      END IF

   END IF


   IF MOD(s,2)=0 THEN !restore map
      FOR i=-L TO L
         LET map(y+i,x)=mmm(i)
      NEXT i
   ELSE
      FOR i=-L TO L
         LET map(y,x+i)=mmm(i)
      NEXT i
   END IF
NEXT k

END SUB


MODULE F !英語読みに変換する
SHARE STRING nm$(0 TO 19) !0〜19
DATA "Zero" !0
DATA "One" !1
DATA "Two" !2
DATA "Three" !3
DATA "Four" !4
DATA "Five" !5
DATA "Six" !6
DATA "Seven" !7
DATA "Eight" !8
DATA "Nine" !9
DATA "Ten" !10
DATA "Eleven" !11
DATA "Twelve" !12
DATA "Thirteen" !13
DATA "Fourteen" !14
DATA "Fifteen" !15
DATA "Sixteen" !16
DATA "Seventeen" !17
DATA "Eighteen" !18
DATA "Nineteen" !19
MAT READ nm$

SHARE STRING nm2$(2 TO 9) !20以上
DATA "Twenty" !20
DATA "Thirty" !30
DATA "Fourty" !40
DATA "Fifty" !50
DATA "Sixty" !60
DATA "Seventy" !70
DATA "Eigthy" !80
DATA "Ninety" !90
MAT READ nm2$

PUBLIC FUNCTION F$
EXTERNAL FUNCTION F$(x) !数値を英語読みに変換する ※0〜99
   IF x<20 THEN !0〜19なら
      LET v$=v$ & nm$(x)
   ELSE
      LET v$=v$ & nm2$(INT(x/10)) !十の位
      LET w=MOD(x,10) !一の位
      IF w<>0 THEN LET v$=v$ & "-" & nm$(w)
   END IF
   LET F$=v$
END FUNCTION
END MODULE


EXTERNAL FUNCTION F2$(x) !数値の長さ
LET F2$=REPEAT$(mid$("123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",x,1),x)
END FUNCTION


!回答、情報、アルゴリズム、パズル
 

新年のご挨拶

 投稿者:GAI  投稿日:2010年 1月 1日(金)07時37分59秒
返信・引用
  明けまして、おめでとうございます。
新年を迎え、皆様方と共に今年が良き年でありますように願いたいと思います。

さっそくではありますが、ここによくこられる方々は、貴重なコミュケーションの宝庫であります。
そこで、皆様を”刎頚の仲”と呼ばせていただいて、次の創作パズルに挑戦していただきたくご案内いたします。

刎頚の仲(フンケイノナカ)
の7文字”ふ”、”ん”、”け”、”い”、”の”、”な”、”か”
を並び替えて単語を作りました。
これを全て作り出し、辞書式に並べた時、今年(2010年)に当たる
2010番目に来る単語は何でしょう?

これを是非漢字に変換され返信されたし。


正解者多数の場合は先着1名様に、豪華景品(この7文字で作る品物)を差し上げます。

<研究熱心な方に>
0、1,2,3,4,5,6,7,8,9
から作られる全ての順列(3628800通り)を小さいほうから並べていった時
1417386番目にくる順列の並びは何になりますか?
実はこの並びを持つ整数はある特別な性質を持ちます。
可能な限りその特徴を発見して下さい。

また、その並びを見つけ出すために有効となるアイデアや計算手順をお聞かせ下さい。
 

Re: 新年のご挨拶

 投稿者:山中和義  投稿日:2010年 1月 1日(金)14時22分5秒
返信・引用
  > No.959[元記事へ]

GAIさんへのお返事です。

> 0、1,2,3,4,5,6,7,8,9
> から作られる全ての順列(3628800通り)を小さいほうから並べていった時
> 1417386番目にくる順列の並びは何になりますか?

3,912,657,840

・0から9までの数字を一度ずつ使っている
  ⇒ すべての順列(10!通り)を生成する
・0を除く全ての一桁の数(1,2,3,4,5,6,7,8,9)で割り切れる
  ⇒ 2^3*3^2*5*7の倍数
・この数に含まれる隣り合う二桁の数(39、91、12、26など)で割り切れる
  ⇒ ?
・この数(数列)にまだ名前がない(円周率、〜の定数など)


また9桁(0〜8)の場合、384,572,160 と 728,451,360 があります。
 

新年の驚き

 投稿者:GAI  投稿日:2010年 1月 1日(金)15時21分45秒
返信・引用  編集済
  > No.960[元記事へ]

山中和義さんへのお返事です。

.................................
............TenN.................
............E..i.................
............l..n.................
............e..e.................
............v..EightS............
............e.......e............
............nTwelve.v............
..................T.e............
..................h.n............
..................i.SixF.........
..................r....i.........
..................t....v.........
..................e....e.........
..................e....FourT.....
..................nFourteenh.....
..........................Fr.....
..........................ie.....
..........................fe.....
..........................tTwoO..
..........................e...n..
..........................e...e..
..........................nZero..
.................................


...................................
.................TenN..............
.................E..i..............
.................l..n..............
.................e..e..............
.................v..EightS.........
.................e.......e.........
...........Twelven.......v.........
...........T.............e.........
...........h.............n.........
...........i..........FSix.........
...........r..........i............
...........t..........v............
...........e..........e............
...........e..........FourT........
...........nFourteen......h........
...................F......r........
...................i......e........
...................f......e........
...................t...OTwo........
...................e...n...........
...................e...e...........
...................nZero...........
...................................


.....................................
.....................................
.........FourteenT...................
.........F.......h...................
.........i.......i...................
.........f.......r...................
.........t...OTwot...................
.........e...n..Te...................
.........e...e..he...................
.........nZero..rn...................
................eTwelveE.............
............Foure......l.............
............F..........e.............
............i..........v.............
............v..........e.............
............eSix.......n.............
...............S....NTen.............
...............e....i................
...............v....n................
...............e....e................
...............nEight................
.....................................


............................
.......TFourteen............
.......h.......F............
.......i.......i............
.......r.......f............
.......t.......t...OTwo.....
.......e.......e...n..T.....
.......e.......e...e..h.....
.......n.......nZero..r.....
.......TwelveE........e.....
.............l....Foure.....
.............e....F.........
.............v....i.........
.............e....v.........
.............n....eSix......
.............TenN....S......
................i....e......
................n....v......
................e....e......
................Eightn......
............................



..............................
...........TFourteen..........
...........h.......F..........
...........r.......f..........
...........t.......t...OTwo...
...........e.......e...n..T...
...........e.......e...e..h...
...........n.......nZero..r...
...........TwelveE........e...
.................l....Foure...
.................e....F.......
.................v....i.......
.................e....v.......
.................n.Sixe.......
..............NTen.S..........
..............i....e..........
..............n....v..........
..............e....e..........
..............Eightn..........
..............................



.........................................................
..................................555554.................
..................................6....4.................
..................................6....4.................
..................................6....4.................
..................................6.2333.................
..................................6.2....................
...........................77777776G1....................
...........................8.......G.....................
...........................8.......G.....................
...........................8.......G.....................
...........................8.......G.....................
...........................8.......G.....................
...........................8.......G.....................
...........................8.......G.....................
..................9999999998.......G.....................
..................A................G.....................
..................A................G.....................
..................A................G.....................
..................A................G.....................
..................A................G.....................
..................A................G.....................
..................A................G.....................
..................A.EFFFFFFFFFFFFFFF.....................
..................A.E....................................
.......BBBBBBBBBBBA.E....................................
.......C............E....................................
.......C............E....................................
.......C............E....................................
.......C............E....................................
.......C............E....................................
.......C............E....................................
.......C............E....................................
.......C............E....................................
.......C............E....................................
.......C............E....................................
.......C............E....................................
.......CDDDDDDDDDDDDD....................................
.........................................................


などなど


> ・0を除く全ての一桁の数(1,2,3,4,5,6,7,8,9)で割り切れる
>   ⇒ 2^3*3^2*5*7の倍数
はーそうか!!!

> ・この数に含まれる隣り合う二桁の数(39、91、12、26など)で割り切れる
よくこれに気づきましたねー

> また9桁(0〜8)の場合、384,572,160 と 728,451,360 があります。
なんと新たな発見

>この数(数列)にまだ名前がない(円周率、〜の定数など
ヌード小町ではどうでしょう。


山中さん凄いの一言です。
 

Re: 散歩コースの探索願い

 投稿者:山中和義  投稿日:2010年 1月 4日(月)12時29分28秒
返信・引用
  > No.902[元記事へ]

90°の連結等角多角形(ポリオミノ)による閉路

●閉路の候補
東西(奇数)、南北(偶数)の移動に分けて考えると、それぞれの合計が0になるものである。
この組み合わせ(積)の中で、交差するものを除いたものが求めるもの(答え)である。
 位数 奇数 偶数     積 答え
   7   1   1      1   1
   8   1   1      1   1
  15   4   4      16   1
  16   4   7     28   3
  23  34  35    1190  25
  24  34  62    2108  67
  :(この範囲は未確認)
  32  346  657   227322  ?
  :(未確認)
  40 3965 7636  30276740  ?
  :(未確認)
  48 48396 93846 4541771016  ?
  :(未確認)

先のプログラム(No.958[元記事へ])では、交差判定による枝刈りを行っているが、N=32は相当時間がかかる。
上記のように処理すると、32や40が計算可能になる。


●候補の個数(、符号パターン)を求めるプログラム
LET t0=TIME

LET N=24 !位数

LET w=INT((N-1)/2)+1 !概算
DIM A(w) !1〜nまでの奇数列、偶数列

LET m=0
FOR i=1 TO N
   IF MOD(i,2)=1 THEN !奇数なら
   !IF MOD(i,2)=0 THEN !偶数なら ←←←←←
      LET m=m+1
      LET A(m)=i
   END IF
NEXT i
redim A(m)


LET ANSWER_COUNT=0

DIM B(m)
FOR i=0 TO 2^(m-1)-1 !ビットパターンで検証する ※MSB=0
   MAT B=CON
   LET t$=right$(REPEAT$("0",m)&BSTR$(i,2),m) !m桁
   FOR k=1 TO LEN(t$)
      IF t$(k:k)="1" THEN LET B(k)=-1 !0:1、1:-1へ
   NEXT k

   IF DOT(A,B)=0 THEN !±1*1 + ±1*3 + … + ±1*(2*m+1)を計算する
      LET ANSWER_COUNT=ANSWER_COUNT+1
      !!!PRINT "DATA ";CHR$(34);t$;CHR$(34)
   END IF
NEXT i

PRINT "個数=";ANSWER_COUNT !奇数の個数
PRINT


PRINT "計算時間=";TIME-t0

END
 

偶然は必然か?

 投稿者:GAI  投稿日:2010年 1月 4日(月)15時48分55秒
返信・引用  編集済
  円周率
π=3.1415926535 8979323846 2643383279・・・・

を数字の順番に
1:3
2:1
3:4
4:1
5:5
6:9
7:2
8:6
9:5
10:3
11:5
12:8
13:9
14:7
15:9
16:3
17:2
18:3
19:8
20:4
21:6
22:2
23:6
24:4
25:3
....
としておく。


ここに魔方陣(各和65)
  17      24        1         8        15
  23       5        7        14        16
   4       6       13        20        22
  10      12       19        21         3
  11      18       25         2         9

の数字をπでの数字へ変換してみると
   2        4        3         6         9・・・24
   6        5        2         7         3・・・23
   1        9        9         4         2・・・25
   3        8        8         6         4・・・29
   5        3        3         1         5・・・17
   ・       ・       ・        ・     ・
   ・       ・       ・    ・     ・
   ・       ・       ・    ・     ・
   17       29       25        24        23

こんな偶然ってあり?
 

散歩コースの探索の結果

 投稿者:GAI  投稿日:2010年 1月 5日(火)06時04分40秒
返信・引用
  > No.962[元記事へ]

山中和義さんへのお返事です。


位数24の全パターンを正月3日間動かし続けて探し出しました。
次の32に挑戦しようとしましたが、この時間の必要を思うと途方に暮れていました。
なお位数7、15などのパターンは各辺の長さが1,2,3、・・・
という訳にはいかないので(例えば位数7では出発点と到着点が一直線になるのでここの
ルートの長さが8とみれるので、これは除外することにしましょう。)

>    7   1   1      1   1
>    8   1   1      1   1
>   15   4   4      16   1
>   16   4   7     28   3
>   23  34  35    1190  25
>   24  34  62    2108  67
>   :(この範囲は未確認)
>   32  346  657   227322  ?  →→→→1259
>   40 3965 7636  30276740  ?  →→→→41381
>   48 48396 93846 4541771016  ?  →→→→1651922
 

プログラムの負荷を減らす

 投稿者:SECOND  投稿日:2010年 1月 7日(木)12時02分56秒
返信・引用
  > No.940[元記事へ]

! プログラムの負荷を減らすと、
!同じN角バウンド・ボールであるが、軽くなった余白で、
!動作中のN角数 変更が、できるようになった。
!左クリックで、1角づつ、3〜15角( 適当に )何時でも変えられる。
!左クリック押し続けると、早送り。
!--------------------------------------

LET m_=15                      !最大角数
LET ma=3                       !開始角数
LET m0=.23                     !ボールの速さ��
DIM x(m_+1),y(m_+1),A(m_+1),ox(m_+1),oy(m_+1)
SET WINDOW -7,7, -7,7
SET DRAW MODE NOTXOR           !2度書きで消える NOTXOR モード
LET r=0.7                      !ボールの半径
LET r0=5.5                     !計算で使用の 多角形、外接円の半径
DO
   CLEAR
   DRAW axes
   LET r1=r0+r/SIN(PI/2-PI/ma) !ボールの当る 多角形、外接円の半径
   LET a0=PI*(1.5-1/ma)        !(x1,y1)の角。
   FOR i=1 TO ma+1
      LET x(i)=r0*COS(a0)
      LET y(i)=r0*SIN(a0)
      IF 1< i THEN
         SET LINE COLOR "silver"
         PLOT LINES: x(i-1),y(i-1); x(i),y(i) !計算外壁
         SET LINE COLOR "black"
         PLOT LINES: r1/r0*x(i-1),r1/r0*y(i-1); r1/r0*x(i),r1/r0*y(i) !ボール外壁
      END IF
      LET a0=a0+2*PI/ma
   NEXT i
   !                      A3         A4  4  A3
   !       3          4──3      5/  \3
   !  A3 /  \ A2   A4│    │A2   A5\    /A2   ・・・
   !   1───2      1──2        1─2
   !       A1             A1             A1
   !
   FOR i=1 TO ma
      LET A(i)=(y(i+1)-y(i))/(x(i+1)-x(i))   !直線i~i+1 の勾配
      LET oy(i)= (x(i+1)-x(i))/SQR((y(i+1)-y(i))^2+(x(i+1)-x(i))^2)
      LET ox(i)=-(y(i+1)-y(i))/SQR((y(i+1)-y(i))^2+(x(i+1)-x(i))^2)
   NEXT i                   !直線i~i+1 に垂直な単位ベクトル(左回転)
   CALL play00
   LET ma=MOD(ma-2,m_-2)+3  !次々角数 3,4,5,6,,,3,4,,
LOOP UNTIL 0< mrb

SUB play00
   PLOT TEXT,AT -6.7, 6.4: "左クリック:角数の選択= "& STR$(ma)
   PLOT TEXT,AT  3.2, 6.4: "右クリック:停止"
   LET i=ANGLE(x(2)-x(1),y(2)-y(1))+SQR(2)*PI/ma/1.1313 !ボールの初期角度
   LET mx=m0*COS(i)                                     !ボールの初期��X
   LET my=m0*SIN(i)                                     !ボールの初期��Y
   LET i=ANGLE(x(1),y(1))
   LET bx=r0*COS(i)*0.999  !ボールの初期位置X
   LET by=r0*SIN(i)*0.999  !ボールの初期位置Y
   LET nb=0
   DO
      DRAW disk WITH SCALE(r)*SHIFT(bx,by) !ボールを書く
      WAIT DELAY 0.02                      ! 省電力効果と、速度
      DRAW disk WITH SCALE(r)*SHIFT(bx,by) !ボールだけを消す
      PLOT LINES : bx,by;                  ! 履歴線を(書く・消す)
      LET bx=bx+mx
      LET by=by+my
      FOR n=1 TO ma
         IF n<>nb THEN
            CALL Sensor                    ! 辺の内外検出と反射(同じ辺の呼出抑制)
            IF n=nb THEN EXIT FOR
         END IF
      NEXT n
      IF mlbk=0 OR mlb=0 THEN LET mlbk=2*mlb ELSE LET mlbk=mlbk-1.001/13
      MOUSE POLL mox,moy,mlb,mrb
   LOOP UNTIL 0< mrb OR  mlbk< mlb         !左クリックは、Leading Edge 検出
   PLOT LINES                              !do〜loop13 回でオートリピートへ入る
END SUB

SUB Sensor
   IF ABS(A(n))< 1 THEN  !境界勾配1
      LET xc=(x(n)*A(n)-y(n)-bx*my/mx+by)/(A(n)-my/mx)   !交点 xc 優先< 45°
      LET yc=(xc-x(n))*A(n)+y(n)
      IF SGN(yc-by)<>SGN(my) AND SGN(x(n)-xc)<>SGN(x(n+1)-xc) THEN CALL Mirror
   ELSE
      LET yc=(y(n)/A(n)-x(n)-by*mx/my+bx)/(1/A(n)-mx/my) !交点 yc 優先 >=45°
      LET xc=(yc-y(n))/A(n)+x(n)
      IF SGN(xc-bx)<>SGN(mx) AND SGN(y(n)-yc)<>SGN(y(n+1)-yc) THEN CALL Mirror
   END IF
END SUB

SUB Mirror
   LET i=mx*ox(n)+my*oy(n) !ox,oy: 辺に垂直で内向き 単位vector
   IF 0<=i THEN EXIT SUB   !後向きの交点
   LET mx=mx-2*i*ox(n)
   LET my=my-2*i*oy(n)     !反射速度
   LET bx=xc
   LET by=yc
   LET nb=n                !反射辺 履歴
END SUB

END
 

お願いです!

 投稿者:angel  投稿日:2010年 1月 8日(金)10時21分15秒
返信・引用
  十進basicを使ってn以下の素数の数を数えるプログラムを作りたいのですが、どのように作成したらよろしいでしょうか?
全くの初心者なので分かりません。
よろしくお願いします。
 

Re: お願いです!

 投稿者:白石 和夫  投稿日:2010年 1月 8日(金)10時53分17秒
返信・引用
  > No.966[元記事へ]

エラトステネスの篩のプログラムを少し修正すれば可能です。
エラトステネスの篩は,サンプルプログラム
MATH\ERATOS.BAS
として収録しています。
具体的にいえば,配列s中の1の個数を添字がn以下の範囲で数えるだけです。
ただし,配列sの大きさは入力を予定するnより大きくとっておく必要があります。
 

グラフ の一部の文字の大きさ

 投稿者:大熊 正  投稿日:2010年 1月 8日(金)16時03分11秒
返信・引用
  グラフに文字を入れてるのですが、現在、下記の インパルス応答  の文字含めソフトの英文字は12の大きさです。
 PLOT TEXT,   AT  3,0.4,USING "a=#.# k=#.# ": A,k
  PLOT TEXT,   AT  2,0.8:"インパルス応答 "

グラフの文字"A,k"の大きさは12で、この"インパルス応答"の文字だけグラフ上のみ18の大きさで、かつ太文字にする方法を御教え下さい。単純に フォントをいじって18にするとソフトの英語文字が18になってしまい、一方グラフの方は両方とも12と変りません。ソフトやグラフの文字"A,k"の大 きさは12でこの"インパルス応答"の文字の部分だけ、グラフ上のみ18の大さと太い文字にしたいのです。

以上
 

Re: グラフ の一部の文字の大きさ

 投稿者:白石 和夫  投稿日:2010年 1月 8日(金)16時09分1秒
返信・引用
  > No.968[元記事へ]

SET TEXT FONT "Courier New",12
PLOT TEXT,   AT  3,0.4,USING "a=#.#  k=#.# ": A,k
SET TEXT FONT "MS ゴシック",18
PLOT TEXT,   AT  2,0.8:"インパルス応答 "
みたいな感じでどうでしょうか。
 

Re: お願いです!

 投稿者:山中和義  投稿日:2010年 1月 8日(金)19時51分35秒
返信・引用
  > No.966[元記事へ]

angelさんへのお返事です。
100 LET N=100
110 LET c=0
120 FOR i=2 TO N
130    FOR k=2 TO i-1 !約数を確認する
140       IF MOD(i,k)=0 THEN GOTO 170 !ひとつでも割り切れるなら、素数でない
150    NEXT k
160    LET c=c+1 !素数
170 NEXT i
180 PRINT c !結果を表示する
190 END
 

Re: グラフ の一部の文字の大きさ

 投稿者:山中和義  投稿日:2010年 1月 9日(土)11時46分59秒
返信・引用  編集済
  > No.968[元記事へ]

大熊 正さんへのお返事です。


書体に太字(Bold)や斜体(Italic)がある場合
SET TEXT font "Courier New Bold Italic",24
PLOT TEXT ,AT 0.3,0.2: "ABCabc"

とすると、きれいな文字が描けると思います。


通常の書体には、「標準」文字しか用意されていないため、システムでは
PLOT TEXT ,AT 0.1,0.8: "ABCabcあいう漢字" !元の書体と大きさ

DRAW PlotText("MS 明朝","",24,"ABCabcあいう漢字") WITH SHIFT(0.1,0.7)
DRAW PlotText("MS 明朝","太字",0,"ABCabcあいう漢字") WITH SHIFT(0.1,0.6)
DRAW PlotText("","斜体",0,"ABCabcあいう漢字") WITH SHIFT(0.1,0.5)
DRAW PlotText("MS 明朝","太字 斜体",24,"ABCabcあいう漢字") WITH SHIFT(0.1,0.4)

END

EXTERNAL PICTURE PlotText(f$,a$,s,s$) !原点を基準に、太字(Bold)や斜体(Italic)で文字を描く
IF f$<>"" OR s<>0 THEN SET TEXT font f$,s

IF POS(a$,"斜体")>0 THEN LET a=0.5 ELSE LET a=0
DRAW TEXT(s$) WITH SHEAR(a)

LET dx=worldx(pixelx(0)+1) !1ドットずらす
LET dy=worldy(pixely(0)+1)
IF POS(a$,"太字")>0 THEN DRAW TEXT(s$) WITH SHEAR(a)*SHIFT(dx,0)
!IF POS(a$,"太字")>0 THEN DRAW TEXT(s$) WITH SHEAR(a)*SHIFT(0,dy) !※必要に応じて
!IF POS(a$,"太字")>0 THEN DRAW TEXT(s$) WITH SHEAR(a)*SHIFT(dx,dy) !※必要に応じて
END PICTURE

EXTERNAL PICTURE TEXT(s$) !原点を基準に文字を描く
PLOT TEXT ,AT 0,0: s$
END PICTURE

と文字の射影変換を使って表示できます。高速描画には向きません。
 

Re: グラフ の一部の文字の大きさ

 投稿者:大熊 正  投稿日:2010年 1月 9日(土)15時42分29秒
返信・引用
  > No.971[元記事へ]

白石先生 山中様

有難うございます。
 

SET COLOR MIX

 投稿者:SECOND  投稿日:2010年 1月12日(火)07時12分30秒
返信・引用  編集済
  SET COLOR MIX(3) 0, .5, 0 !3緑→暗緑(明度50% 10:濃い緑と同色に。)

SET AREA COLOR "red"
SET AREA COLOR "GREEN" !set color mix(3) で、GREEN が 無効になります。
PLOT AREA:0,0;.5,0;.5,.5;0,.5

SET AREA COLOR 3
PLOT AREA:1,1;.5,1;.5,.5;1,.5

END
 

Re: SET COLOR MIX

 投稿者:白石 和夫  投稿日:2010年 1月12日(火)08時06分1秒
返信・引用
  > No.973[元記事へ]

SET AREA COLOR "GREEN"
を実行すると256個の色指標のなから指定された色を探します。
存在しないときは,何もしません。
 

Re: SET COLOR MIX

 投稿者:SECOND  投稿日:2010年 1月12日(火)08時11分13秒
返信・引用
  > No.974[元記事へ]

わかりました。色指標3のシンボルだと思っていました。
 

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2010年 1月20日(水)09時55分16秒
返信・引用
  > No.947[元記事へ]

前回に続きベクトルの計算をなるべく数学表記に近いように行います。
さあ、このシリーズ、2年目のスタートです!
!平面上のベクトル方程式とそのグラフ

OPTION ARITHMETIC COMPLEX

DEF v(a,b)=COMPLEX(a,b) !複素数の和差、実数倍の計算を対応させる

DEF fnDOT(a,b)=( a*conj(b) + conj(a)*b ) / 2 !内積 a1*b1+a2*b2
!絶対値 ベクトル |a|^2=a・a  複素数 |z|^2=z*conj(z)


SET WINDOW -8,8,-8,8 !表示領域を設定する
DRAW grid !XY座標
ASK PIXEL SIZE (-8,-8; 8,8) w,h !画像の縦横の大きさ(ドット単位)を調べる

LET cEps=0.1 !精度 ※調整が必要である

SET POINT STYLE 1 !点の形状


!例 点A(1,0)を通り、方向ベクトル(2,3)である直線の方程式を求めよ。
!参考 複素数による表現
! 点A(α=a+b*i)、d(β=c+d*i)とすると
! conj(β)*z-β*conj(z)=conj(β)*α-β*conj(α)

LET OA=v(1,0)
LET d=v(2,3)

FOR t=-3 TO 3 !t=[-∞,∞] ※範囲は調整が必要である
   LET OP=OA+t*d !(x,y)=(1,0)+t*(2,3)=(1+2*t,3*t)
   PLOT LINES: Re(OP),Im(OP);
NEXT t
PLOT LINES


!例 2点A(2,5)、B(-1,3)を結ぶ線分ABの方程式を求めよ。
!参考 複素数による表現
! 点A(α=a+b*i)、点B(β=c+d*i)とすると、直線ABは
! (conj(β)-conj(α))*z+(β-α)*conj(z)=conj(β)*α-β*conj(α)

LET OA=v(2,5)
LET OB=v(-1,3)

FOR t=0 TO 1 !t=[0,1]
   LET OP=(1-t)*OA+t*OB !(x,y)=(1-t)*(2,5)+t*(-1,3)
   PLOT LINES: Re(OP),Im(OP);
NEXT t
PLOT LINES


!例 点A(2,5)、ベクトルn=(4,3)に垂直な直線の方程式を求めよ。(内積を用いた表現)
!参考 複素数による表現
! 点A(α=a+b*i)、n(β=c+d*i)とすると
! conj(β)*z+β*conj(z)=conj(β)*α+β*conj(α)

LET a=v(2,5)
LET n=v(4,3)

FOR j=0 TO h !画面全体を走査する
   LET y=worldy(j) !ドットをxy座標に変換する
   FOR i=0 TO w
      LET x=worldx(i)

      LET p=v(x,y) !n・(p-a)=0となる点Pの軌跡
      IF ABS( fnDOT(n,p-a) )<cEps THEN PLOT POINTS: x,y

   NEXT i
NEXT j


!例 点C(-1,1)を中心とする半径3の円の方程式を求めよ。
!参考 複素数による表現
! 点C(α=a+b*i)とすると、|z-α|=r

LET OC=v(-1,1)
LET r=3

FOR j=0 TO h !画面全体を走査する
   LET y=worldy(j) !ドットをxy座標に変換する
   FOR i=0 TO w
      LET x=worldx(i)

      LET OP=v(x,y) !|p-c|=rとなる点Pの軌跡
      IF ABS( ABS(OP-OC)-r )<cEps THEN PLOT POINTS: x,y

   NEXT i
NEXT j



!例 2点A(-5,-3)、B(2,4)を直径とする円の方程式を求めよ。(内積を用いた表現)
!参考 複素数による表現
! 点A(α=a+b*i)、点B(β=c+d*i)とすると
! arg((z-α)/(z-β))=±PI/2 または |z-(α+β)/2|=|α-β|/2

LET OA=v(-5,-3)
LET OB=v(2,4)

FOR j=0 TO h !画面全体を走査する
   LET y=worldy(j) !ドットをxy座標に変換する
   FOR i=0 TO w
      LET x=worldx(i)

      LET OP=v(x,y) !PA・PB=0(円周角の定理)となる点Pの軌跡
      IF ABS( fnDOT(OA-OP,OB-OP) )<cEps THEN PLOT POINTS: x,y

   NEXT i
NEXT j


!例 点O(0,0)、A(2,0)、B(1,2)として、点PをOP=s*OA+t*OB、実数s,tとする。
! ��1≦s+t≦3、0≦s、0≦tの範囲を動くとき、点Pの存在範囲を図示せよ。
! ��2*s+t=1を満たすとき、点Pの存在範囲を図示せよ。

LET OA=v(2,0)
LET OB=v(1,2)

FOR s=0 TO 3 STEP 2^(-6) !s≦3 ※刻みは調整が必要である
   FOR t=0 TO 3 STEP 2^(-6) !0≦sより、s+t≦3≦3+sとなる。これより、t≦3
      IF 1<=s+t AND s+t<=3 THEN !��
         LET OP=s*OA+t*OB
         PLOT POINTS: Re(OP),Im(OP)
      END IF
   NEXT t
NEXT s

FOR s=-4 TO 4 STEP 2^(-6) !t=[-∞,∞] ※範囲と刻みは調整が必要である
   LET t=1-2*s !2*s+t=1より
   LET OP=s*OA+t*OB
   PLOT POINTS: Re(OP),Im(OP) !��
NEXT s


!例 X軸上を転がる半径1の円の円周上の点Pの軌跡(サイクロイド)

LET r=1
FOR t=-3*PI TO 3*PI STEP 0.1 !※範囲と刻みは調整が必要である
   LET OA=v(r*t,r) !中心A、X軸との接点Bとすると、OB=弧BPより
   LET AP=v(-r*SIN(t),-r*COS(t))
   LET OP=OA+AP !点Pの軌跡
   PLOT LINES: Re(OP),Im(OP);
NEXT t
PLOT LINES


END
 

テキストアートの作成依頼

 投稿者:GAI  投稿日:2010年 1月22日(金)10時34分41秒
返信・引用
  写真をスキャナーで読み取り、そのビットに対応する濃淡からこれに対応する”文字”(漢字を含む)を割り当て、元のイメージをすべて文字の羅列にてその画を作ることはできませんでしょうか?
できたら横70文字、縦75文字ほどの大きさが欲しいです。
 

Re: テキストアートの作成依頼

 投稿者:山中和義  投稿日:2010年 1月22日(金)11時09分48秒
返信・引用
  > No.977[元記事へ]

GAIさんへのお返事です。

>写真をスキャナーで読み取り、そのビットに対応する濃淡から

直接スキャナからは不可能ですが、画像ファイルを読み込むのなら可能です。

「カラー画像の各1ピクセルをモノトーン(濃淡)に変換して、1文字で表現する」なら
過去掲示板「画像をテキストアートにする」(元記事)を参照のこと。
ドライブ C のフォルダ My Documents に、TEXTART.HTM が作成されます。


>できたら横70文字、縦75文字ほどの大きさが欲しいです。

モザイク処理になるのでしょうか?
 

Re: テキストアートの作成依頼

 投稿者:GAI  投稿日:2010年 1月23日(土)06時28分45秒
返信・引用
  > No.978[元記事へ]

山中和義さんへのお返事です。

> ドライブ C のフォルダ My Documents に、TEXTART.HTM が作成されます。

すばらしいの一言です。
ただこれを見ると画面一面になり、全体像を見るのに苦労します。
これをテキスト編集や、大きさを変更できたりすることはできませんか?



> モザイク処理になるのでしょうか?
B5版やA4版の用紙で全体を印刷する位の大きさがいいのですが・・・
なお、上記の画面をコピーしてメモ帳に貼り付けようとしたらうまくいかないのですがどうしたらいいのですか?
 

Re: テキストアートの作成依頼

 投稿者:山中和義  投稿日:2010年 1月23日(土)09時39分55秒
返信・引用  編集済
  > No.979[元記事へ]

GAIさんへのお返事です。

> ただこれを見ると画面一面になり、全体像を見るのに苦労します。

ドット・を文字■に拡大表示するので大きくなるのは、、、


> これをテキスト編集や、大きさを変更できたりすることはできませんか?

HTML文書(拡張子.HTM)ですので、(インターネット)ブラウザで表示していると思います。
したがって、ブラウザの表示や印字機能(文字を小さくしたり、印字プレビューなど)で
対処してください。
元画像が200×150ピクセルなら、文字サイズを最小にすれば、ほぼ全体が表示できると思います。


> 上記の画面をコピーしてメモ帳に貼り付けようとしたら

メモ帳はファイルサイズが32KBまでなので、ワードパッドかワープロソフトで扱います。


> モザイク処理になるのでしょうか?(自答)

テキストアート
 モノトーン画像の1ピクセル(ドット)を1文字に置き換える
  濃い● →  ● や ◎
  淡い● →  ○ や 0 や O

  たとえば、256階調(濃淡)なら256文字(線の密度パターン)を用意する


アスキーアート
 2値画像のたとえば4×4ピクセル(ドット)を1文字に置き換える
  ■□□■
  □■■□ → X や K
  ■■■□
  ■□□■    高々2^16通りの文字(線の形状パターン)を用意する
 

多倍長LOG(5)を求める

 投稿者:しばっち  投稿日:2010年 1月23日(土)19時18分26秒
返信・引用
  多倍長 LOG(5)を求める

(旧掲示板、投稿ネタからの掘り起しです)

T=1-X/2^N (0<T<=1) として
  LOG(1-T)=-(T+T^2/2+T^3/3+T^4/4+...)
  LOG(X)=LOG(T)+N*LOG(2)

又は

T=X/2^(N-1) (1<T<=2) として
  LOG((1+U)/(1-U))=2*(U+U^3/3+U^5/5...) U=(T-1)/(T+1)
  LOG(X)=LOG(T)+(N-1)*LOG(2)

として求める。
   なお、LOG(2)は予め、用意しておく

実行には、2進モードをご使用ください。

PUBLIC NUMERIC BIAS, KETA, SIGN, EPS
INPUT  PROMPT "桁数=":KETA !' 2000桁まで
LET  KETA = INT(KETA/4)
LET  EPS = 5  !'計算誤差分(4*EPS 桁)
LET  BIAS = 0 !'10000 ^ (BIAS+1) まで
LET  KETA = KETA + EPS !'10000 ^ (-KETA) まで
LET  SIGN = -BIAS - 1  !'多倍長数符号 A(SIGN)=1... 正  A(SIGN)=-1...負
DIM A(-BIAS-1 TO KETA)
LET X=5
!'INPUT  PROMPT "LOG(X) X=":X
CALL SLOG(X,A)
CALL DISPLAY2(A)
END

EXTERNAL  SUB SLOG(X,S())
DIM A(-BIAS-1 TO KETA)
FOR I=1 TO 32
   IF X<=2^I THEN EXIT FOR
NEXT I
IF (2^I-X)/2^I<(X-2^(I-1))/2^(I-1) THEN
   CALL SLOG2(X,S)
ELSE
   CALL SLOG3(X,S)
END IF
END SUB

EXTERNAL  SUB SLOG2(AX, X()) !'LOG(1-T) T=1-X/2^N (0<T<=1) → LOG((2^N-X)/2^N)
IF AX < 0 THEN
   PRINT "ERROR in SLOG2"
   STOP
END IF
DIM U(-BIAS - 1 TO KETA), V(-BIAS - 1 TO KETA), S(-BIAS - 1 TO KETA), N(-BIAS - 1 TO KETA)
LET NN= 1
LET U(0) = 1
LET U(SIGN) = 1
LET S(SIGN) = 1
LET  F = 1
DO WHILE 2 ^ F < AX
   LET  F = F + 1
LOOP
LET XX = 2 ^ F - AX
LET XA = 2 ^ F
CALL LN2(N)
CALL SMUL(N,F)
IF XX=0 THEN
   CALL LCOPY(X,N)
   EXIT SUB
END IF
DO
   CALL SMUL(U,XX)
   CALL SDIV(U,XA)
   CALL LCOPY(V, U)
   CALL SDIV(V, NN)
   CALL LADD2(S, V)
   LET  NN = NN+ 1
LOOP UNTIL ZERO(V)<>0
CALL LSUB (N, S, X)
END SUB

EXTERNAL  SUB SLOG3(XA, X()) !'LOG((T-1)/(T+1)) T=X/2^N (1<T<=2) → LOG((X-2^N)/(X+2^N))
IF XA < 0 THEN
   PRINT "ERROR in SLOG3"
   STOP
END IF
DIM D(-BIAS - 1 TO KETA)
DIM M(-BIAS - 1 TO KETA), S(-BIAS - 1 TO KETA)
DO
   LET K=K+1
LOOP WHILE 2 ^ (K+1) < XA
IF XA - 2 ^ (K+1) = 0  THEN
   CALL LN2(X)
   CALL SMUL(X,K+1)
   EXIT SUB
END IF
LET  N = 1
CALL LCLR (X)
LET  X(0) = XA - 2^K
LET  X(SIGN) = 1
CALL SDIV(X,XA+2^K)
CALL LCOPY(S, X)
DO
   CALL LCOPY(M, S)
   CALL SMUL(X,(XA-2^K)^2)
   CALL SDIV(X,(XA+2^K)^2)
   CALL LCOPY(D, X)
   LET  N = N + 2
   CALL SDIV(D, N)
   CALL LADD2(S, D)
LOOP UNTIL EQUAL(M, S)<>0
CALL SMUL(S,2)
CALL LN2(D)
CALL SMUL(D,K)
CALL LADD(D,S,X)
END SUB

EXTERNAL  SUB LN2(X()) !' LOG(2) (2000桁分)
CALL LCLR (X)
LET X(SIGN)=1
FOR I = 1 TO KETA
   READ IF MISSING THEN EXIT FOR:X(I)
NEXT I
DATA 6931,4718,0559,9453,0941,7232,1214,5817,6568,0755,0013,4360,2552,5412,0680,0094,9339,3621,9696,9471,5605,8633,2699,6418,6875
DATA 4200,1481,0205,7068,5733,6855,2023,5758,1305,5703,2670,7516,3507,5961,9307,2757,0828,3714,3519,0307,0386,2389,1673,4711,2335
DATA 0115,3644,9795,5239,1204,7517,2681,5749,3206,5155,5247,3413,9525,8829,5045,3007,0953,2636,6642,6541,0423,9157,8149,5204,3740
DATA 4303,8550,0801,9441,7064,1671,5186,4471,2839,9681,7178,4546,9570,2627,1631,0645,4615,0257,2074,0248,1637,7733,8963,8550,6952
DATA 6066,8341,1372,7387,3722,9289,5649,3547,0257,6265,2098,8596,9320,1965,0585,5476,4703,3067,9365,4432,5476,3274,4951,2504,0606
DATA 9438,1471,0468,9946,5062,2016,7720,4245,2452,9612,6879,4654,6193,1651,7468,1392,6725,0410,3802,5462,5965,6869,1441,9287,1608
DATA 2938,0317,2714,3677,8265,4877,5664,8508,5674,0776,4845,1464,4399,4046,1422,6031,9309,6735,4025,7444,6070,3080,9608,5047,4866
DATA 3852,3138,1816,7675,1438,6674,7664,7890,8814,3714,1985,4942,3151,9973,5488,0375,1658,6127,5352,9166,1000,7105,3558,2498,7941
DATA 4729,5092,9311,3897,1559,9820,5654,3928,7170,0072,1808,5761,0252,3688,9213,2449,7138,9320,3784,3935,3088,7748,2597,0171,5591
DATA 0708,8236,8362,7589,8425,8918,5353,0243,6342,1436,7061,1892,3678,9192,3723,1467,2321,7205,3401,6492,5687,2747,7823,4453,5347
DATA 6481,1494,1864,2386,7767,7440,6069,5626,5737,9600,8670,7625,7199,1847,3402,2651,4628,3790,4883,0620,3306,1144,6300,7371,9489
DATA 0027,4364,3965,0025,8093,6519,4430,4119,1150,6080,9487,9306,7865,1588,7090,0605,2034,6842,9736,1938,4128,9652,5565,3968,6022
DATA 1941,2292,4207,5743,2175,7489,0977,0675,2687,1158,1705,1137,0091,5894,2665,4785,9596,4890,6530,5846,0258,6683,8294,0022,8330
DATA 0538,2074,0056,7705,3046,7870,0184,1624,0441,8833,2327,9838,6349,0015,6312,1889,5606,5055,3151,2721,9939,8332,0307,5140,8426
DATA 0914,7900,1265,1682,4344,3893,5724,7278,8205,4862,7155,2741,8772,4300,2489,7945,4019,6187,2339,8086,0831,6648,1149,0930,6675
DATA 1933,9312,8904,3164,1370,6813,9777,6498,1769,7486,8903,8877,8999,1296,5036,1927,0710,8892,6410,5230,9247,8391,7373,5012,2984
DATA 2420,4995,6893,5992,2066,0220,4654,9415,1061,3918,7885,7442,4557,7510,2068,3703,0866,6194,8089,6412,1868,0779,0208,1815,8858
DATA 0001,6881,1597,3056,1866,7619,9187,3952,0076,6719,2145,9223,6720,6025,3959,5436,5416,5531,1295,1759,8994,0056,0003,6651,3567
DATA 5690,5124,5926,8257,4394,6483,1683,3262,4901,8038,2424,0824,2314,5230,6140,9638,0570,0702,5513,8770,2681,7851,6306,9025,5137
DATA 0323,4053,8021,4501,9015,3740,2950,9942,2629,9577,9647,4271,3815,7363,8017,2987,3940,7042,4217,9972,2669,6297,9939,3127,0693
DATA 5747,2404,9338,6530,8797
END SUB

!'以下、多倍長計算共通ルーチン  (多倍長LOG(π)を求める、でも使用)

EXTERNAL  SUB DISPLAY2(X()) !'表示
FOR K=-BIAS TO 0
   IF X(K)<>0 THEN EXIT FOR
NEXT K
IF X(SIGN) = -1 THEN PRINT "- ";
IF K>=0 THEN
   LET K=0
   PRINT STR$(X(0));"."
ELSE
   PRINT STR$(X(K));
   FOR I=K+1 TO 0
      LET A$=A$ & RIGHT$("000"&STR$(X(I)),4)
      IF LEN(A$) = 100 THEN
         PRINT A$
         LET A$=""
      END IF
   NEXT I
   IF LEN(A$) > 0 THEN
      PRINT A$;"."
      LET A$=""
   END IF
END IF
LET S=0
FOR I=1 TO KETA-EPS
   LET A$=A$ & RIGHT$("000"&STR$(X(I)),4)
   IF LEN(A$) = 100 THEN
      LET S=S+100
      FOR J=1 TO 10
         PRINT LEFT$(A$,10);" ";
         IF J=5 THEN PRINT "   ";
         LET A$=RIGHT$(A$,LEN(A$)-10)
      NEXT J
      PRINT ":";S
      LET A$=""
      IF MOD(S,1000)=0 THEN PRINT
   END IF
NEXT I
IF LEN(A$) > 0 THEN
   LET S=S+LEN(A$)
   LET A$=A$ & REPEAT$(" ",10)
   FOR J=1 TO 9
      PRINT RTRIM$(LEFT$(A$,10));" ";
      IF J=5 THEN PRINT "   ";
      LET A$=RIGHT$(A$,LEN(A$)-10)
      IF RTRIM$(A$)="" THEN EXIT FOR
   NEXT J
   !'  PRINT ":";S
END IF
END SUB

EXTERNAL  FUNCTION EQUAL(A(), B()) !'等しいかどうか
FOR I = -BIAS - 1 TO KETA-EPS
   IF A(I)<>B(I) THEN
      LET EQUAL=0
      EXIT FUNCTION
   END IF
NEXT I
LET EQUAL=-1
END FUNCTION

EXTERNAL  FUNCTION ZERO(A()) !'0値かどうか
FOR I=-BIAS TO KETA-EPS
   IF A(I)<>0 THEN
      LET ZERO=0
      EXIT FUNCTION
   END IF
NEXT I
LET ZERO=-1
END FUNCTION

EXTERNAL  FUNCTION GREAT(A(), B()) !'多倍長数A > 多倍長数B なら真
LET  SIGNA = A(SIGN)
LET  SIGNB = B(SIGN)
IF SIGNA = -1 AND SIGNB = 1 THEN
   LET  GREAT = 0
   EXIT FUNCTION
END IF
IF SIGNA = 1 AND SIGNB = -1 THEN
   LET  GREAT = -1
   EXIT FUNCTION
END IF
FOR I = -BIAS TO KETA
   IF SIGNA = -1 AND SIGNB = -1 THEN
      IF A(I) < B(I) THEN
         LET  GREAT = -1
         EXIT FUNCTION
      END IF
      IF A(I) > B(I) THEN
         LET  GREAT = 0
         EXIT FUNCTION
      END IF
   ELSE
      IF A(I) > B(I) THEN
         LET  GREAT = -1
         EXIT FUNCTION
      END IF
      IF A(I) < B(I) THEN
         LET  GREAT = 0
         EXIT FUNCTION
      END IF
   END IF
NEXT I
END FUNCTION
 

Re: 多倍長LOG(5)を求める

 投稿者:しばっち  投稿日:2010年 1月23日(土)19時19分36秒
返信・引用
  > No.981[元記事へ]

続き

EXTERNAL  SUB LCLR(A()) !'0値セット
MAT A=ZER
LET  A(SIGN) = 1
END SUB

EXTERNAL  SUB LCOPY(A(), B()) !'値コピー
MAT A=B
END SUB

EXTERNAL  SUB LADD(A(), B(), C()) !'多倍長同士の加算 C=A+B
LET  SIGNA = A(SIGN)
LET  SIGNB = B(SIGN)
IF SIGNA = 1 AND SIGNB = -1 THEN
   LET  B(SIGN) = 1
   CALL LSUB (A, B, C)
   LET  B(SIGN) = -1
   EXIT SUB
ELSEIF SIGNA = -1 AND SIGNB = 1 THEN
   LET  A(SIGN) = 1
   CALL LSUB (B, A, C)
   LET  A(SIGN) = -1
   EXIT SUB
END IF
MAT C=A+B
FOR I = KETA TO -BIAS + 1 STEP -1
   IF C(I) >= 10000 THEN
      LET  C(I) = C(I) - 10000
      LET  C(I - 1) = C(I - 1) + 1
   END IF
NEXT I
IF C(-BIAS) >= 10000 THEN
   PRINT "OVER FLOW in LADD"
   STOP
END IF
IF SIGNA = -1 AND SIGNB = -1 THEN LET  C(SIGN) = -1 ELSE LET  C(SIGN) = 1
END SUB

EXTERNAL  SUB LADD2(A(),B()) !'多倍長同士の加算 A=A+B
DIM C(-BIAS-1 TO KETA)
CALL LADD(A,B,C)
CALL LCOPY(A,C)
END SUB

EXTERNAL  SUB LSUB (A(), B(), C())!'多倍長同士の減算 C=A-B
LET  SIGNA = A(SIGN)
LET  SIGNB = B(SIGN)
LET  A(SIGN) = 1
LET  B(SIGN) = 1
IF SIGNA * SIGNB = -1 THEN
   CALL LADD (A, B, C)
   LET  C(SIGN) = SIGNA
   LET  A(SIGN) = SIGNA
   LET  B(SIGN) = SIGNB
   EXIT SUB
END IF
LET  GR = GREAT(A, B)
IF SIGNA = 1 AND SIGNB = 1 THEN
   IF GR<>0 THEN
      MAT C=A-B
      LET  C(SIGN) = 1
   ELSE
      MAT C=B-A
      LET  C(SIGN) = -1
   END IF
ELSE
   IF GR<>0 THEN
      MAT C=B-A
      LET  C(SIGN) = 1
   ELSE
      MAT C=A-B
      LET  C(SIGN) = -1
   END IF
END IF
FOR I = KETA TO -BIAS + 1 STEP -1
   IF C(I) < 0 THEN
      LET  C(I) = C(I) + 10000
      LET  C(I - 1) = C(I - 1) - 1
   END IF
NEXT I
LET  A(SIGN) = SIGNA
LET  B(SIGN) = SIGNB
END SUB

EXTERNAL  SUB LSUB2(A(),B()) !'多倍長同士の減算 A=A-B
DIM C(-BIAS-1 TO KETA)
CALL LSUB(A,B,C)
CALL LCOPY(A,C)
END SUB

EXTERNAL  SUB SDIV (A(), XA) !'割り算  多倍長数A = 多倍長数A / 整数XA (1E+10程度まで)
IF XA=0 THEN
   PRINT "ERROR in SDIV"
   STOP
END IF
LET  SIGNA = A(SIGN)
LET  SG = SGN(XA)
LET  XX = ABS(XA)
FOR I = -BIAS TO KETA - 1
   LET  R = A(I) - INT(A(I) / XX) * XX
   LET  A(I) = INT(A(I) / XX)
   LET  A(I + 1) = A(I + 1) + R * 10000
NEXT I
LET  A(KETA) = INT(A(KETA) / XX)
LET  A(SIGN) = SIGNA * SG
END SUB

EXTERNAL  SUB SMUL (A(), XA)!'掛け算  多倍長数A = 多倍長数A * 整数XA (1E+10程度まで)
LET  SIGNA = A(SIGN)
IF XA >= 0 THEN LET SG=1 ELSE LET SG=-1
LET  XX = ABS(XA)
MAT A=(XX)*A
FOR I = KETA TO -BIAS + 1 STEP -1
   IF A(I) >= 10000 THEN
      LET  R = INT(A(I) / 10000)
      LET  A(I) = A(I) - 10000 * R
      LET  A(I - 1) = A(I - 1) + R
   END IF
NEXT I
IF A(-BIAS) >= 10000 THEN
   PRINT "OVER FLOW in SMUL"
   STOP
END IF
LET  A(SIGN) = SIGNA * SG
END SUB
 

多倍長LOG(2)を求める

 投稿者:しばっち  投稿日:2010年 1月23日(土)19時21分2秒
返信・引用
  多倍長 LOG(2)を求める

前述の計算方法では別途、LOG(2)値が必要となる

計算式に

    LOG((1+1/X)/(1-1/X))=LOG((X+1)/(X-1)=2*(1/X+1/(3*X^3)+1/(5*X^5)+1/(7*X^7)+...)

を使用し、以下の関係式

    LOG(2) = 3 * LOG(81/80) + 5 * LOG(25/24) + 7 * LOG(16/15)

を使ってLOG(2)を求める。

なお、LOG(5)を直接求めるのなら、上の計算式と関係式

    LOG(5) = 7 * LOG(81/80) + 4 * LOG(16/15) + 12 * LOG(10/9)

を使って求めることができる。

PUBLIC NUMERIC KETA,BIAS,EPS
INPUT  PROMPT "桁数=":KETA
LET  KETA=INT(KETA/4)
LET  EPS=2
LET  BIAS=0
LET  KETA=KETA+EPS
OPTION BASE 0
DIM S(KETA),A(KETA),B(KETA),C(KETA),AA(KETA),BB(KETA),CC(KETA),M(KETA)
LET  N = 1
LET A(0)=3
LET B(0)=5
LET C(0)=7
FOR I = 0 TO KETA - 1
   LET  R = A(I) - INT(A(I) / 161) * 161
   LET  A(I) = INT(A(I) / 161)
   LET  A(I + 1) = A(I + 1) + R * 10000
   LET  R = B(I) - INT(B(I) / 49) * 49
   LET  B(I) = INT(B(I) / 49)
   LET  B(I + 1) = B(I + 1) + R * 10000
   LET  R = C(I) - INT(C(I) / 31) * 31
   LET  C(I) = INT(C(I) / 31)
   LET  C(I + 1) = C(I + 1) + R * 10000
NEXT I
LET  A(KETA) = INT(A(KETA) / 161)
LET  B(KETA) = INT(B(KETA) / 49)
LET  C(KETA) = INT(C(KETA) / 31)
MAT S=S+A
MAT S=S+B
MAT S=S+C
FOR I = KETA TO 0 STEP -1
   IF S(I) >= 10000 THEN
      LET  R = INT(S(I) / 10000)
      LET S(I)=S(I)-R*10000
      LET  S(I - 1) = S(I - 1) + R
   END IF
NEXT I
DO
   FOR I = 0 TO KETA - 1
      LET  R = A(I) - INT(A(I) / 25921) * 25921
      LET  A(I) = INT(A(I) / 25921)
      LET  A(I + 1) = A(I + 1) + R * 10000
      LET  R = B(I) - INT(B(I) / 2401) * 2401
      LET  B(I) = INT(B(I) / 2401)
      LET  B(I + 1) = B(I + 1) + R * 10000
      LET  R = C(I) - INT(C(I) / 961) * 961
      LET  C(I) = INT(C(I) / 961)
      LET  C(I + 1) = C(I + 1) + R * 10000
   NEXT I
   LET  A(KETA) = INT(A(KETA) / 25921)
   LET  B(KETA) = INT(B(KETA) / 2401)
   LET  C(KETA) = INT(C(KETA) / 961)
   MAT AA=A
   MAT BB=B
   MAT CC=C
   LET N=N+2
   FOR I = 0 TO KETA - 1
      LET  R = AA(I) - INT(AA(I) / N) * N
      LET  AA(I) = INT(AA(I) / N)
      LET  AA(I + 1) = AA(I + 1) + R * 10000
      LET  R = BB(I) - INT(BB(I) / N) * N
      LET  BB(I) = INT(BB(I) / N)
      LET  BB(I + 1) = BB(I + 1) + R * 10000
      LET  R = CC(I) - INT(CC(I) / N) * N
      LET  CC(I) = INT(CC(I) / N)
      LET  CC(I + 1) = CC(I + 1) + R * 10000
   NEXT I
   LET  AA(KETA) = INT(AA(KETA) / N)
   LET  BB(KETA) = INT(BB(KETA) / N)
   LET  CC(KETA) = INT(CC(KETA) / N)
   MAT S=S+AA
   MAT S=S+BB
   MAT S=S+CC
   FOR I = KETA TO 0 STEP -1
      IF S(I) >= 10000 THEN
         LET  R = INT(S(I) / 10000)
         LET  S(I)=S(I)-R*10000
         LET  S(I - 1) = S(I - 1) + R
      END IF
   NEXT I
   FOR J = 0 TO KETA
      IF S(J)<>M(J) THEN
         MAT  M = S
         LET K=J
         EXIT FOR
      END IF
   NEXT J
LOOP WHILE J<=KETA-EPS
MAT S=2*S
FOR I = KETA TO 0 STEP -1
   IF S(I) >= 10000 THEN
      LET  S(I) = S(I) - 10000
      LET  S(I - 1) = S(I - 1) + 1
   END IF
NEXT I
CALL WRITEDATA(S,"")
END

EXTERNAL  SUB WRITEDATA(X(),Z$)
IF Z$="" THEN OPEN #1:TextWindow1 ELSE OPEN #1:NAME Z$
ERASE #1
FOR KK=-BIAS TO KETA
   IF X(KK)<>0 THEN EXIT FOR
NEXT KK
PRINT #1:"SUB LN2(X())"
PRINT #1:"CALL LCLR(X)"
PRINT #1:"LET X(SIGN)=1"
PRINT #1:"FOR I=";STR$(KK);" TO KETA"
PRINT #1:"READ IF MISSING THEN EXIT FOR:X(I)"
PRINT #1:"NEXT"
PRINT #1:"DATA ";
FOR I=KK TO KETA-EPS-1
   LET K=K+1
   IF MOD(K,25)=0  THEN
      PRINT #1:RIGHT$("000"&STR$(X(I)),4)
      PRINT #1:"DATA ";
   ELSE
      PRINT #1:RIGHT$("000"&STR$(X(I)),4);
      IF I<>0 THEN PRINT #1:",";
   END IF
   IF -BIAS<=0 AND I=0 THEN
      PRINT #1
      PRINT #1:"DATA ";
      LET K=0
   END IF
NEXT I
PRINT #1:RIGHT$("000"&STR$(X(KETA-EPS)),4)
PRINT #1:"END SUB"
CLOSE #1
END SUB
 

多倍長LOG(π)を求める

 投稿者:しばっち  投稿日:2010年 1月23日(土)19時22分46秒
返信・引用
  多倍長 LOG(π)を求める (2000桁)

計算式に

    LOG(1 - X) = -(X + X^2/2 + X^3/3 + X^4/4 +...)

を使用した。

X は試行錯誤した結果

     X = 1 - 544482330679994391053312457583 / 1710541690073718870111737129379 * π

とした。計算後に

  LOG(17105416...) - LOG(54448233...)を加算して、LOG(π)を求める。

また、計算時間短縮のため、π、LOG(17105416...)、LOG(54448233...)値は予め用意した。

 共通ルーチンが必要。

PUBLIC NUMERIC BIAS, KETA, SIGN, EPS
LET  EPS=12
LET  N=2^9-EPS
LET  BIAS = 0
LET  KETA =-BIAS+N+EPS
LET  SIGN = -BIAS - 1
DIM X(-BIAS - 1 TO KETA)
CALL LLOGPI(X)
CALL DISPLAY2(X)
END

EXTERNAL  SUB LLOGPI(X())
DIM L(-BIAS - 1 TO KETA)
DIM A(-BIAS - 1 TO KETA), B(-BIAS - 1 TO KETA)
DIM S(-BIAS - 1 TO KETA), C(-BIAS - 1 TO KETA)
CALL PI(L)
CALL SDIV(L,9*31*14699) !'1710541690073718870111737129379 で割る
CALL SDIV(L,304439)
CALL SDIV(L,49368533)
CALL SDIV2(L,27751800277)
CALL SMUL(L,101*1657) !' 544482330679994391053312457583 倍する
CALL SMUL(L,3580259)
CALL SMUL(L,5392007)
CALL SMUL2(L,168529144463)
CALL LCLR(X)
LET X(0)=1
CALL LSUB2(X, L)
CALL LCOPY(B, X)
CALL LCOPY(S, X)
LET  NN = 2
DO
   CALL LMUL2(B, X)
   CALL LCOPY(C, B)
   CALL SDIV(C, NN)
   LET  NN = NN + 1
   CALL LADD2(S, C)
LOOP UNTIL ZERO(B)<>0
LET S(SIGN)=-1
CALL LN1710541690073718870111737129379(L)
CALL LADD2(S,L)
CALL LN544482330679994391053312457583(L)
CALL LSUB(S,L,X)
END SUB

EXTERNAL  SUB SMUL2(X(),XA) !'多倍長数X = 多倍長数X * 整数XA (1E+11〜1E+14程度まで)
DIM A(-BIAS*4 TO KETA*4+3)  !'(基数10000 → 基数10 に変換して計算) 精度落ち対策
LET  SIGNA = X(SIGN)
IF XA >= 0 THEN LET SG=1 ELSE LET SG=-1
LET  XX = ABS(XA)
FOR I=-BIAS TO KETA
   LET A(I*4)=MOD(INT(X(I)/1000),10)
   LET A(I*4+1)=MOD(INT(X(I)/100),10)
   LET A(I*4+2)=MOD(INT(X(I)/10),10)
   LET A(I*4+3)=MOD(X(I),10)
NEXT I
MAT A=(XX)*A
FOR I=KETA*4 TO -BIAS*4+1 STEP -1
   IF A(I) >= 10 THEN
      LET  R = INT(A(I) / 10)
      LET  A(I) = MOD(A(I),10)
      LET  A(I - 1) = A(I - 1) + R
   END IF
NEXT I
IF A(-BIAS*4) >= 10 THEN
   PRINT "OVER FLOW in SMUL2"
   STOP
END IF
FOR I=-BIAS TO KETA-1
   LET X(I)=A(I*4)*1000+A(I*4+1)*100+A(I*4+2)*10+A(I*4+3)
NEXT I
LET X(SIGN)= SIGNA * SG
END SUB

EXTERNAL  SUB SDIV2(X(),XA) !'多倍長数X = 多倍長数X / 整数XA (1E+11〜1E+14程度まで)
DIM A(-BIAS*4 TO KETA*4+3)  !'(基数10000 → 基数10 に変換して計算) 精度落ち対策
IF XA=0 THEN
   PRINT "ERROR in SDIV2"
   STOP
END IF
LET  SIGNA = X(SIGN)
LET  SG=SGN(XA)
LET  XX = ABS(XA)
FOR I=-BIAS TO KETA
   LET A(I*4)=MOD(INT(X(I)/1000),10)
   LET A(I*4+1)=MOD(INT(X(I)/100),10)
   LET A(I*4+2)=MOD(INT(X(I)/10),10)
   LET A(I*4+3)=MOD(X(I),10)
NEXT I
FOR I=-BIAS*4 TO KETA*4-1
   LET  R = A(I) - INT(A(I) / XX) * XX
   LET  A(I) = INT(A(I) / XX)
   LET  A(I + 1) = A(I + 1) + R * 10
NEXT I
LET A(KETA*4)=INT(A(KETA*4)/XX)
FOR I=-BIAS TO KETA-1
   LET X(I)=A(I*4)*1000+A(I*4+1)*100+A(I*4+2)*10+A(I*4+3)
NEXT I
LET X(SIGN)= SIGNA * SG
END SUB

EXTERNAL  SUB LMUL(A(),B(),C())!'多倍長同士の乗算 C=A*B
LET N=(KETA+BIAS)*2
IF INT(LOG2(N))<>LOG2(N) THEN
   PRINT "ERROR in LMUL"
   STOP
END IF
OPTION BASE 0
DIM AA(N*2),BB(N*2),CC(N*2)
FOR I=0 TO N/2-1
   LET AA(2*I)=A(-BIAS+I)
   LET BB(2*I)=B(-BIAS+I)
NEXT I
CALL CDFT(2*N, COS(PI/N), SIN(PI/N), AA)
CALL CDFT(2*N, COS(PI/N), SIN(PI/N), BB)
FOR I = 0 TO N-1
   LET  CC(2*I) = AA(2*I) * BB(2*I) - AA(2*I+1) * BB(2*I+1)
   LET  CC(2*I+1) = AA(2*I) * BB(2*I+1) + BB(2*I) * AA(2*I+1)
NEXT I
CALL CDFT(2*N, COS(PI/N), -SIN(PI/N), CC)
FOR I=0 TO N/2-1
   IF -2*BIAS+I>=-BIAS AND -2*BIAS+I<=KETA THEN
      LET C(-2*BIAS+I)=INT(CC(2*I)/N+.5)
   END IF
NEXT I
FOR I=KETA TO -BIAS STEP -1
   IF C(I) >=10000 THEN
      LET  R = INT(C(I) / 10000)
      LET  C(I) = C(I) - R * 10000
      LET  C(I - 1) = C(I - 1) + R
   ELSEIF C(I)<0 THEN
      LET C(I)=C(I)+10000
      LET C(I-1)=C(I-1)-1
   END IF
NEXT I
LET C(SIGN)=A(SIGN)*B(SIGN)
END SUB

EXTERNAL  SUB LMUL2 (A(), B()) !'多倍長同士の乗算 A=A*B
DIM C(-BIAS-1 TO KETA)
CALL LMUL(A,B,C)
CALL LCOPY(A,C)
END SUB

EXTERNAL  SUB CDFT(N, WR, WI, A()) !'ネット上から入手した(※原版はFORTRAN)
LET  WMR = WR
LET  WMI = WI
LET  M = N
DO WHILE M > 4
   LET  L = M / 2
   LET  WKR = 1
   LET  WKI = 0
   LET  WDR = 1 - 2 * WMI * WMI
   LET  WDI = 2 * WMI * WMR
   LET  SS = 2 * WDI
   LET  WMR = WDR
   LET  WMI = WDI
   FOR J = 0 TO N - M STEP M
      LET  I = J + L
      LET  XR = A(J) - A(I)
      LET  XI = A(J + 1) - A(I + 1)
      LET  A(J) = A(J) + A(I)
      LET  A(J + 1) = A(J + 1) + A(I + 1)
      LET  A(I) = XR
      LET  A(I + 1) = XI
      LET  XR = A(J + 2) - A(I + 2)
      LET  XI = A(J + 3) - A(I + 3)
      LET  A(J + 2) = A(J + 2) + A(I + 2)
      LET  A(J + 3) = A(J + 3) + A(I + 3)
      LET  A(I + 2) = WDR * XR - WDI * XI
      LET  A(I + 3) = WDR * XI + WDI * XR
   NEXT J
   FOR K = 4 TO L - 4 STEP 4
      LET  WKR = WKR - SS * WDI
      LET  WKI = WKI + SS * WDR
      LET  WDR = WDR - SS * WKI
      LET  WDI = WDI + SS * WKR
      FOR J = K TO N - M + K STEP M
         LET  I = J + L
         LET  XR = A(J) - A(I)
         LET  XI = A(J + 1) - A(I + 1)
         LET  A(J) = A(J) + A(I)
         LET  A(J + 1) = A(J + 1) + A(I + 1)
         LET  A(I) = WKR * XR - WKI * XI
         LET  A(I + 1) = WKR * XI + WKI * XR
         LET  XR = A(J + 2) - A(I + 2)
         LET  XI = A(J + 3) - A(I + 3)
         LET  A(J + 2) = A(J + 2) + A(I + 2)
         LET  A(J + 3) = A(J + 3) + A(I + 3)
         LET  A(I + 2) = WDR * XR - WDI * XI
         LET  A(I + 3) = WDR * XI + WDI * XR
      NEXT J
   NEXT  K
   LET  M = L
LOOP
IF M > 2 THEN
   FOR J = 0 TO N - 4 STEP 4
      LET  XR = A(J) - A(J + 2)
      LET  XI = A(J + 1) - A(J + 3)
      LET  A(J) = A(J) + A(J + 2)
      LET  A(J + 1) = A(J + 1) + A(J + 3)
      LET  A(J + 2) = XR
      LET  A(J + 3) = XI
   NEXT J
END IF
IF N > 4  THEN CALL BITRV2(N, A)
END SUB
 

Re: 多倍長LOG(π)を求める

 投稿者:しばっち  投稿日:2010年 1月23日(土)19時23分47秒
返信・引用
  > No.984[元記事へ]

続き

EXTERNAL  SUB BITRV2(N, A())
LET  M = N / 4
LET  M2 = 2 * M
LET  N2 = N - 2
LET  K = 0
FOR J = 0 TO M2 - 4 STEP 4
   IF J < K THEN
      LET  XR = A(J)
      LET  XI = A(J + 1)
      LET  A(J) = A(K)
      LET  A(J + 1) = A(K + 1)
      LET  A(K) = XR
      LET  A(K + 1) = XI
   ELSEIF J > K THEN
      LET  J1 = N2 - J
      LET  K1 = N2 - K
      LET  XR = A(J1)
      LET  XI = A(J1 + 1)
      LET  A(J1) = A(K1)
      LET  A(J1 + 1) = A(K1 + 1)
      LET  A(K1) = XR
      LET  A(K1 + 1) = XI
   END IF
   LET  K1 = M2 + K
   LET  XR = A(J + 2)
   LET  XI = A(J + 3)
   LET  A(J + 2) = A(K1)
   LET  A(J + 3) = A(K1 + 1)
   LET  A(K1) = XR
   LET  A(K1 + 1) = XI
   LET  L = M
   DO WHILE K >= L
      LET  K = K - L
      LET  L = L / 2
   LOOP
   LET  K = K + L
NEXT J
END SUB

EXTERNAL  SUB PI(X()) !'π値
CALL LCLR (X)
LET X(SIGN)=1
FOR I=0 TO KETA
   READ IF MISSING THEN EXIT FOR:X(I)
NEXT I
DATA 0003
DATA 1415,9265,3589,7932,3846,2643,3832,7950,2884,1971,6939,9375,1058,2097,4944,5923,0781,6406,2862,0899,8628,0348,2534,2117,0679
DATA 8214,8086,5132,8230,6647,0938,4460,9550,5822,3172,5359,4081,2848,1117,4502,8410,2701,9385,2110,5559,6446,2294,8954,9303,8196
DATA 4428,8109,7566,5933,4461,2847,5648,2337,8678,3165,2712,0190,9145,6485,6692,3460,3486,1045,4326,6482,1339,3607,2602,4914,1273
DATA 7245,8700,6606,3155,8817,4881,5209,2096,2829,2540,9171,5364,3678,9259,0360,0113,3053,0548,8204,6652,1384,1469,5194,1511,6094
DATA 3305,7270,3657,5959,1953,0921,8611,7381,9326,1179,3105,1185,4807,4462,3799,6274,9567,3518,8575,2724,8912,2793,8183,0119,4912
DATA 9833,6733,6244,0656,6430,8602,1394,9463,9522,4737,1907,0217,9860,9437,0277,0539,2171,7629,3176,7523,8467,4818,4676,6940,5132
DATA 0005,6812,7145,2635,6082,7785,7713,4275,7789,6091,7363,7178,7214,6844,0901,2249,5343,0146,5495,8537,1050,7922,7968,9258,9235
DATA 4201,9956,1121,2902,1960,8640,3441,8159,8136,2977,4771,3099,6051,8707,2113,4999,9998,3729,7804,9951,0597,3173,2816,0963,1859
DATA 5024,4594,5534,6908,3026,4252,2308,2533,4468,5035,2619,3118,8171,0100,0313,7838,7528,8658,7533,2083,8142,0617,1776,6914,7303
DATA 5982,5349,0428,7554,6873,1159,5628,6388,2353,7875,9375,1957,7818,5778,0532,1712,2680,6613,0019,2787,6611,1959,0921,6420,1989
DATA 3809,5257,2010,6548,5863,2788,6593,6153,3818,2796,8230,3019,5203,5301,8529,6899,5773,6225,9941,3891,2497,2177,5283,4791,3151
DATA 5574,8572,4245,4150,6959,5082,9533,1168,6172,7855,8890,7509,8381,7546,3746,4939,3192,5506,0400,9277,0167,1139,0098,4882,4012
DATA 8583,6160,3563,7076,6010,4710,1819,4295,5596,1989,4676,7837,4494,4825,5379,7747,2684,7104,0475,3464,6208,0466,8425,9069,4912
DATA 9331,3677,0289,8915,2104,7521,6205,6966,0240,5803,8150,1935,1125,3382,4300,3558,7640,2474,9647,3263,9141,9927,2604,2699,2279
DATA 6782,3547,8163,6009,3417,2164,1219,9245,8631,5030,2861,8297,4555,7067,4983,8505,4945,8858,6926,9956,9092,7210,7975,0930,2955
DATA 3211,6534,4987,2027,5596,0236,4806,6549,9119,8818,3479,7753,5663,6980,7426,5425,2786,2551,8184,1757,4672,8909,7777,2793,8000
DATA 8164,7060,0161,4524,9192,1732,1721,4772,3501,4144,1973,5685,4816,1361,1573,5255,2133,4757,4184,9468,4385,2332,3907,3941,4333
DATA 4547,7624,1686,2518,9835,6948,5562,0992,1922,2184,2725,5025,4256,8876,7179,0494,6016,5346,6804,9886,2723,2791,7860,8578,4383
DATA 8279,6797,6681,4541,0095,3883,7863,6095,0680,0642,2512,5205,1173,9298,4896,0841,2848,8626,9456,0424,1965,2850,2221,0661,1863
DATA 0674,4278,6220,3919,4945,0471,2371,3786,9609,5636,4371,9172,8746,7764,6575,7396,2413,8908,6583,2645,9958,1339,0478,0275,9009
DATA 9465,7640,7895,1269,4683,9835,2595,7098,2582,2620,5224,8940
END SUB

EXTERNAL  SUB LN1710541690073718870111737129379(X()) !'LOG(1710..)値
CALL LCLR(X)
LET X(SIGN)=1
FOR I=0 TO KETA
   READ IF MISSING THEN EXIT FOR:X(I)
NEXT I
DATA 0069
DATA 6143,6288,7993,3268,3004,4228,2256,8485,2026,6785,3596,6394,4004,2459,4994,5470,1366,5214,8581,6415,4697,3145,7866,1523,7272
DATA 6551,2059,0127,0534,7351,7820,4920,0008,7989,9541,7800,2163,7623,0895,4887,3922,8357,3520,5004,0375,5683,9209,4332,0242,9540
DATA 1748,4435,3241,8232,0917,6048,6351,8267,6655,4103,1920,3713,6534,2808,6848,0068,3923,2800,1886,4684,2394,0286,5595,7822,8870
DATA 6824,4083,5434,5674,3002,0302,6430,7887,0940,1081,9799,5193,2835,3565,5690,4021,5682,1679,9587,2726,5741,7738,9966,8303,9374
DATA 4065,5626,7370,2317,3186,2152,1129,2984,3621,1141,6888,7106,2708,7294,1105,4881,3419,1360,3002,9792,2275,7776,7209,3100,7189
DATA 1333,2926,5906,5310,6574,2333,0024,4444,6043,7221,5935,4199,0820,3015,5200,1473,4002,4862,2284,7807,2731,8261,8953,2953,7309
DATA 4162,4615,8900,1280,1186,1445,3416,9135,4404,4277,0805,7623,1006,4866,6480,4750,1673,5797,3590,6210,4828,8466,8064,0621,5369
DATA 6822,3112,8752,9922,5756,4306,5244,5723,7782,5053,2215,5848,6850,0720,0010,0839,6060,6790,9162,7960,6519,9616,7812,3819,6481
DATA 2850,4009,5322,6067,3979,0496,8839,2466,5255,0930,4737,8771,8972,6183,6781,6485,6742,6847,7569,0628,3272,4958,9055,0595,1667
DATA 0318,1311,7655,2636,5449,8892,8994,6549,8185,5605,1410,8418,3957,3941,9585,7859,8354,6284,4894,3324,7101,4235,7355,6297,7705
DATA 6284,7948,3668,3827,3890,3916,7911,8682,2761,6156,8577,8088,8066,9387,2851,5278,4084,2809,0879,0882,6939,4694,4014,9549,7450
DATA 2911,5763,0278,3692,1766,1804,8124,9781,4074,8058,6307,1025,2785,0760,5599,0083,4081,9099,0502,6793,1794,6341,6502,0176,2868
DATA 3796,2139,9878,6835,7170,1164,2205,6497,0107,8877,3771,7488,8657,5263,9761,2416,6278,3016,1690,0953,1383,8181,7952,3541,1635
DATA 6891,5224,4409,2332,4874,2319,4524,2884,0889,5022,8222,5650,3677,3971,7593,6214,1500,2361,0686,4206,4017,9737,8034,3987,7461
DATA 5150,7437,9961,5876,6881,2221,9103,9820,1354,6600,2760,3220,1344,0667,5700,0559,0702,6840,8532,2596,9193,2134,9548,5155,8877
DATA 1115,9327,4668,8319,5471,2802,0874,9640,1131,7970,8168,2428,1598,3983,6017,5960,3281,6942,4686,9574,9764,9433,1216,4959,2387
DATA 0873,8907,8785,5093,6238,0367,4603,0384,3624,6755,5657,2459,9473,2847,7735,8517,5154,0299,6744,3440,0577,4508,6886,3276,1136
DATA 3026,8720,1951,3001,5676,9739,1394,0643,7786,6988,0521,2185,7078,9937,0618,4466,8235,0108,8657,3294,3409,0176,9410,4535,3487
DATA 5923,4566,3163,5408,2042,0034,7213,0857,1778,0402,9447,8452,8732,6232,4880,1913,2182,3249,5532,6094,1509,8743,6779,9084,9870
DATA 0148,8381,3012,8627,2066,3865,1370,4664,5664,9339,4367,0190,7057,6215,5163,9757,6009,6007,7540,5813,9957,0761,4465,5132,0577
DATA 5503,8417,6557,8706,8939,7814,1500,5247,4757,4949,9209,4162
END SUB

EXTERNAL  SUB LN544482330679994391053312457583(X()) !'LOG(5444..)値
CALL LCLR(X)
LET X(SIGN)=1
FOR I=0 TO KETA
   READ IF MISSING THEN EXIT FOR:X(I)
NEXT I
DATA 0068
DATA 4696,3300,2143,9266,5590,0800,8743,3179,3315,0312,4115,3479,0888,5308,1371,0786,7772,6582,8354,8087,7911,8425,1658,1624,6863
DATA 3534,2720,9432,7548,7948,6284,7447,1357,2875,4696,1898,3726,1025,5558,4562,0907,4477,6791,4979,6390,9355,8684,7181,2383,6067
DATA 5125,9038,3164,5872,4149,1463,9290,8100,8221,3858,4661,7368,8894,4392,1782,5529,1379,0706,7263,6717,7094,2864,3556,3900,7575
DATA 8220,5281,5426,2279,7293,8843,9725,1183,2375,0876,2708,1484,0473,9670,8817,3223,4819,0068,2413,2727,7063,0621,1175,4750,7107
DATA 8671,3441,3378,9146,9346,1923,8237,0526,7108,5413,6817,1946,4759,6110,2330,5046,3222,6584,6590,6347,9478,9162,1229,8258,0639
DATA 8629,0999,7506,3639,3766,9619,4748,6069,6562,5828,2302,4778,3079,2466,1935,4340,5305,9867,9470,7594,5310,3809,3799,2927,1647
DATA 2356,9062,6748,9596,1245,0147,5975,5100,6274,8333,6949,6146,2909,4481,6231,2366,8112,4857,0275,2529,1010,3037,7042,6637,0392
DATA 1670,0491,9722,4984,9411,3815,8869,2731,5703,6430,4132,8603,8424,8368,8011,9123,4089,8308,1853,8980,8362,2095,2457,1928,3638
DATA 0053,3991,4538,1624,6079,4415,8152,2109,6785,7592,9725,2195,0650,0526,5590,0422,3146,3046,8647,5876,9130,4732,3389,1245,8068
DATA 7812,3293,5439,3929,1890,9399,6703,8878,7077,5335,6941,7431,1782,2323,8457,0834,4553,9586,3123,6397,5711,0712,1356,5910,7625
DATA 2193,7131,0681,5285,6609,1095,4149,6754,7763,2836,8796,8730,4951,2823,6551,9299,6014,9348,6341,1187,0646,7366,9790,3242,0076
DATA 3159,2614,7305,1479,3803,0883,1726,8138,1385,3562,1576,6493,8245,0199,7851,4583,9672,9911,8496,3168,7333,7765,0503,4451,0920
DATA 5090,5214,6787,1314,6772,6862,3736,8572,0251,7508,8096,1615,0470,5139,3677,8073,5561,0597,8884,4253,9075,0348,7834,3251,6913
DATA 6549,9352,6478,6587,3687,6446,5803,7343,1607,6931,6148,2364,8107,6286,4138,6620,4422,4124,9848,5744,8327,3790,8854,9012,5488
DATA 6930,5446,1559,2103,7235,1105,4337,1632,8662,1702,8001,9460,1977,8871,6694,9328,1262,7307,0409,3747,7022,2234,8243,0766,1057
DATA 1794,9925,2660,2292,2678,0591,1757,8530,6030,0003,8275,0990,6180,5366,9308,0990,1612,3368,9265,3857,0729,5854,4739,4278,6728
DATA 2111,2446,8161,9364,0415,6814,3644,1779,3609,4265,9090,3322,2336,7923,4096,4595,1538,1568,3121,3374,7747,7340,2591,1985,8297
DATA 1375,4564,3882,8472,3644,4193,1371,2433,7491,7818,1991,7233,1335,2034,1296,1177,3339,7135,6549,2440,4227,1453,0204,3370,3408
DATA 9449,0546,0281,3840,9872,7548,2470,7503,6138,4063,2497,2268,8601,9381,1855,0714,6065,2571,9613,8541,6472,6325,5532,3632,6764
DATA 0684,0804,6469,2615,3651,3647,2317,6321,2200,3895,4491,6134,5365,5560,5641,2651,0168,7531,0092,4478,8313,3640,3413,7462,9541
DATA 1403,9443,4183,7689,8013,2877,3469,9226,6078,9523,0380,9531
END SUB

以下に共通ルーチンをコピペする(多倍長LOG(5)を求める、より)
 

多倍長黄金比を求める

 投稿者:しばっち  投稿日:2010年 1月23日(土)19時24分40秒
返信・引用
  多倍長黄金比を求める (SQR(5)+1)/2=1.618033...

計算式に

    (1-X)^(-.5)=1+(1/2)*X+(1*3)/(2*4)*X^2+(1*3*5)/(2*4*6)*X^3+...

を使用し、以下の関係式

    SQR(5)= 6460 / 2889 * (1 - 1 / 8346321)^(-.5)

を使って黄金比を求める。

PUBLIC NUMERIC KETA,EPS,SIGN
INPUT  PROMPT "桁数=":KETA
LET KETA=INT(KETA/4)
LET EPS=2
LET BIAS=0
LET KETA=KETA+EPS
LET SIGN=-BIAS-1
DIM A(-BIAS-1 TO KETA),S(-BIAS-1 TO KETA),T(-BIAS-1 TO KETA)
LET A(0)=1
LET S(0)=1
LET N=1
DO
   MAT A=(2*N-1)*A
   FOR I = 0 TO KETA - 1
      LET  R = A(I) - INT(A(I)/16692642/N)*(16692642*N)
      LET  A(I) = INT(A(I) /16692642/N)
      LET  A(I + 1) = A(I + 1) + R * 10000
   NEXT I
   LET  A(KETA) = INT(A(KETA)/16692642/N)
   MAT S=S+A
   FOR I = KETA TO 0 STEP -1
      IF S(I) >= 10000 THEN
         LET  R = INT(S(I) / 10000)
         LET  S(I) = S(I) - R * 10000
         LET  S(I-1) = S(I-1) + R
      END IF
   NEXT I
   LET FL=0
   FOR I=0 TO KETA
      IF S(I)<>T(I) THEN
         LET T(I)=S(I)
         LET FL=1
         LET N=N+1
         EXIT FOR
      END IF
   NEXT I
   IF FL=0 THEN EXIT DO
LOOP
MAT S=6460*S
FOR I = KETA TO 0 STEP -1
   IF S(I) >= 10000 THEN
      LET  R = INT(S(I) / 10000)
      LET  S(I) = S(I) - R * 10000
      LET  S(I-1) = S(I-1) + R
   END IF
NEXT I
FOR I = 0 TO KETA - 1
   LET  R = S(I) - INT(S(I)/2889)*2889
   LET  S(I) = INT(S(I)/2889)
   LET  S(I + 1) = S(I + 1) + R * 10000
NEXT I
LET  S(KETA) = INT(S(KETA)/2889)
LET S(0)=S(0)+1
FOR I = 0 TO KETA - 1
   LET  R = S(I) - INT(S(I)/2)*2
   LET  S(I) = INT(S(I)/2)
   LET  S(I + 1) = S(I + 1) + R * 10000
NEXT I
LET  S(KETA) = INT(S(KETA)/2)
CALL DISPLAY(S)
END

EXTERNAL  SUB DISPLAY(X())
FOR K=-BIAS TO 0
   IF X(K)<>0 THEN EXIT FOR
NEXT K
IF K > 0 THEN LET K=0
IF X(SIGN) = -1 THEN PRINT "- ";
PRINT STR$(X(K));" ";
IF K=0 THEN PRINT "."
FOR I=K+1 TO KETA-EPS
   LET L=L+1
   PRINT RIGHT$("000"&STR$(X(I)),4);" ";
   IF I=0 THEN
      PRINT "."
      LET L=0
   END IF
   IF MOD(L,25)=0 THEN PRINT
NEXT I
PRINT
END SUB
 

お願いです

 投稿者:sukehiro  投稿日:2010年 1月24日(日)07時17分32秒
返信・引用
  私も十進BASICの愛用者です。
苦労してァグランジェの方程式と、MuPaDを駆使して、2重振り子の運動方程式c1'',
c2''を導き出し、動作シミュレーションをすることができました。

3重振り子に挑戦したのですが、収拾がつかなくなりました。
どなたか、プログラム作成し掲示していただけると嬉しいです
 

Re: お願いです

 投稿者:山中和義  投稿日:2010年 1月25日(月)10時08分5秒
返信・引用  編集済
  > No.987[元記事へ]

sukehiroさんへのお返事です。
!直列多重振り子
!参考サイト http://www.aihara.co.jp/~taiji/pendula-equations/present-node5.html

LET N=3 !振り子の数

DIM m(N) !振り子のおもりの質量
DATA 0.2, 0.3, 0.2
MAT READ m

DIM l(N) !振り子の糸の長さ
DATA 3, 3, 4
MAT READ l

DIM th(N) !振り子のy軸に対する角度
LET th(1)=2*PI/3 !初期値
LET th(2)=-PI/2
LET th(3)=PI/6

!θ[d](d=1,n)に関するラグランジュ運動方程式
!   m[d,n]*l[d]^2*d/dt^2{θ[d]}
! + Σ[i=1,d-1] m[d,n]*l[d]*l[i]*d/dt^2{θ[i]}*C[d,i]
! + Σ[i=d+1,n] m[i,n]*l[d]*l[i]*d/dt^2{θ[i]}*C[d,i]
! + Σ[i=1,d-1] m[d,n]*l[d]*l[i]*(d/dt{θ[i])^2*S[d,i]
! + Σ[i=d+1,n] m[i,n]*l[d]*l[i]*(d/dt{θ[i])^2*S[d,i]
! + m[d,n]*g*l[d]*SIN(θ[d])
! = 0

LET G=9.8 !重力加速度

FUNCTION sm(k,l) !m[k,l]=Σ[j=k,l] mj
   local s,j
   LET s=0
   FOR j=k TO l
      LET s=s+m(j)
   NEXT j
   LET sm=s
END FUNCTION
DEF C(i,j)=COS(th(i)-th(j)) !C[i,j]=COS(θi-θj)
DEF S(i,j)=SIN(th(i)-th(j)) !S[i,j]=SIN(θi-θj)

!2階微分方程式を連立1階微分方程式にする
! ωd=d/dt{θd}とすると、R*d/dt^2{θd}=vよりd/dt{ωd}=[INV(R)*v]d

DIM R(N,N),v(N)
SUB FNC(t,x(), f()) !連立微分方程式 d/dt{Xi}=f(t,Xi)
   FOR d=1 TO N !行
      FOR i=1 TO N !列
         IF i>d THEN !右上部分
            LET R(d,i)=sm(i,N)*l(d)*l(i)*C(d,i)
         ELSEIF i=d THEN !対角線
            LET R(d,i)=sm(d,N)*l(d)^2
         ELSE !左下部分
            LET R(d,i)=sm(d,N)*l(d)*l(i)*C(d,i)
         END IF
      NEXT i
   NEXT d
   !!!MAT PRINT R;

   FOR d=1 TO N !行
      LET ss=0
      FOR i=1 TO d-1
         LET ss=ss-sm(d,N)*l(d)*l(i)*x(i)^2*S(d,i)
      NEXT i
      FOR i=d+1 TO N
         LET ss=ss-sm(i,N)*l(d)*l(i)*x(i)^2*S(d,i)
      NEXT i
      LET ss=ss-sm(d,N)*G*l(d)*SIN(th(d))

      LET v(d)=ss
   NEXT d
   !!!MAT PRINT v;

   MAT R=INV(R)
   MAT f=R*v
END SUB


SET WINDOW -10,10,-12,8 !描画領域

DIM w(N) !振り子のy軸に対する角速度
MAT w=ZER

LET h=0.01 !時間刻み幅 ��t
FOR t=0 TO 30 STEP h !※調整すること

   SET DRAW mode hidden !ちらつき防止開始
   CLEAR
   DRAW PendulumN(1) !親から順に描画する
   SET DRAW mode explicit !ちらつき防止終了

   !WAIT DELAY 0.2 !※必要に応じて

   !4次のルンゲ・クッタ法で連立微分方程式 d/dt{Xi}=f(t,Xi)を解く
   DIM k1(N),k2(N),k3(N),k4(N), f(N)

   DIM x(N),TT(N)
   MAT x=w
   CALL FNC(t,x, f)
   MAT k1=h*f

   MAT TT=(1/2)*k1
   MAT x=w+TT
   CALL FNC(t+h/2,x, f)
   MAT k2=h*f

   MAT TT=(1/2)*k2
   MAT x=w+TT
   CALL FNC(t+h/2,x, f)
   MAT k3=h*f

   MAT x=w+k3
   CALL FNC(t+h,x, f)
   MAT k4=h*f

   FOR i=1 TO N
      LET w(i)=w(i)+(k1(i)+2*(k2(i)+k3(i))+k4(i))/6 !x(t+h)=x(t)+(k1+2*k2+2*k3+k4)/6
   NEXT i

   MAT TT=h*w !ωd=d/dt{θd}より
   MAT th=th+TT
   !!!MAT PRINT th;

NEXT t


PICTURE PendulumN(i) !n重の振り子を描く
   LET LL=l(i)
   LET AA=th(i)
   DRAW Pendulum(LL,m(i)) WITH ROTATE(AA) !親
   IF i<N THEN DRAW PendulumN(i+1) WITH SHIFT(LL*SIN(AA),-LL*COS(AA)) !階層関係(子へ)
END PICTURE

PICTURE Pendulum(L,r) !原点を基準に振り子を描く
   PLOT LINES: 0,0; 0,-L !糸
   DRAW disk WITH SCALE(r)*SHIFT(0,-L) !おもり
END PICTURE

END
 

有難うございました

 投稿者:sukehiro  投稿日:2010年 1月26日(火)03時48分53秒
返信・引用
  山中和義様、有難うございました。  

3次元 解析ソフト 絵

 投稿者:与坂  昇平  投稿日:2010年 1月26日(火)16時09分3秒
返信・引用
  難しい  数学を  使用しないで  マトリックスが  解れば
理解できる  3次元  の  有限要素法での  構造解析ソフトを  作成しています
今
25要素の  棒を  右端  固定して   左を  持ち上げ
その後  後ろに  押した  グラヒックを  お見せします
full  basic  です

感想は  どうですか  ???
 

3次元の  絵

 投稿者:与坂  昇平  投稿日:2010年 1月26日(火)16時11分14秒
返信・引用
  絵が  載らないので  再度  送ります  

Re: センター試験程度のプログラム演習

 投稿者:山中和義  投稿日:2010年 1月26日(火)19時54分57秒
返信・引用
  > No.976[元記事へ]

三角形の性質をベクトル方程式などで表現してみました。
!図形とベクトル方程式(三角形の心)

!平面の点を「平面のベクトルとみる」と「複素数とみる」と考えられる

OPTION ARITHMETIC COMPLEX

DEF v(a,b)=COMPLEX(a,b) !複素数の和差、実数倍の計算を対応させる

DEF fnDOT(a,b)=( a*conj(b) + conj(a)*b ) / 2 !内積 a1*b1+a2*b2
!絶対値 ベクトル |a|^2=a・a  複素数 |z|^2=z*conj(z)

DEF fnNormalize(a)=a/ABS(a) !正規化

!------------------------------ ここまでがサブルーチン


SET WINDOW -8,8,-8,8 !表示領域を設定する
DRAW grid !XY座標
ASK PIXEL SIZE (-8,-8; 8,8) w,h !画像の縦横の大きさ(ドット単位)を調べる

LET cEps=0.1 !精度 ※調整が必要である

SET POINT STYLE 1 !点の形状


!例 三角形ABCの心
!   C
! b /\ a
! A ── B
!   c

LET OA=v(-4,-5)
LET OB=v(3,-4)
LET OC=v(4,6)

LET AB=OB-OA !辺AB
LET BC=OC-OB !辺BC
LET CA=OA-OC !辺CA

PLOT LINES: Re(OA),Im(OA); Re(OB),Im(OB) !辺ABを描く
PLOT LINES: Re(OB),Im(OB); Re(OC),Im(OC) !辺BC
PLOT LINES: Re(OC),Im(OC); Re(OA),Im(OA) !辺CA


LET a=ABS(BC) !辺BCの長さ
LET b=ABS(CA) !辺CA
LET c=ABS(AB) !辺AB

LET t=(a+b+c)/2 !ヘロンの公式より、面積S
LET S=SQR(t*(t-a)*(t-b)*(t-c))


!------------------------------

LET OI=(a*OA+b*OB+c*OC)/(a+b+c) !内心の位置ベクトル
SET AREA COLOR 4
DRAW disk WITH SCALE(0.2)*SHIFT(OI)

SET LINE COLOR 4
LET R=S/t !S=△IAB+△IBC+△ICA=1/2*c*r+1/2*a*r+1/2*b*r=r*(a+b+c)/2より
DRAW circle WITH SCALE(R)*SHIFT(OI) !内接円を描く |z-α|=r

CALL DrawLine4(OA,OB,OC)
SUB DrawLine4(OA,OB,OC) !�あ�BACを二等分する線
   FOR t=0 TO 10 !t=[0,∞] ※範囲は調整が必要である
      LET wAB=OB-OA
      LET wAC=OC-OA
      LET OP=OA+(fnNormalize(wAB)+fnNormalize(wAC))*t !ひし形AbDcの対角線AD
      PLOT LINES: Re(OP),Im(OP);
   NEXT t
   PLOT LINES
END SUB
CALL DrawLine4(OB,OC,OA)
CALL DrawLine4(OC,OA,OB)


!------------------------------

LET OG=(OA+OB+OC)/3 !重心の位置ベクトル
SET AREA COLOR 2
DRAW disk WITH SCALE(0.2)*SHIFT(OG)

SET LINE COLOR 2
CALL DrawLine2(OA,OB,OC)
SUB DrawLine2(OA,OB,OC) !��点Aと辺BCの中点を通る線
   FOR t=0 TO 10 !t=[0,∞] ※範囲は調整が必要である
      LET OP=OA+(OB+OC-2*OA)*t !平行四辺形ABDCの対角線AD
      PLOT LINES: Re(OP),Im(OP);
   NEXT t
   PLOT LINES
END SUB
CALL DrawLine2(OB,OC,OA)
CALL DrawLine2(OC,OA,OB)



!------------------------------

LET sin2A=2*S*(b^2+c^2-a^2)/(b*c)^2 !sin2A=2*cosA*sinA、余弦定理cosA=(b^2+c^2-a^2)/(2*b*c)、面積S=1/2*b*c*sinAより
LET sin2B=2*S*(c^2+a^2-b^2)/(c*a)^2
LET sin2C=2*S*(a^2+b^2-c^2)/(a*b)^2
LET OQ=(sin2A*OA+sin2B*OB+sin2C*OC)/(sin2A+sin2B+sin2C) !外心の位置ベクトル
SET AREA COLOR 3
DRAW disk WITH SCALE(0.2)*SHIFT(OQ)

SET LINE COLOR 3
LET R=a*b*c/(4*S) !正弦定理a/sinA=b/sinB=c/sinC=2*Rと面積S=1/2*b*c*sinAより
DRAW circle WITH SCALE(R)*SHIFT(OQ) !外接円を描く


!------------------------------

LET tanA=2*S/(b^2+c^2-a^2) !tanA=sinA/cosAと余弦定理cosA=(b^2+c^2-a^2)/(2*b*c)と面積S=1/2*b*c*sinAより
LET tanB=2*S/(c^2+a^2-b^2)
LET tanC=2*S/(a^2+b^2-c^2)
LET OH=(tanA*OA+tanB*OB+tanC*OC)/(tanA+tanB+tanC) !垂心の位置ベクトル
SET AREA COLOR 1
DRAW disk WITH SCALE(0.2)*SHIFT(OH)


FOR j=0 TO h !画面全体を走査する
   LET y=worldy(j) !ドットをxy座標に変換する
   FOR i=0 TO w
      LET x=worldx(i)

      LET OP=v(x,y)

      SET POINT COLOR 3 !外心
      IF ABS( fnDOT(OP-(OB+OC)/2,BC) )<cEps THEN PLOT POINTS: x,y !�J�BCの垂直二等分線
      IF ABS( fnDOT(OP-(OC+OA)/2,CA) )<cEps THEN PLOT POINTS: x,y
      IF ABS( fnDOT(OP-(OA+OB)/2,AB) )<cEps THEN PLOT POINTS: x,y

      SET POINT COLOR 1 !垂心
      IF ABS( fnDOT(OP-OA,BC) )<cEps THEN PLOT POINTS: x,y !�‥�Aから辺BCへの垂線 AP⊥BC
      IF ABS( fnDOT(OP-OB,CA) )<cEps THEN PLOT POINTS: x,y
      IF ABS( fnDOT(OP-OC,AB) )<cEps THEN PLOT POINTS: x,y

   NEXT i
NEXT j


END
 

ゲーム解析のお願い

 投稿者:GAI  投稿日:2010年 1月27日(水)11時42分43秒
返信・引用  編集済
  52枚のカードから任意の13枚を抜き出すと、必ず4枚の同じマークのカードが含まれるようになるので、この4枚だけが表向きで終了するような作品を作りたい。
表にしたいカードの位置として考えられる全パターンが13C4=715通り考えられ、これらがすべて可能であるのか知りたい。

<13枚のパケットの操作方法>
裏向きに持ち、上から任意の枚数でひっくり返しパケットに戻す。
この操作を何回かくり返していき、目的の4枚だけが表向きになっている状態にする。

パケットの上から持ち上げる枚数と最終表のカード(*)の例

4枚
1        *4
2        *3
3        *2
4        *1
5         5
6         6
7         7
8         8
9         9
10       10
11       11
12       12
13       13


6枚   3枚   4枚   9枚
1       *6        4        3        *9
2       *5        5       *6        *8
3       *4        6       *5        *7
4       *3       *3       *4         1
5       *2       *2       *2         2
6       *1       *1       *1         4
7        7        7        7         5
8        8        8        8         6
9        9        9        9        *3
10       10       10       10        10
11       11       11       11        11
12       12       12       12        12
13       13       13       13        13

最終パターンを達成するための持ち上げる枚数の戦略を知りたい。
 

Re: ゲーム解析のお願い

 投稿者:山中和義  投稿日:2010年 1月27日(水)16時11分19秒
返信・引用
  > No.993[元記事へ]

GAIさんへのお返事です。

例
 1,2,3,4,5,6,7,8,9,10,11,12,13
   ↓
 -9,-8,-7,1,2,4,5,6,-3,10,11,12,13

 枚数列{6,3,4,9}の4手が最少手数のようです。

LET t0=TIME


PUBLIC NUMERIC N !カードの枚数
LET N=13

DIM c(N) !最初のパターン ※
DATA 1,2,3,4,5,6,7,8,9,10,11,12,13
MAT READ c

PUBLIC NUMERIC GOAL(100) !最終のパターン ※
MAT GOAL=ZER(N)
DATA -9,-8,-7,1,2,4,5,6,-3,10,11,12,13
MAT READ GOAL

PUBLIC NUMERIC LIMIT !手数の上限 ※
LET LIMIT=10

DIM A(LIMIT) !枚数
CALL backtrack(c,1,A)


PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB reverse(c(),P) !先頭からP枚を裏返す
FOR i=1 TO INT(P/2) !交換
   LET t=c(i)
   LET c(i)=c(P-i+1)
   LET c(P-i+1)=t
NEXT i
FOR i=1 TO P !反転
   LET c(i)=-c(i)
NEXT i
END SUB

EXTERNAL SUB backtrack(c(),K,A()) !バックトラック法で検証する
IF K<=LIMIT THEN !手数の上限内なら
   DIM x(N)
   MAT x=c !save it

   FOR i=1 TO N !枚数を変える
      LET A(K)=i
      CALL reverse(c,i) !反転

      FOR j=1 TO N !最終のパターンかどうか確認する
         IF c(j)<>GOAL(j) THEN EXIT FOR
      NEXT j
      IF j>N THEN !一致したら
         LET LIMIT=K-1 !上限を狭める ※最初に見つかったもの
         PRINT K;"手"
         FOR j=1 TO K
            PRINT A(j); !枚数
         NEXT j
         PRINT
         !!!MAT PRINT c; !debug
      ELSE
         CALL backtrack(c,K+1,A) !次へ
      END IF

      MAT c=x !restore it
   NEXT i
END IF
END SUB
 

Re: ゲーム解析のお願い

 投稿者:GAI  投稿日:2010年 1月27日(水)19時12分53秒
返信・引用
  > No.994[元記事へ]

山中和義さんへのお返事です。

さっそく作って頂きありがとうございます。
自分で少し変更してみようと試みましたが、迷路に入り再びお願いがあります。

カードを任意の枚数でひっくり返していくとき、表が4枚になったならカードの配列を表示し(最終パターンに相当するもの。)
そこまでの、持ち上げる枚数を同時に見てみたい。


この表が4枚となるあらゆるパターン(最初の何番目のカードが表かでの違いについての)は調べることは出来ますか?
 

Re: ゲーム解析のお願い

 投稿者:山中和義  投稿日:2010年 1月27日(水)20時26分9秒
返信・引用
  > No.995[元記事へ]

GAIさんへのお返事です。
LET t0=TIME


PUBLIC NUMERIC N !カードの枚数
LET N=13

DIM c(N) !最初のパターン ※
DATA 1,2,3,4,5,6,7,8,9,10,11,12,13
MAT READ c

PUBLIC NUMERIC LIMIT !手数の上限 ※
LET LIMIT=4

PUBLIC NUMERIC cMIN !最少手数
LET cMIN=LIMIT+1

DIM A(LIMIT) !枚数
CALL backtrack(c,0,A)

IF cMIN<=LIMIT THEN PRINT "最少手数=";cMIN


PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB reverse(c(),P) !先頭からP枚を裏返す
FOR i=1 TO INT(P/2) !交換
   LET t=c(i)
   LET c(i)=c(P-i+1)
   LET c(P-i+1)=t
NEXT i
FOR i=1 TO P !反転
   LET c(i)=-c(i)
NEXT i
END SUB

EXTERNAL SUB backtrack(c(),K,A()) !バックトラック法で検証する
LET s=0
FOR j=1 TO N !表の枚数を確認する
   IF c(j)<0 THEN LET s=s+1
NEXT j
IF s=4 THEN !一致したら
   IF K<cMIN THEN LET cMIN=K !最少手数を記録する
   PRINT K;"手"
   FOR j=1 TO K
      PRINT A(j); !枚数列
   NEXT j
   PRINT
   MAT PRINT c; !最終のパターン
ELSE
   IF K<LIMIT THEN !手数の上限内なら
      DIM x(N)
      MAT x=c !save it

      FOR i=1 TO N !枚数を変える
         IF K>=1 AND i=A(K) THEN !同じ手が続く場合は無効!
         ELSE
            LET A(K+1)=i
            CALL reverse(c,i) !反転

            CALL backtrack(c,K+1,A) !次へ

            MAT c=x !restore it
         END IF
      NEXT i
   END IF
END IF
END SUB
 

分析して分かったこと

 投稿者:GAI  投稿日:2010年 1月30日(土)16時10分20秒
返信・引用
  山中さんから作って頂いたプログラムを動かしてその結果を整理していたら、次の原理が見えてきました。
表にしたいカードの最初の位置が上から例えば3,7,8,11番目であったとすると
一回目:2枚(これは3の手前までの枚数)
二回目:3枚(これは最初のカードの位置3に対応する)
三回目:6枚(次の7の手前までの枚数)
四回目:8枚(7,8と連続しているから8までの枚数)
五回目:10枚(最後の11の手前までの枚数)
六回目:11枚(最後の11に対応する)

分かってみると当たり前に感じるが、最初からこのことにはなかなか気がつかない。
従ってカードがどこに何枚あろうがこの原則さえ熟知しておけばちょっとしたゲームやパズルに応用が利く。
 

Re: 分析して分かったこと

 投稿者:山中和義  投稿日:2010年 1月30日(土)20時24分52秒
返信・引用
  > No.997[元記事へ]

GAIさんへのお返事です。

(p-1)枚、p枚とめくると、-p,1,2,3,…,p-1 の順に並ぶ。

これは、「p番目のカードのみを表向きで先頭へ。以降の順番は変わらず」を意味する。

参考
 反転操作によるブロック移動(No.716 [元記事へ])
 の2分割の特殊形(前半部分(p-1)個と後半部分1個より、前半と全体の反転)となります。
 

小作品

 投稿者:GAI  投稿日:2010年 1月31日(日)08時40分56秒
返信・引用
  1〜10の番号(同一マークで)のカードを準備し

1.客に電話番号を何気に聞く。(ただし4つの数字はすべて異なってなければならない。
そうでないなら、他の数字を考えてもらう。)
<例>
客の番号:9265
これを小さい順に並べ、基準数とする。
基準数 :2569

2.10枚のカードを上からすべて裏向きで
2番目に9
5番目に2
6番目に6
9番目に5
のカードが位置するように(0はカード10で作業する。)何気にセットしておく。
他の位置のカードは何でもよい。
<頭の中で電話番号と基準数を対応させて作業する。>

3.このパケットをフォールスシャッフルし
先の方法で基準数の数字が表向きに出現する操作をやる。
演技的には、如何にも無造作にやっていると感じさせるように・・・
「これらをよーく混ぜます。」などの口上と共に作業する。
この例では
1回目:上から1枚持ち上げひっくり返して元に戻す
2回目:2枚持ち上げ同じく返して戻す
3回目:4枚
4回目:6枚
5回目:8枚
6回目:9枚

このとき最後の操作でトップに4枚の表向きカード(5,6,2,9の順番)
が来るから、最後の時にパケットをひっくり返しながらこれがボトム側へ来るように持ち替える。

4.上から5枚を数え取り(すべて表向きカード)右手に持つ。

5.残った左手のパケットとパーフェト・リフル・シャッフルをする。
 (右手から先ず1枚落とし、次に左手から1枚、次に右手より1枚、・・・と交互にパラパラとテーブルにカードを噛み合わせながら落としていく。:慣れると簡単です。)

6.カードを揃え、パケットをすべてひっくり返して右手に持つ。
  「電話番号は何でしたっけ?」と確認をとり
  テーブルへパケットをリボンスプレッドして下さい。
  **9*2*6*5*    (*は裏向きカード)
  で並びます。


客を驚かせるようにするのは大変です。
 

この問いはプログラム可能ですか?

 投稿者:GAI  投稿日:2010年 1月31日(日)09時44分45秒
返信・引用
  1^3+2^3+3^3+・・・・+n^3
=1*1^2+2*2^2+3*3^2+・・・・n*n^2
=(1+2+3+・・・・+n)^2(={n(n+1)/2}^2)

のよく知られた関係式は

一辺が1の正方形が1個
一辺が2の正方形が2個
一辺が3の正方形が3個
・・・・・・・・・・
一辺がnの正方形がn個
を使って、一辺がn(n+1)/2 の正方形を敷き詰める可能性を示唆する。

さて本当にこのことを実現できるのはnがいくつのときでしょうか?
その最小値を調べてください。(n>1の条件で)
またこの時の敷き詰め図は?