Ubuntu に Microsoft Office 2007 をインストール

少し前に UbuntuMicrosoft Office 2007 をインストールする機会があったので、記事にまとめます。

環境

Ubuntu 8.04.2 に wine 本家のパッケージ。

前情報

wine 本家 AppDB より
A regression broke the Office 2003 & 2007 installers in 1.1.17. It is still not fixed as of 1.1.20. Already-installed Office apps appear to run fine in these versions. Install in an earlier version and upgrade.

wine のバージョン 1.1.17 でインストールできなくなってバージョン 1.1.20 現在も直っていないが、
インストール済みのはうまく動くよ。昔のバージョンでインストールして、アップグレードするといいよ。
ってことらしい。

インストール

ということで、インストールできる最新のバージョンである 1.1.16 をここからダウンロードしてインストールします。
wine をインストールしたら Microsoft Office 2007 のメディアをマウントしてsetup.exe を
実行するだけでインストーラーは起動しますが、一つ注意しないといけないことがあります。

それは、日本語版 Office の場合「Microsoft Office IME(日本語)」のインストール時に止まってしまうこと。
これは俺の記事@自宅サーバさんが書かれているように、IMJPKLMG.EXE というプロセスを kill することで回避できます*1


もしくはインストール時のオプションで、「Microsoft Office IME(日本語)」を外してしまっても大丈夫です。

wine のアップグレード

Microsoft Office 2007 のインストールが完了したら、wine 本家サイトに従ってソフトウェア・ソースを追加します。
その後、最新のバージョンにアップグレードすればインストール完了です。

*1:Windows バージョンの設定やライブラリのオーバーライドは不要

Windows で git

インストール

Windows で git を使う場合、cygwin か msysgit を使うのが一般的。
git だけ使えればいいので、msysgit をチョイス。
インストールはここに従った。
日本語環境を構築する為の注意書きがあるが、リンクが切れてたり、
設定の意味が解説されていなかったりするので、忘れないように書いておきます。

Git Bash 上で日本語入力

初期状態では、Git Bash 上で日本語入力が出来ない。*1
[git のインストールディレクトリ]/etc/inputrc に次の設定を追記。*2

set kanji-code utf-8
set convert-meta off
set meta-flag on
set output-meta on

PAGER のマルチバイト対応

先のリンク先では、日本語対応 less を別途ダウンロードしていたが、
標準で入る less でも、環境変数 LESSCHARSET に utf-8 と設定すれば問題なし。


nkf は、次のいずれかに当てはまる場合は必要。

  1. git で管理するファイルで、Shift-JIS 以外のエンコーディングを使用している。
  2. コミットメッセージに日本語を使う場合。*3


nkf は、ここからダウンロードして、[git のインストールディレクトリ]/bin に入れておく。


[git のインストールディレクトリ]/etc/profile に次の設定を追記。

# nkf を使う場合
export GIT_PAGER="nkf -s | LESSCHARSET=utf-8 less"

# nkf を使わない場合
export GIT_PAGER="LESSCHARSET=utf-8 less"

コミットユーザーに設定される、ユーザ名、メールアドレスを設定

Git Bash を立ち上げ、次のコマンドを実行。

$ git config --global user.name "your name"
$ git config --global user.email "your mail address"

コミットメッセージに日本語を使用する

エディタが、デフォルト UTF-8 で立ち上がるなら、設定は必要なし。
もし、Shift-JIS で立ち上がるなら Git Bash で次のコマンドを実行する。*4

$ git config --global i18n.commitEncoding sjis

このコマンドを実行したそれ以降は、Shift-JISのままメッセージを書いておk。

コミットメッセージの入力に xyzzy を使う。

これは超個人的な設定。
xyzzy がすでに起動中の場合に、起動中の xyzzy でコミットメッセージを入力する為の設定。
[git のインストールディレクトリ]/etc/profile に次の設定を追記。

# xyzzy が D://xyzzy/ にインストールされている場合
export GIT_EDITOR="start //wait /d/xyzzy/xyzzycli.exe -wait"

