WdGridAdvAnalyzeVm.cs 33.1 KB
Newer Older
潘栩锋's avatar
潘栩锋 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
using FlyADBase;
using GalaSoft.MvvmLight.Command;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

namespace Flyad7_WPF
{
潘栩锋's avatar
潘栩锋 committed
15
    public class WdGridAdvAnalyzeVm : INotifyPropertyChanged
潘栩锋's avatar
潘栩锋 committed
16 17 18 19 20 21 22
    {
        public double R { get; set; }
        public double CurrR { get; set; }
        public double CurrGroupR { get; set; }
        public double Speed { get; set; }
        public ObservableCollection<double> KsP { get; } = new ObservableCollection<double>();
        public ObservableCollection<double> Ks { get; } = new ObservableCollection<double>();
潘栩锋's avatar
潘栩锋 committed
23

潘栩锋's avatar
潘栩锋 committed
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

        public int CellCnt { get; private set; }
        public int SampleCellIdx { get; set; }



        public RelayCommand LoadCmd { get; private set; }
        public RelayCommand AutoCmd { get; private set; }
        public RelayCommand Auto2Cmd { get; private set; }
        public RelayCommand ManualCmd { get; private set; }
        public RelayCommand NextIdxCmd { get; private set; }
        public RelayCommand PreIdxCmd { get; private set; }
        public RelayCommand ClearRCmd { get; private set; }

        public RelayCommand ConvDebugCmd { get; private set; }
        List<GridAdvAnalyzeCell> gridAdvAnalyzeCells = new List<GridAdvAnalyzeCell>();
        List<GridAdvAnalyzeCellGroup> groups = new List<GridAdvAnalyzeCellGroup>();
        int[] Target;
        int[] Roller;

        System.Windows.Forms.DataVisualization.Charting.Chart chart;
        System.Windows.Forms.DataVisualization.Charting.Chart chart1;
        System.Windows.Forms.DataVisualization.Charting.Chart chart2;
        FlyAD7 flyad;

        public event PropertyChangedEventHandler PropertyChanged;

        public WdGridAdvAnalyzeVm()
        {
            LoadCmd = new RelayCommand(Load);
            AutoCmd = new RelayCommand(AutoCal);
            Auto2Cmd = new RelayCommand(AutoCal2);
            ManualCmd = new RelayCommand(ManualCal);
            ClearRCmd = new RelayCommand(DrawClear);
            NextIdxCmd = new RelayCommand(NextIdx);
            PreIdxCmd = new RelayCommand(PreIdx);
            ConvDebugCmd = new RelayCommand(ConvDebug);


            for (int i = 0; i < 5; i++)
            {
                KsP.Add(0);
                Ks.Add(0);
            }
            Ks[0] = 1;
        }

        public void Init(
            FlyAD7 flyad,
            System.Windows.Forms.DataVisualization.Charting.Chart chart0,
            System.Windows.Forms.DataVisualization.Charting.Chart chart1,
            System.Windows.Forms.DataVisualization.Charting.Chart chart2
潘栩锋's avatar
潘栩锋 committed
76
            )
潘栩锋's avatar
潘栩锋 committed
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
        {
            this.flyad = flyad;
            this.chart = chart0;
            this.chart1 = chart1;
            this.chart2 = chart2;
        }

        private void ConvDebug()
        {
            WdConvolution w = new WdConvolution();
            w.Init(Target);
            w.ShowDialog();
        }

        private void PreIdx()
        {
            SampleCellIdx--;
            ManualCal();
        }

        private void NextIdx()
        {
            SampleCellIdx++;
            ManualCal();
        }

潘栩锋's avatar
潘栩锋 committed
103
        void Load()
潘栩锋's avatar
潘栩锋 committed
104 105 106 107 108
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.DefaultExt = ".json";
            if (ofd.ShowDialog() != true)
                return;
潘栩锋's avatar
潘栩锋 committed
109 110

            List<TimeGridAdv2EventArgs> timeGridAdv2Datas;
潘栩锋's avatar
潘栩锋 committed
111 112 113 114
            string path = ofd.FileName;
            try
            {
                string json = File.ReadAllText(path);
潘栩锋's avatar
潘栩锋 committed
115
                timeGridAdv2Datas = Newtonsoft.Json.JsonConvert.DeserializeObject<List<TimeGridAdv2EventArgs>>(json);
潘栩锋's avatar
潘栩锋 committed
116
            }
潘栩锋's avatar
潘栩锋 committed
117
            catch (Exception e)
潘栩锋's avatar
潘栩锋 committed
118 119 120 121
            {
                MessageBox.Show(e.Message);
                return;
            }
潘栩锋's avatar
潘栩锋 committed
122
            if (timeGridAdv2Datas == null || timeGridAdv2Datas.Count() < 4)
潘栩锋's avatar
潘栩锋 committed
123 124 125 126 127
            {
                MessageBox.Show("数量为空,或者太少了");
                return;
            }

潘栩锋's avatar
潘栩锋 committed
128
            toGridAdvAnalyzeCells(timeGridAdv2Datas);
潘栩锋's avatar
潘栩锋 committed
129 130 131


            MessageBox.Show(
潘栩锋's avatar
潘栩锋 committed
132
                $"共加载 {gridAdvAnalyzeCells.Count()}幅数据 " + System.Environment.NewLine
潘栩锋's avatar
潘栩锋 committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
                + $"速度从 {gridAdvAnalyzeCells.First().speed:F1}pps -> {gridAdvAnalyzeCells.Last().speed:F1}pps"
                );
            return;
        }

