wrongwrongな開発日記

情報系大学院生の忘備録

【Java】Functionを使ってみる

タイトル通り、Java 8で追加されたFunctionが便利だったので書きます。

Functionとは

Function<T,R> は引数Tを受け取って戻り値Rを返す関数を変数っぽく扱えるものです。大体cの関数ポインタとか.Netのdelegateみたいなもんです。
例えば以下の例では、funcintを受け取って処理を行い、intを返します。

Function<Integer, Integer> func = input -> input * 3; //int inputに3を掛けたものが帰る
func.apply(3); //呼び出し例、3 * 3 = 9が帰る

正直うまく書けて無いと思うので、以下の記事を参照してください。。。
www.atmarkit.co.jp

なにがうれしい?

同じxを入力とする一次関数と二次関数があり、それぞれパラメータはある程度一定であるような場合を例に書きます。結論のソースコード全体は一番下に置きます。

素直に書くと

素直に書くと以下のようになります。
変化するのはxだけなのに何度も何度も変数を書いて関数を呼び出して……というのは一々書くのがダサくて面倒くさいです。各関数のパラメータも、何らかのラベル付けをした方がTypoによる事故も起きにくいと思われます。

private static int linearFunction(int a, int b, int x){
    return a * x + b;
}
private static int quadricFunction(int a, int p, int q, int x){
    return a * (x - p) + q;
}
public static void main(String[] args) {
    int x = 2;
    System.out.println(linearFunction(1, 1, x));
    System.out.println(quadricFunction(1, 1, 1, x));
}
Function + EnumMap

これをFunction + EnumMapで書き直すと以下のようになります。
Enumでラベルを付けてマップに登録して呼び出してます。呼び出しがスッキリしたのとかはうれしいです。もうちょっといいやり方が有る気もしますがとりあえず気にしないことにします。

private enum e{
    La1b2,
    Qa1p1q1,
}

private static int linearFunction(int a, int b, int x){
    return a * x + b;
}
private static int quadricFunction(int a, int p, int q, int x){
    return a * (x - p) + q;
}

private static final EnumMap<e, Function<Integer, Integer>> map;
static {
    map = new EnumMap<>(e.class);
    map.put(e.La1b2, x -> linearFunction(1, 2, x));
    map.put(e.Qa1p1q1, x -> quadricFunction(1, 1, 1, x));
}

public static void main(String[] args) {
    System.out.println(map.get(e.La1b2).apply(2));
    System.out.println(map.get(e.Qa1p1q1).apply(2));
}
続きを読む

【日記】はじめての外部発表を終えて

詳細は書きませんが、卒業研究について外部発表をしてきました。今年度は1回以上の外部発表を目標としていましたが、早くも達成できた感じです。

できたこと

発表と発表準備を合わせて、今までの研究での疑問点や改善点が整理されたのは非常に良かったです。これによって今後の研究において取り組むべき内容に関して整理することができました。

発表に関しては、自分の研究内容について「これがあれば助かる!」という旨の感想を直接頂けたことが非常に嬉しかったです。発表への反応を通じて研究の重要性を再認識することができました。

できなかったことと反省

折角自分の作ったものに多大な興味を抱いて頂けたにもかかわらず、発表の完成度が低くなってしまったことが最大の心残りです。とにかく講義とレポートで資料作りと発表練習に時間を取ることができませんでした。

特に大きな反省点は、今回の発表は20+10分でしたが、これに合わせた発表資料作りができなかった点です。これまでの『削る』発表のノリで作業した時間が長すぎ、発表練習でのセリフも忘れ、最終的には発表時間を大きく残して終わってしまいました。

また先行研究についての理解・読解も不足しており、検証済みの内容に関する質問にも「分からない」と返答してしまいました。次はこういったことが無いようにしたいです。

今後に向けて

何にせよ、初めての外部発表は終わってしまいました。今後は整理した研究計画に基づき研究を進めつつ、並行して関連論文の読み込みを進めていこうと思います。研究に関しては現状明確な課題が3点有るので、修士課程を通してこの解決に取り組みます。

勿論結果を出した上での話ですが、次は自分が納得できるだけの発表ができるようにがんばります。少なくとも今年度末には発表に繋げたいですね。

インターンに行きたいこともあって各地のイベントに参加するなどしており、研究に掛けられる時間が十分ではありませんが、できるだけ効率的に進めていくことを目標とします。

【自作PC】COMPUTEX TAIPEI 2018で紹介されたAORUSブランドのDDR4メモリーについて【日記】

