作業中のメモ

よく「計算機」を使って作業をする.知らなかったことを中心にまとめるつもり.

n 変数関数の最小二乗近似

どうも,筆者です.数点のデータから,関数フィッティングを行う必要が出てきたので,原理から考えたいと思う. gnuplot の fit コマンドを使えば,解は出てくるけど,C 言語等のプログラム中で処理を行いたいため,1 から考えてみる.

最小二乗近似

まず, {n} {\boldsymbol{x} = (x_{1}, x_{2}, \cdots, x_{n})^{T}} から得られる観測データ  {y} {m} 個あるとする.

これらを関数

 { \displaystyle 
  f(\boldsymbol{x}) = \sum_{i = 1}^{n} a_{i}g_{i}(x_{i}) \qquad (1)
}

で近似することを考える.ここで,関数  {g_{i}(x_{i})} {i} 番目の基底関数である. このとき,測定値の組  {(\boldsymbol{x}_{j}, y_{j}), (j = 1, 2, \cdots, m)} における誤差  {\varepsilon_{j}}

 { \displaystyle
  \varepsilon_{j} = f(\boldsymbol{x}_{j}) - y_{j}\qquad (2)
}

で定義する.そして, {m} 個のデータの二乗誤差  {J}

 { \displaystyle
  J = \dfrac{1}{2} \sum_{j = 1}^{m} \varepsilon_{j}^{2}\qquad (3)
}

を最小にするような係数  {a_{i}, (i = 1, \cdots, n)} を求める.これを満たす  {a_{i}} は,

 { \displaystyle
  \dfrac{\partial J}{\partial a_{i}} = 0\qquad (4)
}

を解くことで求められる.ここで,式 (4) の左辺は,

 {
  \begin{eqnarray}
    \dfrac{\partial J}{\partial a_{i}} & = & \dfrac{1}{2} \dfrac{\partial}{\partial a_{i}} \sum_{j = 1}^{m} \varepsilon_{j}^{2} \\
    & = & \dfrac{1}{2} \sum_{j = 1}^{m} \dfrac{\partial \varepsilon_{j}^{2}}{\partial a_{i}} \\
    & = & \sum_{j = 1}^{m} \varepsilon_{j} \cdot \dfrac{\partial \varepsilon_{j}}{\partial a_{i}} \qquad (5)
  \end{eqnarray}
}

で求められる.式 (2) から,実際に偏微分の値を求めると,

 {
  \begin{eqnarray}
   \dfrac{\partial \varepsilon_{j}}{\partial a_{i}} & = & g_{i}(x_{i, j})\\
  \end{eqnarray}
}

