Beamerによる発表小技集

LaTeX2e美文書作成入門第6版に Beamer, TikZの章が追加(?:4版にはなかった)されたので、 記念に私のBeamer小技を公開してみる。

初級編

handout

\documentclass[12pt,handout]{beamer}

とすると、\pause等のアニメーションを考慮しない、 配布用の資料が作れる。

Logo

\logo{\includegraphics[width=1cm]{figure/logo.png}}

プリアンブルに書くと全ページに表示される。

Theme

お気にいりは標準のこれ:

\usetheme{CambridgeUS}

columns

プレゼンでは良く2行のページを使う:

\begin{columns}
    \begin{column}{.4\textwidth}
        ...
    \end{column}
    \begin{column}{.6\textwidth}
        ...
    \end{column}
\end{columns}

column環境の引数で横幅を指定できる。

block

\begin{block}{定常進行波解}
    \footnotesize
    \begin{itemize}
        \item ...
        ...
    \end{itemize}
\end{block}

強調して表示してくれる。column環境の幅を認識してくれる。 これを使用するのと、単なるitemaize環境だけのだと、 大きく見栄えが異なる。 columnsと組み合わせて使うと便利

\begin{block}{KSEのフィルター方程式}
    \begin{equation*}
        ...
    \end{equation*}
    \begin{itemize}
        \item ...
    \end{itemize}
\end{block}
\pause
\begin{columns}
    \begin{column}{.45\textwidth}
        \begin{block}{対称性}
            ...
        \end{block}
    \end{column}
    \pause
    \begin{column}{.5\textwidth}
        \begin{block}{定常進行波解}
            ...
        \end{block}
    \end{column}
\end{columns}

上のブロック、左下のブロック、右下のブロックと順に説明する。

単なる\pauseでなく、もう少し複雑な表示の切り替えには

\begin{columns}
    \begin{column}{.5\textwidth}
        \begin{block}<1>{span-wisely localized}
            \begin{figure}[h]
                ...
            \end{figure}
        \end{block}
        \begin{block}<1-2>{stream-wisely localized}
            \begin{figure}[h]
                ...
            \end{figure}
        \end{block}
    \end{column}
    \begin{column}{.4\textwidth}
        \begin{block}<1>{wall-normally localized}
            \begin{figure}[h]
                ...
            \end{figure}
        \end{block}
    \end{column}
\end{columns}

のようにする(1:全部,2:左下のみ)。

table of contents

\frame{\tableofcontents}

\section, \subsectionで指定されているタイトルを列挙する。 今回の発表の目次的な。

\section{Method}
\frame{\tableofcontents[currentsection]}

目次の内、今のセクションだけ強調表示したスライドを挿入する。 上記の場合、Methodが強調される。

vspace, hspace

上手く位置が調整できない時の最終手段。 \vspce{-1cm}で左に1cm寄る

応用編

幅を自動取得するbox