*1:コピペも無理

*2:ファイルがなかったら作成する

*3:git 内部では、コミットメッセージを UTF-8 として管理しているらしい

*4:Windows のエディタで、エンコーディングを自動判定にしているなら、ほぼ Shift-JIS と判定される

Fermat の小定理

SICP を読んでいる時に、いつもつまってしまうのでまとめてみる。

概要

Fermat の小定理 - P.28
n を素数,a を n より小さい正の任意の整数とすると,a の n 乗は n を法として a と合同である.


そして、それをテストするコードが下記である。

(define (square n)
        (* n n))

(define (even? n)
        (= (remainder n 2) 0))

;; gosh用
(define (random n)
        (use srfi-27)
        (random-integer n))

(define (expmod base exp m)
        (cond ((= exp 0) 1)
              ((even? exp)
               (remainder (square (expmod base (/ exp 2) m))
                          m))
              (else
               (remainder (* base (expmod base (- exp 1) m))
                          m))))

(define (fermat-test n)
        (define (try-it a)
                (= (expmod a n n) a))
        (try-it (+ 1 (random (- n 1)))))

このコードの expmod が難しい。
後で参照する度に「何やってるんだっけ?」って話になって、時間をロスしてしまう。

Fermat の小定理を数式にする

まずは、素直に数式にする。
a^n \bmod n = a \bmod n --- (1)
a は n より小さい正の任意の整数であるから
a \bmod n = a --- (2)
よって、(2)(1)の右辺に当てはめ
a^n \bmod n = a --- (3)
になる。

問題点

(3)の左辺は計算し求める必要があるが、素直にa^nを算出した後に n で
割った剰余を求めようとすると、n が大きい時に計算量がとんでもないことになる。
例えば n が 100000 である時、a が取り得る最大数は 99999 だが、
a^nつまり99999^{100000}は 50 万桁にもなってしまう。
それに n で割った剰余を求めないといけないのだ。
もっと大きな数の素数性を調べる時は、これが指数的に増えるのだから、
いくらコンピュータと言えども処理が追いつかない*1

どうするか

解決に必要な情報は、本にすべて提示されている。

  • 武器その 1 「逐次平方」

P.25 では、逐次平方を次のように定義した。

n は 0
b^{n} = 1
n は偶数
b^{n} = (b^{n/2})^{2}
n は奇数
b^{n} = b \cdot b^{n-1}
  • 武器その 2 「剰余演算」

脚注 46 より抜粋 - P.29
任意の整数 x, y と m について,x \times y \bmod mの剰余は,x \bmod my \bmod mの剰余を別々に計算し,その結果を掛け合わせ,更に積の\bmod mの剰余をとればよい

これにより、次のような式が成り立つ。
[tex:(x \times y) \bmod m = *2 \bmod m] --- (4)


必要な武器は以上。

解決法

(3)を逐次平方を用いて表す。
またその時に、(2)及び(4)も用いて式を展開する。
これが解決法で且つ、expmod の行っていることである*3

n は 0
a^{n} \bmod n = 1
n は偶数
\begin{eqnarray}a^{n} \bmod n &=& (a^{\frac{n}{2}})^{2} \bmod n \\ &=& (a^{\frac{n}{2}} \bmod n)^{2} \bmod n\end{eqnarray}
n は奇数
[tex:\begin{eqnarray}a^{n} \bmod n &=& (a \cdot a^{n-1}) \bmod n \\ &=& *4 \bmod n \\ &=& (a \cdot (a^{n-1} \bmod n)) \bmod n \end{eqnarray}]


これにより、なるべく小さい数であるうちに剰余を出すことが出来るので、前述のような問題は起きなくなる。
また、逐次平方を使うので、対数ステップで処理できる。

*1:問題 1.25 は、まさにこれを行っている

