我正在开发一个接口,用于使用C#在Microsoft Visual Studio Express上对数据执行回归。
我现在面临的主要问题是使图表动态更新。回归算法非常复杂,预计将运行10分钟以上。我试图研究解决方案,例如使用backgroundworker来运行进程,但是我发现跨线程操作无效错误。 不幸的是,我没有很强的CS背景,因此我的实现很可能是错误的。
这是我的算法代码的样子:Run是启动算法的按钮。
private void Run_Click(object sender, EventArgs e)
{
//double[] Fluo_ex = new double[no_datapt];
//double[] Time_ex = new double[no_datapt];
double[] coeff_temp = new double[] { 4.0, 0.1, 5.0, 0.05 };
double[] Fluo_th1 = new double[totaltime+1];
double[] Fluo_ex1 = new double[no_datapt];
int[] timeslot = new int[no_datapt];
for (int i = 0; i<no_datapt; i++)
{
timeslot[i] = Convert.ToInt32(Fluo_ex[i].Item1);
Fluo_th1[i] = Fluo_ex[i].Item2;
}
bool flag = true;
double alp = 0.01;
int current = 0;
backgroundWorker1.RunWorkerAsync();
while (flag)
{
//enter the loop
current ++;
//update current
Run.Text = "Running!";
Fluo_th1 = Positive_Model(coeff_temp, new double[] { 0, 0, 0, 0 });
double sum00 = GetDist(timeslot, Fluo_ex1, Fluo_th1);
Fluo_th1 = Positive_Model(coeff_temp, new double[] { alp, 0, 0, 0 });
double sum01 = GetDist(timeslot, Fluo_ex1, Fluo_th1);
Fluo_th1 = Positive_Model(coeff_temp, new double[] { 0, alp, 0, 0 });
double sum02 = GetDist(timeslot, Fluo_ex1, Fluo_th1);
Fluo_th1 = Positive_Model(coeff_temp, new double[] { 0, 0, alp, 0 });
double sum03 = GetDist(timeslot, Fluo_ex1, Fluo_th1);
Fluo_th1 = Positive_Model(coeff_temp, new double[] { 0, 0, 0, alp });
double sum04 = GetDist(timeslot, Fluo_ex1, Fluo_th1);
Fluo_th1 = Positive_Model(coeff_temp, new double[] { -alp, 0, 0, 0 });
double sum05 = GetDist(timeslot, Fluo_ex1, Fluo_th1);
Fluo_th1 = Positive_Model(coeff_temp, new double[] { 0, -alp, 0, 0 });
double sum06 = GetDist(timeslot, Fluo_ex1, Fluo_th1);
Fluo_th1 = Positive_Model(coeff_temp, new double[] { 0, 0, -alp, 0 });
double sum07 = GetDist(timeslot, Fluo_ex1, Fluo_th1);
Fluo_th1 = Positive_Model(coeff_temp, new double[] { 0, 0, 0, -alp });
double sum08 = GetDist(timeslot, Fluo_ex1, Fluo_th1);
double[] force = new double[4];
force[0] = (sum01 - sum05) / alp / 2 ;
force[1] = (sum02 - sum06) / alp / 2 ;
force[2] = (sum03 - sum07) / alp / 2 ;
force[3] = (sum04 - sum08) / alp / 2 ;
double step = -0.5;
double temp = 0;
for (int i = 0; i<4; i++)
{
temp += Math.Sqrt(Math.Pow(force[0], 2));
}
for (int i = 0; i<4; i++)
{
force[i] = force[i]*step/temp;
}
//double[] coeff_temp2 = new double[4];
// we dont even need this
Fluo_th1 = Positive_Model(coeff_temp, force);
double sum10 = GetDist(timeslot, Fluo_ex1, Fluo_th1);
if (sum10 > sum00 && sum00 < 1000)
{
flag = false;
}// we found a minima and can stop now
else
{
for (int i = 0; i < 4; i++)
{
coeff_temp[i] = coeff_temp[i] - force[i];
}// updates coeff_temp after each run
}
if(true)
{
Debugger.Text = Convert.ToString(sum00);
//plotting the results
//int[] x = new int[100];
//int[] y = new int[100];
chart1.Series["Series2"].Points.Clear();
//show the correct Fluo_th
Fluo_th1 = Positive_Model(coeff_temp, new double[] { 0, 0, 0, 0 });
for (int i = 0; i < totaltime + 1; i++)
{
//x[i] = i;
//y[i] = 2 * i + 1;
chart1.Series["Series2"].Points.AddXY(i, Fluo_th1[i]);
}
//original invalidate command, but can push this to bgworker
}
//update the progress on the debugger and plot
} // big while ends
//redraws the chart
chart1.Invalidate();
label6.Text = Convert.ToString(coeff_temp[0]);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
chart1.Invalidate();
}
}