示例#1
0
        // generate double bivariate Chebychev polynomial
        public static bool bchgen(projUV a, projUV b, int nu, int nv, projUV[][] f, ProjFunc func)
        {
            projUV arg, bma, bpa;

            projUV[] t, c;

            bma.u = 0.5 * (b.u - a.u); bma.v = 0.5 * (b.v - a.v);
            bpa.u = 0.5 * (b.u + a.u); bpa.v = 0.5 * (b.v + a.v);
            for (int i = 0; i < nu; i++)
            {
                arg.u = Math.Cos(Proj.PI * (i + 0.5) / nu) * bma.u + bpa.u;
                for (int j = 0; j < nv; j++)
                {
                    arg.v   = Math.Cos(Proj.PI * (j + 0.5) / nv) * bma.v + bpa.v;
                    f[i][j] = func(arg);
                    if (f[i][j].u == Libc.HUGE_VAL)
                    {
                        return(true);
                    }
                }
            }

            try
            {
                c = new projUV[nu];
            }
            catch
            {
                return(true);
            }

            double fac = 2.0 / nu;

            for (int j = 0; j < nv; j++)
            {
                for (int i = 0; i < nu; i++)
                {
                    arg.u = arg.v = 0.0;
                    for (int k = 0; k < nu; k++)
                    {
                        double d = Math.Cos(Proj.PI * i * (k + 0.5) / nu);
                        arg.u += f[k][j].u * d;
                        arg.v += f[k][j].v * d;
                    }
                    arg.u *= fac;
                    arg.v *= fac;
                    c[i]   = arg;
                }
                for (int i = 0; i < nu; i++)
                {
                    f[i][j] = c[i];
                }
            }

            try
            {
                c = new projUV[nv];
            }
            catch
            {
                return(true);
            }

            fac = 2.0 / nv;
            for (int i = 0; i < nu; i++)
            {
                t = f[i];
                for (int j = 0; j < nv; j++)
                {
                    arg.u = arg.v = 0.0;
                    for (int k = 0; k < nv; k++)
                    {
                        double d = Math.Cos(Proj.PI * j * (k + 0.5) / nv);
                        arg.u += t[k].u * d;
                        arg.v += t[k].v * d;
                    }
                    arg.u *= fac;
                    arg.v *= fac;
                    c[j]   = arg;
                }
                f[i] = c;
                c    = t;
            }

            return(false);
        }
