TBD

東大理物 五月祭展示 Physics Lab. の歴史

Qiita を見たら Physics Lab. 2024 でアドベントカレンダーをやっている [1]。計算物理班が今もあって、しかし記事を見ると 2017 年を最後に 7 年ぶりなのだそうだ。

各年でどのような班があったのかを掘り出してみるのも一興と思って調べてみることにした。

発表年度 班の数
2007 宇宙物理班、プラズマ班、粉体班、パラメトリックスピーカー班、レーザー班、経済物理班 6
2008 宇宙マイクロ波背景放射超流動超伝導、臨界現象、流体シミュレーション、EPRパラドクス 6
2009 宇宙班、エントロピー班、摩擦班、計算機班、非平衡班、流体班?(マグナス力)、超伝導班?(マイスナー効果) 7
2010 生物物理班、プラズマ班、流体ブラックホール班、一次元電子系班、宇宙班、計算機班、リニアモーター班 7
2011 液体班、粉体班、低次元物性班、宇宙班、メタマテリアル 5
2012 プラズマ班、超伝導班、BEC班、メタマテリアル班、非線形科学班、計算機班 6
2013 物理定数班、スピンカレント班、非平衡相転移班、計算機班 4
2014 宇宙素粒子班、スピントロニクス班、情報熱力学班、計算機班、生物物理班、BEC班 6
2015 テラヘルツ班、加速器班、経済物理班、BEC班、計算機班、電波望遠鏡班、相転移 7
2016 透明マント班、真空ゆらぎ班、BEC班、超伝導班、量子情報班、計算機班、加速器班、物理ショー班 8
2017 低温班、計算機班、シンクロ班、量子測定班、宇宙班、スピン班 6
2018 物理ショー班、相転移班、宇宙班、生物物理班 4
2019 計算物理班、物性班、量子情報班、宇宙班、光学ショー班、生物物理班 6
2020 非平衡班、量子情報班、宇宙班、ゲージ理論班、生物物理班 5
2021 アクティブマター班、物性班、量子物理学班、数理物理学班 4
2022 幾何班、量子物理学班、生物物理班、トポロジカル物性班、宇宙班 5
2023 経済物理班、宇宙班、量子班、生物物理班、数理物理班、統計物理班 6
2024 量子班、統計物理班、宇宙班、数理物理班、計算物理班 5

