27
2017-01 更新 熊本高専 森下功啓 VBA数値計算07

VBAで数値計算 07 ベクトル

Embed Size (px)

Citation preview

2017-01更新 熊本高専森下功啓

VBAで数値計算07

本資料の目次

ベクトルの計算練習問題その他

2

ベクトルの計算3

ベクトルとは

ベクトルとは、大きさと向きを持った量である。例えば速度や磁束などを表現できる。ベクトルはp(𝑥𝑥𝑝𝑝,𝑦𝑦𝑝𝑝)の様に各次元の大きさを持つ。ベクトルの次元数は2以上である。

4

𝑥𝑥

𝑦𝑦p(𝑥𝑥𝑝𝑝,𝑦𝑦𝑝𝑝)

図 2次元ベクトルの例

O

𝑥𝑥

𝑦𝑦

p(𝑥𝑥𝑝𝑝, 𝑦𝑦𝑝𝑝, 𝑧𝑧𝑝𝑝)

図 3次元ベクトルの例

O

𝑧𝑧

図 n次元ベクトルの例

(描けない・・・)𝑥𝑥𝑝𝑝

𝑦𝑦𝑝𝑝𝑧𝑧𝑝𝑝

𝑥𝑥𝑝𝑝

𝑦𝑦𝑝𝑝

*右手系

ベクトルの数学的表記ベクトルの表記方法にはいくつかある。2重線,ボールド体,上矢印などである。2重線は手書きでよく使われる。基本的に小文字である。本資料では、以降は小文字のボールド体を用いる。

5

ベクトルの成分を表記する方法も複数ある。以下に例を示す。ここで、本資料では転置をTとし、カッコには丸括弧を用いる。

𝒂𝒂 �⃗�𝑎𝕔𝕔

図 ベクトルの表記方法

𝒂𝒂 = (𝑎𝑎1 𝑎𝑎2 𝑎𝑎3)T=𝑎𝑎1𝑎𝑎2𝑎𝑎3

=𝑎𝑎1𝑎𝑎2𝑎𝑎3

ノルム(ベクトル長)

ベクトル𝒙𝒙の長さ 𝒙𝒙 は、各次元が直交するならば以下の式で求めることができる。この定義は「𝐿𝐿2ノルム」や「ユークリッドノルム」ともいう。本資料では以降で単にノルムと表記する。ここで、ノルムには複数の定義が存在する。ベクトルの長さとは一般的にユークリッドノルムを指す。

6

𝒙𝒙 𝟐𝟐 = �𝑖𝑖=1

𝑛𝑛

𝑥𝑥𝑖𝑖2

*左辺の添字の2は省略することも有る。

プログラミングにおけるベクトルの表現プログラムにおいて、ベクトルの表現は基本的に配列である。ベクトルを表す型が存在しない場合は配列を用いる。VBAでは、動作速度が気にならないならばArray型を使った方がよい。

7

Dim vector_arr(最大要素番号) As Double ' Double型変数を格納する配列' ↑は初期化も要素の追加も面倒vector_arr2 = Array(1,2,3,43,2,2,4,21,9) ' ←初期化は簡単だだが、追加は面倒

@VBA

ベクトルの合成(足し算・引き算)次元数の同じベクトル同士では、足し算や引き算ができます。

8

𝒂𝒂 − 𝒃𝒃 =𝑎𝑎1 − 𝑏𝑏1𝑎𝑎2 − 𝑏𝑏2𝑎𝑎3 − 𝑏𝑏3

𝒂𝒂 + 𝒃𝒃 =𝑎𝑎1 + 𝑏𝑏1𝑎𝑎2 + 𝑏𝑏2𝑎𝑎3 + 𝑏𝑏3

ベクトルの足し算の実装

ベクトルの足し算を行うVBAの実装例を左に示す。

9

Function vector_plus(vect1, vect2)ans = vect1 ' deep copy