示例#2
0
        public static Tseries mk_cheby(projUV a, projUV b, double res, ref projUV resid, ProjFunc func, int nu, int nv, bool power)
        {
            try
            {
                projUV[][] w = new projUV[nu][];
                for (int k = 0; k < nu; k++)
                {
                    w[k] = new projUV[nv];
                }

                if (bchgen(a, b, nu, nv, w, func))
                {
                    return(null);
                }

                // analyse coefficients and adjust until residual OK
                double cutres = res;
                int    i      = 4;
                for (; i > 0; i--)
                {
                    eval(w, nu, nv, cutres, ref resid);
                    if (resid.u < res && resid.v < res)
                    {
                        break;
                    }
                    cutres *= 0.5;
                }

                // warn of too many tries
                if (i <= 0)
                {
                    resid.u = -resid.u;
                }

                double   ab;
                double[] p;

                int[] ncu = new int[nu];
                int[] ncv = new int[nv];

                // apply cut resolution and set pointers
                int nru = 0, nrv = 0;
                for (int j = 0; j < nu; ++j)
                {
                    ncu[j] = ncv[j] = 0;                 // clear column maxes

                    projUV[] s = w[j];
                    for (i = 0; i < nv; i++)
                    {
                        // < resolution ?
                        ab = Math.Abs(s[i].u);
                        if (ab < cutres)
                        {
                            s[i].u = 0.0;                                       // clear coefficient
                        }
                        else
                        {
                            ncu[j] = i + 1;                                             // update column max
                        }
                        ab = Math.Abs(s[i].v);
                        if (ab < cutres)
                        {
                            s[i].v = 0.0;                                       // same for v coef's
                        }
                        else
                        {
                            ncv[j] = i + 1;
                        }
                    }
                    if (ncu[j] != 0)
                    {
                        nru = j + 1;                                            // update row max
                    }
                    if (ncv[j] != 0)
                    {
                        nrv = j + 1;
                    }
                }

                if (power)
                {                 // convert to bivariate power series
                    if (!bch2bps(a, b, w, nu, nv))
                    {
                        return(null);
                    }

                    // possible change in some row counts, so readjust
                    nru = nrv = 0;
                    for (int j = 0; j < nu; ++j)
                    {
                        ncu[j] = ncv[j] = 0;                     // clear column maxes

                        projUV[] s = w[j];

                        for (i = 0; i < nv; i++)
                        {
                            if (s[i].u != 0)
                            {
                                ncu[j] = i + 1;                                         // update column max
                            }
                            if (s[i].v != 0)
                            {
                                ncv[j] = i + 1;
                            }
                        }
                        if (ncu[j] != 0)
                        {
                            nru = j + 1;                                                // update row max
                        }
                        if (ncv[j] != 0)
                        {
                            nrv = j + 1;
                        }
                    }

                    Tseries T = makeT(nru, nrv);
                    if (T != null)
                    {
                        T.a     = a;
                        T.b     = b;
                        T.mu    = nru - 1;
                        T.mv    = nrv - 1;
                        T.power = 1;

                        for (i = 0; i < nru; ++i)                    // store coefficient rows for u
                        {
                            T.cu[i].m = ncu[i];
                            if (T.cu[i].m != 0)
                            {
                                p = T.cu[i].c = new double[ncu[i]];
                                projUV[] s = w[i];
                                for (int j = 0; j < ncu[i]; j++)
                                {
                                    p[j] = s[j].u;
                                }
                            }
                        }

                        for (i = 0; i < nrv; ++i)                    // same for v
                        {
                            T.cv[i].m = ncv[i];
                            if (T.cv[i].m != 0)
                            {
                                p = T.cv[i].c = new double[ncv[i]];
                                projUV[] s = w[i];
                                for (int j = 0; j < ncv[i]; j++)
                                {
                                    p[j] = s[j].v;
                                }
                            }
                        }
                    }
                    return(T);
                }
                else
                {
                    Tseries T = makeT(nru, nrv);
                    if (T != null)
                    {
                        // else make returned Chebyshev coefficient structure
                        T.mu    = nru - 1;                  // save row degree
                        T.mv    = nrv - 1;
                        T.a.u   = a.u + b.u;                // set argument scaling
                        T.a.v   = a.v + b.v;
                        T.b.u   = 1.0 / (b.u - a.u);
                        T.b.v   = 1.0 / (b.v - a.v);
                        T.power = 0;

                        for (i = 0; i < nru; ++i)                    // store coefficient rows for u
                        {
                            T.cu[i].m = ncu[i];
                            if (T.cu[i].m != 0)
                            {
                                p = T.cu[i].c = new double[ncu[i]];
                                projUV[] s = w[i];
                                for (int j = 0; j < ncu[i]; j++)
                                {
                                    p[j] = s[j].u;
                                }
                            }
                        }

                        for (i = 0; i < nrv; ++i)                    // same for v
                        {
                            T.cv[i].m = ncv[i];
                            if (T.cv[i].m != 0)
                            {
                                p = T.cv[i].c = new double[ncv[i]];
                                projUV[] s = w[i];
                                for (int j = 0; j < ncv[i]; j++)
                                {
                                    p[j] = s[j].v;
                                }
                            }
                        }
                    }
                    return(T);
                }
            }
            catch
            {
                return(null);
            }
        }
