Exemplo n.º 1
0
 public lsfitreport(lsfit.lsfitreport obj)
 {
     _innerobj = obj;
 }
Exemplo n.º 2
0
        private static bool buildlinearmodel(double[,] x,
            ref double[,] y,
            int n,
            int ny,
            int modeltype,
            ref double[,] v)
        {
            bool result = new bool();
            double[] tmpy = new double[0];
            double[,] a = new double[0,0];
            double scaling = 0;
            double[] shifting = new double[0];
            double mn = 0;
            double mx = 0;
            double[] c = new double[0];
            lsfit.lsfitreport rep = new lsfit.lsfitreport();
            int i = 0;
            int j = 0;
            int k = 0;
            int info = 0;

            v = new double[0,0];

            alglib.ap.assert(n>=0, "BuildLinearModel: N<0");
            alglib.ap.assert(ny>0, "BuildLinearModel: NY<=0");
            
            //
            // Handle degenerate case (N=0)
            //
            result = true;
            v = new double[ny, mxnx+1];
            if( n==0 )
            {
                for(j=0; j<=mxnx; j++)
                {
                    for(i=0; i<=ny-1; i++)
                    {
                        v[i,j] = 0;
                    }
                }
                return result;
            }
            
            //
            // Allocate temporaries
            //
            tmpy = new double[n];
            
            //
            // General linear model.
            //
            if( modeltype==1 )
            {
                
                //
                // Calculate scaling/shifting, transform variables, prepare LLS problem
                //
                a = new double[n, mxnx+1];
                shifting = new double[mxnx];
                scaling = 0;
                for(i=0; i<=mxnx-1; i++)
                {
                    mn = x[0,i];
                    mx = mn;
                    for(j=1; j<=n-1; j++)
                    {
                        if( (double)(mn)>(double)(x[j,i]) )
                        {
                            mn = x[j,i];
                        }
                        if( (double)(mx)<(double)(x[j,i]) )
                        {
                            mx = x[j,i];
                        }
                    }
                    scaling = Math.Max(scaling, mx-mn);
                    shifting[i] = 0.5*(mx+mn);
                }
                if( (double)(scaling)==(double)(0) )
                {
                    scaling = 1;
                }
                else
                {
                    scaling = 0.5*scaling;
                }
                for(i=0; i<=n-1; i++)
                {
                    for(j=0; j<=mxnx-1; j++)
                    {
                        a[i,j] = (x[i,j]-shifting[j])/scaling;
                    }
                }
                for(i=0; i<=n-1; i++)
                {
                    a[i,mxnx] = 1;
                }
                
                //
                // Solve linear system in transformed variables, make backward 
                //
                for(i=0; i<=ny-1; i++)
                {
                    for(j=0; j<=n-1; j++)
                    {
                        tmpy[j] = y[j,i];
                    }
                    lsfit.lsfitlinear(tmpy, a, n, mxnx+1, ref info, ref c, rep);
                    if( info<=0 )
                    {
                        result = false;
                        return result;
                    }
                    for(j=0; j<=mxnx-1; j++)
                    {
                        v[i,j] = c[j]/scaling;
                    }
                    v[i,mxnx] = c[mxnx];
                    for(j=0; j<=mxnx-1; j++)
                    {
                        v[i,mxnx] = v[i,mxnx]-shifting[j]*v[i,j];
                    }
                    for(j=0; j<=n-1; j++)
                    {
                        for(k=0; k<=mxnx-1; k++)
                        {
                            y[j,i] = y[j,i]-x[j,k]*v[i,k];
                        }
                        y[j,i] = y[j,i]-v[i,mxnx];
                    }
                }
                return result;
            }
            
            //
            // Constant model, very simple
            //
            if( modeltype==2 )
            {
                for(i=0; i<=ny-1; i++)
                {
                    for(j=0; j<=mxnx; j++)
                    {
                        v[i,j] = 0;
                    }
                    for(j=0; j<=n-1; j++)
                    {
                        v[i,mxnx] = v[i,mxnx]+y[j,i];
                    }
                    if( n>0 )
                    {
                        v[i,mxnx] = v[i,mxnx]/n;
                    }
                    for(j=0; j<=n-1; j++)
                    {
                        y[j,i] = y[j,i]-v[i,mxnx];
                    }
                }
                return result;
            }
            
            //
            // Zero model
            //
            alglib.ap.assert(modeltype==3, "BuildLinearModel: unknown model type");
            for(i=0; i<=ny-1; i++)
            {
                for(j=0; j<=mxnx; j++)
                {
                    v[i,j] = 0;
                }
            }
            return result;
        }
Exemplo n.º 3
0
        private void Calculate (bool recalc, string filename)
        {
                        
            
            //FILE fin = fopen("obs.dat", "r");
            
            //double Fi=43.7486111;   //{иЁа®в  ¬Ґбв  ­ Ў«о¤Ґ­Ёп ў Ја ¤гб е}
            //double Lamb=2.844444;  //{¤®«Ј®в  ¬Ґбв  ­ Ў«о¤Ґ­Ёп ў з б е}
            //double Fi = 59.4612;
            //double Lamb = 2 + 0.021944444444444444444444444443778;


            if (cbMethod.SelectedIndex == -1)
            {
                MessageBox.Show("Не выбран метод решения");
                return;
            }
            
            System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("ru-RU");
            int method = cbMethod.SelectedIndex;

            
            lObserv.Items.Clear();
            lOper2.Items.Clear();


            string ftscope = "e:\\1\\dpas\\MTM500M.dat";
            ftscope = tfiletscope.Text;
            if (ftscope == "")
            {
                MessageBox.Show("Выберите файл с настройками телескопа");
                return;
            }
            StreamReader finmtm = new StreamReader(ftscope);
            char[] separator = new char[] { (char)09, (char)32, '/', ':' };
            string line;
            string[] pars;
            line = finmtm.ReadLine();
            pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            int Dt = Convert.ToInt32(pars[0]);
            line = finmtm.ReadLine();
            pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            int JD_R = Convert.ToInt32(pars[0]);
            line = finmtm.ReadLine();
            line = line.Replace(".", ci.NumberFormat.NumberDecimalSeparator);
            line = line.Replace(",", ci.NumberFormat.NumberDecimalSeparator);
            pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            double Temp = Convert.ToDouble(pars[0]);
            line = finmtm.ReadLine();
            line = line.Replace(".", ci.NumberFormat.NumberDecimalSeparator);
            line = line.Replace(",", ci.NumberFormat.NumberDecimalSeparator);
            pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            double Dav = Convert.ToDouble(pars[0]);
            /*line = finmtm.ReadLine();
            pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            int God0 = Convert.ToInt32(pars[0]);
            int Mes0 = Convert.ToInt32(pars[1]);
            int Den0 = Convert.ToInt32(pars[2]);
            int Hour0 = Convert.ToInt32(pars[3]);
            int Min0 = Convert.ToInt32(pars[4]);
            line = finmtm.ReadLine();
            line = line.Replace(".", ci.NumberFormat.NumberDecimalSeparator);
            line = line.Replace(",", ci.NumberFormat.NumberDecimalSeparator);
            pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            double ds0 = Convert.ToDouble(pars[0]);
            double V = Convert.ToDouble(pars[1]);*/
            line = finmtm.ReadLine();
            line = line.Replace(".", ci.NumberFormat.NumberDecimalSeparator);
            line = line.Replace(",", ci.NumberFormat.NumberDecimalSeparator);
            pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            double Fi = Convert.ToDouble(pars[0]);
            line = finmtm.ReadLine();
            line = line.Replace(".", ci.NumberFormat.NumberDecimalSeparator);
            line = line.Replace(",", ci.NumberFormat.NumberDecimalSeparator);
            pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            double Lamb = Convert.ToDouble(pars[0]);
            line = finmtm.ReadLine();
            line = line.Replace(".", ci.NumberFormat.NumberDecimalSeparator);
            line = line.Replace(",", ci.NumberFormat.NumberDecimalSeparator);
            pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            double ex_t = Convert.ToDouble(pars[0]);
            double Eex_t = Convert.ToDouble(pars[1]);
            line = finmtm.ReadLine();
            line = line.Replace(".", ci.NumberFormat.NumberDecimalSeparator);
            line = line.Replace(",", ci.NumberFormat.NumberDecimalSeparator);
            pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            double ex_d = Convert.ToDouble(pars[0]);
            double Eex_d = Convert.ToDouble(pars[1]);



            string fobs;
            int ii2;
            StreamReader fin2;

            if (recalc == false)
            {
                //StreamReader fin = new StreamReader("obs.dat");
                bool loggerfile = false;

                Fform2.lResult.Clear();
                fobs = tfileobs.Text;
                if (fobs == "")
                {
                    MessageBox.Show("Выберите файл с наблюдениями");
                    return;
                }
                fin2 = new StreamReader(fobs);
                line = "";
                ii2 = 0;
                line = fin2.ReadLine();
                if (line.IndexOf("Log") != -1)
                {
                    loggerfile = true;
                }

                if (loggerfile == true)
                {
                    progressBar1.Visible = true;
                    System.IO.FileInfo fi = new System.IO.FileInfo(fobs);
                    progressBar1.Maximum = (int)fi.Length;
                    progressBar1.Value = 0;
                    string fobsnew = LoggerToObs(fobs);
                    fobs = fobsnew;
                    progressBar1.Visible = false;
                    fin2.Close();
                    fin2 = new StreamReader(fobs);
                    line = "";
                    line = fin2.ReadLine();
                }

            }

            else //recalc==true
            {
                fobs = filename;
                fin2 = new StreamReader(fobs);
                line = "";
                ii2 = 0;
                line = fin2.ReadLine();
            }
            
            
            while (line != null)
            {
                
                ii2++;
                line = fin2.ReadLine();
            }
            
            fin2.Close();


            if (recalc == false)
            {
                FileInfo fn = new FileInfo(fobs);
                fobs = fobs + ".temp";
                fn.CopyTo(fobs, true);
            }
            
            int NN = ii2 * 2;
            int MM=0;
            if (method == 0) MM = 8;
            if (method == 1) // пр. восхождение
            {
                MM = 6;
                NN = NN / 2;
            }
            if (method == 2) // сколонение
            {
                MM = 4;
                NN = NN / 2;
            }

            StreamReader fin = new StreamReader(fobs);
            separator = new char[] { (char)09, (char)32, '/', ':' };
            double[] OC=new double [NN];
            double[] y = new double[NN];
            double[,] Fmatrix=new double[NN,MM];//8,36
            double[] c = new double[NN];//36
            lsfit.lsfitreport rep = new lsfit.lsfitreport();
            int info = 0;
            int i_count = 0;
            double Delta=0;
            lOper.Items.Clear();
            dg1.RowCount = MM;
            dg1.ColumnCount = 3;
            if (recalc == false)
            {
                for (int i = 0; i < dg1.RowCount; i++)
                {
                    dg1[0, i].Value = 1;
                }
            }
            else
            {
                int method_old = Convert.ToInt32((lSummary.Items[0].ToString())[7]) - 48;
                if (method != method_old)
                {
                    for (int i = 0; i < dg1.RowCount; i++)
                    {
                        dg1[0, i].Value = 1;
                    }
                }
                   
            }
            lSummary.Items.Clear();
           
            dg1.Columns[1].Width = 225;
            dg2.RowCount = NN;
            dg2.ColumnCount = 9;
            
            dg2.Columns[0].Name = "Number";
            dg2.Columns[1].Name = "Observation";
            dg2.Columns[2].Name = "Calculation";
            dg2.Columns[3].Name = "O-C";
            dg2.Columns[4].Name = "Alpha";
            dg2.Columns[5].Name = "Delta";
            dg2.Columns[6].Name = "T";
            dg2.Columns[7].Name = "Delta";
            dg2.Columns[8].Name = "Alpha";


            //MessageBox.Show(Convert.ToString(((CheckBox)dg1[0,0].Value).Checked));
               // MessageBox.Show(Convert.ToString(dg1[0,0].Value));
            
            int Alf1,Alf2,Delt1,Delt2;
            double Alf3,Delt3;
            
            while ((line = fin.ReadLine()) != null)
            {
                
                line = line.Replace(".", ci.NumberFormat.NumberDecimalSeparator);
                line = line.Replace(",", ci.NumberFormat.NumberDecimalSeparator);
                lOper2.Items.Add(line);
                pars = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);

                //Разбиваешь на составляющие. Дальше работаешь с массивом строк pars
                //textBox1.Text = Convert.ToString(pars.Length);
                int God=Convert.ToInt32(pars[0]);
                int Mes=Convert.ToInt32(pars[1]);
                int Den=Convert.ToInt32(pars[2]);
                int Hour=Convert.ToInt32(pars[3]);
                int Min=Convert.ToInt32(pars[4]);
                //double ss = Convert.ToDouble("11,1");
                pars[5]=pars[5].Replace(".", ci.NumberFormat.NumberDecimalSeparator);
                pars[5]=pars[5].Replace(",", ci.NumberFormat.NumberDecimalSeparator);
                double Sec=Convert.ToDouble(pars[5]);
                int NWE=Convert.ToInt32(pars[6]);
                Alf1=Convert.ToInt32(pars[7]);
                Alf2=Convert.ToInt32(pars[8]);
                pars[9]=pars[9].Replace(".", ci.NumberFormat.NumberDecimalSeparator);
                pars[9]=pars[9].Replace(",", ci.NumberFormat.NumberDecimalSeparator);
                Alf3=Convert.ToDouble(pars[9]);
                Delt1=Convert.ToInt32(pars[10]);
                Delt2=Convert.ToInt32(pars[11]);
                pars[12]=pars[12].Replace(".", ci.NumberFormat.NumberDecimalSeparator);
                pars[12]=pars[12].Replace(",", ci.NumberFormat.NumberDecimalSeparator);
                Delt3=Convert.ToDouble(pars[12]);
                double t1=Convert.ToDouble(pars[13]);
                double t2=Convert.ToDouble(pars[14]);
                double t3=Convert.ToDouble(pars[15]);
                double d1=Convert.ToDouble(pars[16]);
                double d2=Convert.ToDouble(pars[17]);
                double d3=Convert.ToDouble(pars[18]);
                int dtt=Convert.ToInt32(pars[19]);
                int ddd=Convert.ToInt32(pars[20]);

                double tin=t1+t2/60.0+t3/3600.0;
                double din=d1+d2/60.0+d3/3600.0;
                string WE;
                int Znnn = 1;
                if (NWE == 1)
                {
                    WE = "W";
                    Znnn = -1;
                }
                else
                {
                    WE = "E";
                    Znnn = 1;
                }
                int Zn_Delt = 1;
                if (Delt1 < 0)
                {
                    Zn_Delt = -1;
                    Delt1 = Math.Abs(Delt1);
                }
                if ((Delt1 == 0) && (Delt2 < 0))
                {
                    Zn_Delt = -1;
                    Delt2 = Math.Abs(Delt2);
                }
                if ((Delt1 == 0) && (Delt2 == 0) && (Delt3 < 0))
                {
                    Zn_Delt = -1;
                    Delt3 = Math.Abs(Delt3);
                }
                Delta = Zn_Delt * (Delt1 + Delt2 / 60.0 + Delt3 / 3600.0);
//                Delta = (Delt1 + Delt2 / 60.0 + Delt3 / 3600.0);

                Mathgr Mgr=new Mathgr();
                double dt_CCD=0;
                double dd_CCD = 0;
                if (NWE == 1)
                {
                    dt_CCD = -1.205 * ((dtt - 512.0) / Mgr.cos(Delta)) / 15.0;
                    dd_CCD = -1.205 * (ddd - 512.0);
                }
                if (NWE == 2)
                {
                    dt_CCD = 1.205 * ((dtt - 512.0) / Mgr.cos(Delta)) / 15.0;
                    dd_CCD = 1.205 * (ddd - 512.0);
                }

                Alf3 = Alf3 + dt_CCD;
                Delt3 = Delt3 + dd_CCD;
                
                //Delta = Zn_Delt * (Delt1 + Delt2 / 60.0 + Delt3 / 3600.0);
                
                Telescope Tscope = new Telescope();
                Tscope.Fi = Fi;
                Tscope.Lamb = Lamb;
                Tscope.Dt = Dt;
                Tscope.Temp = Temp;
                Tscope.Dav = Dav;
                Tscope.ex_t = ex_t;
                Tscope.ex_d = ex_d;
                Tscope.Eex_t = Eex_t;
                Tscope.Eex_d = Eex_d;
                Tscope.JD_R = JD_R;
                Tscope.Alf1 = Alf1;
                Tscope.Alf2 = Alf2;
                Tscope.Alf3 = Alf3;
                Tscope.WE = WE;
                Tscope.Zn_Delt = Zn_Delt;
                Tscope.Delt1 = Delt1;
                Tscope.Delt2 = Delt2;
                Tscope.Delt3 = Delt3;
                Tscope.God = God;
                Tscope.Mes = Mes;
                Tscope.Den = Den;
                Tscope.Hour = Hour;
                Tscope.Min = Min;
                Tscope.Sec = Sec;
                Tscope.Ustanovka();
                Type type = Tscope.GetType();
                BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
                PropertyInfo[] properties = type.GetProperties(flags);

                dg2[4, i_count].Value = Convert.ToString(Alf1) + " " + Convert.ToString(Alf2) + " " + Convert.ToString(Alf3);
                dg2[5, i_count].Value = Convert.ToString(Delt1) + " " + Convert.ToString(Delt2) + " " + Convert.ToString(Delt3);
                dg2[6, i_count].Value = Convert.ToString(Tscope.t);
                dg2[7, i_count].Value = Convert.ToString(Delta);
                double Alff=(Alf1 + Alf2 / 60.0 + Alf3 / 3600.0);
                dg2[8, i_count].Value = Convert.ToString(Alff);
                

               /* foreach (PropertyInfo property in properties)
                {

                    lOper.Items.Add("1");
                    lOper.Items.Add("Name: " + property.Name + ", Value: " + property.GetValue(Tscope, null));
                    //Console.WriteLine();
                }
                */
                
                //Tscope.Ustanovka(Fi,Lamb,Dt,WE,Temp,Dav,ex_t,Eex_t,ex_d,Eex_d,God0,Mes0,Den0,Hour0,Min0,ds0,V,JD_R,Alf1,Alf2,Alf3,Zn_Delt,Delt1,Delt2,Delt3,God,Mes,Den,Hour,Min,Sec);
                


                /*public static void lsfitlinear(ref double[] y,
    ref double[,] fmatrix,
    int n,
    int m,
    ref int info,
    ref double[] c,
    ref lsfitreport rep)*/
                if (method == 0)
                {

                    dg1[1, 0].Value = "Нуль-пункт по склонению";
                    dg1[1, 1].Value = "Установки пол.оси по азимуту";
                    dg1[1, 2].Value = "Установки пол.оси по широте (склонению)";
                    dg1[1, 3].Value = "Нуль-пункт по часовому углу";
                    dg1[1, 4].Value = "Наклонности";
                    dg1[1, 5].Value = "Коллимации";
                    dg1[1, 6].Value = "Гнутия по склонению";
                    dg1[1, 7].Value = "Гнутия по прямому восхождению";

                    Fmatrix[i_count, 0] = -1.0;
                    Fmatrix[i_count, 1] = Znnn * Mgr.cos(Fi) * Mgr.cos(15.0 * Tscope.t);
                    Fmatrix[i_count, 2] = Znnn * Mgr.sin(15.0 * Tscope.t);
                    Fmatrix[i_count, 3] = 0;
                    Fmatrix[i_count, 4] = 0;
                    Fmatrix[i_count, 5] = 0;
                    Fmatrix[i_count, 6] = Znnn * (-Mgr.sin(Fi) * Mgr.cos(Delta) - Mgr.cos(Fi) * Mgr.sin(Delta) * Mgr.cos(15.0 * Tscope.t));
                    Fmatrix[i_count, 7] = 0;

                    
                    // Fmatrix[i_count, 8] = 0;
                    // Fmatrix[i_count, 9] = 0;

                    Fmatrix[i_count + 1, 0] = 0;
                    Fmatrix[i_count + 1, 1] = Mgr.cos(Fi) * Mgr.sin(15.0 * Tscope.t) * Mgr.tn(Delta);
                    Fmatrix[i_count + 1, 2] = -Mgr.cos(15.0 * Tscope.t) * Mgr.tn(Delta);
                    Fmatrix[i_count + 1, 3] = 1.0;
                    Fmatrix[i_count + 1, 4] = (NWE == 1) ? Mgr.tn(Delta) : -Mgr.tn(Delta);
                    Fmatrix[i_count + 1, 5] = (NWE == 1) ? 1.0 / Mgr.cos(Delta) : -1.0 / Mgr.cos(Delta);
                    Fmatrix[i_count + 1, 6] = Mgr.sin(Fi) * Mgr.cos(Fi) * Mgr.sin(Delta) * Mgr.tn(Delta) + Mgr.cos(Fi) * Mgr.cos(15.0 * Tscope.t) * Mgr.cos(Fi) * Mgr.sin(Delta);
                    if (NWE != 1)
                    {
                        Fmatrix[i_count + 1, 6] = -Fmatrix[i_count + 1, 6];
                    }


                    Fmatrix[i_count + 1, 7] = Mgr.cos(Fi) * Mgr.sin(15.0 * Tscope.t) / Mgr.cos(Delta);

                    for (int j = 0; j < dg1.RowCount; j++)
                    {
                        Fmatrix[i_count, j] *= Convert.ToInt32(dg1[0, j].Value);
                        Fmatrix[i_count+1, j] *= Convert.ToInt32(dg1[0, j].Value);
                    }
                    
                    OC[i_count] = din - Tscope.DeltaL2;
                    OC[i_count + 1] = tin - Tscope.tL2;
                    lOper.Items.Add(Convert.ToString(Sec) + " " + Convert.ToString(i_count) + "   " + Convert.ToString(OC[i_count + 1]) + "   " + Convert.ToString(OC[i_count]) + "   " + Convert.ToString(Tscope.t) + "   " + Convert.ToString(Tscope.tL2) + "   " + Convert.ToString(Tscope.DeltaL2));
                    

                    i_count += 2;
                } //if

                if (method == 1)
                {
                    dg1[1, 0].Value = "Нуль пункт по часовому углу";
                    dg1[1, 1].Value = "Установки пол.оси по азимуту";
                    dg1[1, 2].Value = "Установки пол.оси по широте";
                    dg1[1, 3].Value = "Наклонности";
                    dg1[1, 4].Value = "Коллимации";
                    dg1[1, 5].Value = "Гнутия по прямому восхождению";
                    

                    Fmatrix[i_count, 0] = 1.0;
                    Fmatrix[i_count, 1] = Mgr.cos(Fi) * Mgr.sin(15.0 * Tscope.t) * Mgr.tn(Delta);
                    Fmatrix[i_count, 2] = -Mgr.cos(15.0 * Tscope.t) * Mgr.tn(Delta);
                    Fmatrix[i_count, 3] = (NWE == 1) ? Mgr.tn(Delta) : -Mgr.tn(Delta);
                    Fmatrix[i_count, 4] = (NWE == 1) ? 1.0 / Mgr.cos(Delta) : -1 / Mgr.cos(Delta);
                    Fmatrix[i_count, 5] = Mgr.cos(Fi) * Mgr.sin(15.0 * Tscope.t) / Mgr.cos(Delta);

                    for (int j = 0; j < dg1.RowCount; j++)
                    {
                        Fmatrix[i_count, j] *= Convert.ToInt32(dg1[0, j].Value);
                    }


                    OC[i_count] = tin - Tscope.tL2 + PopHor2(PopHor(Tscope.t), PopVert(Tscope.t)) / 60 + PopVert2(PopHor(Tscope.t), PopVert(Tscope.t)) / 60;
                    lOper.Items.Add(Convert.ToString(Sec) + " " + Convert.ToString(i_count) + "   " +  "   " + Convert.ToString(OC[i_count]) + "   " + Convert.ToString(Tscope.t) + "   " + Convert.ToString(Tscope.tL2) + "   " + Convert.ToString(Tscope.DeltaL2));
                    i_count += 1;
                }

                if (method == 2)
                {
                    dg1[1, 0].Value = "Нуль-пункт по склонению";
                    dg1[1, 1].Value = "Установки пол.оси по азимуту";
                    dg1[1, 2].Value = "Установки пол.оси по склонению";
                    dg1[1, 3].Value = "Гнутия по склонению";
                    
                    Fmatrix[i_count, 0] = -1.0;
                    Fmatrix[i_count, 1] = Znnn * Mgr.cos(Fi) * Mgr.cos(15.0 * Tscope.t);
                    Fmatrix[i_count, 2] = Znnn * Mgr.sin(15.0 * Tscope.t);
                    Fmatrix[i_count, 3] = Znnn * (-Mgr.sin(Fi) * Mgr.cos(Delta) - Mgr.cos(Fi) * Mgr.sin(Delta) * Mgr.cos(15.0 * Tscope.t));

                    for (int j = 0; j < dg1.RowCount; j++)
                    {
                        Fmatrix[i_count, j] *= Convert.ToInt32(dg1[0, j].Value);
                    }

                    OC[i_count] = din - Tscope.DeltaL2;
                    lOper.Items.Add(Convert.ToString(Sec) + " " + Convert.ToString(i_count) + "   "+ "   " + Convert.ToString(OC[i_count]) + "   " + Convert.ToString(Tscope.t) + "   " + Convert.ToString(Tscope.tL2) + "   " + Convert.ToString(Tscope.DeltaL2));
                    i_count += 1;
                }

                
            
            } //while

            //Start least squares method
            //MessageBox.Show(Convert.ToString(i_count));
            lsfit.lsfitlinear(ref OC, ref Fmatrix, i_count, MM, ref info, ref c, ref rep);
            //MessageBox.Show(Convert.ToString(info));
            for (int ii = 0; ii < MM; ii++)
            {
                dg1[2, ii].Value = Math.Round(c[ii]*60,5);
                lOper.Items.Add(Convert.ToString(c[ii]));
            }
            lOper.Items.Add(" ");
            lSummary.Items.Add("Method " + Convert.ToString(method)); //7th symbol 
            lSummary.Items.Add("FileName " + fobs);
            lSummary.Items.Add("Average error     " + Convert.ToString(rep.avgerror*60));
            lSummary.Items.Add("Maximum error     "+Convert.ToString(rep.maxerror*60));


            lOper.Items.Add(rep.avgerror);
            lOper.Items.Add(rep.maxerror);
            // zdes' budem probivat' schitat' nevyazku
            for (int ii = 0; ii < NN; ii++)
            {
                double ypol=0;
                for (int jj = 0; jj < MM; jj++)
                {
                    ypol += Fmatrix[ii, jj] * c[jj];
                }
                lOper.Items.Add(OC[ii]-ypol);
                //dg2[0, ii].Value = (int)ii / 2;
                if (method == 0) dg2[0, ii].Value = (int)ii / 2;
                else dg2[0, ii].Value = ii;

                dg2[1, ii].Value = Math.Round(OC[ii]*60,5);
                dg2[2, ii].Value = Math.Round(ypol*60,5);
                dg2[3, ii].Value = Math.Round((OC[ii] - ypol)*60,5);



                /*for (int jj = 0; jj < 4; jj++)
                {
                    if (Math.Abs(OC[ii] - ypol) / 5 > rep.avgerror)
                    {
                        dg2[jj, ii].Style.BackColor = Color.Red;
                    }
                }*/
            }


            Fform2.lResult.Text += "\n";
            
            Fform2.lResult.Text += "---------------------------";
            Fform2.lResult.Text += "\n";
                     

            for (int i = 0; i < dg1.RowCount; i++)
            {
                string str = "";
                for (int j = 0; j < dg1.ColumnCount; j++)
                {
                    str += dg1[j, i].Value + "   ";
                }
                Fform2.lResult.Text += (str+"\n");
            }
            

            //Обработка и раскраска
            double xav = 0;
            for (int ii = 0; ii < dg2.Rows.Count; ii++)
            {
                xav += Convert.ToDouble(dg2[3, ii].Value);
            }
            xav = xav / dg2.Rows.Count;
           
            double ss = 0;
            for (int ii = 0; ii < dg2.Rows.Count; ii++)
            {
                ss += (Convert.ToDouble(dg2[3, ii].Value) - xav) * (Convert.ToDouble(dg2[3, ii].Value) - xav);
            }
            double ss2 = Math.Sqrt(ss / dg2.Rows.Count);

            for (int ii = 0; ii < dg2.Rows.Count; ii++)
            {
                if (Math.Abs(Convert.ToDouble(dg2[3, ii].Value)) > 3*ss2)
                {
                    for (int jj = 0; jj < 6; jj++)
                    {
                        dg2[jj, ii].Style.BackColor = Color.Red;
                    }
                }
            }




            fin.Close();
        }