GIGABYTEがAORUSブランドでDDR4メモリーを発売するようです。

www.gdm.or.jp

まだ名前も出ていませんが、詳細が出たらまとめ記事に追加しようと思います。

製品の特長

RGB LEDもそうですが、ダミーモジュールが付いてきます。

 メモリスロットが4スロットでも、価格などの都合で2スロットしか埋められずに見栄えが悪くなることは多いので、これはいいかもしれないと思いました。

ヒートシンク

TwitterでAORUSの中の人に測定していただくことができました。

一応スクショを。

f:id:wrongwrongwrongwrong163377:20180606031658p:plain

実測40mmだそうです。RGB LED搭載製品はヒートシンク高が大きい製品が多いため、これも大きな特徴かもしれませんね。

少し残念な点

(ここからは愚痴がメインです)

RGB Fusion以外での制御は想定していないそうです。

マザーボードに比べDDR4メモリーはそうそう買い換えるものではないため、これを変えばGigabyte製品から離れにくくなるというわけですね。

Gigabyteに限った話ではなく、RGB LEDによるライティング界隈では「自社ユーザーを離さないために独自規格を継続しつつ自社ブランド製品を充実させる」戦略が取られており、ユーザーとしては頭が痛いです。NZXTやらCorsairやら周辺機器メーカーもやっているわけで、特にNZXTはマザーボードまで投入してきているわけですが、何せ現状でも規格が乱立している訳で、ここから更に増やすのかと……。

製品そのものはどれも魅力的ですが、とにかく「自分で選んで組み合わせる」のが自作の大きな魅力でもあるわけで、ブランド縛りはあくまで「他社製品も選べるけどこの組み合わせがカッコいい」という程度の緩いものであることが健全なんじゃないかなあと思います。

ということで、規格の統一を切に願います。

その他

そう言えば先日@gigabyte_newsにブロックされていることに気付き、@AORUS_JPさんにメンションを飛ばした所「話し合ってみる」との返信を頂きましたが、今確認した所まだブロックされたままでした。

ブロックされた原因として思い当たる件があんまりにもアレなので早くブロック解除して欲しいというか、ブロックの原因があの件なら@gigabyte_newsの担当さんそのままで大丈夫なんですかねって感情があります。(あ、@AORUS_JPさんにはお世話になりっぱなしで好感情しか無いです)

プリンターで一部日本語が印刷されず出力がおかしくなる時に試してみること

pdfをUSBメモリから印刷すると、途中の日本語が表示されずに画像のような状態で印刷される場合があります。

f:id:wrongwrongwrongwrong163377:20180531160110j:plain

対処法

pdfを圧縮すると問題なく印刷できる場合があります。圧縮はpdf圧縮を行ってくれるwebサービスが幾つかあるので、そちらを利用してみて下さい。

注意点

サービスの設定によっては画像の品質なども劣化します。後述しますが、消えて欲しくないフォント設定まで消えることが考えられるので、圧縮後は一度目を通しておくべきでしょう。

原理

特定できている訳ではなく推測ですが、上手く印刷できない原因はプリンタが印刷できないフォントがpdfに混じっていることだと考えられます。pdf圧縮はフォントの情報を抜くなどの処理が行われるため、印刷できない情報が抜けて印刷できるようになるのだと思われます。

【c++】Suffix ArrayとBWTに関するプログラムを作ってみた【c++17】

最近c++を触る機会ができたり、c++17の機能を使ってみたかったりしたので、課題にかこつけて取り組んでみました。

何を作ったか

Burrows-Wheeler Transform(BWT)とは

d.hatena.ne.jp

プログラム

ソースコード

最新のコードはGitHubを参照してください。ここに載せている分からいくらか改善をしました。
github.com

#include <algorithm> //sort用
#include <execution> //algorithmの並列実行ポリシー
#include <ppl.h> //parallel_for用

#include <iostream>
#include <vector>
#include <string>
#include <tuple>

//単語を入れたらSuffixのベクターを返す
std::vector<std::tuple<int, std::string>>
MakeSuffix(const std::string &str
){
    using namespace std;

    vector<tuple<int, string>> v;
    //parallel_forで並列処理
    concurrency::parallel_for(size_t(0), str.length(), [&str, &v](size_t i){
        v.emplace_back(make_tuple(i, str.substr(i, str.length())));
    });

    return v;
}