示例#3
0
        public static Tseries mk_cheby(projUV a, projUV b, double res, ref projUV resid, ProjFunc func, int nu, int nv, bool power)
        {
            try
            {
                projUV[][] w=new projUV[nu][];
                for(int k=0; k<nu; k++) w[k]=new projUV[nv];

                if(bchgen(a, b, nu, nv, w, func)) return null;

                // analyse coefficients and adjust until residual OK
                double cutres=res;
                int i=4;
                for(; i>0; i--)
                {
                    eval(w, nu, nv, cutres, ref resid);
                    if(resid.u<res&&resid.v<res) break;
                    cutres*=0.5;
                }

                // warn of too many tries
                if(i<=0) resid.u=-resid.u;

                double ab;
                double[] p;

                int[] ncu=new int[nu];
                int[] ncv=new int[nv];

                // apply cut resolution and set pointers
                int nru=0, nrv=0;
                for(int j=0; j<nu; ++j)
                {
                    ncu[j]=ncv[j]=0; // clear column maxes

                    projUV[] s=w[j];
                    for(i=0; i<nv; i++)
                    {
                        // < resolution ?
                        ab=Math.Abs(s[i].u);
                        if(ab<cutres) s[i].u=0.0;	// clear coefficient
                        else ncu[j]=i+1;			// update column max

                        ab=Math.Abs(s[i].v);
                        if(ab<cutres) s[i].v=0.0;	// same for v coef's
                        else ncv[j]=i+1;
                    }
                    if(ncu[j]!=0) nru=j+1;			// update row max
                    if(ncv[j]!=0) nrv=j+1;
                }

                if(power)
                { // convert to bivariate power series
                    if(!bch2bps(a, b, w, nu, nv)) return null;

                    // possible change in some row counts, so readjust
                    nru=nrv=0;
                    for(int j=0; j<nu; ++j)
                    {
                        ncu[j]=ncv[j]=0; // clear column maxes

                        projUV[] s=w[j];

                        for(i=0; i<nv; i++)
                        {
                            if(s[i].u!=0) ncu[j]=i+1;	// update column max
                            if(s[i].v!=0) ncv[j]=i+1;
                        }
                        if(ncu[j]!=0) nru=j+1;			// update row max
                        if(ncv[j]!=0) nrv=j+1;
                    }

                    Tseries T=makeT(nru, nrv);
                    if(T!=null)
                    {
                        T.a=a;
                        T.b=b;
                        T.mu=nru-1;
                        T.mv=nrv-1;
                        T.power=1;

                        for(i=0; i<nru; ++i) // store coefficient rows for u
                        {
                            T.cu[i].m=ncu[i];
                            if(T.cu[i].m!=0)
                            {
                                p=T.cu[i].c=new double[ncu[i]];
                                projUV[] s=w[i];
                                for(int j=0; j<ncu[i]; j++) p[j]=s[j].u;
                            }
                        }

                        for(i=0; i<nrv; ++i) // same for v
                        {
                            T.cv[i].m=ncv[i];
                            if(T.cv[i].m!=0)
                            {
                                p=T.cv[i].c=new double[ncv[i]];
                                projUV[] s=w[i];
                                for(int j=0; j<ncv[i]; j++) p[j]=s[j].v;
                            }
                        }
                    }
                    return T;
                }
                else
                {
                    Tseries T=makeT(nru, nrv);
                    if(T!=null)
                    {
                        // else make returned Chebyshev coefficient structure
                        T.mu=nru-1; // save row degree
                        T.mv=nrv-1;
                        T.a.u=a.u+b.u; // set argument scaling
                        T.a.v=a.v+b.v;
                        T.b.u=1.0/(b.u-a.u);
                        T.b.v=1.0/(b.v-a.v);
                        T.power=0;

                        for(i=0; i<nru; ++i) // store coefficient rows for u
                        {
                            T.cu[i].m=ncu[i];
                            if(T.cu[i].m!=0)
                            {
                                p=T.cu[i].c=new double[ncu[i]];
                                projUV[] s=w[i];
                                for(int j=0; j<ncu[i]; j++) p[j]=s[j].u;
                            }
                        }

                        for(i=0; i<nrv; ++i) // same for v
                        {
                            T.cv[i].m=ncv[i];
                            if(T.cv[i].m!=0)
                            {
                                p=T.cv[i].c=new double[ncv[i]];
                                projUV[] s=w[i];
                                for(int j=0; j<ncv[i]; j++) p[j]=s[j].v;
                            }
                        }
                    }
                    return T;
                }
            }
            catch
            {
                return null;
            }
        }