Exemplo n.º 4
0
 public lsfitreport()
 {
     _innerobj = new lsfit.lsfitreport();
 }
Exemplo n.º 5
0
        /*************************************************************************
        *  Internal Floater-Hormann fitting subroutine for fixed D
        *************************************************************************/
        private static void barycentricfitwcfixedd(double[] x,
                                                   double[] y,
                                                   ref double[] w,
                                                   int n,
                                                   double[] xc,
                                                   double[] yc,
                                                   ref int[] dc,
                                                   int k,
                                                   int m,
                                                   int d,
                                                   ref int info,
                                                   ref barycentricinterpolant b,
                                                   ref barycentricfitreport rep)
        {
            double[,] fmatrix = new double[0, 0];
            double[,] cmatrix = new double[0, 0];
            double[]               y2        = new double[0];
            double[]               w2        = new double[0];
            double[]               sx        = new double[0];
            double[]               sy        = new double[0];
            double[]               sbf       = new double[0];
            double[]               xoriginal = new double[0];
            double[]               yoriginal = new double[0];
            double[]               tmp       = new double[0];
            lsfit.lsfitreport      lrep      = new lsfit.lsfitreport();
            double                 v0        = 0;
            double                 v1        = 0;
            double                 mx        = 0;
            barycentricinterpolant b2        = new barycentricinterpolant();
            int    i      = 0;
            int    j      = 0;
            int    relcnt = 0;
            double xa     = 0;
            double xb     = 0;
            double sa     = 0;
            double sb     = 0;
            double decay  = 0;
            int    i_     = 0;

            x  = (double[])x.Clone();
            y  = (double[])y.Clone();
            xc = (double[])xc.Clone();
            yc = (double[])yc.Clone();

            if (n < 1 | m < 2 | k < 0 | k >= m)
            {
                info = -1;
                return;
            }
            for (i = 0; i <= k - 1; i++)
            {
                info = 0;
                if (dc[i] < 0)
                {
                    info = -1;
                }
                if (dc[i] > 1)
                {
                    info = -1;
                }
                if (info < 0)
                {
                    return;
                }
            }

            //
            // weight decay for correct handling of task which becomes
            // degenerate after constraints are applied
            //
            decay = 10000 * AP.Math.MachineEpsilon;

            //
            // Scale X, Y, XC, YC
            //
            lsfit.lsfitscalexy(ref x, ref y, n, ref xc, ref yc, ref dc, k, ref xa, ref xb, ref sa, ref sb, ref xoriginal, ref yoriginal);

            //
            // allocate space, initialize:
            // * FMatrix-   values of basis functions at X[]
            // * CMatrix-   values (derivatives) of basis functions at XC[]
            //
            y2      = new double[n + m];
            w2      = new double[n + m];
            fmatrix = new double[n + m, m];
            if (k > 0)
            {
                cmatrix = new double[k, m + 1];
            }
            y2 = new double[n + m];
            w2 = new double[n + m];

            //
            // Prepare design and constraints matrices:
            // * fill constraints matrix
            // * fill first N rows of design matrix with values
            // * fill next M rows of design matrix with regularizing term
            // * append M zeros to Y
            // * append M elements, mean(abs(W)) each, to W
            //
            sx  = new double[m];
            sy  = new double[m];
            sbf = new double[m];
            for (j = 0; j <= m - 1; j++)
            {
                sx[j] = (double)(2 * j) / ((double)(m - 1)) - 1;
            }
            for (i = 0; i <= m - 1; i++)
            {
                sy[i] = 1;
            }
            barycentricbuildfloaterhormann(ref sx, ref sy, m, d, ref b2);
            mx = 0;
            for (i = 0; i <= n - 1; i++)
            {
                barycentriccalcbasis(ref b2, x[i], ref sbf);
                for (i_ = 0; i_ <= m - 1; i_++)
                {
                    fmatrix[i, i_] = sbf[i_];
                }
                y2[i] = y[i];
                w2[i] = w[i];
                mx    = mx + Math.Abs(w[i]) / n;
            }
            for (i = 0; i <= m - 1; i++)
            {
                for (j = 0; j <= m - 1; j++)
                {
                    if (i == j)
                    {
                        fmatrix[n + i, j] = decay;
                    }
                    else
                    {
                        fmatrix[n + i, j] = 0;
                    }
                }
                y2[n + i] = 0;
                w2[n + i] = mx;
            }
            if (k > 0)
            {
                for (j = 0; j <= m - 1; j++)
                {
                    for (i = 0; i <= m - 1; i++)
                    {
                        sy[i] = 0;
                    }
                    sy[j] = 1;
                    barycentricbuildfloaterhormann(ref sx, ref sy, m, d, ref b2);
                    for (i = 0; i <= k - 1; i++)
                    {
                        System.Diagnostics.Debug.Assert(dc[i] >= 0 & dc[i] <= 1, "BarycentricFit: internal error!");
                        barycentricdiff1(ref b2, xc[i], ref v0, ref v1);
                        if (dc[i] == 0)
                        {
                            cmatrix[i, j] = v0;
                        }
                        if (dc[i] == 1)
                        {
                            cmatrix[i, j] = v1;
                        }
                    }
                }
                for (i = 0; i <= k - 1; i++)
                {
                    cmatrix[i, m] = yc[i];
                }
            }

            //
            // Solve constrained task
            //
            if (k > 0)
            {
                //
                // solve using regularization
                //
                lsfit.lsfitlinearwc(y2, ref w2, ref fmatrix, cmatrix, n + m, m, k, ref info, ref tmp, ref lrep);
            }
            else
            {
                //
                // no constraints, no regularization needed
                //
                lsfit.lsfitlinearwc(y, ref w, ref fmatrix, cmatrix, n, m, k, ref info, ref tmp, ref lrep);
            }
            if (info < 0)
            {
                return;
            }

            //
            // Generate interpolant and scale it
            //
            for (i_ = 0; i_ <= m - 1; i_++)
            {
                sy[i_] = tmp[i_];
            }
            barycentricbuildfloaterhormann(ref sx, ref sy, m, d, ref b);
            barycentriclintransx(ref b, 2 / (xb - xa), -((xa + xb) / (xb - xa)));
            barycentriclintransy(ref b, sb - sa, sa);

            //
            // Scale absolute errors obtained from LSFitLinearW.
            // Relative error should be calculated separately
            // (because of shifting/scaling of the task)
            //
            rep.taskrcond   = lrep.taskrcond;
            rep.rmserror    = lrep.rmserror * (sb - sa);
            rep.avgerror    = lrep.avgerror * (sb - sa);
            rep.maxerror    = lrep.maxerror * (sb - sa);
            rep.avgrelerror = 0;
            relcnt          = 0;
            for (i = 0; i <= n - 1; i++)
            {
                if ((double)(yoriginal[i]) != (double)(0))
                {
                    rep.avgrelerror = rep.avgrelerror + Math.Abs(barycentriccalc(ref b, xoriginal[i]) - yoriginal[i]) / Math.Abs(yoriginal[i]);
                    relcnt          = relcnt + 1;
                }
            }
            if (relcnt != 0)
            {
                rep.avgrelerror = rep.avgrelerror / relcnt;
            }
        }
