Juliaでスタック画像を保存する方法


環境
Ubuntu 16.04 LTS
・Julia v1.01

#必要なパッケージのインストール
using Pkg
add.Pkg(FileIO)#画像の入出力に使用
add.Pkg(NRRD)#.nrrdファイルを扱うパッケージ
using FileIO
using NRRD

img1 = rand(255, 255, 100) #3D画像の保存
save("stack.nrrd", img1)

img2 = rand(255, 255, 100, 10) #4D画像の保存
save("hyper_stack.nrrd", img)

tiff形式で保存したかったが、いまいち方法がわからなかったので、nrrdという形式で保存。下記サイトの丸パクリ。
参考サイト
github.com

Atcoder Typical DP contest A問題

今年は少し競プロを頑張りたいので、DPの練習をすることにした。
人に説明すると自分の理解が深まる気がするので方針と実装をダサくても積極的に晒して行きたい。
Typical DP Contest - AtCoder

解法

i個の問題を解いた時、配点の合計がjとなりうる場合は1、どのように解いてもjとならない場合は0を取る関数をdp(i, j)と書くことにする。
定義域は0\leq i\leq N0\leq j \leq \sum_{i} p_{i}
 dp(i, j)を0または1の値に取るようにしたのは、最終的に

\sum_{j}dp(N, j) = N問解いた時の配点の得点の場合の数

として、配点の場合の数を数え上げたいからである。

i個の問題を解いた時、配点の合計がjとなる場合は、
①i-1個の問題を解いた段階で配点の合計がjとなっていて、i番目の問題は解かない
②i-1個の問題を解いた段階で配点の合計が j-p[i]となっていて、i番目の問題(配点はp[i])を解く
の二通りがある。よって解くべき漸化式は以下のようになる。

 dp(i, j) = max(dp(i-1, j), dp(i-1, j-p[i])) (j\geq p[i])
 dp(i, j) = dp(i-1, j) (j < p[i])

すなわち、dp(i-1, j)=1またはdp(i-1, j-p[i])=1が成り立てば、dp(i, j)=1となり、dp(i-1, j)=0かつdp(i-1, j-p[i])=0の時のみ、dp(i, j)=0となるような漸化式を立てた。

初期条件は
dp(0, 0) = 1
dp(1, j) = 0 (1\leq j \leq N)
配点が0の場合も1通りとして数えることに注意する。

実装

あとは上の漸化式を実装する。メモ化再帰でしか書けない脳みそなのでメモ化再帰で書く。
実装言語:Python 3.6.1

N = int(input())
p = list(map(int, input().split()))

sum_p = sum(p)
#prepare memo
memo = [[-1 for _ in range(sum_p+1)] for _ in range(N+1)]

#set initial condition
memo[0][0] = 1
for i in range(1, sum_p+1):
    memo[0][i] = 0

#define dp function
def dp(i, j):
    global memo, p
    if memo[i][j] == -1:
        if j>=p[i-1]:
            memo[i][j] = max(dp(i-1, j), dp(i-1, j-p[i-1]))
        else:
            memo[i][j] = dp(i-1, j)

    return memo[i][j]

#calculate dp
for j in range(sum_p+1):
    dp(N, j)

print(sum(memo[N]))

今更Googleトレンドで遊んでみたら結構面白かった(前編)

とあることをGoogleトレンドで調べてたついでに色々検索したら推理ゲームみたいで結構楽しかったので、自分が調べてみたものの中でいくつか紹介してみることにしました。

Googleトレンドとは?

Googleで検索されたワードの件数の時系列を見れるサイトです。たかが検索件数だけど世の中の流行とかを結構捉えていています。使い方はGoogleで検索するときみたいキーワードを入力するだけです。国別、地域別、期間別と色々フィルターもかけることができます。
trends.google.co.jp

取り敢えず試す

手始めに2017年に流行ったことを調べてみます。僕は将棋が好きなので今年世間を賑わした中学生プロ棋士藤井聡太四段の検索件数を調べてみます。

軸の定義

横軸は時間です。調べたい期間も指定することができます。今回はプロ入りを決定する少し前の2016年8月1日から2017年12月21日までの時系列をプロットしてみました。
縦軸は、その時刻の検索件数みたいなものを表しています。正確な定義としては、表示している全期間内で最大の検索件数で各時刻の検索件数を割った値に100をかけて求めています。つまり、その期間で一番検索された時に比べて、何パーセントの割合の検索件数だったかです。そのため表示されたグラフは0から100の範囲をとります。縦軸の指標の名前は「人気度」らしいので、今後人気度と呼んであげることにします。

