maxima

昨日のチコちゃんで、一つのスピーカーなのに色々な音が聞こえるのは何故? てのをやってた。お約束で、誰も答えられず。

電通大の先生によると、それは、耳が音をバラバラにしているからーー と、分かったような分からないような回答。

阿佐ヶ谷姉妹とか言う(昔で言うこまどり姉妹か)ユニットな人達が出てきて、姉の声、妹の声、それに被せてピアノやらトライアングルやらでお囃子。不思議な事に、確かに聞き分けられる。

スピーカーから出て来る音は、これらを全て合成した、一つの波。そう考えると、分解してるのは、それを聞く人しかない。

耳は外耳、中耳、内耳の3つによって構成されている。外耳は音を集めるパラボラアンテナ、中耳は、音の増幅器、内耳は音を電気パルスに変換する機能を負っている。

音の増幅器と言っても、単純に増幅すると非常にまずい事になる。やっと聞こえる小さな音からジェットエンジンの爆音まで、音の強さで言うと100万倍ぐらい違う。この範囲の音でもちゃんと内耳に異常なく伝わるように、増幅や減衰を行っている。(ああ、無駄知識ですね)

姉の低い声は、内耳の中にある蝸牛とか言う、とぐろを巻いたくだみたいな器官の深い部分で、妹の高い声は気管の浅い部分で、他の音も高さによって感じる部分が違うらしい。

これってエレキテル風に言うとフィルターなのかな? それともFFTなの? タイムドメインな音を周波数ドメインに変換して、それを脳味噌コンピューターで分析してる?

聖徳太子(近頃の教科書では、別の呼び方をするらしいけど)は、同時に10人の話を聞けたらしい。だとすると、大昔にもスーパーコンピューターが存在してた事になる。

シリだとかコルチナだかアマゾンエコーで人の話声を拾えるらしいけど、まだまだ複数の声を同時に認識出来るレベルまでは到達していないはず。結構なパワーを持った石を使っても達せられない領域。

それを人間はいとも簡単に実現しちゃう。渋谷の交差点みたいな雑踏の中でも、相手の声を容易に聞き分けられる。

現場川柳を見ていたら、(5カ国語、タダで学べる、我が現場) なんてのが有ったけど、知ってる言語と言うか単語は、何となく聞き分けられるな。

年寄り川柳もあるな。

ボーとして、テレビの中から、叱られる

鳴る家電、どれかわからぬ、手をあげろ

ワシャできん、シリをつかって、話せだと?

渋谷で思い出した。もうすぐ かぼちゃ祭り。去年は軽トラがヒックリ返されたから、今年は是非、ダンプでもヒックリ返して気勢を上げてください。(追跡されてタイーホされても、責任は取れんけど!)

maxima

ある方がネットから情報を得る時のこつを披露されてた。例えば、前回取り上げたmaximaの情報を欲しいなら、

maxima filetype:pdf site:.ac.jp

日本の大学で、PDFで書かれた資料ってのを指示すると、良質なものが手に入るらしい。英語でよければ、site:edu と指示。先生によっては古い版用の資料を公開してる事が有るんで、公開時期を見繕っておいた方が良いと思われ。

無料数式処理ソフト Maxima(pdf)

Maxima 5.42.2 Manual

maxima を source から

CentOS8でmaximaを使おうとしたら見つからない。企業向けだから、遊び道具には用が無いのだろう。でも、ひょっとして、

(base) [sakae@c8 ~]$ dnf grouplist
  :
Available Groups:
   Scientific Support

こういう福袋に入っていないかしらねぇ。ダメダメ、単体の注文にも対応出来ないんだから、取り扱いはしておりませんって事だろう。じゃ、例によって自分で何とかする。

そもそも、 CentOS 8 にしたきっかけは、sbclを入れようとしたら CentOS7系のglicでは古すぎると馬鹿に されたからだった。そんな訳で、8にはsbclが入ってる。なら、ソースから入れるのも容易い事だろう。

Maxima download

へ行ったら、パッケージも有ったけど、初志貫徹。ソースから。

configureが付いているので普通にやれば良い。コンパイルはxx.lspのコンパイルなのね。 sudo make install したら、sbclが見つからんと言われた。何でかなあ、なんでかな?と、3秒考えたら理由が分かった。

root権限のユーザーでは、sbclのPATHが通っていなかったから。それにしても、インストールまでsbclの力を借りるんかい。がちがちのlisp派なんだな。

INSTALLの文書を見たら

