2007-12-31

Count Down

セブンイレブンのレジで。一言も話さず黙々と商品を差し出してお金を払っていたら、
店員:日本人ですか
私 :はい
店員:中国語聞き取れますか
私 :少し
店員:中国語話せますか
私 :少し(さっきからあんたと中国語で話しているだろう!と突っ込みたかったのですが、ツッコミ入れるほど話せない)
店員:仕事ですか、勉強ですか?(と聞かれたのですが「勉強」の部分が分からずに戸惑っていると)
店員:「仕事」は分かりますか
私 :はい
店員:「勉強」は分かりますか
私 :分かりません
店員:「Study」
ここで「分かった」というつもりで「はい」と答えたら「勉強のために来ている」と勘違いされて
店員:加油、頑張って
私 :ありがとう
店員:ガンバレ、ガンバッテー(←日本語)
私 :ありがとう、ありがとう
店員:謝々、再見
私 :謝々、byebye
店員:新年快楽
私 :新年快楽

夜は散歩、食べ歩き。一眠りして台北101のカウントダウン花火を見に。

2007-12-30

台北101

台北101の5階にあるイギリス喫茶店でまったりとお茶を飲みました。。 フェラーリとマセラッティの展示がありました。
10時頃バスで帰ろうと思ってバス停へ行くと、約15分間隔で10時半までと書かれています。 ところが10時半まで30分待ってもバスが来ません。諦めてタクシーで帰りました。寒かったです。
多分その路線の運行時刻、つまり終点につく時間が夜10時半だったのでしょう。

2007-12-29

カラオケ

髪を切って、夜はカラオケへ。 台湾のカラオケは、曲が、まず総文字数順に並んでいて、同じ文字数の曲は最初の文字の画数順に並んでいました。

2007-12-28

美麗華

台北の美麗華というショッピングモールへ行きました。
ここの観覧車からの眺めは良かったです。写真は後で。

2007-12-27

ショッピングセンター

写真は後で。
桃園市内でCDを探して、それから大潤発というショッピングセンターで食料品その他大量に買い込みました。

2007-12-26

台湾へ出発

写真は後で。
関西空港へはリムジンバスで行きました。年末で道路が混んでいたので神戸まで途中でバイパスに入ることなくずっと高速道路でした。
通常は加古川付近はバイパスを通ります。高速料金節約と、道路状況によって所要時間が大きく変動しないように、混んでいるときに高速道路を使った場合の所要時間を元に時刻表を決めて、混んでいないときは高速道路を通らないのでしょう。

桃園空港へ着いてから、旅行の最後の頃、香港から台湾への便の時刻を変更しました。一日に沢山の便があるのですが何故か楽天で予約すると最終便しか取れなかったのです。現地変更可のチケットなので変更しました。

バスで桃園市内へ行ってから、来福星で飲茶を食べました。

2007-12-25

