« 2020年6月 | トップページ | 2020年8月 »

2020年7月31日 (金)

[R]ベクトルのノルムを求める

norm関数を使う。第1引数は行列を与えなければならないので、matrix関数で行ベクトルか列ベクトルに変換して与える。第2引数に"1"を与えると、L1ノルム、"2"を与えるとL2ノルム(ユークリッドノルム)を返す。第2引数を省略するとL1ノルムを返すことに注意。

> d <- c(-1, 2, 3)
> mx <- matrix(d)
> mx
[,1]
[1,] -1
[2,] 2
[3,] 3
> norm(mx)
[1] 6
> norm(mx, "1")
[1] 6
> norm(mx, "2")
[1] 3.741657

2020年7月30日 (木)

[R]行列の積を求める

%*%演算子を使う。

> d1 <- c(1, 2, 3, 4)
> d2 <- c(5, 6, 7, 8)
> mx1 <- matrix(d1, 2, 2, byrow = TRUE)
> mx2 <- matrix(d2, 2, 2, byrow = TRUE)
> mx1
[,1] [,2]
[1,] 1 2
[2,] 3 4
> mx2
[,1] [,2]
[1,] 5 6
[2,] 7 8
> mx1 %*% mx2
[,1] [,2]
[1,] 19 22
[2,] 43 50

2020年7月29日 (水)

[R]文字列の前後の空白を取り除く

trimws関数を使う。デフォルトでは前後の空白を取り除くが、第2引数に l か r を指定することで、前だけ、後ろだけの空白を取り除くことができる。l と r はそれぞれ left と right の略。デフォルトは前後を取り除く b (both の略)が指定された状態になっている。

> s1 <- " ABC  "
> trimws(s1)
[1] "ABC"
> trimws(s1, "l")
[1] "ABC "
> trimws(s1, "r")
[1] " ABC"
> trimws(s1, "b")
[1] "ABC"
> trimws(s1, "both")
[1] "ABC"

trimwsは内部でsub関数を呼び出しており、内部的にsub関数を使い正規表現を使うことで動作している。その除去をする文字列はデフォルトでは正規表現で [ \t\r\n] と指定している。これは、①空白、②タブ、③復帰、④改行、①~④のすべてということ。

いわゆる全角空白も取り除きたければ、whitespace オプションに全角空白を指定すればよい。以下は、前後の半角空白か全角空白を取り除いた例。whitespace に [  ] (半角空白1つと全角空白1つ)を指定している。文字型ベクトル s2 は「あいう」の前には半角空白が2つ、後ろには全角空白が2つついている。

> s2 <- "  あいう  "
> trimws(s2)
[1] "あいう  "
> trimws(s2, whitespace = "[  ]")
[1] "あいう"
> trimws(s2, "b", whitespace = "[  ]")
[1] "あいう"

当然、ベクトルも扱える。

> s3 <- c(" AB ", " あいう ")
> trimws(s3, whitespace = "[  ]")
[1] "AB" "あいう"

2020年7月28日 (火)

[Visual Basic]コマンドラインでコンパイルする

Windows 10には、標準でVisual Basicのコンパイラーが付属している。64ビット版であれば、以下のフォルダー。

C:\Windows\Microsoft.NET\Framework64\v4.0.30319

コンパイルを試してみる。以下のソースコードをhi.vbとして保存する。

module hi
sub main()
Console.WriteLine("Hi")
end sub
end module

コンパイルする。

>C:\Windows\Microsoft.NET\Framework64\v4.0.30319\vbc.exe hi.vb
Microsoft (R) Visual Basic Compiler version 〇.〇.〇
(以下、表示省略)

動作させてみる。

>hi.exe
Hi

2020年7月20日 (月)

[gfortran]エラーメッセージ「Program received signal SIGSEGV: Segmentation fault - invalid memory reference.」

gfortranの古いバージョンにはバグがあり、ブログラムに間違いがなくても、このエラーメッセージが表示されることがある。

>a.exe
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 ○○
(以下、表示省略)

ソースコードに誤りがなくてもこのメッセージが表示される場合は、gfortranのバージョンを上げてみる。例えば、以下のバージョンだと、このエラーメッセージが表示されることが多いようだ。

