粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

matlabで行列の特定の値を持つ行を検出・置換・削除する

今回はfind関数を主に使っていきたいと思います。

find:特定の条件に一致する部分を調べる

等号条件

例> 行列 A から値が0である箇所を探す。

find(A==0)

この際の出力は1次元の配列になります。m行n列のi行j列目にある場合は,i*n+j として出力されることに注意。

以下のようなコードを書いて位置との対応を掴んでください。

mg = magic(4)
find(mg==1)

なお,後ろにfind(A==0,3)などと数値を列挙すると条件に一致する部分のうち数値の数だけ列挙してくれます。

不等号条件

例> 行列 A から値が10より大きい箇所を探す。

find(A>10)

findを使わない場合の記法との比較

findを使わずとも

A==0

という表記単体で,条件に一致するか否かの論理値を得ることができます。

A = magic(3)

A =

     8     1     6
     3     5     7
     4     9     2

>> A>5

ans =

     1     0     1
     0     0     1
     0     1     0

findではこの論理値行列の代わりに条件を満たす行列のindexをそのまま返します。

>> find(A>5)

ans =

     1
     6
     7
     8

特定の条件に一致する部分を置換

先程調べた箇所を行列に代入することで置換できます。

試しに行列の中で特定の条件を満たす部分を0にしてみましょう。

mg = magic(4)
place = find(mg>10)
mg(place)=0

魔法陣mgのうち,10より大きい成分の位置がplaceに入り,
mgのうちのplaceに該当する部分をまとめて0に置換できています。

これは,次のように縮めて書くことが多いです。

mg = magic(4)
mg(find(mg>10)) = 0

追記:先程述べた表記を活用すればfindを省略しても以下のように書くことも可能です。

mg = magic(4)
mg(mg>10) = 0

特定の条件に一致する部分を削除

同様に特定の値ではなく [] を代入することで該当する箇所を削除可能です。

例>ベクトルAのうち,0に該当する箇所を削除。

A(find(A==0)) = []

あるいは

A(A==0) = []

どうやらmatlabの仕様上では

Memoryブロックを用いてSimulinkで直前のデータを保持する

Memoryブロックを使おうって話です。
前のタイム ステップでの入力を出力 - Simulink - MathWorks 日本

機能と作成例

Memoryブロックは前回の値をHoldして出力します。
また,初期状態をSetすることが出来ます。

要件

初期状態で出力y=0,入力uがある閾値VALを超えた場合,y=1を出力。
前回y=1が出力されているならy=1を維持。

作成例

ORブロックを使って以下のように組みます。
f:id:ossyaritoori:20170505031327p:plain

注意点

データの型に注意(Boolean型なので直前の入力は論理値であるべきSwitchを使うなどしましょう。)

PCの空き容量が急に減った話(Latex暴走事件)

事件概要

シミュレーションを走らせていたらPCの空き容量がいきなり0になりました。
しかも減ったのは200G近く!

なにを言っているか(略)
f:id:ossyaritoori:20170102010912p:plain

これは仕事どころではない。GWを返せ。

犯人は誰だ

慌てて以下のメモリ新弾ツールを導入しました。
「DiskInfo」フォルダー内のファイル占有率を表示 - 窓の杜ライブラリ
頼むぞ。

これで中身を精査すると下の図のようにメモリの使用率をGraphicalに示してくれます。


なんだなんだ!?

辿っていくと…

どう見てもこいつが犯人やろ…
f:id:ossyaritoori:20170503172412p:plain

ちなみに場所は「C:\Users\<ユーザ名>\AppData\Local\Temp」にありました。

見ると
mY9956.log
等を名乗る謎のlogファイルが出力されていました。

よくよく見るとこれはTexのlogファイルではありませんか。ということで速攻消しました。

原因は何なのか。

logは複数ありよく見るとTexファイルのlogのようです。

以下の文から始まります,
This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/W32TeX) (preloaded format=pdflatex 2015.5.19) 3 MAY 2017 01:27
entering extended mode

ちょうど昨日Beamerいじってたあたりです,

元凶のTexファイル

以下のようなTexファイルをコンパイルした結果?こんなログが出ているようです。
ちなみにTemp以下にあるのですが何処から生まれたのかよくわからないです,

なお,これと同じ内容のがたくさんあって正直ブルっちゃいました。
なんなんだ…

\documentclass{article}
\usepackage{filehook}
\usepackage{currfile}
\AtBeginOfEveryFile{\message{^^Jentering file \currfilename ^^J}}
\AtEndOfEveryFile{\message{^^Jleaving file \currfilename ^^J}}
\tracingonline=1
\tracingassigns=1
\usepackage{ajmacros}
\tracingassigns=0
\AtBeginOfEveryFile{}
\AtEndOfEveryFile{}
\begin{document}
\end{document}

そして訪れる平和。

