ラベル SysRPL の投稿を表示しています。 すべての投稿を表示
ラベル SysRPL の投稿を表示しています。 すべての投稿を表示

2015年6月11日木曜日

グラフ電卓の愉しみ #2 - Pickover Attractor

グラフ電卓には、それなりのグラフィクス機能があります。簡単なプログラムで興味深いグラフィクスを描き出す「Clifford Attractors」のプログラムを作成してみました。

Clifford A. Pickover 氏によるアトラクタで、en wiki には、2DのClifford attractor、3Dの「Pickover attractor」がある、と書かれています。3Dの表示はPCでも少々手数が掛かってしまうので、2D表示で出来るClifford attractor について、行ってみました。
Clifford attractorについては、以下のサイトで例が示されています。

Clifford Attractor
http://paulbourke.net/fractals/clifford/

ここで紹介されているグラフィクスは高性能のコンピュータを使って描き出されたものですから、これがそのままグラフ電卓で再現できるわけではないのですが、大まかな所は十分に描き出される筈です。

先ずは、TI-83+ で描いてみました。プログラム自体は実に簡単ですが、結構時間が掛かります。

PROGRAM:ATTRCT
:AxesOff
:ClrDraw
:0.5→X:0.5→Y
:For(I,1,1000)
:Pt-On(X,Y)
:sin(AY)+Ccos(AX)→Z
:sin(BX)+Dcos(BY)→Y
:Z→X
:End

プログラムを実行する前に、細かい指定を行っておかないとなりません。

1. Clifford attractor では、A, B, C, Dの4つのパラメタを変換させる事で、様々な意匠が得られます。プログラム実行前に、変数A, B, C, Dを予め指定しておきます。

例)
1.32→A : 0.804→B : 2.568→C : 1.824→D

2. つぎに、グラフを描く範囲を指定しておきます。TI83+の場合、グラフ電卓の機能として描図領域の設定等を電卓のメニューから行います。X, Y共に、-4~+4の範囲で描くと、いい感じです。

ついでにHP50GのSysRPLで作成したものを掲載しておきます。UserRPLより断然早いのですが、それでも1分以上掛かってしまいますネ。
こちらの場合は、スタックにA, B, C, Dの数値を積み、プログラムを実行します。
描図範囲は PPAR を参照するので、プログラム実行前に[WIN]キー([Left-Shift]+[F2])で描図範囲を設定して下さい。

!NO CODE
!RPL

::

0LASTOWDOB!
CK2NOLASTWD
CK&DISPATCH1
#1111

  ::

  GETXMIN GETXMAX GETXMIN %-
  GETYMAX GETYMAX GETYMIN %-

  { LAM a LAM b LAM c LAM d LAM xmin LAM xrng LAM ymax LAM yrng } BIND

  CLEARLCD
  TURNMENUOFF

  80 131 MAKEGROB
  GROB>GDISP
  TOGDISP

  ' ID X PURGE
  %0.5 ' ID X CREATE
  ' ID Y PURGE
  %0.5 ' ID Y CREATE

  1000 0 DO
    LAM a ID Y %* %SIN LAM c LAM a ID X %* %COS %* %+
    LAM b ID X %* %SIN LAM d LAM b ID Y %* %COS %* %+
    ' ID Y STO ' ID X STO

    ID X LAM xmin %- LAM xrng %/ %131 %* COERCE
    LAM ymax ID Y %- LAM yrng %/ %80  %* COERCE
    PIXON3
  LOOP

  ABND
  ;
;
@


グラフ電卓の愉しみ #1 - Sierpinski gaskets

プログラムで描くグラフィクスという事で、今回は「Sierpinski gaskets」を御紹介。

TI-83+のマニュアルには、Sierpinski gaskets を「乱数を使う手法」で描くプログラムが掲載されています。
Sierpinski gasketsは「再帰図形」なので、再帰処理によって描く事が出来るのですが、TI-83+には再帰処理のメカがないため、乱数を使う手法を例示していたのでした。