For i = 0 To UBound(ans)ans(i) = vect1(i) + vect2(i)

Next ivector_plus = ans

End Function

@VBA

2つの引数とも、Array型

*実用上はベクトルの要素数が異なるかどうかのチェックを行った方が良い。

ベクトルの引き算の実装

ベクトルの引き算を行うVBAの実装例を左に示す。

10

Function vector_minus(vect1, vect2)ans = vect1 ' deep copy

For i = 0 To UBound(ans)ans(i) = vect1(i) - vect2(i)

Next ivector_minus = ans

End Function

@VBA

2つの引数とも、Array型

ベクトルのスカラー倍

ベクトルにスカラーを掛けることでベクトル長(ベクトルの大きさ)を変化させる事ができます。ここで、スカラー倍しても向きは変わらないことに注意して下さい。

11

𝑐𝑐𝒂𝒂 = 𝑐𝑐𝑎𝑎1𝑎𝑎2𝑎𝑎3

=𝑐𝑐𝑎𝑎1𝑐𝑐𝑎𝑎2𝑐𝑐𝑎𝑎3

スカラー倍の実装

ベクトルに定数を掛ける実装例を左に示す。

12

Function vector_times(vect, coefficient)ans = vect ' deep copy

For i = 0 To UBound(vect)ans(i) = coefficient * vect(i)

Next ivector_times = ans

End Function@VBA

vectはArray型,coefficientは掛ける係数

(スカラー値)

内積

内積とは、各次元の要素同士を掛け合わせてその和を取ったものである。直行したベクトル同士の内積では0が得られる。内積の表記方法にはいくつか流儀が有る。以下に内積の表記と計算方法を示す。

13

𝒂𝒂 � 𝒃𝒃 = 𝒂𝒂,𝒃𝒃 = 𝒃𝒃,𝒂𝒂 = 𝒂𝒂 𝒃𝒃 cos𝜃𝜃 = �𝑖𝑖=1

𝑛𝑛

𝑎𝑎𝑖𝑖𝑏𝑏𝑖𝑖

𝒂𝒂

𝒃𝒃𝜃𝜃

*それぞれのノルムを1に調整した(正規化)後に内積を取ると、ベクトルのある種の相関を取ることができる。

𝒂𝒂 cos𝜃𝜃

内積の実装

ベクトルの内積を行うVBAの実装例を左に示す。

14

Function vector_inner(vect1, vect2)ans = 0For i = 0 To UBound(vect1)

ans = ans + vect1(i) * vect2(i)Next ivector_inner = ans

End Function

@VBA

2つの引数とも、Array型

外積(クロス積)外積(クロス積: vector product)とは、2つのベクトルで張る平方四辺形の面積の大きさを持ち、2つのベクトルに直行した方向に向くベクトルを求める操作である。外積におけるベクトルの次元数は3である。外積の定義式を以下に示す。外積は3Dポリゴンの向きの計算にも使える。

15𝒂𝒂

𝒃𝒃

𝒄𝒄

* 𝒄𝒄は𝒂𝒂と𝒃𝒃の張る平面に直交している。 𝒄𝒄の向きは右ねじ方向。

*「外積」は多義的なので注意**高次元に拡張した概念も有る

𝒂𝒂 × 𝒃𝒃 = −𝒃𝒃 × 𝒂𝒂 = 𝒂𝒂,𝒃𝒃 =𝑎𝑎2𝑏𝑏3 − 𝑎𝑎3𝑏𝑏2𝑎𝑎3𝑏𝑏1 − 𝑎𝑎1𝑏𝑏3𝑎𝑎1𝑏𝑏2 − 𝑎𝑎2𝑏𝑏1

=𝒆𝒆1 𝑎𝑎1 𝑏𝑏1𝒆𝒆2 𝑎𝑎2 𝑏𝑏2𝒆𝒆3 𝑎𝑎3 𝑏𝑏3

