TUTクラスタ計算機で好きな言語を動かす

この記事はTUT Advent Calendar 2016の17日目の記事です.

豊橋技術科学大学には,2つのHPCクラスタがあります. 一つは次世代シミュレーション技術者教育用クラスタ(以下,次世代クラスタ),もう一つは広域連携教育用クラスタ(以下,広域クラスタ)です.

  • 次世代クラスタでは,Xeon E2680(8コア)を2個,メモリを64GB搭載したノードが28ノードあります.
  • 広域クラスタでは,Xeon E5-2680 v2(10コア)を2個,メモリを100GB搭載したノードが30ノードあります.

クラスタの詳細はTUT HPC Cluster Wikiを参照してください.

情報系の研究室や,分子計算だったり電磁界解析などを行っている研究室では,活発にクラスタを利用しているようです. 私も,去年くらいから,コンピュータクラブの友達からクラスタ計算機の利用についていろいろ聞いていて,興味がありました. そこで,今年度初めに研究室の先生に利用申請を頼みました. 先生としても,

  • 研究室所有の計算用PC群がだいぶ古くなっており(10年前とかのが7台とか),近いうちに更新しなければいけない
  • 上記PCなどの管理は学生が行っているが,手間であること
  • 学生一人あたり年間実質1000円しかかからず,現状の何倍もの実行速度が得られる

などなどのため,すぐに了承して頂けました.

利用申請方法

計算機利用申込書に記入して,指導教員の先生にお願いしましょう.

Linuxbrewをクラスタ計算機につっこむ

クラスタ計算機の環境ではgitが古かったり,D言語コンパイラがなかったり,いろいろと不便なことが多く, そのままでは研究できませんでした. なので,私の研究室ではLinuxbrewというパッケージ管理システムをクラスタ計算機につっこみ,利用しています.

Linuxbrewは,OSX(MacOS)のHomebrewのLinux版で,Homebrewをフォークする形で開発が進められています. そのため,基本的にはHomebrewと全く同じで,利用可能なパッケージも一部を除きHomebrewと同じです.

Linuxbrewのインストールは簡単です. SSHクラスタの開発ノードに接続し,以下を実行します.

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install)"

TUTクラスタでは,ホーム領域が5GBしか割り当てられていないため,/gpfs/work/{user-id}領域を使用するように,Linuxbrewのフォルダを移動しましよう. ここで,{user}の部分はイニシャル+学籍番号(例:a123456)です.

$ mv ~/.linuxbrew /gpfs/work/{user}/.linuxbrew
$ mv ~/.cache /gpfs/work/{user}/.cache
$ mkdir /gpfs/work/{user}/tmp
$ ln -s /gpfs/work/{user}/.linuxbrew ~/.linuxbrew
$ ln -s /gpfs/work/{user}/.cache ~/.cache
$ ln -s /gpfs/work/{user}/tmp ~/tmp

また,Linuxbrewの各ディレクトリにパスを通しておきます. .bashrcなどに次の記述を追加します.

export PATH=$HOME/.linuxbrew/bin:$HOME/.linuxbrew/sbin:$PATH
export MANPATH=$HOME/.linuxbrew/share/man:$MANPATH
export INFOPATH=$HOME/.linuxbrew/share/info:$INFOPATH
export HOMEBREW_TEMP=$HOME/tmp

また,~/.linuxbrew/Library/Homebrew/brew.shの91行目を次のように編集し,/usr/bin/curlの代わりにLinuxbrewで入れたcurlが利用できるようにしておきます.

- HOMEBREW_CURL="/usr/bin/curl"
+ HOMEBREW_CURL="curl"

以上でLinuxbrewの使用準備が整いました. brew doctorを実行し,warningしか出なければ成功です.

$ brew doctor

古いコマンドを更新する

クラスタ環境のcurlgitが古いので,早速brewで新しいものをいれてみましょう.

$ brew install curl
$ brew install git

好きな言語のコンパイラを入れる

これでもうD言語だろうが,コンパイラさえbrewで提供されていればクラスタ上で動かすことができます.

$ brew install dmd dub

