2013-07-08 8 views
3

Существует ли версия умножения для операции a * = b для массивов с комплексными числами? Другими словами, какой наиболее эффективный способ умножить все элементы массива комплексных чисел (большое количество элементов или неизвестной длины) и сохранить результат в сложной двойной переменной?Умножение массива комплексных чисел

В следующем коде Ans1 дает правильный ответ, однако для моего приложения нецелесообразно обращаться к каждому элементу массива, так как будет сотни. В идеале, я бы хотел иметь цикл (нечто похожее на Ans2), который умножает все элементы массива и сохраняет ответ. Если я не инициирую Ans2 как 1.0,1.0, ответ будет равен 0,0, поскольку элементы будут умножены на 0. Однако инициализация с 1.0.1.0 не будет работать, поскольку мы имеем дело со сложными числами.

EDIT - Причина, по которой я не могу адресовать каждый элемент вручную, заключается в том, что это будет связано с более крупной программой, где элементы массива «a» будут поступать откуда-то еще, а длина «a» будет меняться ,

В идеале ОТВЕТ = КОМПЛЕКСНОЕ ЭЛЕМЕНТ [0] * КОМПЛЕКС ЭЛЕМЕНТОВ [1] КОМПЛЕКС ЭЛЕМЕНТОВ [2] .... КОМПЛЕКС ЭЛЕМЕНТОВ [п]

/* 
     Complex Array Multiplication 
    */ 

    #include <complex> 
    #include <iostream> 
    #include <cmath> 

    using namespace std; 

    int main() 
    { 
     int n = 3; 
     complex<double> Ans1, Ans2(1.0,1.0); 

     complex<double> a[n]; 

     a[0] = complex<double>(1.0, 1.5); 
     a[1] = complex<double>(-1.0, 1.5); 
     a[2] = complex<double>(1.0, -1.5); 

     Ans1 = (a[0]*a[1]*a[2]); 
     cout << "\nAns1 = " << Ans1; 

     for (int i =0; i < n; i++) { 
      Ans2 = Ans2 * a[i]; 
     } 

     cout << "\nAns2 = " << Ans2; 

     getchar(); 
    } 

Может быть, это можно было бы сделать очень легко, но я «Что-то не хватает. Заранее спасибо.

+2

Умножение «сотни «сложных значений на самом деле не является проблемой для современных компьютеров ... – filmor

+0

« для моего приложения не имеет смысла обращаться к каждому элементу массива, так как будет сотни »вы пишете эту программу на перфокартах? – djechlin

+0

Правда, но написание каждого элемента вручную, как я сделал для Ans1, вероятно, не самый эффективный способ использования современных компьютеров.Я только что создал массив A для заполнения значений, но для моего приложения значения будут получены откуда-то еще. – user2550888

ответ

5

мультипликативная тождество для комплексных чисел 1 + 0i, так что вы должны инициализировать Ans2 к (1, 0) до вашего цикла.

Если вы не знакомы с термином, то идентификатор является значением, которое не изменяет результат операции. Например, аддитивное тождество для действительных чисел равно 0, потому что a + 0 = a для любого действительного значения a. Для умножения комплексных чисел (a + bi) * (1 + 0i) = (a + bi). В вашем цикле вы хотите инициализировать Ans2 значению, которое не повлияет на результат вычисления, поэтому вы используете мультипликативный идентификатор.

+0

Спасибо, именно то, что я искал! – user2550888

+0

Нет, проблема, рада помочь. – Caleb

0

Вы можете попробовать это:

if (n>=2) 
{ 
    complex<double> ans3 = a[0]*a[1]; 
    for (unsigned int i = 2; i < n; ++i) 
    { 
     ans3 *= a[i]; 
    } 
    cout << "ans3 = " << ans3<<std::endl; 
} 
5

Прежде всего, строка complex<double> a[n]; недопустима C++, поскольку n не является константой компиляции - она ​​должна быть (по крайней мере, до C++ 14). Ваш компилятор может внедрять VLA, но они не являются частью стандарта (пока).

Другими словами, что является наиболее эффективным способом умножения всех элементов массива комплексных чисел (большого количества элементов или неизвестной длины) и сохранения результата в сложной двойной переменной?

Вы могли бы пойти с std::accumulate:

#include <complex> 
#include <iostream> 
#include <cmath> 
#include <algorithm> //accumulate 
#include <functional> //multiplies 

using namespace std; 

int main() 
{ 
    cons static int n = 3; //compiletime constant 

    complex<double> a[n]; 

    a[0] = complex<double>(1.0, 1.5); 
    a[1] = complex<double>(-1.0, 1.5); 
    a[2] = complex<double>(1.0, -1.5); 

    //define variables when they are needed 

    //alternative 1: using std::multiplies 
    auto Ans1 = std::accumulate(begin(a), end(a), complex<double>{1}, multiplies<complex<double>>{}); 
    cout << "\nAns1 = " << Ans1; 

    //alternative 2: using a C++11 lambda 
    auto Ans2 = std::accumulate(begin(a), end(a), complex<double>{1.0,1.0}, [](complex<double> a, complex<double> b) {return a*b;}) 
    cout << "\nAns2 = " << Ans2; 

    //alternative 3: using a C++14 templated lambda 
    auto Ans3 = std::accumulate(begin(a), end(a), complex<double>{1.0,1.0}, [](auto a, auto b) {return a*b;}) 
    cout << "\nAns3 = " << Ans3; 
} 

Примечание: Я не знаю, если complex(1,1) действительно начальное значение, которое вы хотите пойти с - мультипликативная идентичность complex(1,0)

+0

Благодарим за всеобъемлющий ответ. Раньше я не знал о мультипликативной идентичности и фиксировал проблему :) – user2550888

Смежные вопросы