\newlength{\bw}
\newcommand{\vcbox}[1]{
    \settowidth{\bw}{#1}
    \parbox{\bw}{#1}
}

\settowidthで引数で指定された物 (\includegaphixとか)のサイズを取得して\bwに保存。 \parboxでボックス化する。

TikZ

おまけ程度に:

\begin{tikzpicture}[domain=0:10]
    ...
\end{tikzpicture}

domainは横軸を決める。 図の左端が0、右端が10になる。

長さの定義

\def\distnode{28}
\def\righttoleft{27.5}

何度も使う場合。

矢印

\draw[->] (0,0) -- (9,0) node[right] {\scriptsize $x$};

x軸

塗り潰す

\fill[blue!20!white] (0,0) -- (4.5,0) -- (4.5,1) -- (0,1);

色はbluewhiteの他に、混合色blue!20!white(青:80%,白:20%)、 あるいはRGB指定した色

\definecolor{redblack}{rgb}{.4,0,0}

(プリアンブルで定義しておく)が指定可能。

曲線

\draw[variable=\t,domain=0:4] plot ({\t},{-\aL*(\t-\bL)*(\t-\bL)+\cL}) node {};

domainvariableの動く範囲。

曲線で指定された領域を塗り潰す

\fill[fill=white!60!green] (0,0.5) --
plot [variable=\t,domain=0:4.08] ({\t},{-\aLs*(\t-\bLs)*(\t-\bLs)+\cLs}) --
plot [variable=\t,domain=4.93:0] ({\t},{-\aUs*(\t-\bUs)*(\t-\bUs)+\cUs}) -- cycle;

Links

LLVMリンク集

最近何かと話題のLLVM(low-level virtual machine)。 今回はLLVM初心者が、どうしてLLVMが魅力的と思ったか、 幾つかリンクを紹介する形でまとめます。

リンク集

LLVM フレームワークで実用的なコンパイラーを作成する: 第 1 回

早速ですが、紹介記事です。曰く:

LLVM (Low Level Virtual Machine) は、 任意のプログラミング言語で作成されたプログラムを コンパイル時、リンク時、実行時に最適化するために設計された、 極めて強力なコンパイラー・インフラストラクチャーフレームワークです。 LLVM は多岐に渡るプラットフォームで動作し、 その最大の特徴である、高速に実行されるコードを生成します。

つまりC/C++に限らず、様々な言語で書かれたコードを それぞれのプラットフォームに最適化されたバイナリにコンパイルする事ができます。

実際にLLVMに基づいたコンパイラが多数開発さています。

コンパイラが存在するDはともかく、 PythonLuaをネイティブコードに変換できる事は非常に魅力的に思えます。

またGCCをフロントエンドとして使用できるため、GCCでサポートされている

で書かれたコードはLLVMの中間表現であるLLVM IRにコンパイルする事ができ、 LLVMの最適化の恩恵を受けられます。 もっともこれらの場合、GCCにより最適化されたバイナリを既に使用できるのですが。

この記事はツール(lli, llvm-config, etc.)の使い方、 LLVM APIによる中間コード(IR)の自動生成までを解説しています。

CUDA LLVM Compiler

nVidiaによるGPGPUのためのフレームワークであるCUDAのコンパイラnvccはLLVMに基づいています。

任意の言語で書いたコードをLLVM IR(正確にはそのサブセットであるNVVM)に変換できれば、 nVidiaの提供するNVVMからPTX(GPU用の低級言語)への変換用バックエンドを用いて GPU上で動作するバイナリを生成する事ができます。

つまりCUDAのような少し特殊な言語を使用せずに、 通常のC/C++GPU用のコードに変換しうるという事です。 実際にFortranで実行している猛者がいます:

また直接NVVM書いている人もいます:

CUDAだけでなくOpenCLでも同様の取り組み(?)が有る様です:

The LLVM Compiler Infrastructure Project

本家のHPです。ニュースやダウンロードはこちらから確認します。 LLVMは非常に活発に開発されており、

  • 2014/01/02 3.4 (最新)
  • 2013/07/17 3.3
  • 2012/12/20 3.2
  • 2012/05/22 3.1
  • 2011/12/01 3.0

のようにおよそ半年毎にリリースがあります。

最後に

今後は公式のドキュメントを元に勉強していこうと思います。

vimでひかえめな自動保存

Vim Advent Calendar 2013、 67日目の記事になります。

御存知の通り、 webapi-vimの出現により vimによって簡単にwebサービスを読み書きができるようになりました。 さらにunite.vimvim-metarwを 使用する事で簡単にインターフェイスを構築できます。

しかし、これらのサービスのAPIの応答は、 一般にローカルに保存する場合に比べ圧倒的に時間がかかります。 さらに現状のvimではajaxのようにスクリプトを非同期実行できない。 もしvim-metarwのwriteで毎回送信する場合、 :wと押すたびに数秒待たされるかもしれない。 かといって手動で送信するのは忘れがち。

つまりアクセスの回数を絞った自動保存機能が欲しい

試行錯誤編

という事で試行錯誤が始まります。 多分autocmdにそれっぽいトリガーがあるだろうと思ってhelpを読む事数十分。。。 (あまり読みなれてない)

BufUnload       Before unloading a buffer.  This is when the
                text in the buffer is going to be freed.  This
                may be after a BufWritePost and before a
                BufDelete.  Also used for all buffers that are
                loaded when Vim is going to exit.
                NOTE: When this autocommand is executed, the
                current buffer "%" may be different from the
                buffer being unloaded "<afile>".
                Don't change to another buffer, it will cause
                problems.
                When exiting and v:dying is 2 or more this
                event is not triggered.

多分これっぽいんだけど、なんか後半に良くわからない事が書いてるorz

めげずに<afile>について調べると、

<afile>  When executing autocommands, is replaced with the file name
         for a file read or write.
<abuf>   When executing autocommands, is replaced with the currently
         effective buffer number (for ":r file" and ":so file" it is
         the current buffer, the file being read/sourced is not in a
         buffer).

つまりバッファがアンロードされる時の現在のバッファ(%)が トリガーが指定されたバッファ(<abuf>)と違うかもしれないという事か!!(オウム返し) :bdeleteで消す場合とか:qaで全部閉じる場合を考えろってことか。

ともかくこれで行ける!? <abuf>はきっとexpand()使うんだろう:

function! s:buffer_infos()
    let file_name = expand("<afile>")
    let buffer_number = expand("<abuf>")
    let buffer_name = bufname(buffer_number)
    echo "File name    : " . file_name
    echo "Buffer number: " . buffer_number
    echo "Buffer name  : " . buffer_name
    let lines = getbufline(buffer_number, 1, '$')
    echo lines
endfunction

augroup test_trigger
    autocmd!
    autocmd BufUnload test.vim call s:save_buffer_to_file()
augroup END

多分これでいけるはず!! :so %してバッファを閉じるぜ!!!

File name    : test.vim
Buffer number: 1
Buffer name  : 
[]

(´・ω・`)ショボーン

bufname({expr})                        *bufname()*
        ...
        If the {expr} is a String, but you want to use it as a buffer
        number, force it to be a Number by adding zero to it: >
            :echo bufname("3" + 0)
        If the buffer doesn't exist, or doesn't have a name, an empty
        string is returned. 

これか?

function! s:buffer_infos()
    let file_name = expand("<afile>")
    let buffer_number = expand("<abuf>")
    let buffer_name = bufname(buffer_number + 0)
    echo "File name    : " . file_name
    echo "Buffer number: " . buffer_number
    echo "Buffer name  : " . buffer_name
    let lines = getbufline(buffer_number, 1, '$')
    echo lines
endfunction
File name    : test.vim
Buffer number: 1
Buffer name  : test.vim
[ "function! s:buffer_infos()", "    let file_name = expand("<afile>")", "    let buffer_number = expand("<abuf>")", "    let buffer_name = bufname(buffer_number)", "    echo "File name    : " . file_name", "    echo "Buffer number: " . buffer_number", "    echo "Buffer name  : " . buffer_name", "    let lines = getbufline(buffer_number, 1, '$')", "    echo lines", "endfunction", "", "augroup test_trigger", "    autocmd!", "    autocmd BufUnload test.vim call s:save_buffer_to_file()", "augroup END", ]

大勝利!!! 別バッファから:bdeleteしても上手く動く (`・ω・´)キリッ

まとめ

最終的に

function! s:send(lines)
    " send data to web service
endfunction

function! s:wrapper()
    let buffer_number = expand("<abuf>")
    let lines = getbufline(buffer_number + 0, 1, '$')
    call s:send(lines)
endfunction

augroup ModestAutoSave
    autocmd!
    autocmd BufUnload * call s:wrapper()
augroup END

とすればいい!パターンの部分は適当に。

おわりに

プラグインとして公開しようと思っていたのですが、 autocmdのパターンの扱い(変数が使えない?)がよくわからなかったので無期限延期しました。 結局すごく短かいですし。

最近vimプラグインを作成し始めた新参なので、 間違い等指摘してもらえると助かります。

ctestの導入

ctestはcmakeに付随するテスト実行支援ツールである。 Boost TestやCppUnitとは異なり、あくまで実行を支援するツールである。 公式のページを見ると、ダッシュボードを導入しないといけないような印象を受けるが、 cmake管理化のプロジェクトであれば単独で使用できる。

何ができるか?

あなたがcmake管理化のプロジェクトを開発中、 テストを書く必要があるとする。 テストを書く事の重要性は耳にタコができるほど聴いたが、面倒な事は面倒だ。

ともあれ、mylibraryの機能Func1のテストコードtestFunc1.cppを書いたとしよう。 残念ながら、テストコードは自分でかかなければならない。 しかし、テストコードのビルドと実行は手伝う事ができる。 もしあなたが以下に説明する設定を施している場合、 あなたは単にテストコードtestFunc1.cppを含むディレクトリの CMakeLists.txtに以下の一行を追加すればいい。

mytest(Func1 S testFunc1.cpp mylibrary)

よりよいテストのためには次の行さらに前に追加するべきだろう:

set(CMAKE_BUILD_TYPE Debug)

これであなたはそのディレクトリで

make

とすれば、このコードをTEST_Func1_Sコンパイルする事ができ、

make test

で実行する事ができる。 テストした結果は

Test project /path/to/mylibrary/test
      Start  1: TEST_Func1_S
 1/1  Test  #1: TEST_Func1_S .....................   Passed    0.02 sec

100% tests passed, 0 tsets failed out of 1

Total Test time (real) = 0.02 sec

のように表示される。 もちろん実行ファイルをそのままターミナルから実行する事も可能である。

これは現在のディレクトリ以下にあるテストを再帰的に実行するので、 プロジェクトの一番上で実行すれば全てのテストが実行される。 実行ファイルが異常終了した場合にはテストが失敗したと見做され、 まとめて表示される。

これによりコードを変更した際の再テストが

cd $PROJECT_HOME
make test

とするだけでよくなる。

使い方

この記事では読者はcmakeの基本的な使い方(add_executableくらい)を知っているとする。 まず先に私のCMakeLists.txtの抜粋を示す。

enable_testing()
add_custom_target(build_test)
add_custom_target(short_test COMMAND "ctest" "-R" "TEST_.*_S")
add_custom_target(long_test COMMAND "ctest" "-V" "-R" "TEST_.*_L" "2>&1" ">" "long.log" "&")
add_dependencies(short_test build_test)
macro(mytest name type src libs)
    set(test_name TEST_${name}_${type})
    add_executable(${test_name} ${src})
    target_link_libraries(${test_name} ${libs})
    add_test(${test_name} ${CMAKE_CURRENT_BINARY_DIR}/${test_name})
    add_dependencies(build_test ${test_name})
    unset(test_name)
endmacro(mytest)

やっている事は以下の4つ:

  • ctestの有効化 enable_testing()
  • targetの追加 build_test, short_test, long_test
  • 依存関係の追加 (short_test depends on build_test)
  • mytestマクロの定義

ctestの有効化

enable_testing()

これを行なってcmakeを実行すると各ディレクトリにTestingディレクトリが作成される。 ctestを使用するには必須である。

targetの追加

cmakeではshellスクリプトを実行するターゲットを作成する事ができる。

add_custom_target(short_test COMMAND "ctest" "-R" "TEST_.*_S")

によって

make short_test

は依存する物(build_test)をmakeした後、

ctest -R TEST_.*_S

を実行する。 -Rは名前が正規表現に一致するテストをすべて実行する。 実行ファイル名にSが付いているのはこのためである。 というのも上述のコードは私の数値計算のコードなので、 一秒以内に終るもの(Sort)もあれば、数十分かかる物(Long)もある。

依存関係の追加

make short_test

とした際にbuild_testコンパイルされるようにしたのが、

add_dependencies(short_test build_test)

この行である。 さらにbuild_testが全てのテストに依存するようにしたのが マクロ中の

    add_dependencies(build_test ${test_name})

この行である。 つまり結局

make short_test

とすれば全てのテストがコンパイルされ、実行されるのである。

マクロの定義

macro(mytest name type src libs)
    set(test_name TEST_${name}_${type})
    add_executable(${test_name} ${src})
    target_link_libraries(${test_name} ${libs})
    add_test(${test_name} ${CMAKE_CURRENT_BINARY_DIR}/${test_name})
    add_dependencies(build_test ${test_name})
    unset(test_name)
endmacro(mytest)

さていよいよマクロの定義である。 macroは最初の引数にマクロの名前を、 以降の引数にマクロの引数を取る。 setでテスト名を生成し、 add_executableで実行ファイルを生成する。 肝心なのがadd_testで、これがテストを定義している。 第一引数がテストの名前、第二引数がテストの実行ファイルである。 この際実行ファイルのパスに注意する。また追加で引数も追加できる。

上述の通りこれをbuild_testの依存関係に追加する事で、 make short_testで一気にmakeできる。

何故複雑な依存関係を構築したか?

ここまでで読者は不思議に思ったに違いない: 依存関係を設定しなくても全てのテストがmakeされるのではないかと。 その通りである。 しかし、ある設定をしている場合、そうはならない。

add_subdirectory(test EXCLUDE_FROM_ALL)

がその正体である。 これはtestディレクトリ以下を追加するが、 makeではtest以下のexecutableはmakeしない、という指示である。 これにより不要なビルドを避ける事で、 ビルド時間を削減するという恩恵が得られる。 上記の設定はこの環境下で行なったための回避策である。

hateblo.vimのmetarw化

pluginのテストのためにこの記事を使用しているため、 情報がおかしい場合があります。 ご注意ください。

hateblo.vimをmetarw化した。

GitHub - termoshtt/hateblo.vim

気にいらなかった挙動は以下の2点

  • 記事名のファイルが所構わず作成される
  • 新規記事を書き始めにくい
:e hateblo:

で起動する。

コードを読む過程でちょっと書き換えすぎたので、 現在整理中。そのうちpull requestをなげる予定。 refactoring部分とmetarw化の部分を分けてrequestすると思う。

まだ不十分な点が多く、

  • New Entryで記事名の入力の際に何も表示されない(入力は成功する)
  • 投稿時にwebの応答を待つため、1秒近く止る

はそのうち改善する。

Entryのtitleとcategoryの指定方法を変えた。 この記事を

:e hateblo:{entry_id}

で開くと({entry_id}は実際には20桁くらいの数値)先頭に、

TITLE:hateblo.vimのmetarw化
CATEGORY:vim

という行が入る。 ここを保存する際に読み込むので、 この行を変更するとタイトルとカテゴリが変更できる。 これならタイトルの入力中に補完が効く。

だいぶ使用できるようになってきた。

投稿した際の遅延だけはどうしようもないのか?

iPadで論文を読む

以前の記事でpybtexとjinja2を使った論文のリストの生成について書きました。 今回から何回かでそれを発展させて作ったiPadでつかえる論文管理webアプリについて紹介します。

https://github.com/termoshtt/articles

前回同様githubで公開してありますので、使ってもらえるとありがたいです。 つたない英語が読みにくい場合はここで質問してもらえると補足できます。

articles

このアプリはそもそもiPad、特にGoodReaderでの使用を目的として開発されています。 GoodReaderはpdfを読む分には申し分ないのですが、 ファイル名以上の論文の管理ができず、別個でpaper等のアプリを用いる必要がありました。 本アプリはこの点を解決し、GoodReader内部で論文を読む作業を閉じさせるために開発されています。

GoodReaderはHTML,Javascriptを読む事ができ、さらにGoodReader管理下のHTMLからは相対パスで pdfにリンクすることが可能です。 この機能を利用してこのアプリは論文の情報を一覧したHTMLのリストを作成し、リンクを埋め込みます。 さらにJavascriptを用いて検索を行なうことが可能です。

このようにHTMLで作成することにより、デスクトップ環境でも同じ様に使用する事が可能です。 (寧ろ現状ではデスクトップ環境の方が便利です)

構成

このアプリはHTMLとJavascriptから成るwebアプリとCGI部分から成ります。 上記の機能、即ち論文の一覧と検索機能を使用する場合はwebアプリ部分だけで十分ですので、 CGIを使用する必要はありません。 CGIは後述するタグ付けの機能を使用する際に必要となります。 ちなみにCGIpythonで書いています。

要件

このアプリを使用するには論文の情報を纏めているbibファイルがあり、 さらにpdfのファイル名がそのbibtexkeyに一致している必要があります。 これはJabRef等で用いられている規則です。 異る命名規則を用いている場合は自力で変換してください。 さらに変換を行うためにpythonが動作するデスクトップが必要です。 現在はLinuxでのみ動作します(Windows上でプログラム書いたことない)。

今回は以上、概略の説明までです。 次回以降でインストールの方法、タグ付けについて紹介します。

unite-bibtex

前回までに作成したunite.vimにおけるbibtexキーの補完機能。 単独で動作するようになりました

GitHub: termoshtt/unite-bibtex

基本Pythonで実装してあります(ファイルは.vimだけど)ので+pythonが必要です。 またbibtexのIOにpybtexを使用しているので別途インストールが必要です。

sudo easy_install pybtex

でインストールできます。 主要ディストリでもパッケージは提供していないマイナーライブラリですが、 easy_installはこういう時便利ですね。 easy_install自体はFedoraではpython-setuptoolsで提供されています。

未だにvundle使ってるので最近のneobundle等に疎く、 プラグインの追加方法は各自お願いします。 unite-buildを参考に作ったので、そんな感じで動く筈(汗

設定はbibファイルの位置を指定するだけで、

let g:unite_bibtex_bib_files=["~/papers/bib/all.bib"]

とすれば使えます。 複数bibファイルがある場合のためにリストにしてあります。

:Unite bibtex

とすれば、

f:id:termoshtt:20130829051355p:plain

の様にuniteに表示され、 <CR>で対応するbibtexkeyがカーソルの位置に挿入されます。