VBAで複素数の多項式展開

このQ&Aのポイント
  • VBAを使用して複素数の多項式展開を行いたいです。
  • 10次程度の多項式を展開したいですが、実数の場合はできますが、複素数の場合は間違った解が出てきてしまいます。
  • 正解にたどりつくための問題の指摘や正負の逆転の仕方について教えていただけると助かります。
回答を見る
  • ベストアンサー

VBAで、複素数の多項式展開がしたい

はじめまして 初めて質問させていただきます。 私は、VBAにて10次程度の多項式 (X-A-Bi)(X-C-Di)…   (1) を α10*x^10+α9*x^9…    (2) に展開したく、プログラムを製作しています。 (1)の解が実数のみ(A、C)の場合の 展開は製作することができました。 ----------------------------------------- Sub tenkai() Dim ji As Integer Dim A(10) As Double Dim X(11) As Double ji = Cells(1, 2).Value '次数の入力 For i = 0 To ji A(i) = Cells(3, 12 - i) '解の入力 X(i) = 1 Next i X(0) = A(1) For n = 2 To ji X(n) = X(n - 1) X(n) = X(n - 1) For i = n - 1 To 1 Step -1 X(i) = X(i - 1) + A(n) * X(i) Next i X(0) = A(n) * X(0) Next n For i = 0 To ji Cells(8, 12 - i) = X(i) Next i End Sub ------------------------------------- 上記は、正負は逆になるのですが、一応の答えは出ます。 しかし、これに複素数を考慮したところ、 まったく間違った解が出てきてしまいます。 ------------------------------------- Sub tenkai2() Dim ji As Integer Dim Ar(10) As Double Dim Ai(10) As Double Dim Xr(11) As Double Dim Xi(11) As Double ji = Cells(1, 2).Value '次数の入力 For i = 0 To ji Ar(i) = Cells(3, 12 - i) '解の入力(実数) Ai(i) = Cells(4, 12 - i) '解の入力(複素数) Xr(i) = 1 Xi(i) = 0 Next i Xr(0) = Ar(1) Xi(0) = Ai(1) For n = 2 To ji Xr(n) = Xr(n - 1) Xi(n) = Xi(n - 1) For i = n - 1 To 1 Step -1 Xr(i) = Xr(i - 1) + Ar(n) * Xr(i) - Ai(n) * Xi(i) Xi(i) = Xi(i - 1) + Ar(n) * Xi(i) + Ai(i) * Xr(i) Next i Xr(0) = Ar(n) * Xr(0) - Ai(n) * Xi(0) Xi(0) = Ar(n) * Xi(0) + Ai(n) * Xr(0) Next n For i = 0 To ji Cells(8, 12 - i) = Xr(i) Cells(9, 12 - i) = Xi(i) Next i End Sub -------------------------------------- 式の解はあっても、展開については解説サイトがなく、 どうしても、正解にたどりつくことができず困っています。 どなたか問題を指摘していただく事はできませんでしょうか? もしわかれば、 正負の逆転の仕方についても、教えて頂ければと思います。 C言語の解説サイトなどでも理解ができます。

  • J2J
  • お礼率77% (7/9)

質問者が選んだベストアンサー

  • ベストアンサー
  • nishi6
  • ベストアンサー率67% (869/1280)
回答No.1

