2016-07-05 2 views
0

Je travaille avec un tableau de nombres complexes a et un tableau de nombres réels b (comme double).Utilisation de tableaux de nombres réels et de nombres complexes

typedef std::complex<double> Complex; 

std::valarray<Complex> a(1024); 
std::valarray<double> b(1024); 

std::valarray<double> modulus = std::abs(a); // problem 1 
std::valarray<Complex> modulus2 = std::abs(a); // this works but uses 2 times more memory :(
std::valarray<Complex> c = a * b;    // problem 2 

je rencontre deux problèmes (vivre runnable demo here):

  1. Pour des raisons de gestion de la mémoire, comme la valeur absolue (ou "module") est un nombre réel , il devrait être possible de le stocker comme std::valarray<double>. Mais ici ça ne marche pas: il y a une erreur conversion from 'std::_Expr<std::_UnClos<std::_Abs, std::_ValArray, std::complex<double> >, std::complex<double> >' to non-scalar type 'std::valarray<double>' requested. Comment stocker modulus en tant que std::valarray<double>?

  2. Il devrait être possible de multiplier a par b et de stocker le résultat sous la forme d'un tableau de nombres complexes. Mais il y a cette erreur: no match for 'operator*' (operand types are 'std::valarray<std::complex<double> >' and 'std::valarray<double>'). Comment faire cette multiplication de tableaux correctement?

+1

On pourrait même dire que le comité a tout gâché. –

+0

@BaummitAugen Je l'ai utilisé parce que je voulais être capable de faire des choses de haut niveau comme 'c = a * b' où a et b sont des tableaux, comme je le ferais en Python avec numpy ... Pensez-vous que je devrais utiliser autre chose? – Basj

+0

Si j'étais vous, je chercherais une bibliothèque d'algèbre linéaire décente. La recherche simple avec votre moteur de recherche préféré vous donnera de meilleures alternatives. (Je suis entièrement d'accord que votre code devrait fonctionner si 'valarray' était sain d'esprit.) –

Répondre

0

Voici la solution que je pourrais trouver (vivre runnable demo here):

#include <valarray> 
#include <complex> 

typedef std::complex<double> Complex; 

int main() 
{ 
    std::valarray<Complex> a(1024); 
    std::valarray<double> b(1024); 

    // Solution to problem 1 
    std::valarray<double> modulus(a.size()); 
    auto mod = std::abs(a); 
    for (size_t i=0;i<mod.size();i++) { 
     modulus[i] = std::abs(mod[i]); 
    } 

    std::valarray<Complex> modulus2 = std::abs(a); // this works but uses 2 times more memory :(
    std::valarray<Complex> c = a * b;    // problem 2 

    // Solution to problem 2 
    std::valarray<Complex> b2(1024); 
    std::valarray<Complex> c2(a); 
    c *= b2;          
} 

Malheureusement @Basj vous couru dans le problème d'aller de facile à utiliser Python pour C++ (je cours en ce mur aussi). Mais vous en avez, vous en perdez.

  1. std::abs() renvoie la valeur absolue des éléments tels que le valarray du même type que l'argument. Par conséquent, vous ne pouvez pas l'affecter directement à valarray<double> puisque vous avez passé l'argument en tant que valarray<Complex>.
  2. Les tableaux peuvent être multipliés, mais pas indépendamment. Vérifiez these operators. Vous pouvez multiplier votre tableau par un tableau différent (ou scalaire), mais pas par des tableaux arbitraires. `Std :: valarray` n'est pas tout à fait le summum de C++.