マウスカーソルに円を描かせる
% ruby -e ' 0.upto(360) {|i| x = (500 + 200*Math.cos(i*Math::PI/180)).to_i y = (400 + 200*Math.sin(i*Math::PI/180)).to_i system "xwit -root -warp #{x} #{y}" sleep 0.01 } '
NetBSD に openat が入る、のか?
2009-09-17 NetBSD tech-kern: openat/fstatat functions implementation
とりあえず名前は嫌われているようだ
いや、前にも話があって、入っていないのか
2009-01-11 NetBSD tech-kern: Patch: openat() family of system calls
FreeBSD の openat は 8.0 から、か。
ふと調べたら、DragonFly BSD 2.4 が出ていて、Unix98 pty がついに導入されたようだ
これで生き残っている BSD で pty の確保に特権が必要なものはなくなった (と思う)
UDP の通信を中継するにはどうするか。
IPv6 な DNS サーバで resolv.rb が動かないというのだが手元に IPv6 な DNS サーバがない。なんとなく、IPv6 なソケットから IPv4 な DNS サーバに通信を中継するだけでいいんじゃないかと思って中継してみた。
中継するにはクライアントからのパケットとサーバからのパケットを両方待つ必要があり、それをひとつの select loop で済ましたい。最初、Socket.udp_server_loop_on は使えないのではないかと思ったが、引数の sockets を破壊的に書き換えれば使えるようではある。あまり行儀がよいとはいえない。
% ruby -rsocket -e ' a = Addrinfo.udp("192.168.0.1", 53) clients = {} servers = {} Socket.udp_server_sockets(9999) {|sockets| Socket.udp_server_loop_on(sockets) {|msg, msg_src| assoc = "#{msg_src.remote_address.inspect_sockaddr} #{msg_src.local_address.inspect_sockaddr}" if clients[assoc] clients[assoc].send msg, 0 elsif servers[assoc] servers[assoc].reply msg else s = a.connect s.send msg, 0 clients[assoc] = s sassoc = "#{s.remote_address.inspect_sockaddr} #{s.local_address.inspect_sockaddr}" servers[sassoc] = msg_src sockets << s end } }'
リクエストを送ってきたクライアントに返事をちゃんと返すには、結局セッションを管理する必要がある。ここで TCP と違って自前で管理しないといけないのが厄介である。なお、本当はタイムアウトなどで古いのを破棄していくべきだがさぼっている。
考えてみると、select loop はプログラム全体にひとつにすることが多いので、それをライブラリ側に持たせるという判断は微妙である。
それが嬉しいこともあるが、それを強制されるのは嬉しくない。アプリケーション側で select loop を書くという選択肢が禁止されてしまう。
Socket.udp_server_loop_on から select loop 以外の部分を抽出して提供すべきだろうな。そうすれば、アプリケーション側で select loop を書くという選択肢がとれる。
一般に、プログラム全体にひとつという性質のコンポーネントをライブラリで提供するときは気をつけるべきか。
論文の締切間際に、論文を投稿するサイトの SSL 証明書の有効期限が切れたらどうするか。
これにより、chkbuild では (TMPDIR を設定するので) rubyspec が /tmp にはテンポラリファイルを作らなくなる... と思ったらまだ /tmp にディレクトリがひとつ残る。
<URL:http://github.com/rubyspec/rubyspec/commit/de6e3af9335be36a152f1f1ee2ec96c73c9bee87> で残らなくなった。
しかし、残らないからといって /tmp を使っていないかというとそれは分からない。ちゃんと消しているだけかもしれない。
というわけで、inotify を使って /tmp を監視 してみると、やはりまだ使っていた。
<URL:http://github.com/rubyspec/rubyspec/commit/db6cac9adba5754e7f5cd7ccf6ca28ea8a619ab5> と修正して、手元の環境では (TMPDIR を別のところに設定すれば) rubyspec に /tmp を使わせないようにできたようだ。
これにはいくつかの効果があるが、ひとつの効果は /tmp にテンポラリファイルが溜まっていかないというものである。chkbuild は build 毎に別々のディレクトリを作って、古いのを順に削除する。ここで、TMPDIR もその中に設定するので、その中のテンポラリファイルもいっしょに削除される。
というわけで、たとえ ruby が落ちてテンポラリファイルを削除し損ねようと、後でテンポラリディレクトリごと削除されることになる。
まぁ、rubyspec は ruby が落ちなくても派手にテンポラリファイルを残すので、いままでたまに手動で掃除していたのだが、それが不要になって嬉しい。
atanh(1) や atanh(-1) がどうなるべきかという話で、考えると inf/-inf も悪くないかなぁと思ったが、複素数はどうなのかなぁと思ったらどうも関数の形がイメージできないのでプロットしてみる。
引数も結果も複素数なので、どうプロットすべきか悩む。
等高線で、実数部と虚数部、また絶対値と偏角を描いてみるがしっくりとこない。
atanh-contour.R:
r <- seq(-2, 2, len=201) i <- seq(-2, 2, len=201) fr <- outer(r, i, function(r, i) Re(atanh(r+i*1i))) fi <- outer(r, i, function(r, i) Im(atanh(r+i*1i))) fa <- outer(r, i, function(r, i) abs(atanh(r+i*1i))) fp <- outer(r, i, function(r, i) Arg(atanh(r+i*1i))) l = seq(-10,10,by=0.2) par(mfrow=c(2,2)) contour(r, i, fr, levels=l, xlab="x", ylab="y", main="real(atanh(x+yi))") contour(r, i, fi, levels=l, xlab="x", ylab="y", main="image(atanh(x+yi))") contour(r, i, fa, levels=l, xlab="x", ylab="y", main="abs(atanh(x+yi))") contour(r, i, fp, levels=seq(-3,3,by=0.2), xlab="x", ylab="y", main="arg(atanh(x+yi))")
ベクトル場でやってみる。
atanh.R:
r <- seq(-2, 2, len=21) i <- seq(-2, 2, len=21)[-11] x0 <- rep(r,length(i)) y0 <- rep(i,rep(length(r),length(i))) fr <- Re(atanh(x0+y0*1i)) fi <- Im(atanh(x0+y0*1i)) scale = 0.4 i0 <- rep(0, length(r)) fr0 <- Re(atanh(r)) fi0 <- Im(atanh(r)) plot(c(), xlab="real", ylab="image", xlim=c(-2,2), ylim=c(-2,2)) points(x0, y0, cex=0.2) arrows(x0, y0, x0+fr*scale, y0+fi*scale, length=0.1) points(r, i0, cex=0.2, col="red") arrows(r, i0, r+fr0*scale, i0+fi0*scale, length=0.1, col="red")
赤いところは実数軸。
問題の、-1, 1 のあたりを拡大してみる。
atanh2.R:
par(mfrow=c(1,2)) r <- seq(-1.05, -0.95, len=21) i <- seq(-0.1, 0.1, len=21)[-11] x0 <- rep(r,length(i)) y0 <- rep(i,rep(length(r),length(i))) fr <- Re(atanh(x0+y0*1i)) fi <- Im(atanh(x0+y0*1i)) scale = 0.003 i0 <- rep(0, length(r)) fr0 <- Re(atanh(r)) fi0 <- Im(atanh(r)) plot(c(), xlab="real", ylab="image", xlim=c(-1.05,-0.95), ylim=c(-0.1,0.1)) points(x0, y0, cex=0.2) arrows(x0, y0, x0+fr*scale, y0+fi*scale, length=0.05) points(r, i0, cex=0.2, col="red") arrows(r, i0, r+fr0*scale, i0+fi0*scale, length=0.05, col="red") r <- seq(0.95, 1.05, len=21) i <- seq(-0.1, 0.1, len=21)[-11] x0 <- rep(r,length(i)) y0 <- rep(i,rep(length(r),length(i))) fr <- Re(atanh(x0+y0*1i)) fi <- Im(atanh(x0+y0*1i)) i0 <- rep(0, length(r)) fr0 <- Re(atanh(r)) fi0 <- Im(atanh(r)) plot(c(), xlab="real", ylab="image", xlim=c(0.95,1.05), ylim=c(-0.1,0.1)) points(x0, y0, cex=0.2) arrows(x0, y0, x0+fr*scale, y0+fi*scale, length=0.05) points(r, i0, cex=0.2, col="red") arrows(r, i0, r+fr0*scale, i0+fi0*scale, length=0.05, col="red")
うぅむ。1, -1 などの危ないところがどう危ないかいまひとつ感覚が表現できないな。
実数軸にごく近いところも描くか。
atanh3.R:
par(mfrow=c(1,2)) r <- seq(-1.05, -0.95, len=21) i <- append(seq(-0.1, 0.1, len=21)[-11],c(-0.00001,0.00001)) x0 <- rep(r,length(i)) y0 <- rep(i,rep(length(r),length(i))) fr <- Re(atanh(x0+y0*1i)) fi <- Im(atanh(x0+y0*1i)) scale = 0.003 i0 <- rep(0, length(r)) fr0 <- Re(atanh(r)) fi0 <- Im(atanh(r)) plot(c(), xlab="real", ylab="image", xlim=c(-1.05,-0.95), ylim=c(-0.1,0.1)) points(x0, y0, cex=0.2) arrows(x0, y0, x0+fr*scale, y0+fi*scale, length=0.05) points(r, i0, cex=0.2, col="red") arrows(r, i0, r+fr0*scale, i0+fi0*scale, length=0.05, col="red") r <- seq(0.95, 1.05, len=21) i <- append(seq(-0.1, 0.1, len=21)[-11],c(-0.00001,0.00001)) x0 <- rep(r,length(i)) y0 <- rep(i,rep(length(r),length(i))) fr <- Re(atanh(x0+y0*1i)) fi <- Im(atanh(x0+y0*1i)) i0 <- rep(0, length(r)) fr0 <- Re(atanh(r)) fi0 <- Im(atanh(r)) plot(c(), xlab="real", ylab="image", xlim=c(0.95,1.05), ylim=c(-0.1,0.1)) points(x0, y0, cex=0.2) arrows(x0, y0, x0+fr*scale, y0+fi*scale, length=0.05) points(r, i0, cex=0.2, col="red") arrows(r, i0, r+fr0*scale, i0+fi0*scale, length=0.05, col="red")
こうすると、なぜ、実数軸上で、絶対値が 1 より大きいところで値が決定できないのかわかる気がする。
だが、どうもしっくりとこない。
角度と半径で攻めてみるか。(角度は度数法で 0-360 としよう)
atanh-polar1.R:
par(mfrow=c(2,1)) f <- function(r,a) { atanh(1+r*(cos(a*pi/180)+1i*sin(a*pi/180))) } curve(Re(f(0.1,x)), xlim=c(0,360), ylim=c(0,2), xlab="angle", ylab="Re(atanh(1+ar)") par(new=T) curve(Re(f(0.5,x)), xlim=c(0,360), ylim=c(0,2), xlab="", ylab="", lty=2) par(new=T) curve(Re(f(0.9,x)), xlim=c(0,360), ylim=c(0,2), xlab="", ylab="", lty=3) text(250,1.7, "r=0.1") text(250,0.9, "r=0.5") text(250,0.2, "r=0.9") curve(Im(f(0.1,x)), xlim=c(0,360), ylim=c(-2,2), xlab="angle", ylab="Im(atanh(1+ar)") par(new=T) curve(Im(f(0.5,x)), xlim=c(0,360), ylim=c(-2,2), xlab="", ylab="", lty=2) par(new=T) curve(Im(f(0.9,x)), xlim=c(0,360), ylim=c(-2,2), xlab="", ylab="", lty=3) text(250,-0.3, "r=0.1") text(250,-1.1, "r=0.9")
これはわかりやすい。
1 に近づくにつれ、
-1 の周囲も描いてみよう。
atanh-polar2.R:
par(mfrow=c(2,1)) f <- function(r,a) { atanh(-1+r*(cos(a*pi/180)+1i*sin(a*pi/180))) } curve(Re(f(0.1,x)), xlim=c(0,360), ylim=c(-2,0), xlab="angle", ylab="Re(atanh(1+ar)") par(new=T) curve(Re(f(0.5,x)), xlim=c(0,360), ylim=c(-2,0), xlab="", ylab="", lty=2) par(new=T) curve(Re(f(0.9,x)), xlim=c(0,360), ylim=c(-2,0), xlab="", ylab="", lty=3) text(250,-1.7, "r=0.1") text(250,-0.9, "r=0.5") text(250,-0.3, "r=0.9") curve(Im(f(0.1,x)), xlim=c(0,360), ylim=c(-2,2), xlab="angle", ylab="Im(atanh(1+ar)") par(new=T) curve(Im(f(0.5,x)), xlim=c(0,360), ylim=c(-2,2), xlab="", ylab="", lty=2) par(new=T) curve(Im(f(0.9,x)), xlim=c(0,360), ylim=c(-2,2), xlab="", ylab="", lty=3) text(250,-0.7, "r=0.1") text(250,-1.3, "r=0.9")
-1 に近づくにつれ、
実数軸だけ考えると、1, -1 に近づく方向は正から近づくか負から近づくかのふたつしかなくて、どちらもその一方は値がないので、残りの inf, -inf にするというのもひとつのやりかたではあるが。
結局、複素数を考えると、1 にせよ -1 にせよ、どの方向から近づくかで虚数部の値が異なる値に決定する感じなので、値は不定ということにしておくのがよいのではなかろうか。
あるいは、Complex(Inf,NaN) と Complex(-Inf,NaN) という手もあるか? しかし、それはデカルト座標系を表現形式に選んだ幸運に依存しているわけで、いつも幸運に恵まれるとは限らない。他の表現形式に幸運が訪れたときに表現形式を変えるのはありえそうにない。
そういや、0/0 が NaN になるのは同じようにプロットするとどうなるか。
div0.R:
f <- function(x,y) { x/y } g <- function(r,a) { f(r*cos(a*pi/180),r*sin(a*pi/180)) } curve(Re(g(1,x)), xlim=c(0,360), ylim=c(-2,2), xlab="angle", ylab="x/y") text(0, -2, "(1,0)") text(90, -2, "(0,1)") text(180, -2, "(-1,0)") text(270, -2, "(0,-1)") text(360, -2, "(1,0)")
どの方向から攻めても、その方向で値は決まって変わらない。まぁ x/y は傾きなんだからそうだよな。
あと、0**0 は。
pow0.R:
par(mfrow=c(2,1)) f <- function(x,y) { (x+0i)**y } g <- function(r,a) { f(r*cos(a*pi/180),r*sin(a*pi/180)) } yl = c(0,2) curve(abs(g(1,x)), xlim=c(0,360), ylim=yl, xlab="angle", ylab="abs(x**y)", lty=4) par(new=T) curve(abs(g(0.1,x)), xlim=c(0,360), ylim=yl, xlab="angle", ylab="", lty=3) par(new=T) curve(abs(g(0.01,x)), xlim=c(0,360), ylim=yl, xlab="", ylab="", lty=2) par(new=T) curve(abs(g(0.001,x)), xlim=c(0,360), ylim=yl, xlab="", ylab="", lty=1) text(120, 0.3, "r=1") text(120, 0.7, "r=0.1") text(120, 0.9, "r=0.01") text(120, 1.08, "r=0.001") y = 0 text(0, y, "(1,0)") text(90, y, "(0,1)") text(180, y, "(-1,0)") text(270, y, "(0,-1)") text(360, y, "(1,0)") yl = c(-4,4) curve(Arg(g(1,x)), xlim=c(0,360), ylim=yl, xlab="angle", ylab="Arg(x**y)", lty=4) par(new=T) curve(Arg(g(0.1,x)), xlim=c(0,360), ylim=yl, xlab="angle", ylab="", lty=3) par(new=T) curve(Arg(g(0.01,x)), xlim=c(0,360), ylim=yl, xlab="", ylab="", lty=2) par(new=T) curve(Arg(g(0.001,x)), xlim=c(0,360), ylim=yl, xlab="", ylab="", lty=1) text(120, 3.2, "r=1") text(120, 0.8, "r=0.1") text(120, -0.4, "r=0.001")
傾き一定で近づくと、だいたいのところで 1 になるのか。
Inf + i NaN にする実例もあるようだ。
無限大というのも実数部と虚数部という表現ではナニである
(1.1+1.1i)**x で x を無限大に近づけると結果は何に近づくか。
spiral.gp:
set parametric plot real({1.1,1.1}**t), imag({1.1,1.1}**t)
実数部も虚数部も符号が決まらない。
いや、これは実数だけの世界でも同じか?
(-2)**x で x を無限大に近づけていけば... いや、x が整数でなければ複素数か。
spiral2.gp:
set parametric plot real((-2)**t), imag((-2)**t)
R で媒介変数を使ってグラフを描く方法が見つからない...
prime.rb を眺めていて、唐突に、篩 (ふるい) と櫛 (くし) は似ているんじゃないかと思ったが、見直すとそんなに似ていないな。共通しているのは竹冠だけだ。あとは密度もおなじくらい?
ここでいう密度というのは白と黒の割合である。
ちょっと測ってみよう。
まず、xfonts-intl-japanese のソースの Japanese/j90-16.bdf から bitmap を取り出す。
篩:
1040 1040 3eff 6990 c408 1000 7dff 4410 44fe 7c92 4092 7c92 4492 4496 7c10 0010
櫛:
2210 2210 27df f528 2884 2000 67df 7451 6fd1 a451 a7d1 2411 2491 27d7 2c50 2010
あとはこれの 1のビットの数を数えればいい...
なんで Ruby には popcount がないのだ? そのうちどうにかしよう。
まぁ、それはそれとして
ARGF.each {|line| puts line.to_i(16).to_s(2).rjust(16, "0").gsub(/0/, " ") }
とするとパターンが表示できる。
それで、
p ARGF.read.gsub(/\s/, "").to_i(16).to_s(2).chars.count("1")
として 1 を数えた。
篩が 92 で、櫛が 100 か。櫛のほうがちょっと濃い。
rubyspec は ci モードでなくても最後までいくようになったようなので、chkbuild で ci モードを使うのをやめてみる。
ちょっと前に、ふと爪の正しい切り方を調べたら、いままでの切り方は深爪ぎみで、もっとのばすべきだということが分かった。
で、のばしているのだが、どうもキーボードに爪が当たって打ちにくい。とくにホームポジションよりも手前のキーを打つと、指を曲げて打つので、必然的に爪が当たる気がする。
のばすべきなのは左右の端なので、まんなかの部分をちょっと切るといくらかマシか。
なんか prog1 が欲しい状況があってテンポラリ変数を使わない方法を考えた。
まず思いついたのが [exp1, exp2][0] である。
そして、次に思いついたのが、最初の引数を返すメソッド
def firstarg(a, *_) a end
を定義して、firstarg(exp1, exp2) とするというものである。
Ruby では引数の評価順序が左から右と決まっているので、firstarg は prog1 として使用できる。
ここで思ったのだが、Lisp ではなんで prog1 や progn (Scheme なら begin) は関数じゃないんだっけ? 引数の評価順序が決まってないから?
では、引数の評価順序を決めてしまえば普通の関数にしていい?
効率?
なるほど、tail position と多値と定義式 ですか。
tail position はたしかに重要ですね。
多値は... まぁあまり。定義のやりかた次第という気もするし、どう定義しても問題になるような気もするので。
定義式は... おぉ、そんな機能が。
gosh> (begin (begin (define a 1) (define b 2)) (cons a b)) (1 . 2)
でもなんか作為的。
tail position が理由としていちばん素直な感じがします。
ありゃ、なんか誤解してるかな?
gosh> x *** ERROR: unbound variable: x Stack Trace: _______________________________________ gosh> (car (begin (define x 1) '(1 2))) 1 gosh> x 1
そういえば、正整数 (n > 0)、負整数 (n < 0)、非負整数 (n >= 0)、に対して、あまり非正整数 (n <= 0) というのは聞かない、とふと思ったのだが、検索してみるとそうでもないようだ。
オーランド
タイムゾーンを設定しようとして tzconfig としたら
WARNING: the tzconfig command is deprecated, please use: dpkg-reconfigure tzdata
だそうな。
lenny では dpkg-reconfigure tzdata が良いようだ。
もともと、tzconfig は探しにくくて、dpkg-reconfigure tzdata を先に試して動かなくて残念に思ったことがあるので、これは良い感じである。
オーランド
オーランド
オーランド
オーランド
とある発表で、pathname.rb の world_readable?, world_writable? が (1.8 で) type error と指摘されてしまった...
いちおう、今は FileTest.world_readable?, FileTest.world_writable? が定義されているときしか定義しないようにしてあるが。
openssl の、Integer#to_bn も指摘されていて、これは [ruby-core:22297] のようだ。ていうか、この報告者はこの論文の著者だな。
成田
ふと東成田まで歩いてみようかと思ったが、どこに通路があるのか分からなかった。
[latest]