//Suffixをソート
void
DictionaryOrderSort(std::vector<std::tuple<int, std::string>> &Suffix
){
    using namespace std;
    sort(execution::par_unseq,
         Suffix.begin(), Suffix.end(),
         [](tuple<int, string> &t1, tuple<int, string> &t2) {
        return (get<1>(t1) <= get<1>(t2)); }
        );
}

//BWT系列を作成
std::tuple<int, std::string>
MakeBWT(const std::string OriginalString,
        const std::vector<std::tuple<int, std::string>> &SuffixArray
){
    using namespace std;

    string s(OriginalString.length(), '0'); //容量固定のstringを配列っぽく使用
    int OriginalPoint;
    concurrency::parallel_for(size_t(0), OriginalString.length(), [&](size_t i){
        if(get<0>(SuffixArray[i]) == 0){
            s[i] = OriginalString[OriginalString.length()-1];
            OriginalPoint = i;
        }
        else s[i] = OriginalString[get<0>(SuffixArray[i])-1];
    });

    return make_tuple(OriginalPoint, s);
}

std::string
ReconstructionFromBWT(const std::tuple<int, std::string> &BWT,
                      const unsigned int limit = INT_MAX // 何文字目まで再生するかの指定
){
    using namespace std;
    //タグ付け
    vector<tuple<char, int>> v;
    string temp = get<1>(BWT);
    for(size_t i = 0; i < temp.length(); i++){
        v.emplace_back(make_tuple(temp[i], i));
    }
    //安定ソートで並べ替え、法則を得る
    stable_sort(execution::par_unseq, v.begin(), v.end());

    //リミットまで復元
    const int lim = max((int)temp.length()-(int)limit-1, 0);
    int val = get<0>(BWT);
    int j;
    for(int i = (int)temp.length() -1; i >= lim; i--){
        temp[i] = get<1>(BWT)[val];
        j = 0;
        while(val != get<1>(v[j])) j++;
        val = j;
    }

    return temp.substr(max(lim, 0), temp.length());
}

int main() {
    using namespace std;

    string str = "internationalization$"; //入力
    vector<tuple<int, string>> v = MakeSuffix(str); //Suffix作成
    cout << "Suffix" << endl;
    for(auto t : v){
        cout << get<0>(t) << "\t:" << get<1>(t) << endl;
    }

    DictionaryOrderSort(v); //ソート
    cout << "\nSuffix Array" << endl;
    for(auto t : v){
        cout << get<0>(t) << "\t:" << get<1>(t) << endl;
    }

    tuple<int, string> BWT = MakeBWT(str, v); //BWT取得
    cout << "\nGet BWT" << endl;
    cout << get<0>(BWT) << "\t:" << get<1>(BWT) << endl;

    cout << "\nDecode" << endl;
    //cout << ReconstructionFromBWT(BWT, 5) << endl; //デコード
    cout << ReconstructionFromBWT(BWT) << endl; //デコード

    return 0;
}

出力

「internationalization」という単語についての出力です。

解説

重要なのは大きく以下の2点です。

  1. Suffix ArrayからBWT系列を求める場合の行末の扱い
  2. BWT系列から文字列を復元する方法
Suffix ArrayからBWT系列を求める場合の行末の扱い

Suffix ArrayからBWTを求める場合、行末を区別しなければソート順が乱れるパターンが有るため、何らかの記号を補っておく必要があります。単語の末尾に「$」を加えているのはそのためです。

BWT系列から文字列を復元する方法

BWT系列からの復元は、原理の説明を飛ばして、BWT系列の各文字に数字でタグを付け、

vector<tuple<char, int>> v;
string temp = get<1>(BWT);
for(size_t i = 0; i < temp.length(); i++){
    v.emplace_back(make_tuple(temp[i], i));
}

BWT文字列を辞書順に安定ソートし、

stable_sort(execution::par_unseq, v.begin(), v.end());

BWTキーから順に『キーと同値のタグを見つける→文字列の先頭にBWT文字列[タグ]を加える→見つけた場所の番号のタグが入っている場所をキーとする』という操作を繰り返していくことで、

int val = get<0>(BWT);
int j;
for(int i = (int)temp.length() -1; i >= lim; i--){
    temp[i] = get<1>(BWT)[val];
    j = 0;
    while(val != get<1>(v[j])) j++;
    val = j;
}

行うことができます。ただし復元は末尾から行われます。

工夫した点

parallel_forを使う

