/// <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 override void Execute(Mtb.Project proj) { // 將資料匯入 Minitab if (_rawdata == null || _rawdata.Rows.Count == 0) { throw new ArgumentNullException("查無對應資料"); } _rptLst = new List <IRptOutput>(); //重新建立一個分析結果列舉 proj.Commands.Delete(); proj.Worksheets.Delete(); Mtb.Worksheet ws = proj.Worksheets.Add(1); //新增工作表 Mtblib.Tools.MtbTools.InsertDataTableToMtbWs(_rawdata, ws); //匯入資料至 Minitab List <Mtb.Column> varCols = new List <Mtb.Column>(); //變數的欄位集合 List <Mtb.Column> bkCols = new List <Mtb.Column>(); //斷絲率的集合 Mtb.Column timeCol = null; for (int i = 0; i < _rawdata.Columns.Count; i++) { DataColumn col = _rawdata.Columns[i]; switch (col.ColumnName) { case "TIMESTAMP": timeCol = ws.Columns.Item(col.ColumnName); break; case "RPT_TIMEHOUR": case "GROUP_ID": case "SITE_ID": break; default: if (col.ColumnName.Substring(0, 2) == "BK") { bkCols.Add(ws.Columns.Item(col.ColumnName)); } else { varCols.Add(ws.Columns.Item(col.ColumnName)); } break; } } foreach (var col in bkCols) { if ((int)col.DataType == 3 || col.MissingCount == col.RowCount) { throw new ArgumentNullException(string.Format("[{0}]查無資料", col.Name)); } } foreach (var col in varCols) { if ((int)col.DataType == 3 || col.MissingCount == col.RowCount) { throw new ArgumentNullException(string.Format("[{0}]查無資料", col.Name)); } } StringBuilder cmnd = new StringBuilder(); /* * Create TSPlot * 該圖會將數據於多個平面中顯示(k*1的方式),所以要先設定 Panel 的安排方式 * */ cmnd.AppendLine("notitle"); cmnd.AppendLine("brief 0"); cmnd.AppendFormat("fdate {0};\r\n", timeCol.SynthesizedName); cmnd.AppendLine("format(dtyyyy-MM-dd hh:mm)."); cmnd.AppendFormat("tsplot {0} {1};\r\n", string.Join(" &\r\n", bkCols.Select(x => x.SynthesizedName)), string.Join(" &\r\n", varCols.Select(x => x.SynthesizedName))); double gHeight = 3; //if (varCols.Count > 3) gHeight = Math.Min(30, 4 + ((double)varCols.Count - 3) * 0.8); cmnd.AppendFormat("graph 8 {0};\r\n", gHeight); string gpath_trend = System.IO.Path.Combine(Environment.GetEnvironmentVariable("tmp"), "Minitab", string.Format("trend_{0}.jpg", _rawdata.TableName)); cmnd.AppendFormat("gsave \"{0}\";\r\n", gpath_trend); cmnd.AppendLine("repl;"); cmnd.AppendLine("jpeg;"); //cmnd.AppendLine("panel;"); //cmnd.AppendFormat("rc {0} 1;\r\n", varCols.Count + bkCols.Count); //cmnd.AppendLine("noal;"); //cmnd.AppendLine("label;"); //cmnd.AppendLine(" psize 5;"); cmnd.AppendLine("scale 1;"); cmnd.AppendLine(" psize 8;"); cmnd.AppendLine("grid 1;"); cmnd.AppendLine("axlab 1;"); cmnd.AppendLine("lshow;"); cmnd.AppendLine(" angle 90;"); cmnd.AppendLine("grid 2;"); cmnd.AppendLine("scale 2;"); cmnd.AppendLine(" psize 8;"); if (timeCol != null && (int)timeCol.DataType != 3) { cmnd.AppendFormat("stamp {0};\r\n", timeCol.SynthesizedName); } cmnd.AppendLine("symb;"); cmnd.AppendLine("conn;"); //cmnd.AppendFormat("foot \"建立時間: {0}\";\r\n", DateTime.Now); cmnd.AppendLine("nodt."); //Create Matrix Plot cmnd.AppendFormat("matrixplot ({0})*({1});\r\n", string.Join(" &\r\n", bkCols.Select(x => x.SynthesizedName)), string.Join(" &\r\n", varCols.Select(x => x.SynthesizedName))); double gWidth = 8; if (varCols.Count > 5) { gWidth = Math.Min(30, 8 + ((double)varCols.Count - 5) * 0.8); } cmnd.AppendFormat("graph {0} 5;\r\n", gWidth); string gpath_corr = System.IO.Path.Combine(Environment.GetEnvironmentVariable("tmp"), "Minitab", string.Format("corr_{0}.jpg", _rawdata.TableName)); cmnd.AppendFormat("gsave \"{0}\";\r\n", gpath_corr); cmnd.AppendLine("repl;"); cmnd.AppendLine("jpeg;"); cmnd.AppendLine("scale 1;"); cmnd.AppendLine(" psize 8;"); cmnd.AppendLine("nojitter;"); cmnd.AppendLine("full;"); cmnd.AppendLine("bound;"); cmnd.AppendLine("noal;"); cmnd.AppendLine("regr;"); cmnd.AppendLine("symb;"); cmnd.AppendLine("nodt."); //Calculate correlation coefficient string[] matIds = Mtblib.Tools.MtbTools.CreateVariableStrArray(ws, 1, Mtblib.Tools.MtbVarType.Matrix); cmnd.AppendFormat("corr {0} {1} {2}\r\n", string.Join(" &\r\n", bkCols.Select(x => x.SynthesizedName)), string.Join(" &\r\n", varCols.Select(x => x.SynthesizedName)), string.Join(" &\r\n", matIds) ); //刪除所有圖形 cmnd.AppendLine("gmana;"); cmnd.AppendLine("all;"); cmnd.AppendLine("close;"); cmnd.AppendLine("nopr."); string fpath = Mtblib.Tools.MtbTools.BuildTemporaryMacro("mymacro.mtb", cmnd.ToString()); proj.ExecuteCommand(string.Format("exec \"{0}\" 1", fpath), ws); //將檔案轉為二進位陣列 string _root = System.IO.Path.Combine(Environment.GetEnvironmentVariable("tmp"), "Minitab", string.Format("trend_{0}", _rawdata.TableName)); string _file; for (int i = 0; i < bkCols.Count + varCols.Count; i++) { _file = _root + (i + 1).ToString("D3") + ".jpg"; if (File.Exists(_file)) { this.Contents.Add(new RptOutput() { OType = MtbOType.GRAPH, OutputInByteArr = File.ReadAllBytes(_file), Tag = "Trend" }); } } //if (File.Exists(gpath_trend)) //{ // this.Contents.Add(new RptOutput() // { // OType = MtbOType.GRAPH, // OutputInByteArr = File.ReadAllBytes(gpath_trend), // Tag = "Trend" // }); //} if (File.Exists(gpath_corr)) { this.Contents.Add(new RptOutput() { OType = MtbOType.GRAPH, OutputInByteArr = File.ReadAllBytes(gpath_corr), Tag = "Scatter" }); } //Create Correlation table DataTable corrTable = new DataTable(); corrTable.Columns.Add("熔爐項目", typeof(string)); foreach (Mtb.Column col in bkCols) { corrTable.Columns.Add(col.Name, typeof(double)); } //corrTable.Columns.Add("CorrCoef", typeof(double)); var corrMat = ws.Matrices.Item(matIds[0]).GetData(); //取出 correlation matrix var mBuilder = LinearAlgebra.Matrix <double> .Build; LinearAlgebra.Matrix <double> corM = mBuilder.DenseOfColumnMajor(bkCols.Count + varCols.Count, bkCols.Count + varCols.Count, corrMat); LinearAlgebra.Matrix <double> subCorrMat = corM.SubMatrix(bkCols.Count, varCols.Count, 0, bkCols.Count); string[] labNames = varCols.Select(x => x.Name).ToArray(); List <object> itemArray; DataRow dr; for (int i = 0; i < varCols.Count; i++) { itemArray = new List <object>(); itemArray.Add(labNames[i]); itemArray.AddRange(subCorrMat.Row(i).ToArray().Select(x => (object)Math.Round(x, 3)).ToArray()); //dr = corrTable.NewRow(); //dr.ItemArray = itemArray; corrTable.Rows.Add(itemArray.ToArray()); } //double[] subCorr = new double[varCols.Count]; //double[] corr = corrMat as double[]; //if (corr != null) //{ // Array.Copy(corr, 1, subCorr, 0, varCols.Count); // // DataRow dr; // for (int i = 0; i < subCorr.Length; i++) // { // dr = corrTable.NewRow(); // dr[0] = labNames[i]; // dr[1] = subCorr[i]; // corrTable.Rows.Add(dr); // } //} this.Contents.Add(new RptOutput() { OType = MtbOType.TABLE, OutputInByteArr = Tool.ConvertDataSetToByteArray(corrTable), Tag = "Table" }); }