        //void createRollerView()
        //{
        //    int roller_begin = 20;
        //    int roller_end = 60;
        //    Roller = new int[Target.Count()];



        //    //把 Target 的 测到不锈钢部分删除, 剩下求平均值
        //    int sum =0;
        //    int cnt=0;
        //    for (int i = 0; i < Target.Count(); i++) 
        //    {
        //        if (i >= roller_begin && i <= roller_end)
        //            continue;
        //        if (Misc.MyBase.ISVALIDATA(Target[i]))
        //        {
        //            sum += Target[i];
        //            cnt++;
        //        }
        //    }

        //    airAd = sum / cnt;
        //    int sensorGridWidth = (int)(25 / mmpp / flyad.PosOfGrid);
        //    int rollerGridWidth = (int)(rollerWidth / mmpp / flyad.PosOfGrid);

        //    //通过相关性,找到中心位置
        //    int rollerGridPos = 40;

        //    var roller = new int[rollerGridWidth + sensorGridWidth * 4];
        //    int idx = 0;
        //    for (int i = 0; i < sensorGridWidth*2; i++)
        //    {
        //        roller[idx] = airAd;
        //        idx++;
        //    }
        //    for (int i = 0; i < rollerGridWidth; i++)
        //    {
        //        roller[idx] = airAd;
        //        idx++;
        //    }
        //    for (int i = 0; i < sensorGridWidth * 2; i++)
        //    {
        //        roller[idx] = airAd;
        //        idx++;
        //    }

        //    //找到最大相关性对应的位置
        //    CurrR = Misc.MyMath.Correl(Target, ad_x);
        //}
潘栩锋's avatar
潘栩锋 committed
188
        async void toGridAdvAnalyzeCells(List<TimeGridAdv2EventArgs> timeGridAdv2Datas)
潘栩锋's avatar
潘栩锋 committed
189 190
        {
            gridAdvAnalyzeCells.Clear();
潘栩锋's avatar
潘栩锋 committed
191
            foreach (var gridAdvUnit in timeGridAdv2Datas)
潘栩锋's avatar
潘栩锋 committed
192 193 194 195 196 197 198 199 200
            {
                var cell = new GridAdvAnalyzeCell()
                {
                    units = gridAdvUnit
                };
                gridAdvAnalyzeCells.Add(cell);
            }

            //计算速度
潘栩锋's avatar
潘栩锋 committed
201
            foreach (var cell in gridAdvAnalyzeCells)
潘栩锋's avatar
潘栩锋 committed
202 203
            {
                //计算中间1/3数据的平均速度
潘栩锋's avatar
潘栩锋 committed
204
                int cnt = cell.units.AdList.Count();
潘栩锋's avatar
潘栩锋 committed
205
                int range = cnt / 20;
潘栩锋's avatar
潘栩锋 committed
206 207 208 209 210
                int idx_last = (cnt + range) / 2;
                int idx_first = (cnt - range) / 2;
                int delta_pos = cell.units.PosList[idx_last] - cell.units.PosList[idx_first];
                double delta_sec = (idx_last - idx_first) * 1.28 / 1000;
                cell.speed = delta_pos / delta_sec;
潘栩锋's avatar
潘栩锋 committed
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
            }

            //画出速度
            //await Draw2(gridAdvAnalyzeCells.Select(c => Math.Abs(c.speed)).ToArray());

            //把相同速度的,放在一起
            double speed_diff = 25;
            groups.Clear();
            for (int i = 0; i < gridAdvAnalyzeCells.Count(); i++)
            {
                var cell = gridAdvAnalyzeCells[i];
                GridAdvAnalyzeCellGroup group;
                if (groups.Count() == 0)
                {
                    group = new GridAdvAnalyzeCellGroup() { speed = Math.Abs(cell.speed) };
                    groups.Add(group);
                    if (cell.speed > 0)
                    {
                        group.fCellIdxs.Add(i);
                    }
                    else
                    {
                        group.bCellIdxs.Add(i);
                    }
                    group.range.Begin = i;
                    group.range.End = i;
                }
潘栩锋's avatar
潘栩锋 committed
238
                else
潘栩锋's avatar
潘栩锋 committed
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
                {
                    group = groups.Last();
                    if (Math.Abs(group.speed - Math.Abs(cell.speed)) < speed_diff)
                    {
                        //同一个
                        if (cell.speed > 0)
                        {
                            group.fCellIdxs.Add(i);
                        }
                        else
                        {
                            group.bCellIdxs.Add(i);
                        }
                        group.range.End = i;
                    }
潘栩锋's avatar
潘栩锋 committed
254
                    else
潘栩锋's avatar
潘栩锋 committed
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
                    {
                        group = new GridAdvAnalyzeCellGroup() { speed = Math.Abs(cell.speed) };
                        groups.Add(group);
                        if (cell.speed > 0)
                        {
                            group.fCellIdxs.Add(i);
                        }
                        else
                        {
                            group.bCellIdxs.Add(i);
                        }
                        group.range.Begin = i;
                        group.range.End = i;
                    }
                }
            }
            GetTarget();
            CellCnt = gridAdvAnalyzeCells.Count();
            SampleCellIdx = CellCnt * 3 / 4;
            ManualCal();
        }
        int GetGroupIdxFromCellIdx(int cellidx)
        {
            return groups.FindIndex(group => group.range.Contain(cellidx));
        }

潘栩锋's avatar
潘栩锋 committed
281
        int[] CalGroupData(int groupIdx)
潘栩锋's avatar
潘栩锋 committed
282 283 284 285 286 287
        {
            int[] ad_sum = new int[1000];
            int[] ad_cnt = new int[1000];
            foreach (var cal_cell_idx in groups[groupIdx].fCellIdxs)
            {
                Filter2(gridAdvAnalyzeCells[cal_cell_idx].units, out var Xs, Ks);
潘栩锋's avatar
潘栩锋 committed
288 289
                
                var ad_x = TimeGridAdvHelperExt.ToGrid(Xs.AdList, Xs.PosList, flyad.PosOfGrid, flyad.GridLen);
潘栩锋's avatar
潘栩锋 committed
290 291
                for (int i = 0; i < 1000; i++)
                {
潘栩锋's avatar
潘栩锋 committed
292
                    if (Misc.MyBase.ISVALIDATA(ad_x[i]))
潘栩锋's avatar
潘栩锋 committed
293 294 295 296
                    {
                        ad_sum[i] += ad_x[i];
                        ad_cnt[i]++;
                    }
潘栩锋's avatar
潘栩锋 committed
297 298
;
                }
潘栩锋's avatar
潘栩锋 committed
299 300 301 302
            }
            foreach (var cal_cell_idx in groups[groupIdx].bCellIdxs)
            {
                Filter2(gridAdvAnalyzeCells[cal_cell_idx].units, out var Xs, Ks);
潘栩锋's avatar
潘栩锋 committed
303 304
                var ad_x = TimeGridAdvHelperExt.ToGrid(Xs.AdList, Xs.PosList, flyad.PosOfGrid, flyad.GridLen);

潘栩锋's avatar
潘栩锋 committed
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
                for (int i = 0; i < 1000; i++)
                {
                    if (Misc.MyBase.ISVALIDATA(ad_x[i]))
                    {
                        ad_sum[i] += ad_x[i];
                        ad_cnt[i]++;
                    }
                }
            }

            for (int i = 0; i < 1000; i++)
            {
                if (ad_cnt[i] > 0)
                {
                    ad_sum[i] /= ad_cnt[i];
                }
潘栩锋's avatar
潘栩锋 committed
321
                else
潘栩锋's avatar
潘栩锋 committed
322 323 324 325 326 327 328 329 330 331 332 333 334 335
                {
                    ad_sum[i] = Misc.MyBase.NULL_VALUE;
                }
            }
            return ad_sum;
            //await Chart1DrawData(3, ad_sum);
        }