久しぶりに『複素数』という文字を見て、考えて見ました。 基本的な考え方は合っていると思います。 計算の途中、   Xr(i) = Xr(i - 1) + Ar(n) * Xr(i) - Ai(n) * Xi(i)   Xi(i) = Xi(i - 1) + Ar(n) * Xi(i) + Ai(i) * Xr(i) と   Xr(0) = Ar(n) * Xr(0) - Ai(n) * Xi(0)   Xi(0) = Ar(n) * Xi(0) + Ai(n) * Xr(0) の箇所で、Xr(i)とXr(0)を再計算してしまって、それを次の行で使用しています。 これが原因でおかしな結果になるでしょう。下のコードはそれを回避してみました。 (『//** 』を付加している行が変更箇所です) 実数を『+1』、虚数部分を『非常に小さく』してみると、パスカルの三角形の値が出るので、合っているかと思います。 答えがあれば照合してください。 >正負の逆転の仕方についても、教えて頂ければと思います。 質問のモジュールは (X+b+ci) の形式の掛け算を展開しています。b、cが正として作られています。 (X-b-ci) を解くようにb、cをセットするのであれば、読み込み時点で定数の符号を逆転させればいいでしょう。(下記を参照してください) Sub tenkai2()   Dim i As Integer   '//** 追加   Dim n As Integer   '//** 追加   Dim ji As Integer      Dim Ar(10) As Double   Dim Ai(10) As Double   Dim Xr(11) As Double   Dim Xi(11) As Double      ji = Cells(1, 2).Value '次数の入力      For i = 0 To ji     Ar(i) = -Cells(3, 12 - i) '解の入力(実数) //**逆符号で取り込む     Ai(i) = -Cells(4, 12 - i) '解の入力(複素数)//**逆符号で取り込む     Xr(i) = 1     Xi(i) = 0   Next      Dim Xr0 As Double  '//** 作業用変数を追加   Dim Xi0 As Double  '//** 作業用変数を追加      Xr(0) = Ar(1)   Xi(0) = Ai(1)   For n = 2 To ji     Xr(n) = Xr(n - 1)     Xi(n) = Xi(n - 1)     For i = n - 1 To 1 Step -1       '//** 互いに干渉しないように計算するよう変更(下4行)       Xr0 = Xr(i - 1) + Ar(n) * Xr(i) - Ai(n) * Xi(i)       Xi0 = Xi(i - 1) + Ar(n) * Xi(i) + Ai(i) * Xr(i)       Xr(i) = Xr0       Xi(i) = Xi0     Next          '//** 互いに干渉しないように計算するよう変更(下4行)     Xr0 = Ar(n) * Xr(0) - Ai(n) * Xi(0)     Xi0 = Ar(n) * Xi(0) + Ai(n) * Xr(0)     Xr(0) = Xr0     Xi(0) = Xi0   Next        For i = 0 To ji     Cells(8, 12 - i) = Xr(i)     Cells(9, 12 - i) = Xi(i)   Next End Sub

J2J
質問者

お礼

ありがとうございます!! >作業用変数を追加 まさに!!これが必要でした! 表記していただいたモジュールを実行したところ、 3次までしか精巧な値は得られませんでした。 そこで、再度、紙とペンで式を展開し、 問題であろう、   Xr(i) = Xr(i - 1) + Ar(n) * Xr(i) - Ai(n) * Xi(i)   Xi(i) = Xi(i - 1) + Ar(n) * Xi(i) + Ai(i) * Xr(i) を変更したところ、正常に作動を確認する事ができました。 nishi6さんのアドバイスと、 >「基本的な考え方は合っていると思います。」 という、お褒めの言葉が実現につながりました。 大変うれしかったです。 感謝いたします!ありがとうございました! 以下に、完成したソースを載せておきます。 ('//でくくった点が変更点) -------------------------------------------- Sub tenkai4() Dim ji As Integer Dim Ar(10) As Double Dim Ai(10) As Double Dim Xr(11) As Double Dim Xi(11) As Double Dim TEMPr(11) As Double Dim TEMPi(11) As Double ji = Cells(1, 2).Value '//次数の入力 For i = 0 To ji Ar(i) = -Cells(3, 12 - i) '//解の入力(実数) Ai(i) = -Cells(4, 12 - i) '//解の入力(複素数) Xr(i) = 1 Xi(i) = 0 '// TEMPr(i) = 0 '作業用変数を追加 TEMPi(i) = 0 '作業用変数を追加 '// Next i For n = 1 To ji '// '//以下、変更点/ For i = n - 1 To 0 Step -1 TEMPr(i + 1) = TEMPr(i + 1) + Xr(i) TEMPr(i) = TEMPr(i) + (Xr(i) * Ar(n) - Xi(i) * Ai(n)) TEMPi(i + 1) = TEMPi(i + 1) + Xi(i) TEMPi(i) = TEMPi(i) + (Xr(i) * Ai(n) + Xi(i) * Ar(n)) Next i For i = 0 To n Xr(i) = TEMPr(i) Xi(i) = TEMPi(i) TEMPr(i) = 0 TEMPi(i) = 0 Next i '//変更点終わり/ '// Next n For i = 0 To ji Cells(8, 12 - i) = Xr(i) Cells(9, 12 - i) = Xi(i) Next i End Sub

関連するQ&A

  • VBAで縦一列に数字を入力したい

    Private Sub CommandButton1_Click() Dim n As Integer Dim i As Integer Dim x As Integer For i = 1 To n x = i + 3 n = InputBox("層数の値を入力してください") Cells(3, 1).Value = ("基板") Cells(x, 1).Value = i x = x + 1 Next End Sub 上記のようなマクロを組んだのですが、4行目に1が入ってとまってしまいました。 これを完成させるにはどうしたらいいでしょうか?

  • vbaでオーバーフローしてしまいました。

    Dim i As Long Dim k As Long For i = 1 To 829 For k = 1 To 995 Worksheets("2").Cells(k,i) = Worksheets("1").Cells(k,i) /Worksheets("1").Cells(996,i) Next k Next i これを実行したらオーバーフローしてしまい、途中までしか計算できませんでした。 解決方法を教えて頂きたいです。よろしくお願いします。

  • VBAの乱数について質問

    乱数 x (0<x<1)を0.1刻みで発生させたいんですが うまくいきません。 プログラム例 Sub 一様乱数() Dim bin#(10) n = 1000 For m = 1 To 10 bin#(m) = 0 Next m For J = 1 To n x = Rnd(1) ix = Int(10 * Rnd(1)) bin#(ix) = bin#(ix) + 1 Next J Cells(4, 1) = " I" Cells(4, 2) = "Bin#(I)度数分布" For I = 0 To 10 Cells(I + 5, 1).Value = I Cells(I + 5, 2).Value = bin#(I) Next I End Sub ここで、9行目ix = Int(10 * Rnd(1))で0.1刻みになり 15行目のFor I = 0 To 10を0 to 1に変えればできると思ったんですが できませんでした。 どこが問題なのかヒントでもいいので教えてください。

  • エクセル2003のVBAで列を指定

    エクセルで特定の列の2~10行目に対して、ある作業をする場合、列を指定する方法は以下のどれがいいでしょうか?あるいはもっといい方法があれば教えてください。 実際には列は約40列(固定)、行は1~2万行(変動)程度で、作業はもっと複雑です。 Sub test01() Dim col Dim i As Long, n As Long For Each col In Array(1, 3, 7, 8, 11) '列番号で指定 For i = 2 To 10 n = n + 1 Cells(i, col).Value = n Next i Next col End Sub Sub test02() Dim col Dim i As Long, n As Long For Each col In Array("A", "C", "G", "H", "K") '列の記号で指定 For i = 2 To 10 n = n + 1 Cells(i, col).Value = n Next i Next col End Sub Sub test03() Dim col Dim i As Long, n As Long For Each col In Range("A2,C2,G2,H2,K2") 'セルで指定 For i = 2 To 10 n = n + 1 col.Offset(i - 2).Value = n Next i Next col End Sub

  • 以前に回答いただいたVBAですが、理解できない部分があったので、抜粋し

    以前に回答いただいたVBAですが、理解できない部分があったので、抜粋して質問に投稿したところ、多くの方々から、「これでは、わからない」などの指摘をいただき、これでは、以前に回答していただいた回答者様の名誉にかかわると思い全文を記載させていただくことにしました。  あわせて、この、VBAの詳しい説明を快くしていただける方は回答よろしくお願いします。以下のとうりです。  A列  B列 1 期間  90 2 人数  21 3 4 氏名  回数 5 A   23 6 B   23 7 C   19 8 D   16 9 E   12 10 F   9 11 G   8 12 H   7 13 I   7 14 J   6 15 K   6 16 L   6 17 M   5 18 N   5 19 O   4 20 P   4 21 Q   4 22 R   4 23 S   4 24 T   4 25 U   4 Sub 当番割当() Dim 期間 As Integer Dim 人数 As Integer Dim 氏名() As String Dim 回数() As Integer Dim i As Integer Dim j As Integer Dim k As Integer Dim m As Integer Dim n As Integer Dim n1 As Integer Dim n2 As Integer Dim p As Single Dim q As Single Dim 当番() As String Dim 担当() As Single 期間 = Cells(1, 2) 人数 = Cells(2, 2) ReDim 氏名(人数) ReDim 回数(人数) For i = 1 To 人数 氏名(i) = Cells(4 + i, 1) 回数(i) = Cells(4 + i, 2) Next i ReDim 当番(期間 * 2) ReDim 担当(期間 * 2) n = 0 For i = 1 To 人数 n1 = 0 n2 = 0 For j = 1 To 人数 If 回数(j) = 回数(i) Then n1 = n1 + 1 If j <= i Then n2 = n2 + 1 End If Next j p = 期間 / 回数(i) For j = 1 To 回数(i) q = p * (n2 - 0.5) / n1 + p * (j - 1) m = 1 For k = n To 1 Step -1 If 担当(k) <= q Then m = k + 1 Exit For End If 当番(k + 1) = 当番(k) 担当(k + 1) = 担当(k) Next k 当番(m) = 氏名(i) 担当(m) = q n = n + 1 Next j Next i Range("E:G").Clear For n = 1 To 期間 Cells(n, 5) = n & "日" Cells(n, 6) = 当番(n * 2 - 1) Cells(n, 7) = 当番(n * 2) Next n End Sub

  • VBAで行列を作る方法

    次のようなプログラミングで1,0,-1の要素で作られる3×3行列を全通り調べています。 この場合3の9乗通り調べることができます。 これを4×4や5×5行列など数を大きくして調べたいのですが、このプログラムを配列を使うなどして 簡単にできる方法を教えてください。 よろしくおねがいします。 Sub test() Dim a As Integer '行 Dim b As Integer '列 Dim c As Integer, i As Integer, j As Integer, d As Integer, e As Integer Dim 内積 As Integer, step As Integer Dim f As Integer, g As Integer, h As Integer, l As Integer, m As Integer, n As Integer, k As Integer, x As Integer Dim sum As Integer, total As Integer Dim aa As Integer, aaa As Integer, aaaa As Integer, bb As Integer, bbb As Integer, bbbb As Integer a = 3 '行 b = 3 '列 c = 0 内積 = 0 con = 0 sum = 0 tatal = 0 aa = 0 aaa = 0 aaaa = 0 bb = 0 bbb = 0 bbbb = 0 x = 0 For n = 0 To 2 For m = 0 To 2 For l = 0 To 2 For k = 0 To 2 For h = 0 To 2 For g = 0 To 2 For f = 0 To 2 For e = 0 To 2 For d = 0 To 2 '要素がすべて1 For i = 1 To a For j = 1 To b Cells(i, j) = 1 Next j Next i If bbbb = 1 Then Cells(a - 2, b - 2) = 0 ElseIf bbbb = 2 Then Cells(a - 2, b - 2) = -1 End If If bbb = 1 Then Cells(a - 1, b - 2) = 0 ElseIf bbb = 2 Then Cells(a - 1, b - 2) = -1 End If If bb = 1 Then Cells(a, b - 2) = 0 ElseIf bb = 2 Then Cells(a, b - 2) = -1 End If If aaaa = 1 Then Cells(a - 2, b - 1) = 0 ElseIf aaaa = 2 Then Cells(a - 2, b - 1) = -1 End If If aaa = 1 Then Cells(a - 1, b - 1) = 0 ElseIf aaa = 2 Then Cells(a - 1, b - 1) = -1 End If If aa = 1 Then Cells(a, b - 1) = 0 ElseIf aa = 2 Then Cells(a, b - 1) = -1 End If If total = 1 Then Cells(a - 2, b) = 0 ElseIf total = 2 Then Cells(a - 2, b) = -1 End If If sum = 1 Then Cells(a - 1, b) = 0 ElseIf sum = 2 Then Cells(a - 1, b) = -1 End If If con = 1 Then Cells(a, b) = 0 ElseIf con = 2 Then Cells(a, b) = -1 End If con = con + 1 Next d con = 0 sum = sum + 1 Next e sum = 0 total = total + 1 Next f total = 0 aa = aa + 1 Next g aa= 0 aaa = aaa + 1 Next h aaa = 0 aaaa = aaaa + 1 Next k aaaa = 0 bb = bb + 1 Next l bb = 0 bbb = bbb + 1 Next m bbb = 0 bbbb = bbbb + 1 Next n End Sub

  • エクセルVBAで配列?

    以下は、文字列"t", "e", "s", "t"を配列に取り込み、セルに表示する例ですが、 ar = Array("t", "e", "s", "t") なら作動しますが、セル範囲から取り込もうと、 ar = Range("A1:D1").Value とするとエラーになります。 どうしてでしょうか? Sub test() Dim ar As Variant Dim n As Integer ar = Array("t", "e", "s", "t") 'ar = Range("A1:D1").Value For n = LBound(ar) To UBound(ar) Cells(n + 1, 5) = ar(n) Next n End Sub

  • vba boolean変数を開放する方法

    エクセルのセルに「○○○○○○○○○○××××××××××」と入っているものをランダムに並べ代えるマクロを探してみました。 Sub macro2() Dim i, m As Integer Dim b, c As String Dim flg(1 To 20) As Boolean b = Cells(1, 1).Value Randomize For i = 1 To 20 Do m = Int(20 * Rnd + 1) If flg(m) = False Then flg(m) = True Exit Do End If Loop c = c & Mid(b, m, 1) Next i Cells(1, 2).Value = c End Sub これはうまく動くのですが、10行分やろうとして、以下のように変更すると暴走(終わらない)します。 Sub macro2() Dim i, m, n As Integer Dim b, c As String Dim flg(1 To 20) As Boolean For n = 1 To 10 b = Cells(n, 1).Value Randomize For i = 1 To 20 Do m = Int(20 * Rnd + 1) If flg(m) = False Then flg(m) = True Exit Do End If Loop c = c & Mid(b, m, 1) Next i Cells(n, 2).Value = c next n End Sub 一行目が終わってもboolean変数の値がそのまま残っているのが原因らしいのですが開放する方法がわかりません。 取りあえずもう一つマクロを追加してやりたいことはできたのですが、 Sub macro1() Dim n As Integer For n = 1 To 10 Call macro2(n) Next n End Sub Sub macro2(n As Variant) 以下略 なんかスッキリしません。 boolean変数を開放し、マクロひとつですます方法を教えて頂きたくお願いします。 flg(m) = Falseを挿入してもダメでした。

  • Excel VBAライフゲーム

    ExcelのVBAでライフゲームを作りたいのですが、次のプログラムの途中以降がわかりません。 もしよろしければ、このつづきの簡単な実行できるVBAライフゲームを教えてください。 続きのプログラムを教えていただけたら幸いです。 Option Explicit Const ALIVE As Integer = 1 Const DEAD As Integer = 0 Const SIZE As Integer = 19 Const Tmax As Integer = 100 Dim C(SIZE, SIZE) As Integer Sub LifeGame() Dim InitRate As Single Dim T As Integer Dim N As Integer Dim Cnext(SIZE, SIZE) As Integer Dim I As Integer, J As Integer InitRate = -1 Do While InitRate < 0 Or 1 < InitRate Loop For I = 0 To SIZE For J = 0 To SIZE If Rnd() < InitRate Then C(I, J) = ALIVE Else C(I, J) = DEAD End If Next J Next I For T = 1 To Tmax For I = 0 To SIZE For J = 0 To SIZE If C(I, J) = ALIVE Then Cells(I + 1, J + 1).Value = "■" Else Cells(I + 1, J + 1).Vallue = "" End If Next J Next I For I = 0 To SIZE For J = 0 To SIZE N = Count(I, J) Next J Next I For I = 0 To SIZE For J = 0 To SIZE C(I, J) = Cnext(I, J) Next J Next I Next T End Sub Function Count(I As Integer, J As Integer) As Integer End Function

  • エクセル VBA もっときれいな書き方?

    Sub test() Dim i As Integer, n As Integer n = 1 For i = 2 To 150 If Cells(i, 1) <> Cells(i - 1, 1) Then Cells(i - 1, 5) = i - n Cells(i - 1, 6) = Application.WorksheetFunction.Sum(Range("B" & n & ":" & "B" & i - 1)) n = i End If Next i End Sub 上記のマクロですが Application.WorksheetFunction.Sum(Range("B" & n & ":" & "B" & i - 1)) この部分、もっとスマートに書く方法を教えてください。 Range("B" & n & ":" & "B" & i - 1)って、ちゃんと動きますが、書き方が何か変なような気がするんです。 よくわかってもいないのにすみません。