FComplexe.hpp 6.3 KB
Newer Older
1
// ===================================================================================
2 3 4 5 6 7 8 9
// Logiciel initial: ScalFmm Version 0.5
// Co-auteurs : Olivier Coulaud, Bérenger Bramas.
// Propriétaires : INRIA.
// Copyright © 2011-2012, diffusé sous les termes et conditions d’une licence propriétaire.
// Initial software: ScalFmm Version 0.5
// Co-authors: Olivier Coulaud, Bérenger Bramas.
// Owners: INRIA.
// Copyright © 2011-2012, spread under the terms and conditions of a proprietary license.
10
// ===================================================================================
11 12
#ifndef FCOMPLEXE_HPP
#define FCOMPLEXE_HPP
13

14 15 16 17 18 19 20 21 22 23 24

#include "FMath.hpp"

/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class 
* Please read the license
*
* Propose basic complexe class.
* Do not modify the attributes of this class.
* It can be passed to blas fonction and has to be
25
* 2 x complex[0] size only.
26 27
*/
class FComplexe {
28
    FReal complex[2];    //< Real & Imaginary
29 30

public:
31 32 33 34
    /** Default Constructor (set complex[0]&imaginary to 0) */
    FComplexe() {
        complex[0] = 0;
        complex[1] = 0;
35 36 37 38
    }

    /** Constructor with values
      * @param inImag the imaginary
39
      * @param inReal the complex[0]
40
      */
41 42 43
    explicit FComplexe(const FReal inImag, const FReal inReal) {
        complex[0] = inReal;
        complex[1] = inImag;
44 45 46
    }

    /** Copy constructor */
47 48 49
    FComplexe(const FComplexe& other){
        complex[0] = other.complex[0];
        complex[1] = other.complex[1];
50 51 52 53
    }

    /** Copy operator */
    FComplexe& operator=(const FComplexe& other){
54 55
        this->complex[1] = other.complex[1];
        this->complex[0] = other.complex[0];
56 57 58 59 60
        return *this;
    }

    /** Equality operator */
    bool operator==(const FComplexe& other){
61 62
        return FMath::LookEqual(this->complex[1],other.complex[1])
                       && FMath::LookEqual(this->complex[0],other.complex[0]);
63 64 65 66 67 68 69 70 71
    }

    /** Different equal */
    bool operator!=(const FComplexe& other){
        return !(*this == other);
    }

    /** Get imaginary */
    FReal getImag() const{
72
        return this->complex[1];
73 74
    }

75
    /** Get complex[0] */
76
    FReal getReal() const{
77
        return this->complex[0];
78 79 80 81
    }

    /** Set Imaginary */
    void setImag(const FReal inImag) {
82
        this->complex[1] = inImag;
83 84 85 86
    }

    /** Set Real */
    void setReal(const FReal inReal) {
87 88 89 90 91 92 93
        this->complex[0] = inReal;
    }

    /** Set Real and imaginary */
    void setRealImag(const FReal inReal, const FReal inImag) {
        this->complex[0] = inReal;
        this->complex[1] = inImag;
94 95 96 97
    }

    /**
     * Operator +=
98
     * in complex[0] with other complex[0], same for complex[1]
99 100 101
     * @param other the complexe to use data
     */
    FComplexe& operator+=(const FComplexe& other){
102 103
        this->complex[0] += other.complex[0];
        this->complex[1] += other.complex[1];
104 105 106
        return *this;
    }   

107 108 109
    /** Inc complex[0] and imaginary by values
      * @param inIncReal to inc the complex[0]
      * @param inIncImag to inc the complex[1]
110 111
      */
    void inc(const FReal inIncReal, const FReal inIncImag){
112 113
        this->complex[0] += inIncReal;
        this->complex[1] += inIncImag;
114 115
    }

116 117
    /** Inc complex[0] by FReal
      * @param inIncReal to inc the complex[0]
118 119
      */
    void incReal(const FReal inIncReal){
120
        this->complex[0] += inIncReal;
121 122 123
    }

    /** Inc imaginary by FReal
124
      * @param inIncImag to inc the complex[1]
125 126
      */
    void incImag(const FReal inIncImag){
127
        this->complex[1] += inIncImag;
128 129
    }

130 131
    /** Dec complex[0] by FReal
      * @param inDecReal to dec the complex[0]
132 133
      */
    void decReal(const FReal inIncReal){
134
        this->complex[0] -= inIncReal;
135 136 137
    }

    /** Dec imaginary by FReal
138
      * @param inDecImag to dec the complex[1]
139 140
      */
    void decImag(const FReal inIncImag){
141
        this->complex[1] -= inIncImag;
142 143
    }

144
    /** Mul complex[0] and imaginary by a FReal
145 146 147
      * @param inValue the coef to mul data
      */
    void mulRealAndImag(const FReal inValue){
148 149
        this->complex[1] *= inValue;
        this->complex[0] *= inValue;
150 151 152 153
    }

    /** Mul a complexe by another "c*=c2" */
    FComplexe& operator*=(const FComplexe& other){
154 155 156
        const FReal tempReal = this->complex[0];
        this->complex[0] = (tempReal * other.complex[0]) - (this->complex[1] * other.complex[1]);
        this->complex[1] = (tempReal * other.complex[1]) + (this->complex[1] * other.complex[0]);
157 158
        return *this;
    }
159

160 161 162 163 164 165 166
    /** Mul a complexe by another "c*=c2" */
    FComplexe& operator*=(const FReal& real){
        this->complex[0] *= real;
        this->complex[1] *= real;
        return *this;
    }

167 168
    /** Test if a complex is not a number */
    bool isNan() const {
169
        return FMath::IsNan(complex[1]) || FMath::IsNan(complex[0]);
170
    }
171 172 173 174 175 176

    /** Mul other and another and add the result to current complexe */
    void addMul(const FComplexe& other, const FComplexe& another){
        this->complex[0] += (other.complex[0] * another.complex[0]) - (other.complex[1] * another.complex[1]);
        this->complex[1] += (other.complex[0] * another.complex[1]) + (other.complex[1] * another.complex[0]);
    }
177 178 179 180 181 182 183 184 185 186

    /** To cast to FReal */
    static FReal* ToFReal(FComplexe*const array){
        return reinterpret_cast<FReal*>(array);
    }

    /** To cast to FReal */
    static const FReal* ToFReal(const FComplexe*const array){
        return reinterpret_cast<const FReal*>(array);
    }
COULAUD Olivier's avatar
COULAUD Olivier committed
187 188 189 190 191 192 193
    /**
     * Operator stream FComplexe to std::ostream
     * This can be used to simpldata[1] write out a complex with format (Re,Im)
     * @param[in,out] output where to write the position
     * @param[in] inPosition the position to write out
     * @return the output for multiple << operators
     */
194 195
    template <class StreamClass>
    friend StreamClass& operator<<(StreamClass& output, const FComplexe& inC){
COULAUD Olivier's avatar
COULAUD Olivier committed
196 197 198 199
        output << "(" <<  inC.getReal() << ", " << inC.getImag() << ")";
        return output;  // for multiple << operators.
    }

200 201 202
};

/** Global operator Mul a complexe by another "c=c1*c2" */
berenger-bramas's avatar
berenger-bramas committed
203 204
inline FComplexe operator*=(const FComplexe& first, const FComplexe& second){
    return FComplexe(
205 206 207 208 209 210 211
            (first.getReal() * second.getImag()) + (first.getImag() * second.getReal()),
            (first.getReal() * second.getReal()) - (first.getImag() * second.getImag())
            );
}

#endif //FCOMPLEXE_HPP

212