HP50GでRPLを使うと、再帰処理のプログラムを作成できます。今回も懲りずにSysRPLで書いたプログラムを示します (もちろん、UserRPLでも書けます)。

ユーザーが使える「スタック」を用意する事で、BASICでも再帰処理のプログラムは書けると思います。Androidの「BASIC !」には、スタックのメカが用意されておりました。3DSのプチコンにもスタックのメカがあるそうです(藤堂様、多謝 !)から、再帰処理プログラムの作成は可能です、多分。
(こちゃこちゃしてしまい、当方、着手出来ず。申し訳ない。loadがガンガン上がって、頭から湯気が出ております ...)

!NO CODE
!RPL

::
  '
  ::
    {
      LAM ax LAM ay LAM bx LAM by LAM cx LAM cy LAM d
    } BIND

    LAM d #0= ITE
    :: 
      LAM ax 80 LAM ay #- LAM bx 80 LAM by #- DRAWLINE#3
      LAM ax 80 LAM ay #- LAM cx 80 LAM cy #- DRAWLINE#3
      LAM bx 80 LAM by #- LAM cx 80 LAM cy #- DRAWLINE#3
    ;

    ::  
      LAM ax LAM ay 
      LAM ax LAM bx #+ #2/ LAM ay LAM by #+ #2/ 
      LAM ax LAM cx #+ #2/ LAM ay LAM cy #+ #2/ 
      LAM d #1- LAM sier EVAL

      LAM ax LAM bx #+ #2/ LAM ay LAM by #+ #2/ 
      LAM bx LAM by 
      LAM bx LAM cx #+ #2/ LAM by LAM cy #+ #2/ 
      LAM d #1- LAM sier EVAL

      LAM ax LAM cx #+ #2/ LAM ay LAM cy #+ #2/ 
      LAM bx LAM cx #+ #2/ LAM by LAM cy #+ #2/ 
      LAM cx LAM cy 
      LAM d #1- LAM sier EVAL
    ;
    ABND
  ;

  { LAM sier } BIND

  CLEARLCD
  TURNMENUOFF

  80 131 MAKEGROB
  GROB>GDISP
  TOGDISP

  65 80 25 1 105 1 4
  LAM sier EVAL
  SetDAsTemp

  ABND
;
@



SysRPLで再帰大作戦

SysRPLで再帰処理を書くにはどうするのか、気になって居りました。

ここでは、再帰処理による階乗計算の例を示しておきます。

!NO CODE
!RPL

::
  { LAM n } BIND

  LAM n %0 %> 
  ITE 
    ::  LAM n DUP %1 %- ID facto %*  ;
    ::  %1 ;
  ABND
;
@


これをASM でコンパイルし、スタックに載っているSysRPLコードを「'facto' STO 」とやって保存すると使える様になります。CK2とか使っていないので、パラメタは決め打ちです。実数として明確にスタックに数を置き、引き続いてfacto と打ち込みます。
例えば、70の階乗を求めるには、「70. facto」とやってやります。70の後に少数点をつけて実数とするのです。

実は、局所変数に関数定義を束縛し、呼び出すという技法があります。

SysRPL Recursion Question - comp.sys.hp48
https://groups.google.com/forum/#!topic/comp.sys.hp48/JrtXN0bz1QU

上記ではAckermann functionの例が出ておりますが、こちらでは上と同じく階乗の例を示しておきます。

!NO CODE
!RPL

::
  '
  :: 
    { LAM n } BIND
    LAM n %0=
    ITE
      :: %1 ;
      :: LAM n %1- LAM facto EVAL LAM n %* ;
    ABND
  ;
  { LAM facto } BIND
  LAM facto EVAL
  ABND
;
@

冒頭の「'」は、以降のプログラム節 (「::」と「;」で括られたもの) をQuoteする、というものです。これにより、

  :: 
    { LAM n } BIND
    LAM n %0=
    ITE
      :: %1 ;
      :: LAM n %1- LAM facto EVAL LAM n %* ;
    ABND
  ;

