Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


8531 / 13644 ツリー ←次へ | 前へ→

【32646】何が間違えてるか教えてください。 素人 05/12/20(火) 13:06 質問[未読]
【32649】Re:何が間違えてるか教えてください。 やっちん 05/12/20(火) 14:01 発言[未読]
【32651】すいません。 素人 05/12/20(火) 14:07 発言[未読]
【32652】Re:すいません。 やっちん 05/12/20(火) 14:17 発言[未読]
【32653】Re:すいません。 素人 05/12/20(火) 14:36 発言[未読]
【32654】Re:すいません。 やっちん 05/12/20(火) 14:40 発言[未読]
【32708】Re:すいません。 やっちん 05/12/21(水) 8:50 発言[未読]
【32677】Re:何が間違えてるか教えてください。 ni 05/12/20(火) 18:07 回答[未読]
【32696】Re:何が間違えてるか教えてください。 素人 05/12/20(火) 23:22 発言[未読]
【32700】Re:何が間違えてるか教えてください。 ni 05/12/21(水) 0:53 発言[未読]
【32751】Re:何が間違えてるか教えてください。 素人 05/12/21(水) 16:42 発言[未読]
【32761】Re:何が間違えてるか教えてください。 ni 05/12/21(水) 17:52 発言[未読]

【32646】何が間違えてるか教えてください。
質問  素人  - 05/12/20(火) 13:06 -

引用なし
パスワード
   逆行列のソースなんですがうまく行かないんです。
至急間違えを教えて下さい。


Sub gyaku()
Dim n As Integer
Dim a() As Double, d() As Double
Dim i As Integer, j As Integer, k As Integer, l As Integer
Dim ip As Integer
Dim p As Double, r As Double

  With Worksheets("Sheet1")
    n = .Cells(2, 3)
  End With
  ReDim d(n, n) As Double
  
  With Worksheets("Sheet2")
  For i = 1 To n
    For l = 1 To n
      If i = l Then
        d(i, l) = 1
        .Cells(i, 2 * n + j) = d(i, l)
      Else
        d(i, l) = 0
        .Cells(i, 2 * n + j) = d(i, l)
      End If
    Next l
  Next i
  End With
  ReDim a(n, n) As Double
  ReDim d(n, n) As Double
  MsgBox "計算開始。行列サイズは" & n & "だす。"
  
  With Worksheets("Sheet2")
  For i = 1 To n
    For j = 1 To n
      a(i, j) = .Cells(i, j).Value
    Next j
  Next i
  End With
    
    With Worksheets("Sheet2")
  For i = 1 To n
    For l = 1 To n
      d(i, l) = .Cells(i, 2 * n + l).Value
    Next l
  Next i
End With
  
  
  For l = 1 To n

  For k = 1 To n
 
  
    p = 0
    ip = 0
    For i = k To n
      If p < Abs(a(i, k)) Then
        p = Abs(a(i, k))
        ip = i
        Exit For
      End If
    Next i
    If ip = 0 Then
      MsgBox "行列が得意である(PIVOT=0)", vbCritical
      Exit For
    End If
    
    If ip > k Then
      For j = k To n
        swap a(k, j), a(ip, j)
      Next j
        swap d(k, l), d(ip, l)
    End If
    
    r = a(k, k)
    For j = k To n
      a(k, j) = a(k, j) / r
    Next j
    
    d(k, l) = d(k, l) / r
    
    For i = 1 To n
   
      If i <> k Then
        r = a(i, k)
        For j = k To n
        a(i, j) = a(i, j) - r * a(k, j)
      Next j
      d(i, l) = d(i, l) - r * d(k, l)
    
    End If
  Next i
  
  Next k
Next l
 

With Worksheets("Sheet2")
  For l = 1 To n
    For i = 1 To n
    .Cells(i, n + l) = d(i, l)
    Next i
  Next l
End With
MsgBox "計算終了。結果はシート2だす。"
End Sub

Sub swap(ByRef a As Double, ByRef d As Double)
Dim c
  c = a
  a = d
  d = c
End Sub

【32649】Re:何が間違えてるか教えてください。
発言  やっちん  - 05/12/20(火) 14:01 -

引用なし
パスワード
   ▼素人 さん:
線形代数ですか?
もっと詳しい説明が必要でしょう。
VBAがどうこうより回答する側にも逆行列の知識が必要なのでしょう?

【32651】すいません。
発言  素人  - 05/12/20(火) 14:07 -

引用なし
パスワード
   線形台数です。
えーと、ある行列とその次元数を入力したら自動的にその次元数に対応した単位行列と逆行列を作るソースを作りたいのですが単位行列はできるものの逆行列は1列目の計算だけで他の列に関してはなぜか単位行列の残りの行が表示されてしまうのです。
ちなみに逆行列を導きだすために掃き出し法という手法を持ちいています。

…あとどのようなことを書けばいいんでしょうか?

【32652】Re:すいません。
発言  やっちん  - 05/12/20(火) 14:17 -

引用なし
パスワード
   ▼素人 さん:
>ちなみに逆行列を導きだすために掃き出し法という手法を持ちいています。
その内容の説明はないのですか?

【32653】Re:すいません。
発言  素人  - 05/12/20(火) 14:36 -

引用なし
パスワード
   ▼やっちん さん:
まず最初の行列の隣に単位行列を加えたものを考えます。
ある列とある列に対して足したりひいたりかけたりして全ての列の1行目に1を一つ、他を0にします。さらに2行目のに対してもうまく計算して1と0(但し1は1行目で0だったもの)とします。それを全ての行に対して行います。
最初右にあった行列が左にう移り終わった時、右っかわに求めるべき逆行列が出来ます。
…と言っても。あまりうまく掃き出し法を表現できません。

