spline.src

来自「没有说明」· SRC 代码 · 共 1,362 行 · 第 1/3 页

SRC
1,362
字号
                if isw == 0;
                    sinhm = (expx - 1 / expx) / (ax + ax) - 1;
                endif;
            else;
                xs = ax * ax;
                coshm = xs * ((((cp4 * xs + cp3) * xs + cp2) * xs + cp1) *
                    xs + cp0);
                if isw == 0;
                    sinhm = xs * (((sp13 * xs + sp12) * xs + sp11) * xs +
                        sp10);
                endif;
            endif;
        endif;
    else;
        if ax > 4.45;
            if ax > 7.65;
                if ax > 10.1;
                    sinhm = exp(ax) / (ax + ax) - 1;
                else;
                    xs = ax * ax;
                    sinhm = xs * (((sp43 * xs + sp42) * xs + sp41) * xs +
                        1) / ((sq42 * xs + sq41) * xs + sq40);
                endif;
            else;
                xs = ax*ax;
                sinhm = xs * (((sp33 * xs + sp32) * xs + sp31) * xs + 1) /
                    ((sq32 * xs + sq31) * xs + sq30);
            endif;
        else;
            xs = ax * ax;
            if ax > 2.3;
                sinhm = xs * ((((sp24 * xs + sp23) * xs + sp22) * xs +
                    sp21) * xs + sp20);
            else;
                sinhm = xs * (((sp13 * xs + sp12) * xs + sp11) * xs + sp10);
            endif;
        endif;
    endif;
    retp(sinhm,coshm);
endp;

proc _spl_intrvl(t,x);
/*
**    translated into GAUSS from Fortran by Ronald Schoenberg
**
**                    coded into Fortran by alan kaylor cline
**                           from fitpack -- january 26, 1987
**                        a curve and surface fitting package
**                      a product of pleasant valley software
**                  8603 altus cove, austin, texas 78759, usa
*/
    local n,il,ih,tt;
    n = rows(x);

    tt = t;
/*
** check for illegal i
*/
    if _spl_i >= n;
        _spl_i = n / 2;
    endif;

/*
** check old interval and extremes
*/
    if tt < x[_spl_i];
        if tt <= x[2];
            _spl_i = 1;
            retp(1);
        else;
            il = 2;
            ih = _spl_i;
        endif;
    elseif tt <= x[_spl_i+1];
        retp(_spl_i);
    elseif tt >= x[n-1];
        _spl_i = n - 1;
        retp(n - 1);
    else;
        il = _spl_i + 1;
        ih = n - 1;
    endif;

/*
** binary search loop
*/

A1:

    _spl_i = (il + ih) / 2;
    if tt < x[_spl_i];
        ih = _spl_i;
    elseif tt > x[_spl_i+1];
        il = _spl_i + 1;
    else;
        retp(_spl_i);
    endif;
    goto A1;
endp;

proc _spl_add(i,j,k,m,n);
    retp(m*n*(k-1)+m*(i-1)+j);
endp;

proc _spl_hermz(f1,f2,fp1,fp2,del1,del2,dels);
/* inline one dimensional cubic spline interpolation */
    retp((f2 * del1 + f1 * del2) / dels - del1 * del2 * (fp2 * (del1 +
        dels) + fp1 * (del2 + dels)) / (6.*dels) );
endp;

proc _spl_hermnz(f1,f2,fp1,fp2,sigmap,del1,del2,dels,sinhm1,sinhm2,sinhms);
/* inline one dimensional spline under tension interpolation */
    retp( (f2 * del1 + f1 * del2) / dels + (fp2 * del1 * (sinhm1 - sinhms)
        + fp1 * del2 * (sinhm2 - sinhms)) / (sigmap * sigmap * dels * (1 +
        sinhms)) );
endp;






proc _spl_curv2 (t,x,y,yp,sigma);

/*
**    translated into GAUSS from Fortran by Ronald Schoenberg
**
**                    coded into Fortran by alan kaylor cline
**                           from fitpack -- january 26, 1987
**                        a curve and surface fitting package
**                      a product of pleasant valley software
**                  8603 altus cove, austin, texas 78759, usa
**
*/

      local im1,i,n,sigmap,del1,del2,dels,sum,dummy,sigdel,ss,s1,s2;

      n = rows(x);