示例#4
0
        public static void gen_cheb(bool inverse, ProjFunc proj, string s, PJ P, int iargc, string[] iargv)
        {
            InputFunc input=Proj.dmstor;
            if(inverse) input=Libc.strtod;

            int errin=0;
            projUV low, upp;
            low.u=low.v=upp.u=upp.v=0;
            if(s.Length>0) low.u=input(s, out s); else errin++;
            if(s.Length>1&&s[0]==',') upp.u=input(s.Substring(1), out s); else errin++;
            if(s.Length>1&&s[0]==',') low.v=input(s.Substring(1), out s); else errin++;
            if(s.Length>1&&s[0]==',') upp.v=input(s.Substring(1), out s); else errin++;

            if(errin!=0) emess(16, "null or absent -T parameters");

            int NU=15, NV=15, res=-1;

            if(s.Length>1&&s[0]==',')
            {
                s=s.Substring(1);
                if(s[0]!=',') res=Libc.strtol(s, out s, 10);
            }
            if(s.Length>1&&s[0]==',')
            {
                s=s.Substring(1);
                if(s[0]!=',') NU=Libc.strtol(s, out s, 10);
            }
            if(s.Length>1&&s[0]==',')
            {
                s=s.Substring(1);
                if(s[0]!=',') NV=Libc.strtol(s, out s, 10);
            }

            bool pwr=s.Length>0&&s.StartsWith(",P");
            Console.WriteLine("#proj_{0}\n#\trun-line:", pwr?"Power":"Chebyshev");

            // proj execution audit trail
            if(iargc>0)
            {
                int n=0;

                for(int i=0; i<iargc; i++)
                {
                    string arg=iargv[i];
                    if(arg[0]!='+')
                    {
                        if(n==0)
                        {
                            Console.Write("#");
                            n++;
                        }
                        Console.Write(" "+arg);
                        n+=arg.Length+1;
                        if(n>50)
                        {
                            Console.WriteLine(); n=0;
                        }
                    }
                }
                if(n!=0) Console.WriteLine();
            }

            Console.WriteLine("# projection parameters");
            Console.WriteLine("#"+P.DescriptionName);
            Console.WriteLine("#"+P.DescriptionParameters);
            Console.WriteLine("#"+P.DescriptionType);
            Console.WriteLine("#"+P.ToProj4String());

            if(low.u==upp.u||low.v>=upp.v) emess(16, "approx. argument range error");
            if(low.u>upp.u) low.u-=Proj.TWOPI;
            if(NU<2||NV<2) emess(16, "approx. work dimensions ({0} {1}) too small", NU, NV);

            projUV resid=new projUV();
            Tseries F=mk_cheby(low, upp, Math.Pow(10.0, res)*0.5, ref resid, proj, NU, NV, pwr);
            if(F==null) emess(16, "generation of approx failed\nreason: {0}\n", Proj.pj_strerrno(Libc.errno));

            Console.WriteLine("{0},{1:G12},{2:G12},{3:G12},{4:G12},{5:G12}", inverse?'I':'F', P.lam0*Proj.RAD_TO_DEG,
                low.u*(inverse?1.0:Proj.RAD_TO_DEG), upp.u*(inverse?1.0:Proj.RAD_TO_DEG),
                low.v*(inverse?1.0:Proj.RAD_TO_DEG), upp.v*(inverse?1.0:Proj.RAD_TO_DEG));

            string fmt;
            if(pwr) fmt="G15";
            else if(res<=0) fmt=string.Format("F{0}", -res+1);
            else fmt="F0";

            p_series(F, Console.Out, fmt);
            Console.WriteLine("# |u,v| sums {0} {1}\n#end_proj_{2}", resid.u, resid.v, pwr?"Power":"Chebyshev");
        }
示例#5
0
        // generate double bivariate Chebychev polynomial
        public static bool bchgen(projUV a, projUV b, int nu, int nv, projUV[][] f, ProjFunc func)
        {
            projUV arg, bma, bpa;
            projUV[] t, c;

            bma.u=0.5*(b.u-a.u); bma.v=0.5*(b.v-a.v);
            bpa.u=0.5*(b.u+a.u); bpa.v=0.5*(b.v+a.v);
            for(int i=0; i<nu; i++)
            {
                arg.u=Math.Cos(Proj.PI*(i+0.5)/nu)*bma.u+bpa.u;
                for(int j=0; j<nv; j++)
                {
                    arg.v=Math.Cos(Proj.PI*(j+0.5)/nv)*bma.v+bpa.v;
                    f[i][j]=func(arg);
                    if(f[i][j].u==Libc.HUGE_VAL) return true;
                }
            }

            try
            {
                c=new projUV[nu];
            }
            catch
            {
                return true;
            }

            double fac=2.0/nu;
            for(int j=0; j<nv; j++)
            {
                for(int i=0; i<nu; i++)
                {
                    arg.u=arg.v=0.0;
                    for(int k=0; k<nu; k++)
                    {
                        double d=Math.Cos(Proj.PI*i*(k+0.5)/nu);
                        arg.u+=f[k][j].u*d;
                        arg.v+=f[k][j].v*d;
                    }
                    arg.u*=fac;
                    arg.v*=fac;
                    c[i]=arg;
                }
                for(int i=0; i<nu; i++) f[i][j]=c[i];
            }

            try
            {
                c=new projUV[nv];
            }
            catch
            {
                return true;
            }

            fac=2.0/nv;
            for(int i=0; i<nu; i++)
            {
                t=f[i];
                for(int j=0; j<nv; j++)
                {
                    arg.u=arg.v=0.0;
                    for(int k=0; k<nv; k++)
                    {
                        double d=Math.Cos(Proj.PI*j*(k+0.5)/nv);
                        arg.u+=t[k].u*d;
                        arg.v+=t[k].v*d;
                    }
                    arg.u*=fac;
                    arg.v*=fac;
                    c[j]=arg;
                }
                f[i]=c;
                c=t;
            }

            return false;
        }
