2

数値データをその座標 (xValues、yValues) とともにリストに格納しました。そのデータ セットを別のデータ セットと比較 (加算、減算、除算...) する場合は、比較できないことに注意する必要があります。 xValues が一致しない場合 (比較するものが何もないため)。したがって、実際には他のセットに存在し、新しいポイントを生成する「欠落している」xValues の間で線形補間する必要があります。この写真を確認してください:

ここに画像の説明を入力

赤い線の水色の四角は、保存されたポイント (xValues2) を表し、(通常) 他のセットの xValues (xValues1) とは一致しません。緑の線上の 2 つの四角形は、目的の生成点の例です。それらを使用すると、この 2 つのグラフを問題なく処理できます。

線形補間の場合 とても簡単です: 2 つの点 (x0,y0) と (x1,y1) があり、"x2" を指定してそれらの間に新しい点を追加したい場合:

y2=y0+(x2-x0)*(y1-y0)/(x1-x0)

これを機能させるには、次のようなものを実装する必要があると思います。

  1. 新しいリストを作成します (xValuesNew、yValuesNew)。
  2. xValues1 と xValues2 (xValuesNew) の和集合を作成します。
  3. 元の xValues1 と xValuesNew の違いを確認します。
  4. 見つかった新しい値ごとに、上記の式を使用して「y」を生成します。
  5. その 4 つのステップをメソッドに入れて、もう一度使用しますが、今度は set2 で使用します。

おそらくLinqまたはラムダ式を使用して、簡単な解決策を見つけようとしていますが、それらを扱うことに慣れておらず、そのトピックに関する知識が不足しています。この操作はかなり頻繁に行われるので、重すぎないようにする必要があることに注意してください。そのため、元のリストの途中にポイントを挿入する代わりに、新しいリストを生成することをお勧めします。

誰かが私を少し案内してくれるか、実際にこれを行っている数学ライブラリがあるかどうか教えてください。ありがとうございました。


編集: 適切に説明していない場合は申し訳ありません。

ここに例があります(Excelで作成):

ここに画像の説明を入力

Series1 と Series2 (+) またはその他の演算を直接加算することはできません。それらの X 間隔が異なるためです。だから私が望むのは、必要なときに Series1 で新しいポイントを生成することです。

そのために、単純に線形補間を使用したいと思います。series1 に P1(0,40) と P2(0,60) があるとしますが、series2 には点 (1,10) があります。(1,50) 座標で P1 と P2 の間に点 P3 を生成する必要があります。

ここに画像の説明を入力

ここに画像の説明を入力

これを SkipWhile で実行し、両方のシリーズの次の X 値を比較しようとしました。series1 の XValue が低い場合は、その XValue と対応する YValue を newSeries に追加します。それ以外の場合は、Y を生成するために XValue2 を使用し、それを newSeries に追加します。これが私の試みの1つです(機能しません):

List<double> series1X = new List<double> { 0, 2, 4, 6, 8 };
        List<double> series1Y = new List<double> { 120, 100, 110, 105, 70 };
        List<double> series2X = new List<double> { 0, 1, 7, 8,9 };

        List<double> newSeries1X = new List<double>();
        List<double> newSeries1Y = new List<double>();

  double lastX1 = series1X[series1X.Count()-1];
        int i = 0;

        while (next1X <= lastX1)
        {

            next2X = series2X.SkipWhile(p => p <= next1X).First();
            Console.WriteLine(next2X.ToString());

            if (next1X <= next2X)
            {

                newSeries1X.Add(series1X[i]);
                newSeries1Y.Add(series1Y[i]);
            }

            if (next2X < next1X)
            {

                while (next2X < next1X)
                {
                    newSeries1X.Add(next2X);
                    newY = series1Y[i] + (next2X - series1X[i]) * (series1Y[i + 1] - series1Y[i]) / (series1X[i + 1] - series1X[i]);
                    newSeries1Y.Add(newY);

                    next2X = series2X.SkipWhile(p => p <= next2X).First();
                }
            }


            next1X = series1X.SkipWhile(p => p <= next2X).First();
            Console.WriteLine(next1X.ToString());
            i++;

        }

Zip メソッドでこれを行うのは素晴らしいことです。しかし、その条件を述語に記述する方法がわかりません。

4

2 に答える 2

0

間隔の異なる 2 つのシリーズを操作するには、まず最初のセットでポイントを生成し、次に (同じ方法で) 2 番目のセットでポイントを生成し、最後にポイントを合計する必要があります。

そのメソッドのコードは次のとおりです。

using OxyPlot.Series;
using OxyPlot;

namespace Algorithm1
{

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            List<DataPoint> S1 = new List<DataPoint> ();
            List<DataPoint> S2 = new List<DataPoint>();
            List<DataPoint> NS1 = new List<DataPoint>();

            S1.Add(new DataPoint(4, 10));
            S1.Add(new DataPoint(6, 20));
            S1.Add(new DataPoint(8, 15));
            S1.Add(new DataPoint(9, 70));
            S1.Add(new DataPoint(10, 5));

            S2.Add(new DataPoint(1, 0));
            S2.Add(new DataPoint(2, 0));
            S2.Add(new DataPoint(3, 0));
            S2.Add(new DataPoint(6, 0));
            S2.Add(new DataPoint(7, 0));
            S2.Add(new DataPoint(8.1, 0));
            S2.Add(new DataPoint(8.2, 0));
            S2.Add(new DataPoint(8.3, 0));
            S2.Add(new DataPoint(8.4, 0));
            S2.Add(new DataPoint(9, 0));
            S2.Add(new DataPoint(9.75, 0));
            S2.Add(new DataPoint(11, 0));
            S2.Add(new DataPoint(12, 0));
            S2.Add(new DataPoint(16, 0));

           NS1 = GetMiddlePoints(S1, S2);
           foreach (DataPoint pointin NS1)
           {
               MessageBox.Show( point.X.ToString()+" : "+ point.Y.ToString());
           }


        }

        #region GetMiddlePoints
        private List<DataPoint> GetMiddlePoints(List<DataPoint> S1, List<DataPoint> S2)
        {
            List<DataPoint> NS1 = new List<DataPoint>();

            int i = 0;
            int j = S2.TakeWhile(p => p.X < S1[0].X).Count();


            int PointsInS1 = S1.Count;
            int PointsInS2 = S2.Count;

            DataPoint newPoint = new DataPoint();


            while (i < PointsInS1 )
            {
                if (j < PointsInS2 )
                {
                    if (S1[i].X < S2[j].X)
                    {
                        newPoint = S1[i];
                        NS1.Add(newPoint );
                        i++;
                    }

                    else if (S1[i].X == S2[j].X)
                    {
                        newPoint = S1[i];
                        NS1.Add(newPoint );
                        i++;
                        j++;
                    }

                    else if (S1[i].X > S2[j].X)
                    {
                        newPoint .X = S2[j].X;
                        newPoint .Y = S1[i-1].Y + (S2[j].X - S1[i-1].X) * (S1[i].Y - S1[i-1].Y) / (S1[i].X - S1[i-1].X);
                        NS1.Add(newPoint );
                        j++;

                    }

                }

                if (j == PointsInS2 )
                {
                    newPoint = S1[i];
                    NS1.Add(newPoint );
                    i++;
                }


            }


            return NS1;

        }

        #endregion

    }
}
于 2013-06-17T21:21:07.077 に答える