行列の積

  1. 前回の解答

    Sub 行列の和()
    Dim x() As Single, y() As Single, z() As Single, i As Integer, j As Integer, gyou1 As Integer, retu1 As Integer, gyou2 As Integer, retu2 As Integer

    Sheets(1).Select
    i = 1
    Do While Cells(i, 1) <> "" And IsNumeric(Cells(i, 1))
     i = i + 1
    Loop
    gyou1 = i - 1

    i = 1
    Do While Cells(1, i) <> "" And IsNumeric(Cells(1, i))
     i = i + 1
    Loop
    retu1 = i - 1

    Sheets(2).Select
    i = 1
    Do While Cells(i, 1) <> "" And IsNumeric(Cells(i, 1))
     i = i + 1
    Loop
    gyou2 = i - 1

    i = 1
    Do While Cells(1, i) <> "" And IsNumeric(Cells(1, i))
     i = i + 1
    Loop
    retu2 = i - 1

    If gyou1 = gyou2 And retu1 = retu2 Then
     ReDim x(gyou1, retu1)
     ReDim y(gyou1, retu1)
     ReDim z(gyou1, retu1)

     Sheets(1).Select
     For i = 1 To gyou1
      For j = 1 To retu1
       x(i, j) = Cells(i, j)
      Next j
     Next i

     Sheets(2).Select
     For i = 1 To gyou1
      For j = 1 To retu1
       y(i, j) = Cells(i, j)
      Next j
     Next i

     For i = 1 To gyou1
      For j = 1 To retu1
       z(i, j) = x(i, j) + y(i, j)
      Next j
     Next i

     Sheets(3).Select
     For i = 1 To gyou1
      For j = 1 To retu1
       Cells(i, j) = z(i, j)
      Next j
     Next i
    Else
     Sheets(3).Select
     Msgbox ("行列の型が異なるので足し算できません")
    End If

    End Sub

  2. 行列の積

    以前載せた練習問題

    をまだ考えていない人は、プログラミングの前にまずこの問題をノートで考えてください。

    今回は、行列の掛け算のプログラムを考えます。
    まず、2行2列の行列の掛け算から計算しましょう。
    =
    の掛け算をすると、


    となります。これをプログラムで書くと、

    c(1,1)=a(1,1)*b(1,1)+a(1,2)*b(2,1)
    c(1,2)=a(1,1)*b(1,2)+a(1,2)*b(2,2)
    c(2,1)=a(2,1)*b(1,1)+a(2,2)*b(2,1)
    c(2,2)=a(2,1)*b(1,2)+a(2,2)*b(2,2)

    となります。

  3. 練習問題1
    次の行列の掛け算をするプログラムを書きなさい。

  4. このままではもっと大きな行列の計算ができないので、For文を使って書き直します。
    まず、Cの成分ごとに4行に分けて書いている部分を
    For i=1 to 2
        For j=1 to 2
            c(i,j)=a(i,1)*b(1,j)+a(i,2)*b(2,j)
        Next j
    Next i
    
    のようにFor文による繰り返しで書きます。さらに、c(i,j)=a(i,1)*b(1,j)+a(i,2)*b(2,j)の部分もFor文による繰り返しを使って
    For i=1 to 2
      For j=1 to 2
        c(i,j)=0
        For k=1 to 2
          c(i,j)=c(i,j)+a(i,k)*b(k,j)
        Next k
       Next j
    Next i
    
    のように書きます。

  5. 練習問題2
    2行2列に限らず,行列の型を数えて、掛け算できる時には掛け算をし,掛け算できないときは出来ないと表示するプログラムを書きなさい。

2007-12-21

第二章, 第三章

レポート問題

風邪で欠席した人へ:次のレポート課題を提出してください。
正しいさいころを1回投げて、出た目が
  • 偶数ならばX=0, 奇数ならばX=1
  • 1, 2, 3ならばY=0, 4, 5, 6ならばY=1
とします。このとき確率変数XとYは独立ですか?理由を述べなさい。

確率関数、分布関数の値の求め方

二項分布B(n,p)の確率関数P(X=x)はエクセルの関数BINOMDIST(x,n,p,0)で求めることが出来ます。
一方分布関数P(X≦x)はBINOMDIST(x,n,p,1)で求めることが出来ます。

練習:正しいコインを10回投げたときに、5回表が出る確率を求めてください。また6回以上表が出る確率を求めてください。

しかし、BINOMDISTでは10,000回投げたときに5,000回以上表が出る確率を求めることは出来ませんので、こんなときは正規分布で近似します。
正規分布N(μ,σ2)の密度関数f(x)はエクセルの関数NORMDIST(x,μ,σ,0)で求めることが出来ます。
分布関数P(X≦x)はNORMDIST(x,μ,σ,1)で求めることが出来ます。

練習:Xの確率分布が標準正規分布の時、P(X≦1)を求めなさい。

次に、二項分布B(n,p)でnが大きいときの正規分布による近似が正しいかどうか確かめるために、まずBINOMDISTも使えるn=100で確かめてみましょう。
正しいコインを100回投げたときに表が出た回数をXとします。
P(X≦50)とP(X≦55)をBINOMDISTを用いて求めなさい。
Xの分布を正規分布で近似する時の、μとσ2の値を求めなさい(これは教科書やノートを見てください)
P(X≦50)とP(X≦55)を正規分布による近似で求めなさい。
もっと近似精度を良くする方法がありますので、講義中に紹介します。

二項分布

確率関数、分布関数、期待値、分散を求めましょう。また(分布関数を求めてしまえば必要ないのですが)正規分布で近似してみましょう。 まず、分布のパラメータを入力します。

xの欄に0から10まで入力します。一つずつ入れていると大変なので、 まずA6に0を入れた後は自動で埋めましょう。0を入れたセルをクリックして 編集→フィル→連続データの作成を選びます。

列方向に1つずつ10まで増やします。

するとこのようになります。

次に確率関数を入力します。確率関数の式に従ってx=0に対しては
=COMBIN(B$2,A6)*B$3^A6*(1-B$3)^(B$2-A6)
と入力します。

それをB16セルまでコピーして、確率関数の完成です。

次に分布関数を入力します。 x=0に対しては=SUM(B$6:B6)と入力します。

それをC16セルまでコピーします。

