1 /*
2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_COMPLEX_MATRIX_H_
12 #define WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_COMPLEX_MATRIX_H_
13 
14 #include <complex>
15 
16 #include "webrtc/base/checks.h"
17 #include "webrtc/base/scoped_ptr.h"
18 #include "webrtc/modules/audio_processing/beamformer/matrix.h"
19 
20 namespace webrtc {
21 
22 using std::complex;
23 
24 // An extension of Matrix for operations that only work on a complex type.
25 template <typename T>
26 class ComplexMatrix : public Matrix<complex<T> > {
27  public:
ComplexMatrix()28   ComplexMatrix() : Matrix<complex<T> >() {}
29 
ComplexMatrix(size_t num_rows,size_t num_columns)30   ComplexMatrix(size_t num_rows, size_t num_columns)
31       : Matrix<complex<T> >(num_rows, num_columns) {}
32 
ComplexMatrix(const complex<T> * data,size_t num_rows,size_t num_columns)33   ComplexMatrix(const complex<T>* data, size_t num_rows, size_t num_columns)
34       : Matrix<complex<T> >(data, num_rows, num_columns) {}
35 
36   // Complex Matrix operations.
PointwiseConjugate()37   ComplexMatrix& PointwiseConjugate() {
38     complex<T>* const data = this->data();
39     size_t size = this->num_rows() * this->num_columns();
40     for (size_t i = 0; i < size; ++i) {
41       data[i] = conj(data[i]);
42     }
43 
44     return *this;
45   }
46 
PointwiseConjugate(const ComplexMatrix & operand)47   ComplexMatrix& PointwiseConjugate(const ComplexMatrix& operand) {
48     this->CopyFrom(operand);
49     return PointwiseConjugate();
50   }
51 
ConjugateTranspose()52   ComplexMatrix& ConjugateTranspose() {
53     this->CopyDataToScratch();
54     size_t num_rows = this->num_rows();
55     this->SetNumRows(this->num_columns());
56     this->SetNumColumns(num_rows);
57     this->Resize();
58     return ConjugateTranspose(this->scratch_elements());
59   }
60 
ConjugateTranspose(const ComplexMatrix & operand)61   ComplexMatrix& ConjugateTranspose(const ComplexMatrix& operand) {
62     RTC_CHECK_EQ(operand.num_rows(), this->num_columns());
63     RTC_CHECK_EQ(operand.num_columns(), this->num_rows());
64     return ConjugateTranspose(operand.elements());
65   }
66 
ZeroImag()67   ComplexMatrix& ZeroImag() {
68     complex<T>* const data = this->data();
69     size_t size = this->num_rows() * this->num_columns();
70     for (size_t i = 0; i < size; ++i) {
71       data[i] = complex<T>(data[i].real(), 0);
72     }
73 
74     return *this;
75   }
76 
ZeroImag(const ComplexMatrix & operand)77   ComplexMatrix& ZeroImag(const ComplexMatrix& operand) {
78     this->CopyFrom(operand);
79     return ZeroImag();
80   }
81 
82  private:
ConjugateTranspose(const complex<T> * const * src)83   ComplexMatrix& ConjugateTranspose(const complex<T>* const* src) {
84     complex<T>* const* elements = this->elements();
85     for (size_t i = 0; i < this->num_rows(); ++i) {
86       for (size_t j = 0; j < this->num_columns(); ++j) {
87         elements[i][j] = conj(src[j][i]);
88       }
89     }
90 
91     return *this;
92   }
93 };
94 
95 }  // namespace webrtc
96 
97 #endif  // WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_COMPLEX_MATRIX_H_
98