の部分を実行(評価)せずに、「そのまま」の状態でスタックに置く、というイメージです。続く「{ LAM facto } BIND」によって局所変数(シンボル)facto に束縛します。
更に「LAM facto EVAL」で、factoシンボルに束縛されたプログラム節をEVALにて評価する事で、実行します。
最後は「ABND」で、BINDで束縛した局所シンボルスコープを脱し、プログラムの終了という具合です。

2015年4月30日木曜日

HP50g : SysRPLで配列を扱うためのメモ

SysRPLにも配列(行列、ベクトル)を確保するためのコマンドがいくつかあります。まずは「^MAKEARRY 」というコマンドを使ってみようと思いました。

HP49G Entry Reference
https://staff.fnwi.uva.nl/c.dominik/hpcalc/entries/hp49g/entries.pdf

には、SysRPLの多くのコマンドが掲載されています。しかし、これに従ってコードを書いてみたのですが、なかなかうまく動いてくれません。(注意 ! このコードは確実に暴走します)

!NO CODE
!RPL
::
  { 3 } %2.3 ^MAKEARRY
;
@

ホトホト困り果て、調べてみた所、どうやら足りないモノがあった模様。

HP49G SYSRPL ^MAKEARRY HELP - compgroups.net
http://compgroups.net/comp.sys.hp48/hp49g-sysrpl-makearry-help/123989

によると、「If the command start with ^, add FPTR2」とあります。^MAKEARRYの様にキャレットで始まるコマンドを使う場合、FPTR2 を付けよ、という具合らしい。エェッー、そんなん聞いていないヨ !!
そんな具合で、取り敢えず「配列を作る(だけの)」プログラムは、こんな具合になりました。

!NO CODE
!RPL
::
  { 3 } %2.3 FPTR2 ^MAKEARRY
;
@

  1. { 3 } で作成する配列の大きさを指定し、
  2. 各要素の初期値を %2.3 (実数値の2.3) として、
  3. FPTR2 ^MAKEARRY で配列を作成します。

これで作成できるのは配列と言っても「ベクトル(1次元配列)」です。大きさの指定を変える事で行列(2次元配列)も作成できます。

配列を作る命令語には、ほかに「^XEQ>ARRY」などがあります。^XEQ>ARRYは、スタックから、配列の大きさと構成する要素を取り出して配列を構成します。キャレットが付いているので「FPTR2」を忘れずに。
配列の要素取り出しには「GETATELN」、要素設定には「PUTEL」があり、この辺りのコードを使った習作を示しておきます。

!NO CODE
!RPL
::
    %0 %1 %2 %3 %4 { %5 } FPTR2 ^XEQ>ARRY
    DUP
    #4 SWAP GETATELN DROP
    %5 %* #3 PUTEL
;
@

無事に実行が終わると [0. 1. 15. 3. 4.] というベクトルがスタックに残っている筈です。

大して長いコードではないのですが、勉強しながらの作業なので暴走させる事もしばしばです。

今回は、リセットが効かない暴走を経験しました。リセットを掛けようとON+[F3], ON+[F1]+[F6] を押しても、反応がないのです。画面の下、4/5が真っ黒くろすけになって、動きがないのですね。これはコマッタ。

Educalc.netに「電池抜きリセット」(電池を全て取り外し、15分以上放置新聞)というTipsが出ていたので、藁をもすがる思いで試したのですが、電源を入れても同様の状態です。ウーム !?
検索していたら、「FlashROM更新とセルフテストメニューの呼び出し」という話題が見つかって、「そうだ、コレだ」と試してみる事にしました。ON+[F3]が効かないので、電池を入れる前に「+」、「-」キーの両方を押しておき、押しながら電池を装填するという奇っ怪な技でメニューの呼び出しに成功し、セルフテストも一通り問題ない事が確認できました。ハードウェアはイカれていない様子。そこで判ったのは「SysRPLの暴走で、FlashROMが書き換わってしまった」という可能性です。
現在、最新のROMは2.15で、これは一度書き込んでいるので、手元にイメージはあります。早速、SDカードによるFlashROMの書き込みを行い、ようやく復旧したという次第です。ヨカッタ、ヨカッタ。