Exemplo n.º 6
0
    public static int Main(string[] args)
    {
        int m = 0;
        int n = 0;
        int k = 0;

        double[] y = new double[0];
        double[,] x = new double[0, 0];
        double[]          c     = new double[0];
        lsfit.lsfitreport rep   = new lsfit.lsfitreport();
        lsfit.lsfitstate  state = new lsfit.lsfitstate();
        int    info             = 0;
        double epsf             = 0;
        double epsx             = 0;
        int    maxits           = 0;
        int    i = 0;
        int    j = 0;
        double a = 0;
        double b = 0;

        System.Console.Write("Fitting 0.5(1+cos(x)) on [-pi,+pi] with exp(-alpha*x^2)");
        System.Console.WriteLine();

        //
        // Fitting 0.5(1+cos(x)) on [-pi,+pi] with Gaussian exp(-alpha*x^2):
        // * without Hessian (gradient only)
        // * using alpha=1 as initial value
        // * using 1000 uniformly distributed points to fit to
        //
        // Notes:
        // * N - number of points
        // * M - dimension of space where points reside
        // * K - number of parameters being fitted
        //
        n = 1000;
        m = 1;
        k = 1;
        a = -Math.PI;
        b = +Math.PI;

        //
        // Prepare task matrix
        //
        y = new double[n];
        x = new double[n, m];
        c = new double[k];
        for (i = 0; i <= n - 1; i++)
        {
            x[i, 0] = a + (b - a) * i / (n - 1);
            y[i]    = 0.5 * (1 + Math.Cos(x[i, 0]));
        }
        c[0]   = 1.0;
        epsf   = 0.0;
        epsx   = 0.0001;
        maxits = 0;

        //
        // Solve
        //
        lsfit.lsfitnonlinearfg(ref x, ref y, ref c, n, m, k, true, ref state);
        lsfit.lsfitnonlinearsetcond(ref state, epsf, epsx, maxits);
        while (lsfit.lsfitnonlineariteration(ref state))
        {
            if (state.needf)
            {
                //
                // F(x) = Exp(-alpha*x^2)
                //
                state.f = Math.Exp(-(state.c[0] * AP.Math.Sqr(state.x[0])));
            }
            if (state.needfg)
            {
                //
                // F(x)      = Exp(-alpha*x^2)
                // dF/dAlpha = (-x^2)*Exp(-alpha*x^2)
                //
                state.f    = Math.Exp(-(state.c[0] * AP.Math.Sqr(state.x[0])));
                state.g[0] = -(AP.Math.Sqr(state.x[0]) * state.f);
            }
        }
        lsfit.lsfitnonlinearresults(ref state, ref info, ref c, ref rep);
        System.Console.Write("alpha:   ");
        System.Console.Write("{0,0:F3}", c[0]);
        System.Console.WriteLine();
        System.Console.Write("rms.err: ");
        System.Console.Write("{0,0:F3}", rep.rmserror);
        System.Console.WriteLine();
        System.Console.Write("max.err: ");
        System.Console.Write("{0,0:F3}", rep.maxerror);
        System.Console.WriteLine();
        System.Console.Write("Termination type: ");
        System.Console.Write("{0,0:d}", info);
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.WriteLine();
        return(0);
    }