次に期待値μ=Σxp(x)を求めます。まずx=0に対して=a6*b6と入力します。

それをD16セルまでコピーします。

それらを合計したものが期待値です。実は期待値はnpとして求めることが出来ます。

次に分散σ^2=Σ(x-μ)^2p(x)を求めます。まずx=0に対して=(a6-d$18)^2*b6と入力します。

それをE16セルまでコピーします。

それらを合計したものが分散です。実は分散はnp(1-p)として求めることが出来ます。

さて、n=10の場合はこのように確率関数、分布関数を計算することが出来ましたが、 nが大きくなると確率関数を計算することが出来なくなります。 よって正規分布N(μ,σ^2)の分布関数で近似します。 B(n,p)の場合、期待値μ=np、分散σ^2=np(1-p)なのでN(np,np(1-p))で近似します。 Excelには正規分布の分布関数を求める関数NORMDISTが用意されています。 まずx=0に対して
=NORMDIST(a6,d$18,sqrt(e$18),true)と入力します。3番目の引数には分散ではなく その平方根である標準偏差を代入します。

それをF16セルまでコピーします。

さて近似してみましたが、C列とF列を見比べてみると値はかなり異なっています。 nが大きくなければ正規分布に近くないのも理由の一つですが、一番の理由は 二項分布の確率関数と正規分布の密度関数のグラフを重ねて、面積を比較するとき、 二項分布の確率関数は幅が±0.5あったことを無視しているからです。よってその分補正します。 まずx=0に対して
=NORMDIST(a6+0.5,d$18,sqrt(e$18),true)と入力します。つまり幅の分0.5増やしています。

それをG16セルまでコピーします。

如何ですか。小数点以下2桁までは合いました。まだ近似としては不十分ですが、 そもそもn=10ならば直接確率関数を計算した方が話は早いです。 ここまで出来た人は、このSheet1をSheet2へコピーして、n=100の場合について 同じ計算をして見ましょう。これよりnが大きくなると、確率関数が計算出来なくなったり、 出来たとしても確率関数を足すときの誤差が大きくなってしまいます。

以上が終わった人は、確率分布を擬似乱数を用いたシミュレーションで調べましょう。

一様乱数

1.新しくブックを開いてください。
2.A1セルに[0,1]の一様乱数を作ります。先ほどと同じ手順で関数の挿入を行います。「数学/三角」の「RAND」を選択してOKを押してください。


3.100個の一様乱数を作るため、A1セルをコピーしてA100セルまで貼り付けます。
4.B2セルに>0.5と入力してください。
5.先ほど発生させた100個の一様乱数の中で、0.5よりも大きいものの個数を調べます。B1セルにCOUNTIF関数を挿入します。「統計」の「COUNTIF」を選択してOKを押してください。
6.範囲にA1:A100、検索条件にB2とそれぞれ入力してください。検索条件は4.で入力してもらった>0.5という条件を指定しています。


7.ファンクションキー「F9」を押すと、新しく乱数を発生させることができます。0.5より大きい個数も、F9を押す度に変化します。
8.これらの値がどの区間に入っているかを調べます。まずC1セルからC11セルに0から1までの数を0.1刻みで、次のように入力してください。


9.度数分布を調べます。ツールタブ→分析ツール→ヒストグラムを選択してください。
10.入力範囲にA1セルからA100セルのデータを選択してください。データ区間に先ほど入力したC1セルからC11セルを選択してください。出力先にはE3セルを指定してください。グラフ作成にチェックを入れてください。最終的には次のような形になっていると思います。


11.OKを押してください。適当にグラフを移動し、広げて見やすい形にしてください。

練習:乱数をA1000まで1,000個発生させて同じことをやってみましょう。どんな違いがありますか。

簡便な正規乱数

1.演習1のワークシートをそのまま利用します。
2.A1セルに10個の一様乱数の和を作ります。A1セルに=RAND()+RAND()+RAND()+RAND()+RAND()+RAND()+RAND()+RAND()+RAND()+RAND()と入力してください。
3.先ほどと同じく、A1セルのコピーをA100セルまで貼り付けてください。
4.B2セルには>5と入力してください。するとB1セルに5より大きいものの個数が表示されます。
5.C1セルからC21セルに0から10までの数を0.5刻みで次のように入力してください。


6.演習1と同じ要領でヒストグラムを作ってください。データ区間にはC1セルからC21セルを選択してください。


このようなヒストグラムの図になっているでしょうか。 練習:乱数をA1000まで1,000個発生させて同じことをやってみましょう。どんな違いがありますか。

2007-12-20