示例#6
0
        public static void gen_cheb(bool inverse, ProjFunc proj, string s, PJ P, int iargc, string[] iargv)
        {
            InputFunc input = Proj.dmstor;

            if (inverse)
            {
                input = Libc.strtod;
            }

            int    errin = 0;
            projUV low, upp;

            low.u = low.v = upp.u = upp.v = 0;
            if (s.Length > 0)
            {
                low.u = input(s, out s);
            }
            else
            {
                errin++;
            }
            if (s.Length > 1 && s[0] == ',')
            {
                upp.u = input(s.Substring(1), out s);
            }
            else
            {
                errin++;
            }
            if (s.Length > 1 && s[0] == ',')
            {
                low.v = input(s.Substring(1), out s);
            }
            else
            {
                errin++;
            }
            if (s.Length > 1 && s[0] == ',')
            {
                upp.v = input(s.Substring(1), out s);
            }
            else
            {
                errin++;
            }

            if (errin != 0)
            {
                emess(16, "null or absent -T parameters");
            }

            int NU = 15, NV = 15, res = -1;

            if (s.Length > 1 && s[0] == ',')
            {
                s = s.Substring(1);
                if (s[0] != ',')
                {
                    res = Libc.strtol(s, out s, 10);
                }
            }
            if (s.Length > 1 && s[0] == ',')
            {
                s = s.Substring(1);
                if (s[0] != ',')
                {
                    NU = Libc.strtol(s, out s, 10);
                }
            }
            if (s.Length > 1 && s[0] == ',')
            {
                s = s.Substring(1);
                if (s[0] != ',')
                {
                    NV = Libc.strtol(s, out s, 10);
                }
            }

            bool pwr = s.Length > 0 && s.StartsWith(",P");

            Console.WriteLine("#proj_{0}\n#\trun-line:", pwr?"Power":"Chebyshev");

            // proj execution audit trail
            if (iargc > 0)
            {
                int n = 0;

                for (int i = 0; i < iargc; i++)
                {
                    string arg = iargv[i];
                    if (arg[0] != '+')
                    {
                        if (n == 0)
                        {
                            Console.Write("#");
                            n++;
                        }
                        Console.Write(" " + arg);
                        n += arg.Length + 1;
                        if (n > 50)
                        {
                            Console.WriteLine(); n = 0;
                        }
                    }
                }
                if (n != 0)
                {
                    Console.WriteLine();
                }
            }

            Console.WriteLine("# projection parameters");
            Console.WriteLine("#" + P.DescriptionName);
            Console.WriteLine("#" + P.DescriptionParameters);
            Console.WriteLine("#" + P.DescriptionType);
            Console.WriteLine("#" + P.ToProj4String());

            if (low.u == upp.u || low.v >= upp.v)
            {
                emess(16, "approx. argument range error");
            }
            if (low.u > upp.u)
            {
                low.u -= Proj.TWOPI;
            }
            if (NU < 2 || NV < 2)
            {
                emess(16, "approx. work dimensions ({0} {1}) too small", NU, NV);
            }

            projUV  resid = new projUV();
            Tseries F     = mk_cheby(low, upp, Math.Pow(10.0, res) * 0.5, ref resid, proj, NU, NV, pwr);

            if (F == null)
            {
                emess(16, "generation of approx failed\nreason: {0}\n", Proj.pj_strerrno(Libc.errno));
            }

            Console.WriteLine("{0},{1:G12},{2:G12},{3:G12},{4:G12},{5:G12}", inverse?'I':'F', P.lam0 * Proj.RAD_TO_DEG,
                              low.u * (inverse?1.0:Proj.RAD_TO_DEG), upp.u * (inverse?1.0:Proj.RAD_TO_DEG),
                              low.v * (inverse?1.0:Proj.RAD_TO_DEG), upp.v * (inverse?1.0:Proj.RAD_TO_DEG));

            string fmt;

            if (pwr)
            {
                fmt = "G15";
            }
            else if (res <= 0)
            {
                fmt = string.Format("F{0}", -res + 1);
            }
            else
            {
                fmt = "F0";
            }

            p_series(F, Console.Out, fmt);
            Console.WriteLine("# |u,v| sums {0} {1}\n#end_proj_{2}", resid.u, resid.v, pwr?"Power":"Chebyshev");
        }