D言語LDCを入れる場合,2016年12月現在ではllvm3.9.0のビルドに失敗するので,.linuxbrew/Library/Taps/homebrew/homebrew-core/Formula/llvm.rbここのファイルに置き換える必要があります. その後,ldcを次のようにしてインストールできます.

$ brew install ldc --devel

こうした方がいいよって情報

があれば教えてください.

明日は

明日はコンピュータクラブのfoldoriくんです. TUTイス(物理)ということで,どんな記事なのか期待大です.

一人で合唱する方法の解説

伝搬とインパルス応答について

波の伝搬は,伝搬路の特性に左右されます.伝搬路のインパルス応答h(\tau)と呼ばれる特性を用いると,送信波x(t)と受信波y(t)は,次式のように表すことができます.

\displaystyle{y(t)=h(\tau) \ast x(t)}

ここで,演算子\astは畳み込み演算と呼ばれ,連続時間であれば

\displaystyle{(h \ast x)(t) = \int_0^\infty h(\tau) x(t-\tau) d\tau}

となります.ここで,\tauは遅延時間を表します.この式は何を表しているかというと,波は空間を直進しますが,その速度は音速だったり,光速です.したがって,時刻t=0で波を出したとしても,受信側では遅延して観測できます.また,波は壁などで反射や回折したり,いろいろな影響を受けます.そうすると,h(\tau)とは,受信信号y(t)に含まれている\tau秒遅延した送信信号x(t)の大きさのことです.なので,先ほどの積分の式は「受信波は0秒〜無限秒遅延した送信波の重ねあわせである」ということを表現しています.

本題

さて,本題に入ります.一人で合唱する方法を考えるわけですが,まずはN人の合唱している人たちの声が聞いている人にとってどのように聞こえるかを考えます.単純に,全員分の声を加算すればよいので,次のように表せそうです.ただし,人間には耳が2つありますので,受信波は2つになります.また,伝搬路の特性はすべての伝搬路で異なりますので,そのインパルス応答も異なります.

\displaystyle{y_1(y)= \sum_{i=1}^N h_{1i} (\tau) \ast x_i (t)}
\displaystyle{y_2(y)=\sum_{i=1}^N h_{2i} (\tau) \ast x_i (t)}

x_i(t)は,i番目の人が送信している波です.

ではy_1(t)y_2(t)をそのまま自分の口から発すれば合唱になるかというと,そうでもありません.なぜなら,自分の口から出る波は一つですが,受信波は2つあります.これはひどく致命的です.なので,とりあえず「二人で合唱する」としましょう.このとき,二人が出す送信波は \xi_1(t)及び \xi_2(t)とします.また,この二人が出す波も伝搬路の特性 g_{ij}(\tau)の影響を受けるとします.したがって,受信波は,