(1) Lisp-only build

    Lisp-only build is suitable for systems lacking GNU Autotools,
    e.g. MS Windows systems. Lisp-only build creates a Maxima
    executable image, but it does not create the Maxima texinfo
    documentation, it does not adjust various pathnames and other
    environmental variables in the maxima and xmaxima scripts,
    it does not install Gnuplot, and it does not create an
    installer file (neither RPM or Windows installer).
      :
(4) Unix GNU Autotools build and install

    Unix GNU Autotools build and install is suitable for Unix and
    Unix-like systems (e.g. Linux) with GNU Autotools.

こんな事が書かれていて、INTALL.lispには、lisp派の手順の説明があった。

(1) Launch your Lisp implementation.
(2) Load the file configure.lisp:
    (load "configure.lisp")
(3) Generate configuration files:
    (configure)
(5) cd src then Restart Lisp, and load maxima-build.lisp:
    (load "maxima-build.lisp")
(6) Compile the Lisp source code:
    (maxima-compile)
(7) Quit Lisp, and restart Lisp.
(8) Load the compiled Lisp files:
    (load "maxima-build.lisp")
    (maxima-load)
(9b) As an alternative to executing maxima immediately, most Lisps support
    dumping the compiled application as an image that can later be loaded in

    "(maxima-dump) works when threading is disabled."
    Some Lisp implementations (SBCL, GCL, CMUCL, Scieneer, maybe others)
    terminate after saving the image.

つい熱が入ってしまったわい。

/usr/local/binの下には、maxima、rmaxima、xmaximaって言う起動スクリプトが用意されるけど、お勧めは、rmaxima。補完が効くから、不案内な人にはうってつけ。

(base) [sakae@c8 ~]$ rmaxima
Maxima 5.43.0 http://maxima.sourceforge.net
using Lisp SBCL 1.5.6
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) sin(%pi/4);
                                       1
(%o1)                               -------
                                    sqrt(2)
(%i2) bf
bf_fft               bfallroots           bfpsi0
bf_find_root         bffac                bftorat
bf_fmin_cobyla       bfhzeta              bftrunc
bf_inverse_fft       bfloat               bfzeta
bf_inverse_real_fft  bfloatp
bf_real_fft          bfpsi
(%i4) ? bfloat


 -- Function: bfloat (<expr>)

     Converts all numbers and functions of numbers in <expr> to bigfloat
     numbers.  The number of significant digits in the resulting
     bigfloats is specified by the global variable 'fpprec'.

     When 'float2bf' is 'false' a warning message is printed when a
     floating point number is converted into a bigfloat number (since
     this may lead to loss of precision).

  There are also some inexact matches for `bfloat'.
  Try `?? bfloat' to see them.

xmaximaはTclと言うかwishの支援を受けているが、ちと使いずらそう。それより、gnuplotと連携してグラフを書けるのがいいな。

on OpenBSD

OpenBSDでは、満遍なくパッケージが用意されている。勿論maximaもね。

ob$ maxima
;;; Loading #P"/usr/local/lib/ecl/sb-bsd-sockets.fas"
;;; Loading #P"/usr/local/lib/ecl/sockets.fas"
;;; Loading #P"/usr/local/lib/ecl/defsystem.fas"
;;; Loading #P"/usr/local/lib/ecl/cmp.fas"
Maxima 5.42.2 http://maxima.sourceforge.net
using Lisp ECL 16.1.3
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1)

ん? ちと版が古いな(そんなの誤差のうち)。折角最新のソースが有るんだかから、Lisp派のインストールを試してみるか。きっと経験値が上がるだろう。

ob$ ecl
ECL (Embeddable Common-Lisp) 16.1.3 (git:UNKNOWN)
 :
Type :h for Help.
Top level in: #<process TOP-LEVEL>.
> (load "configure.lisp")

;;; Loading "/home/sakae/maxima/configure.lisp"
#P"/home/sakae/maxima/configure.lisp"
> (configure)
Enter the Maxima directory [/home/sakae/maxima]:

Is this a Windows system? (true/false) [false]:

Posix shell (optional) [/bin/sh]:

Name of the Clisp executable (optional) [clisp]:
no
 :
Name of the ECL executable (optional) [ecl]:
 :
Created maxima-local
Created src/maxima
Created src/maxima.bat
Created src/autoconf-variables.lisp
("maxima-local.in" "src/maxima.in" "src/maxima.bat.in"
 "src/autoconf-variables.lisp.in")

指示に従ってlisp流のconfigure。肝はお前どんなlispを使ってるって所だろう。eclってのは、組み込み用の小さいlispだ。

