1

ZedGraph を使用して C# で空き領域のシュレディンガー方程式を記述したり、プロットしようとしたりしたところ、作成された実行可能ファイルの実行中に System.OutOfMemoryException エラーが発生しました。

************** Exception Text **************
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at System.Collections.Generic.List`1.set_Capacity(Int32 value)
   at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
   at System.Collections.Generic.List`1.Add(T item)
   at ZedGraph.PointPairList.Add(Double x, Double y)
   at Wavepacket.Form1.CreateGraph(ZedGraphControl schrodinger) in C:\Users\user1748005\Documents\Visual Studio 2010\Projects\Wavepacket\Wavepacket\Form1.cs:line 72
   at Wavepacket.Form1.Form1_Load(Object sender, EventArgs e) in C:\Users\user1748005\Documents\Visual Studio 2010\Projects\Wavepacket\Wavepacket\Form1.cs:line 35
   at System.Windows.Forms.Form.OnLoad(EventArgs e)
   at System.Windows.Forms.Form.OnCreateControl()
   at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   at System.Windows.Forms.Control.CreateControl()
   at System.Windows.Forms.Control.WmShowWindow(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.Form.WmShowWindow(Message& m)
   at System.Windows.Forms.Form.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

私の Cmplx クラスに必要な関数/コンストラクターは比較的単純で、次のとおりです。

    public Cmplx(double r, double i)
    {
        this.real = r;
        this.imag = i;
    }

    public double Real
    {
        get { return this.real; }
        set { this.real = value; }
    }

    public double Imag
    {
        get { return this.imag; }
        set { this.imag = value; }
    }
    public Cmplx Multiply(Cmplx b)
    {
        return new Cmplx((this.real * b.real - this.imag * b.imag), (b.imag * this.real + this.imag * b.real));
    }

    public Cmplx Divide(Cmplx b)
    {
        return new Cmplx((this.real * b.real + this.imag * b.imag) / (b.real * b.real + b.imag * b.imag), (b.real * this.imag - this.real * b.imag) / (b.real * b.real + b.imag * b.imag));
    }

    public Cmplx Scale(Double b)
    {
        return new Cmplx(this.real * b, this.imag * b);
    }

    public double Mod()
    {
        return Math.Sqrt(this.real * this.real + this.imag * this.imag);
    }

    public Cmplx Sqrt()
    {
        double r, theta;
        r = this.Mod();
        theta = this.Arg();

        return new Cmplx(Math.Sqrt(r) * (Math.Cos(theta / 2)), Math.Sqrt(r) * Math.Sin(theta / 2));
    }

    public Cmplx Exp()
    {
        double x, y, z;
        x = Math.Exp(this.real);
        y = Math.Cos(this.imag);
        z = Math.Sin(this.imag);

        return new Cmplx(x * y, x * z);
    } 

以下は、Codeproject ZedGraph チュートリアルから変更された CreateGraph メソッドのみを含む私の ZedGraph メソッドです。

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Resize(object sender, EventArgs e)
    {
        SetSize();
    }

    private void SetSize()
    {
        zedGraphControl1.Location = new Point(10, 10);
        zedGraphControl1.Size = new Size(ClientRectangle.Width - 20,
                                ClientRectangle.Height - 20);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        CreateGraph(zedGraphControl1);
        SetSize();
    }

    private void CreateGraph(ZedGraphControl schrodinger)
    {
        GraphPane myPane = schrodinger.GraphPane;

        myPane.Title.Text = "Free Space Schrodinger Equation)";
        myPane.XAxis.Title.Text = "Time (s)";
        myPane.YAxis.Title.Text = "Psi";

        double alpha, beta, norm, k0, t;
        double L,N;

        L = 25;
        N = 4096;
        alpha = 0.5;
        beta = 0.5785;  
        k0 = 1;
        t = 0;
        norm = (Math.Exp(-k0 * k0 * alpha)) * (Math.Pow((alpha / (2 * Math.PI)), 0.25));

        PointPairList list1 = new PointPairList();

        for (double i = -L; i <= L; i -= (-2L) / N)
        {
            Cmplx gamma = new Cmplx(alpha, beta * t);
            Cmplx a = new Cmplx(2 * alpha * k0, 0);
            a.Imag = i;
            Cmplx b = a.Multiply(a);
            Cmplx phi = (((b.Divide(gamma.Scale(4))).Exp()).Scale(norm)).Divide(gamma.Sqrt());
            list1.Add(phi.Mod(),i);
        }

        LineItem myCurve = myPane.AddCurve("t=0",
              list1, Color.Red, SymbolType.Default);
        schrodinger.AxisChange();
    }

を変更しました

list1.Add(phi.Mod(), i); 

上記のコード ブロックの for ループ内の行を

Console.WriteLine("{0}, {1}", phi.Mod(), i); 

これは、コマンドライン インターフェイス内ではありますが、期待どおりに機能します。ZedGraph ライブラリの結果を使用する Windows フォーム アプリケーションは、前述の例外をスローする前に最大 1.7 GB の RAM を消費します。

大量のデータ ポイントをプロットすることで、ZedGraph がメモリ不足になるインスタンスを見つけました。

大量のデータをグラフ化する

しかし、わずか 4096 個のデータ ポイントのプロットがそのようなメモリの消費につながるとはあまり考えず、プログラミング スキル (の欠如) のせいだと思います。

注意: これは学術的な課題であるため、提供されるヘルプはそれを考慮に入れる必要があります。乾杯!

EDIT : L と N の初期化を double ではなく int として修正しました。前述のように、問題は引き続き発生します。

EDIT2私はばかです。テスト CLI プロジェクト内で L と N の初期化を double に変更しましたが、Windows フォーム アプリケーションのソース コードを更新できませんでした。正しい方向に向けてくれた Jeppe Stig Nielsen に感謝します。

4

1 に答える 1

0

forループを確認してください。マイナス(-)が多すぎるようです。

また、除算(-2*L) / N(アスタリスク*がない)は整数除算であるため、ゼロになります。これを修正するには、1つの要素をにキャストするか、単に次のように記述します。double

2.0 * L / N

.0は浮動小数点数( )を示していることに注意してくださいSystem.Double。これにより、「ステップ」の計算全体が必要に応じて浮動小数点で実行されるようになります。

要約すると、ステップがゼロであるか、間違った方向に進んでいる場合はlist1、メモリが不足するまでポイントを追加し続けます。たぶん、このforループの方が優れています(ただし、自分でテストしてください)。

for (double i = -L; i <= L; i += (2.0 * L) / N)
于 2012-10-15T19:26:00.683 に答える