List <int> MoveWindowFunc(double[] samples, int width, int interval)//滑窗法进行筛选 { int index = 0; List <int> list = new List <int>(); do { double[] temp_samp = new double[width];//临时样本 bool isQualified = false; for (int i = 0; i < width; i++) { temp_samp[i] = samples[index + i]; } double means = temp_samp.Mean(); for (int i = 0; i < width; i++) { temp_samp[i] -= means; } ParaVec paraVec = ComputeParaVec(temp_samp); if (paraVec.tao1 < -1.95)//-1.95 -2.89 -3.45 { isQualified = true; } if (index >= 300) { ; } if (isQualified)///如果窗口合格 { for (int j = 0; j < width; j++) { if (!list.Contains(j + index)) { list.Add(j + index); } } } index += interval; if (index + width > samples.Count()) { break; } }while (true); return(list); }
private void OnCompute(object sender, RoutedEventArgs args) { try { ParaList = ReadXml(@"..\..\ParaXml.xml"); //读取xml文档 FileStream file = new FileStream("file.txt", FileMode.Create); ///创建文件用于存放稳态工况数据 StreamWriter writer = new StreamWriter(file); writer.WriteLine("创建日期" + DateTime.Now.ToString()); writer.Flush(); List <DateTime> timeList = new List <DateTime>(); //存放稳态工况的时间点 string strStart = ((DateTime)StartDate.SelectedDate).ToString("yyyy-MM-dd"); ///开始时间字符串 string strEnd = ((DateTime)EndDate.SelectedDate).ToString("yyyy-MM-dd"); //结束时间字符串 DateTime loopTime = (DateTime)StartDate.SelectedDate; ///开始时间,用于循环 DateTime EndTime = (DateTime)EndDate.SelectedDate; //结束时间 ////从参数表中取出参数详细信息 DataTable measure_dt = QueryData("select id,name,saveindex from tb_nx_measure"); string strSql = "select cytime"; foreach (ParameterSetting childParameter in ParaList)///查找存储索引并构建字符串 { var re = from h in measure_dt.AsEnumerable() where h.Field <string>("name") == childParameter.name select Convert.ToInt32(h.Field <object>("saveindex")); if (re == null) { throw new Exception("结果为null"); } if (re.Count() != 1) { throw new Exception("未找到指定参数"); } foreach (int d in re) { childParameter.saveindex = d; strSql += ",V"; strSql += d.ToString(); } } strSql = strSql + " from tb_nx_his_run where cytime between '" + strStart + "' and '" + strEnd + "'"; //完成对字符串的构建 DataTable data_dt = QueryData(strSql); ///查询指定时间内的数据 TimeSpan Windowspan = new TimeSpan(0, ParaList[0].time, 0); ///窗口宽度/min TimeSpan Scannspan = new TimeSpan(0, int.Parse(扫描间隔.Text), 0); ///扫描间隔/min do { DateTime tempEndTime = loopTime + Windowspan; var re2 = from h in data_dt.AsEnumerable() let tempTime = Convert.ToDateTime(h.Field <string>("cytime")) where tempTime >= loopTime && tempTime < tempEndTime select h; bool isQualified = true; //先假设该窗口合格 //单纯的稳态判别方式 //for(int index=0;index<ParaList.Count();index++) //{ // double max = re2.Max(x => Convert.ToDouble(x.Field<object>(index+1))); // double min = re2.Min(x => Convert.ToDouble(x.Field<object>(index+1))); // if(ParaList[index].type==0) // { // if (Math.Abs(max - min) > ParaList[index].value) // { // isQualified = false; // break; // } // } // if (ParaList[index].type == 1) // { // if (Math.Abs(max - min)/max > ParaList[index].value) // { // isQualified = false; // break; // } // } //} ///DF检验判别方式 double[] samples = new double[re2.Count()];//新建指定宽度窗口内的样本 for (int index = 0; index < re2.Count(); index++) { samples[index] = Convert.ToDouble(re2.ElementAt(index).Field <object>(1)); } ParaVec paraVec = ComputeParaVec(GenerateDataFromData(samples)); if (paraVec.tao1 > -2.86) { isQualified = false; } if (isQualified)///如果窗口合格 { foreach (var d in re2) { DateTime temp_time = Convert.ToDateTime(d.Field <string>("cytime")); if (!timeList.Contains(temp_time)) { timeList.Add(temp_time); } } } loopTime += Scannspan; ///将循环时间增加一个扫面时间间隔 if (loopTime > (EndTime - Windowspan)) ///如果循环时间不足以进行下一次的计算,则推出循环 { break; } }while (true); writer.WriteLine("共" + timeList.Count + "条记录,占比" + timeList.Count + "/" + data_dt.Rows.Count + "=" + ((double)timeList.Count / data_dt.Rows.Count)); //foreach (DateTime date in timeList) //{ // var re3 = from h in data_dt.AsEnumerable() // let tempTime = Convert.ToDateTime(h.Field<string>("cytime")) // where tempTime == date // select Convert.ToDouble(h.Field<object>(1)); // foreach (double d in re3) // { // writer.WriteLine(date.ToString("yyyy-MM-dd HH:mm:ss") + "\t" + d.ToString()); // } //} //writer.Flush(); //writer.Close(); //file.Close(); foreach (DataRow row in data_dt.Rows) { DateTime tempTime = Convert.ToDateTime(row.Field <string>("cytime"));//取出时间 string temp_str = tempTime.ToString("yyyy-MM-dd HH:mm:ss"); for (int i = 1; i < data_dt.Columns.Count; i++) { temp_str = temp_str + "\t" + row.Field <object>(i).ToString(); } if (timeList.Contains(tempTime)) { writer.WriteLine(temp_str); } else { writer.WriteLine(); } writer.Flush(); } file.Close(); MessageBox.Show("共" + timeList.Count + "条记录,占比" + timeList.Count + "/" + data_dt.Rows.Count + "=" + ((double)timeList.Count / data_dt.Rows.Count)); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
//一阶含常数无趋势自回归DF检验 ParaVec ComputeParaVec(double[] samples) { int mCount = samples.Count(); //定义矩阵系数 double a11 = 0; double a12 = 0; double a13 = 0; double a21 = 0; double a22 = 0; double a23 = 0; double a31 = 0; double a32 = 0; double a33 = 0; ///定义向量 double b1 = 0; double b2 = 0; double b3 = 0; ///定义解向量 double c1 = 0; double c2 = 0; double c3 = 0; for (int index = 1; index < mCount; index++) { a11++; a12 += samples[index - 1]; a13 += (index + 1); a22 += samples[index - 1] * samples[index - 1]; a23 += (index + 1) * samples[index - 1]; a33 += (index + 1) * (index + 1); b1 += samples[index]; b3 += (index + 1) * samples[index]; b2 += samples[index - 1] * samples[index]; } a21 = a12; a31 = a13; a32 = a23; ParaVec paraVec = new ParaVec();//新建参数向量矩阵 //情形1 { double[,] aMatrix = new double[1, 1]; aMatrix[0, 0] = a22; double[] bMatrix = new double[1]; bMatrix[0] = b2; double[] cMatrix = new double[1]; cMatrix = Matrix.Multiply(aMatrix.Inverse(), bMatrix);//计算参数向量 paraVec.fai1 = cMatrix[0]; double squre = aMatrix.Inverse()[0, 0]; double s2t = 0; for (int index = 1; index < mCount; index++) { paraVec.sigma21 += Math.Pow((samples[index] - paraVec.fai1 * samples[index - 1]), 2); } s2t = paraVec.sigma21 + samples[0] * samples[0]; paraVec.sigma21 /= mCount - 1; s2t /= mCount - 1; paraVec.tao1 = (paraVec.fai1 - 1) / Math.Sqrt(s2t * squre); paraVec.rou1 = samples.Count() * (paraVec.fai1 - 1); } //情形2 { double[,] aMatrix = new double[2, 2]; aMatrix[0, 0] = a11; aMatrix[0, 1] = a12; aMatrix[1, 0] = a21; aMatrix[1, 1] = a22; double[] bMatrix = new double[2]; bMatrix[0] = b1; bMatrix[1] = b2; double[] cMatrix = new double[2]; cMatrix = Matrix.Multiply(aMatrix.Inverse(), bMatrix);//计算参数向量 paraVec.miu2 = cMatrix[0]; paraVec.fai2 = cMatrix[1]; paraVec.sigma22 = 0; double[] xishu = new double[] { 0, 1 }; double squre = xishu.Multiply(aMatrix.Inverse()).Multiply(xishu.Transpose())[0]; double s2t = 0; for (int index = 1; index < mCount; index++) { paraVec.sigma22 += Math.Pow((samples[index] - paraVec.miu2 - paraVec.fai2 * samples[index - 1]), 2); // squre += Math.Pow(samples[index - 1], 2); } s2t = paraVec.sigma22 + (samples[0] - paraVec.miu2) * (samples[0] - paraVec.miu2); paraVec.sigma22 /= mCount - 1; s2t /= mCount - 1; paraVec.tao2 = (paraVec.fai2 - 1) / Math.Sqrt(s2t * squre); paraVec.rou2 = samples.Count() * (paraVec.fai2 - 1); } //情形3 { double[,] aMatrix = new double[3, 3]; aMatrix[0, 0] = a11; aMatrix[0, 1] = a12; aMatrix[0, 2] = a13; aMatrix[1, 0] = a21; aMatrix[1, 1] = a22; aMatrix[1, 2] = a23; aMatrix[2, 0] = a31; aMatrix[2, 1] = a32; aMatrix[2, 2] = a33; double[] bMatrix = new double[3]; bMatrix[0] = b1; bMatrix[1] = b2; bMatrix[2] = b3; double[] cMatrix = new double[3]; cMatrix = Matrix.Multiply(aMatrix.Inverse(), bMatrix);//计算参数向量 paraVec.miu3 = cMatrix[0]; paraVec.fai3 = cMatrix[1]; paraVec.beta3 = cMatrix[2]; double[] xishu = new double[] { 0, 1, 0 }; double squre = xishu.Multiply(aMatrix.Inverse()).Multiply(xishu.Transpose())[0]; double s2t = 0; for (int index = 1; index < mCount; index++) { paraVec.sigma23 += Math.Pow((samples[index] - paraVec.miu3 - paraVec.beta3 * (index + 1) - paraVec.fai3 * samples[index - 1]), 2); // squre += Math.Pow(samples[index - 1], 2); } s2t = paraVec.sigma23 + (samples[0] - paraVec.miu3) * (samples[0] - paraVec.miu3); paraVec.sigma23 /= mCount - 1; s2t /= mCount - 1; paraVec.tao3 = (paraVec.fai3 - 1) / Math.Sqrt(s2t * squre); paraVec.rou3 = samples.Count() * (paraVec.fai3 - 1); } return(paraVec); }