【32654】Re:すいません。
発言  やっちん  - 05/12/20(火) 14:40 -

引用なし
パスワード
   ▼素人 さん:
内容はわかりませんが
最初の0と1の行列を作っているところで

  For i = 1 To n
    For l = 1 To n
      If i = l Then
        d(i, l) = 1
        .Cells(i, 2 * n + j) = d(i, l)
      Else
        d(i, l) = 0
        .Cells(i, 2 * n + j) = d(i, l)
      End If
    Next l
  Next i

上のjはlの間違いでは?

【32677】Re:何が間違えてるか教えてください。
回答  ni  - 05/12/20(火) 18:07 -

引用なし
パスワード
   ▼素人 さん:
>逆行列のソースなんですがうまく行かないんです。

こんにちは

逆行列の計算が必要なら、ワークシート関数の MINVERSE が使えますよ。

【32696】Re:何が間違えてるか教えてください。
発言  素人  - 05/12/20(火) 23:22 -

引用なし
パスワード
   ▼ni さん:
返信ありがとうございます。
ソースの方が必要なんです。

【32700】Re:何が間違えてるか教えてください。
発言  ni  - 05/12/21(水) 0:53 -

引用なし
パスワード
   ▼素人 さん:
>▼ni さん:
>返信ありがとうございます。
>ソースの方が必要なんです。
逆行列が必要と言うのじゃないのですね?
宿題ですか? 違ってたらごめんなさい。

【32708】Re:すいません。
発言  やっちん  - 05/12/21(水) 8:50 -

引用なし
パスワード
   ▼素人 さん:
a()とd()は
平行して同じ処理をする必要があります。
ループもなぜか1つ多い気がしますね。
私にはこれが限界かな。


Sub gyaku()
  Dim n As Integer
  Dim a() As Double, d() As Double
  Dim i As Integer, j As Integer, k As Integer, l As Integer
  Dim ip As Integer
  Dim p As Double, r As Double

  With Worksheets("Sheet1")
    n = .Cells(2, 3)
  End With
  ReDim d(n, n) As Double
 
  With Worksheets("Sheet2")
    For i = 1 To n
      For l = 1 To n
        If i = l Then
          d(i, l) = 1
  '        .Cells(i, 2 * n + j) = d(i, l)
          .Cells(i, 2 * n + l) = d(i, l)
        Else
          d(i, l) = 0
  '        .Cells(i, 2 * n + j) = d(i, l)
          .Cells(i, 2 * n + l) = d(i, l)
        End If
      Next l
    Next i
  End With
  ReDim a(n, n) As Double
'  ReDim d(n, n) As Double
  MsgBox "計算開始。行列サイズは" & n & "だす。"
 
  With Worksheets("Sheet2")
    For i = 1 To n
      For j = 1 To n
        a(i, j) = .Cells(i, j).Value
      Next j
    Next i
  End With
  
'  With Worksheets("Sheet2")
'    For i = 1 To n
'      For l = 1 To n
'        d(i, l) = .Cells(i, 2 * n + l).Value
'      Next l
'    Next i
'  End With
 
 
'  For l = 1 To n

  For k = 1 To n
 
 
    p = 0
    ip = 0
    For i = k To n
      If p < Abs(a(i, k)) Then
        p = Abs(a(i, k))
        ip = i
        Exit For
      End If
    Next i
    If ip = 0 Then
      MsgBox "行列が得意である(PIVOT=0)", vbCritical
      Exit For
    End If
  
    If ip > k Then
      For j = k To n
        swap a(k, j), a(ip, j)
        swap d(k, j), d(ip, j)
      Next j
'      swap d(k, l), d(ip, l)
    End If
  
    r = a(k, k)
'    For j = k To n
    For j = 1 To n
      a(k, j) = a(k, j) / r
      d(k, j) = d(k, j) / r '*
    Next j
  
'    d(k, l) = d(k, l) / r
  
'    For i = k To n
    For i = 1 To n
 
      If i <> k Then
        r = a(i, k)
'        For j = k To n
        For j = 1 To n
          a(i, j) = a(i, j) - r * a(k, j)
          d(i, j) = d(i, j) - r * d(k, j) '*
        Next j
'        d(i, l) = d(i, l) - r * d(k, l)
  
      End If
    Next i
 
  Next k
'Next l


  With Worksheets("Sheet2")
    For l = 1 To n
      For i = 1 To n
        .Cells(i, n + l) = d(i, l)
      Next i
    Next l
  End With
  MsgBox "計算終了。結果はシート2だす。"
End Sub

【32751】Re:何が間違えてるか教えてください。
発言  素人  - 05/12/21(水) 16:42 -

引用なし
パスワード
   ▼ni さん:
まぁそんなところです。

【32761】Re:何が間違えてるか教えてください。
発言  ni  - 05/12/21(水) 17:52 -

引用なし
パスワード
   ▼素人 さん:
>▼ni さん:
>まぁそんなところです。

宿題なら、自分でやらなきゃ。

でも、ここまでできているのですから、やっちんさんが仰るように、
変数を間違えていないか、タイプミスが無いかなど、チェックしてみましょう。
小さな行列を与えて、ステップ実行で意図しているところのあたいを書き換えているか、
などチェックしましょう。

参考までに、Cで書かれた逆行列計算のプログラムを発見しましたので、
比較するのも間違い発見につながるかと思います。

http://www.fuka.info.waseda.ac.jp/~kozo/suuchi/simple_equation/simple_equation_4.html

8531 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free