ob$ cd src
ob$ ecl
> (load "maxima-build.lisp")

;;; Loading "/home/sakae/maxima/src/maxima-build.lisp"
;;; Loading "/home/sakae/maxima/src/../lisp-utils/defsystem.lisp"
;;; Loading #P"/usr/local/lib/ecl/cmp.fas"
;;; Loading "/home/sakae/maxima/src/maxima-package.lisp"
;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3, Debug=0
;;;
;;; End of Pass 1.
#P"/home/sakae/maxima/src/maxima-build.lisp"
> (maxima-compile)
   :
;;; Compiling (DEFUN SHARE-SUBDIRS-LIST ...).
;;; End of Pass 1.
;;; Emitting code for SHARE-SUBDIRS-LIST.
;;; Finished compiling /home/sakae/maxima/src/share-subdirs.lisp.
;;;
;;;
;;; Compiling /home/sakae/maxima/src/init-cl.lisp.
;;; OPTIMIZE levels: Safety=2, Space=3, Speed=3, Debug=2
;;;
;;; Compiling (DEFVAR *MAXIMA-BUILD-TIME* ...).
;;; Compiling (DEFVAR *MAXIMA-PREFIX*).
   :
 #<MODULE: declarations> #<MODULE: sloop> #<MODULE: info> #<MODULE: intl>
 #<MODULE: package>)

Makefileに変わって、build用のlispコードを読み込み、maxima用のlispコードをコンパイルする。eclの場合は、lispコードをC語に変換、それをllvmでオブジェクトコードに落とす事を繰り返す。ああ、ある程度はモジュールに組み上げているんか。

ob$ ecl
> (load "maxima-build.lisp")
> (maxima-load)

;;; Loading "/home/sakae/maxima/src/maxima.system"
(#<MODULE: final> #<MODULE: graphics-drivers> #<MODULE: translated-packages>
 #<MODULE: poisson-series> #<MODULE: miscellaneous> #<MODULE: debugging>
 #<MODULE: solve> #<MODULE: limits> #<MODULE: determinants>
 #<MODULE: matrix-algebra> #<MODULE: special-functions>
 #<MODULE: definite-integration> #<MODULE: taylor-series>
 #<MODULE: integration> #<MODULE: algebraic-database> #<MODULE: documentation>
 #<MODULE: gcd> #<MODULE: display> #<MODULE: reader>
 #<MODULE: numerical-functions> #<MODULE: trigonometry>
 #<MODULE: pattern-matching> #<MODULE: maxima-language-compiler>
 #<MODULE: rational-functions> #<MODULE: ifactor> #<MODULE: factoring>
 #<MODULE: i-o> #<MODULE: server> #<MODULE: numeric-bigfloat>
 #<MODULE: simplification> #<MODULE: numerical> #<MODULE: evaluator>
 #<MODULE: commands> #<MODULE: utilities> #<MODULE: rat-macros>
 #<MODULE: other-macros> #<MODULE: utility-macros>
 #<MODULE: fundamental-macros> #<MODULE: command-line> #<MODULE: getopt>
 #<MODULE: maxima-language-compiler-macros> #<MODULE: prerequisites>
 #<MODULE: compatibility-macros> #<MODULE: defmfun>
 #<MODULE: compatibility-macros1> #<MODULE: destructuring-let>
 #<MODULE: declarations> #<MODULE: sloop> #<MODULE: info> #<MODULE: intl>
 #<MODULE: package>)
> (maxima-dump)
Sorry, I don't know how to dump an image on this Lisp
NIL

そして、今度はそのモジュールを読み込んでから、メモリーイメージを作る。んだけど、eclには、そんな事は出来ないようだ。苦し紛れに、勘を働かせてみたら、動いちゃよ。

> (run)

Maxima 5.43.0 http://maxima.sourceforge.net
using Lisp ECL 16.1.3
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) sin(%pi/4);
                                       1
(%o1)                               -------
                                    sqrt(2)

確かmaximaとlispの間を行ったりきたり出来たはず。

(%i2) to_lisp();

Type (to-maxima) to restart, ($quit) to quit Maxima.

MAXIMA>
MAXIMA> ($qui)

Maxima encountered a Lisp error:                                                
 The function $QUI is undefined.
Automatically continuing.
To reenable the Lisp debugger set *debugger-hook* to nil.

MAXIMA> (setq *debugger-hook* nil)

NIL
MAXIMA> (namespace)