        int[] CalGroupDataAvg(int groupIdx)
        {
            int[] ad_sum = new int[1000];
            int[] ad_cnt = new int[1000];
            foreach (var cal_cell_idx in groups[groupIdx].fCellIdxs)
            {
潘栩锋's avatar
潘栩锋 committed
336 337
                var Xs = gridAdvAnalyzeCells[cal_cell_idx].units;
                var ad_x = TimeGridAdvHelperExt.ToGrid(Xs.AdList, Xs.PosList, flyad.PosOfGrid, flyad.GridLen);
潘栩锋's avatar
潘栩锋 committed
338 339 340 341 342 343 344 345 346 347 348 349 350
                for (int i = 0; i < 1000; i++)
                {
                    if (Misc.MyBase.ISVALIDATA(ad_x[i]))
                    {
                        ad_sum[i] += ad_x[i];
                        ad_cnt[i]++;
                    }
;
                }
            }
            foreach (var cal_cell_idx in groups[groupIdx].bCellIdxs)
            {
                Filter2(gridAdvAnalyzeCells[cal_cell_idx].units, out var Xs, Ks);
潘栩锋's avatar
潘栩锋 committed
351 352 353
                
                var ad_x = TimeGridAdvHelperExt.ToGrid(Xs.AdList, Xs.PosList, flyad.PosOfGrid, flyad.GridLen);

潘栩锋's avatar
潘栩锋 committed
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
                for (int i = 0; i < 1000; i++)
                {
                    if (Misc.MyBase.ISVALIDATA(ad_x[i]))
                    {
                        ad_sum[i] += ad_x[i];
                        ad_cnt[i]++;
                    }
                }
            }

            for (int i = 0; i < 1000; i++)
            {
                if (ad_cnt[i] > 0)
                {
                    ad_sum[i] /= ad_cnt[i];
                }
                else
                {
                    ad_sum[i] = Misc.MyBase.NULL_VALUE;
                }
            }
            return ad_sum;
            //await Chart1DrawData(3, ad_sum);
        }