ppl.hparallel_forを使って並列処理でSuffixを作りました。c++ラムダ式を触ってみたかったのですが、これで理解できたかなと思います。
場合によってはalgolithmfor_eachExecutionPolicyを指定する形とした方がppl.hに依存しなくなるので良いかなと思いました。……本音を言うとparallel_forの形が規格として取り込まれてくれるといいなと思います。
参考資料:
parallel_forの書き方:
方法: parallel_for ループを記述する
ラムダ式の書き方:
cpprefjp.github.io

std::sortの並列実行

c++17でalgorithmに並列実行オプションが追加されました。execution::par_unseqがそれです。c++17の機能、これしか使えませんでした……。
stable_sortexecution::par_unseqを指定するとコンパイルできなくて悩んでましたが、今朝アップデートをかけたら普通に動きました。先にアップデート確認しとけばよかったです。
参考資料:
c++17の並列アルゴリズムライブラリ関連:
faithandbrave.hateblo.jp

tupleの独自ソート

参考資料:
minus9d.hatenablog.com

感想

c++17の新機能ってことで畳み込み式とか使ってみたかったんですが、使う場面が思いつかず。強力そうには見え、並列処理や畳み込み式等「使いたい!」って感情が強いですが、実際に使う場面が思い浮かばない辺りが何とも……研究室の他の方のプログラムに導入して改善できそうならやってみたいですね。
並列処理に関してはthreadだのOpenMPだの試してみましたが、algorithm系を除けば結局parallel_forが使いやすいかなと感じました。
一方文字列を長くするとparallel_forでプログラムが不安定になるなど、この辺まだ分かっていない部分も多いです。怪しいのはemplace_backの辺りでしょうか。
後Clionの構文チェックが結構いい加減というか、tupleへのgetなんかにエラーが出て色々とよろしくない感じがあったのがダルかったです。
そもそもc++の書き方を大半忘れていて全然書けなかったのが辛い……。
もっと良いアルゴリズムも有るようですが、力尽きたのでここまで。

【Google ドキュメント】Google ドキュメントで使える等幅フォント

(※6/13 記事を全面的に差し替え)

ドキュメントにプログラムを貼り付ける時に見やすくなるように、Googleドキュメント/スプレッドシート/スライドで使える等幅フォントを探しました。

フォントの追加手順についても書きます。

フォントの選択/追加

以下の順番でやると分かりやすいと思います。

  1. 「フォントの追加」から等幅フォントを探す
  2. 使える等幅フォントの中から良さ気なものを探す
手順

フォント選択画面から「その他のフォント」を選びます。

f:id:wrongwrongwrongwrong163377:20180613150558p:plain

以下のような画面が出るので、「表示」のプルダウンから「等幅」を選びます。等幅以外にも色々なフォントを見ることが出来ます。

f:id:wrongwrongwrongwrong163377:20180613150713p:plain

フォントの使用例

Source Code Pro、Ubuntu Mono、Roboto Monoの3種類のフォントを試してみました。

f:id:wrongwrongwrongwrong163377:20180613152350p:plain

個人的にはUbuntu Monoが良さ気かな?と思ってます。

不満な点

日本語のフォントがもっと欲しいです。貼ったサンプルの通り、日本語は全く等幅では有りません。コメントが綺麗に表示されないのは困るので、もう少しなんとかしてほしいなと思います。

【LaTeX】複数行立ての数式環境で縦にスペースを空ける

別々の式のイコールの位置は揃えたいがalign環境などでそのまま書くと上下の式がくっついて紛らわしく、\vspaceを用いてもスペースを空けることができないという状況に当たりました。
そのまま書くと以下のような出力となります*1

\begin{align}
  a &= b \\
  c &= d
\end{align}

f:id:wrongwrongwrongwrong163377:20180519074153p:plain

解決方法

mathtools.styの\shortintertextを用いることで1行分のスペースを空けることができます。これは本来数式と数式の間にスペースを空けずに式と式の間に文章を挿入しますが、中に何も入れなければ空行が入ります。

% プリアンブル部
\usepackage{mathtools}

% 省略

\begin{align}
  a &= b 
  \shortintertext{}
  c &= d
\end{align}

f:id:wrongwrongwrongwrong163377:20180519074642p:plain

もう少し上下幅を小さくしたかったのですがやり方が分かりませんでした。

補足:mathtools.styの導入

下記のURLからmathtools.tds.zipをダウンロードします。
https://ctan.org/tex-archive/install/macros/latex/contrib
フォルダ内のtex/latex/mathtools/mathtools.styを取り出して.texファイルと同一階層に置き、プリアンブル部に\usepackage{mathtools}と書きます。

*1:サンプル画像は全てbeamer+professionalfontsで表示したものを切り取っています