/// <summary> /// 計算多變量管制圖的 Tsquare decomposition /// </summary> /// <param name="data"></param> /// <param name="mean"></param> /// <param name="S"></param> /// <returns></returns> public static LinearAlgebra.Matrix <double> T2Decomposition(LinearAlgebra.Matrix <double> data, LinearAlgebra.Matrix <double> mean, LinearAlgebra.Matrix <double> S) { //mean 的 #column = #columns of data = #columns of covariance if (data.ColumnCount != mean.ColumnCount || data.ColumnCount != S.ColumnCount || mean.ColumnCount != S.ColumnCount) { throw new ArgumentException("矩陣的維度無法計算"); } LinearAlgebra.Matrix <double> invS = S.Inverse(); List <double> tsquare = new List <double>(); for (int i = 0; i < data.RowCount; i++) { tsquare.Add(CalculateTSquare(data.Row(i).ToRowMatrix(), mean, invS)); } List <double> decoValue = new List <double>(); for (int c = 0; c < data.ColumnCount; c++) { LinearAlgebra.Matrix <double> subData = data.RemoveColumn(c); LinearAlgebra.Matrix <double> subMean = mean.RemoveColumn(c); LinearAlgebra.Matrix <double> subS = S.RemoveColumn(c).RemoveRow(c); LinearAlgebra.Matrix <double> invSubS = subS.Inverse(); for (int r = 0; r < data.RowCount; r++) { decoValue.Add(tsquare[r] - CalculateTSquare(subData.Row(r).ToRowMatrix(), subMean, invSubS)); } } LinearAlgebra.Matrix <double> m = LinearAlgebra.Matrix <double> .Build.DenseOfColumnMajor(data.RowCount, data.ColumnCount, decoValue); return(m); }
public LinearAlgebra.Vector <double> solveEquations(LinearAlgebra.Matrix <double> stiffnessMatrix, LinearAlgebra.Vector <double> forceVector, List <int> boundaryDofs, List <double> boundaryConstraints) { int nDof = forceVector.Count; // Find all dofs where force is known List <int> allDofs = Enumerable.Range(0, nDof).ToList(); List <int> unknownDofs = allDofs.Except(boundaryDofs).ToList(); // Add the know displacements to the result LinearAlgebra.Vector <double> displacementVector = LinearAlgebra.Vector <double> .Build.Dense(nDof); for (int i = 0; i < boundaryDofs.Count; i++) { displacementVector[boundaryDofs[i]] = boundaryConstraints[i]; } // Pick out part of matrix corresponding to known forces int nrUnknownDofs = unknownDofs.Count; LinearAlgebra.Matrix <double> unknownK = LinearAlgebra.Matrix <double> .Build.Dense(nrUnknownDofs, nrUnknownDofs); LinearAlgebra.Vector <double> knownForces = LinearAlgebra.Vector <double> .Build.Dense(unknownDofs.Count); for (int i = 0; i < unknownDofs.Count; i++) { for (int j = 0; j < unknownDofs.Count; j++) { unknownK[i, j] = stiffnessMatrix[unknownDofs[i], unknownDofs[j]]; } knownForces[i] = forceVector[unknownDofs[i]]; } LinearAlgebra.Matrix <double> unkownKnownK = LinearAlgebra.Matrix <double> .Build.Dense(nrUnknownDofs, boundaryDofs.Count); for (int i = 0; i < unknownDofs.Count; i++) { for (int j = 0; j < boundaryDofs.Count; j++) { unkownKnownK[i, j] = stiffnessMatrix[unknownDofs[i], boundaryDofs[j]]; } knownForces[i] = forceVector[unknownDofs[i]]; } // Solve for the unknown displacements LinearAlgebra.Vector <double> unknownDisplacements = unknownK.Inverse().Multiply(knownForces.Subtract(unkownKnownK.Multiply(LinearAlgebra.Vector <double> .Build.Dense(boundaryConstraints.ToArray())))); // Insert the calculated displacements for (int i = 0; i < unknownDofs.Count; i++) { displacementVector[unknownDofs[i]] = unknownDisplacements[i]; } return(displacementVector); }