        async void DrawClear()
        {
            await Task.Yield();
            //画图
            App.Current.Dispatcher.Invoke(() =>
            {
                System.Windows.Forms.DataVisualization.Charting.Series series = chart.Series[0];
                series.Points.Clear();
                //chart.ChartAreas[0].AxisX.Minimum = double.NaN;
                //chart.ChartAreas[0].AxisX.Maximum = double.NaN;
            });
        }
        async Task DrawR(int index, double r)
        {
            //画图
            await Task.Yield();
            await Task.Factory.StartNew(() =>
            {
                App.Current.Dispatcher.Invoke(() =>
                {
                    System.Windows.Forms.DataVisualization.Charting.Series series = chart.Series[index];
潘栩锋's avatar
潘栩锋 committed
401
                    series.Points.AddY(r * 10000);
潘栩锋's avatar
潘栩锋 committed
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
                    double max = series.Points.Max(p => p.YValues[0]);
                    double min = series.Points.Min(p => p.YValues[0]);
                    if (max != min)
                    {
                        double range = (max - min) / 10;
                        chart.ChartAreas[0].AxisY.Minimum = min - range;
                        chart.ChartAreas[0].AxisY.Maximum = max + range;
                    }
                });
            });
        }

        async Task Draw2(double[] data)
        {
            var chart = chart2;
            //画图
            await Task.Yield();
            await Task.Factory.StartNew(() =>
            {
                App.Current.Dispatcher.Invoke(() =>
                {
                    System.Windows.Forms.DataVisualization.Charting.Series series = chart.Series[0];

                    series.Points.Clear();
                    for (int i = 0; i < data.Count(); i++)
                    {
                        series.Points.AddXY(i, data[i]);
                    }

                    double max = series.Points.Max(p => p.YValues[0]);
                    double min = series.Points.Min(p => p.YValues[0]);
                    if (max != min)
                    {
                        double range = (max - min) / 10;
                        chart.ChartAreas[0].AxisY.Minimum = min - range;
                        chart.ChartAreas[0].AxisY.Maximum = max + range;
                    }
                });
            });
        }


        async Task Chart1DrawData(int index, int[] data)
        {
            var chart = chart1;
            await Task.Yield();
            //画图
            await Task.Factory.StartNew(() =>
            {
                App.Current.Dispatcher.Invoke(() =>
                {
                    System.Windows.Forms.DataVisualization.Charting.Series series = chart.Series[index];
                    series.Points.Clear();
                    for (int i = 0; i < data.Count(); i++)
                    {
                        if (Misc.MyBase.ISVALIDATA(data[i]))
                            series.Points.AddXY(i, data[i]);
                    }
                    //if (series.Points.Count() > 0)
                    //{
                    //    double max = series.Points.Max(p => p.YValues[0]);
                    //    double min = series.Points.Min(p => p.YValues[0]);
                    //    if (max != min)
                    //    {
                    //        double range = (max - min) / 10;
                    //        chart.ChartAreas[0].AxisY.Minimum = min - range;
                    //        chart.ChartAreas[0].AxisY.Maximum = max + range;
                    //    }
                    //}
                });
            });
        }

        async Task Chart2DrawData(int index, int[] data)
        {
            var chart = chart2;
            await Task.Yield();
            //画图
            await Task.Factory.StartNew(() =>
            {
                App.Current.Dispatcher.Invoke(() =>
                {
                    System.Windows.Forms.DataVisualization.Charting.Series series = chart.Series[index];
                    series.Points.Clear();
                    for (int i = 0; i < data.Count(); i++)
                    {
                        if (Misc.MyBase.ISVALIDATA(data[i]))
                            series.Points.AddXY(i, data[i]);
                    }
                    //if (series.Points.Count() > 0)
                    //{
                    //    double max = series.Points.Max(p => p.YValues[0]);
                    //    double min = series.Points.Min(p => p.YValues[0]);
                    //    if (max != min)
                    //    {
                    //        double range = (max - min) / 10;
                    //        chart.ChartAreas[0].AxisY.Minimum = min - range;
                    //        chart.ChartAreas[0].AxisY.Maximum = max + range;
                    //    }
                    //}
                });
            });
        }

