IEnumerator EvalRun()
    {
        float err   = 0f;
        int   iTest = 1;

        proc.StartTest(param_list);

        while (!proc.IsDone())
        {
            yield return(new WaitForSeconds(waitSampleTest));
        }

        best_err = proc.GetErr();

        while (SumOfDp() > thresh)
        {
            for (int iParam = 0; iParam < dp.Length; iParam++)
            {
                if (focusOnSinglaParam != -1 && iParam != focusOnSinglaParam)
                {
                    continue;
                }

                param_list[iParam] += dp[iParam];

                Debug.Log(string.Format("Test {0} iParam {1}", iTest++, iParam));
                Debug.Log(string.Format("Param {0} dp {1}", param_list[iParam], dp[iParam]));

                proc.StartTest(param_list, best_err);

                while (!proc.IsDone())
                {
                    yield return(new WaitForSeconds(waitSampleTest));
                }

                err = proc.GetErr();

                if (err < best_err)
                {
                    best_err = err;

                    //try a larger change next time
                    dp[iParam] *= 1.1f;
                }
                else
                {
                    //try the same change but in the other direction.
                    param_list[iParam] -= 2 * dp[iParam];

                    Debug.Log(string.Format("Test {0} iParam {1}", iTest++, iParam));
                    Debug.Log(string.Format("Param {0} dp {1}", param_list[iParam], dp[iParam]));

                    proc.StartTest(param_list, best_err);

                    while (!proc.IsDone())
                    {
                        yield return(new WaitForSeconds(waitSampleTest));
                    }

                    err = proc.GetErr();

                    if (err < best_err)
                    {
                        best_err = err;

                        //error reduced, so try larger change in this dir.
                        dp[iParam] *= 1.1f;
                    }
                    else
                    {
                        //restore param to initial value
                        param_list[iParam] += dp[iParam];

                        //try smaller change.
                        dp[iParam] *= 0.9f;
                    }
                }
            }
        }
    }