If文

  1. 配列
    これまでの変数はxとかx1のように書きましたが、数学で使うx1, x2のように添え字付の変数を使うことも出来ます。添え字付の変数はx(1), x(2)のように書きます。
    使う場合は、プログラムの先頭で

    Dim x(100)

    のように、何個まで使うか明示しておく必要があります。
    もしx(1)は使わなくてx(2)からx(10)まで使うのなら

    Dim x(2 To 10)

    と書きます。
    Cells(1,1)からCells(100,1)までに書かれた数字をx(1)からx(100)へ読み込むには

    For i = 1 To 100
     x(i) = Cells(i, 1)
    Next i

    と書きます。
    次に、これらを足すには、1+2+…+100の計算同様

    wa = 0
    For i = 1 To 100
     wa = wa + x(i)
    Next i

    と書きます。

  2. Input Box
    プログラムの実行中に何かを問い合わせる画面を表示して、入力結果を変数xへ代入するには

    x = InputBox("a", "b")

    と書いて実行すると

    のように表示されます。上のプログラムでaとかbと書いた部分がそのまま表示されていますので、ここを必要に応じて書き直します。

  3. MsgBox これだけだと入力後何もせずに終わってしまうので

    x = InputBox("a", "b")
    MsgBox (x)

    と書いて、入力した内容が表示されるようにします。

  4. 課題1.
    1から入力した数までの合計を表示するプログラムを書いてください。
    例えば5と入力したら、1+2+3+4+5、つまり15を表示するプログラムです。

  5. If文
    先ほどのプログラムでゼロ以下の数を入力したら意味がありません。
    ですから、数が正なのかどうか判断させましょう。
    判断するにはIf文を使います。書き方は

    If 条件 Then
    条件が成り立つときに実行する文
    End If

    です。条件が成り立たないときは別のことをするなら

    If 条件 Then
    条件が成り立つときに実行する文
    Else
    条件が成り立たないときに実行する文
    End If

    のように書きます。

  6. 課題2
    正の数が入力されたら1からその数までの足し算をして答えを表示し、そうでない場合は"正の数を入力してください"と表示するプログラムを書いてください。
    VBAに関してはとても沢山の機能があってきりが無いので、この講義ではここまでにして、来年は別のテーマに入ります。最後に課題2をメールで提出してください。

  7. MsgBoxのあれこれ
    aとかbの部分は必要に応じて書き換えてください。

    x = MsgBox("a", 0, "b")

    x = MsgBox("a", 1, "b")

    OKをクリックするとxに1が代入され、キャンセルをクリックするとxに2が代入されます。

    x = MsgBox("a", 1, "b")
    MsgBox (x)

    を実行して、xの値を確かめてください。
    0,1の他にも、次のメッセージボックスの種類があります。

    2[中止]、[再試行]、[無視]
    3[はい]、[いいえ]、[キャンセル]
    4[はい]、[いいえ]
    5[再試行]、[キャンセル]

    クリックしたボタンとxに代入される値の関係

    1OK
    2キャンセル
    3中止
    4再試行
    5無視
    6はい
    7いいえ
  8. 次回の講義は1月10日5限です。試験期間中のこの講義を休講にしますので、その補講を、補講日であるこの日に行います。

2007-12-19