        async void GetTarget()
        {
潘栩锋's avatar
潘栩锋 committed
508

潘栩锋's avatar
潘栩锋 committed
509 510 511 512 513 514
            int[] sum = new int[1000];
            int[] cnt = new int[1000];
            int[] targets = new int[1000];

            for (int i = 0; i < 4; i++)
            {
潘栩锋's avatar
潘栩锋 committed
515 516 517 518
                
                var Xs = gridAdvAnalyzeCells[i].units;
                var datas = TimeGridAdvHelperExt.ToGrid(Xs.AdList, Xs.PosList, flyad.PosOfGrid, flyad.GridLen);

潘栩锋's avatar
潘栩锋 committed
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
                for (int j = 0; j < 1000; j++)
                {
                    if (Misc.MyBase.ISVALIDATA(datas[j]))
                    {
                        sum[j] += datas[j];
                        cnt[j]++;
                    }
                }
            }

            for (int j = 0; j < 1000; j++)
            {
                if (cnt[j] > 0)
                {
                    targets[j] = sum[j] / cnt[j];
                }
                else
                {
                    targets[j] = Misc.MyBase.NULL_VALUE;
                }
            }
            Target = targets;

            await Chart1DrawData(0, Target);
            await Chart2DrawData(0, Target);
        }
潘栩锋's avatar
潘栩锋 committed
545
        async void ManualCal()
潘栩锋's avatar
潘栩锋 committed
546 547 548 549 550 551 552 553 554
        {
            if (SampleCellIdx < 0)
                SampleCellIdx = 0;
            else if (SampleCellIdx >= CellCnt)
                SampleCellIdx = CellCnt - 1;

            int cal_cell_idx = SampleCellIdx;
            Speed = gridAdvAnalyzeCells[cal_cell_idx].speed;
            //1. 找中间的图
潘栩锋's avatar
潘栩锋 committed
555 556 557 558 559

            var Xs = gridAdvAnalyzeCells[cal_cell_idx].units;
            var orgs0 = TimeGridAdvHelperExt.ToGrid(Xs.AdList, Xs.PosList, flyad.PosOfGrid, flyad.GridLen);


潘栩锋's avatar
潘栩锋 committed
560 561 562 563 564
            await Chart1DrawData(1, orgs0);
            await Chart2DrawData(1, orgs0);
            //2. 算出相关性
            R = Misc.MyMath.Correl(Target, orgs0);

潘栩锋's avatar
潘栩锋 committed
565

潘栩锋's avatar
潘栩锋 committed
566 567 568 569
            if (Ks.Sum() != 1)
            {
                Ks[4] = 1 - (Ks.Sum() - Ks[4]);
            }
潘栩锋's avatar
潘栩锋 committed
570 571
            Filter2(gridAdvAnalyzeCells[cal_cell_idx].units, out Xs, Ks);
            var ad_x = TimeGridAdvHelperExt.ToGrid(Xs.AdList, Xs.PosList, flyad.PosOfGrid, flyad.GridLen);
潘栩锋's avatar
潘栩锋 committed
572 573 574 575 576
            CurrR = Misc.MyMath.Correl(Target, ad_x);

            await DrawR(0, CurrR);
            await Chart1DrawData(2, ad_x);
            int groupIdx = GetGroupIdxFromCellIdx(SampleCellIdx);
潘栩锋's avatar
潘栩锋 committed
577

潘栩锋's avatar
潘栩锋 committed
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
            int[] group_ad = CalGroupDataAvg(groupIdx);
            await Chart2DrawData(2, group_ad);


            group_ad = CalGroupData(groupIdx);
            CurrGroupR = Misc.MyMath.Correl(Target, group_ad);
            await Chart1DrawData(3, group_ad);
            await Chart2DrawData(3, group_ad);
            //await Draw2(gridAdvAnalyzeCells.Select(c => Math.Abs(c.speed)).ToArray());


        }

        private async void AutoCal()
        {
            if (SampleCellIdx < 4)
                SampleCellIdx = 4;
            else if (SampleCellIdx >= CellCnt)
                SampleCellIdx = CellCnt - 1;

            int cal_cell_idx = SampleCellIdx;

            //1. 找中间的图
潘栩锋's avatar
潘栩锋 committed
601 602
            var Xs = gridAdvAnalyzeCells[cal_cell_idx].units;
            var orgs0 = TimeGridAdvHelperExt.ToGrid(Xs.AdList, Xs.PosList, flyad.PosOfGrid, flyad.GridLen);
潘栩锋's avatar
潘栩锋 committed
603 604 605 606 607 608 609
            await Chart1DrawData(1, orgs0);

            //2. 算出相关性
            R = Misc.MyMath.Correl(Target, orgs0);

            DrawClear();
            Ks[0] = 1;
潘栩锋's avatar
潘栩锋 committed
610
            for (int i = 0; i < 4; i++)
潘栩锋's avatar
潘栩锋 committed
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630
            {
                await AutoSearchKn(cal_cell_idx, 0, Ks[i], 0.1, 0.000001, Ks.Take(i).ToArray());
            }

            int groupIdx = GetGroupIdxFromCellIdx(SampleCellIdx);
            int[] group_ad = CalGroupData(groupIdx);
            CurrGroupR = Misc.MyMath.Correl(Target, group_ad);
            await Chart1DrawData(3, group_ad);

            //await AutoSearchKn(cal_cell_idx, 0, 1, 0.1, 0.000001);

            //await AutoSearchKn(cal_cell_idx, 0, Ks[1], 0.1, 0.000001, Ks.Take(1).ToArray());

            //await AutoSearchKn(cal_cell_idx, 0, Ks[2], 0.1, 0.000001, Ks.Take(2).ToArray());

            //await AutoSearchKn(cal_cell_idx, 0, Ks[3], 0.1, 0.000001, Ks.Take(3).ToArray());
        }

