10c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org/* 20c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 30c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org * 40c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org * Use of this source code is governed by a BSD-style license 50c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org * that can be found in the LICENSE file in the root of the source 60c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org * tree. An additional intellectual property rights grant can be found 70c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org * in the file PATENTS. All contributing project authors may 80c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org * be found in the AUTHORS file in the root of the source tree. 90c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org */ 100c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 110c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_MATRIX_H_ 120c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org#define WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_MATRIX_H_ 130c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 140c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org#include <algorithm> 15dfa36058c945cf2ef9932a566987f648c24fa632Michael Graczyk#include <cstring> 160c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org#include <string> 170c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org#include <vector> 180c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 190c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org#include "webrtc/base/checks.h" 200c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org#include "webrtc/base/constructormagic.h" 2100b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org#include "webrtc/base/scoped_ptr.h" 220c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 230c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.orgnamespace { 240c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 250c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// Wrappers to get around the compiler warning resulting from the fact that 260c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// there's no std::sqrt overload for ints. We cast all non-complex types to 270c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// a double for the sqrt method. 280c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.orgtemplate <typename T> 290c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.orgT sqrt_wrapper(T x) { 300c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return sqrt(static_cast<double>(x)); 310c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org} 320c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 330c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.orgtemplate <typename S> 340c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.orgstd::complex<S> sqrt_wrapper(std::complex<S> x) { 350c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return sqrt(x); 360c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org} 370c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org} // namespace 380c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 390c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.orgnamespace webrtc { 400c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 410c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// Matrix is a class for doing standard matrix operations on 2 dimensional 420c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// matrices of any size. Results of matrix operations are stored in the 430c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// calling object. Function overloads exist for both in-place (the calling 440c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// object is used as both an operand and the result) and out-of-place (all 450c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// operands are passed in as parameters) operations. If operand dimensions 460c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// mismatch, the program crashes. Out-of-place operations change the size of 470c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// the calling object, if necessary, before operating. 480c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// 490c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// 'In-place' operations that inherently change the size of the matrix (eg. 500c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// Transpose, Multiply on different-sized matrices) must make temporary copies 510c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// (|scratch_elements_| and |scratch_data_|) of existing data to complete the 520c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// operations. 530c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// 540c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// The data is stored contiguously. Data can be accessed internally as a flat 550c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// array, |data_|, or as an array of row pointers, |elements_|, but is 560c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// available to users only as an array of row pointers through |elements()|. 570c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// Memory for storage is allocated when a matrix is resized only if the new 580c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// size overflows capacity. Memory needed temporarily for any operations is 590c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// similarly resized only if the new size overflows capacity. 600c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// 610c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// If you pass in storage through the ctor, that storage is copied into the 620c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// matrix. TODO(claguna): albeit tricky, allow for data to be referenced 630c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org// instead of copied, and owned by the user. 640c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.orgtemplate <typename T> 650c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.orgclass Matrix { 660c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org public: 670c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix() : num_rows_(0), num_columns_(0) {} 680c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 690c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // Allocates space for the elements and initializes all values to zero. 706955870806624479723addfae6dcf5d13968796cPeter Kasting Matrix(size_t num_rows, size_t num_columns) 710c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org : num_rows_(num_rows), num_columns_(num_columns) { 720c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Resize(); 730c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org scratch_data_.resize(num_rows_ * num_columns_); 740c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org scratch_elements_.resize(num_rows_); 750c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 760c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 770c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // Copies |data| into the new Matrix. 786955870806624479723addfae6dcf5d13968796cPeter Kasting Matrix(const T* data, size_t num_rows, size_t num_columns) 79661af50dd55a2beb488d4995ed21c5ffd53f8eddaluebs@webrtc.org : num_rows_(0), num_columns_(0) { 800c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyFrom(data, num_rows, num_columns); 810c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org scratch_data_.resize(num_rows_ * num_columns_); 820c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org scratch_elements_.resize(num_rows_); 830c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 840c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 850c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org virtual ~Matrix() {} 860c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 870c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // Deep copy an existing matrix. 880c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org void CopyFrom(const Matrix& other) { 890c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyFrom(&other.data_[0], other.num_rows_, other.num_columns_); 900c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 910c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 920c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // Copy |data| into the Matrix. The current data is lost. 936955870806624479723addfae6dcf5d13968796cPeter Kasting void CopyFrom(const T* const data, size_t num_rows, size_t num_columns) { 94661af50dd55a2beb488d4995ed21c5ffd53f8eddaluebs@webrtc.org Resize(num_rows, num_columns); 95661af50dd55a2beb488d4995ed21c5ffd53f8eddaluebs@webrtc.org memcpy(&data_[0], data, num_rows_ * num_columns_ * sizeof(data_[0])); 960c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 970c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 98dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting Matrix& CopyFromColumn(const T* const* src, 99dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t column_index, 1006955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_rows) { 1010c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Resize(1, num_rows); 1026955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < num_columns_; ++i) { 1030c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org data_[i] = src[i][column_index]; 1040c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1050c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1060c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 1070c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1080c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1096955870806624479723addfae6dcf5d13968796cPeter Kasting void Resize(size_t num_rows, size_t num_columns) { 110661af50dd55a2beb488d4995ed21c5ffd53f8eddaluebs@webrtc.org if (num_rows != num_rows_ || num_columns != num_columns_) { 111661af50dd55a2beb488d4995ed21c5ffd53f8eddaluebs@webrtc.org num_rows_ = num_rows; 112661af50dd55a2beb488d4995ed21c5ffd53f8eddaluebs@webrtc.org num_columns_ = num_columns; 113661af50dd55a2beb488d4995ed21c5ffd53f8eddaluebs@webrtc.org Resize(); 114661af50dd55a2beb488d4995ed21c5ffd53f8eddaluebs@webrtc.org } 1150c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1160c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1170c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // Accessors and mutators. 1186955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_rows() const { return num_rows_; } 1196955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_columns() const { return num_columns_; } 1200c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org T* const* elements() { return &elements_[0]; } 1210c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org const T* const* elements() const { return &elements_[0]; } 1220c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1230c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org T Trace() { 12491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_rows_, num_columns_); 1250c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1260c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org T trace = 0; 1276955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < num_rows_; ++i) { 1280c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org trace += elements_[i][i]; 1290c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1300c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return trace; 1310c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1320c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1330c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // Matrix Operations. Returns *this to support method chaining. 1340c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Transpose() { 1350c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyDataToScratch(); 136661af50dd55a2beb488d4995ed21c5ffd53f8eddaluebs@webrtc.org Resize(num_columns_, num_rows_); 1370c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return Transpose(scratch_elements()); 1380c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1390c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1400c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Transpose(const Matrix& operand) { 14191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(operand.num_rows_, num_columns_); 14291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(operand.num_columns_, num_rows_); 1430c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1440c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return Transpose(operand.elements()); 1450c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1460c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1470c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org template <typename S> 1480c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Scale(const S& scalar) { 1490c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org for (size_t i = 0; i < data_.size(); ++i) { 1500c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org data_[i] *= scalar; 1510c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1520c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1530c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 1540c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1550c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1560c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org template <typename S> 1570c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Scale(const Matrix& operand, const S& scalar) { 1580c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyFrom(operand); 1590c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return Scale(scalar); 1600c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1610c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1620c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Add(const Matrix& operand) { 16391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_rows_, operand.num_rows_); 16491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_columns_, operand.num_columns_); 1650c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1660c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org for (size_t i = 0; i < data_.size(); ++i) { 1670c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org data_[i] += operand.data_[i]; 1680c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1690c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1700c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 1710c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1720c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1730c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Add(const Matrix& lhs, const Matrix& rhs) { 1740c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyFrom(lhs); 1750c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return Add(rhs); 1760c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1770c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1780c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Subtract(const Matrix& operand) { 17991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_rows_, operand.num_rows_); 18091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_columns_, operand.num_columns_); 1810c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1820c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org for (size_t i = 0; i < data_.size(); ++i) { 1830c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org data_[i] -= operand.data_[i]; 1840c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1850c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1860c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 1870c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1880c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1890c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Subtract(const Matrix& lhs, const Matrix& rhs) { 1900c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyFrom(lhs); 1910c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return Subtract(rhs); 1920c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 1930c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1940c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& PointwiseMultiply(const Matrix& operand) { 19591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_rows_, operand.num_rows_); 19691d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_columns_, operand.num_columns_); 1970c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 1980c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org for (size_t i = 0; i < data_.size(); ++i) { 1990c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org data_[i] *= operand.data_[i]; 2000c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2010c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2020c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 2030c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2040c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2050c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& PointwiseMultiply(const Matrix& lhs, const Matrix& rhs) { 2060c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyFrom(lhs); 2070c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return PointwiseMultiply(rhs); 2080c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2090c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2100c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& PointwiseDivide(const Matrix& operand) { 21191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_rows_, operand.num_rows_); 21291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_columns_, operand.num_columns_); 2130c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2140c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org for (size_t i = 0; i < data_.size(); ++i) { 2150c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org data_[i] /= operand.data_[i]; 2160c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2170c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2180c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 2190c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2200c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2210c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& PointwiseDivide(const Matrix& lhs, const Matrix& rhs) { 2220c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyFrom(lhs); 2230c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return PointwiseDivide(rhs); 2240c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2250c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2260c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& PointwiseSquareRoot() { 2270c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org for (size_t i = 0; i < data_.size(); ++i) { 2280c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org data_[i] = sqrt_wrapper(data_[i]); 2290c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2300c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2310c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 2320c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2330c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2340c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& PointwiseSquareRoot(const Matrix& operand) { 2350c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyFrom(operand); 2360c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return PointwiseSquareRoot(); 2370c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2380c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2390c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& PointwiseAbsoluteValue() { 2400c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org for (size_t i = 0; i < data_.size(); ++i) { 2410c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org data_[i] = abs(data_[i]); 2420c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2430c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2440c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 2450c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2460c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2470c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& PointwiseAbsoluteValue(const Matrix& operand) { 2480c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyFrom(operand); 2490c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return PointwiseAbsoluteValue(); 2500c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2510c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2520c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& PointwiseSquare() { 2530c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org for (size_t i = 0; i < data_.size(); ++i) { 2540c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org data_[i] *= data_[i]; 2550c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2560c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2570c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 2580c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2590c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2600c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& PointwiseSquare(const Matrix& operand) { 2610c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyFrom(operand); 2620c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return PointwiseSquare(); 2630c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2640c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2650c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Multiply(const Matrix& lhs, const Matrix& rhs) { 26691d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(lhs.num_columns_, rhs.num_rows_); 26791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_rows_, lhs.num_rows_); 26891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_columns_, rhs.num_columns_); 2690c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2700c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return Multiply(lhs.elements(), rhs.num_rows_, rhs.elements()); 2710c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2720c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2730c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Multiply(const Matrix& rhs) { 27491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_EQ(num_columns_, rhs.num_rows_); 2750c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2760c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org CopyDataToScratch(); 277661af50dd55a2beb488d4995ed21c5ffd53f8eddaluebs@webrtc.org Resize(num_rows_, rhs.num_columns_); 2780c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return Multiply(scratch_elements(), rhs.num_rows_, rhs.elements()); 2790c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2800c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2810c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org std::string ToString() const { 2820c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org std::ostringstream ss; 2830c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org ss << std::endl << "Matrix" << std::endl; 2840c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2856955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < num_rows_; ++i) { 2866955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t j = 0; j < num_columns_; ++j) { 2870c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org ss << elements_[i][j] << " "; 2880c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2890c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org ss << std::endl; 2900c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2910c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org ss << std::endl; 2920c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2930c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return ss.str(); 2940c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 2950c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 2960c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org protected: 2976955870806624479723addfae6dcf5d13968796cPeter Kasting void SetNumRows(const size_t num_rows) { num_rows_ = num_rows; } 2986955870806624479723addfae6dcf5d13968796cPeter Kasting void SetNumColumns(const size_t num_columns) { num_columns_ = num_columns; } 2990c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org T* data() { return &data_[0]; } 3000c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org const T* data() const { return &data_[0]; } 3010c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org const T* const* scratch_elements() const { return &scratch_elements_[0]; } 3020c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3030c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // Resize the matrix. If an increase in capacity is required, the current 3040c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // data is lost. 3050c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org void Resize() { 3060c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org size_t size = num_rows_ * num_columns_; 3070c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org data_.resize(size); 3080c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org elements_.resize(num_rows_); 3090c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3106955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < num_rows_; ++i) { 3110c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org elements_[i] = &data_[i * num_columns_]; 3120c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3130c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3140c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3150c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // Copies data_ into scratch_data_ and updates scratch_elements_ accordingly. 3160c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org void CopyDataToScratch() { 3170c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org scratch_data_ = data_; 3180c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org scratch_elements_.resize(num_rows_); 3190c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3206955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < num_rows_; ++i) { 3210c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org scratch_elements_[i] = &scratch_data_[i * num_columns_]; 3220c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3230c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3240c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3250c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org private: 3266955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_rows_; 3276955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_columns_; 3280c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org std::vector<T> data_; 3290c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org std::vector<T*> elements_; 3300c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3310c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // Stores temporary copies of |data_| and |elements_| for in-place operations 3320c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // where referring to original data is necessary. 3330c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org std::vector<T> scratch_data_; 3340c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org std::vector<T*> scratch_elements_; 3350c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3360c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // Helpers for Transpose and Multiply operations that unify in-place and 3370c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org // out-of-place solutions. 3380c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org Matrix& Transpose(const T* const* src) { 3396955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < num_rows_; ++i) { 3406955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t j = 0; j < num_columns_; ++j) { 3410c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org elements_[i][j] = src[j][i]; 3420c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3430c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3440c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3450c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 3460c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3470c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3486955870806624479723addfae6dcf5d13968796cPeter Kasting Matrix& Multiply(const T* const* lhs, 3496955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_rows_rhs, 3506955870806624479723addfae6dcf5d13968796cPeter Kasting const T* const* rhs) { 3516955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t row = 0; row < num_rows_; ++row) { 3526955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t col = 0; col < num_columns_; ++col) { 3530c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org T cur_element = 0; 3546955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < num_rows_rhs; ++i) { 3550c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org cur_element += lhs[row][i] * rhs[i][col]; 3560c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3570c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3580c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org elements_[row][col] = cur_element; 3590c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3600c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3610c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3620c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org return *this; 3630c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org } 3640c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3653c089d751ede283e21e186885eaf705c3257ccd2henrikg RTC_DISALLOW_COPY_AND_ASSIGN(Matrix); 3660c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org}; 3670c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3680c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org} // namespace webrtc 3690c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org 3700c39e91cc827f222ab227bad09cf9199163d28f8aluebs@webrtc.org#endif // WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_MATRIX_H_ 371