\displaystyle{y'_1(t) = g_{11}(\tau)  \ast \xi_1(t) + g_{12}(\tau) \ast \xi_2(t) }
\displaystyle{y'_2(t) = g_{21}(\tau) \ast \xi_1(t) + g_{22}(\tau) \ast \xi_2(t) }

となります.

ここで,一旦目的を整理しておきましょう.
僕たちは「x'_1(t)x'_2(t)を送信して,y'_1(t)y'_2(t)y_1(t)y_2(t)を再現」したいのでした.つまり,「y_1(t)y_2(t)を再現するx'_1(t)x'_2(t)を求めたい」わけです.もし,インパルス応答と送信波が畳み込みh(\tau) \ast x(t)ではなく,単純な積h(\tau) \ast x(t)ならどうなるでしょうか?実はすごく簡単な式に落とし込めます.

 \displaystyle{g'_{11}(\tau) \xi_1(t) + g'_{12}(\tau) \xi_1(t) = \sum_{i=1}^N h'_{1i} (\tau) x_i (t)}
 \displaystyle{g'_{21}(\tau) \xi_1(t) + g'_{22}(\tau) \xi_2(t) = \sum_{i=1}^N h'_{2i} (\tau) x_i (t)}

これを行列で書くと,

 \displaystyle{\mathbf{G}' \mathbf{\xi} = \mathbf{H} \mathbf{x}}

なので,解は次のようになります.

 \displaystyle{\mathbf{\xi} = \mathbf{G}'^{-1}\mathbf{H} \mathbf{x}}

しかしながら,インパルス応答と送信波を単純な積h(\tau) \ast x(t)でかけて受信波 y(t)が得られる場合というのは,反射波などの遅延波が一切なく,すべての波の遅延時間が同一である場合のみですので,このような仮定は不可能です.

周波数軸で考える

では,これでもうお手上げなのでしょうか.私達の置かれている状況は十分絶望的な気がしますが,ここで救世主が登場します.皆さん大好きなフーリエ変換です.フーリエ変換とは,関数 x(t)から関数 X(f)へ変換する変換で,

 \displaystyle{X(f) = \int_{-\infty}^{\infty} x(t) e^{-i2\pi f t} dt}

と表せる変換です.フーリエ変換の物理的な意味は,時間関数 x(t)が持っている周波数成分 X(f)を得る変換です.フーリエ変換を使うと,畳み込みを単純な積にすることができます!

これを証明してみましょう!
畳み込み h(\tau) \ast x(t)フーリエ変換は,次のようになります.
 \displaystyle{Y(f) = \int_{-\infty}^{\infty} \left( \int_0^\infty h(\tau) x(t-\tau) d \tau \right) e^{-i2\pi f t} dt}
ここで,積分の順序を入れ替えることができて,
 \displaystyle{Y(f)=\int_{0}^{\infty} h(\tau) \left( \int_{-\infty}^\infty x(t-\tau) e^{-i2\pi f t} dt \right) d \tau}
さらに,内側の積分フーリエ変換にするために,少し変形して,
 \displaystyle{Y(f)=\int_{0}^{\infty} h(\tau)e^{-i2\pi f \tau} \left( \int_{-\infty}^\infty x(t-\tau) e^{-i2\pi f (t - \tau)} dt \right) d \tau}
すると,内側の積分フーリエ変換になっているので,
 \displaystyle{Y(f)=\int_{0}^{\infty} h(\tau)e^{-i2\pi f \tau} X(f) d \tau}
 X(f)積分の外に出すことができて,
 \displaystyle{Y(f)= X(f) \int_{0}^{\infty} h(\tau)e^{-i2\pi f \tau} d \tau}
遅延時間が負であるような波は存在しないので, h(t) = 0, t<0が成立しますので,
 \displaystyle{Y(f)= H(f)X(f)}
となり,畳み込み積分が単純な積の形になりました.

よって,問題だった式もフーリエ変換することで,

 \displaystyle{G_{11}(f) \Xi_1(f) + G_{12}(f) \Xi_2(f) = \sum_{i=1}^{N} H_{1i}(f) X_i(f) }
 \displaystyle{G_{21}(f) \Xi_1(f) + G_{22}(f) \Xi_2(f) = \sum_{i=1}^{N} H_{2i}(f) X_i(f) }

こうなってしまえば,先ほど導出した逆行列の計算ができて,次のようになります.

 \displaystyle{
\begin{bmatrix}
G_{11}(f) & G_{12}(f) \\
G_{12}(f) & G_{22}(f)
\end{bmatrix}
\begin{bmatrix}
\Xi_1(f) \\
\Xi_2(f)
\end{bmatrix}
=
\begin{bmatrix}
H_{11}(f) & H_{12}(f) & \cdots & H_{1N}(f) \\
H_{21}(f) & H_{22}(f) & \cdots & H_{2N}(f)
\end{bmatrix}
\begin{bmatrix}
X_1(f) \\
X_2(f) \\
\vdots \\
X_N(f)
\end{bmatrix}
}

 \displaystyle{
\begin{bmatrix}
\Xi_1(f) \\
\Xi_2(f)
\end{bmatrix}
=
\begin{bmatrix}
G_{11}(f) & G_{12}(f) \\
G_{12}(f) & G_{22}(f)
\end{bmatrix}^{-1}
\begin{bmatrix}
H_{11}(f) & H_{12}(f) & \cdots & H_{1N}(f) \\
H_{21}(f) & H_{22}(f) & \cdots & H_{2N}(f)
\end{bmatrix}
\begin{bmatrix}
X_1(f) \\
X_2(f) \\
\vdots \\
X_N(f)
\end{bmatrix}
}

これで, \Xi_1(f) \Xi_2(f)が手にはいりましたので,あとはこれを逆フーリエ変換すれば時間領域の送信波となります.

まとめ

では最後にまとめておきます.一人で合唱するのは,人間の耳が2つある状況ではちょっと難しそうだったので,最低二人いる状況で話を進めました.すると,再現を行う全員分の伝搬路特性 h_{ij}(\tau)と,自分の伝搬特性 g_{ij}(\tau)さえわかっていれば,それらのフーリエ変換を使用することで,次のようになんとか計算できそうでした.

 \displaystyle{
\begin{bmatrix}
\Xi_1(f) \\
\Xi_2(f)
\end{bmatrix}
=
\begin{bmatrix}
G_{11}(f) & G_{12}(f) \\
G_{12}(f) & G_{22}(f)
\end{bmatrix}^{-1}
\begin{bmatrix}
H_{11}(f) & H_{12}(f) & \cdots & H_{1N}(f) \\
H_{21}(f) & H_{22}(f) & \cdots & H_{2N}(f)
\end{bmatrix}
\begin{bmatrix}
X_1(f) \\
X_2(f) \\
\vdots \\
X_N(f)
\end{bmatrix}
}

実際にはここから逆フィルタなどの考え方を使うと思うのですが,今回はここまでで止めておきます.
以上です.

1日限定のトークン認証システムを考えてみた

はじめに

タイトルのままです. その日限定で認証可能なトークン認証システムを考えてみました. 日付にIPアドレスなども付加すれば,そのIPアドレスのみとか制約を付加できると考えています.

いろいろ定義

この記事で使う関数とか変数を定義しておきます.

// 適当なハッシュ関数
string Hash(string val);

// HMAC
string HMAC(string val);

トークン生成

ユーザからの入力

  • ID: ID
  • PW: パスワード

生成方法

  • まず,IDとPWが正しいか普通にチェック
  • 正しければ,次のようにTokenペア生成
token = Hash(today.toString() + ID)
hmac = HMAC(token, "適当な秘密鍵(PWのハッシュ値とか)")

認証

ユーザからの入力

  • ID
  • token
  • hmac

認証方法

if(hmac == HMAC(token, "生成に使った秘密鍵(PWのハッシュ値とか)")
&& token == Hash(today.toString() + ID)
{
    認証成功
}
else
{
    失敗
}

思ったこと

tokenIDと日付さえわかっていれば簡単に生成可能. hmactoken秘密鍵(PWのハッシュ値とか)が分かっていれば生成可能. なので,サーバがわざわざ鍵を生成する必要もない気がする. HMACに使う秘密鍵がサーバで固有なものであれば話は別だけど.

最後に

セキュリティとか暗号とかそういうのを一切勉強したことがないので,トンチンカンなことを書いてると思います. 勉強のため,優しく教えて下さい><

僕が実務訓練を通して学んだこと

僕の大学は,4年生の1月上旬から2月下旬までという特殊な期間に実務訓練(いわゆるインターンシップ)が必修科目としてあります. 実際に企業や研究所で実務や研修を受けるわけですから,研究室とは全く違うことを学ぶことができます. 今回は,そんな実務訓練を通じて学び,自分で考えたこととして,「ソフトウェアの標準化」について,特に社内ライブラリとプログラミング言語について書きます. もちろん,本文には,私の実務訓練先の企業の情報は一切含まれませんので安心してください.

標準化とは?

実は,僕は実務訓練を行うまでソフトウェア開発における標準化について一切知りませんでした. この記事を読んでいる人は,多分標準化について熟知されている方たちだと思うのですが,一応標準化についておさらいしましょう. 標準化について,NTT DataのWebページには次のように記載があります.

システムやソフトウェアを開発するプロジェクトでは、作業の手順や成果物を定義するのが一般的です。すべての開発担当者の作業を標準化することで、作業効率や作業品質の向上、コミュニケーションロスの低減などを実現できます。これによって、プロセス品質が向上し、さらには開発するプロダクトの品質も向上することにつながります。NTT Dataのコラムページより

つまり,標準化とは,結果(プロダクトの品質向上)を達成するために,過程(プロダクトを作るプロセス)を確立することのようです.

標準化のメリットとして,プロダクトの品質向上と高い生産性はもちろんのこと,プロダクトとプログラマの独立性*1が向上します.

標準化と言語と社内ライブラリ

標準化を推し進める場合,社内で使う言語も統一する必要があります. また,その会社独自のソフトウェアライブラリも開発する必要があります. もちろん,社内ライブラリは再利用性が高いものでないといけませんし,社内で使う言語も全員が慣れ親しんだ言語である必要があります. これらを考慮すれば,オブジェクト指向言語オブジェクト指向なライブラリを組むことが最適であるように感じます.

オブジェクト指向言語オブジェクト指向なライブラリが適切に組まれていれば,その言語を使用した経験が一切なくても実際に開発を行うことができる,これを実務訓練で最初に学ぶ事ができました.

では,最適に組まれたライブラリとは何でしょうか? 僕は,誰が見ても使い方がわかり,どこにどんな関数があるかが誰でもわかり,派生したクラスや処理を書く場合に一切コピペを必要としないライブラリだと思いますし,たぶんみなさんもそう思っていただけると思います.

たとえば,このサイト様から引用し,データベースに次のようなテーブルがあるとします.

CREATE TABLE SHOHIN(
    CODE  CHAR(3) PRIMARY KEY,
    NAME  CHAR(20),
    PATH  CHAR(40),
    KIND  CHAR(12),
    GENKA DECIMAL(7)
)

このテーブルを,例えばC++で表現するなら次のようになるでしょう*2

struct Shohin
{
    std::string code;
    std::string name;
    std::string path;
    std::string kind;
    double genka;
};

C++でこのように型を定義すればデータベースの方のテーブルも設定されると楽ですが,C++の構造体では,最大長さやDECIMALなどなどを表現できません. もしくは,逆にデータベースのテーブル定義からC++の構造体を生成する方法があります. この方法は,外部ツールを使用する必要があるので,テストの段階でテーブル定義を変更する場合,またツールで構造体を生成する必要があります. 構造体を生成しなおすということは,その他さまざなコードにも変更を加える必要があるわけです. これでは生産性は向上しません.

やっぱりD言語

こういう時,やっぱりD言語は強いです. たとえば,次のように構造体を定義してやります.

@SQLTable!"SHOHIN"
struct Shohin
{
  @SQLColumnNameAttr!"UpperCase"
  {
    @SQLAttr!`"商品コード"|CHAR(3)|Key`
    string code;
    
    @SQLAttr!`"商品名"|CHAR(20)`
    string name;
    
    @SQLAttr!`"画像URI"|CHAR(40)`
    string path;
    
    @SQLAttr!`"商品種別"|CHAR(12)`
    string kind;
    
    @SQLAttr!`"原価"|DECIMAL(7)` @Invariant!"a >= 0"
    real genka;
  }
}

なんかゴテゴテに修飾されていますが,コレ1つを定義しておけばSQLのCREATE TABLE文を生成することも可能ですし, たとえばデータベースに格納するデータが正常かどうかをチェックする関数も生成可能です*3. さらに,SELECTやWHERE,ORDER BYの自動生成などなども可能です. この方法の重要な点は,プログラマがわざわざコードを書かなくても,この構造体宣言さえしておけばすべて自動生成可能であることです. つまり,プログラマは何もする必要はありませんから,誰がプログラムを書いたとしても誰も迷うことはありません. さらに生産性は向上しますし,人的なミスは圧倒的に削減されます. これこそが標準化が目指すものではないでしょうか.

「けど,D言語って聞いたこと無いよ」って,最初の方に書きましたが,適切にライブラリが組まれていれば,一切書いたことのない言語でもスムーズに書くことができます. 問題ありません.

 それでもD言語はちょっと

それでもD言語は無理,そりゃあそうでしょう. 未だに言語仕様は確定してないし,ライブラリも充実しているとは言えません. そういう会社にオススメなのが,.NET系言語です. .NET系言語は,非常に優れたライブラリを持ち,さらにユーザー定義の属性や実行時リフレクションも行えますので,D言語と同じような機能を作ることも不可能ではないと思います. 多少強引になるかもしませんが. さあ,C#を書くのです!

まとめ

会社の人へ, D言語書きましょう.

*1:プログラム制作者でなくても,保守がしやすいということ

*2:DECIMAL(7)をdoubleで表すのは良いのだろうか?謎

*3:もちろん,SQL文を生成する関数テンプレートとか,チェックする関数テンプレートを書かないといけませんが,ライブラリで定義してれば後は呼び出すだけです

ラプラス変換を使って難しい積分を簡単に解く話

はじめに

なぜこの記事を書こうかと思ったかというと,昨年度(2014年度)の複素解析という広義で,次のような積分の問題が出題されたためです.

{\displaystyle \int_0^{\infty} \cos x^2 dx}

みなさんコレ解けますか? この積分の名前はフレネル積分というそうです. フレネル積分の値は \frac{1}{2}\sqrt{\frac{\pi}{2}}になります.

このフレネル積分,以下のブログ様では,なんと4つの記事にまたがり証明されています. かなり参考になる解法なので,複素解析の講義を取っている人は要確認です.

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

今回は,この難しく,めんどくさいフレネル積分ラプラス変換を使って綺麗に(数学的には汚く?)解きます. 今回使用するテクニックは,様々な積分を簡単に解くことができる方法ですので,使ってみてください.

本題:フレネル積分を解く

いきなりですが,\cos x^2e^{ix^2}を用いて表します.

{\displaystyle I = \int_0^{\infty} \cos x^2 dx = \Re \left\lbrack \int_0^{\infty} e^{ix^2} dx \right\rbrack }

 x^2=tと置換します.このとき,dx=\frac{1}{2\sqrt{t}}dtですので,次のように変形できます.

 {\displaystyle I = \Re \left\lbrack \int_0^{\infty} \frac{1}{2} \frac{1}{\sqrt{t}} e^{it} dt \right\rbrack }

ここで,s=-iと定めると,さらに次のように変形できます.

 {\displaystyle I = \Re \left\lbrack \int_0^{\infty} \frac{1}{2} \frac{1}{\sqrt{t}} e^{-st} dt \right\rbrack}

さて,f(t)に対するラプラス変換とは,

 {\displaystyle \mathcal{L}\lbrack f(t) \rbrack = \int_0^{\infty} f(t) e^{-st} dt}

でした.  Iは,ラプラス変換を用いることで,次のように表すことができます.

 {\displaystyle I = \frac{1}{2} \Re \left\lbrack \mathcal{L}\left\lbrack \frac{1}{\sqrt{t}} \right\rbrack \right\rbrack}

これでだいぶ綺麗になりました. あとは, \mathcal{L}\left\lbrack \frac{1}{\sqrt{t}} \right\rbrackさえわかれば解けますね.

ラプラス変換の公式に,次のような物があります.

 {\displaystyle \mathcal{L}\left\lbrack t^{\alpha} \right\rbrack = \frac{\Gamma(\alpha+1)}{s^{\alpha+1}}}

この公式で, \alpha=-\frac{1}{2} s=-iとすれば求まります.

{\displaystyle \Gamma \left(\frac{1}{2} \right) = \sqrt{\pi}}

ですから,結局

 {\displaystyle \mathcal{L}\left\lbrack \frac{1}{\sqrt{t}} \right\rbrack = \frac{1}{\sqrt{s}} \sqrt{\pi}}

また,

 {\displaystyle \frac{1}{\sqrt{-i}} = e^{i(\frac{\pi}{4}+n\pi)}=\pm \frac{1}{\sqrt{2}}(1+i)}

です. 困ったことに,正負の両符号が出てしまいました. ここで,

 {\displaystyle I = \Re \left\lbrack \int_0^{\infty} \frac{1}{2} \frac{1}{\sqrt{t}} e^{it} dt \right\rbrack }

であったことを思い出します. これをちょっと変形すると,次のように級数として表すことができます.

 {\displaystyle I = \sum_{k=0}^{\infty} \int_{k \pi}^{(k+1)\pi} \frac{1}{2} \frac{1}{\sqrt{t}} \cos(t) dt = \sum_{k=0}^{\infty} I_k}

 x\ge 0 \frac{1}{\sqrt{t}}は単調減少関数,さらに k \ge 0について|I_{k+1}| \le |I_k|ですから, I_{2k} + I_{2k+1} \ge 0となります. したがって, I \ge 0です.

 {\displaystyle I = \frac{1}{2} \Re \left\lbrack \mathcal{L}\left\lbrack \frac{1}{\sqrt{t}} \right\rbrack \right\rbrack = \frac{1}{2} \Re \left\lbrack \pm \frac{1}{\sqrt{2}}(1+i) \sqrt{\pi} \right\rbrack}

以上より, I \ge 0を満たす解は,次の通りとなります.

 {\displaystyle I = \int_0^{\infty} \cos x^2 dx = \frac{1}{2} \sqrt{\frac{\pi}{2}}}

まとめ

ラプラス変換を用いると簡単になる積分の問題として,フレネル積分を取り上げました. 結果として,ラプラス変換を使用しない正攻法を用いた方法よりも簡単に求めることができたと思います. ちなみに,ラプラス変換を使用する方法では,簡単な置換積分ラプラス変換とガンマ関数の値さえ覚えておけば,フレネル積分を解くことができます.

D言語Web本のレビューをした話

はじめに

タイトルの通り,来年1月くらいにPackt Publishingから出版される予定のD Web Developmentのテクニカルレビュアーをやらせてもらったお話です. 本の内容とかは書けませんが,どのような経緯でこうなったのかの流れを書いていきます.

出版社からのお誘い

ある日突然,こんなメールが届きました.

担当者(意訳):「やあ,PACKT PublishingではD言語のvibe.dに関する本を出そうと思ってるんだけど興味ない?Googleで検索したらGitHubのキミのプロフィールにたどり着いたんだけど.レビューするのに興味あったらメールしてね?」

このメールだけだと,「レビュー」とは何をすることなのかイマイチ把握できなかったので,以下の内容で返信してみました.

私(意訳):「メールありがとうございます。大変興味がありますが,私は今まで一度もそのようなことをしたことがありません.もしよろしければ,詳細を教えていただけますか?」

それに対するPACKTの担当者さんからは次のようなメールが返ってきました.

担当者(意訳):「メール返信ありがとう.2016年1月に本を出したいんだけど,レビュアーとして,出版前の本の内容を読んで,コードが正しく動くかとか文章の内容をチェックして欲しいんだ.レビューしてくれた内容を著者にフィードバックするよ.毎回1, 2章ずつ送るから2日くらいでレビューして返信よろしく.」

章当たり2日間くらいしか時間がないらしく,大変タイトなスケジュールであることがわかります.

実際になにをやったか

その後,何回かメールをやり取りし,実際に僕は4章から9章までレビューすることになりました. PACKT側もコッチのことをちゃんと考えてくれているらしく,月1回くらいのペースで,かならず金曜日に「この章のレビューを月曜日までにお願いね」とのメールが届きました. 毎回1章ずつで,各章数ページか十数ベージだったので,英語に不慣れな僕でも大丈夫でした.

各章はWordで書かれており,私はWordの機能でコメントを書き込んで返信する,という作業でした. あと,「アンケート用紙」なるものがあり,「不足している内容はなにか?」とか「この章に点数をつけるとすれば何点か?」とか「点数を上げるためにはどうすればよいか?」などのコメントを書き,提出しました.

テクニカルレビュアーは,出版後に本がもらえるのと,本に名前とプロフィールが載ること以外は無償です. 僕も研究が結構忙しかったものですから,基本的にはそれに見合った程度の事しかしていません. もちろん,D言語の本のプロジェクトに関われるという人生で一度あるかないかのことなので,やることはやりました.

今は

10月くらいに最後の章のレビューが終わりました. それ以来PACKTからは音信不通で,多分1月の出版後にまたメールが来るのだと思います. 楽しみに待っています.

買ってよかったものを紹介する

はじめに

猫でも犬はわかるのでしょうが,僕は「猫でもわかる犬」というタイトルがわからなかったので,代わりに「僕がここ数年で買った中で最高だったデバイス」を4つ紹介します. 技科大生のみなさんはぜひ購入してみてください.

トラックボール

光学式のマウスの欠点として,手首を痛めるという問題があります. また,絶対に平面に置いて操作しなければいけないという制約があります. トラックボールですとそれらが解決します. トラックボールは,指でボールを転がして操作するポインティングデバイスなので,マウスのように腕や手首を動かす必要がありません. また,指でボールを転がせれば,平面の上に設置する必要はありません. 欠点ももちろんあり,時々掃除しなければいけないことと,慣れるまでは操作しにくいという点があります.

www.amazon.co.jp

高級キーボード

Realforceは本当にいいものです. こればっかりは実際にキーボードを打たないとわからないと思います. 利点は,キーが軽いので疲れにくいです. あと,人差し指で押すようなキーは重めに設計されていたり,逆に薬指とかで押すようなキーはかなり軽めに設計されています. 一番重いキーでも,他のキーボードよりも軽いと思います. とにかく素晴らしいキーボードです.

www.amazon.co.jp

www.amazon.co.jp

ノイズキャンセリングヘッドホン

僕は,音質厨とかそういう部類の人間ではないので,ヘッドホンとかイヤホンの音質にこだわりはありません. ただ,雑音が大きな環境でも快適に音楽を聞きたくて,ノイズキャンセリング機能が 付いたヘッドホンが欲しくなりました. ノイズキャンセリング機能があるの無いのかで相当値段は変わります. メーカーとかよくわからなかったので,くそ高かったんですが,とある文庫本の中で紹介(ステマ)されていたBOSEのQC25を買いました.

このヘッドホンは低周波数領域の雑音をかなり切ってくれるように感じます. 電車とかバスとか,あと部屋の冷暖房機の音をガッツリ消してくれます. 雑音が小さくなるということは,相対的に音楽の音量も小さくできるので,耳にも良いと思います. 普通のイヤホンで音漏れするくらいの大音量で聞いてる人は,ノイズキャンセリング機能がついたヘッドホンかイヤホンを買うべきです. あと,音楽を流さずに,ただ耳につけているだけで耳栓として機能しますので,僕みたいに作業に集中したい人にオススメです. 本当にオススメです.

www.amazon.co.jp

大容量USBメモリ

現代の学生にとっては必需品となったUSBメモリですが,数年前までは4GBあれば多い方でした. 今では8GB,16GB,32GBといった容量のものも販売されています.

私がおすすめするUSBメモリ(?)は,120GB以上の高容量・高速USBです. これらの代表的なものは,http://ascii.jp/elem/000/000/994/994553/ でわかりやすくまとめられています. 大体の相場は,120GBで2万円弱,安いもので1万円前後だと思います. 所詮USBメモリに1〜2万円も払うのかと思うと思いますが,書き込み・読み込み速度が一般的なUSBメモリとは桁違いです. また,容量も大きいので,Linuxを入れることができます!! 僕は,USB-SSDUbuntuを入れて研究で使用しています.

www.amazon.co.jp

www.amazon.co.jp

まとめ

今回は技科大生が買っておくべきデバイスを紹介しました. これらのデバイスは結構な値段がしますが,Realforceでも2万円くらいなのでバイトすれば余裕です. ノイズキャンセリング機能付きのヘッドホンはかなり高価なので,いつもノイズの中で爆音で聞いてる人は,耳を大切にするという意味で買うべきです. あと,猫でも犬はわかりますが,僕は「猫でもわかる犬」を理解できませんでした.