消す際にもずっとpdflatexが該当するファイルをコンパイルし続けていたのでタスクマネージャーからKillして一件落着。

こうしてCドライブに平和が再び訪れたのでした。
f:id:ossyaritoori:20170503174427p:plain

しかし顛末はわからない

platexが延々にファイルをコンパイルしたlogを吐いていたのが原因でした。
Beamerをいじっている時によくわからないプログラムを走らせてしまったのか,
あるいは悪意あるソフトによる攻撃だったのかまだわからないままです。


誰かおしえちくり~~


(完)

追伸

この記事を書きながら問題解決を行っていたため途中文章に乱れがあるかと思います。
「ライブ感」ということで読者の皆様にはお許しいただければと思います。

また,ファイル診断のフリーソフトは結構気に入りました,続投決定です。

MATLABでPDFに余白を付けずに保存Ⅲ(MATLAB)

背景

古来より我々はmatlabの作るPDFのへんてこなことに悩まされ続けてきました。
今までも以下のようなシリーズで様々に悪戦苦闘してきました。

ossyaritoori.hatenablog.com
ossyaritoori.hatenablog.com

他の人のツールを使おう

以下のところからツールを落としてきます。
github.com

使い方 : テンプレ

このツールには主にpubfigとexpfigの2つがあります。
pubfigはfigureを綺麗に整形する機能が,
expfigはfigureを綺麗に出力(保存)する機能があります。

以下その例をば,

%figure定義
hfig=figure(1);
plot(~~);%なんか入れてplotしてね
grid on;
xlabel('frame number');
ylabel('error')
legend('A','B','Location','best')
title('Pyoyon')
pfig = pubfig(hfig);
pfig.LegendLoc = 'best';
pfig.FigDim = [15 11];
expfig('filename','-pdf');

loationをいじるところとか被ってたりするけどとりあえず何も考えなくともキレイな図が出るのが良いですね。

2018年4月追記)最後から二行目のところですが,FigDimという要素が削除されたようなので
pfig.Dimension = [15 11];
と書き換えて実行しましょう。

Figの大きさをいじる。

ソースコードはとても難解でしたがFigDimというクラスでFigureのサイズを司っています。

なおMATLAB公式によるとfigのうちのpositionというハンドルをいじれば変更できます。
https://jp.mathworks.com/help/matlab/ref/figure-properties.html

とりあえずコンパクトなサイズとして以下を使うようにしています,
[横 縦]の順です。

pfig.FigDim = [15 11];

Texでもろもろを綺麗に書くには(小ネタ集)

予め断っておくとこれは宗教です。個人メモです。
あくまでご参考までに。

何番目とかのアレ : nth

\nthというパッケージがあるらしく,
\usepackage{nth}で\nth{2}みたいな感じで書けるのですが…
これは記号には対応していないというポンコツ

そこで,プリアンブルにて,

\newcommand{\ts}{\textsuperscript}

と定義して文中で

$2$ \tf{nd} to $n$\ts{th} 

と書けばこの通り。↓
f:id:ossyaritoori:20170430184742p:plain

これ使いましょう。

転置

転置と言えば
Tや\mathsf{T},\intercal等があるようですが,これは\top一択。

見た目としては\mathsf{T}もなかなかです。(下図左が\mathsf{T},右の転置が\top)
f:id:ossyaritoori:20170430185138p:plain

打ち易さや式におけるスペースの占拠なども考えたらやっぱり\topを使うのが良いでしょう。


他にも何かあれば追加したいです。(追加するとは言ってない)

Git Desktopでpushが出来ない(大きいファイルをpushしてしまった時)

いつもgitを間違えてギットと読んで後輩に指摘されるマンです。

gitあんまり馴染みがなかったのでDesktopアプリを主に使うマンなんですが突然Git Desktopでpush(sync)出来ない事態に襲われました。
メモしながらやったので結果だけ知りたい方は(危険です)解決編をご覧あれ。

最初の原因:重いファイルをcommit,pushした。

shellで

git push

と打つと,「 this exceeds GitHub's file size limit of 100.00 MB 」と出ます。
Gitでは100MB以上のファイルpushできないようです。

gitignoreの変更と反映

gitで不要なファイルを無視する設定を保存するために.gitignoreというファイルがあります。
これに先程の.matファイルを登録したのですがそれでもダメでした。

git rm --cached .
git add .gitignore
git commit -m "add file to .gitignore"
git push origin master

一行目で全てキャッシュを消して,その後にgitignoreを変更,変更をcommitしてpushするという流れのようです。

これでも上手く行きませんでした!

大きいファイルをpushしてしまったときの対処法

先程の変更でもダメです。
何故なら大きいファイルを追加・変更したという情報がgitに残っているのでこいつはいつまでも追加対象から外れてくれないのです。

公式でもこの問題について言及してくれています。
Removing files from a repository's history - User Documentation
結論これではダメでした。