*2:x \bmod m) \cdot (y \bmod m

*3:ちなみに fermat-test では、a は n より小さい正の任意を生成し、(3)をテストしている

*4:a \bmod n) \cdot (a^{n-1} \bmod n

オライリーのEbook

http://www.oreilly.co.jp/ebook/
始まった時は品揃えがしょぼかったけど、地味に充実してきてた。


本より安いし、場所も取らないし持ち運びも楽だと思われるので、
「気になっていたけど買っていない」ような本が出たら、試しに一冊買ってみよう。

蔵書管理

http://mediamarker.net/u/hattorix/
蔵書リストを作りました。
小説の類はまだですが、技術系の本はすべて登録しました。
タグを打ってジャンルの傾向も分かって、
読了済みなのが3分の1程度であるのも分かってしまいました(^^;


ここのサービスを選んだ理由は次の2点。
・ローカルアプリだと共有が面倒だからWEBアプリ。
SNSのようなコミュ機能よりも、本を管理する機能に重点を置く。


バーコードリーダーも買ってしまいましたw

クラステンプレートの具現化の位置

初エントリです。


テンプレートのインスタンス化のタイミングが分からない><
興味が沸いたので調べてみた。
本当にあっているのかは分からないけど。

  • 14.7.1 暗黙の具現化

クラステンプレート特殊化が,既に明示的に具現(14.7.2)されているか又は
明示的に特殊化(14.7.3)されている場合を除き,そのクラステンプレート特殊化が,
完全に定義されたオブジェクト型を要求する文脈で使用されるか 又は そのクラス型の
完全性がプログラムの意味に影響を与える場合,そのクラステンプレート特殊化は,
暗黙に具現される。(1)


クラステンプレート特殊化が暗黙に具現されることによって,そのクラスのメンバ関数
メンバクラス,静的データメンバ 及び メンバテンプレートの宣言は,暗黙に具現される。
しかし,それらの定義 又は 省略時実引数は,暗黙に具現されることはない。(2)


クラステンプレートのメンバ 又は メンバテンプレートが,既に明示的に具現されているか
又は 明示的に特殊化されている場合を除き,その特殊化は,そのメンバ定義が要求される
文脈で用いられたときに,暗黙に具現される。(3)

  • 14.6.4.1 具現化の位置

(中略) クラステンプレートのメンバ関数 (中略) の特殊化の具現化の位置は,
その特殊化を参照する,名前空間有効範囲の宣言 又は 定義の直後とする。(4)

翻訳単位の最外側の宣言領域も名前空間となり,大域的名前空間(global namespace)と呼ぶ。
大域的名前空間で宣言された名前は,大域的名前空間有効範囲(大域的有効範囲ともいう)をもつ。
こうした名前の潜在有効範囲は,その宣言位置(3.3.1)に始まり,
その宣言領域である翻訳単位の終わりで終わる。(5)


上記より、次のように解釈される。

namespace ns {
	struct B {};
}

template<typename T>
struct A
{
	void f0(T b) {
		f(b);
	}
};

int main(int, char**)
{
	A<ns::B> a;    // (1) クラスA<ns::B>の具現化が要求される。
	               // (2) A<ns::B>::f0(ns::B)の宣言は暗黙に具現されるが、
	               //     定義は暗黙に具現されない。
	a.f0(ns::B()); // (3) A<ns::B>::f0(ns::B)の具現化が要求される。
	               // (4) (3)での具現化の要求は、ここの名前空間有効範囲
	               //     (ここでは大域的名前空間)が終わるまで処理されない。
	return 0;
}

namespace ns {
	void f(ns::B) {}
}

// (5) 大域的名前空間の終わり(翻訳単位の終わり)。
//     ここで、A<ns::B>::f0(ns::B)が具現化される。
//     すでに、ns::f(ns::B)は可視である。


元エントリでは触れていませんが、A::f0(ns::B)内で、ns名前空間にあるはずのf(ns::B)を
修飾無しに呼び出せているのを不思議に思う方もいるかもしれません。

それは、仮引数bがns名前空間のものなので、この関数内ではns名前空間がスコープに入るからです。
[Exceptiona C++ 項目31]