となるので,これらを式 (5) に代入すると, {n} 個の連立方程式

 {
  \begin{equation}
    \left\{
      \begin{array}{ccc}
        \sum\limits_{j = 1}^{m} \left( \sum\limits_{i = 1}^{n} a_{i}g_{i}(x_{i, j}) - y_{j} \right)g_{1}(x_{1, j}) & = & 0\\
        \sum\limits_{j = 1}^{m} \left( \sum\limits_{i = 1}^{n} a_{i}g_{i}(x_{i, j}) - y_{j} \right)g_{2}(x_{2, j}) & = & 0\\
                   \vdots & \vdots & \vdots\\
        \sum\limits_{j = 1}^{m} \left( \sum\limits_{i = 1}^{n} a_{i}g_{i}(x_{i, j}) - y_{j} \right)g_{n}(x_{n, j}) & = & 0\\
      \end{array}
    \right. \qquad (6)
  \end{equation}
}

が得られる.これは

 {
  \begin{equation}
    \left\{
      \begin{array}{cc}
        \sum\limits_{j = 1}^{m} a_{1}g_{1}(x_{1, j})g_{1}(x_{1, j}) + \sum\limits_{j = 1}^{m} a_{2}g_{2}(x_{2, j})g_{1}(x_{1, j}) + \cdots + \sum\limits_{j = 1}^{m} a_{n}g_{n}(x_{n, j})g_{1}(x_{1, j}) & = & \sum\limits_{j = 1}^{m} g_{1}(x_{1, j})y_{j}\\
        \sum\limits_{j = 1}^{m} a_{1}g_{1}(x_{1, j})g_{2}(x_{2, j}) + \sum\limits_{j = 1}^{m} a_{2}g_{2}(x_{2, j})g_{2}(x_{2, j}) + \cdots + \sum\limits_{j = 1}^{m} a_{n}g_{n}(x_{n, j})g_{2}(x_{2, j}) & = & \sum\limits_{j = 1}^{m} g_{2}(x_{2, j})y_{j}\\
        \vdots & \vdots & \vdots\\
        \sum\limits_{j = 1}^{m} a_{1}g_{1}(x_{1, j})g_{n}(x_{n, j}) + \sum\limits_{j = 1}^{m} a_{2}g_{2}(x_{2, j})g_{n}(x_{n, j}) + \cdots + \sum\limits_{j = 1}^{m} a_{n}g_{n}(x_{n, j})g_{n}(x_{n, j}) & = & \sum\limits_{j = 1}^{m} g_{2}(x_{n, j})y_{j}\\
      \end{array}
    \right. \qquad (6)
  \end{equation}
}

と書き換えることが出来, {m \times n} の行列  {G = (\boldsymbol{g}_{1}(\boldsymbol{x}), \boldsymbol{g}_{2}(\boldsymbol{x}), \cdots, \boldsymbol{g}_{n}(\boldsymbol{x})), \quad \boldsymbol{g}_{i}(\boldsymbol{x}) = (g_{i}(x_{1}), g_{i}(x_{2}), \cdots, g_{i}(x_{m}))^{T}} {n} 次元ベクトル  {\boldsymbol{a} = (a_{1}, a_{2}, \cdots, a_{n})^{T}} {m} 次元ベクトル  {\boldsymbol{y} = (y_{1}, y_{2}, \cdots, y_{m})^{T}} を用いて,

 { \displaystyle
  G^{T}G \boldsymbol{a} = G^{T}\boldsymbol{y}\qquad (7)
}

と表せる.これは,正規方程式と呼ばれる.ガウスジョルダン法等を用いて解を求める.行列が特異になる場合は,特異値分解を用いて,解くことになる.

はてなブログにおける数式の表記

よく分からないが,文章中の数式に関して,「_」を数式中で使用すると,正しく表示されないことが分かった.なので, {(x_{1}, x_{2})} などを文章中で表示するには,「\_」と「_」をエスケープすることで,表示することが出来る.はてなブログ {\LaTeX} 記法には,まだまだ慣れない.少しずつ解決していこうと思う.現段階でまだ謎なのは,

  • <pre> 中で,「_」をエスケープしなくても表示出来る理由
  • 数式中で式番号を表示する方法.出来れば,label をつけて相互参照を行いたい(現段階では,直接数字を入力している).
  • どの程度まで  {\LaTeX} の表記が使えるか.

ということである.3 つ目に関しては,色々試すのが早い気がする...

参考サイト

最小二乗法 - Wikipedia

bash における部分削除

bash を扱っていると,拡張子だけや,ファイル名だけなど文字列の一部を取り出したいことが多々ある.以前調べたが,また忘れてしまったので,ここにまとめておく.

コマンド 意味
${変数名#[パターン]} パターンに対応する最短接頭部を除去する
${変数名##[パターン]} パターンに対応する最長接頭部を除去する
${変数名%[パターン]} パターンに対応する最短接尾部を除去する
${変数名%%[パターン]} パターンに対応する最長接尾部を除去する

具体的な使い方を示しつつ,理解していく.まずは,以下のような文字列を考える.

#!/bin/bash

string=/sample/program/hoge/foo.f
string2=/sample/program/hogehoge/fileList.list.$$

ここから,ファイル名(拡張子あり)だけを取り出す方法を考える.このとき,「foo.f」,「fileList.list.$$」より左側は必要ないことが分かるので,先頭から「*/」までのうち,一番長い部分(最長接頭部)を削除すればよい.よって,

fileName=${string##*/}
fileName2=${string2##*/}

となる.同様な問題として,拡張子だけを取り出すことを考える.この場合,「.f」より左側は必要ないので,先頭から「*.」までのうち一番長い部分(最長接頭部)を削除すればよい.よって,

extension=${string##*.}

となる.string2 の方は,拡張子を「.list」としたいので,先ほど処理したファイル名から,「.$$」を削除すればよい.このとき,「.*」から末尾までのうち,もっとも短い部分(最短接尾部)を削除すればよい.よって,

extension2=${fileName2%.*}

となる.次に,絶対パスを含むファイル名(拡張子なし)を取り出すことを考える.このとき,「.f」,「.list.$$」の部分が必要ないことが分かるので,「.*」から末尾までのうち,もっとも長い部分(再調節尾部)を削除すればよい.よって,

pathFileName=${string%%.*}
pathFileName2=${string2%%.*}

となる.最後に,ファイル名(拡張子なし)だけ取り出すことを考える.この場合,絶対パスを含むファイル名(拡張子なし)から,ファイル名だけを取り出す方法を適応すればよい.よって,

fileNameWithoutExtension=${pathFileName##*/}
fileNameWithoutExtension2=${pathFileName2##*/}

となる.

数式表示とその動作確認

日頃,数式を入力することが多いが,ここにも数式を書く可能性を考えて,環境を整えておく. といっても,いつの間にか,はてなブログでは, {\LaTeX} が使えるようになっているらしいので,表記にしたがってそのまま書いてゆく.

書き方

書き方はいたって簡単で,

[tex: { \displaystyle
ここに数式を書く
}]

で表示することが出来る.よく分からないが,上手くいかないときがあるらしい.そのときは,

<pre style="border: none; font-size: 100%;">
[tex: { \displaystyle
ここに数式を書く
}]</pre>

とすれば良いらしい.

サンプル数式

正規分布

正規分布確率密度関数を書いてみる.

 { \displaystyle
  f(x) = \dfrac{1}{\sqrt{2\pi}\sigma} \exp{\left( -\dfrac{(x - \mu)^{2}}{2\sigma^{2}} \right)}
}

上手くいった.

テイラー展開

では次に, {e^{x}}テイラー展開をやってみる.

 { \displaystyle
  e^{x} = \sum_{n = 0}^{\infty} \dfrac{x^{n}}{n!}
}

これも上手く出来た.

変動係数

最後に,変動係数を表記してみる.ここで, {\boldsymbol{x} \in \mathcal{R}^{N}} は,観測データである.

 { \displaystyle
  C.V. = \dfrac{\sqrt{\dfrac{1}{N} \sum_{i = 1}^{N} \left( x_{i} - \dfrac{1}{N} \sum_{i = 1}^{N} x_{i} \right)^{2}}}{\dfrac{1}{N} \sum_{i = 1}^{N} x_{i}}
}

予想通り,分数になると,数式がつぶれてしまったので,\sum の後に「\limits」 を追加(\sum\limits の状態)して,再度描画すると,

 { \displaystyle
  C.V. = \dfrac{\sqrt{\dfrac{1}{N} \sum\limits_{i = 1}^{N} \left( x_{i} - \dfrac{1}{N} \sum\limits_{i = 1}^{N} x_{i} \right)^{2}}}{\dfrac{1}{N} \sum\limits_{i = 1}^{N} x_{i}}
}

となる.とりあえず,普段使っているもので正しく描画出来るので,満足.後は,イコールを揃えたりすること位か.

参考サイト

はてなブログにLaTeXで数式を書く (Markdown記法用) - 余白の書きなぐり

はてなブログでtex記法を使うときのメモ - minus9d's diary

vim で利用できるコマンド

どうも,筆者です.

vim を使い始めて数日が経つ(前回の記事の段階で,ある程度は使えるようにはなっていた).しかし,まだ,コマンドをよく把握していない. こういうものは使いながら覚えていくのがいいが,どうしても忘れやすいため,ここに,記録しておく.

移動

コマンド 処理内容
h 左に 1 文字分移動(←)
j 下に 1 文字分移動(↓)
k 上に 1 文字分移動(↑)
l 右に 1 文字分移動(→)
gg ファイルの先頭(1 行目)に移動
G ファイルの末尾(最後の行)に移動
w 前方に 1 単語分移動
b 後方に 1 単語分移動
W 空白を挟んで,前方に 1 単語分移動
B 空白を挟んで,後方に 1 単語分移動
^ テキストの先頭に移動(空白は無視)
0 行頭に移動(空白も含む)
$ 行末に移動
Ctrl + d 半ページ分下にスクロール
Ctrl + u 半ページ分上にスクロール
Ctrl + f 1 ページ分下にスクロール
Ctrl + b 1 ページ分上にスクロール

f[char]
次の [char] に移動
「;」でさらにを調べる,
「,」で後ろを調べる

テキスト内の編集

[n] は数字が入る.例えば,3yy としたら,現在のカーソルの位置から,3 行コピーされる

コピー関連

コピーコマンド 処理内容
yw カーソルの位置から,前方に 1 単語分コピー
yb カーソルの位置から,後方に 1 単語分コピー
y0 カーソルの位置から,行頭までコピー
y^ カーソルの位置から,その行のテキストの先頭までコピー
y$ カーソルの位置から,行末までコピー
yy 1 行コピー
[n]yy n 行コピー
y[n]G 現在のカーソルの位置から,n 行目までをコピー

切り取り関連

切り取りコマンド 処理内容
dw カーソルの位置から,前方に 1 単語分カット
db カーソルの位置から,後方に 1 単語分カット
d0 カーソルの位置から,行頭までカット
d^ カーソルの位置から,その行のテキストの先頭までカット
d$ カードルの位置から,行末までカット
dd 1 行切り取り
[n]dd n 行切り取り
d[n]G 現在のカーソルの位置から,n 行目までを切り取り

マーカーを利用したコピーと切り取り

まずは,マーカーの使い方を以下に示す.

コマンド 処理内容
mk 現在のカーソルの位置を k にマークする
'k k の位置にカーソルを移動する

これを利用して,任意の行から,任意の行までをコピー,切り取りを行うことが出来る.編集したい最初の行で「mk」とし,編集した最後の行で「d'k」もしくは,「y'k」とするとこで編集が行える. 行番号が分かっているならば,上の方法を利用した方が早い.

テキスト内の検索

検索を行うには,ノーマルモード中で,「/」を押す.すると,コマンドラインのところに,「/」が表示されるので,検索したい文字列を入力して Enter を押す.

コマンド 処理内容
n ヒットした次の単語に移動
N ヒットした前の単語に移動

テキスト内の置換

ここでは,よく使うものだけ紹介する.先ほどと同様にして,[n] は行数を表す.

コマンド 処理内容
:s/[old]/[new]/ 現在カーソルがある行で,最初の [old] を [new] に置換
:s/[old]/[new]/g 現在カーソルがある行で,すべての [old] を [new] に置換
:%s/[old]/[new]/g ファイル全体で,[old] を [new] に置換
:[n],$s/[old]/[new]/g n 行目からファイルの末尾までの [old] を [new] に置換
:g/string/d string を含んでいる行を削除
:v/string/d string を含んでいない行を削除
Ctrl + a 現在のカーソルの位置から,最初に見つかった数字をインクリメント
Ctrl + x 現在のカーソルの位置から,最初に見つかった数字をデクリメント

範囲選択による大文字小文字の入れ変え

コマンド 処理内容
Vu 現在の行の文字を小文字にする
VU 現在の行の文字を大文字にする
g~~ 現在の行の文字の大文字小文字を反転させる
vEU 単語単位で大文字にする
vEu 単語単位で小文字にする
vE~ 単語単位で大文字小文字を反転させる

参考サイト

vimエディタ・スターターマニュアル #3 (カーソルの移動) — 名無しのvim使い

Vimを体系的に学ぶつもりのない人のためのVim講座 - Qiita

プログラマが知っておくべき100のVimコマンド | Lonely Mobiler

vim を使ってみる

筆者は,最近 vim を使い始めた.emacs でも良かったけど,vim 使ってみたかったから,vim を使う(emacsCUI(若しくは CLI) で使う方法があるみたいだから,emacs でも良かったかもな まぁ,動きゃいいんですよ,動きゃ

vim を動かす

さて,長らく Windows エディタを使ってきたせいか,起動した段階で色々問題が生じた.まず,ファイルがないので,保存しようとして,Ctrl + S をショートカットで入力したが,反応がない. 早い段階で,この方法では出来ないことを悟ったので,調べた.

vim には,モードというものがある(らしい).入力モード,ノーマルモード,コマンドモード,ビジュアルモードの 4 つである(調べたら,検索もモードの 1 つとして数えているところがある).

  • 入力モードは,その名の通り,文字を入力するためのモードである.このモードに入るには,「i」を入力すればよい(Insert の i だとか). 他にも,1 行空けて挿入するには,「o」を入力したり,カーソルの右側から入力したい場合は,「a」を入力したりすればよいらしい.

  • ノーマルモードは,カーソルの移動や,カット,ペースト等が行えるモード(基本のモード)である.vim を起動したときのモードがこれに当たる.

  • コマンドモードは,ファイルの保存やタブでファイルを開いたり等,vim エディタのコマンドを実行するモードである.「:」を入力することで,コマンドモードになる.

  • ビジュアルモードは,テキストの選択が出来るモード(らしい).筆者はまだあまり使ったことがない.これから勉強していく予定だ.「v」を入力することで,ビジュアルモードになる.

さて,簡単ではあるが,一通りモードのことは説明した.しかし,このままでは,別のモードに移動出来ない(入力モードは悲惨だ).そのために,一旦ノーマルモードに切り替える方法がある. 「ESC」を入力すればよい.とりあえず,困ったら「ESC」を連打することで,ノーマルモードには戻ることが出来る.

本題になるが,保存する方法が分からなかったので,調べたところ,コマンドモードで w を入力すればよいらしい.w は write の略だろうな.ということで,とりあえず,EGS を連打したのち,「:w」と入力した.すると,左下にコマンドが表示された!(Ubuntu 14.04 LTS 64-bit で確認)

この後,Enter を押すと,「E32: ファイル名がありません」と出てきた.名前をつけて保存する方法を調べると,「:w ファイルパス」とあったので,「:w ./sample.txt」として Enter を押すと,ファイルが保存できた.閉じるには,「:q」を入力(quit の略らしい)すればよいので,「:q」を入力して終了した.

慣れないと,大変だが,慣れてしまうと,かなり早く作業が出来る気がする.次回は,とりあえず,使えそうなコマンドをまとめてみようと思う(すぐ忘れるので).

参考サイト

vimエディタ・スターターマニュアル #2 (モードの切替) — 名無しのvim使い