グラフを解釈する上での注意点としては、あくまでもプロットした期間内で相対的にみればどのくらいたくさんググられたかということを表していることです。そのため時刻の定義域を変われば縦軸の値も変わります。

解釈してみる

まずこのグラフをぱっと見た時目立つのは、2017/6/11の直後に大きなピークがあることでしょう。特に、人気度が100の時は、2017/6/25~2017/7/1となっています。(マウスカーソルをプロットの線上におけば、その時点の人気度と期間が表示されます。)
この期間の藤井四段に関する特徴的な出来事は、2017/6/26にプロ棋士最多連勝記録である29連勝を達成した対局があったことです。テレビをつければどこかで藤井四段の話をしている、まさに一番注目されていたであろう時期に人気度が最大となっています。
次に僕が、注目したところはその次の点(2017/7/2~2017/7/6)まで高い値をとり続けていたのに、その後大きく人気度の値が下落していることです。2017/7/2~2017/7/6の間に起こったことは、30連勝がかかった佐々木勇気五段との対局です。この天才少年がどこまで勝ち続けるのか注目されつづけていたことが数値としても伺えます。しかし、この対局では佐々木五段が勝ち、藤井四段の連勝は29でストップしました。その後大きく人気度の値が下落しているところに注目すると、世間の熱が冷えたことを定量的に評価できていることがわかります。実際あのあとぱったり報道が減りましたからね。

行事のような定期イベントのトレンド

割と自明な気もするが、流行だけでなく、季節や毎年恒例のイベントとかに関するキーワードは周期的に人気度の値が変化するのがみえました。
具体例として「ケーキ」を過去13年間(2004/1/1~2017/12/21)にわたって検索してみると以下のようになりました。

なんとなく予想がついている人も多いと思いますが、クリスマスの時期になると鋭いピークが現れていることが分かると思います。おそらくクリスマスケーキの注文や店探しが殺到しているのでしょう。
他方、2月にも12月の時ほどではないものの、ピークが現れていることがわかります。2月で甘いものということはおそらくバレンタインだろうということで、より解像度をあげるために2017/2/1~2017/2/28までをプロットしてみました。

すると、2017/2/11~2017/2/14に大きめの値を持つ人気度の山がみえます。
受験の合格祝いとか他の可能性もありえそうですが、多分バレンタインが支配的な気がします。

バレンタインはチョコだと決めつけていましたが、ケーキをプレゼントすることもあるんですね。全然知りませんでした。学びがありました。

ついでに、あと3つ山があります。2/11~2/14の山も含めると、ちょうど1週間ごとに現れていることがわかります。これらの山の曜日を調べて見ると、全て土日であることがわかりました。ケーキは土日に食べるものみたいです。

取り敢えず締め

筆が遅い&文章が長くなりそうなので本題に入る前に力尽きたので、後編として後日おもしろかったキーワードを紹介します。

Google Canlendar APIを使ってみた(python)

Googleカレンダーの予定を取得して寝る時間と起きる時間を通知してくれるみたいなことをやりたいと思ったので手始めとしてGoogle Calendar APIを少し触ってみた。

以下のチュートリアルをやった。

Python Quickstart  |  Google Calendar API  |  Google Developers


 

複数アカウントのカレンダーにアクセスしようと思ったらサンプルコードのget_credential()で作成しているcredential_pathを各アカウント毎に作れば良さそう。

他のアカウントと同期している予定を取得したければmain関数内の

eventsResult = service.events().list(
        calendarId='primary', timeMin=now, maxResults=10, singleEvents=True,
        orderBy='startTime').execute()

の引数にあるcalendarIdを変えれば良い。同期している予定を作ったアカウント名を入れれば良いっぽい。primaryだとアクセスしているアカウント自身が作った予定しか取得できなかった。

calendarIdは

service_list = service.calendarList().list().execute

for item in service_list['items']:

   print('id : ' + 'item['id'] + ' summary' + item['summary'])

といったコードをmain関数内でseviceを定義したあとに入れれば教えてくれる。item['id']はcalendarIdを保持していてitem['summary']はその予定の名前を保持している。

意外と簡単で良かった。

Heroku入門(python)1

今まで作ったものをアプリにして公開してみたいと思ったのでHerokuのアカウント作ってgetting started on Heroku with Pythonしてみた。

インターンで使ったことあるから知っていたという理由だけでHerokuを使うことにした。

 

環境

Ubuntu 16.04.2 LTS

Python 3.6.0

 

基本的には以下のリンクの公式ガイドに従って写経した。

devcenter.heroku.com

取り敢えずPush local changesまで終えた。pipenvがどういうツールかよくわからなかったから調べる必要あり。