        private async void AutoCal2()
        {
潘栩锋's avatar
潘栩锋 committed
631
            
潘栩锋's avatar
潘栩锋 committed
632 633 634 635 636 637 638 639
            if (SampleCellIdx < 4)
                SampleCellIdx = 4;
            else if (SampleCellIdx >= CellCnt)
                SampleCellIdx = CellCnt - 1;

            int cal_cell_idx = SampleCellIdx;

            //1. 找中间的图
潘栩锋's avatar
潘栩锋 committed
640 641
            var Xs = gridAdvAnalyzeCells[cal_cell_idx].units;
            var orgs0 = TimeGridAdvHelperExt.ToGrid(Xs.AdList, Xs.PosList, flyad.PosOfGrid, flyad.GridLen);
潘栩锋's avatar
潘栩锋 committed
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
            await Chart1DrawData(1, orgs0);

            //2. 算出相关性
            R = Misc.MyMath.Correl(Target, orgs0);

            DrawClear();
            await AutoSearchKn2(cal_cell_idx, 0.000001, Ks.ToArray());

        }
        async Task<double> AutoSearchKn(int cal_cell_idx, double min, double max, double step, double min_step, params double[] kn)
        {
            double[] Ks = new double[5];
            int cnt = kn.Count();
            if (cnt > 3)
            {
                throw new Exception("AutoSearchKn 输出 参数太多");
            }
            double k_sum = 0;
            for (int i = 0; i < cnt; i++)
            {
                Ks[i] = kn[i];
                k_sum += kn[i];
            }
潘栩锋's avatar
潘栩锋 committed
665

潘栩锋's avatar
潘栩锋 committed
666 667 668 669 670 671 672 673 674
            double max_r = -1;
            double best_k = -1;
            int[] ad_x = null;
            for (double k = max; k >= min; k -= step)
            {
                Ks[cnt] = k;
                Ks[cnt + 1] = 1 - k_sum - Ks[cnt];

                Filter2(gridAdvAnalyzeCells[cal_cell_idx].units, out var Xs, Ks[0], Ks[1], Ks[2], Ks[3], Ks[4]);
潘栩锋's avatar
潘栩锋 committed
675 676
                
                ad_x = TimeGridAdvHelperExt.ToGrid(Xs.AdList, Xs.PosList, flyad.PosOfGrid, flyad.GridLen);
潘栩锋's avatar
潘栩锋 committed
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
                double r = Misc.MyMath.Correl(Target, ad_x);
                if (r > max_r)
                {
                    max_r = r;
                    CurrR = max_r;
                    best_k = k;
                    for (int i = 0; i < Ks.Count(); i++)
                    {
                        this.Ks[i] = Ks[i];
                    }
                }
            }
            if (ad_x != null)
            {
                await DrawR(0, max_r);
                await Chart1DrawData(2, ad_x);
            }
            if (step <= min_step)
                return best_k;

            step = step / 10;
            double next_min = best_k - step * 2;
            double next_max = best_k + step * 2;
            if (next_max <= min)
                return best_k;
            if (next_min >= max)
                return best_k;
            if (next_min < min)
                next_min = min;
            if (next_max > max)
                next_max = max;
            return await AutoSearchKn(cal_cell_idx, next_min, next_max, step / 10, min_step, kn);
        }


        async Task AutoSearchKn2(int cal_cell_idx, double step, double[] Ks)
        {
            if (Ks.Count() != 5)
            {
                throw new Exception("AutoSearchKn2 初始值数量不为5");
            }
            int step_i = 0;
            int[] ad_x;
潘栩锋's avatar
潘栩锋 committed
720
            while (true)
潘栩锋's avatar
潘栩锋 committed
721 722
            {
                Filter2Avg(gridAdvAnalyzeCells[cal_cell_idx].units, out var Xs0, Ks);
潘栩锋's avatar
潘栩锋 committed
723
                ad_x = TimeGridAdvHelperExt.ToGrid(Xs0.AdList, Xs0.PosList, flyad.PosOfGrid, flyad.GridLen);
潘栩锋's avatar
潘栩锋 committed
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
                double r0 = Misc.MyMath.Correl(Target, ad_x);

                bool hasChanged = false;
                double[] ks = Ks.Clone() as double[];
                double r = r0;
                await Task.Factory.StartNew(() =>
                {
                    //每个参数改变 step, 确定方向
                    for (int i = 0; i < Ks.Count(); i++)
                    {
                        double curr_step = step;
                        double r1;
                        double r2;
                        int[] ad_x1;
                        int[] ad_x2;
                        while (true)
                        {
                            ks[i] = Ks[i] + curr_step;
潘栩锋's avatar
潘栩锋 committed
742 743 744
                            Filter2Avg(gridAdvAnalyzeCells[cal_cell_idx].units, out var Xs1, ks);
                            ad_x1 = TimeGridAdvHelperExt.ToGrid(Xs1.AdList, Xs1.PosList, flyad.PosOfGrid, flyad.GridLen);
                            
潘栩锋's avatar
潘栩锋 committed
745 746 747 748 749
                            r1 = Misc.MyMath.Correl(Target, ad_x1);


                            ks[i] = Ks[i] - curr_step;
                            Filter2Avg(gridAdvAnalyzeCells[cal_cell_idx].units, out Xs1, ks);
潘栩锋's avatar
潘栩锋 committed
750 751
                            
                            ad_x2 = TimeGridAdvHelperExt.ToGrid(Xs1.AdList, Xs1.PosList, flyad.PosOfGrid, flyad.GridLen);
潘栩锋's avatar
潘栩锋 committed
752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
                            r2 = Misc.MyMath.Correl(Target, ad_x2);

                            if ((r1 == r0) || (r2 == r0))
                            {
                                //居然没有变化,把step翻倍
                                curr_step *= 1.5;
                            }
                            else
                            {
                                //有变化了
                                break;
                            }
                        }

                        if (r1 > r0)
                        {
                            //方向正确
                            ks[i] = Ks[i] + curr_step;
                            hasChanged = true;
                            r = r1;
                            ad_x = ad_x1;
                            continue;
                        }
                        else if (r2 > r0)
                        {
                            //方向正确
                            ks[i] = Ks[i] - curr_step;
                            hasChanged = true;
                            r = r2;
                            ad_x = ad_x2;
                            continue;
                        }
                        else
                        {
                            //方向错误,回到以前
                            ks[i] = Ks[i];
                        }
                    }
                });

                step_i++;
                CurrR = r;
                //if(step_i%10==0)
                await DrawR(0, r);

                ks.CopyTo(Ks, 0);
                //K1 = Ks[0];
                //K2 = Ks[1];
                //K3 = Ks[2];
                //K4 = Ks[3];
                //K5 = Ks[4];

                Kp2Ks(ks, out double[] kkkkk);
潘栩锋's avatar
潘栩锋 committed
805
                for (int i = 0; i < kkkkk.Count(); i++)
潘栩锋's avatar
潘栩锋 committed
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
                {
                    this.Ks[i] = kkkkk[i];
                };
                if (!hasChanged)
                {
                    //已经计算完毕
                    break;
                }
            }
            if (ad_x != null)
            {
                await Chart1DrawData(2, ad_x);
            }
        }