Exemplo n.º 7
0
        public static bool testlls(bool silent)
        {
            bool   result      = new bool();
            bool   waserrors   = new bool();
            bool   llserrors   = new bool();
            bool   nlserrors   = new bool();
            double threshold   = 0;
            double nlthreshold = 0;
            int    maxn        = 0;
            int    maxm        = 0;
            int    passcount   = 0;
            int    n           = 0;
            int    m           = 0;
            int    i           = 0;
            int    j           = 0;
            int    k           = 0;
            int    pass        = 0;
            double xscale      = 0;

            double[] x  = new double[0];
            double[] y  = new double[0];
            double[] w  = new double[0];
            double[] w2 = new double[0];
            double[] c  = new double[0];
            double[] c2 = new double[0];
            double[,] a  = new double[0, 0];
            double[,] a2 = new double[0, 0];
            double[,] cm = new double[0, 0];
            double v  = 0;
            double v1 = 0;
            double v2 = 0;

            lsfit.lsfitreport rep  = new lsfit.lsfitreport();
            lsfit.lsfitreport rep2 = new lsfit.lsfitreport();
            int    info            = 0;
            int    info2           = 0;
            double refrms          = 0;
            double refavg          = 0;
            double refavgrel       = 0;
            double refmax          = 0;

            lsfit.lsfitstate state = new lsfit.lsfitstate();

            waserrors   = false;
            llserrors   = false;
            nlserrors   = false;
            threshold   = 10000 * AP.Math.MachineEpsilon;
            nlthreshold = 0.00001;
            maxn        = 6;
            maxm        = 6;
            passcount   = 4;

            //
            // Testing unconstrained least squares (linear/nonlinear)
            //
            for (n = 1; n <= maxn; n++)
            {
                for (m = 1; m <= maxm; m++)
                {
                    for (pass = 1; pass <= passcount; pass++)
                    {
                        //
                        // Solve non-degenerate linear least squares task
                        // Use Chebyshev basis. Its condition number is very good.
                        //
                        a      = new double[n, m];
                        x      = new double[n];
                        y      = new double[n];
                        w      = new double[n];
                        xscale = 0.9 + 0.1 * AP.Math.RandomReal();
                        for (i = 0; i <= n - 1; i++)
                        {
                            if (n == 1)
                            {
                                x[i] = 2 * AP.Math.RandomReal() - 1;
                            }
                            else
                            {
                                x[i] = xscale * ((double)(2 * i) / ((double)(n - 1)) - 1);
                            }
                            y[i]    = 3 * x[i] + Math.Exp(x[i]);
                            w[i]    = 1 + AP.Math.RandomReal();
                            a[i, 0] = 1;
                            if (m > 1)
                            {
                                a[i, 1] = x[i];
                            }
                            for (j = 2; j <= m - 1; j++)
                            {
                                a[i, j] = 2 * x[i] * a[i, j - 1] - a[i, j - 2];
                            }
                        }

                        //
                        // 1. test weighted fitting (optimality)
                        // 2. Solve degenerate least squares task built on the basis
                        //    of previous task
                        //
                        lsfit.lsfitlinearw(ref y, ref w, ref a, n, m, ref info, ref c, ref rep);
                        if (info <= 0)
                        {
                            llserrors = true;
                        }
                        else
                        {
                            llserrors = llserrors | !isglssolution(n, m, 0, ref y, ref w, ref a, ref cm, c);
                        }
                        a2 = new double[n, 2 * m];
                        for (i = 0; i <= n - 1; i++)
                        {
                            for (j = 0; j <= m - 1; j++)
                            {
                                a2[i, 2 * j + 0] = a[i, j];
                                a2[i, 2 * j + 1] = a[i, j];
                            }
                        }
                        lsfit.lsfitlinearw(ref y, ref w, ref a2, n, 2 * m, ref info, ref c2, ref rep);
                        if (info <= 0)
                        {
                            llserrors = true;
                        }
                        else
                        {
                            //
                            // test answer correctness using design matrix properties
                            // and previous task solution
                            //
                            for (j = 0; j <= m - 1; j++)
                            {
                                llserrors = llserrors | (double)(Math.Abs(c2[2 * j + 0] + c2[2 * j + 1] - c[j])) > (double)(threshold);
                            }
                        }

                        //
                        // test non-weighted fitting
                        //
                        w2 = new double[n];
                        for (i = 0; i <= n - 1; i++)
                        {
                            w2[i] = 1;
                        }
                        lsfit.lsfitlinearw(ref y, ref w2, ref a, n, m, ref info, ref c, ref rep);
                        lsfit.lsfitlinear(ref y, ref a, n, m, ref info2, ref c2, ref rep2);
                        if (info <= 0 | info2 <= 0)
                        {
                            llserrors = true;
                        }
                        else
                        {
                            //
                            // test answer correctness
                            //
                            for (j = 0; j <= m - 1; j++)
                            {
                                llserrors = llserrors | (double)(Math.Abs(c[j] - c2[j])) > (double)(threshold);
                            }
                            llserrors = llserrors | (double)(Math.Abs(rep.taskrcond - rep2.taskrcond)) > (double)(threshold);
                        }

                        //
                        // test nonlinear fitting on the linear task
                        // (only non-degenerate task are tested)
                        // and compare with answer from linear fitting subroutine
                        //
                        if (n >= m)
                        {
                            c2 = new double[m];

                            //
                            // test gradient-only or Hessian-based weighted fitting
                            //
                            lsfit.lsfitlinearw(ref y, ref w, ref a, n, m, ref info, ref c, ref rep);
                            for (i = 0; i <= m - 1; i++)
                            {
                                c2[i] = 2 * AP.Math.RandomReal() - 1;
                            }
                            lsfit.lsfitnonlinearwfg(ref a, ref y, ref w, ref c2, n, m, m, (double)(AP.Math.RandomReal()) > (double)(0.5), ref state);
                            lsfit.lsfitnonlinearsetcond(ref state, 0.0, nlthreshold, 0);
                            fitlinearnonlinear(m, true, ref a, ref state, ref nlserrors);
                            lsfit.lsfitnonlinearresults(ref state, ref info, ref c2, ref rep2);
                            if (info <= 0)
                            {
                                nlserrors = true;
                            }
                            else
                            {
                                for (i = 0; i <= m - 1; i++)
                                {
                                    nlserrors = nlserrors | (double)(Math.Abs(c[i] - c2[i])) > (double)(100 * nlthreshold);
                                }
                            }
                            for (i = 0; i <= m - 1; i++)
                            {
                                c2[i] = 2 * AP.Math.RandomReal() - 1;
                            }
                            lsfit.lsfitnonlinearwfgh(ref a, ref y, ref w, ref c2, n, m, m, ref state);
                            lsfit.lsfitnonlinearsetcond(ref state, 0.0, nlthreshold, 0);
                            fitlinearnonlinear(m, false, ref a, ref state, ref nlserrors);
                            lsfit.lsfitnonlinearresults(ref state, ref info, ref c2, ref rep2);
                            if (info <= 0)
                            {
                                nlserrors = true;
                            }
                            else
                            {
                                for (i = 0; i <= m - 1; i++)
                                {
                                    nlserrors = nlserrors | (double)(Math.Abs(c[i] - c2[i])) > (double)(100 * nlthreshold);
                                }
                            }

                            //
                            // test gradient-only or Hessian-based fitting without weights
                            //
                            lsfit.lsfitlinear(ref y, ref a, n, m, ref info, ref c, ref rep);
                            for (i = 0; i <= m - 1; i++)
                            {
                                c2[i] = 2 * AP.Math.RandomReal() - 1;
                            }
                            lsfit.lsfitnonlinearfg(ref a, ref y, ref c2, n, m, m, (double)(AP.Math.RandomReal()) > (double)(0.5), ref state);
                            lsfit.lsfitnonlinearsetcond(ref state, 0.0, nlthreshold, 0);
                            fitlinearnonlinear(m, true, ref a, ref state, ref nlserrors);
                            lsfit.lsfitnonlinearresults(ref state, ref info, ref c2, ref rep2);
                            if (info <= 0)
                            {
                                nlserrors = true;
                            }
                            else
                            {
                                for (i = 0; i <= m - 1; i++)
                                {
                                    nlserrors = nlserrors | (double)(Math.Abs(c[i] - c2[i])) > (double)(100 * nlthreshold);
                                }
                            }
                            for (i = 0; i <= m - 1; i++)
                            {
                                c2[i] = 2 * AP.Math.RandomReal() - 1;
                            }
                            lsfit.lsfitnonlinearfgh(ref a, ref y, ref c2, n, m, m, ref state);
                            lsfit.lsfitnonlinearsetcond(ref state, 0.0, nlthreshold, 0);
                            fitlinearnonlinear(m, false, ref a, ref state, ref nlserrors);
                            lsfit.lsfitnonlinearresults(ref state, ref info, ref c2, ref rep2);
                            if (info <= 0)
                            {
                                nlserrors = true;
                            }
                            else
                            {
                                for (i = 0; i <= m - 1; i++)
                                {
                                    nlserrors = nlserrors | (double)(Math.Abs(c[i] - c2[i])) > (double)(100 * nlthreshold);
                                }
                            }
                        }
                    }
                }

                //
                // test correctness of the RCond field
                //
                a  = new double[n - 1 + 1, n - 1 + 1];
                x  = new double[n - 1 + 1];
                y  = new double[n - 1 + 1];
                w  = new double[n - 1 + 1];
                v1 = AP.Math.MaxRealNumber;
                v2 = AP.Math.MinRealNumber;
                for (i = 0; i <= n - 1; i++)
                {
                    x[i] = 0.1 + 0.9 * AP.Math.RandomReal();
                    y[i] = 0.1 + 0.9 * AP.Math.RandomReal();
                    w[i] = 1;
                    for (j = 0; j <= n - 1; j++)
                    {
                        if (i == j)
                        {
                            a[i, i] = 0.1 + 0.9 * AP.Math.RandomReal();
                            v1      = Math.Min(v1, a[i, i]);
                            v2      = Math.Max(v2, a[i, i]);
                        }
                        else
                        {
                            a[i, j] = 0;
                        }
                    }
                }
                lsfit.lsfitlinearw(ref y, ref w, ref a, n, n, ref info, ref c, ref rep);
                if (info <= 0)
                {
                    llserrors = true;
                }
                else
                {
                    llserrors = llserrors | (double)(Math.Abs(rep.taskrcond - v1 / v2)) > (double)(threshold);
                }
            }

            //
            // Test constrained least squares
            //
            for (pass = 1; pass <= passcount; pass++)
            {
                for (n = 1; n <= maxn; n++)
                {
                    for (m = 1; m <= maxm; m++)
                    {
                        //
                        // test for K<>0
                        //
                        for (k = 1; k <= m - 1; k++)
                        {
                            //
                            // Prepare Chebyshev basis. Its condition number is very good.
                            // Prepare constraints (random numbers)
                            //
                            a      = new double[n, m];
                            x      = new double[n];
                            y      = new double[n];
                            w      = new double[n];
                            xscale = 0.9 + 0.1 * AP.Math.RandomReal();
                            for (i = 0; i <= n - 1; i++)
                            {
                                if (n == 1)
                                {
                                    x[i] = 2 * AP.Math.RandomReal() - 1;
                                }
                                else
                                {
                                    x[i] = xscale * ((double)(2 * i) / ((double)(n - 1)) - 1);
                                }
                                y[i]    = 3 * x[i] + Math.Exp(x[i]);
                                w[i]    = 1 + AP.Math.RandomReal();
                                a[i, 0] = 1;
                                if (m > 1)
                                {
                                    a[i, 1] = x[i];
                                }
                                for (j = 2; j <= m - 1; j++)
                                {
                                    a[i, j] = 2 * x[i] * a[i, j - 1] - a[i, j - 2];
                                }
                            }
                            cm = new double[k, m + 1];
                            for (i = 0; i <= k - 1; i++)
                            {
                                for (j = 0; j <= m; j++)
                                {
                                    cm[i, j] = 2 * AP.Math.RandomReal() - 1;
                                }
                            }

                            //
                            // Solve constrained task
                            //
                            lsfit.lsfitlinearwc(y, ref w, ref a, cm, n, m, k, ref info, ref c, ref rep);
                            if (info <= 0)
                            {
                                llserrors = true;
                            }
                            else
                            {
                                llserrors = llserrors | !isglssolution(n, m, k, ref y, ref w, ref a, ref cm, c);
                            }

                            //
                            // test non-weighted fitting
                            //
                            w2 = new double[n];
                            for (i = 0; i <= n - 1; i++)
                            {
                                w2[i] = 1;
                            }
                            lsfit.lsfitlinearwc(y, ref w2, ref a, cm, n, m, k, ref info, ref c, ref rep);
                            lsfit.lsfitlinearc(y, ref a, ref cm, n, m, k, ref info2, ref c2, ref rep2);
                            if (info <= 0 | info2 <= 0)
                            {
                                llserrors = true;
                            }
                            else
                            {
                                //
                                // test answer correctness
                                //
                                for (j = 0; j <= m - 1; j++)
                                {
                                    llserrors = llserrors | (double)(Math.Abs(c[j] - c2[j])) > (double)(threshold);
                                }
                                llserrors = llserrors | (double)(Math.Abs(rep.taskrcond - rep2.taskrcond)) > (double)(threshold);
                            }
                        }
                    }
                }
            }

            //
            // nonlinear task for nonlinear fitting:
            //
            //     f(X,C) = 1/(1+C*X^2),
            //     C(true) = 2.
            //
            n    = 100;
            c    = new double[1];
            c[0] = 1 + 2 * AP.Math.RandomReal();
            a    = new double[n, 1];
            y    = new double[n];
            for (i = 0; i <= n - 1; i++)
            {
                a[i, 0] = 4 * AP.Math.RandomReal() - 2;
                y[i]    = 1 / (1 + 2 * AP.Math.Sqr(a[i, 0]));
            }
            lsfit.lsfitnonlinearfg(ref a, ref y, ref c, n, 1, 1, true, ref state);
            lsfit.lsfitnonlinearsetcond(ref state, 0.0, nlthreshold, 0);
            while (lsfit.lsfitnonlineariteration(ref state))
            {
                if (state.needf)
                {
                    state.f = 1 / (1 + state.c[0] * AP.Math.Sqr(state.x[0]));
                }
                if (state.needfg)
                {
                    state.f    = 1 / (1 + state.c[0] * AP.Math.Sqr(state.x[0]));
                    state.g[0] = -(AP.Math.Sqr(state.x[0]) / AP.Math.Sqr(1 + state.c[0] * AP.Math.Sqr(state.x[0])));
                }
            }
            lsfit.lsfitnonlinearresults(ref state, ref info, ref c, ref rep);
            if (info <= 0)
            {
                nlserrors = true;
            }
            else
            {
                nlserrors = nlserrors | (double)(Math.Abs(c[0] - 2)) > (double)(100 * nlthreshold);
            }

            //
            // solve simple task (fitting by constant function) and check
            // correctness of the errors calculated by subroutines
            //
            for (pass = 1; pass <= passcount; pass++)
            {
                //
                // test on task with non-zero Yi
                //
                n         = 4;
                v1        = AP.Math.RandomReal();
                v2        = AP.Math.RandomReal();
                v         = 1 + AP.Math.RandomReal();
                c         = new double[1];
                c[0]      = 1 + 2 * AP.Math.RandomReal();
                a         = new double[4, 1];
                y         = new double[4];
                a[0, 0]   = 1;
                y[0]      = v - v2;
                a[1, 0]   = 1;
                y[1]      = v - v1;
                a[2, 0]   = 1;
                y[2]      = v + v1;
                a[3, 0]   = 1;
                y[3]      = v + v2;
                refrms    = Math.Sqrt((AP.Math.Sqr(v1) + AP.Math.Sqr(v2)) / 2);
                refavg    = (Math.Abs(v1) + Math.Abs(v2)) / 2;
                refavgrel = 0.25 * (Math.Abs(v2) / Math.Abs(v - v2) + Math.Abs(v1) / Math.Abs(v - v1) + Math.Abs(v1) / Math.Abs(v + v1) + Math.Abs(v2) / Math.Abs(v + v2));
                refmax    = Math.Max(v1, v2);

                //
                // Test LLS
                //
                lsfit.lsfitlinear(ref y, ref a, 4, 1, ref info, ref c, ref rep);
                if (info <= 0)
                {
                    llserrors = true;
                }
                else
                {
                    llserrors = llserrors | (double)(Math.Abs(c[0] - v)) > (double)(threshold);
                    llserrors = llserrors | (double)(Math.Abs(rep.rmserror - refrms)) > (double)(threshold);
                    llserrors = llserrors | (double)(Math.Abs(rep.avgerror - refavg)) > (double)(threshold);
                    llserrors = llserrors | (double)(Math.Abs(rep.avgrelerror - refavgrel)) > (double)(threshold);
                    llserrors = llserrors | (double)(Math.Abs(rep.maxerror - refmax)) > (double)(threshold);
                }

                //
                // Test NLS
                //
                lsfit.lsfitnonlinearfg(ref a, ref y, ref c, 4, 1, 1, true, ref state);
                lsfit.lsfitnonlinearsetcond(ref state, 0.0, nlthreshold, 0);
                while (lsfit.lsfitnonlineariteration(ref state))
                {
                    if (state.needf)
                    {
                        state.f = state.c[0];
                    }
                    if (state.needfg)
                    {
                        state.f    = state.c[0];
                        state.g[0] = 1;
                    }
                }
                lsfit.lsfitnonlinearresults(ref state, ref info, ref c, ref rep);
                if (info <= 0)
                {
                    nlserrors = true;
                }
                else
                {
                    nlserrors = nlserrors | (double)(Math.Abs(c[0] - v)) > (double)(threshold);
                    nlserrors = nlserrors | (double)(Math.Abs(rep.rmserror - refrms)) > (double)(threshold);
                    nlserrors = nlserrors | (double)(Math.Abs(rep.avgerror - refavg)) > (double)(threshold);
                    nlserrors = nlserrors | (double)(Math.Abs(rep.avgrelerror - refavgrel)) > (double)(threshold);
                    nlserrors = nlserrors | (double)(Math.Abs(rep.maxerror - refmax)) > (double)(threshold);
                }
            }

            //
            // report
            //
            waserrors = llserrors | nlserrors;
            if (!silent)
            {
                System.Console.Write("TESTING LEAST SQUARES");
                System.Console.WriteLine();
                System.Console.Write("LINEAR LEAST SQUARES:                    ");
                if (llserrors)
                {
                    System.Console.Write("FAILED");
                    System.Console.WriteLine();
                }
                else
                {
                    System.Console.Write("OK");
                    System.Console.WriteLine();
                }
                System.Console.Write("NON-LINEAR LEAST SQUARES:                ");
                if (nlserrors)
                {
                    System.Console.Write("FAILED");
                    System.Console.WriteLine();
                }
                else
                {
                    System.Console.Write("OK");
                    System.Console.WriteLine();
                }
                if (waserrors)
                {
                    System.Console.Write("TEST FAILED");
                    System.Console.WriteLine();
                }
                else
                {
                    System.Console.Write("TEST PASSED");
                    System.Console.WriteLine();
                }
                System.Console.WriteLine();
                System.Console.WriteLine();
            }

            //
            // end
            //
            result = !waserrors;
            return(result);
        }
        /*************************************************************************
        Internal spline fitting subroutine

          -- ALGLIB PROJECT --
             Copyright 08.09.2009 by Bochkanov Sergey
        *************************************************************************/
        private static void spline1dfitinternal(int st,
            double[] x,
            double[] y,
            double[] w,
            int n,
            double[] xc,
            double[] yc,
            int[] dc,
            int k,
            int m,
            ref int info,
            spline1dinterpolant s,
            spline1dfitreport rep)
        {
            double[,] fmatrix = new double[0,0];
            double[,] cmatrix = new double[0,0];
            double[] y2 = new double[0];
            double[] w2 = new double[0];
            double[] sx = new double[0];
            double[] sy = new double[0];
            double[] sd = new double[0];
            double[] tmp = new double[0];
            double[] xoriginal = new double[0];
            double[] yoriginal = new double[0];
            lsfit.lsfitreport lrep = new lsfit.lsfitreport();
            double v0 = 0;
            double v1 = 0;
            double v2 = 0;
            double mx = 0;
            spline1dinterpolant s2 = new spline1dinterpolant();
            int i = 0;
            int j = 0;
            int relcnt = 0;
            double xa = 0;
            double xb = 0;
            double sa = 0;
            double sb = 0;
            double bl = 0;
            double br = 0;
            double decay = 0;
            int i_ = 0;

            x = (double[])x.Clone();
            y = (double[])y.Clone();
            xc = (double[])xc.Clone();
            yc = (double[])yc.Clone();
            info = 0;

            ap.assert(st==0 | st==1, "Spline1DFit: internal error!");
            if( st==0 & m<4 )
            {
                info = -1;
                return;
            }
            if( st==1 & m<4 )
            {
                info = -1;
                return;
            }
            if( (n<1 | k<0) | k>=m )
            {
                info = -1;
                return;
            }
            for(i=0; i<=k-1; i++)
            {
                info = 0;
                if( dc[i]<0 )
                {
                    info = -1;
                }
                if( dc[i]>1 )
                {
                    info = -1;
                }
                if( info<0 )
                {
                    return;
                }
            }
            if( st==1 & m%2!=0 )
            {
                
                //
                // Hermite fitter must have even number of basis functions
                //
                info = -2;
                return;
            }
            
            //
            // weight decay for correct handling of task which becomes
            // degenerate after constraints are applied
            //
            decay = 10000*math.machineepsilon;
            
            //
            // Scale X, Y, XC, YC
            //
            lsfit.lsfitscalexy(ref x, ref y, n, ref xc, ref yc, dc, k, ref xa, ref xb, ref sa, ref sb, ref xoriginal, ref yoriginal);
            
            //
            // allocate space, initialize:
            // * SX     -   grid for basis functions
            // * SY     -   values of basis functions at grid points
            // * FMatrix-   values of basis functions at X[]
            // * CMatrix-   values (derivatives) of basis functions at XC[]
            //
            y2 = new double[n+m];
            w2 = new double[n+m];
            fmatrix = new double[n+m, m];
            if( k>0 )
            {
                cmatrix = new double[k, m+1];
            }
            if( st==0 )
            {
                
                //
                // allocate space for cubic spline
                //
                sx = new double[m-2];
                sy = new double[m-2];
                for(j=0; j<=m-2-1; j++)
                {
                    sx[j] = (double)(2*j)/(double)(m-2-1)-1;
                }
            }
            if( st==1 )
            {
                
                //
                // allocate space for Hermite spline
                //
                sx = new double[m/2];
                sy = new double[m/2];
                sd = new double[m/2];
                for(j=0; j<=m/2-1; j++)
                {
                    sx[j] = (double)(2*j)/(double)(m/2-1)-1;
                }
            }
            
            //
            // Prepare design and constraints matrices:
            // * fill constraints matrix
            // * fill first N rows of design matrix with values
            // * fill next M rows of design matrix with regularizing term
            // * append M zeros to Y
            // * append M elements, mean(abs(W)) each, to W
            //
            for(j=0; j<=m-1; j++)
            {
                
                //
                // prepare Jth basis function
                //
                if( st==0 )
                {
                    
                    //
                    // cubic spline basis
                    //
                    for(i=0; i<=m-2-1; i++)
                    {
                        sy[i] = 0;
                    }
                    bl = 0;
                    br = 0;
                    if( j<m-2 )
                    {
                        sy[j] = 1;
                    }
                    if( j==m-2 )
                    {
                        bl = 1;
                    }
                    if( j==m-1 )
                    {
                        br = 1;
                    }
                    spline1dbuildcubic(sx, sy, m-2, 1, bl, 1, br, s2);
                }
                if( st==1 )
                {
                    
                    //
                    // Hermite basis
                    //
                    for(i=0; i<=m/2-1; i++)
                    {
                        sy[i] = 0;
                        sd[i] = 0;
                    }
                    if( j%2==0 )
                    {
                        sy[j/2] = 1;
                    }
                    else
                    {
                        sd[j/2] = 1;
                    }
                    spline1dbuildhermite(sx, sy, sd, m/2, s2);
                }
                
                //
                // values at X[], XC[]
                //
                for(i=0; i<=n-1; i++)
                {
                    fmatrix[i,j] = spline1dcalc(s2, x[i]);
                }
                for(i=0; i<=k-1; i++)
                {
                    ap.assert(dc[i]>=0 & dc[i]<=2, "Spline1DFit: internal error!");
                    spline1ddiff(s2, xc[i], ref v0, ref v1, ref v2);
                    if( dc[i]==0 )
                    {
                        cmatrix[i,j] = v0;
                    }
                    if( dc[i]==1 )
                    {
                        cmatrix[i,j] = v1;
                    }
                    if( dc[i]==2 )
                    {
                        cmatrix[i,j] = v2;
                    }
                }
            }
            for(i=0; i<=k-1; i++)
            {
                cmatrix[i,m] = yc[i];
            }
            for(i=0; i<=m-1; i++)
            {
                for(j=0; j<=m-1; j++)
                {
                    if( i==j )
                    {
                        fmatrix[n+i,j] = decay;
                    }
                    else
                    {
                        fmatrix[n+i,j] = 0;
                    }
                }
            }
            y2 = new double[n+m];
            w2 = new double[n+m];
            for(i_=0; i_<=n-1;i_++)
            {
                y2[i_] = y[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                w2[i_] = w[i_];
            }
            mx = 0;
            for(i=0; i<=n-1; i++)
            {
                mx = mx+Math.Abs(w[i]);
            }
            mx = mx/n;
            for(i=0; i<=m-1; i++)
            {
                y2[n+i] = 0;
                w2[n+i] = mx;
            }
            
            //
            // Solve constrained task
            //
            if( k>0 )
            {
                
                //
                // solve using regularization
                //
                lsfit.lsfitlinearwc(y2, w2, fmatrix, cmatrix, n+m, m, k, ref info, ref tmp, lrep);
            }
            else
            {
                
                //
                // no constraints, no regularization needed
                //
                lsfit.lsfitlinearwc(y, w, fmatrix, cmatrix, n, m, k, ref info, ref tmp, lrep);
            }
            if( info<0 )
            {
                return;
            }
            
            //
            // Generate spline and scale it
            //
            if( st==0 )
            {
                
                //
                // cubic spline basis
                //
                for(i_=0; i_<=m-2-1;i_++)
                {
                    sy[i_] = tmp[i_];
                }
                spline1dbuildcubic(sx, sy, m-2, 1, tmp[m-2], 1, tmp[m-1], s);
            }
            if( st==1 )
            {
                
                //
                // Hermite basis
                //
                for(i=0; i<=m/2-1; i++)
                {
                    sy[i] = tmp[2*i];
                    sd[i] = tmp[2*i+1];
                }
                spline1dbuildhermite(sx, sy, sd, m/2, s);
            }
            spline1dlintransx(s, 2/(xb-xa), -((xa+xb)/(xb-xa)));
            spline1dlintransy(s, sb-sa, sa);
            
            //
            // Scale absolute errors obtained from LSFitLinearW.
            // Relative error should be calculated separately
            // (because of shifting/scaling of the task)
            //
            rep.taskrcond = lrep.taskrcond;
            rep.rmserror = lrep.rmserror*(sb-sa);
            rep.avgerror = lrep.avgerror*(sb-sa);
            rep.maxerror = lrep.maxerror*(sb-sa);
            rep.avgrelerror = 0;
            relcnt = 0;
            for(i=0; i<=n-1; i++)
            {
                if( (double)(yoriginal[i])!=(double)(0) )
                {
                    rep.avgrelerror = rep.avgrelerror+Math.Abs(spline1dcalc(s, xoriginal[i])-yoriginal[i])/Math.Abs(yoriginal[i]);
                    relcnt = relcnt+1;
                }
            }
            if( relcnt!=0 )
            {
                rep.avgrelerror = rep.avgrelerror/relcnt;
            }
        }
Exemplo n.º 9
0
    public static int Main(string[] args)
    {
        int m = 0;
        int n = 0;
        int k = 0;

        double[] y = new double[0];
        double[,] x = new double[0, 0];
        double[]          c     = new double[0];
        lsfit.lsfitreport rep   = new lsfit.lsfitreport();
        lsfit.lsfitstate  state = new lsfit.lsfitstate();
        int    info             = 0;
        double epsf             = 0;
        double epsx             = 0;
        int    maxits           = 0;
        int    i = 0;
        int    j = 0;
        double a = 0;
        double b = 0;

        System.Console.Write("Fitting 1-x^2 on [-1,+1] with cos(alpha*pi*x)+beta");
        System.Console.WriteLine();

        //
        // Fitting 1-x^2 on [-1,+1] with cos(alpha*pi*x)+beta:
        // * using Hessian
        // * using alpha=1 and beta=0 as initial values
        // * using 1000 uniformly distributed points to fit to
        //
        // Notes:
        // * N - number of points
        // * M - dimension of space where points reside
        // * K - number of parameters being fitted
        //
        n = 1000;
        m = 1;
        k = 2;
        a = -1;
        b = +1;

        //
        // Prepare task matrix
        //
        y = new double[n];
        x = new double[n, m];
        c = new double[k];
        for (i = 0; i <= n - 1; i++)
        {
            x[i, 0] = a + (b - a) * i / (n - 1);
            y[i]    = 1 - AP.Math.Sqr(x[i, 0]);
        }
        c[0]   = 1.0;
        c[1]   = 0.0;
        epsf   = 0.0;
        epsx   = 0.0001;
        maxits = 0;

        //
        // Solve
        //
        lsfit.lsfitnonlinearfgh(ref x, ref y, ref c, n, m, k, ref state);
        lsfit.lsfitnonlinearsetcond(ref state, epsf, epsx, maxits);
        while (lsfit.lsfitnonlineariteration(ref state))
        {
            //
            // F(x) = Cos(alpha*pi*x)+beta
            //
            state.f = Math.Cos(state.c[0] * Math.PI * state.x[0]) + state.c[1];

            //
            // F(x)      = Cos(alpha*pi*x)+beta
            // dF/dAlpha = -pi*x*Sin(alpha*pi*x)
            // dF/dBeta  = 1.0
            //
            if (state.needfg | state.needfgh)
            {
                state.g[0] = -(Math.PI * state.x[0] * Math.Sin(state.c[0] * Math.PI * state.x[0]));
                state.g[1] = 1.0;
            }

            //
            // F(x)            = Cos(alpha*pi*x)+beta
            // d2F/dAlpha2     = -(pi*x)^2*Cos(alpha*pi*x)
            // d2F/dAlphadBeta = 0
            // d2F/dBeta2     =  0
            //
            if (state.needfgh)
            {
                state.h[0, 0] = -(AP.Math.Sqr(Math.PI * state.x[0]) * Math.Cos(state.c[0] * Math.PI * state.x[0]));
                state.h[0, 1] = 0.0;
                state.h[1, 0] = 0.0;
                state.h[1, 1] = 0.0;
            }
        }
        lsfit.lsfitnonlinearresults(ref state, ref info, ref c, ref rep);
        System.Console.Write("alpha:   ");
        System.Console.Write("{0,0:F3}", c[0]);
        System.Console.WriteLine();
        System.Console.Write("beta:    ");
        System.Console.Write("{0,0:F3}", c[1]);
        System.Console.WriteLine();
        System.Console.Write("rms.err: ");
        System.Console.Write("{0,0:F3}", rep.rmserror);
        System.Console.WriteLine();
        System.Console.Write("max.err: ");
        System.Console.Write("{0,0:F3}", rep.maxerror);
        System.Console.WriteLine();
        System.Console.Write("Termination type: ");
        System.Console.Write("{0,0:d}", info);
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.WriteLine();
        return(0);
    }
Exemplo n.º 10
0
        /*************************************************************************
        *  Weighted  fitting  by  Chebyshev  polynomial  in  barycentric  form,  with
        *  constraints on function values or first derivatives.
        *
        *  Small regularizing term is used when solving constrained tasks (to improve
        *  stability).
        *
        *  Task is linear, so linear least squares solver is used. Complexity of this
        *  computational scheme is O(N*M^2), mostly dominated by least squares solver
        *
        *  SEE ALSO:
        *   PolynomialFit()
        *
        *  INPUT PARAMETERS:
        *   X   -   points, array[0..N-1].
        *   Y   -   function values, array[0..N-1].
        *   W   -   weights, array[0..N-1]
        *           Each summand in square  sum  of  approximation deviations from
        *           given  values  is  multiplied  by  the square of corresponding
        *           weight. Fill it by 1's if you don't  want  to  solve  weighted
        *           task.
        *   N   -   number of points, N>0.
        *   XC  -   points where polynomial values/derivatives are constrained,
        *           array[0..K-1].
        *   YC  -   values of constraints, array[0..K-1]
        *   DC  -   array[0..K-1], types of constraints:
        * DC[i]=0   means that P(XC[i])=YC[i]
        * DC[i]=1   means that P'(XC[i])=YC[i]
        *           SEE BELOW FOR IMPORTANT INFORMATION ON CONSTRAINTS
        *   K   -   number of constraints, 0<=K<M.
        *           K=0 means no constraints (XC/YC/DC are not used in such cases)
        *   M   -   number of basis functions (= polynomial_degree + 1), M>=1
        *
        *  OUTPUT PARAMETERS:
        *   Info-   same format as in LSFitLinearW() subroutine:
        * Info>0    task is solved
        * Info<=0   an error occured:
        *                       -4 means inconvergence of internal SVD
        *                       -3 means inconsistent constraints
        *                       -1 means another errors in parameters passed
        *                          (N<=0, for example)
        *   P   -   interpolant in barycentric form.
        *   Rep -   report, same format as in LSFitLinearW() subroutine.
        *           Following fields are set:
        * RMSError      rms error on the (X,Y).
        * AvgError      average error on the (X,Y).
        * AvgRelError   average relative error on the non-zero Y
        * MaxError      maximum error
        *                           NON-WEIGHTED ERRORS ARE CALCULATED
        *
        *  IMPORTANT:
        *   this subroitine doesn't calculate task's condition number for K<>0.
        *
        *  SETTING CONSTRAINTS - DANGERS AND OPPORTUNITIES:
        *
        *  Setting constraints can lead  to undesired  results,  like ill-conditioned
        *  behavior, or inconsistency being detected. From the other side,  it allows
        *  us to improve quality of the fit. Here we summarize  our  experience  with
        *  constrained regression splines:
        * even simple constraints can be inconsistent, see  Wikipedia  article  on
        *  this subject: http://en.wikipedia.org/wiki/Birkhoff_interpolation
        * the  greater  is  M (given  fixed  constraints),  the  more chances that
        *  constraints will be consistent
        * in the general case, consistency of constraints is NOT GUARANTEED.
        * in the one special cases, however, we can  guarantee  consistency.  This
        *  case  is:  M>1  and constraints on the function values (NOT DERIVATIVES)
        *
        *  Our final recommendation is to use constraints  WHEN  AND  ONLY  when  you
        *  can't solve your task without them. Anything beyond  special  cases  given
        *  above is not guaranteed and may result in inconsistency.
        *
        *  -- ALGLIB PROJECT --
        *    Copyright 10.12.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void polynomialfitwc(double[] x,
                                           double[] y,
                                           ref double[] w,
                                           int n,
                                           double[] xc,
                                           double[] yc,
                                           ref int[] dc,
                                           int k,
                                           int m,
                                           ref int info,
                                           ref ratint.barycentricinterpolant p,
                                           ref polynomialfitreport rep)
        {
            double xa = 0;
            double xb = 0;
            double sa = 0;
            double sb = 0;

            double[] xoriginal = new double[0];
            double[] yoriginal = new double[0];
            double[] y2        = new double[0];
            double[] w2        = new double[0];
            double[] tmp       = new double[0];
            double[] tmp2      = new double[0];
            double[] tmpdiff   = new double[0];
            double[] bx        = new double[0];
            double[] by        = new double[0];
            double[] bw        = new double[0];
            double[,] fmatrix = new double[0, 0];
            double[,] cmatrix = new double[0, 0];
            int    i      = 0;
            int    j      = 0;
            double mx     = 0;
            double decay  = 0;
            double u      = 0;
            double v      = 0;
            double s      = 0;
            int    relcnt = 0;

            lsfit.lsfitreport lrep = new lsfit.lsfitreport();
            int i_ = 0;

            x  = (double[])x.Clone();
            y  = (double[])y.Clone();
            xc = (double[])xc.Clone();
            yc = (double[])yc.Clone();

            if (m < 1 | n < 1 | k < 0 | k >= m)
            {
                info = -1;
                return;
            }
            for (i = 0; i <= k - 1; i++)
            {
                info = 0;
                if (dc[i] < 0)
                {
                    info = -1;
                }
                if (dc[i] > 1)
                {
                    info = -1;
                }
                if (info < 0)
                {
                    return;
                }
            }

            //
            // weight decay for correct handling of task which becomes
            // degenerate after constraints are applied
            //
            decay = 10000 * AP.Math.MachineEpsilon;

            //
            // Scale X, Y, XC, YC
            //
            lsfit.lsfitscalexy(ref x, ref y, n, ref xc, ref yc, ref dc, k, ref xa, ref xb, ref sa, ref sb, ref xoriginal, ref yoriginal);

            //
            // allocate space, initialize/fill:
            // * FMatrix-   values of basis functions at X[]
            // * CMatrix-   values (derivatives) of basis functions at XC[]
            // * fill constraints matrix
            // * fill first N rows of design matrix with values
            // * fill next M rows of design matrix with regularizing term
            // * append M zeros to Y
            // * append M elements, mean(abs(W)) each, to W
            //
            y2      = new double[n + m];
            w2      = new double[n + m];
            tmp     = new double[m];
            tmpdiff = new double[m];
            fmatrix = new double[n + m, m];
            if (k > 0)
            {
                cmatrix = new double[k, m + 1];
            }

            //
            // Fill design matrix, Y2, W2:
            // * first N rows with basis functions for original points
            // * next M rows with decay terms
            //
            for (i = 0; i <= n - 1; i++)
            {
                //
                // prepare Ith row
                // use Tmp for calculations to avoid multidimensional arrays overhead
                //
                for (j = 0; j <= m - 1; j++)
                {
                    if (j == 0)
                    {
                        tmp[j] = 1;
                    }
                    else
                    {
                        if (j == 1)
                        {
                            tmp[j] = x[i];
                        }
                        else
                        {
                            tmp[j] = 2 * x[i] * tmp[j - 1] - tmp[j - 2];
                        }
                    }
                }
                for (i_ = 0; i_ <= m - 1; i_++)
                {
                    fmatrix[i, i_] = tmp[i_];
                }
            }
            for (i = 0; i <= m - 1; i++)
            {
                for (j = 0; j <= m - 1; j++)
                {
                    if (i == j)
                    {
                        fmatrix[n + i, j] = decay;
                    }
                    else
                    {
                        fmatrix[n + i, j] = 0;
                    }
                }
            }
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                y2[i_] = y[i_];
            }
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                w2[i_] = w[i_];
            }
            mx = 0;
            for (i = 0; i <= n - 1; i++)
            {
                mx = mx + Math.Abs(w[i]);
            }
            mx = mx / n;
            for (i = 0; i <= m - 1; i++)
            {
                y2[n + i] = 0;
                w2[n + i] = mx;
            }

            //
            // fill constraints matrix
            //
            for (i = 0; i <= k - 1; i++)
            {
                //
                // prepare Ith row
                // use Tmp for basis function values,
                // TmpDiff for basos function derivatives
                //
                for (j = 0; j <= m - 1; j++)
                {
                    if (j == 0)
                    {
                        tmp[j]     = 1;
                        tmpdiff[j] = 0;
                    }
                    else
                    {
                        if (j == 1)
                        {
                            tmp[j]     = xc[i];
                            tmpdiff[j] = 1;
                        }
                        else
                        {
                            tmp[j]     = 2 * xc[i] * tmp[j - 1] - tmp[j - 2];
                            tmpdiff[j] = 2 * (tmp[j - 1] + xc[i] * tmpdiff[j - 1]) - tmpdiff[j - 2];
                        }
                    }
                }
                if (dc[i] == 0)
                {
                    for (i_ = 0; i_ <= m - 1; i_++)
                    {
                        cmatrix[i, i_] = tmp[i_];
                    }
                }
                if (dc[i] == 1)
                {
                    for (i_ = 0; i_ <= m - 1; i_++)
                    {
                        cmatrix[i, i_] = tmpdiff[i_];
                    }
                }
                cmatrix[i, m] = yc[i];
            }

            //
            // Solve constrained task
            //
            if (k > 0)
            {
                //
                // solve using regularization
                //
                lsfit.lsfitlinearwc(y2, ref w2, ref fmatrix, cmatrix, n + m, m, k, ref info, ref tmp, ref lrep);
            }
            else
            {
                //
                // no constraints, no regularization needed
                //
                lsfit.lsfitlinearwc(y, ref w, ref fmatrix, cmatrix, n, m, 0, ref info, ref tmp, ref lrep);
            }
            if (info < 0)
            {
                return;
            }

            //
            // Generate barycentric model and scale it
            // * BX, BY store barycentric model nodes
            // * FMatrix is reused (remember - it is at least MxM, what we need)
            //
            // Model intialization is done in O(M^2). In principle, it can be
            // done in O(M*log(M)), but before it we solved task with O(N*M^2)
            // complexity, so it is only a small amount of total time spent.
            //
            bx   = new double[m];
            by   = new double[m];
            bw   = new double[m];
            tmp2 = new double[m];
            s    = 1;
            for (i = 0; i <= m - 1; i++)
            {
                if (m != 1)
                {
                    u = Math.Cos(Math.PI * i / (m - 1));
                }
                else
                {
                    u = 0;
                }
                v = 0;
                for (j = 0; j <= m - 1; j++)
                {
                    if (j == 0)
                    {
                        tmp2[j] = 1;
                    }
                    else
                    {
                        if (j == 1)
                        {
                            tmp2[j] = u;
                        }
                        else
                        {
                            tmp2[j] = 2 * u * tmp2[j - 1] - tmp2[j - 2];
                        }
                    }
                    v = v + tmp[j] * tmp2[j];
                }
                bx[i] = u;
                by[i] = v;
                bw[i] = s;
                if (i == 0 | i == m - 1)
                {
                    bw[i] = 0.5 * bw[i];
                }
                s = -s;
            }
            ratint.barycentricbuildxyw(ref bx, ref by, ref bw, m, ref p);
            ratint.barycentriclintransx(ref p, 2 / (xb - xa), -((xa + xb) / (xb - xa)));
            ratint.barycentriclintransy(ref p, sb - sa, sa);

            //
            // Scale absolute errors obtained from LSFitLinearW.
            // Relative error should be calculated separately
            // (because of shifting/scaling of the task)
            //
            rep.taskrcond   = lrep.taskrcond;
            rep.rmserror    = lrep.rmserror * (sb - sa);
            rep.avgerror    = lrep.avgerror * (sb - sa);
            rep.maxerror    = lrep.maxerror * (sb - sa);
            rep.avgrelerror = 0;
            relcnt          = 0;
            for (i = 0; i <= n - 1; i++)
            {
                if ((double)(yoriginal[i]) != (double)(0))
                {
                    rep.avgrelerror = rep.avgrelerror + Math.Abs(ratint.barycentriccalc(ref p, xoriginal[i]) - yoriginal[i]) / Math.Abs(yoriginal[i]);
                    relcnt          = relcnt + 1;
                }
            }
            if (relcnt != 0)
            {
                rep.avgrelerror = rep.avgrelerror / relcnt;
            }
        }
    public static int Main(string[] args)
    {
        int m = 0;
        int n = 0;
        double[] y = new double[0];
        double[,] fmatrix = new double[0,0];
        double[,] cmatrix = new double[0,0];
        lsfit.lsfitreport rep = new lsfit.lsfitreport();
        int info = 0;
        double[] c = new double[0];
        int i = 0;
        int j = 0;
        double x = 0;
        double a = 0;
        double b = 0;

        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.Write("Fitting tan(x) by third degree polynomial");
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.Write("Fit type             rms.err max.err    p(0)   dp(0)");
        System.Console.WriteLine();
        
        //
        // Fitting tan(x) at [0, 0.4*pi] by third degree polynomial:
        // a) without constraints
        // b) constrained at x=0: p(0)=0
        // c) constrained at x=0: p'(0)=1
        // c) constrained at x=0: p(0)=0, p'(0)=1
        //
        m = 4;
        n = 100;
        a = 0;
        b = 0.4*Math.PI;
        
        //
        // Prepare task matrix
        //
        y = new double[n];
        fmatrix = new double[n, m];
        for(i=0; i<=n-1; i++)
        {
            x = a+(b-a)*i/(n-1);
            y[i] = Math.Tan(x);
            fmatrix[i,0] = 1.0;
            for(j=1; j<=m-1; j++)
            {
                fmatrix[i,j] = x*fmatrix[i,j-1];
            }
        }
        
        //
        // Solve unconstrained task
        //
        lsfit.lsfitlinear(ref y, ref fmatrix, n, m, ref info, ref c, ref rep);
        System.Console.Write("Unconstrained        ");
        System.Console.Write("{0,7:F4}",rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",c[0]);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",c[1]);
        System.Console.WriteLine();
        
        //
        // Solve constrained task, p(0)=0
        // Prepare constraints matrix:
        // * first M columns store values of basis functions at X=0
        // * last column stores zero (desired value at X=0)
        //
        cmatrix = new double[1, m+1];
        cmatrix[0,0] = 1;
        for(i=1; i<=m-1; i++)
        {
            cmatrix[0,i] = 0;
        }
        cmatrix[0,m] = 0;
        lsfit.lsfitlinearc(y, ref fmatrix, ref cmatrix, n, m, 1, ref info, ref c, ref rep);
        System.Console.Write("Constrained, p(0)=0  ");
        System.Console.Write("{0,7:F4}",rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",c[0]);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",c[1]);
        System.Console.WriteLine();
        
        //
        // Solve constrained task, p'(0)=0
        // Prepare constraints matrix:
        // * first M columns store derivatives of basis functions at X=0
        // * last column stores 1.0 (desired derivative at X=0)
        //
        cmatrix = new double[1, m+1];
        for(i=0; i<=m-1; i++)
        {
            cmatrix[0,i] = 0;
        }
        cmatrix[0,1] = 1;
        cmatrix[0,m] = 1;
        lsfit.lsfitlinearc(y, ref fmatrix, ref cmatrix, n, m, 1, ref info, ref c, ref rep);
        System.Console.Write("Constrained, dp(0)=1 ");
        System.Console.Write("{0,7:F4}",rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",c[0]);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",c[1]);
        System.Console.WriteLine();
        
        //
        // Solve constrained task, p(0)=0, p'(0)=0
        // Prepare constraints matrix:
        // * first M columns store values/derivatives of basis functions at X=0
        // * last column stores desired values/derivative at X=0
        //
        cmatrix = new double[2, m+1];
        cmatrix[0,0] = 1;
        for(i=1; i<=m-1; i++)
        {
            cmatrix[0,i] = 0;
        }
        cmatrix[0,m] = 0;
        for(i=0; i<=m-1; i++)
        {
            cmatrix[1,i] = 0;
        }
        cmatrix[1,1] = 1;
        cmatrix[1,m] = 1;
        lsfit.lsfitlinearc(y, ref fmatrix, ref cmatrix, n, m, 2, ref info, ref c, ref rep);
        System.Console.Write("Constrained, both    ");
        System.Console.Write("{0,7:F4}",rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",c[0]);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}",c[1]);
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.WriteLine();
        return 0;
    }
Exemplo n.º 12
0
        /*************************************************************************
        Internal Floater-Hormann fitting subroutine for fixed D
        *************************************************************************/
        private static void barycentricfitwcfixedd(double[] x,
            double[] y,
            double[] w,
            int n,
            double[] xc,
            double[] yc,
            int[] dc,
            int k,
            int m,
            int d,
            ref int info,
            barycentricinterpolant b,
            barycentricfitreport rep)
        {
            double[,] fmatrix = new double[0,0];
            double[,] cmatrix = new double[0,0];
            double[] y2 = new double[0];
            double[] w2 = new double[0];
            double[] sx = new double[0];
            double[] sy = new double[0];
            double[] sbf = new double[0];
            double[] xoriginal = new double[0];
            double[] yoriginal = new double[0];
            double[] tmp = new double[0];
            lsfit.lsfitreport lrep = new lsfit.lsfitreport();
            double v0 = 0;
            double v1 = 0;
            double mx = 0;
            barycentricinterpolant b2 = new barycentricinterpolant();
            int i = 0;
            int j = 0;
            int relcnt = 0;
            double xa = 0;
            double xb = 0;
            double sa = 0;
            double sb = 0;
            double decay = 0;
            int i_ = 0;

            x = (double[])x.Clone();
            y = (double[])y.Clone();
            xc = (double[])xc.Clone();
            yc = (double[])yc.Clone();
            info = 0;

            if( ((n<1 | m<2) | k<0) | k>=m )
            {
                info = -1;
                return;
            }
            for(i=0; i<=k-1; i++)
            {
                info = 0;
                if( dc[i]<0 )
                {
                    info = -1;
                }
                if( dc[i]>1 )
                {
                    info = -1;
                }
                if( info<0 )
                {
                    return;
                }
            }
            
            //
            // weight decay for correct handling of task which becomes
            // degenerate after constraints are applied
            //
            decay = 10000*math.machineepsilon;
            
            //
            // Scale X, Y, XC, YC
            //
            lsfit.lsfitscalexy(ref x, ref y, n, ref xc, ref yc, dc, k, ref xa, ref xb, ref sa, ref sb, ref xoriginal, ref yoriginal);
            
            //
            // allocate space, initialize:
            // * FMatrix-   values of basis functions at X[]
            // * CMatrix-   values (derivatives) of basis functions at XC[]
            //
            y2 = new double[n+m];
            w2 = new double[n+m];
            fmatrix = new double[n+m, m];
            if( k>0 )
            {
                cmatrix = new double[k, m+1];
            }
            y2 = new double[n+m];
            w2 = new double[n+m];
            
            //
            // Prepare design and constraints matrices:
            // * fill constraints matrix
            // * fill first N rows of design matrix with values
            // * fill next M rows of design matrix with regularizing term
            // * append M zeros to Y
            // * append M elements, mean(abs(W)) each, to W
            //
            sx = new double[m];
            sy = new double[m];
            sbf = new double[m];
            for(j=0; j<=m-1; j++)
            {
                sx[j] = (double)(2*j)/(double)(m-1)-1;
            }
            for(i=0; i<=m-1; i++)
            {
                sy[i] = 1;
            }
            barycentricbuildfloaterhormann(sx, sy, m, d, b2);
            mx = 0;
            for(i=0; i<=n-1; i++)
            {
                barycentriccalcbasis(b2, x[i], ref sbf);
                for(i_=0; i_<=m-1;i_++)
                {
                    fmatrix[i,i_] = sbf[i_];
                }
                y2[i] = y[i];
                w2[i] = w[i];
                mx = mx+Math.Abs(w[i])/n;
            }
            for(i=0; i<=m-1; i++)
            {
                for(j=0; j<=m-1; j++)
                {
                    if( i==j )
                    {
                        fmatrix[n+i,j] = decay;
                    }
                    else
                    {
                        fmatrix[n+i,j] = 0;
                    }
                }
                y2[n+i] = 0;
                w2[n+i] = mx;
            }
            if( k>0 )
            {
                for(j=0; j<=m-1; j++)
                {
                    for(i=0; i<=m-1; i++)
                    {
                        sy[i] = 0;
                    }
                    sy[j] = 1;
                    barycentricbuildfloaterhormann(sx, sy, m, d, b2);
                    for(i=0; i<=k-1; i++)
                    {
                        ap.assert(dc[i]>=0 & dc[i]<=1, "BarycentricFit: internal error!");
                        barycentricdiff1(b2, xc[i], ref v0, ref v1);
                        if( dc[i]==0 )
                        {
                            cmatrix[i,j] = v0;
                        }
                        if( dc[i]==1 )
                        {
                            cmatrix[i,j] = v1;
                        }
                    }
                }
                for(i=0; i<=k-1; i++)
                {
                    cmatrix[i,m] = yc[i];
                }
            }
            
            //
            // Solve constrained task
            //
            if( k>0 )
            {
                
                //
                // solve using regularization
                //
                lsfit.lsfitlinearwc(y2, w2, fmatrix, cmatrix, n+m, m, k, ref info, ref tmp, lrep);
            }
            else
            {
                
                //
                // no constraints, no regularization needed
                //
                lsfit.lsfitlinearwc(y, w, fmatrix, cmatrix, n, m, k, ref info, ref tmp, lrep);
            }
            if( info<0 )
            {
                return;
            }
            
            //
            // Generate interpolant and scale it
            //
            for(i_=0; i_<=m-1;i_++)
            {
                sy[i_] = tmp[i_];
            }
            barycentricbuildfloaterhormann(sx, sy, m, d, b);
            barycentriclintransx(b, 2/(xb-xa), -((xa+xb)/(xb-xa)));
            barycentriclintransy(b, sb-sa, sa);
            
            //
            // Scale absolute errors obtained from LSFitLinearW.
            // Relative error should be calculated separately
            // (because of shifting/scaling of the task)
            //
            rep.taskrcond = lrep.taskrcond;
            rep.rmserror = lrep.rmserror*(sb-sa);
            rep.avgerror = lrep.avgerror*(sb-sa);
            rep.maxerror = lrep.maxerror*(sb-sa);
            rep.avgrelerror = 0;
            relcnt = 0;
            for(i=0; i<=n-1; i++)
            {
                if( (double)(yoriginal[i])!=(double)(0) )
                {
                    rep.avgrelerror = rep.avgrelerror+Math.Abs(barycentriccalc(b, xoriginal[i])-yoriginal[i])/Math.Abs(yoriginal[i]);
                    relcnt = relcnt+1;
                }
            }
            if( relcnt!=0 )
            {
                rep.avgrelerror = rep.avgrelerror/relcnt;
            }
        }
Exemplo n.º 13
0
        /*************************************************************************
        Weighted  fitting  by  Chebyshev  polynomial  in  barycentric  form,  with
        constraints on function values or first derivatives.

        Small regularizing term is used when solving constrained tasks (to improve
        stability).

        Task is linear, so linear least squares solver is used. Complexity of this
        computational scheme is O(N*M^2), mostly dominated by least squares solver

        SEE ALSO:
            PolynomialFit()

        INPUT PARAMETERS:
            X   -   points, array[0..N-1].
            Y   -   function values, array[0..N-1].
            W   -   weights, array[0..N-1]
                    Each summand in square  sum  of  approximation deviations from
                    given  values  is  multiplied  by  the square of corresponding
                    weight. Fill it by 1's if you don't  want  to  solve  weighted
                    task.
            N   -   number of points, N>0.
            XC  -   points where polynomial values/derivatives are constrained,
                    array[0..K-1].
            YC  -   values of constraints, array[0..K-1]
            DC  -   array[0..K-1], types of constraints:
                    * DC[i]=0   means that P(XC[i])=YC[i]
                    * DC[i]=1   means that P'(XC[i])=YC[i]
                    SEE BELOW FOR IMPORTANT INFORMATION ON CONSTRAINTS
            K   -   number of constraints, 0<=K<M.
                    K=0 means no constraints (XC/YC/DC are not used in such cases)
            M   -   number of basis functions (= polynomial_degree + 1), M>=1

        OUTPUT PARAMETERS:
            Info-   same format as in LSFitLinearW() subroutine:
                    * Info>0    task is solved
                    * Info<=0   an error occured:
                                -4 means inconvergence of internal SVD
                                -3 means inconsistent constraints
            P   -   interpolant in barycentric form.
            Rep -   report, same format as in LSFitLinearW() subroutine.
                    Following fields are set:
                    * RMSError      rms error on the (X,Y).
                    * AvgError      average error on the (X,Y).
                    * AvgRelError   average relative error on the non-zero Y
                    * MaxError      maximum error
                                    NON-WEIGHTED ERRORS ARE CALCULATED

        IMPORTANT:
            this subroitine doesn't calculate task's condition number for K<>0.

        SETTING CONSTRAINTS - DANGERS AND OPPORTUNITIES:

        Setting constraints can lead  to undesired  results,  like ill-conditioned
        behavior, or inconsistency being detected. From the other side,  it allows
        us to improve quality of the fit. Here we summarize  our  experience  with
        constrained regression splines:
        * even simple constraints can be inconsistent, see  Wikipedia  article  on
          this subject: http://en.wikipedia.org/wiki/Birkhoff_interpolation
        * the  greater  is  M (given  fixed  constraints),  the  more chances that
          constraints will be consistent
        * in the general case, consistency of constraints is NOT GUARANTEED.
        * in the one special cases, however, we can  guarantee  consistency.  This
          case  is:  M>1  and constraints on the function values (NOT DERIVATIVES)

        Our final recommendation is to use constraints  WHEN  AND  ONLY  when  you
        can't solve your task without them. Anything beyond  special  cases  given
        above is not guaranteed and may result in inconsistency.

          -- ALGLIB PROJECT --
             Copyright 10.12.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void polynomialfitwc(double[] x,
            double[] y,
            double[] w,
            int n,
            double[] xc,
            double[] yc,
            int[] dc,
            int k,
            int m,
            ref int info,
            ratint.barycentricinterpolant p,
            polynomialfitreport rep)
        {
            double xa = 0;
            double xb = 0;
            double sa = 0;
            double sb = 0;
            double[] xoriginal = new double[0];
            double[] yoriginal = new double[0];
            double[] y2 = new double[0];
            double[] w2 = new double[0];
            double[] tmp = new double[0];
            double[] tmp2 = new double[0];
            double[] tmpdiff = new double[0];
            double[] bx = new double[0];
            double[] by = new double[0];
            double[] bw = new double[0];
            double[,] fmatrix = new double[0,0];
            double[,] cmatrix = new double[0,0];
            int i = 0;
            int j = 0;
            double mx = 0;
            double decay = 0;
            double u = 0;
            double v = 0;
            double s = 0;
            int relcnt = 0;
            lsfit.lsfitreport lrep = new lsfit.lsfitreport();
            int i_ = 0;

            x = (double[])x.Clone();
            y = (double[])y.Clone();
            xc = (double[])xc.Clone();
            yc = (double[])yc.Clone();
            info = 0;

            ap.assert(n>0, "PolynomialFitWC: N<=0!");
            ap.assert(m>0, "PolynomialFitWC: M<=0!");
            ap.assert(k>=0, "PolynomialFitWC: K<0!");
            ap.assert(k<m, "PolynomialFitWC: K>=M!");
            ap.assert(ap.len(x)>=n, "PolynomialFitWC: Length(X)<N!");
            ap.assert(ap.len(y)>=n, "PolynomialFitWC: Length(Y)<N!");
            ap.assert(ap.len(w)>=n, "PolynomialFitWC: Length(W)<N!");
            ap.assert(ap.len(xc)>=k, "PolynomialFitWC: Length(XC)<K!");
            ap.assert(ap.len(yc)>=k, "PolynomialFitWC: Length(YC)<K!");
            ap.assert(ap.len(dc)>=k, "PolynomialFitWC: Length(DC)<K!");
            ap.assert(apserv.isfinitevector(x, n), "PolynomialFitWC: X contains infinite or NaN values!");
            ap.assert(apserv.isfinitevector(y, n), "PolynomialFitWC: Y contains infinite or NaN values!");
            ap.assert(apserv.isfinitevector(w, n), "PolynomialFitWC: X contains infinite or NaN values!");
            ap.assert(apserv.isfinitevector(xc, k), "PolynomialFitWC: XC contains infinite or NaN values!");
            ap.assert(apserv.isfinitevector(yc, k), "PolynomialFitWC: YC contains infinite or NaN values!");
            for(i=0; i<=k-1; i++)
            {
                ap.assert(dc[i]==0 | dc[i]==1, "PolynomialFitWC: one of DC[] is not 0 or 1!");
            }
            
            //
            // weight decay for correct handling of task which becomes
            // degenerate after constraints are applied
            //
            decay = 10000*math.machineepsilon;
            
            //
            // Scale X, Y, XC, YC
            //
            lsfit.lsfitscalexy(ref x, ref y, n, ref xc, ref yc, dc, k, ref xa, ref xb, ref sa, ref sb, ref xoriginal, ref yoriginal);
            
            //
            // allocate space, initialize/fill:
            // * FMatrix-   values of basis functions at X[]
            // * CMatrix-   values (derivatives) of basis functions at XC[]
            // * fill constraints matrix
            // * fill first N rows of design matrix with values
            // * fill next M rows of design matrix with regularizing term
            // * append M zeros to Y
            // * append M elements, mean(abs(W)) each, to W
            //
            y2 = new double[n+m];
            w2 = new double[n+m];
            tmp = new double[m];
            tmpdiff = new double[m];
            fmatrix = new double[n+m, m];
            if( k>0 )
            {
                cmatrix = new double[k, m+1];
            }
            
            //
            // Fill design matrix, Y2, W2:
            // * first N rows with basis functions for original points
            // * next M rows with decay terms
            //
            for(i=0; i<=n-1; i++)
            {
                
                //
                // prepare Ith row
                // use Tmp for calculations to avoid multidimensional arrays overhead
                //
                for(j=0; j<=m-1; j++)
                {
                    if( j==0 )
                    {
                        tmp[j] = 1;
                    }
                    else
                    {
                        if( j==1 )
                        {
                            tmp[j] = x[i];
                        }
                        else
                        {
                            tmp[j] = 2*x[i]*tmp[j-1]-tmp[j-2];
                        }
                    }
                }
                for(i_=0; i_<=m-1;i_++)
                {
                    fmatrix[i,i_] = tmp[i_];
                }
            }
            for(i=0; i<=m-1; i++)
            {
                for(j=0; j<=m-1; j++)
                {
                    if( i==j )
                    {
                        fmatrix[n+i,j] = decay;
                    }
                    else
                    {
                        fmatrix[n+i,j] = 0;
                    }
                }
            }
            for(i_=0; i_<=n-1;i_++)
            {
                y2[i_] = y[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                w2[i_] = w[i_];
            }
            mx = 0;
            for(i=0; i<=n-1; i++)
            {
                mx = mx+Math.Abs(w[i]);
            }
            mx = mx/n;
            for(i=0; i<=m-1; i++)
            {
                y2[n+i] = 0;
                w2[n+i] = mx;
            }
            
            //
            // fill constraints matrix
            //
            for(i=0; i<=k-1; i++)
            {
                
                //
                // prepare Ith row
                // use Tmp for basis function values,
                // TmpDiff for basos function derivatives
                //
                for(j=0; j<=m-1; j++)
                {
                    if( j==0 )
                    {
                        tmp[j] = 1;
                        tmpdiff[j] = 0;
                    }
                    else
                    {
                        if( j==1 )
                        {
                            tmp[j] = xc[i];
                            tmpdiff[j] = 1;
                        }
                        else
                        {
                            tmp[j] = 2*xc[i]*tmp[j-1]-tmp[j-2];
                            tmpdiff[j] = 2*(tmp[j-1]+xc[i]*tmpdiff[j-1])-tmpdiff[j-2];
                        }
                    }
                }
                if( dc[i]==0 )
                {
                    for(i_=0; i_<=m-1;i_++)
                    {
                        cmatrix[i,i_] = tmp[i_];
                    }
                }
                if( dc[i]==1 )
                {
                    for(i_=0; i_<=m-1;i_++)
                    {
                        cmatrix[i,i_] = tmpdiff[i_];
                    }
                }
                cmatrix[i,m] = yc[i];
            }
            
            //
            // Solve constrained task
            //
            if( k>0 )
            {
                
                //
                // solve using regularization
                //
                lsfit.lsfitlinearwc(y2, w2, fmatrix, cmatrix, n+m, m, k, ref info, ref tmp, lrep);
            }
            else
            {
                
                //
                // no constraints, no regularization needed
                //
                lsfit.lsfitlinearwc(y, w, fmatrix, cmatrix, n, m, 0, ref info, ref tmp, lrep);
            }
            if( info<0 )
            {
                return;
            }
            
            //
            // Generate barycentric model and scale it
            // * BX, BY store barycentric model nodes
            // * FMatrix is reused (remember - it is at least MxM, what we need)
            //
            // Model intialization is done in O(M^2). In principle, it can be
            // done in O(M*log(M)), but before it we solved task with O(N*M^2)
            // complexity, so it is only a small amount of total time spent.
            //
            bx = new double[m];
            by = new double[m];
            bw = new double[m];
            tmp2 = new double[m];
            s = 1;
            for(i=0; i<=m-1; i++)
            {
                if( m!=1 )
                {
                    u = Math.Cos(Math.PI*i/(m-1));
                }
                else
                {
                    u = 0;
                }
                v = 0;
                for(j=0; j<=m-1; j++)
                {
                    if( j==0 )
                    {
                        tmp2[j] = 1;
                    }
                    else
                    {
                        if( j==1 )
                        {
                            tmp2[j] = u;
                        }
                        else
                        {
                            tmp2[j] = 2*u*tmp2[j-1]-tmp2[j-2];
                        }
                    }
                    v = v+tmp[j]*tmp2[j];
                }
                bx[i] = u;
                by[i] = v;
                bw[i] = s;
                if( i==0 | i==m-1 )
                {
                    bw[i] = 0.5*bw[i];
                }
                s = -s;
            }
            ratint.barycentricbuildxyw(bx, by, bw, m, p);
            ratint.barycentriclintransx(p, 2/(xb-xa), -((xa+xb)/(xb-xa)));
            ratint.barycentriclintransy(p, sb-sa, sa);
            
            //
            // Scale absolute errors obtained from LSFitLinearW.
            // Relative error should be calculated separately
            // (because of shifting/scaling of the task)
            //
            rep.taskrcond = lrep.taskrcond;
            rep.rmserror = lrep.rmserror*(sb-sa);
            rep.avgerror = lrep.avgerror*(sb-sa);
            rep.maxerror = lrep.maxerror*(sb-sa);
            rep.avgrelerror = 0;
            relcnt = 0;
            for(i=0; i<=n-1; i++)
            {
                if( (double)(yoriginal[i])!=(double)(0) )
                {
                    rep.avgrelerror = rep.avgrelerror+Math.Abs(ratint.barycentriccalc(p, xoriginal[i])-yoriginal[i])/Math.Abs(yoriginal[i]);
                    relcnt = relcnt+1;
                }
            }
            if( relcnt!=0 )
            {
                rep.avgrelerror = rep.avgrelerror/relcnt;
            }
        }
    public static int Main(string[] args)
    {
        int m = 0;
        int n = 0;
        int k = 0;
        double[] y = new double[0];
        double[,] x = new double[0,0];
        double[] c = new double[0];
        lsfit.lsfitreport rep = new lsfit.lsfitreport();
        lsfit.lsfitstate state = new lsfit.lsfitstate();
        int info = 0;
        double epsf = 0;
        double epsx = 0;
        int maxits = 0;
        int i = 0;
        int j = 0;
        double a = 0;
        double b = 0;

        System.Console.Write("Fitting 0.5(1+cos(x)) on [-pi,+pi] with exp(-alpha*x^2)");
        System.Console.WriteLine();
        
        //
        // Fitting 0.5(1+cos(x)) on [-pi,+pi] with Gaussian exp(-alpha*x^2):
        // * without Hessian (gradient only)
        // * using alpha=1 as initial value
        // * using 1000 uniformly distributed points to fit to
        //
        // Notes:
        // * N - number of points
        // * M - dimension of space where points reside
        // * K - number of parameters being fitted
        //
        n = 1000;
        m = 1;
        k = 1;
        a = -Math.PI;
        b = +Math.PI;
        
        //
        // Prepare task matrix
        //
        y = new double[n];
        x = new double[n, m];
        c = new double[k];
        for(i=0; i<=n-1; i++)
        {
            x[i,0] = a+(b-a)*i/(n-1);
            y[i] = 0.5*(1+Math.Cos(x[i,0]));
        }
        c[0] = 1.0;
        epsf = 0.0;
        epsx = 0.0001;
        maxits = 0;
        
        //
        // Solve
        //
        lsfit.lsfitnonlinearfg(ref x, ref y, ref c, n, m, k, true, ref state);
        lsfit.lsfitnonlinearsetcond(ref state, epsf, epsx, maxits);
        while( lsfit.lsfitnonlineariteration(ref state) )
        {
            if( state.needf )
            {
                
                //
                // F(x) = Exp(-alpha*x^2)
                //
                state.f = Math.Exp(-(state.c[0]*AP.Math.Sqr(state.x[0])));
            }
            if( state.needfg )
            {
                
                //
                // F(x)      = Exp(-alpha*x^2)
                // dF/dAlpha = (-x^2)*Exp(-alpha*x^2)
                //
                state.f = Math.Exp(-(state.c[0]*AP.Math.Sqr(state.x[0])));
                state.g[0] = -(AP.Math.Sqr(state.x[0])*state.f);
            }
        }
        lsfit.lsfitnonlinearresults(ref state, ref info, ref c, ref rep);
        System.Console.Write("alpha:   ");
        System.Console.Write("{0,0:F3}",c[0]);
        System.Console.WriteLine();
        System.Console.Write("rms.err: ");
        System.Console.Write("{0,0:F3}",rep.rmserror);
        System.Console.WriteLine();
        System.Console.Write("max.err: ");
        System.Console.Write("{0,0:F3}",rep.maxerror);
        System.Console.WriteLine();
        System.Console.Write("Termination type: ");
        System.Console.Write("{0,0:d}",info);
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.WriteLine();
        return 0;
    }
    public static int Main(string[] args)
    {
        int m = 0;
        int n = 0;
        int k = 0;
        double[] y = new double[0];
        double[,] x = new double[0,0];
        double[] c = new double[0];
        lsfit.lsfitreport rep = new lsfit.lsfitreport();
        lsfit.lsfitstate state = new lsfit.lsfitstate();
        int info = 0;
        double epsf = 0;
        double epsx = 0;
        int maxits = 0;
        int i = 0;
        int j = 0;
        double a = 0;
        double b = 0;

        System.Console.Write("Fitting 1-x^2 on [-1,+1] with cos(alpha*pi*x)+beta");
        System.Console.WriteLine();
        
        //
        // Fitting 1-x^2 on [-1,+1] with cos(alpha*pi*x)+beta:
        // * using Hessian
        // * using alpha=1 and beta=0 as initial values
        // * using 1000 uniformly distributed points to fit to
        //
        // Notes:
        // * N - number of points
        // * M - dimension of space where points reside
        // * K - number of parameters being fitted
        //
        n = 1000;
        m = 1;
        k = 2;
        a = -1;
        b = +1;
        
        //
        // Prepare task matrix
        //
        y = new double[n];
        x = new double[n, m];
        c = new double[k];
        for(i=0; i<=n-1; i++)
        {
            x[i,0] = a+(b-a)*i/(n-1);
            y[i] = 1-AP.Math.Sqr(x[i,0]);
        }
        c[0] = 1.0;
        c[1] = 0.0;
        epsf = 0.0;
        epsx = 0.0001;
        maxits = 0;
        
        //
        // Solve
        //
        lsfit.lsfitnonlinearfgh(ref x, ref y, ref c, n, m, k, ref state);
        lsfit.lsfitnonlinearsetcond(ref state, epsf, epsx, maxits);
        while( lsfit.lsfitnonlineariteration(ref state) )
        {
            
            //
            // F(x) = Cos(alpha*pi*x)+beta
            //
            state.f = Math.Cos(state.c[0]*Math.PI*state.x[0])+state.c[1];
            
            //
            // F(x)      = Cos(alpha*pi*x)+beta
            // dF/dAlpha = -pi*x*Sin(alpha*pi*x)
            // dF/dBeta  = 1.0
            //
            if( state.needfg | state.needfgh )
            {
                state.g[0] = -(Math.PI*state.x[0]*Math.Sin(state.c[0]*Math.PI*state.x[0]));
                state.g[1] = 1.0;
            }
            
            //
            // F(x)            = Cos(alpha*pi*x)+beta
            // d2F/dAlpha2     = -(pi*x)^2*Cos(alpha*pi*x)
            // d2F/dAlphadBeta = 0
            // d2F/dBeta2     =  0
            //
            if( state.needfgh )
            {
                state.h[0,0] = -(AP.Math.Sqr(Math.PI*state.x[0])*Math.Cos(state.c[0]*Math.PI*state.x[0]));
                state.h[0,1] = 0.0;
                state.h[1,0] = 0.0;
                state.h[1,1] = 0.0;
            }
        }
        lsfit.lsfitnonlinearresults(ref state, ref info, ref c, ref rep);
        System.Console.Write("alpha:   ");
        System.Console.Write("{0,0:F3}",c[0]);
        System.Console.WriteLine();
        System.Console.Write("beta:    ");
        System.Console.Write("{0,0:F3}",c[1]);
        System.Console.WriteLine();
        System.Console.Write("rms.err: ");
        System.Console.Write("{0,0:F3}",rep.rmserror);
        System.Console.WriteLine();
        System.Console.Write("max.err: ");
        System.Console.Write("{0,0:F3}",rep.maxerror);
        System.Console.WriteLine();
        System.Console.Write("Termination type: ");
        System.Console.Write("{0,0:d}",info);
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.WriteLine();
        return 0;
    }
Exemplo n.º 16
0
        private static void testgeneralfitting(ref bool llserrors,
            ref bool nlserrors)
        {
            double threshold = 0;
            double nlthreshold = 0;
            int maxn = 0;
            int maxm = 0;
            int passcount = 0;
            int n = 0;
            int m = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            int pass = 0;
            double xscale = 0;
            double diffstep = 0;
            double[] x = new double[0];
            double[] y = new double[0];
            double[] w = new double[0];
            double[] w2 = new double[0];
            double[] c = new double[0];
            double[] c2 = new double[0];
            double[,] a = new double[0,0];
            double[,] a2 = new double[0,0];
            double[,] cm = new double[0,0];
            double v = 0;
            double v1 = 0;
            double v2 = 0;
            lsfit.lsfitreport rep = new lsfit.lsfitreport();
            lsfit.lsfitreport rep2 = new lsfit.lsfitreport();
            int info = 0;
            int info2 = 0;
            double refrms = 0;
            double refavg = 0;
            double refavgrel = 0;
            double refmax = 0;
            lsfit.lsfitstate state = new lsfit.lsfitstate();

            llserrors = false;
            nlserrors = false;
            threshold = 10000*math.machineepsilon;
            nlthreshold = 0.00001;
            diffstep = 0.0001;
            maxn = 6;
            maxm = 6;
            passcount = 4;
            
            //
            // Testing unconstrained least squares (linear/nonlinear)
            //
            for(n=1; n<=maxn; n++)
            {
                for(m=1; m<=maxm; m++)
                {
                    for(pass=1; pass<=passcount; pass++)
                    {
                        
                        //
                        // Solve non-degenerate linear least squares task
                        // Use Chebyshev basis. Its condition number is very good.
                        //
                        a = new double[n, m];
                        x = new double[n];
                        y = new double[n];
                        w = new double[n];
                        xscale = 0.9+0.1*math.randomreal();
                        for(i=0; i<=n-1; i++)
                        {
                            if( n==1 )
                            {
                                x[i] = 2*math.randomreal()-1;
                            }
                            else
                            {
                                x[i] = xscale*((double)(2*i)/(double)(n-1)-1);
                            }
                            y[i] = 3*x[i]+Math.Exp(x[i]);
                            w[i] = 1+math.randomreal();
                            a[i,0] = 1;
                            if( m>1 )
                            {
                                a[i,1] = x[i];
                            }
                            for(j=2; j<=m-1; j++)
                            {
                                a[i,j] = 2*x[i]*a[i,j-1]-a[i,j-2];
                            }
                        }
                        
                        //
                        // 1. test weighted fitting (optimality)
                        // 2. Solve degenerate least squares task built on the basis
                        //    of previous task
                        //
                        lsfit.lsfitlinearw(y, w, a, n, m, ref info, ref c, rep);
                        if( info<=0 )
                        {
                            llserrors = true;
                        }
                        else
                        {
                            llserrors = llserrors | !isglssolution(n, m, 0, y, w, a, cm, c);
                        }
                        a2 = new double[n, 2*m];
                        for(i=0; i<=n-1; i++)
                        {
                            for(j=0; j<=m-1; j++)
                            {
                                a2[i,2*j+0] = a[i,j];
                                a2[i,2*j+1] = a[i,j];
                            }
                        }
                        lsfit.lsfitlinearw(y, w, a2, n, 2*m, ref info, ref c2, rep);
                        if( info<=0 )
                        {
                            llserrors = true;
                        }
                        else
                        {
                            
                            //
                            // test answer correctness using design matrix properties
                            // and previous task solution
                            //
                            for(j=0; j<=m-1; j++)
                            {
                                llserrors = llserrors | (double)(Math.Abs(c2[2*j+0]+c2[2*j+1]-c[j]))>(double)(threshold);
                            }
                        }
                        
                        //
                        // test non-weighted fitting
                        //
                        w2 = new double[n];
                        for(i=0; i<=n-1; i++)
                        {
                            w2[i] = 1;
                        }
                        lsfit.lsfitlinearw(y, w2, a, n, m, ref info, ref c, rep);
                        lsfit.lsfitlinear(y, a, n, m, ref info2, ref c2, rep2);
                        if( info<=0 | info2<=0 )
                        {
                            llserrors = true;
                        }
                        else
                        {
                            
                            //
                            // test answer correctness
                            //
                            for(j=0; j<=m-1; j++)
                            {
                                llserrors = llserrors | (double)(Math.Abs(c[j]-c2[j]))>(double)(threshold);
                            }
                            llserrors = llserrors | (double)(Math.Abs(rep.taskrcond-rep2.taskrcond))>(double)(threshold);
                        }
                        
                        //
                        // test nonlinear fitting on the linear task
                        // (only non-degenerate tasks are tested)
                        // and compare with answer from linear fitting subroutine
                        //
                        if( n>=m )
                        {
                            c2 = new double[m];
                            
                            //
                            // test function/gradient/Hessian-based weighted fitting
                            //
                            lsfit.lsfitlinearw(y, w, a, n, m, ref info, ref c, rep);
                            for(i=0; i<=m-1; i++)
                            {
                                c2[i] = 2*math.randomreal()-1;
                            }
                            lsfit.lsfitcreatewf(a, y, w, c2, n, m, m, diffstep, state);
                            lsfit.lsfitsetcond(state, 0.0, nlthreshold, 0);
                            fitlinearnonlinear(m, 0, a, state, ref nlserrors);
                            lsfit.lsfitresults(state, ref info, ref c2, rep2);
                            if( info<=0 )
                            {
                                nlserrors = true;
                            }
                            else
                            {
                                for(i=0; i<=m-1; i++)
                                {
                                    nlserrors = nlserrors | (double)(Math.Abs(c[i]-c2[i]))>(double)(100*nlthreshold);
                                }
                            }
                            for(i=0; i<=m-1; i++)
                            {
                                c2[i] = 2*math.randomreal()-1;
                            }
                            lsfit.lsfitcreatewfg(a, y, w, c2, n, m, m, (double)(math.randomreal())>(double)(0.5), state);
                            lsfit.lsfitsetcond(state, 0.0, nlthreshold, 0);
                            fitlinearnonlinear(m, 1, a, state, ref nlserrors);
                            lsfit.lsfitresults(state, ref info, ref c2, rep2);
                            if( info<=0 )
                            {
                                nlserrors = true;
                            }
                            else
                            {
                                for(i=0; i<=m-1; i++)
                                {
                                    nlserrors = nlserrors | (double)(Math.Abs(c[i]-c2[i]))>(double)(100*nlthreshold);
                                }
                            }
                            for(i=0; i<=m-1; i++)
                            {
                                c2[i] = 2*math.randomreal()-1;
                            }
                            lsfit.lsfitcreatewfgh(a, y, w, c2, n, m, m, state);
                            lsfit.lsfitsetcond(state, 0.0, nlthreshold, 0);
                            fitlinearnonlinear(m, 2, a, state, ref nlserrors);
                            lsfit.lsfitresults(state, ref info, ref c2, rep2);
                            if( info<=0 )
                            {
                                nlserrors = true;
                            }
                            else
                            {
                                for(i=0; i<=m-1; i++)
                                {
                                    nlserrors = nlserrors | (double)(Math.Abs(c[i]-c2[i]))>(double)(100*nlthreshold);
                                }
                            }
                            
                            //
                            // test gradient-only or Hessian-based fitting without weights
                            //
                            lsfit.lsfitlinear(y, a, n, m, ref info, ref c, rep);
                            for(i=0; i<=m-1; i++)
                            {
                                c2[i] = 2*math.randomreal()-1;
                            }
                            lsfit.lsfitcreatef(a, y, c2, n, m, m, diffstep, state);
                            lsfit.lsfitsetcond(state, 0.0, nlthreshold, 0);
                            fitlinearnonlinear(m, 0, a, state, ref nlserrors);
                            lsfit.lsfitresults(state, ref info, ref c2, rep2);
                            if( info<=0 )
                            {
                                nlserrors = true;
                            }
                            else
                            {
                                for(i=0; i<=m-1; i++)
                                {
                                    nlserrors = nlserrors | (double)(Math.Abs(c[i]-c2[i]))>(double)(100*nlthreshold);
                                }
                            }
                            for(i=0; i<=m-1; i++)
                            {
                                c2[i] = 2*math.randomreal()-1;
                            }
                            lsfit.lsfitcreatefg(a, y, c2, n, m, m, (double)(math.randomreal())>(double)(0.5), state);
                            lsfit.lsfitsetcond(state, 0.0, nlthreshold, 0);
                            fitlinearnonlinear(m, 1, a, state, ref nlserrors);
                            lsfit.lsfitresults(state, ref info, ref c2, rep2);
                            if( info<=0 )
                            {
                                nlserrors = true;
                            }
                            else
                            {
                                for(i=0; i<=m-1; i++)
                                {
                                    nlserrors = nlserrors | (double)(Math.Abs(c[i]-c2[i]))>(double)(100*nlthreshold);
                                }
                            }
                            for(i=0; i<=m-1; i++)
                            {
                                c2[i] = 2*math.randomreal()-1;
                            }
                            lsfit.lsfitcreatefgh(a, y, c2, n, m, m, state);
                            lsfit.lsfitsetcond(state, 0.0, nlthreshold, 0);
                            fitlinearnonlinear(m, 2, a, state, ref nlserrors);
                            lsfit.lsfitresults(state, ref info, ref c2, rep2);
                            if( info<=0 )
                            {
                                nlserrors = true;
                            }
                            else
                            {
                                for(i=0; i<=m-1; i++)
                                {
                                    nlserrors = nlserrors | (double)(Math.Abs(c[i]-c2[i]))>(double)(100*nlthreshold);
                                }
                            }
                        }
                    }
                }
                
                //
                // test correctness of the RCond field
                //
                a = new double[n-1+1, n-1+1];
                x = new double[n-1+1];
                y = new double[n-1+1];
                w = new double[n-1+1];
                v1 = math.maxrealnumber;
                v2 = math.minrealnumber;
                for(i=0; i<=n-1; i++)
                {
                    x[i] = 0.1+0.9*math.randomreal();
                    y[i] = 0.1+0.9*math.randomreal();
                    w[i] = 1;
                    for(j=0; j<=n-1; j++)
                    {
                        if( i==j )
                        {
                            a[i,i] = 0.1+0.9*math.randomreal();
                            v1 = Math.Min(v1, a[i,i]);
                            v2 = Math.Max(v2, a[i,i]);
                        }
                        else
                        {
                            a[i,j] = 0;
                        }
                    }
                }
                lsfit.lsfitlinearw(y, w, a, n, n, ref info, ref c, rep);
                if( info<=0 )
                {
                    llserrors = true;
                }
                else
                {
                    llserrors = llserrors | (double)(Math.Abs(rep.taskrcond-v1/v2))>(double)(threshold);
                }
            }
            
            //
            // Test constrained least squares
            //
            for(pass=1; pass<=passcount; pass++)
            {
                for(n=1; n<=maxn; n++)
                {
                    for(m=1; m<=maxm; m++)
                    {
                        
                        //
                        // test for K<>0
                        //
                        for(k=1; k<=m-1; k++)
                        {
                            
                            //
                            // Prepare Chebyshev basis. Its condition number is very good.
                            // Prepare constraints (random numbers)
                            //
                            a = new double[n, m];
                            x = new double[n];
                            y = new double[n];
                            w = new double[n];
                            xscale = 0.9+0.1*math.randomreal();
                            for(i=0; i<=n-1; i++)
                            {
                                if( n==1 )
                                {
                                    x[i] = 2*math.randomreal()-1;
                                }
                                else
                                {
                                    x[i] = xscale*((double)(2*i)/(double)(n-1)-1);
                                }
                                y[i] = 3*x[i]+Math.Exp(x[i]);
                                w[i] = 1+math.randomreal();
                                a[i,0] = 1;
                                if( m>1 )
                                {
                                    a[i,1] = x[i];
                                }
                                for(j=2; j<=m-1; j++)
                                {
                                    a[i,j] = 2*x[i]*a[i,j-1]-a[i,j-2];
                                }
                            }
                            cm = new double[k, m+1];
                            for(i=0; i<=k-1; i++)
                            {
                                for(j=0; j<=m; j++)
                                {
                                    cm[i,j] = 2*math.randomreal()-1;
                                }
                            }
                            
                            //
                            // Solve constrained task
                            //
                            lsfit.lsfitlinearwc(y, w, a, cm, n, m, k, ref info, ref c, rep);
                            if( info<=0 )
                            {
                                llserrors = true;
                            }
                            else
                            {
                                llserrors = llserrors | !isglssolution(n, m, k, y, w, a, cm, c);
                            }
                            
                            //
                            // test non-weighted fitting
                            //
                            w2 = new double[n];
                            for(i=0; i<=n-1; i++)
                            {
                                w2[i] = 1;
                            }
                            lsfit.lsfitlinearwc(y, w2, a, cm, n, m, k, ref info, ref c, rep);
                            lsfit.lsfitlinearc(y, a, cm, n, m, k, ref info2, ref c2, rep2);
                            if( info<=0 | info2<=0 )
                            {
                                llserrors = true;
                            }
                            else
                            {
                                
                                //
                                // test answer correctness
                                //
                                for(j=0; j<=m-1; j++)
                                {
                                    llserrors = llserrors | (double)(Math.Abs(c[j]-c2[j]))>(double)(threshold);
                                }
                                llserrors = llserrors | (double)(Math.Abs(rep.taskrcond-rep2.taskrcond))>(double)(threshold);
                            }
                        }
                    }
                }
            }
            
            //
            // nonlinear task for nonlinear fitting:
            //
            //     f(X,C) = 1/(1+C*X^2),
            //     C(true) = 2.
            //
            n = 100;
            c = new double[1];
            c[0] = 1+2*math.randomreal();
            a = new double[n, 1];
            y = new double[n];
            for(i=0; i<=n-1; i++)
            {
                a[i,0] = 4*math.randomreal()-2;
                y[i] = 1/(1+2*math.sqr(a[i,0]));
            }
            lsfit.lsfitcreatefg(a, y, c, n, 1, 1, true, state);
            lsfit.lsfitsetcond(state, 0.0, nlthreshold, 0);
            while( lsfit.lsfititeration(state) )
            {
                if( state.needf )
                {
                    state.f = 1/(1+state.c[0]*math.sqr(state.x[0]));
                }
                if( state.needfg )
                {
                    state.f = 1/(1+state.c[0]*math.sqr(state.x[0]));
                    state.g[0] = -(math.sqr(state.x[0])/math.sqr(1+state.c[0]*math.sqr(state.x[0])));
                }
            }
            lsfit.lsfitresults(state, ref info, ref c, rep);
            if( info<=0 )
            {
                nlserrors = true;
            }
            else
            {
                nlserrors = nlserrors | (double)(Math.Abs(c[0]-2))>(double)(100*nlthreshold);
            }
            
            //
            // solve simple task (fitting by constant function) and check
            // correctness of the errors calculated by subroutines
            //
            for(pass=1; pass<=passcount; pass++)
            {
                
                //
                // test on task with non-zero Yi
                //
                n = 4;
                v1 = math.randomreal();
                v2 = math.randomreal();
                v = 1+math.randomreal();
                c = new double[1];
                c[0] = 1+2*math.randomreal();
                a = new double[4, 1];
                y = new double[4];
                a[0,0] = 1;
                y[0] = v-v2;
                a[1,0] = 1;
                y[1] = v-v1;
                a[2,0] = 1;
                y[2] = v+v1;
                a[3,0] = 1;
                y[3] = v+v2;
                refrms = Math.Sqrt((math.sqr(v1)+math.sqr(v2))/2);
                refavg = (Math.Abs(v1)+Math.Abs(v2))/2;
                refavgrel = 0.25*(Math.Abs(v2)/Math.Abs(v-v2)+Math.Abs(v1)/Math.Abs(v-v1)+Math.Abs(v1)/Math.Abs(v+v1)+Math.Abs(v2)/Math.Abs(v+v2));
                refmax = Math.Max(v1, v2);
                
                //
                // Test LLS
                //
                lsfit.lsfitlinear(y, a, 4, 1, ref info, ref c, rep);
                if( info<=0 )
                {
                    llserrors = true;
                }
                else
                {
                    llserrors = llserrors | (double)(Math.Abs(c[0]-v))>(double)(threshold);
                    llserrors = llserrors | (double)(Math.Abs(rep.rmserror-refrms))>(double)(threshold);
                    llserrors = llserrors | (double)(Math.Abs(rep.avgerror-refavg))>(double)(threshold);
                    llserrors = llserrors | (double)(Math.Abs(rep.avgrelerror-refavgrel))>(double)(threshold);
                    llserrors = llserrors | (double)(Math.Abs(rep.maxerror-refmax))>(double)(threshold);
                }
                
                //
                // Test NLS
                //
                lsfit.lsfitcreatefg(a, y, c, 4, 1, 1, true, state);
                lsfit.lsfitsetcond(state, 0.0, nlthreshold, 0);
                while( lsfit.lsfititeration(state) )
                {
                    if( state.needf )
                    {
                        state.f = state.c[0];
                    }
                    if( state.needfg )
                    {
                        state.f = state.c[0];
                        state.g[0] = 1;
                    }
                }
                lsfit.lsfitresults(state, ref info, ref c, rep);
                if( info<=0 )
                {
                    nlserrors = true;
                }
                else
                {
                    nlserrors = nlserrors | (double)(Math.Abs(c[0]-v))>(double)(threshold);
                    nlserrors = nlserrors | (double)(Math.Abs(rep.rmserror-refrms))>(double)(threshold);
                    nlserrors = nlserrors | (double)(Math.Abs(rep.avgerror-refavg))>(double)(threshold);
                    nlserrors = nlserrors | (double)(Math.Abs(rep.avgrelerror-refavgrel))>(double)(threshold);
                    nlserrors = nlserrors | (double)(Math.Abs(rep.maxerror-refmax))>(double)(threshold);
                }
            }
        }
    public static int Main(string[] args)
    {
        int m = 0;
        int n = 0;

        double[] y = new double[0];
        double[,] fmatrix = new double[0, 0];
        double[,] cmatrix = new double[0, 0];
        lsfit.lsfitreport rep = new lsfit.lsfitreport();
        int info = 0;

        double[] c = new double[0];
        int      i = 0;
        int      j = 0;
        double   x = 0;
        double   a = 0;
        double   b = 0;

        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.Write("Fitting tan(x) by third degree polynomial");
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.Write("Fit type             rms.err max.err    p(0)   dp(0)");
        System.Console.WriteLine();

        //
        // Fitting tan(x) at [0, 0.4*pi] by third degree polynomial:
        // a) without constraints
        // b) constrained at x=0: p(0)=0
        // c) constrained at x=0: p'(0)=1
        // c) constrained at x=0: p(0)=0, p'(0)=1
        //
        m = 4;
        n = 100;
        a = 0;
        b = 0.4 * Math.PI;

        //
        // Prepare task matrix
        //
        y       = new double[n];
        fmatrix = new double[n, m];
        for (i = 0; i <= n - 1; i++)
        {
            x             = a + (b - a) * i / (n - 1);
            y[i]          = Math.Tan(x);
            fmatrix[i, 0] = 1.0;
            for (j = 1; j <= m - 1; j++)
            {
                fmatrix[i, j] = x * fmatrix[i, j - 1];
            }
        }

        //
        // Solve unconstrained task
        //
        lsfit.lsfitlinear(ref y, ref fmatrix, n, m, ref info, ref c, ref rep);
        System.Console.Write("Unconstrained        ");
        System.Console.Write("{0,7:F4}", rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", c[0]);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", c[1]);
        System.Console.WriteLine();

        //
        // Solve constrained task, p(0)=0
        // Prepare constraints matrix:
        // * first M columns store values of basis functions at X=0
        // * last column stores zero (desired value at X=0)
        //
        cmatrix       = new double[1, m + 1];
        cmatrix[0, 0] = 1;
        for (i = 1; i <= m - 1; i++)
        {
            cmatrix[0, i] = 0;
        }
        cmatrix[0, m] = 0;
        lsfit.lsfitlinearc(y, ref fmatrix, ref cmatrix, n, m, 1, ref info, ref c, ref rep);
        System.Console.Write("Constrained, p(0)=0  ");
        System.Console.Write("{0,7:F4}", rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", c[0]);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", c[1]);
        System.Console.WriteLine();

        //
        // Solve constrained task, p'(0)=0
        // Prepare constraints matrix:
        // * first M columns store derivatives of basis functions at X=0
        // * last column stores 1.0 (desired derivative at X=0)
        //
        cmatrix = new double[1, m + 1];
        for (i = 0; i <= m - 1; i++)
        {
            cmatrix[0, i] = 0;
        }
        cmatrix[0, 1] = 1;
        cmatrix[0, m] = 1;
        lsfit.lsfitlinearc(y, ref fmatrix, ref cmatrix, n, m, 1, ref info, ref c, ref rep);
        System.Console.Write("Constrained, dp(0)=1 ");
        System.Console.Write("{0,7:F4}", rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", c[0]);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", c[1]);
        System.Console.WriteLine();

        //
        // Solve constrained task, p(0)=0, p'(0)=0
        // Prepare constraints matrix:
        // * first M columns store values/derivatives of basis functions at X=0
        // * last column stores desired values/derivative at X=0
        //
        cmatrix       = new double[2, m + 1];
        cmatrix[0, 0] = 1;
        for (i = 1; i <= m - 1; i++)
        {
            cmatrix[0, i] = 0;
        }
        cmatrix[0, m] = 0;
        for (i = 0; i <= m - 1; i++)
        {
            cmatrix[1, i] = 0;
        }
        cmatrix[1, 1] = 1;
        cmatrix[1, m] = 1;
        lsfit.lsfitlinearc(y, ref fmatrix, ref cmatrix, n, m, 2, ref info, ref c, ref rep);
        System.Console.Write("Constrained, both    ");
        System.Console.Write("{0,7:F4}", rep.rmserror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", rep.maxerror);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", c[0]);
        System.Console.Write(" ");
        System.Console.Write("{0,7:F4}", c[1]);
        System.Console.WriteLine();
        System.Console.WriteLine();
        System.Console.WriteLine();
        return(0);
    }