行列の和

  1. 前回の回答

    Sub ベクトル()
    Dim n1 As Integer, n2 As Integer, i As Integer
    Dim x() As Single, y() As Single, z() As Single

    Sheets(1).Select
    i = 1
    Do While Selection.Cells(i, 1) <> "" And IsNumeric(Selection.Cells(i, 1))
    i = i + 1
    Loop
    n1 = i - 1

    Sheets(2).Select
    i = 1
    Do While Selection.Cells(i, 1) <> "" And IsNumeric(Selection.Cells(i, 1))
    i = i + 1
    Loop
    n2 = i - 1

    If n1 = n2 Then
    ReDim x(n1)
    ReDim y(n1)
    ReDim z(n1)

    Sheets(1).Select
    For i = 1 To n1
    x(i) = Selection.Cells(i, 1)
    Next i

    Sheets(2).Select
    For i = 1 To n1
    y(i) = Selection.Cells(i, 1)
    Next i

    For i = 1 To n1
    z(i) = x(i) + y(i)
    Next i

    Sheets(3).Select
    For i = 1 To n1
    Selection.Cells(i, 1) = z(i)
    Next i

    Else
    MsgBox ("ベクトルの型が異なるので足し算できません")
    End If

    End Sub

  2. 行列の足し算 ベクトルではなく次のように行列が入力されている場合について足し算するプログラムを書きましょう。
     +  → 

    このように、縦横の2つの方向に数字が並んでいるときには、それを記憶する配列も添え字が2つ必要です。
    Dim x(4,3) As Single
    と書くと、
    x(1,1), x(1,2), x(1,3)
    x(2,1), x(2,2), x(2,3)
    x(3,1), x(3,2), x(3,3)
    x(4,1), x(4,2), x(4,3)
    の12個が使えるようになります。(注:正確にはx(0,0)なども使えるので20個使えます)
    この配列にシートから数字を読み込むためには
    x(1,1)=Selection.Cells(1,1)
    x(2,1)=Selection.Cells(2,1)
    x(3,1)=Selection.Cells(3,1)
    x(4,1)=Selection.Cells(4,1)

    x(1,2)=Selection.Cells(1,2)
    x(2,2)=Selection.Cells(2,2)
    x(3,2)=Selection.Cells(3,2)
    x(4,2)=Selection.Cells(4,2)

    x(1,3)=Selection.Cells(1,3)
    x(2,3)=Selection.Cells(2,3)
    x(3,3)=Selection.Cells(3,3)
    x(4,3)=Selection.Cells(4,3)
    と書きますが、この書き方だと行列の成分の個数と同じ数だけプログラムを繰り返し書かなければなりません。 繰り返す部分をFor文を使ってまとめましょう。

    For i=1 to 4
    x(i,1)=Selection.Cells(i,1)
    Next i

    For i=1 to 4
    x(i,2)=Selection.Cells(i,2)
    Next i

    For i=1 to 4
    x(i,3)=Selection.Cells(i,3)
    Next i

    このようにすると少しはまとめることが出来ますが、まだまだ似たようなプログラムを3回書かなければなりません。

    For i=1 to 4
    x(i,1)=Selection.Cells(i,1)
    Next i

    この赤い部分だけが1, 2, 3と変わりながら繰り返されているので、さらにFor文を使って繰り返します。

    For j=1 to 3
     For i=1 to 4
      x(i,j)=Selection.Cells(i,j)
     Next i
    Next j

    このように書くと、Sheet1の行列を配列xに読み込むことが出来ました。

  3. 課題1:4行3列の行列の足し算を行うプログラムを完成させなさい。

    課題2:行列の型を調べて、行の数同士が等しく、列の数同士が等しい時だけ行列の足し算をし、そうでないときは「行列の型が異なるので足し算できません」と表示するプログラムを作ってください。If 文で条件が二つ以上あるときは、 And や Or を使います。

2007-12-17

スプライン

n次のスプラインとは
  1. 節点以外ではn次多項式
  2. 節点ではn-1階微分までが節点の左右で一致
するものです。
一般に上記を満たすように各節点間の多項式の係数を決めるのは大変ですので、上記を満たす基底関数を作ってその線形和として表します。

さらに、n次スプライン基底関数をいきなり作るのも大変ですので、0次スプラインから順に作っていきましょう。
0次スプラインとは、定義どおりに

  1. 節点以外では0次多項式、つまり定数。
  2. 節点では-1階微分までが節点の左右で一致、つまり不連続で構わない。
    注)0階微分までが節点の左右で一致というのは連続ということです。
ということですので、簡単のために節点を0と1とすると、
  1. 0から1の間では1
  2. その他では0
という関数ですので、Rで書くと
sp=function(x) {
if (x >= 0 && x <= 1) {
return(1)
} else {
return(0)
}
}
になります。

しかしこのままでは引数としてベクトルを与えたときに成分ごとに計算してくれませんので、ifを使わずに組み込み関数の組み合わせで表現することにします。
どこかでジャンプのある関数が必要ですので、正負を返す関数signを使って
sp0=function(x) {
return((sign(x)-sign(x-1))/2 )
}
と書きます。

plot(sp0,-1,2)
と入力して、このグラフの形を見てみましょう。

次に、この0次スプライン基底関数同士を組み合わせて1次スプラインを作ります。2つのスプラインを組み合わせるには、まず節点の幅だけずらした基底関数を用意し、左側はその幅の間で1から0へ減る重みをかけて、右側は0から1へ増える重みをかけます。分かりづらいので式で書くと
sp1=function(x) {
return( (x)*sp0(x) + (2-x)*sp0(x-1) )
}
となります。
この方法を組み合わせて、2次、3次スプライン関数を作ってください。通常3次スプラインが良く使われます。

2007-12-13

InputBoxとMsgBox

