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
diff --git a/webrtc/modules/audio_processing/beamformer/beamformer.cc b/webrtc/modules/audio_processing/beamformer/beamformer.cc
index ced14d7..99fe846 100644
--- a/webrtc/modules/audio_processing/beamformer/beamformer.cc
+++ b/webrtc/modules/audio_processing/beamformer/beamformer.cc
@@ -95,9 +95,7 @@
 
   for (int i = 0; i < norm_mat.num_columns(); ++i) {
     for (int j = 0; j < norm_mat.num_columns(); ++j) {
-      complex<float> cur_norm_element = conj(norm_mat_els[0][j]);
-      complex<float> cur_mat_element = mat_els[j][i];
-      first_product += cur_norm_element * cur_mat_element;
+      first_product += conj(norm_mat_els[0][j]) * mat_els[j][i];
     }
     second_product += first_product * norm_mat_els[0][i];
     first_product = 0.f;
@@ -140,6 +138,19 @@
   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
 
 Beamformer::Beamformer(const std::vector<Point>& array_geometry)
@@ -332,8 +343,7 @@
   // angle.
   for (int i = low_average_start_bin_; i < high_average_end_bin_; ++i) {
     eig_m_.CopyFromColumn(input, i, num_input_channels_);
-    float eig_m_norm_factor =
-        std::sqrt(ConjugateDotProduct(eig_m_, eig_m_)).real();
+    float eig_m_norm_factor = std::sqrt(SumSquares(eig_m_));
     if (eig_m_norm_factor != 0.f) {
       eig_m_.Scale(1.f / eig_m_norm_factor);
     }
diff --git a/webrtc/modules/audio_processing/beamformer/matrix.h b/webrtc/modules/audio_processing/beamformer/matrix.h
index e1891b6..3778fdb 100644
--- a/webrtc/modules/audio_processing/beamformer/matrix.h
+++ b/webrtc/modules/audio_processing/beamformer/matrix.h
@@ -76,7 +76,7 @@
 
   // Copies |data| into the new Matrix.
   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);
     scratch_data_.resize(num_rows_ * num_columns_);
     scratch_elements_.resize(num_rows_);
@@ -91,15 +91,8 @@
 
   // Copy |data| into the Matrix. The current data is lost.
   void CopyFrom(const T* const data, int num_rows, int num_columns) {
-    num_rows_ = num_rows;
-    num_columns_ = num_columns;
-    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_];
-    }
+    Resize(num_rows, num_columns);
+    memcpy(&data_[0], data, num_rows_ * num_columns_ * sizeof(data_[0]));
   }
 
   Matrix& CopyFromColumn(const T* const* src, int column_index, int num_rows) {
@@ -112,9 +105,11 @@
   }
 
   void Resize(int num_rows, int num_columns) {
-    num_rows_ = num_rows;
-    num_columns_ = num_columns;
-    Resize();
+    if (num_rows != num_rows_ || num_columns != num_columns_) {
+      num_rows_ = num_rows;
+      num_columns_ = num_columns;
+      Resize();
+    }
   }
 
   // Accessors and mutators.
@@ -136,8 +131,7 @@
   // Matrix Operations. Returns *this to support method chaining.
   Matrix& Transpose() {
     CopyDataToScratch();
-    std::swap(num_rows_, num_columns_);
-    Resize();
+    Resize(num_columns_, num_rows_);
     return Transpose(scratch_elements());
   }
 
@@ -278,8 +272,7 @@
     CHECK_EQ(num_columns_, rhs.num_rows_);
 
     CopyDataToScratch();
-    num_columns_ = rhs.num_columns_;
-    Resize();
+    Resize(num_rows_, rhs.num_columns_);
     return Multiply(scratch_elements(), rhs.num_rows_, rhs.elements());
   }