/*
** determine interval
*/
      im1 = _spl_intrvl(t,x);
      i = im1 + 1;

/*
** denormalize tension factor
*/

      sigmap = abs(sigma) * (n - 1) / (x[n] - x[1]);

/*
** set up and perform interpolation
*/
      del1 = t - x[im1];
      del2 = x[i] - t;
      dels = x[i] - x[im1];
      sum = (y[i] * del1 + y[im1] * del2) / dels;
      if (sigmap == 0);
        retp(sum-del1*del2*(yp(i)*
            (del1+dels)+yp(im1)*(del2+dels))/(6*dels));
      endif;
      sigdel = sigmap * dels;
      { ss,dummy } = _spl_snhcsh(sigdel,-1);
      { s1,dummy } = _spl_snhcsh(sigmap*del1,-1);
      { s2,dummy } = _spl_snhcsh(sigmap*del2,-1);

      retp(sum+(yp[i]*del1*(s1-ss)+yp[im1]*del2*(s2-ss))/
                 (sigdel*sigmap*(1+ss)));
endp;




proc _spl_curv1(x,y,d,s,sigma);

/*
**    translated into GAUSS from Fortran by Ronald Schoenberg
**
**                    coded into Fortran by alan kaylor cline
**                           from fitpack -- january 26, 1987
**                        a curve and surface fitting package
**                      a product of pleasant valley software
**                  8603 altus cove, austin, texas 78759, usa
**
*/
      local n,ierr,eps,ys,ysp,td,tsd1,hd,hsd1,hsd2,rd,rsd1,rsd2,v;
      local f,wim1,wim2,h,p,g,step,sum,sl,su,delyi1,delyi,nm1,ibak,
         yspim2,rsd2i,alphap,betapp,hsd1p,hdim1,hdi,delxi,rsd1i,tui,wi,
         delxi1,dim1,di,rdim1,sigmap,nm3,i,alpha,beta,betap,tt;


      n = rows(x);


      if n < 2;
          retp(error(1));
      endif;

      s = abs(s);
      eps = sqrt(2/n);

      v = zeros(n,1);
      ysp = zeros(n,1);
      ierr = 0;
      p = 0;

      if n == 2;
          retp(ysp);
      endif;

      rsd1 = zeros(n,1);
      rd = zeros(n,1);
      rsd2 = zeros(n,1);
      ys = zeros(n,1);
      tsd1 = zeros(n,1);
      hsd1 = zeros(n,1);
      hsd2 = zeros(n,1);
      td = zeros(n,1);
      hd = zeros(n,1);

      rdim1 = 0;
      yspim2 = 0;

/*
** denormalize tension factor
*/

      sigmap = abs(sigma) * (n - 1) / (x[n] - x[1]);

/*
** form t matrix and second differences of y into ys
*/
      nm1 = n - 1;
      nm3 = n - 3;
      delxi1 = 1;
      delyi1 = 0;
      dim1 = 0;

      i = 1;
      do until i > nm1;
        delxi = x[i+1] - x[i];
        if delxi <= 0;
            retp(error(5));
        endif;
        delyi = (y[i+1]-y[i])/delxi;
        ys[i] = delyi-delyi1;
        { di,tt } = _spl_terms(sigmap,delxi);
        tsd1[i+1] = tt;
        td[i] = di + dim1;
        hd[i] = -(1/delxi+1/delxi1);
        hsd1[i+1] = 1/delxi;
        delxi1 = delxi;
        delyi1 = delyi;
        dim1 = di;
        i = i + 1;
     endo;

/*
** calculate lower and upper tolerances
*/

      sl = s * (1 - eps);
      su = s * (1 + eps);

      d = vec(d);
      if rows(d) == 1;
/*
** form h matrix - d constant
*/
          if d[1] <= 0;
              retp(error(5));
          endif;
          sl = d[1]*d[1]*sl;
          su = d[1]*d[1]*su;
          hsd1p = 0;
          hdim1 = 0;
          i = 2;
          do until i > nm1;
            hdi = hd[i];
            hd[i] = hsd1[i]*hsd1[i]+hdi*hdi+hsd1[i+1]*hsd1[i+1];
            hsd2[i] = hsd1[i]*hsd1p;
            hsd1p = hsd1[i];
            hsd1[i] = hsd1p*(hdi+hdim1);
            hdim1 = hdi;
            i = i + 1;
          endo;
     else;