今日の内容
  1. 先週の九九の答え合わせ
  2. 添え字付変数(配列と言います。)
  3. InputBoxとMsgBoxを使った簡単な対話型プログラム
  4. If文による分岐

2007-12-12

IF文による条件分岐

  1. 前回の解答

    Sub ベクトル()

    Dim x(100) As Single, y(100) As Single, z(100) As Single

    Sheets(1).Select
    For i = 1 To 100
    x(i) = Cells(i, 1)
    Next i

    Sheets(2).Select
    For i = 1 To 100
    y(i) = Cells(i, 1)
    Next i

    For i = 1 To 100
    z(i) = x(i) + y(i)
    Next i

    Sheets(3).Select
    For i = 1 To 100
    Cells(i, 1) = z(i)
    Next i

    End Sub

  2. 個数を数えてから足す
    3個とか100個とかに限らず、縦に何個数字が並んでいるベクトルなのかを数えてから足すプログラムを考えて見ます。まずは、1枚目のシートに並んでいる数を数えるだけのプログラムです。

    Sub ベクトル2()
    Dim x() As Single, y() As Single, z() As Single, i As Integer, n As Integer

    Sheets(1).Select
    i = 1
    Do While Selection.Cells(i, 1) <> "" And IsNumeric(Selection.Cells(i, 1))
    i = i + 1
    Loop

    n = i - 1
    ReDim x(n)
    ReDim y(n)
    ReDim z(n)

    For i = 1 To n
    x(i) = Selection.Cells(i, 1)
    Next i

    Sheets(2).Select
    For i = 1 To n
    y(i) = Selection.Cells(i, 1)
    Next i

    For i = 1 To n
    z(i) = x(i) + y(i)
    Next i

    Sheets(3).Select
    For i = 1 To n
    Selection.Cells(i, 1) = z(i)
    Next i

    End Sub

  3. 場合分け
    Sheet1に並んでいる個数とSheet2に並んでいる個数が違っていると、ベクトルの足し算は出来ません。例えば
    +
    では足し算できません。
    ですから、Sheet1に並んでいる数字の個数と、Sheet2に並んでいる数字の個数を数えて、等しいときは足し算をして、等しくないときは足し算しないという場合分けが必要になります。場合分けのためにはIF文を使います。IF文の書き方は

    If 条件 Then
    条件が成立するときに実行するプログラム
    Else
    条件が不成立のときに実行するプログラム
    End If
    です。

  4. IF文の例

    Sheet1とSheet2に自分でベクトルを入力して、次のプログラムを実行してみてください。

    Sub ベクトルの型判定()

    Sheets(1).Select
    i = 1
    Do Until Selection.Cells(i, 1) = ""
    i = i + 1
    Loop
    n1 = i - 1

    Sheets(2).Select
    i = 1
    Do Until Selection.Cells(i, 1) = ""
    i = i + 1
    Loop
    n2 = i - 1

    If n1 = n2 Then
    MsgBox ("ベクトルの型は等しいので足し算できます")
    Else
    MsgBox ("ベクトルの型は異なるので足し算できません")
    End If

    End Sub

  5. 課題

    ベクトルの型が等しいときに、ベクトルの足し算をしてSheet3に表示するプログラムを書きなさい。

  6. 行列の足し算 ベクトルではなく次のように行列が入力されている場合について足し算するプログラムを書きましょう。
     +  → 

    このように、縦横の2つの方向に数字が並んでいるときには、それを記憶する配列も添え字が2つ必要です。
    Dim x(4,3) As Single
    と書くと、
    x(1,1), x(1,2), x(1,3)
    x(2,1), x(2,2), x(2,3)
    x(3,1), x(3,2), x(3,3)
    x(4,1), x(4,2), x(4,3)
    の12個が使えるようになります。(注:正確にはx(0,0)なども使えるので20個使えます)
    この配列にシートから数字を読み込むためには
    x(1,1)=Selection.Cells(1,1)
    x(2,1)=Selection.Cells(2,1)
    x(3,1)=Selection.Cells(3,1)
    x(4,1)=Selection.Cells(4,1)

    x(1,2)=Selection.Cells(1,2)
    x(2,2)=Selection.Cells(2,2)
    x(3,2)=Selection.Cells(3,2)
    x(4,2)=Selection.Cells(4,2)

    x(1,3)=Selection.Cells(1,3)
    x(2,3)=Selection.Cells(2,3)
    x(3,3)=Selection.Cells(3,3)
    x(4,3)=Selection.Cells(4,3)
    と書きますが、この書き方だと行列の成分の個数と同じ数だけプログラムを繰り返し書かなければなりません。 繰り返す部分をFor文を使ってまとめましょう。

    For i=1 to 4
    x(i,1)=Selection.Cells(i,1)
    Next i

    For i=1 to 4
    x(i,2)=Selection.Cells(i,2)
    Next i

    For i=1 to 4
    x(i,3)=Selection.Cells(i,3)
    Next i

    このようにすると少しはまとめることが出来ますが、まだまだ似たようなプログラムを3回書かなければなりません。

    For i=1 to 4
    x(i,1)=Selection.Cells(i,1)
    Next i

    この赤い部分だけが1, 2, 3と変わりながら繰り返されているので、さらにFor文を使って繰り返します。

    For j=1 to 3
     For i=1 to 4
      x(i,j)=Selection.Cells(i,j)
     Next i
    Next j

    このように書くと、Sheet1の行列を配列xに読み込むことが出来ました。

  7. 課題1:4行3列の行列の足し算を行うプログラムを完成させなさい。

    課題2:行列の型を調べて、行の数同士が等しく、列の数同士が等しい時だけ行列の足し算をし、そうでないときは「行列の型が異なるので足し算できません」と表示するプログラムを作ってください。If 文で条件が二つ以上あるときは、 And や Or を使います。

  8. 課題が出来た人は
    行列の掛算のプログラムを作ります。行列の掛算の方法、特に掛算をするためには行列の型に どのような条件があったかを復習してください。
    復習問題:次の行列の掛算は出来ますか。出来るかどうか判定し、出来る場合は掛算してください。