Condition of type: UNDEFINED-FUNCTION
The function MAXIMA::NAMESPACE is undefined.

Available restarts:

1. (MACSYMA-QUIT) Maxima top-level
2. (RESTART-TOPLEVEL) Go back to Top-Level REPL.

Broken at SI:BYTECODES. [Evaluation of: (MAXIMA::NAMESPACE)] In: #<process TOP-LEVEL>.
>>

戻ろうとしたら綴りを間違えた。おかげで、debuggerに落ちる方法を知った。怪我の功名である。色々出来そうで、楽しくなるぞ。

その前に、maxima-build.lispの中を見ておく。

(load "../lisp-utils/defsystem.lisp")

(defun maxima-compile ()
  (mk:oos "maxima" :compile))
(defun maxima-load ()
  (mk:oos "maxima" :load))

(defun maxima-dump ()
   :
  #+sbcl (sb-ext:save-lisp-and-die "binary-sbcl/maxima.core" :toplevel #'cl-user::run)
  #-(or clisp sbcl gcl cmu scl allegro lispworks ccl)
  (format t "Sorry, I don't know how to dump an image on this Lisp"))

冒頭に#+sbclとかって書いてあるのは、if文ね。eclはどれにも相当しないから。そんなの知らんメッセージを出したんだな。

んじゃ、OpenBSDが用意したパッケージはどうやってる? 調べたら、lisp屋風じゃなくて、unix屋風のやり方で、作ってるのね。(configure --with-ecl)

まあ、C語にコンパイルされてるなら、その実体は多分/usr/local/libの下あたりだろうね。

ob$ cd /usr/local/lib/maxima/5.42.2/binary-ecl/
ob$ file maxima
maxima: ELF 64-bit LSB shared object, x86-64, version 1
ob$ ldd ./maxima
./maxima:
        Start            End              Type  Open Ref GrpRef Name
        00000502a1162000 00000502a1c88000 exe   2    0   0      ./maxima
        00000504b93bb000 00000504b9705000 rlib  0    1   0      /usr/local/lib/libecl.so.6.0
        0000050542092000 000005054211f000 rlib  0    2   0      /usr/local/lib/libgmp.so.10.0
        00000504c556f000 00000504c55d6000 rlib  0    2   0      /usr/local/lib/libgc.so.4.0
        000005056d3e4000 000005056d3ef000 rlib  0    2   0      /usr/local/lib/libffi.so.1.2
        000005056f90b000 000005056f917000 rlib  0    3   0      /usr/lib/libpthread.so.26.1
        00000504ea04f000 00000504ea07e000 rlib  0    2   0      /usr/lib/libm.so.10.1
        00000504e41b2000 00000504e42a7000 rlib  0    1   0      /usr/lib/libc.so.95.0
        00000504d9c4a000 00000504d9c4f000 rlib  0    1   0      /usr/local/lib/libatomic_ops.so.2.0
        00000504a6b55000 00000504a6b55000 ld.so 0    1   0      /usr/libexec/ld.so

maximaの中にmaximaのlispコードをコンパイルしたものが入り、後のライブラリィーは、純粋なeclと似ていたぞ。実行出来るはず。

ob$ ./maxima
;;; Loading #P"/usr/local/lib/ecl/sb-bsd-sockets.fas"
;;; Loading #P"/usr/local/lib/ecl/sockets.fas"
;;; Loading #P"/usr/local/lib/ecl/defsystem.fas"
;;; Loading #P"/usr/local/lib/ecl/cmp.fas"
Maxima 5.42.2 http://maxima.sourceforge.net
using Lisp ECL 16.1.3
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) sin(%pi/4);
                                       1
(%o1)                               -------
                                    sqrt(2)

基本的なのは動いている。正式には、shareなdirの位置等を設定の上

maxima_image_base="$MAXIMA_IMAGESDIR/binary-$MAXIMA_LISP/maxima"

elif [ "$MAXIMA_LISP" = "ecl" ]; then
   exec "$maxima_image_base" --frame-stack 4096 --lisp-stack 65536 $MAXIMA_LISP_OPTIONS -- "$@"

at debian

maxima-dumpしてcoreが出来る所を見たいな。んな事で、debian機にswitchした。先客のmaximaが居た。京都発のcommon lispを下敷きにしたやつね。でも、それはそのままで、sbclを下敷きにする事にした。

lisp屋さんのmaxima作成の最後のフェーズ。

