8ttyan’s blog

コンピュータ関係の小ネタ

LaTeXでアンダーラインだけ色をつける方法

TeXでアンダーラインを引いて,そのアンダーラインだけ色を変える場合は,全体を一旦ある色にして,文字の部分を再度黒にすれば良い.

\textcolor{BrickRed}{\underline{\textcolor{black}{ほげほげ}}}

もしくはプリアンブルで次のように定義すると良い:

%プリアンブル
\newcommand{\redunderline}[1]{\textcolor{BrickRed}{\underline{\textcolor{black}{#1}}}}   %赤いアンダーライン

%本文
\begin{document}
\redunderline{ほげほげ}
:

f:id:y8ttyan:20160120144637p:plain

数式環境で数式に斜線を引く cancel.sty があるが,これも同様に斜線だけ色をつけることが出来る:

\begin{align}
   \textcolor{BrickRed}{\cancel{\textcolor{black}{abc}}}
\end{align}

もしくは

%プリアンブル
\usepackage{cancel}
\newcommand{\redcancel}[1]{\textcolor{BrickRed}{\cancel{\textcolor{black}{#1}}}} %赤いキャンセル

%本文
\begin{align}
   \redcancel{abc}
\end{align}

f:id:y8ttyan:20160121132318p:plain

datファイルの行列を転置する(行と列の入れ替え)プログラム

スペース or タブ区切りのdatファイルの行と列を転置するプログムラム.

#!/bin/bash
#@(#) Transposing column and row in a text file script (c)8ttyan 2016 http://8ttyan.hatenablog.com/

echo -e "\x1b[7mHello!! This is transposing script.\x1b[0m" >&2

FILENAME=$1
NUMOFFIELDS=$(awk 'NR==1{print NF}' $FILENAME)

for i in `seq 1 $NUMOFFIELDS`
do
  awk '{printf("%s ", $'$i')}' $FILENAME
  echo "" | awk '{printf("\n")}'
done

echo -e "\x1b[7mFinished. Good-Bye!\x1b[0m" >&2

これをメモ帳などにコピペして transpose.sh というファイル名で保存.

初めて使うときは実行権限を付与する:

sudo chmod u+x transpose.sh

使い方(test.datの内容を転置して,test_trans.datに保存)

./transpose.sh test.dat > test_trans.dat

使い方(test.datの内容を転置して画面に表示)

./transpose.sh test.dat

gnuplotでdatファイルから行と列を指定して値を拾う方法

例えば,1行目にタイトル,2行目以降にデータが有るようなファイルがあるとする:

titleOfTest
0.0 0.000000
0.4 0.389418
0.8 0.717356
1.2 0.932039
1.6 0.999574
2.0 0.909297

これをgnuplot

plot "test.dat" u 1:2 with linespoint

とすると,1行目の部分は1列しか無いので無視されて,2〜7行目の部分がプロットされる. データファイルの(1,1)の部分を使いたいときは,以下のようにする.

gyou=1 #行番号を指定
retsu=1 #列番号を指定
filename="test.dat" # ファイル名を指定
elem=system("cat " . filename . " | awk \'NR==" . gyou ."{print $" . retsu . "}\'") # 特定の行列から値を拾う

# ここから通常の処理
set title elem
plot filename u 1:2 with linespoint

また,拾う行列の値が数値の場合,以下の様に4行目を変更して,C言語同様の書式指定(%e,%4f,%d など・・・)ができる.

gyou=2 #行番号を指定
retsu=1 #列番号を指定
filename="test.dat" # ファイル名を指定
elem=system("cat " . filename . " | awk \'NR==" . gyou ."{printf(\"%e\", $" . retsu . ")}\'") # %eの部分を好きに変える

# ここから通常の処理
set title elem
plot filename u 1:2 with linespoint

Mathematicaの有用なコマンド

意外に知らない or 良く使う or 有用だったMathematicaのコマンドを羅列します.

  • Exportなどを使うとき,出力先のフォルダ(作業フォルダ)をノートブックの保存先と同じにする
SetDirectory[NotebookDirectory[]]
  • 変数に代入された値を消去
a=1
b=2
Clear[a];
a=.; (*ピリオドを代入するとクリア*)
  • 非常に小さい数値を0とみなす関数
Chop[1.0*10^-20]

C言語で正確にミリ秒マイクロ秒単位まで計測する方法

C標準ライブラリには多数の時間に関するライブラリがある.
注目すべきはtime.hsys/time.hである.よくあるのはtime.hstruct time_tに1970年1月1日からの秒数を格納し,それを年月日時分秒をメンバ変数として持つ構造体struct tmに変換して得る方法である.
しかし,sys/time.hではさらに上位の(?)構造体timevalが定義されており,メンバ変数としてtime_t型のtv_secとマイクロ秒単位で時刻を格納するsuseconds_t型のtv_usecが定義されている:

/* <time.h>および<sys/time.h>から構造体の定義を抜粋 */

    // timevalは基準年からの秒数とマイクロ秒を格納
    struct timeval {
        time_t      tv_sec;     /* 秒 */
        suseconds_t tv_usec;    /* マイクロ秒 */
    };
    // time_t型は基準年からの秒数
    // time_tのままでは使いにくい.time_tはtm構造体に相互に変換できる
    struct tm {
        int tm_sec;        /* 秒 (0-60) */
        int tm_min;        /* 分 (0-59) */
        int tm_hour;       /* 時間 (0-23) */
        int tm_mday;       /* 月内の日付 (1-31) */
        int tm_mon;        /* 月 (0-11) */
        int tm_year;       /* 年 - 1900 */
        int tm_wday;       /* 曜日 (0-6, 日曜 = 0) */
        int tm_yday;       /* 年内通算日 (0-365, 1 月 1 日 = 0) */
        int tm_isdst;      /* 夏時間 */
    };

これらを用いて現在日時時刻を取得&表示する例

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
// time.hとsys/time.hは別物なので注意!

int main() {

    /* まず,日時・時刻情報を格納するための変数を宣言 */
    struct timeval myTime;    // time_t構造体を定義.1970年1月1日からの秒数を格納するもの
    struct tm *time_st;       // tm構造体を定義.年月日時分秒をメンバ変数に持つ構造体
    const char weekName[7][4] = {   // 曜日は数字としてしか得られないので,文字列として用意
        "Sun",
        "Mon",
        "Tue",
        "Wed",
        "Thu",
        "Fri",
        "Sat"
    };

    /* 時刻取得 */
    gettimeofday(&myTime, NULL);    // 現在時刻を取得してmyTimeに格納.通常のtime_t構造体とsuseconds_tに値が代入される
    time_st = localtime(&myTime.tv_sec);    // time_t構造体を現地時間でのtm構造体に変換

    printf("Date : %d/%02d/%02d(%s) %02d:%02d:%02d.%06d\n",     // 現在時刻
                time_st->tm_year+1900,     // 年
                time_st->tm_mon+1,         // 月
                time_st->tm_mday,          // 日
                weekName[time_st->tm_wday],// 曜日
                time_st->tm_hour,          // 時
                time_st->tm_min,           // 分
                time_st->tm_sec,           // 秒
                myTime.tv_usec            // マイクロ秒
                );

}

これを実行すると

Date : 2015/02/03(Tue) 00:27:10.386185

といった感じで表示される. ちなみに,マイクロ秒単位まで時刻を取得する方法として,

#include <time.h>
(略)
clock_t microSec;
microSec = clock();
printf("%d\n", microSec/CLOCKS_PER_SEC);

などとする方法が見受けられるが,これは間違いである.これはCPU時間なのでCPU稼働率が100%なら正しい時刻を示すが,そうでない場合は時計の時間とは異なる.特にopenmpなどを用いて並列化すると(CPU稼働率が数百パーセントなどとなるので)意味がない.
逆にこれを利用して、簡易的に該当プログラムのCPU占有率を調べることもできる:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

int main() {
    
    struct timeval startTime, endTime;  // 構造体宣言
    clock_t startClock, endClock;       // clock_t型変数宣言
    
    gettimeofday(&startTime, NULL);     // 開始時刻取得
    startClock = clock();               // 開始時刻のcpu時間取得
    
//    (何らかの処理)
    
    gettimeofday(&endTime, NULL);       // 開始時刻取得
    endClock = clock();                 // 開始時刻のcpu時間取得
    
    time_t diffsec = difftime(endTime.tv_sec, startTime.tv_sec);    // 秒数の差分を計算
    suseconds_t diffsub = endTime.tv_usec - startTime.tv_usec;      // マイクロ秒部分の差分を計算
    //以下の処理は不要(15/10/28)
    //if (diffsub < 0) {                                              // マイクロ秒が負になったとき
    //    diffsec -= 1;                                               // 秒部分を繰り下げ
    //    diffsub = 1000000 + diffsub;                                // 1秒との差
    //}
    double realsec = diffsec+diffsub*1e-6;                          // 実時間を計算
    double cpusec = (endClock - startClock)/(double)CLOCKS_PER_SEC; // cpu時間を計算
    
    double percent = 100.0*cpusec/realsec;                          // 使用率を100分率で計算
    printf("CPU使用率%f %%\n", percent);                            // 表示
    
    return 0;
           
}

LaTeXでlabelを自動判別してrefを簡単にする方法

\usepackage{hyperref}して,\ref{hoge}の代わりに\autoref{hoge}を使うと,labelが式なのか,図なのか,sectionなのかなどを自動的に判別して図1(1)式みたいに自動的に図や式といった文字を出力してくれる. ただし,defaultでは日本語に対応していないようなので,プリアンブルに以下のように記述しておくと良い.

\def\equationautorefname~#1\null{\textrm{~(#1)式\;}\null}
\def\figureautorefname~#1\null{ 図~#1\null}
\def\tableautorefname~#1\null{ 表~#1\null}
\def\sectionautorefname~#1\null{第~#1\null}
\def\subsectionautorefname~#1\null{~#1\null}
\def\subsubsectionautorefname~#1\null{~#1\null}
\def\paragraphautorefname~#1\null{第~#1パラグラフ\null}
\def\subparagraphautorefname~#1\null{第~#1小パラグラフ\null}
\def\pageautorefname~#1\null{~#1ページ \null}
\def\appendixautorefname~#1\null{~#1 \null}

アクティブなネットワークインターフェースのIPアドレスを拾う方法

ifアドレスを拾うコマンドとして$ifconfigがあるが,情報が大量に表示されて見にくい.しかも使っていない(アクティブでない)IPアドレスも表示されてしまう. この場合は以下のようにする.

$ ifconfig `ifconfig | pcregrep -M -o '^[^\t:]+:([^\n]|\n\t)*status: active' | egrep -o -m 1 '^[^\t:]+'` | grep 'inet ' | awk '{print $2}'

海外のサイトから引用してきた方法なので,もっと良い方法があるかもしれない.

command line - How to use ifconfig to show active interface only - Unix & Linux Stack Exchange

アクティブなネットワークインターフェースのipアドレスを拾う方法

2015/01/11 11:04

pcregrepコマンドはportsな人は以下でインストールできる.

$ sudo port install pcre