>gfortran --version
GNU Fortran (MinGW.org GCC-6.3.0-1) 6.3.0

2020年7月時点の最新バージョンは以下のとおり。

>gfortran --version
GNU Fortran (MinGW.org GCC Build-20200227-1) 9.2.0

このバージョンでは、上記のエラーメッセージが表示されることは少ないはず。

2020年7月12日 (日)

[Python]要素数を指定して空のリストを作る

Noneと乗算演算子 * を組み合わせる。要素数が3ですべての要素が空のリストを作る。

>>> x = [None] * 3
>>> x
[None, None, None]

後から値の代入が容易に行える。

>>> x[1] = 100
>>> x
[None, 100, None]

2020年7月 9日 (木)

[Python]ndarray型の中身を簡単にテキストファイルに出力する

savetxt関数を使う。

>>> import numpy as np
>>> mx = np.array([[1, 2, 3], [4, 5, 6]])
>>> np.savetxt('out.txt', mx, fmt = '%.3f')

出力したファイルout.txtは、以下のように出力されているはず。

1.000 2.000 3.000
4.000 5.000 6.000

2020年7月 4日 (土)

[R]要素にNAかNaNが含まれていないか簡単に確認する

anyNA関数を使う。引数に指定したものに1つでもNAかNaNが含まれているとTRUEを返す。関数名からしてNAだけと思われがちだが、NaNがあってもTRUEを返す。引数に与えるものはベクトルでも行列でもかまわない。

> d <- c(1, 2, 3)
> anyNA(d)
[1] FALSE
> d <- c(1, 2, NA)
> anyNA(d)
[1] TRUE
> d <- c(1, 2, NaN)
> anyNA(d)
[1] TRUE
> mx <- matrix(c(1, 2, 3, 4), 2, 2)
> mx
[,1] [,2]
[1,] 1 3
[2,] 2 4
> anyNA(mx)
[1] FALSE
> mx <- matrix(c(1, 2, 3, NA), 2, 2)
> anyNA(mx)
[1] TRUE

無限大(Inf)は判定の対象にはならないことに注意。

> d <- c(1, 2, Inf)
> anyNA(d)
[1] FALSE

2020年7月 2日 (木)

[Python]2次元配列(リストのリスト)の要素の値が勝手に変わる

2次元配列(リストのリスト)を作るときに、乗算演算子を繰り返し使用して作成するとうまくいかない。以下は、この方法で2行3列の2次元配列を新規に作成して、1行目の2列目に100を代入した例。

>>> x = [[0] * 3] * 2
>>> x
[[0, 0, 0], [0, 0, 0]]
>>> x[0][1] = 100
>>> x
[[0, 100, 0], [0, 100, 0]]

1列目の2列目の要素だけを100にしたはずだが、2行目の2列目の要素も100になっている。

id関数で、1行目と2行目の識別番号を確認する(表示される識別番号は環境などにより異なる)。

>>> id(x[0])
1854005696968
>>> id(x[1])
1854005696968
>>> id(x[0]) == id(x[1])
True

識別番号が同一のため、同じオブジェクトであることがわかる。つまり、この場合は、行同士は互いに参照でしかないことがわかる。

そのため、2次元配列(リストのリスト)を作るときは、乗算演算子を繰り返して使用してはいけない。最初に1次元目を作成して、そのあとに1次元目ごとに2次元目を作成する。

>>> x = [None] * 2
>>> for i in range(2):
... x[i] = [None] * 3
...
>>> x
[[None, None, None], [None, None, None]]
>>> x[0][1] = 100
>>> x
[[None, 100, None], [None, None, None]]

最後に1行目の2列目に100を代入したが、1行目2列目の値だけが変わっており、他の要素はそのままであることが分かる。

リスト内包表記を使うと1行で作成することができる。

>>> x = [[None] * 3 for i in range(2)]
>>> x
[[None, None, None], [None, None, None]]
>>> x[0][1] = 100
>>> x
[[None, 100, None], [None, None, None]]

« 2020年6月 | トップページ | 2020年8月 »

無料ブログはココログ

■■

■■■