2007-12-06

ExcelのVisual Basic

九九の表

先週の続きで九九の表を作りましょう。
For文を使うと
1
2
3
4
5
6
7
8
9
という表は作れると思います。同じような文をもう一度書くと
12
24
36
48
510
612
714
816
918
という表を作ることも出来るので、同じような文を9回書けば九九の表は出来るはずですが、それはあまりにも大変ですので、For文を上手に使って同じような文を9回も書かずに九九の表を作ってください。

足し算

別のプログラムを書くには、先ほどのプログラムのEnd Subの下の行に
Sub 別のプログラムの名前
と書いてEnterを押すと、区切りの線が自動的に引かれます。

今度は1から100までの数を足してみましょう。
1+2+3+…+99+100と入力していては大変ですので、For文を使った繰り返しで計算しましょう。まず
wa=0
としておいて
wa=wa+1 (この時点でwaは1)
wa=wa+2 (この時点でwaは1+2)
wa=wa+3 (この時点でwaは1+2+3)
wa=wa+4
wa=wa+5

wa=wa+98
wa=wa+99
wa=wa+100
とするとwa=1+2+3+…+99+100になりますので、最後に
Cells(1,1) = wa
と書いて計算結果を表示しましょう。

データの読み込み

まずExcelのA1からA3セルに適当に数字を入力してください。そしてこれらの数字を足し算するプログラムを書きましょう。  x1=cells(1,1)
 x2=cells(2,1)
 x3=cells(3,1)
 wa=x1+x2+x3
 cells(4,1)="合計"
 cells(4,2)=wa
と書くと、3つの数字を足すことが出来ます。では10個とか100個のデータを足すにはどうすればよいでしょうか。

2007-12-05

