/// <summary> /// Finds and returns a list of commands matching the specified filters by the specified condition. /// <para>Available filters: SimpleCommandScanner (Equals/NotEquals), StringCommandScanner (Contains/NotContains), ListCommandScanner (Contains/NotContains)</para> /// <param name="condition">If condition is FindCondition.And, returns is <see langword="true"/> if all filters are true. /// If condition is FindCondition.Or, returns is <see langword="true"/> if one of filters is true</param> /// </summary> public static List <Command> Find(FindCondition condition, params CommandScanner[] filters) { List <Command> foundCommands = new List <Command>(); foreach (Command command in Commands) { foreach (CommandScanner commandScanner in filters) { if (condition == FindCondition.And) { if (commandScanner.Scan(command) == false) { break; } else if (filters.Last() == commandScanner) { foundCommands.Add(command); } } else { if (commandScanner.Scan(command) == true && !foundCommands.Contains(command)) { foundCommands.Add(command); } } } } return(foundCommands); }
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { FindCondition condition = (FindCondition)e.Argument; GetCandidatesDelegate[] d = new GetCandidatesDelegate[threadTotal]; IAsyncResult[] ar = new IAsyncResult[threadTotal]; Candidate[][] c = new Candidate[threadTotal][]; for (int i = 0; i < threadTotal; i++) { d[i] = new GetCandidatesDelegate(GetCandidatesForThread); } int counter = 0; int lastCounter = 0; Random r = new Random(); int tryNumber = 1000; while (!backgroundWorker.CancellationPending) { counter += threadTotal * tryNumber; for (int i = 0; i < threadTotal; i++) { ar[i] = d[i].BeginInvoke(condition, r.Next(), tryNumber, ref c[i], null, null); //各スレッド起動転送 } for (int i = 0; i < threadTotal; i++) //スレッド終了待ち { d[i].EndInvoke(ref c[i], ar[i]); for (int j = 0; j < c[i].Length; j++) { Candidates.Add(c[i][j]); } } if (counter - lastCounter > 20000 || Candidates.Count > 1200) { lastCounter = counter; Candidates.Sort(); for (int i = 0; i < Candidates.Count - 1; i++) { if (Candidates[i].A == Candidates[i + 1].A && Candidates[i].B == Candidates[i + 1].B && Candidates[i].C == Candidates[i + 1].C && Candidates[i].Alpha == Candidates[i + 1].Alpha && Candidates[i].Beta == Candidates[i + 1].Beta && Candidates[i].Gamma == Candidates[i + 1].Gamma) { Candidates.RemoveAt(i-- + 1); } } if (Candidates.Count > 300) { Candidates.RemoveRange(300, Candidates.Count - 300); } backgroundWorker.ReportProgress(counter, Candidates.ToArray()); } } }
public T FirstConfig <T>(FindCondition <T> conditon) where T : JSONConfigBase { TryToLoad <T>(); var ty = typeof(T); T[] list; if (configs.ContainsKey(ty)) { list = configs[ty].Values.ToArray() as T[]; return(list.FirstOrDefault(t => conditon(t))); } return(default(T)); }
public LinkedList <Sweet> findSomeSweets(FindCondition condition) { LinkedList <Sweet> resSweets = new LinkedList <Sweet>(); foreach (Sweet s in this.Sweets) { if (condition(s)) { resSweets.AddLast(s); } } return(resSweets); }
private Candidate[] GetCandidates(FindCondition condition, int seed, int tryNumber) { Random r = new Random(seed); List <Candidate> c = new List <Candidate>(); for (int i = 0; i < tryNumber && !backgroundWorker.CancellationPending; i++) { Candidate temp = FindCellParameter(condition, r.Next()); if (temp.R < 1000) { c.Add(temp); } } return(c.ToArray()); }
public T[] GetConfigs <T>(FindCondition <T> condtion) where T : JSONConfigBase { TryToLoad <T>(); var ty = typeof(T); var list = new List <T>(16); if (configs.ContainsKey(ty)) { var values = configs[ty].Values; foreach (var i in values) { list.Add(i as T); } return(list.Where(t => condtion(t)).ToArray()); } return(new T[0]); }
private Candidate GetResidualValue(Candidate c, FindCondition condition, int seed) { Random r = new Random(seed); double SinAlpha = Math.Sin(c.Alpha); double SinBeta = Math.Sin(c.Beta); double SinGamma = Math.Sin(c.Gamma); double CosAlpha = Math.Cos(c.Alpha); double CosBeta = Math.Cos(c.Beta); double CosGamma = Math.Cos(c.Gamma); double a2 = c.A * c.A; double b2 = c.B * c.B; double c2 = c.C * c.C; double sigma11 = b2 * c2 * SinAlpha * SinAlpha; double sigma22 = c2 * a2 * SinBeta * SinBeta; double sigma33 = a2 * b2 * SinGamma * SinGamma; double sigma23 = a2 * c.B * c.C * (CosBeta * CosGamma - CosAlpha); double sigma31 = c.A * b2 * c.C * (CosGamma * CosAlpha - CosBeta); double sigma12 = c.A * c.B * c2 * (CosAlpha * CosBeta - CosGamma); double CellVolumeSqure = a2 * b2 * c2 * (1 - CosAlpha * CosAlpha - CosBeta * CosBeta - CosGamma * CosGamma + 2 * CosAlpha * CosBeta * CosGamma); //検索する指数範囲を設定 int hMax = Math.Min((int)(c.A / (condition.SortedD[condition.SortedD.Length - 1].D * 0.9)), 30); int kMax = Math.Min((int)(c.B / (condition.SortedD[condition.SortedD.Length - 1].D * 0.9)), 30); int lMax = Math.Min((int)(c.C / (condition.SortedD[condition.SortedD.Length - 1].D * 0.9)), 30); Plane[] obs = new Plane[condition.SortedD.Length]; for (int i = 0; i < obs.Length; i++) { obs[i] = condition.SortedD[i]; } //計算上のd値を格納するリストを定義 List <Plane> calcPlanes = new List <Plane>(); //観測値が計算値のどの配列位置か対応付ける整数配列を定義 int[] obsToCalcIndex = new int[condition.SortedD.Length]; //まず結晶系を判定 switch (condition.CrystalSystem) { case 0: //triclinic for (int h = 0; h <= hMax; h++) { for (int k = -kMax; k <= kMax; k++) { for (int l = -lMax; l <= lMax; l++) { if (!(h == 0 && k == 0 && l == 0)) { calcPlanes.Add(new Plane(Math.Sqrt(1.0 / (h * h * sigma11 + k * k * sigma22 + l * l * sigma33 + 2 * k * l * sigma23 + 2 * l * h * sigma31 + 2 * h * k * sigma12) * CellVolumeSqure), h, k, l, 0, 0)); } } } } break; case 1: //monoclinic for (int h = 0; h <= hMax; h++) { for (int k = 0; k <= kMax; k++) { for (int l = h == 0 ? 0 : -lMax; l <= lMax; l++) { if (!(h == 0 && k == 0 && l == 0)) { calcPlanes.Add(new Plane(Math.Sqrt(1.0 / (h * h * sigma11 + k * k * sigma22 + l * l * sigma33 + 2 * k * l * sigma23 + 2 * l * h * sigma31 + 2 * h * k * sigma12) * CellVolumeSqure), h, k, l, 0, 0)); } } } } break; case 2: //orthorhombic for (int h = 0; h <= hMax; h++) { for (int k = 0; k <= kMax; k++) { for (int l = h + k == 0 ? 1 : 0; l <= lMax; l++) { calcPlanes.Add(new Plane(Math.Sqrt(1.0 / (h * h * sigma11 + k * k * sigma22 + l * l * sigma33 + 2 * k * l * sigma23 + 2 * l * h * sigma31 + 2 * h * k * sigma12) * CellVolumeSqure), h, k, l, 0, 0)); } } } break; case 3: //tetragonal for (int h = 0; h <= hMax; h++) { for (int k = h; k <= kMax; k++) { for (int l = h + k == 0 ? 1 : 0; l <= lMax; l++) { calcPlanes.Add(new Plane(Math.Sqrt(1.0 / (h * h * sigma11 + k * k * sigma22 + l * l * sigma33 + 2 * k * l * sigma23 + 2 * l * h * sigma31 + 2 * h * k * sigma12) * CellVolumeSqure), h, k, l, 0, 0)); } } } break; case 4: //trigonal for (int h = 0; h < hMax; h++) { for (int k = h; k < kMax; k++) { for (int l = h + k == 0 ? 1 : 0; l < lMax; l++) { calcPlanes.Add(new Plane(Math.Sqrt(1.0 / (h * h * sigma11 + k * k * sigma22 + l * l * sigma33 + 2 * k * l * sigma23 + 2 * l * h * sigma31 + 2 * h * k * sigma12) * CellVolumeSqure), h, k, l, 0, 0)); } } } break; case 5: //hexagonal for (int h = 0; h <= hMax; h++) { for (int k = h; k <= kMax; k++) { for (int l = h + k == 0 ? 1 : 0; l <= lMax; l++) { calcPlanes.Add(new Plane(Math.Sqrt(1.0 / (h * h * sigma11 + k * k * sigma22 + l * l * sigma33 + 2 * k * l * sigma23 + 2 * l * h * sigma31 + 2 * h * k * sigma12) * CellVolumeSqure), h, k, l, 0, 0)); } } } break; case 6: //cubic for (int h = 0; h <= hMax; h++) { for (int k = h; k <= kMax; k++) { for (int l = h + k == 0 ? 1 : k; l <= lMax; l++) { calcPlanes.Add(new Plane(Math.Sqrt(1.0 / (h * h * sigma11 + k * k * sigma22 + l * l * sigma33 + 2 * k * l * sigma23 + 2 * l * h * sigma31 + 2 * h * k * sigma12) * CellVolumeSqure), h, k, l, 0, 0)); } } } break; } calcPlanes.Sort(); for (int i = 0; i < calcPlanes.Count - 1; i++) { if (Math.Abs(calcPlanes[i].D - calcPlanes[i + 1].D) < 10E-9) { calcPlanes.RemoveAt(i-- + r.Next(2)); } } //planes と d とを関連付ける double[] diff = new double[obs.Length]; double temp; for (int i = 0; i < obs.Length; i++) { diff[i] = double.MaxValue; } for (int i = 0; i < obs.Length; i++) { for (int j = 0; j < calcPlanes.Count; j++) { if ((temp = (obs[i].D - calcPlanes[j].D) * (obs[i].D - calcPlanes[j].D)) < diff[i]) { diff[i] = temp; obsToCalcIndex[i] = j; } } } double diffMax = double.NegativeInfinity; for (int i = 0; i < obs.Length; i++) { if (diffMax < diff[i]) { diffMax = diff[i]; } } if (diffMax > 0.0004) { return(new Candidate(0, 0, 0, 0, 0, 0, 0, double.PositiveInfinity, double.PositiveInfinity, null)); } //obsToCalcに重複がないかどうかチェック int retry = 0, retryMax = 20; //重複チェック回数(retry)がretryMax回数を超えると失敗 for (int i = 0; i < obsToCalcIndex.Length - 1; i++) { if (obsToCalcIndex[i] == obsToCalcIndex[i + 1])//重複があったら { if (retry++ > retryMax) { return(new Candidate(0, 0, 0, 0, 0, 0, 0, double.PositiveInfinity, double.PositiveInfinity, null)); } if (r.Next(2) == 1)//さいころを振って選ばれたほうを残す { if (obsToCalcIndex[i] > 0) { obsToCalcIndex[i] -= 1; } else if (obsToCalcIndex[i + 1] < calcPlanes.Count - 1) { obsToCalcIndex[i + 1] += 1; } } else { if (obsToCalcIndex[i + 1] < calcPlanes.Count - 1) { obsToCalcIndex[i + 1] += 1; } else if (obsToCalcIndex[i] > 0) { obsToCalcIndex[i] -= 1; } } i = -1;//値を戻してやり直し } } //重複チェックをくぐり抜けたら指数を配当 for (int i = 0; i < condition.SortedD.Length; i++) { obs[i].H = calcPlanes[obsToCalcIndex[i]].H; obs[i].K = calcPlanes[obsToCalcIndex[i]].K; obs[i].L = calcPlanes[obsToCalcIndex[i]].L; } //最小2乗法によるフィッティング。 c = RefineCellParameter(condition.CrystalSystem, obs); c.R = Math.Sqrt(c.SigmaDQ / condition.TotalWeight) * calcPlanes.Count / condition.SortedD.Length; //最後にobs.Dを計算しなおす SinAlpha = Math.Sin(c.Alpha); SinBeta = Math.Sin(c.Beta); SinGamma = Math.Sin(c.Gamma); CosAlpha = Math.Cos(c.Alpha); CosBeta = Math.Cos(c.Beta); CosGamma = Math.Cos(c.Gamma); a2 = c.A * c.A; b2 = c.B * c.B; c2 = c.C * c.C; sigma11 = b2 * c2 * SinAlpha * SinAlpha; sigma22 = c2 * a2 * SinBeta * SinBeta; sigma33 = a2 * b2 * SinGamma * SinGamma; sigma23 = a2 * c.B * c.C * (CosBeta * CosGamma - CosAlpha); sigma31 = c.A * b2 * c.C * (CosGamma * CosAlpha - CosBeta); sigma12 = c.A * c.B * c2 * (CosAlpha * CosBeta - CosGamma); CellVolumeSqure = a2 * b2 * c2 * (1 - CosAlpha * CosAlpha - CosBeta * CosBeta - CosGamma * CosGamma + 2 * CosAlpha * CosBeta * CosGamma); for (int i = 0; i < obs.Length; i++) { obs[i].D = Math.Sqrt(1.0 / (obs[i].H * obs[i].H * sigma11 + obs[i].K * obs[i].K * sigma22 + obs[i].L * obs[i].L * sigma33 + 2 * obs[i].K * obs[i].L * sigma23 + 2 * obs[i].L * obs[i].H * sigma31 + 2 * obs[i].H * obs[i].K * sigma12) * CellVolumeSqure); } return(c); }
private Candidate FindCellParameter(FindCondition condition, int seed) { Random r = new Random(seed); int unk = 0; switch (condition.CrystalSystem) { case 0: unk = 6; break; //triclinic case 1: unk = 4; break; //monoclinic case 2: unk = 3; break; //orthorhombic case 3: unk = 2; break; //tetragonal case 4: unk = 2; break; //trigonal case 5: unk = 2; break; //hexagonal case 6: unk = 1; break; //cubic } if (unk > condition.DtoSortedD.Length) { return(new Candidate()); } Plane[] planes = new Plane[unk]; //まず対象となるピークをunk本選ぶ List <int> targetPeak = new List <int>(); for (int j = 0; j < unk; j++) { targetPeak.Sort(); int tempTarget = r.Next(r.Next(condition.DtoSortedD.Length / 2)); for (int n = 0; n < targetPeak.Count; n++) //0からtempTargetの間で既に選ばれている指数を検索し、tempTargetから外す { if (tempTarget >= targetPeak[n]) { tempTarget++; } } targetPeak.Add(tempTarget); } targetPeak.Sort(); //ピーク選定おわり //次にピークに指数を与える for (int j = 0; j < targetPeak.Count; j++) { //指数を生成する orthoは h,k,lすべて >= 0 指数の上限は ピークの順番(何番目の要素か)の値に6を足したもの int h = 0, k = 0, l = 0; while (h == 0 && l == 0 && k == 0) { switch (condition.CrystalSystem) { case 0: //triclinic h = r.Next(r.Next(0, condition.DtoSortedD[j] + 3) + 1); k = r.Next(-(k = r.Next(0, condition.DtoSortedD[j] + 3)), k + 1); l = r.Next(-(l = r.Next(0, condition.DtoSortedD[j] + 3)), l + 1); break; case 1: //monoclinic h = r.Next(r.Next(0, condition.DtoSortedD[j] + 4) + 1); k = r.Next(r.Next(0, condition.DtoSortedD[j] + 4) + 1); l = r.Next(-(l = r.Next(0, condition.DtoSortedD[j] + 4)), l + 1); break; case 2: //ortho h = r.Next(r.Next(0, condition.DtoSortedD[j] + 4) + 1); k = r.Next(r.Next(0, condition.DtoSortedD[j] + 4) + 1); l = r.Next(r.Next(0, condition.DtoSortedD[j] + 4) + 1); break; default: //tetra h = r.Next(r.Next(0, condition.DtoSortedD[j] + 4) + 1); k = r.Next(r.Next(0, condition.DtoSortedD[j] + 4) + 1); l = r.Next(r.Next(0, condition.DtoSortedD[j] + 4) + 1); break; } } planes[j] = new Plane(condition.D[targetPeak[j]], h, k, l, 1, 1); } Candidate c = RefineCellParameter(condition.CrystalSystem, planes); if (double.IsInfinity(c.SigmaDQ)) { return(new Candidate(0, 0, 0, 0, 0, 0, 0, double.PositiveInfinity, double.PositiveInfinity, null)); } //軸を組み替える if (condition.CrystalSystem == 2)//orthoのとき { if (c.A < c.B) { double temp = c.A; c.A = c.B; c.B = temp; } if (c.B < c.C) { double temp = c.B; c.B = c.C; c.C = temp; } if (c.A < c.B) { double temp = c.A; c.A = c.B; c.B = temp; } } if (condition.CrystalSystem == 1) //monoclinicのとき { //βがもっとも90°に近くなるように // c.A = 0.9737; // c.C = 0.5242; // c.Beta = 105.7 / 180.0 * Math.PI; PointD u = new PointD(c.A, 0); PointD v = new PointD(c.C * Math.Cos(c.Beta), c.C * Math.Sin(c.Beta)); double area = c.A * c.C * Math.Sin(c.Beta); List <PointD> p = new List <PointD>(); for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { if (!(i == 0 && j == 0)) { p.Add(i * u + j * v); } } } PointD temp1 = new PointD(0, 0), temp2 = new PointD(0, 0); double tempBeta = double.MaxValue; for (int i = 0; i < p.Count; i++) { for (int j = i + 1; j < p.Count; j++) { if (Math.Abs(area - Math.Abs(p[i].X * p[j].Y - p[i].Y * p[j].X)) < 0.0000001) { double beta = Math.Acos((p[i].X * p[j].X + p[i].Y * p[j].Y) / p[i].Length / p[j].Length); if (beta >= Math.PI / 2 && tempBeta > beta) { temp1 = p[i]; temp2 = p[j]; tempBeta = beta; } } } } c.A = temp1.Length; c.C = temp2.Length; c.Beta = tempBeta; if (c.A < c.C) { double temp = c.A; c.A = c.C; c.C = temp; } } if (condition.MaxA >= c.A && condition.MinA <= c.A && condition.MaxB >= c.B && condition.MinB <= c.B && condition.MaxC >= c.C && condition.MinC <= c.C && condition.MaxAlpha >= c.Alpha && condition.MinAlpha <= c.Alpha && condition.MaxBeta >= c.Beta && condition.MinBeta <= c.Beta && condition.MaxGamma >= c.Gamma && condition.MinGamma <= c.Gamma) { return(GetResidualValue(c, condition, r.Next())); } else { return(new Candidate(0, 0, 0, 0, 0, 0, 0, double.PositiveInfinity, double.PositiveInfinity, null)); } }
private void GetCandidatesForThread(FindCondition condition, int seed, int tryNumber, ref Candidate[] c) { c = GetCandidates(condition, seed, tryNumber); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 21JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * get all records based on search condition. * @param findConditions the search condition. * @return a hashtable of all matched record.the key is the mapInfo ID. */ public Hashtable Search(FindConditions findConditions) { Hashtable retTable = new Hashtable(); ArrayList allCondition = findConditions.GetConditions(); for (int i = 0; i < allCondition.Count; i++) { FindCondition findCondition = (FindCondition)allCondition[i]; int stringID = BinarySearch(findCondition.MatchString); int fieldIndex = findCondition.FieldIndex; if (stringID != -1) { bool bDone = false; _stringIndex.GetRecord(stringID); string strValue = _stringData.GetMapInfoIDAndField(_stringIndex.RecordOffset); while (strValue.StartsWith(findCondition.MatchString) && (!bDone)) { int fieldCount = _stringData.FieldCount; for (int j = 0; j < fieldCount; j++) { if (_stringData.FieldID[j] == fieldIndex) { int mapInfoID = _stringData.MapInfoID[j]; if (!retTable.ContainsKey(mapInfoID)) { retTable.Add(mapInfoID, strValue); } if (retTable.Count > FindConditions.MaxMatchRecord) { return(retTable); } } } bDone = _stringIndex.MovePrevious(); if (!bDone) { strValue = _stringData.GetMapInfoIDAndField(_stringIndex.RecordOffset); } } bDone = false; _stringIndex.GetRecord(stringID); strValue = _stringData.GetMapInfoIDAndField(_stringIndex.RecordOffset); while (strValue.StartsWith(findCondition.MatchString) && (!bDone)) { int fieldCount = _stringData.FieldCount; for (int j = 0; j < fieldCount; j++) { if (_stringData.FieldID[j] == fieldIndex) { int mapInfoID = _stringData.MapInfoID[j]; if (!retTable.ContainsKey(mapInfoID)) { retTable.Add(mapInfoID, strValue); } if (retTable.Count > FindConditions.MaxMatchRecord) { return(retTable); } } } bDone = _stringIndex.MoveNext(); if (!bDone) { strValue = _stringData.GetMapInfoIDAndField(_stringIndex.RecordOffset); } } } } return(retTable); }