実は 2010 年以降は理学部のページにスペース (https://event.phys.s.u-tokyo.ac.jp/physlab<発表年度>/) をもらってそこで公開しているみたいなので、わざわざ「掘り出す」必要もなかった。自分が活動したのは Physics Lab. 2008 と 2009 なのだが、この2つの年の発表ページは散逸してしまってもう見つからない (当時は Yahoo! ジオシティーズ・したらば掲示板・FC2などに分散して活動していたはず)。次の年から理学部の公式ページにスペースがもらえてそれが続いているというのはうらやましいことである。

さて、自分たちがメインでやった 2009 年は班の一覧すら Web 上に見つからない。自分が参加していたのが摩擦班・非平衡班・計算機班だった。一方で、宇宙班へのリンクは残っている。エントロピー班の言及もWeb上に残っている。全部で7つあったらしい。残りの2つは、超伝導によるマイスナー効果を実演した班と、野球ボールだかソフトボールによるマグナス効果を実演した(しようと試みた)班があったように思うが、名前は覚えていない。さしずめ超伝導班と流体班としておく。

2006年以前は Physics Lab で検索しても出てこないし、物理学科 五月祭 で検索しても出てこない。自分が参加した2008年の時点で伝統的な行事であるかのような印象を持っていたので、2006年以前は存在しなかったということはあるまい。2007年に初めて Physics Lab. という名前を使ったのか、或いはそれ以前はそもそも Web を活動の場としていなかったということなのかもしれない。

計算機班は実は自分ともう一人の同級生と一緒に初めて作った (因みに、彼はもう偉くなって隣の京大理学部にいる) のだが、その後コンスタントに計算機班が続いているのは嬉しい。ただ、改めて考えてみると計算機班とはネーミングセンスがないなと思う。というか元々「計算機シミュレーション班」と言っていたのだが長くて面倒だということで計算機班に縮まったのだった気がする。一方で、後続が 2017 年までずっと計算機班という名前を踏襲していることを思うと、結構伝統を気にしてはいるのかなと思う。因みに計算機班を初めて作ったとは書いたが、実は 2008 の流体シミュレーション班を引き継いで拡張する形で計算機シミュレーション班としたので、本当に最初に始めたのは一つ上の先輩である。

ところで Google 検索しても 2009 年の計算機班の発表ページが見つからないのは妙だと思ったが、どうもジオシティーズから GitHub Pages に引っ越した時に Google のアンテナから外れたようである。ちゃんとリンクを何処かにおいておかなければならないのでここに置いておく [2]。

各年度のページへのリンクを以下に列挙しておく。

スパコン電力消費

スパコンの維持費についての話があった。スパコンの維持費はほとんど電気代である。富岳は 20 MW から 30 MW 消費する [1] ようで、原発一基の X% 消費するみたいな表現をするのだという。実際に原発の電力を調べてみると 500 MW から 1 GW 程度らしい [2,3] ので 2-3% に過ぎない。そこまでではない。一方でスパコンは基本的には 24 時間 365 日動かすのが普通である。色々な人が断続的に大きなジョブを投げるので、夜は営業しないだとか土日は営業しないだとかいうことはできない。そうすると電気代が物凄いことになる。20 MW だと一時間に 60 万円で一日で 1440 万円である。一年続けると 52 億円かかる。富岳に隣接してガスタービン発電機もあるらしいがそれでは到底賄えないそうだ (緊急用だろうか)。

水力発電は 10 MW から 100 MW まで幅が広い [4]。最近は 1 MW 程度の小水力発電をたくさん作るというのが趨勢らしい。ダム水路式という方式は原発一基に匹敵する 1 GW の出力を持っている [4] が、これらは揚水式発電だそうで、電力を作り出している訳ではないということと長時間持続できるものではないだろうということに注意する。

一方で加速器の消費電力はどの程度だろう。BNL AGS は 70 MW で CERN SPS は 150 MW で J-PARC は 100 MW という資料があった [5,6]。LHC は Web 上で探してみると 120 MW, 180 MW, 200 MW, 230 MW など様々な数値が見つかる [7-9]。RHIC は冷却に 5 MW [13,14]、計算機システムに 4.5 MW [15,16]、20-30 MW という情報 [17] もある。スパコンよりも加速器の方が断然電力を食う。一方で加速器は年がら年中動かしている訳ではない。様々な設定で実験するために毎回止めて整備をするし、そもそも予算の都合で動かす期間を調整している。というか話が逆で、予算が先にあってそれが動かす期間を決める。

東海道新幹線は一編成の理論最大出力は 17 MW (N700) らしい [10]。500系は 18 MW 程度 [11]。つまり富岳は新幹線1編成の最大出力と大体同程度ということになる。しかし実際には常に最大出力で走っている訳ではない。東京大阪間 2時間24分 で 10 MWh 消費するらしい。平均で 4 MW なので新幹線5編成の平均消費電力が富岳と同程度である。JR東海の営業時の電車全体の電力消費は 200-400 MW 程度のようである。新幹線のエネルギー消費はやはり空気抵抗が一番大きいのだろうか。調べると 500 系が最も効率が良かったのだろうか [12] (でもこの記事は怪しい)。

(2023-11-25 追記) 旅客機のエネルギー消費も気になる。文献 [18] によると旅客機は 3000-9000 L/h の灯油を消費する (これが平均なのか最大なのかなどの詳細は不明である)。文献 [19] などによると灯油は 36.7 MJ/L だそうだ。灯油を仮に効率100%で電力に変換できたとすると、30-90 MW と同等の消費ということになる。ジェットエンジンはどうだろう。文献 [20] によると離陸時 431 kN で、巡航時 TSFC = 13.5 g/kNs なので、灯油の密度 800 g/L と合わせて、単純計算で最大 267 MW になる。離陸時の効率は巡航時よりも悪いだろうから、実際はより大きいだろう。GE9X は XWB よりも 5% TSFC が良いが最大出力が 470 kN らしい [21] ので、277 MW になる。

最近は予算削減などで基研のスパコンもいつまで継続できるかわからないという話も聞く (実際はどうか分からない)。Yukawa-21 はどの程度の電力消費だろう。

野良猫とマスク人間たち

先程京大の構内を歩いていたら道の脇――道の端という訳でもなく真ん中という訳でもなくその間ぐらい――にダンボールか何かが横たわっている。気にせずすぐ横を通り過ぎるつもりで歩いていくと、横たわっているのは何だかダンボールじゃなくて…なんだ…猫だ、と思った瞬間に猫もこちらが遠慮なしに近づいていくるのに気づいて、びっくりして背筋を伸ばし立ち上がりかける。僕もびっくりした。猫もびっくりした。お互いにびっくりした。目が一瞬合ったが、微妙に進路の角度を変えて速度は変化させず何事もなかったの如く通り過ぎる。猫はそのまま再び道の真ん中に寝そべった。

猫は人間を大きな猫か何かのように思っているという話がある。嘘か本当かは知らない。目があって鼻があって口があって、だから人間が自分の顔と猫の顔が対応していると思うように、猫も人間の顔を自分の顔に対応付けて理解しているのだろう。人間同士が互いの顔の共通要素を認識するように、猫同士も互いの顔の共通要素を生来の本能で認識している筈で、だとすれば人間と猫の間でも相互に共通要素を認識してしかるべきなのである。

しかし昨今は人間は皆一様に外ではマスクをしている。猫はマスクをしている人間をどのように認識しているのかかなり謎である。野良猫はマスクの下に鼻や口があるとは知るまい。だとすれば、のっぺらぼうか何かがずんずんと歩いているぞといった具合に捉えているのかもしれない。以前からマスクをしている人間は少なからずいたと思うが、最近になって皆マスクになって口や鼻がなくなってしまったことを、野良猫たちがどの様に受け止めているのか気になる。

森と林の境目

駄文。筆遊び。


記憶が定かでないが、学校で習った英語では林は woods と訳し森は forest と訳すことになっていた気がする。しかし、英語の woods は本当に日本語の「林」という概念に完全に一致するのか、または、森と林の区別は woods と forest の区別と同じなのか、と考えると多分違うのだろう。

では森と林を外国の人に説明するなら、それぞれどのように述べることができるか。素朴には森と林の違いは規模の違いの気がする。しかし、その境目をどの程度の規模とするかは人によるのだろう。個人的には民家数軒分の敷地面積ぐらいであれば森とは呼ばない。グラウンドぐらいの大きさになれば、漸く小さな森という感じがする。然し、本当に規模だけの違いなのかと、自身の感覚に問うてみるとそうでもない気がする。森と林はそれぞれ異なる種類の概念であって、規模の違いは概念の違いから副次的に生じる違いなのではないか。

よく分からなくなったので他の人が何と言っているのか調べてみた。分かったことは、さまざまの分野の人が挙って異なる説を主張していて、それぞれにそれらしい理由付けが示されているということである。特に、どの人も独特の自説が確実であるかのように記していて、少々不健康ではないか。一通り様々の異なる説を見た後に、改めてそれぞれの理由付けを見るとそれぞれこじつけに見えてくる。

色々の説を較べて気づく重要なことは、「森」と「林」の対立概念は文脈や使われ方毎に存在するようであるということである。

和語としての成り立ちから迫る考え方がある。森(盛り)と林(生やし)ということから色々想像できる。或るページによると、林は人が木を "生やし" たものだから人の手が入ったものを林というのだそうだ。然し、別のページでは全く逆のことを主張している。林は木を "生やし" たままに放置したものであるから、人の手が入っていないものを林というのだそうである。結局、古代の日本語において "もり" と "はやし" がどのように使い分けられたのかを現代の日本語を用いて憶測しても詮無いことである。更に、古代の使い分けがそのまま現代に生きている訳でもないことにも注意しなければならない。

森や林の字を含む熟語から意味の違いを量ろうという立場も見られる。ここに【シン/リン】の別と【もり/はやし】の別を混ぜた怪しげな議論が多く見られる。【もり/はやし】にそれぞれ【森/林】の字を当てたのは、当時の中国語での【森/林】の概念の違いが【もり/はやし】の概念の違いに近かったからだろうが、さりとて両者が完全に対応する概念だったとは思われない。丁度【forest/woods】が【もり/はやし】に厳密に対応する訳ではないように。所で、日本語の【シン/リン】と現代中国語の【森/林】にも同様に隔たりはあるのだろう。

更に、「熱帯雨林」「針葉樹林」「原生林」のような、地理や林業において使われる術語を参照して「林」の概念に迫る議論も見られるが、これは尚も怪しい。林業が対象とするような木の集合を「林」というのだと結論づけているが、これはおかしい。そもそも地理や林業では「森」ではなく「林」が専ら使われ、そもそも使い分けもないので話題に上る全てが自明に「林」になってしまう。

「林」という語から浮かぶイメージに「林の中の小径」がある。しかしこれは西洋文学の訳によって齎されたイメージではなかろうか。「森」も西洋文学のイメージがある。そう考えると、実は【forest/woods】という概念も現代の日本語には影響を与えているのではないかと思われてくる。

しかし、由来だの理由付けだのといったことを離れて、実際に人の中に生きている「森」と「林」の概念を考えてみると、様々な熟語や用例を見るのは理に適っていると言える。実際に人が「森」「林」という単語や字を使うときに、わざわざ古代の語源を思ったり、それが音読みか訓読みかを意識したり、或いは生活で生じた語か学問的に導入された語かを区別したりはしない。ただただ実際に使われている用例が概念を形作るのである。そして、その概念の境目は歪で容易に言葉で記せるものではないはずである。

この立場から考えると、用例から両者の意味の区別を言葉として抜き出そうとするのは物事を単純化し過ぎである。「森」と「林」の概念は、長い歴史の中で様々な言語・地域・分野で形成され、互いに影響を与え混ざり合いながら発展してきたものであり、そして今も変わり続ける生き物である。結局、外国の人に説明するときには適当に誤魔化して説明するしかない。

フォント Computer Modern Typewriter Text Bold の METAFONT からの生成について

aghtex の \ttfamily 系フォント用に Computer Modern [1] の Typewriter Text 書体一式を METAFONT ソースを弄って生成したことについて。

★折角なので生成したフォントファイル (TTF形式) を aghtex_cmttxx10.zip においた。 フォント名から中身が分かるように以下の様に命名規則を定めた。

aghtex_cmFFBSDD.ttf

但し FF は書体を指定するアルファベット二文字で Typewriter Text の場合は tt ということにする。 B は太さを表し、細字なら l (light) 普通なら m (medium) 太字なら b (bold) 極太なら h (heavy) ということにした。 S は形状を表し、通常なら n (normal) 斜体なら s (slanted) イタリックなら i (italic) Small-caps なら c (caps) ということにした。 DD は整数で印刷する時に想定するポイント数で今回は 10 だけ調整込みで生成した。

★aghtex に組み込んだ。

\begin{tabular}{c||c|c}
\verb+\ttfamily+& 普通 & 太字 \\ \hline \hline
直立 & \ttfamily Hello world! & \ttfamily\bfseries Hello world! \\
斜体 & \ttfamily\slshape Hello world! & \ttfamily\bfseries\slshape Hello world! \\
イタリック & \ttfamily\itshape Hello world! & \ttfamily\bfseries\itshape Hello world! \\
Small-caps & \ttfamily\scshape Hello world! & \ttfamily\bfseries\scshape Hello world!
\end{tabular}

但し、aghtex では Small-caps はフォントではなくて CSS の font-variant-caps を使っている。 ところで実際にブラウザで試すと @font-facefont-style: italicfont-style: oblique のフォントは独立に設定できないようだ… (Chrome, Firefox, IE, Edge, WebKit で確認)。

前調査

段落モードでは1書体につき6字体必要

aghtex でも \ttfamily に対して $\LaTeX 既定の書体 Computer Modern Typewriter Text (cmtt) を使いたい。 記事 [2] でも述べたが $\LaTeX の段落モードでは family x series x shape の組み合わせでフォントを指定する。 新しく \ttfamily に対応するためには、(1 family につき) 2 series x 4 shapes = 8 種類のフォントが必要になる。 small-caps に関しては CSSfont-variant(-caps): small-caps を使うことにしても 2 series x 3 shapes = 6 種類のフォントが必要である。 一つ Regular なフォントを用意したら自動的に他を synthesize してくれたら良いのだが、 Web fonts の synthesize はブラウザによってまちまちなので、やはり自分で用意しなければならない。

Computer Modern Typewriter Text の足りない字体

先に調べた通り AMSFonts に付属している Computer Modern には cmtt (Computer Modern Typewriter Text) の太字版がない [2]。 一方で Computer Modern Unicode (CMU) [3] には太字と太字イタリックや細字斜体などがある。 しかし太字斜体がどこにもない。 自分で作るしかないのかなと考える。一応 FontForge (フォント編集ソフト) [4] に輪郭を太らせる機能があることは知っている。

Computer Modern は METAFONT で定義されている

元々 Computer Modern は METAFONT で書かれた [1] そうだ。 CMU のページによると CMU も METAFONT ソースから生成しているそうなので CMU のソースを確認してみる。 色々調べた結果、恐らく CMU におけるフォント生成手順は以下のようになっている。

CMU におけるフォント生成手順 for Typewriter Text の Bold (Bold Italic)

  1. ectb.mf (ectx.mf): CMU のソースに含まれるファイル。これが Bold (Bold Italic) のアルファベットの METAFONT ソースである。
  2. ectb.pfb (ectx.pfb) 生成: 上のファイルを mftrace に入れて得られる。 mftrace の中では一旦 mf で字形をラスタライズして、その輪郭を autotrace というプログラムでなぞらせて PostScript を生成している。 その PostScript を t1asm などのコマンドを用いて Type 1 (Binary) 形式のフォントファイルに変換する。
  3. cmuntb.sfd (cmuntx.sfd) 生成: 上のファイル + 他の文字 (ギリシャ文字やその他のヨーロッパ文字) を含むファイル ??tb.pfb (??tx.pfb) をくっつけて FontForge ファイルを生成する。
  4. cmuntb.ttf (cmuntx.ttf) 生成: 最終的なフォントファイル。

METAFONT について調べる [5,6]。 昨今一般的なアウトラインフォントではなくストロークフォントの様だ。 つまり、字形の輪郭ではなくて字画の中心線の情報を保持する。 但し、ペンの形状などを指定することができる。 METAFONT はテキスト形式のプログラムになっていて人の手で記述できるようになっているようだ。 "一次連立方程式を解いてくれる" 機能もあって、 CAD みたいに点の関係を与えるだけで方程式を解いて位置を確定してくれる。

CMUectb.mf の中を覗くとパラメータの設定だけして他の mf を呼び出している。

% ectt.mf
%
%%%%中略(パラメータの設定)%%%%
generate exroman %%%%<-他のmfを呼び出している?%%%%

endinput;

AMSFonts に含まれる tt のソースも複数確認してみたが似たような形である。 つまり一連の Computer Modern のフォントは、文字の定義は全て一括で行っていて、 但しパラメータを変えて様々なスタイルの字形を生み出しているということらしい。 つまり、このパラメータを弄るだけで好きな太さ・形状の Computer Modern フォントを生成できるのでは。

METAFONT を生成して ttf に変換する

スクリプトを書いて生成を行った。 生成するだけならば以下のような雰囲気でできる (コマンドはお使いの環境に合わせて適宜解釈して下さい)。

$ sudo dnf install texlive mftrace
$ git clone git@github.com:akinomyoga/aghfonts.git
$ cd aghfonts
$ ./generate_ttfamily.sh

以下はスクリプトの中でやっていること。

1 パラメータを線形補外して *.mf を自動生成する

Computer Modern のソースにはパラメータがたくさんある。 "文字の太さ" みたいな分かりやすいパラメータはなくて、 字体各部分に対応する値を1つ1つ手で調整する。気が遠くなる。

面倒なので手に入るソースに現れるパラメータ値の差分を取って、 線形補間・補外してパラメータを決定することにした。以下のソースを元にする。

  • amsfonts/cm/cmtt*.mf (Typewriter Text Regular),
  • cm-unicode-0.7.0/ectb.mf (Typewriter Text Bold),
  • cm-unicode-0.7.0/ectx.mf (Typewriter Text Bold Italic),
  • amsfonts/cm/cmtcsc10.mf (Typewriter Text Small-caps)

注意点としては ectb.mf 及び ectx.mf に書き込まれているパラメータ値は fontsize 10 の時だけしか調整されていないということ。 他の fontsize の値は Regular な Typewriter Text の時の値と同じになっている。

適当にスクリプトを書いてmfを生成する。 以下のような感じの .mf ファイルを {細字, 通常, 太字, 極太} ✕ {通常, 斜体, イタリック, Small-caps} ✕ {8pt, 9pt, 10pt, 12pt} で 4x4x4 = 64 種類生成した。

% THIS IS UNOFFICIAL COMPUTER MODERN SOURCE FILE cmtt10.mf BY K MURASE.
% IT MUST NOT BE MODIFIED IN ANY WAY UNLESS THE FILE NAME IS CHANGED!

% Computer Modern Typewriter Text for use with 10 point
if unknown cmbase: input cmbase fi

font_identifier:="AGHTEX_CMTTBC"; font_size 10pt#;

u#:=21.0/36pt#;                            % unit width
%%%%%%%%%%%%
%%%%中略%%%%
%%%%%%%%%%%%
 lower.fudge:=0.8;                   % factor applied to weights of heavy characters

%------------------------------------------------------------------------------

generate csc                    % switch to the driver file

2 mftrace*.mf から *.ttf に変換する

CMU に倣って mftrace*.pfb を生成したい。Fedora に mftrace を入れた。

$ sudo dnf install mftrace

mftracegenfonts.sh の真似をして呼び出してみる。 しかし t1asm でエラーになって動かない。t1utils を reinstall しても変わらない。 使い方が悪いのかと思って色々やったが Ubuntumftrace を入れてみると普通に動いた。 結局、t1utils [7] をソースから自分でビルドして入れたら Fedora でも動くようになった。

$ git clone git@github.com:kohler/t1utils.git
$ cd t1utils
$ autoreconf -i
$ ./configure --prefix=$HOME/opt/t1utils
$ make install
$ ln -s ~/opt/t1utils/bin/t1asm ~/bin/

単に mftrace --formats=ttf example.mf としたら mf から ttf ファイルを直接生成してくれた。

3 FontForge スクリプトでメタ情報埋め込み

完成したファイルを見るとフォントのメタ情報が色々欠けているので、 コマンドラインで設定できるツールを探す。 Perl で書かれた FontUtils というのがあるらしいが結局どうやって入れたら良いのか分からなかったのでやめた。 検索すると Windows で使える ttfname3 [9,10] というのがあったようだがソースコードが見つからなかったので Linux では使えない。 あと、XML なので操作を書くのが面倒だ。

結局 FontForge スクリプト [11] で処理することにした。 ついでに自動ヒントなども付加するようにしてみる。

以下は実際にシェルスクリプトFontForge スクリプトを呼び出している部分を抜粋したもの (勿論各シェル変数には適切な値が設定されている)。

fontforge -lang=ff -script <<EOF
Open("$input")
SetFontNames("$key", "$ttffamily", "$ttffull", "$ttfsub", "$copy", "$version")
#CIDSetFontNames("$key", "$ttffamily", "$ttffull", "$ttfsub", "$copy")
SetTTFName(0x409, 0, "$copy")
SetTTFName(0x409, 1, "$ttffamily")
SetTTFName(0x409, 2, "$ttfsub")
SetTTFName(0x409, 3, "$ttfid")
SetTTFName(0x409, 4, "$ttffull")
SetTTFName(0x409, 5, "Version $version")
SetTTFName(0x409, 13, "The SIL Open Font License, Version 1.1.")
SetTTFName(0x409, 14, "http://scripts.sil.org/OFL")
SetOS2Value("Weight", $os2weight)
#SetOS2Value("StyleMap", $os2style)

# Automatical Adjustment
SelectWorthOutputting()
CanonicalContours()
CanonicalStart()
#ClearHints()
#AutoHint()
#AutoInstr() #自動ヒンティング命令を出力すると表示が変なのでoff

Generate("$output", "ttf", 0x200, -1)
EOF

FontForge の関数一覧はページ [12] にある。SetTTFName で設定する値についてはページ [13] を参照した。 FontForge による自動ヒンティング命令を出力するとレンダリング結果がおかしいので、ヒンティング命令は出力しないことにした。

結果

以下は自分のディスプレイ用の ClearType の画像なので、他のディスプレイだと色がついたり滲んだり掠れたりして見えるかもしれない。

通常 (上から Light, Medium, Bold, Black)

f:id:akinomyoga:20191212015921p:plain
aghtex Computer Modern Typewriter Text Regular
斜体 (上から Light, Medium, Bold, Black)
f:id:akinomyoga:20191212020030p:plain
aghtex Computer Modern Typewriter Text Oblique
イタリック (上から Light, Medium, Bold, Black)
f:id:akinomyoga:20191212020058p:plain
aghtex Computer Modern Typewriter Text Italic
Small-caps (上から Light, Medium, Bold, Black)
f:id:akinomyoga:20191212020120p:plain
aghtex Computer Modern Typewriter Text Small-caps

最後に

普段なら適当に調べるだけ調べて「将来的なメンテナンスのコストと見返り」などなど考えて諦めるところだが、記事 [1] にしてしまったので中途半端は駄目な気がしてフォント作成までしてしまった。書いて思うのはフォント作成よりも記事執筆の方が時間がかかる。しかし、アウトプットは大切な気がする。時間を無駄にした気もするし、しかしこういった時間の使い方も大切にしなければならないとも思う。

アウトプットには時間がかかる。成果を上げることを考えていると、すぐに簡単にアウトプットできないくらいに成果が溜まってしまう。そう考えると研究も本当は一日でできる程度の内容に留めて、一日の研究成果を時間をかけて論文にする、というぐらいがバランスが良いのかもしれない。

C++: private メンバにアクセス - テンプレート明示的実体化の時に private メンバのポインタが取れる

C++ Advent Calendar を見たら private メンバにアクセスする記事が2日連続している [1,2]。 記事 [1] は自前のライブラリを使っていて説明は別記事で行っている [3]。 記事 [3] では2つの方法について言及していて、friend によるものと明示的テンプレート実体化によるものだそうだ。しかし具体的な説明は更に別の記事を参照している。 記事 [2] は本気なのかネタなのか #define private public である (使い古されたネタなのである)。

明示的実体化による方法が具体的にどういうものなのか気になったので調べてみた。 序でなので別の方法についてもまとめる。

テンプレートの明示的実体化を使う手法

しかし記事 [3] で紹介されているリンク [4] を見ると「非公開に設定されています」となって見られない (追記: Wayback Machineアーカイブが残っていた)。検索すると英語の記事が見つかった [5]。

コードを読んでみると「テンプレートの明示的実体化のテンプレート実引数で private メンバポインタが取得できる」[10] ということを利用しているようだ。知らなかった。

自分でやってみる

元の記事 [5] のコードはもっと単純化できそうなので自分でやってみる。 取り敢えずターゲットは以下のクラスのデータメンバ A::a

class A { int a = 12345; }

こんな感じにしたらアクセスできる (wandbox):

int A::*memptr;
template<int A::*mp> struct Initializer { inline static auto dummy = memptr = mp; };
template struct Initializer<&A::a>;

int main() {
  A obj;
  std::cout << obj.*memptr << std::endl;
}

使いやすいようにまとめてみる

毎回記述するのは面倒なのでまとめる (wandbox):

// 準備
namespace TBD {
  template<typename MemPtr, typename Tag>
  struct accessor {
    inline static MemPtr ptr;
    template<MemPtr mp> struct init { inline static auto dummy = ptr = mp; };
  };
}

// 使う時
using A_a = TBD::accessor<int A::*, struct tag_a>;
template struct A_a::init<&A::a>;
int main() {
  A obj;
  std::cout << obj.*A_a::ptr << std::endl;
}

マクロにしてしまった方が楽かもしれない

余り使いたくないけれども、マクロの方がすっきりするかも (wandbox):

// 準備
#define TBDDeclareMemberPointer(MemPtr, Name, Member) \
  using TBDAccessType_##Name = MemPtr; \
  static TBDAccessType_##Name Name; \
  template<TBDAccessType_##Name value> struct TBDAccessFiller_##Name { inline static auto dummy = Name = value; }; \
  template struct TBDAccessFiller_##Name<&Member>;

// 使う時
TBDDeclareMemberPointer(int A::*, memptr, A::a);
int main() {
  A obj;
  std::cout << obj.*memptr << std::endl;
}

この方法だと依存クラスに対する処理を書けない (明示的実体化を依存文脈に書けない為)。 しかし、テストが目的だとすれば結局全て明示的に書くことになる気がするので余り気にならないのだろう。 いざ必要になれば我慢して使う。

他の手法

序でに、他にどのような方法があったかまとめ。

1 #define private public

これは冗談の域を出ない。色々な悪いことが起こりそうなのは想像に難くない。そもそも、

class A { int a; }

のような定義の private メンバに関しては効果がない。 だからと言って #define class struct も追加すると今度は

template<class T> void f() {}

の様な記述をしていた時にコンパイルできなくなる。

更に記事 [6] に

さらに予約語を#defineするのは非合法でもある。

と書かれている。例によってリンク先 [7] が非公開に設定されているが、検索すると規格の [macro.names]/2 に記述がある様だ。

2 friend を設定する ○

これが一番自然な方法だろう。但し、これは対象本体に手を入れなければならない。

本体を弄れない時にどうするか。 記事 [6] で紹介している Exceptional C++ Style 15章 では、 自分で偽物のヘッダを作って"偽装" しているそうだ。 でもそれだと匿名名前空間で定義されているクラスなどに対して使えない。更に ODR 違反である。

3 同じレイアウトのクラス型に reinterpret_cast する ✕

これも Exceptional C++ Style 15章 にあるそうだ [6]。 然し、これは標準レイアウトクラスでなければ動作を保証できない。一般には未定義の動作である。

4 テンプレート特殊化を利用する △

これも Exceptional C++ Style 15章 から [6]。 対象クラスに関数テンプレートメンバがあれば、その関数テンプレートの特殊化を作成してその中でメンバにアクセスすることができる。 しかし、関数テンプレートメンバがなければ使えない手法である。単純なクラスの場合大抵は関数テンプレートメンバはない。

Computer Modern (AMSFonts) のファイル名と中身の対応表

$\LaTeX で使われている Computer Modern (AMSFonts) のファイル名を見ても中身が分からない。開いて確かめた結果を記録する。

1 Introduction

動機: \tt (Computer Modern 等幅) の太字や斜体はあるのだろうか?

aghtex は数式モードでは $\LaTeX の既定のフォントである Computer Modern を主に使っている。特に TeX 環境に付属している AMSFonts (SIL Open Font License) [1] に含まれているものを Type 1 から Web fonts の形式に変換している。一方で、段落モードでは Computer Modern は使わずに OS のフォントを使う様にしている。

しかしやはり、段落モードでも特に \tt については Computer Modern を使いたい気がする。しかし問題は Web fonts だと (Firefox でしか) font-synthesis が有効にならないこと *1。つまり、font-weight や font-style を指定しても太字や斜体にならない。これに対応する為には太字版や斜体版の Web fonts を一つ一つ用意しなければならない。そもそも Computer Modern (AMSFonts) に \tt の太字版や斜体版はあるのだろうか。

Computer Modern (AMSFonts) のファイル名は謎

Computer Modern を確認する。 Computer Modern (AMSFonts) の実体は /usr/share/texmf/fonts/type1/public/amsfonts/cm 的な場所にある。ファイル名は

cm(略号)(数字).pfb

の形式をしている。(数字)の部分はそのフォントのポイント数、つまり、どのポイント数で印刷されることを想定しているかである (Computer Modern では印刷する時の大きさに合わせて文字のバランスを微妙に変えている)。 一方で (略号) はそれぞれ何を意味しているのかすぐには分からない。 検索しても説明は見つからない。開いてみないと分からない。 結局 \tt の太字版があるかどうか全て開いて確認する羽目になった。 二度と全部開いて確かめるということはしたくないのでここにまとめておく。

因みに cmextrcm-super もファイル名だけ眺めてみたが、どれも cm にあったのと同じの気がしたので中は確認しなかった。

$\LaTeX のフォントの分類

$\LaTeX の段落モードのフォントは family と series と shape の組み合わせで指定する。

  • family には既定で \rmfamily (セリフ rm = roman), \sffamily (サンセリフ sf = sans-serif), \ttfamily (等幅 tt = typewriter text) がある。
  • series には \bfseries (太字 bf = boldface), \mdseries (普通 medium) がある。
  • shape には \upshape (直立体 up = upright), \slshape (斜体 sl = slanted), \itshape (イタリック it = italic), \scshape (small-caps) がある。

論理上は 3 x 2 x 4 = 24 の組み合わせがあることになるが、実際には全てに異なる字体が用意されている訳ではない。 何れにしても、この 3 x 2 x 4 に従って Computer Modern のファイルたちを並べてみたい。

ところで、書いていて「そういえば tt って何で tt なんだろう」と思ったけど、たぶん teletype のことの気がする。と思っていたら typewriter text っぽい。

2 対応表

どうも文章を書くと無駄な事を書き始めて良くない。完全に蛇足である。動機とか背景とか重要性とかを説明したくなる。というかですね、そもそも見た目が論文みたいである。今気づいたけれど、引用を [番号] にして下部にリスト表記したくなるのもそれだ。

2.1 rm 系のフォント

通常 太字
直立 cmr, cmex cmb, cmbx
斜体 cmsl cmxsl
イタリック cmmi, cmti cmmib, cmxti
Small-caps cmcsc N/A
  • イタリックで cmmi は数式用で cmti がテキスト用であろう。数式用の方が微妙に幅に余裕を持って設計されている。また数式用ではアルファベットのにがイタリックであるが、テキスト様では数字や記号も含めてイタリックになっている。
  • 他に cmdunh という縦長の字形の入ったフォントファイルがあった。
  • また、cmu は字形はイタリックだが直立したものである。

2.2 tt 系のフォント

tt 系のフォントには太字は用意されていない様子である。

通常 太字
直立 cmtt, cmtex N/A
斜体 cmsltt N/A
イタリック cmitt N/A
Small-caps cmtcsc N/A

他に cmvtt というファイルがあって開いてみると横長の tt に見える。v という名前から推測するに縦書き用だろうか?

2.3 sf 系のフォント

sf 系のフォントは余り用意されていない。

通常 太字 極太
直立 cmss cmssdc cmssbx
斜体 cmssi N/A N/A
イタリック N/A N/A N/A
Small-caps N/A N/A N/A

他に cmssq 及び cmssqi というのがあって、これらはそれぞれ cmss 及び cmssi の丸ゴシック的変種に見える。

2.4 cmf?

cmf? という系列があった。微妙に手書きっぽいが serif っぽくもある変な字体である。

通常 太字
直立 cmff cmfib
斜体 cmfi N/A

2.5 mathcal

cmsy 及び cmbsy (太字) は mathcal 及びその太字である。

通常 太字
直立 cmsy cmbsy

3 最後に

結論: \tt の太字はない。斜体やイタリックはある。

フォントファイルを開いて中を確認しただけでそれっぽい記事が出来上がって自分でも驚いている。 研究もこんな感じに文章を書くだけでできたらいいんだけれど。研究はファイルを開くのとは違って簡単じゃない。

余談: Variable フォント

この記事のために調べていたら variable フォントというものがあるらしい。凄い。style や weight 毎に何個ものフォントファイルがあるのは不毛だと思っていたが、parametrized されたフォントの仕様があるのだ。macOSWindowsfreetype も既に対応しているらしい?

余談: Computer Modern Unicode

以下のページから Computer Modern の Typewriter Text の Bold や Bold Italic がダウンロードできる。 しかしライセンス的にどうだろう。"Free for commercial use" と書いてあるけれど本当だろうか。このサイト自体が怪しい。

追記: 以上でダウンロードできるのは cm-unicode (Computer Modern Unicode; CMU) というプロジェクト [6] のファイルの様だ。 正式リリース 0.6.3 のライセンスは X11 License で、開発版 0.7.0 (2009年を最後に止まっている) のライセンスは SIL Open Font License (OFL) だそうだ。 開発版は SourceForge のサイト [7] からダウンロードできる。

*1:最近確かめていないので、もしかすると最近は他のブラウザもできるようになっているかもしれない。