ベクトルの扱い方

  1. 前回の解答

    Sub 相関係数()
    Dim x() As Single, y() As Single
    Rem 身長の個数を数えます。この個数は最後まで共通で使えます。
    i = 1
    Do While Selection.Cells(i, 1) <> "" And IsNumeric(Selection.Cells(i, 1))
    i = i + 1
    Loop
    n = i - 1
    Selection.Cells(n + 1, 1) = n

    Rem 身長を配列xに読み込みます。そして先週までの方法で、身長の合計、平均、分散、標準偏差を求めてB列に書いてください。
    ReDim x(n)
    For i = 1 To n
    x(i) = Selection.Cells(i, 1)
    Next i

    wa = 0
    For i = 1 To n
    wa = wa + x(i)
    Next i
    Selection.Cells(n + 2, 1) = wa

    heikin1 = wa / n
    Selection.Cells(n + 3, 1) = heikin1

    wa2 = 0
    For i = 1 To n
    wa2 = wa2 + (x(i) - heikin1) ^ 2
    Next i

    bunsan1 = wa2 / n
    Selection.Cells(n + 4, 1) = bunsan1

    hensa1 = Sqr(bunsan1)
    Selection.Cells(n + 5, 1) = hensa1

    Rem 同様に、座高を配列yに読み込んで,座高の合計、平均、分散、標準偏差を求めてC列に書いてください。
    Selection.Cells(n + 1, 2) = n
    ReDim y(n)
    For i = 1 To n
    y(i) = Selection.Cells(i, 2)
    Next i

    wa = 0
    For i = 1 To n
    wa = wa + y(i)
    Next i
    Selection.Cells(n + 2, 2) = wa

    heikin2 = wa / n
    Selection.Cells(n + 3, 2) = heikin2

    wa2 = 0
    For i = 1 To n
    wa2 = wa2 + (y(i) - heikin2) ^ 2
    Next i

    bunsan2 = wa2 / n
    Selection.Cells(n + 4, 2) = bunsan2

    hensa2 = Sqr(bunsan2)
    Selection.Cells(n + 5, 2) = hensa2


    Rem B2に書かれている一人目の身長の値から、身長の平均を引いた値をD2に書いてください。同じことを、D21まで繰り返してください。
    For i = 1 To n
    Selection.Cells(i, 3) = x(i) - heikin1
    Next i

    Rem C2に書かれている一人目の座高の値から、座高の平均を引いた値をE2に書いてください。同じことを、E21まで繰り返してください。
    For i = 1 To n
    Selection.Cells(i, 4) = y(i) - heikin2
    Next i

    Rem D2に書いた一人目の身長と身長の平均との差と、E2に書いた一人目の座高と座高の平均の差を掛け算してF2に書いてください。同じことを、F21まで繰り返してください。
    For i = 1 To n
    Selection.Cells(i, 5) = Selection.Cells(i, 3) * Selection.Cells(i, 4)
    Next i

    Rem F2からF21までの20個の平均を求めてF22に書いてください。それが共分散です。
    wa = 0
    For i = 1 To n
    wa = wa + Selection.Cells(i, 5)
    Next i
    kyobunsan = wa / n
    Selection.Cells(n + 1, 5) = kyobunsan

    Rem 共分散を身長の標準偏差と座高の標準偏差で割ってF23に書いてください。それが相関係数です。
    soukankeisu = kyobunsan / (hensa1 * hensa2)
    Selection.Cells(n + 2, 5) = soukankeisu

    End Sub

  2. 異なるシート上の演算

    今回はシート1、シート2にある数値の和をシート3に表示させてみましょう。
    例えば、シート1のセルA1に「5」、シート2のセルA1に「3」が入れると、シート3のセルA1に5+3の答「8」が入るようなプログラムを組んでみます。

    Sub ベクトル()
    Dim wa As Single, x As Single, y As Single

    Sheets(1).Select
    x = Cells(1, 1)

    Sheets(2).Select
    y = Cells(1, 1)

    wa = x + y
    Sheets(3).Select
    Cells(1, 1) = wa

    End Sub

  3. ベクトルの和

    次にシート1、シート2にあるベクトルの和をシート3に表示させてみましょう。
     +  → 
    例えば、シート1のセルA1から「5,4,3」、シート2のセルA1から「3,5,7」というベクトルが入っているとき、シート3のセルA1から「5+3,4+5,3+7」が入るようなプログラムを組んでみます。
    次のプログラムは一応動きますが、これでは縦に並んだ数が変わるとプログラムを書き直さなければなりません。

    Sub ベクトル()
    Dim x(3) As Single, y(3) As Single, z(3) As Single

    Sheets(1).Select
    x(1) = Cells(1, 1)
    x(2) = Cells(2, 1)
    x(3) = Cells(3, 1)

    Sheets(2).Select
    y(1) = Cells(1, 1)
    y(2) = Cells(2, 1)
    y(3) = Cells(3, 1)

    z(1)=x(1)+y(1)
    z(2)=x(2)+y(2)
    z(3)=x(3)+y(3)

    Sheets(3).Select
    Cells(1,1)=z(1)
    Cells(2,1)=z(2)
    Cells(3,1)=z(3)

    End Sub

  4. 練習問題

    (1)上のプログラムを、数字が3個ではなく100個並んだベクトル用に書き直しなさい。

    (2)3個とか100個とかに固定せずに、Sheet1に並んでいる数を数えて、ベクトルの足し算を行うプログラムを書きなさい。

  5. Sheet1に並んでいる個数とSheet2に並んでいる個数が違っていると、ベクトルの足し算は出来ません。例えば
    +
    では足し算できません。ですから、最初のベクトルと二番目のベクトルの型を 調べて、等しいときだけ足し算するプログラムを作りましょう。等しいかどうか 判定するには
    If 条件 Then
    条件が成立するときに実行するプログラム
    Else
    条件が不成立のときに実行するプログラム
    End If
    という形式の文を使います。