* (maxima-dump)
[undoing binding stack and other enclosing state... done]
[performing final GC... done]
[saving current Lisp image into binary-sbcl/maxima.core:
writing 3304 bytes from the read-only space at 0x1000000
writing 1304 bytes from the static space at 0x1100000
writing 46641152 bytes from the dynamic space at 0x977af000
done]

これが終了するとsbclも死ぬ。あの人の好きなsmalltalkは、常に実行履歴がイメージとして残るけど、まあそれと同じ事だな。

出来たcoreはこんなの。

debian:binary-sbcl$ ls -l maxima.core
-rw-r--r-- 1 sakae sakae 46721776 Oct 19 15:52 maxima.core

src/binary-sbclってdir内に、大量のxxx.faslってlispをコンパイルした断片と共に置かれる。要するに、これらxxx.faslをメモリーにロードして、それをまとめたものだ。

じゃ、このmaxima.coreをメモリー上に展開すればいいんだな。どうやってやる?sbclには不慣れだからなあ。

こういう時は例を参考にするのが手っ取り早い。そう、/usr/bin/maxima を見るのさ。

elif [ "$MAXIMA_LISP" = "sbcl" ]; then
# Use executable image if it exists.
# Since compiling lapack already needed >1200 Megabytes of RAM in August of 2015
# one has to extend the amount of memory sbcl will be able to claim by using the
# switch --dynamic-space-size in order to do so.
  if [ -x "$MAXIMA_IMAGESDIR/binary-$MAXIMA_LISP/maxima" ]; then
    exec "$MAXIMA_IMAGESDIR/binary-$MAXIMA_LISP/maxima" --noinform $MAXIMA_LISP_OPTIONS --end-runtime-options --eval '(cl-user::run)' --end-toplevel-options "$@"
  else
    exec "sbcl" --core "$maxima_image_base.core" --noinform $MAXIMA_LISP_OPTIONS --end-runtime-options --eval '(cl-user::run)' --end-toplevel-options "$@"
  fi

coreが出来ているんで、else句を真似ればいいんだな。取り合えず簡略版でやってみる。

debian:binary-sbcl$ sbcl --core maxima.core
This is SBCL 1.4.16.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
Maxima 5.43.0 http://maxima.sourceforge.net
using Lisp SBCL 1.4.16.debian
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) sin(%pi/4);
                                       1
(%o1)                               -------
                                    sqrt(2)

適当にやっても動いちゃった。else句の方法だと、起動にはsbclが必要。maximaを作る時、普通にconfigureする方法だと、sbcl内蔵のものが出来るんだな。

MAXIMA> (to-xx)
; in: TO-XX
;     (MAXIMA::TO-XX)
;
; caught STYLE-WARNING:
;   undefined function: MAXIMA::TO-XX
;
; compilation unit finished
;   Undefined function:
;     TO-XX
;   caught 1 STYLE-WARNING condition

Maxima encountered a Lisp error:

 The function MAXIMA::TO-XX is undefined.

Automatically continuing.
To reenable the Lisp debugger set *debugger-hook* to nil.

MAXIMA>

sbcl版でも、怒らるとdebuggerへ入る方法が例示された。

MAXIMA> (setq  *debugger-hook* nil)

NIL
MAXIMA> (to-xx)

debugger invoked on a UNDEFINED-FUNCTION in thread
#<THREAD "main thread" RUNNING {98935329}>:
  The function MAXIMA::TO-XX is undefined.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE    ] Retry using TO-XX.
  1: [USE-VALUE   ] Use specified function
  2: [MACSYMA-QUIT] Maxima top-level
  3: [ABORT       ] Exit from the current thread.

(SB-IMPL::RETRY-%COERCE-NAME-TO-FUN TO-XX NIL)

ここから、面白い事が出来そうだな。

etc

こんな所に、補完用のデータが置かれていた。見ておくと吉。

debian:~$ wc /usr/share/maxima/5.42.1/share/builtins-list.txt
 2477  2477 28461 /usr/share/maxima/5.42.1/share/builtins-list.txt

maximaを本格的に使うなら、この辺りを入れておくと大吉。そう言えば、この間、7777って縁起のよい番号のタクシーを見たぞ。8888はまだ見ていない。オークションで高値で取引されるんだろうな。

debian:emacs$ pwd
/home/sakae/src/maxima-5.43.0/interfaces/emacs
debian:emacs$ ls emaxima/
emaxima.el    emaxima.sty  Makefile.in  maxima-font-lock.el
emaxima.lisp  Makefile.am  maxima.el

OpenBSD 6.6 出たな、と、お化けみたいに言わんとき。少し落ち着いたら、試してみる。