        /// <summary>
        /// 一阶滤波 Y(n)=k1*X(n) + k2*Y(n-1) 
        /// </summary>
        /// <param name="y"></param>
        /// <param name="x"></param>
        /// <param name=""></param>
潘栩锋's avatar
潘栩锋 committed
829
        void Filter1(TimeGridAdv2EventArgs Ys, out TimeGridAdv2EventArgs Xs, double k1)
潘栩锋's avatar
潘栩锋 committed
830 831
        {
            double k2 = 1 - k1;
潘栩锋's avatar
潘栩锋 committed
832 833 834 835 836 837 838 839 840 841 842 843
            Xs = new TimeGridAdv2EventArgs()
            {
                AdList = new List<int>(),
                PosList = Ys.PosList.ToList(),
                EndTime = Ys.EndTime,
                Direction = Ys.Direction,
                Marker = Ys.Marker
            };
            for (int i = 0; i < Ys.AdList.Count(); i++)
            {
                double y = Ys.AdList[i - 0];
                double y_1 = i >= 1 ? Ys.AdList[i - 1] : y;
潘栩锋's avatar
潘栩锋 committed
844 845
                double x = (y - k2 * y_1) / k1;

潘栩锋's avatar
潘栩锋 committed
846
                Xs.AdList.Add((int)x);
潘栩锋's avatar
潘栩锋 committed
847 848 849 850 851 852 853 854 855
            }
        }

        /// <summary>
        /// 二阶滤波 Y(n)=k1*X(n) + k2*Y(n-1) + k3*X(n-1)+ k4*Y(n-2) + k5*X(n-2)
        /// </summary>
        /// <param name="y"></param>
        /// <param name="x"></param>
        /// <param name=""></param>
潘栩锋's avatar
潘栩锋 committed
856
        void Filter2(TimeGridAdv2EventArgs Ys, out TimeGridAdv2EventArgs Xs, double k1, double k2, double k3, double k4, double k5)
潘栩锋's avatar
潘栩锋 committed
857
        {
潘栩锋's avatar
潘栩锋 committed
858
            Xs = new TimeGridAdv2EventArgs()
潘栩锋's avatar
潘栩锋 committed
859
            {
潘栩锋's avatar
潘栩锋 committed
860 861 862 863 864 865 866 867 868 869 870
                AdList = new List<int>(),
                PosList = Ys.PosList.ToList(),
                EndTime = Ys.EndTime,
                Direction = Ys.Direction,
                Marker = Ys.Marker
            };
            for (int i = 0; i < Ys.AdList.Count(); i++)
            {
                double y = Ys.AdList[i - 0];
                double y_1 = i >= 1 ? Ys.AdList[i - 1] : y;
                double y_2 = i >= 2 ? Ys.AdList[i - 2] : y_1;
潘栩锋's avatar
潘栩锋 committed
871

潘栩锋's avatar
潘栩锋 committed
872 873
                double x_1 = i >= 1 ? Xs.AdList[i - 1] : y_1;
                double x_2 = i >= 2 ? Xs.AdList[i - 2] : x_1;
潘栩锋's avatar
潘栩锋 committed
874

潘栩锋's avatar
潘栩锋 committed
875 876
                double x = (y - (k2 * y_1 + k3 * x_1 + k4 * y_2 + k5 * x_2)) / k1;
                Xs.AdList.Add((int)x);
潘栩锋's avatar
潘栩锋 committed
877 878 879 880 881 882 883 884 885
            }
        }

