/// <summary> /// 积分小波函数 /// </summary> /// <param name="type"></param> /// <param name="wname"></param> /// <param name="precis"></param> public static WavefunModel Intwave(WaveletsInfoModel infoModel, string wname, int precis) { WavefunModel wf = null; try { wf = WavemngrUtil.Wavefun(wname, infoModel, precis); if (wf != null) { int type = infoModel.type; List <double> xval = wf.xval, psi = wf.psi; if (xval != null && xval.Count > 1) { double step = wf.step = xval[1] - xval[0], temp = 0; if (type == 1 || type == 3 || type == 4 || type == 5) { List <double> out1 = new List <double>(); for (int i = 0; i < psi.Count; i++) { temp += psi[i]; out1.Add(temp * step); } wf.out1 = out1; return(wf); } } } } catch (Exception ex) { var sd = ex; } return(null); }
/// <summary> /// 计算以wname命名的母小波的中心频率 /// </summary> /// <param name="wname">小波名称</param> /// <param name="iter">迭代次数</param> /// <returns></returns> public static WaveletsInfoModel CentFrq(string wname, int iter = 8) { WaveletsInfoModel infoModel = WavemngrUtil.Command("type", wname); if (infoModel != null) { try { WavefunModel wf = WavemngrUtil.Wavefun(wname, infoModel, iter); if (wf != null) { List <double> xval = wf.xval, psi = wf.psi; double T = xval.Max() - xval.Min(), meanpsi = psi.Average(); int n = psi.Count; var sdsd = psi.Max(); psi = psi.Select(m => m - meanpsi).ToList(); ///-----------------------------要修改 Complex[] sdsw = new Complex[n]; Complex[] sdswo = new Complex[n]; for (int j = 0; j < n; j++) { sdsw[j] = new Complex(psi[j], 0); } var input = new PinnedArray <Complex>(sdsw); var output = new PinnedArray <Complex>(sdswo); List <double> sp = new List <double>(); DFT.FFT(input, output); int len = output.Buffer.Length; for (int i = 0; i < len; i++) { Complex val = (Complex)output.Buffer.GetValue(i); sp.Add(Math.Sqrt(val.Real * val.Real + val.Imaginary * val.Imaginary)); } double vmax = sp.Max(); //最大值 int indmax = sp.IndexOf(vmax); //下标 if (indmax > (double)n / 2) { indmax = n - indmax; } infoModel.centerfc = (double)indmax / T; } } catch (Exception ex) { } //switch (wtype) //{ // case 1: // break; // case 2: // break; // case 3: // break; // case 4: // break; // case 5: // break; // default: // break; //} } return(infoModel); }
/// <summary> /// 操作 /// </summary> /// <param name="option">操作代号</param> /// <param name="wname">小波名称</param> public static WaveletsInfoModel Command(string option, string wname) { WaveletsInfoModel varargout = new WaveletsInfoModel(); if (string.IsNullOrEmpty(option) || string.IsNullOrEmpty(wname)) { return(varargout); } try { List <WaveletsInfoModel> infos = varargout.GetWaveletsInfos(); int okwave = 0, addnum = 0; if (infos != null && infos.Any()) { switch (option) { case "type": goto case "indw"; case "indw": int nbfam = infos.Count, lwna = wname.Length, globalifam = 0; //info长度,wname长度 for (int ifam = 0; ifam < nbfam; ifam++) { globalifam = ifam; string fam = infos[ifam].familyShortName; //familyShortName if (fam != null) { int len = fam.Length; if (lwna >= len) { if (fam == wname.Substring(0, len)) { string[] tabNums = infos[ifam].tabNums; string numstr = ""; if (tabNums != null && tabNums.Any()) { for (int inum = 0; inum < tabNums.Count(); inum++) { numstr = tabNums[inum]; if ("no".Equals(numstr)) { numstr = ""; } if (wname.Equals(fam + numstr)) { okwave = 1; break; } } //% test for ** number if (okwave == 0 && "**".Equals(numstr) && (lwna > len)) { string typNums = infos[ifam].typNums; numstr = wname.Substring(len + 1, lwna); switch (typNums) { case "integer": double numi = Convert.ToDouble(numstr); double numex = numi < 0 ? Math.Ceiling(numi) : Math.Floor(numi); if ((numi == numex) && (0 < numi)) { okwave = 1; } addnum = 1; break; case "real": int num = Convert.ToInt32(numstr); if (num >= 0) { okwave = 1; } addnum = 1; break; case "string": okwave = 1; addnum = 1; break; default: break; } } } } } if (okwave == 1) { break; } } } if (okwave == 1) { varargout = infos[globalifam]; } //varargout.Add(globalinum); break; case "fields": goto case "indw"; default: break; } } } catch (Exception ex) { throw ex; } return(varargout); }
/// <summary> /// 连续小波变换 /// </summary> /// <param name="sig">输入信号</param> /// <param name="scals">尺度</param> /// <param name="wname">小波名称</param> /// <returns></returns> public static CWTModel CWT(List <double> sig, int totalscal, string wname, double dt) { CWTModel cwtModel = new CWTModel(); try { if (sig != null && sig.Any() && totalscal > 0) { int lenSIG = sig.Count, stepSIG = 1; WaveletsInfoModel fc = TransformUtil.CentFrq(wname);//获取中心频率 if (fc != null) { double cff = 2 * fc.centerfc * totalscal; List <double> scals = new List <double>(); for (int i = 1; i <= totalscal; i++) { scals.Add(cff / i); } cwtModel.scal2frq = TransformUtil.Scal2Frq(scals, fc.centerfc, dt);//尺度转频率 List <int> xSIG = Enumerable.Range(1, lenSIG).ToList(); WavefunModel wave = TransformUtil.Intwave(fc, wname, 10); if (wave != null) { List <double> valWAV = wave.out1, xWAV = wave.xval; if (xWAV != null && xWAV.Any()) { double xwav = xWAV[0]; xWAV = xWAV.Select(m => m - xwav).ToList(); double xMaxWAV = xWAV.Last(); int nbSCALES = scals.Count; List <List <double> > coefs = new List <List <double> >(); for (int k = 0; k < nbSCALES; k++) { double a = scals[k]; double aSIG = a / stepSIG; double ax = aSIG * xMaxWAV; List <double> re = new List <double>(); for (double i = ax; i >= 0; i--) { re.Add(valWAV[(int)Math.Floor(i / (aSIG * wave.step))]); } if (re.Count == 1) { re = new List <double> { 1, 1 } } ; List <double> wn = Wconv1(sig, re); if (wn != null && wn.Any()) { int count = wn.Count; for (int i = 0; i < count - 1; i++) { wn[i] = wn[i + 1] - wn[i]; } wn.RemoveAt(count - 1); coefs.Add(Wkeep1(wn, lenSIG, "c").Select(m => m * (-Math.Sqrt(a))).ToList()); } } cwtModel.cwt = coefs; } } } } } catch (Exception ex) { throw ex; } return(cwtModel); }
/// <summary> /// 小波基函数 /// </summary> /// <param name="wname">小波名称</param> /// <param name="infoModel">小波信息</param> /// <param name="iter">迭代次数</param> public static WavefunModel Wavefun(string wname, WaveletsInfoModel infoModel, int iter) { WavefunModel data = new WavefunModel(); if (!string.IsNullOrEmpty(wname)) { string debut = wname.Substring(0, 2); double coef = Math.Pow(Math.Sqrt(2), iter), pas = (double)1 / Math.Pow(2, iter); switch (infoModel.type) { case 1: DWT dwt = new DWT(wname); int logn = dwt.Lo_R.Count; int nbpts = Convert.ToInt32((logn - 1) / pas + 1); List <double> psi = DWTUtil.Upcoef("d", dwt, iter); if (psi != null && psi.Any()) { psi = psi.Select(m => m * coef).ToList(); } List <int> result = GetNBpts(nbpts, iter, logn); //nbpts、nb、dn int nb = result[1], dn = result[2] + 1; nbpts = result[0]; DWTUtil.Wkeep1(psi, nb, "c"); psi.Insert(0, 0); for (int i = 1; i <= dn; i++) { psi.Add(0); } //sign depends on wavelet if ("co".Equals(debut) || "sy".Equals(debut) || "dm".Equals(debut)) { psi = psi.Select(m => - m).ToList(); } //data.phi = phi; data.psi = psi; data.type = infoModel.type; data.xval = Linspace(0, (nbpts - 1) * pas, nbpts); break; case 2: break; case 3: break; case 4: data = Morlet(infoModel.bounds[0], infoModel.bounds[1], (int)Math.Pow(2, iter)); break; case 5: break; default: break; } } return(data); }