我已经编写或者更愿意使用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);
}
下面是我的ZedGraph方法,只有从Codeproject ZedGraph教程修改的CreateGraph方法:
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.7GB的RAM。
我通过绘制大量数据点找到了ZedGraph内存不足的实例
Charting massive amounts of data
然而,我不太倾向于我的微弱4096数据点的情节会导致这种内存消耗而宁愿错误(缺乏)编程技巧
NB :这是一项学术任务,因此所提供的任何帮助都应考虑到这一点。干杯!
编辑:修正了L和N的初始化,而不是双精度。如前所述,问题仍然存在。
EDIT2 我是个白痴。我在我的测试CLI项目中将L和N的初始化更改为双精度但未能更新Windows窗体应用程序的源代码。感谢Jeppe Stig Nielsen指出我正确的方向。
答案 0 :(得分:0)
检查for
循环。看起来有一个减去(-
)太多了。
此外,您的部门(-2*L) / N
(缺少星号*
)会给出零,因为它是整数除法。要解决这个问题,请将一个因素投射到double
,或者只写:
2.0 * L / N
请注意,.0
表示浮点数(System.Double
),这将强制执行“步骤”的整个计算,并根据需要使用浮点数。
总结:如果您的步数为零,或者方向错误,您将继续向list1
添加点,直到内存不足为止。也许这个for
循环更好(但是自己测试一下):
for (double i = -L; i <= L; i += (2.0 * L) / N)