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
20namespace webrtc {
21
22using std::complex;
23
24// An extension of Matrix for operations that only work on a complex type.
25template <typename T>
26class ComplexMatrix : public Matrix<complex<T> > {
27 public:
28  ComplexMatrix() : Matrix<complex<T> >() {}
29
30  ComplexMatrix(size_t num_rows, size_t num_columns)
31      : Matrix<complex<T> >(num_rows, num_columns) {}
32
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.
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
47  ComplexMatrix& PointwiseConjugate(const ComplexMatrix& operand) {
48    this->CopyFrom(operand);
49    return PointwiseConjugate();
50  }
51
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
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
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
77  ComplexMatrix& ZeroImag(const ComplexMatrix& operand) {
78    this->CopyFrom(operand);
79    return ZeroImag();
80  }
81
82 private:
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