/*
** form h matrix - d array
*/
          if d[1] <= 0 or d[2] <= 0;
              retp(error(5));
          endif;

          betapp = 0;
          betap = 0;
          alphap = 0;

          i = 2;
          do until i > nm1;
            alpha = hd[i]*d[i]*d[i];
            if d[i+1] <= 0;
                retp(error(5));
            endif;
            beta = hsd1[i+1]*d[i+1]*d[i+1];
            hd[i] = (hsd1[i] * d[i-1])^2 + alpha * hd[i] + beta * hsd1[i+1];
            hsd2[i] = hsd1[i]*betapp;
            hsd1[i] = hsd1[i]*(alpha+alphap);
            alphap = alpha;
            betapp = betap;
            betap = beta;
            i = i + 1;
          endo;

      endif;
/*
** top of iteration
** cholesky factorization of p*t+h into r
*/

A0:

      i = 2;
      do until i > nm1;
        rsd2i = hsd2[i];
        rsd1i = p*tsd1[i]+hsd1[i]-rsd2i*rsd1[i-1];
        rsd2[i] = rsd2i*rdim1;
        rdim1 = rd[i-1];
        rsd1[i] = rsd1i*rdim1;
        rd[i] = 1/(p*td[i]+hd[i]-rsd1i*rsd1[i]-rsd2i*rsd2[i]);
        ysp[i] = ys[i]-rsd1[i]*ysp[i-1]-rsd2[i]*yspim2;
        yspim2 = ysp[i-1];
        i = i + 1;
      endo;

/*
** back solve of r(transpose)* r * ysp = ys
*/

      ysp[nm1] = rd[nm1]*ysp[nm1];
      if n /= 3;
          ibak = 1;
          do until ibak > nm3;
              i = nm1 - ibak;
              ysp[i] = rd[i]*ysp[i]-rsd1[i+1]*ysp[i+1]-rsd2[i+2]*ysp[i+2];
              ibak = ibak + 1;
          endo;
      endif;
      sum = 0;
      delyi1 = 0;
      if rows(d) == 1;

/*
** calculation of residual norm
**  - d constant
*/
           i = 1;
           do until i > nm1;
                delyi = (ysp[i+1]-ysp[i])/(x[i+1]-x[i]);
                v[i] = delyi-delyi1;
                sum = sum+v[i]*(delyi-delyi1);
                delyi1 = delyi;
                i = i + 1;
          endo;
          v[n] = -delyi1;

      else;
/*
** calculation of residual norm
**  - d array
*/
          i = 1;
          do until i > nm1;
            delyi = (ysp[i+1]-ysp[i])/(x[i+1]-x[i]);
            v[i] = (delyi-delyi1)*d[i]*d[i];
            sum = sum+v[i]*(delyi-delyi1);
            delyi1 = delyi;
            i = i + 1;
          endo;
          v[n] = -delyi1*d[n]*d[n];
      endif;
      sum = sum-v[n]*delyi1;

/*
** test for convergence
*/

      if sum <= su;
          goto A1;
      endif;

/*
** calculation of newton correction
*/
      f = 0;
      g = 0;
      wim2 = 0;
      wim1 = 0;

      i = 2;
      do until i > nm1;
        tui = tsd1[i]*ysp[i-1]+td[i]*ysp[i]+tsd1[i+1]*ysp[i+1];
        wi = tui-rsd1[i]*wim1-rsd2[i]*wim2;
        f = f + tui * ysp[i];
        g = g + wi * wi * rd[i];
        wim2 = wim1;
        wim1 = wi;
        i = i + 1;
      endo;

      h = f - p * g;
      if h <= 0;
          goto A1;
      endif;

/*
** update p - newton step
*/
      step = (sum - sqrt(sum * sl)) / h;
      if sl /= 0;
           step = step * sqrt(sum / sl);
      endif;
      p = p + step;

      goto A0;

A1:

/*
** store smoothed y-values and second derivatives
*/
      retp(p*ysp);
endp;











proc(3) = spline(x,y,z,sigma,gridf);
    retp(spline2D(x,y,z,sigma,gridf));
endp;


proc(2) = curve(x,y,d,s,sigma,gridf);
    retp(spline1D(x,y,d,s,sigma,gridf));
endp;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?