/// <summary> /// Estimates the least squares coefficients for the regression formula: Y = a + bX_1 + cX_2 + ... + dX_k /// </summary> /// <typeparam name="T">The type of observation values and the regression coefficients.</typeparam> /// <typeparam name="C">The calculator for the observations' value type.</typeparam> /// <param name="observationRows">The matrix of observations having rows in the following format: X_11 | X_12 | ... | X_1K | Y_1</param> /// <returns>The vector of estimated least squares regression coefficients. Its first term is a free term, and all the following terms correspond to X_1, X_2 etc. up to X_k</returns> public static Vector <T, C> EstimateLeastSquaresCoefficients <T, C>(Matrix <T, C> observationRows) where C : ICalc <T>, new() { Matrix <T, C> xMatrix = new Matrix_SDA <T, C>(observationRows.RowCount, observationRows.ColumnCount); Matrix <T, C> yVector = observationRows.getSubMatrixAt(0, observationRows.ColumnCount - 1); for (int i = 0; i < xMatrix.RowCount; i++) { xMatrix[i, 0] = Numeric <T, C> ._1; for (int j = 1; j < xMatrix.ColumnCount; j++) { xMatrix[i, j] = observationRows[i, j - 1]; } } // TODO: transposition should NOT create a new matrix. // write a new matrix class Matrix <T, C> xTransposed = xMatrix.transposedMatrixCopy(); Matrix <T, C> result = (xTransposed * xMatrix).inverseMatrix_LUP_Factorization() * xTransposed * yVector; IWinder winder = result.GetRowByRowWinder(); return(result.unwindToArray(winder)); }
/// <summary> /// Winds a flat array onto current using the IWinder object. /// The IWinder object is automatically reset before winding. /// IWinder object and current matrix should be have the same dimension (i.e. row count and column count). /// </summary> /// <param name="winder">An IWinder object. Row and column count should match with current matrix.</param> /// <param name="flatMatrix">A single-dimension matrix. Element count should match with current matrix.</param> public void windFromArray(IWinder winder, T[] flatMatrix) { if (flatMatrix.Length != this.ElementCount) { throw new ArgumentException("The element count of the current matrix and the element count of the flat matrix must match."); } winder.reset(); for (int i = 0; i < this.ElementCount; i++) { this[winder.getNextIndexPair()] = flatMatrix[i]; } }
// ------------------------------------------------------------------------------ // -----------------------------WINDING capabilities----------------------------- public T[] unwindToArray(IWinder winder) { T[] temp = new T[this.ElementCount]; winder.reset(); for (int i = 0; i < this.ElementCount; i++) { temp[i] = this[winder.getNextIndexPair()]; } return(temp); }