        /// <summary>
        /// 二阶滤波 Y(n)=k1*X(n) + k2*Y(n-1) + k3*X(n-1)+ k4*Y(n-2) + k5*X(n-2)
        /// </summary>
        /// <param name="y"></param>
        /// <param name="x"></param>
        /// <param name=""></param>
潘栩锋's avatar
潘栩锋 committed
886
        void Filter2(TimeGridAdv2EventArgs Ys, out TimeGridAdv2EventArgs Xs, IEnumerable<double> ks)
潘栩锋's avatar
潘栩锋 committed
887
        {
潘栩锋's avatar
潘栩锋 committed
888
            Xs = new TimeGridAdv2EventArgs()
潘栩锋's avatar
潘栩锋 committed
889
            {
潘栩锋's avatar
潘栩锋 committed
890 891 892 893 894 895 896 897 898 899 900
                AdList = new List<int>(),
                PosList = Ys.PosList.ToList(),
                EndTime = Ys.EndTime,
                Direction = Ys.Direction,
                Marker = Ys.Marker
            };
            for (int i = 0; i < Ys.AdList.Count(); i++)
            {
                double y = Ys.AdList[i - 0];
                double y_1 = i >= 1 ? Ys.AdList[i - 1] : y;
                double y_2 = i >= 2 ? Ys.AdList[i - 2] : y_1;
潘栩锋's avatar
潘栩锋 committed
901

潘栩锋's avatar
潘栩锋 committed
902 903
                double x_1 = i >= 1 ? Xs.AdList[i - 1] : y_1;
                double x_2 = i >= 2 ? Xs.AdList[i - 2] : x_1;
潘栩锋's avatar
潘栩锋 committed
904 905 906

                double x = (y - (ks.ElementAt(1) * y_1 + ks.ElementAt(2) * x_1 + ks.ElementAt(3) * y_2 + ks.ElementAt(4) * x_2)) / ks.ElementAt(0);

潘栩锋's avatar
潘栩锋 committed
907
                Xs.AdList.Add((int)x);
潘栩锋's avatar
潘栩锋 committed
908 909 910
            }
        }

潘栩锋's avatar
潘栩锋 committed
911
        void Kp2Ks(double[] kp, out double[] Ks)
潘栩锋's avatar
潘栩锋 committed
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933
        {
            Ks = new double[5];

            if (kp.Count() != 5)
                throw new Exception("Filter2Avg kp.Count()!=5");
            if (kp.All(p => p == 0))
            {
                for (int i = 0; i < 5; i++)
                    Ks[i] = 1.0 / 5;
            }
            else
            {
                for (int i = 0; i < 5; i++)
                    Ks[i] = kp[i] / kp.Sum();
            }
        }
        /// <summary>
        /// 二阶滤波 Y(n)=k1*X(n) + k2*Y(n-1) + k3*X(n-1)+ k4*Y(n-2) + k5*X(n-2)
        /// </summary>
        /// <param name="y"></param>
        /// <param name="x"></param>
        /// <param name=""></param>
潘栩锋's avatar
潘栩锋 committed
934
        void Filter2Avg(TimeGridAdv2EventArgs Ys, out TimeGridAdv2EventArgs Xs, double[] kp)
潘栩锋's avatar
潘栩锋 committed
935 936
        {
            Kp2Ks(kp, out double[] Ks);
潘栩锋's avatar
潘栩锋 committed
937 938 939 940 941 942 943 944 945
            Xs = new TimeGridAdv2EventArgs()
            {
                AdList = new List<int>(),
                PosList = Ys.PosList.ToList(),
                EndTime = Ys.EndTime,
                Direction = Ys.Direction,
                Marker = Ys.Marker
            };
            for (int i = 0; i < Ys.AdList.Count(); i++)
潘栩锋's avatar
潘栩锋 committed
946
            {
潘栩锋's avatar
潘栩锋 committed
947 948 949
                double y = Ys.AdList[i - 0];
                double y_1 = i >= 1 ? Ys.AdList[i - 1] : y;
                double y_2 = i >= 2 ? Ys.AdList[i - 2] : y_1;
潘栩锋's avatar
潘栩锋 committed
950

潘栩锋's avatar
潘栩锋 committed
951 952
                double x_1 = i >= 1 ? Xs.AdList[i - 1] : y_1;
                double x_2 = i >= 2 ? Xs.AdList[i - 2] : x_1;
潘栩锋's avatar
潘栩锋 committed
953 954

                double x = (y - (Ks[1] * y_1 + Ks[2] * x_1 + Ks[3] * y_2 + Ks[4] * x_2)) / Ks[0];
潘栩锋's avatar
潘栩锋 committed
955
                Xs.AdList.Add((int)x);
潘栩锋's avatar
潘栩锋 committed
956 957 958 959 960 961
            }
        }



    }
潘栩锋's avatar
潘栩锋 committed
962
    public class GridAdvAnalyzeCell
潘栩锋's avatar
潘栩锋 committed
963
    {
潘栩锋's avatar
潘栩锋 committed
964
        public TimeGridAdv2EventArgs units;
潘栩锋's avatar
潘栩锋 committed
965 966 967 968
        public double speed;// 平均速度


    }
潘栩锋's avatar
潘栩锋 committed
969
    public class GridAdvAnalyzeCellGroup
潘栩锋's avatar
潘栩锋 committed
970 971 972 973 974 975 976
    {
        public List<int> fCellIdxs = new List<int>();
        public List<int> bCellIdxs = new List<int>();
        public double speed = 0;
        public Misc.Range range = new Misc.Range();
    }
}