また,以下のブログが非常に参考になりました。
www.walbrix.com
過去の履歴全てから削除するとのこと。
以下のブログでも同様のことを言っています。
Gitリポジトリから容量の大きいファイルを履歴から抹消する | eureka tech blog

$ git filter-branch --force --index-filter  'git rm --cached --ignore-unmatch でかいファイル' --prune-empty --tag-name-filter cat -- --all
$ git commit --amend -CHEAD

これででかいファイルの情報を過去に渡って潰すわけです。

しかし,その後のコミットであえなく爆死。
そして出て来るWarning。

WARNING: Ref 'refs/heads/master' is unchanged
WARNING: Ref 'refs/remotes/origin/master' is unchanged

いろいろ調べましたがこの方向性は結局あきらめました。

git rebaseで過去を改変?

rebaseで過去の関連コミットを全てまとめてしまえばいけるのではと思い立って行動。

git rebase -i HEAD~k

で直近からk番目のcommitをまとめることが出来ます。

これで過去のクソコミットをまとめてしまおうという算段。

すると…以下のエラーが

You must edit all merge conflicts and then
mark them as resolved using git add

調べると手動でconflictをなんとかしろとのこと。憤死。

原因

この前の段階でWeb側で.gitignoreを変更したのが大きな原因らしいです。
無知で動くの本当に良くないですね。

解決編

本当は該当ファイルを撤去して,logを全て飛ばすので十分なんでしょうが,今回はいろいろと込み入ったため,
commitを強制的にふっ飛ばして解決するという手法をとりました。

git rebase -i 十分な分のcommitを遡る

そして,文頭に出てくる幾つかのcommitを削除消します。
これがスムーズに行けば一連の問題はおそらく解決です。

そして強制的にpushするために

git push -f

をします。これも禁じ手の1つで複数人で管理士ているファイルでやっては絶対にいけません。

なお,rebaseでなんか言われたときには

git rebase --skip

でぶっ飛ばしちゃいましょう。


なお,これは本当に最終手段に近いと思ってください。
考えるんだ…まだ手はあるはずだ…

あとバックアップは忘れずに。

総評・感想

とりあえず,
shellときちんと向き合うこと。
Web上のgitを安易に編集しないこと,
事前にきちんとgitignoreを管理すること,
そしてgit外でもデータをバックアップしておくことが肝要です。

まじで!!!

WindowsコマンドラインからPDFをCrop

この手の記事は何度か書きましたが,
コマンドラインからCropするメモを残します。
(大体同じことを3回調べたらもう記事化するつもりでいます。)

大前提:PDFの余白について

matlabやPPTでpdfを作ったり,

texに付属するps2pdf.batを使って

ps2eps.bat hoge.eps hoge.pdf

でepsをpdfにしたりできます。

同様にepstopdf.plを動かすのも良いでしょう。(こちらはバージョンが1.5になる都合で時々困るんですが)

こいつらはとんでもない余白を持っているので,いつだかの記事で余白を切り取る手法を紹介しました。

ossyaritoori.hatenablog.com

bcpdfcrop

有名なpdfcropにpdfcfop.plがあります。
これはperlを入れていることが前提ですが,まとめて処理できてとても良いです。

Perl入れたくない!という方には以下のbcpdfcropやtcpdfcropのbatファイルが用意されています。
GitHub - aminophen/bcpdfcrop: Windows batch file for pdfcrop

githubからbatファイルをpathの通った所において,
とすることでcropしたPDFを作成可能です。

bcpdfcrop.bat hoge.pdf

batファイルの変更

但し,デフォルトではファイル名のうしろに-cropとつくので名前を指定するか
bcpdfcrop.batやbcpdfcrop_multi.batを開いて「-crop」を全て「_c」とかに変更します。(ハイフンをファイル名に使いたくない)

まとめて実行

まとめて実行するには,cropしたいフォルダに移動して

bcpdfcrop.bat *.pdf

とすれば全てのpdfをcropしてくれます。
できれば名前を変えずそのまま更新するには…どうすれば?

名前を変えずに全てのPDFをCropするbatを作成

2018年8月追記:製作者の方からコメントをいただきました。
「元のPDFを上書きしない」との理念があるようで,同じ名前を指定できないようになっているそうです。

コメントの通り,以下の手順を用いるなどの回避策をうちましょう。
(1) bcpdfcrop.bat を使って foo.pdf → foo_c.pdf でクロップする
(2) del foo.pdf で元のファイルを削除
(3) move foo_c.pdf foo.pdf(または ren コマンド)でファイル移動

bcpdfcrop.batに基づいてPDFをそのままの名前で再cropするbatを作成しました。
名前は「bcpdfcrop_all.bat」とします。

@echo off

for "usebackq delims==" %%i IN (`dir/*.pdf`) 
do bcpdfcrop.bat %%i %%i

あれ~なんかおかしい…
あとで考えよう…