/// <summary> /// Returns the nxn outer product of two nd-vectors, or [v1]^T*[v2].\ O(n). /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> /// <returns></returns> public static MatrixFixed OuterProduct(Vector v1, Vector v2) { MatrixFixed outp = new MatrixFixed(v1.size(), v2.size()); for (int i = 0; i < outp.Rows; i++) // v1.column() * v2.row() for (int j = 0; j < outp.Columns; j++) outp[i,j] = v1[i] * v2[j]; return outp; }
/// <summary> /// Solve the matrix-vector system M x = y, returning x. /// </summary> /// <param name="y"></param> /// <returns></returns> public Vector Solve(Vector y) { // fsm sanity check : if (y.size() != U_.Rows) { Debug.WriteLine("__FILE__ : size of rhs is incompatible with no. of rows in U_ " + "y =" + Convert.ToString(y) + "\n" + "m_=" + Convert.ToString(m_) + "\n" + "n_=" + Convert.ToString(n_) + "\n" + "U_=\n" + Convert.ToString(U_) + "V_=\n" + Convert.ToString(V_) + "W_=\n" + W_); } Vector x = new Vector(V_.Rows); // Solution matrix. if (U_.Rows < U_.Columns) { // Augment y with extra rows of Vector yy = new Vector(U_.Rows); // zeros, so that it matches yy.Fill(0); if (yy.size() < y.size()) { // fsm Debug.WriteLine("yy=" + Convert.ToString(yy)); Debug.WriteLine("y =" + Convert.ToString(y)); // the update() call on the next line will abort... } yy.Update(y); // cols of u.transpose. x = U_.ConjugateTranspose() * yy; } else x = U_.ConjugateTranspose() * y; for (int i = 0; i < x.size(); i++) { // multiply with diagonal 1/W float weight = W_[i, i], zero_ = 0.0f; if (weight != zero_) x[i] /= weight; else x[i] = zero_; } return V_ * x; // premultiply with v. }
/// <summary> /// Replaces elements with index begining at start, by values of v. /// </summary> /// <param name="v"></param> /// <param name="start"></param> /// <returns></returns> public Vector Update (Vector v, int start) { int end = start + v.size(); if ((start < data.Length) && (end <= data.Length)) { for (int i = start; i < end; i++) { data[i] = v.data[i - start]; } } return this; }