* 𝒆𝒆は直行基底ベクトル

外積の実装

16

ベクトルの外積を行うVBAの実装例を左に示す。

Function vector_cross(vect1, vect2)ans = vect1 ' deep copy

ans(0) = vect1(1) * vect2(2) - vect1(2) * vect2(1)ans(1) = vect1(2) * vect2(0) - vect1(0) * vect2(2)ans(2) = vect1(0) * vect2(1) - vect1(1) * vect2(0)vector_cross = ans

End Function@VBA

2つの引数とも、Array型

ノルムの実装

ノルムを内積を使って書き直すと下記のようになる。これを用いて関数を簡略化できる。VBAにおけるノルムの実装例を左に示す。

17

𝒙𝒙 𝟐𝟐 = 𝒙𝒙,𝒙𝒙 = �𝑖𝑖=1

𝑛𝑛

𝑥𝑥𝑖𝑖2

Function vector_norm(vect)v = vector_inner(vect, vect)vector_norm = v ^ 0.5

End Function@VBA

Array型

正規化(ノルムを1にする)

単位ベクトルを求める際や、ベクトル同士を比較する際や、内積で相関を求める際にノルムを1にしたほうが良いことが有る。ノルムを1にするにはベクトルをそのノルムで割れば良い。以下に定義式を示す。

18

𝒏𝒏 =𝒂𝒂𝒂𝒂

正規化の実装

VBAにおけるノルムの正規化の実装例を左に示す。

19

Function vector_normalization(vect)Length = vector_norm(vect)vector_normalization = vector_times(vect, 1 / Length)

End Function

@VBA

Array型

練習問題20

データ

各設問で用いるデータを以下よりダウンロードせよ。

21

https://www.dropbox.com/s/xygbnu1ivwzkow4/city.xlsx?dl=0

問1, 2の設問の背景〜実際のデータでベクトルを語る〜

例えば、都市の人口や面積,マンションの戸数,駅の数,人口,大学キャンパスの数などを調べたとする。それらのデータを並べたものを以下に示す。ここで、行方向に1レコードのデータが格納されている。

22

この様な1レコードのデータもベクトルとみなすことができる。ここで、注意してほしいのが各次元の単位の違いである。レコード間の内積を求めればデータの類似性を抽出できるが、分散の小さな次元は実質的に無視されるためそのままだと類似性の判定能力が低い。レコード間の比較を行うには各次元で正規化(数量に対する正規化)を行う必要がある。

都市名 人口[人] 面積[km2] 戸数 駅の数Kumamoto1 10 20 7 9Kagoshima 11 20 12 5Fukuoka 30 40 30 50 *数値はダミーです。

問1 次元毎の正規化

Sheet1のデータに対し、各次元毎に(各列毎に)正規化し、それを元データの下方に保存するプログラムを実装せよ。ここでの正規化とは、各次元毎にN(0, 1)に調整することを指す。

23

平均0.0, 標準偏差1.0

問2 類似データの抽出

Sheet1を正規化したデータを用いて類似データを抽出したい。元データの4番目に最も似たレコードは元データの何番目か求めよ。ここで、内積の値が最も大きいものを最類似データと定義する。*各レコードのノルムを1に調整した上で内積を計算せよ。

24

問3 ベクトルの積分

Sheet2にとある物体に関する時刻と速度v(x, y)のデータを示す。時刻0を基準として、最終的に到達した座標を求めよ。ここで、d𝒙𝒙 = 𝒗𝒗d𝑡𝑡である。

25

その他26

参考文献

SAK Streets - VB 開発言語資料 http://sak.cool.coocan.jp/w_sak3/doc/sysbrd/sak3vb.htm 基本的にVB6.0の解説だが、VBAにほぼそのまま適用できる。かなり詳しい。

[1]ノルムの意味とL1,L2,L∞ノルム, http://mathtrain.jp/lpnorm

27