Small Beamformer optimization
* Don't use ConjugateDotProduct to calculate the norm. * Only resize Matrix when needed. This makes the Beamformer run in 93.6% the original time. The error between the new and original output is really small and is caused by the new norm calculation. R=andrew@webrtc.org Review URL: https://webrtc-codereview.appspot.com/37339004 Cr-Commit-Position: refs/heads/master@{#8438} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8438 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
cce874b8d2
commit
661af50dd5
@ -95,9 +95,7 @@ float Norm(const ComplexMatrix<float>& mat,
|
|||||||
|
|
||||||
for (int i = 0; i < norm_mat.num_columns(); ++i) {
|
for (int i = 0; i < norm_mat.num_columns(); ++i) {
|
||||||
for (int j = 0; j < norm_mat.num_columns(); ++j) {
|
for (int j = 0; j < norm_mat.num_columns(); ++j) {
|
||||||
complex<float> cur_norm_element = conj(norm_mat_els[0][j]);
|
first_product += conj(norm_mat_els[0][j]) * mat_els[j][i];
|
||||||
complex<float> cur_mat_element = mat_els[j][i];
|
|
||||||
first_product += cur_norm_element * cur_mat_element;
|
|
||||||
}
|
}
|
||||||
second_product += first_product * norm_mat_els[0][i];
|
second_product += first_product * norm_mat_els[0][i];
|
||||||
first_product = 0.f;
|
first_product = 0.f;
|
||||||
@ -140,6 +138,19 @@ float SumAbs(const ComplexMatrix<float>& mat) {
|
|||||||
return sum_abs;
|
return sum_abs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculates the sum of squares of a complex matrix.
|
||||||
|
float SumSquares(const ComplexMatrix<float>& mat) {
|
||||||
|
float sum_squares = 0.f;
|
||||||
|
const complex<float>* const* mat_els = mat.elements();
|
||||||
|
for (int i = 0; i < mat.num_rows(); ++i) {
|
||||||
|
for (int j = 0; j < mat.num_columns(); ++j) {
|
||||||
|
float abs_value = std::abs(mat_els[i][j]);
|
||||||
|
sum_squares += abs_value * abs_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum_squares;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Beamformer::Beamformer(const std::vector<Point>& array_geometry)
|
Beamformer::Beamformer(const std::vector<Point>& array_geometry)
|
||||||
@ -332,8 +343,7 @@ void Beamformer::ProcessAudioBlock(const complex_f* const* input,
|
|||||||
// angle.
|
// angle.
|
||||||
for (int i = low_average_start_bin_; i < high_average_end_bin_; ++i) {
|
for (int i = low_average_start_bin_; i < high_average_end_bin_; ++i) {
|
||||||
eig_m_.CopyFromColumn(input, i, num_input_channels_);
|
eig_m_.CopyFromColumn(input, i, num_input_channels_);
|
||||||
float eig_m_norm_factor =
|
float eig_m_norm_factor = std::sqrt(SumSquares(eig_m_));
|
||||||
std::sqrt(ConjugateDotProduct(eig_m_, eig_m_)).real();
|
|
||||||
if (eig_m_norm_factor != 0.f) {
|
if (eig_m_norm_factor != 0.f) {
|
||||||
eig_m_.Scale(1.f / eig_m_norm_factor);
|
eig_m_.Scale(1.f / eig_m_norm_factor);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ class Matrix {
|
|||||||
|
|
||||||
// Copies |data| into the new Matrix.
|
// Copies |data| into the new Matrix.
|
||||||
Matrix(const T* data, int num_rows, int num_columns)
|
Matrix(const T* data, int num_rows, int num_columns)
|
||||||
: num_rows_(num_rows), num_columns_(num_columns) {
|
: num_rows_(0), num_columns_(0) {
|
||||||
CopyFrom(data, num_rows, num_columns);
|
CopyFrom(data, num_rows, num_columns);
|
||||||
scratch_data_.resize(num_rows_ * num_columns_);
|
scratch_data_.resize(num_rows_ * num_columns_);
|
||||||
scratch_elements_.resize(num_rows_);
|
scratch_elements_.resize(num_rows_);
|
||||||
@ -91,15 +91,8 @@ class Matrix {
|
|||||||
|
|
||||||
// Copy |data| into the Matrix. The current data is lost.
|
// Copy |data| into the Matrix. The current data is lost.
|
||||||
void CopyFrom(const T* const data, int num_rows, int num_columns) {
|
void CopyFrom(const T* const data, int num_rows, int num_columns) {
|
||||||
num_rows_ = num_rows;
|
Resize(num_rows, num_columns);
|
||||||
num_columns_ = num_columns;
|
memcpy(&data_[0], data, num_rows_ * num_columns_ * sizeof(data_[0]));
|
||||||
size_t size = num_rows_ * num_columns_;
|
|
||||||
|
|
||||||
data_.assign(data, data + size);
|
|
||||||
elements_.resize(num_rows_);
|
|
||||||
for (int i = 0; i < num_rows_; ++i) {
|
|
||||||
elements_[i] = &data_[i * num_columns_];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix& CopyFromColumn(const T* const* src, int column_index, int num_rows) {
|
Matrix& CopyFromColumn(const T* const* src, int column_index, int num_rows) {
|
||||||
@ -112,9 +105,11 @@ class Matrix {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Resize(int num_rows, int num_columns) {
|
void Resize(int num_rows, int num_columns) {
|
||||||
num_rows_ = num_rows;
|
if (num_rows != num_rows_ || num_columns != num_columns_) {
|
||||||
num_columns_ = num_columns;
|
num_rows_ = num_rows;
|
||||||
Resize();
|
num_columns_ = num_columns;
|
||||||
|
Resize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessors and mutators.
|
// Accessors and mutators.
|
||||||
@ -136,8 +131,7 @@ class Matrix {
|
|||||||
// Matrix Operations. Returns *this to support method chaining.
|
// Matrix Operations. Returns *this to support method chaining.
|
||||||
Matrix& Transpose() {
|
Matrix& Transpose() {
|
||||||
CopyDataToScratch();
|
CopyDataToScratch();
|
||||||
std::swap(num_rows_, num_columns_);
|
Resize(num_columns_, num_rows_);
|
||||||
Resize();
|
|
||||||
return Transpose(scratch_elements());
|
return Transpose(scratch_elements());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,8 +272,7 @@ class Matrix {
|
|||||||
CHECK_EQ(num_columns_, rhs.num_rows_);
|
CHECK_EQ(num_columns_, rhs.num_rows_);
|
||||||
|
|
||||||
CopyDataToScratch();
|
CopyDataToScratch();
|
||||||
num_columns_ = rhs.num_columns_;
|
Resize(num_rows_, rhs.num_columns_);
|
||||||
Resize();
|
|
||||||
return Multiply(scratch_elements(), rhs.num_rows_, rhs.elements());
|
return Multiply(scratch_elements(), rhs.num_rows_, rhs.elements());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user