```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

```
```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());
}

```