Menu

Using interpolation outside of drawings

Help
2024-02-08
2024-02-08
  • Alan Bromborsky

    Alan Bromborsky - 2024-02-08

    I have a table I wish to interpolate as part of an intermediate calculation of a function I want to draw. The documentation is not clear on whether this can be done or not. It refers to an example Interpolate1.asy which I can't find. Can anyone help me out on this problem.

     
  • Charles Staats

    Charles Staats - 2024-02-08

    Here's the text of interpolate1.asy:

    // Lagrange and Hermite interpolation in Asymptote
    // Author: Olivier Guibé
    
    import interpolate;
    import graph;
    
    // Test 1: The Runge effect in the Lagrange interpolation of 1/(x^2+1).
    
    unitsize(2cm);
    
    real f(real x) {return(1/(x^2+1));}
    real df(real x) {return(-2*x/(x^2+1)^2);}
    
    real a=-5, b=5;
    int n=15;
    real[] x,y,dy;
    x=a+(b-a)*sequence(n+1)/n;
    y=map(f,x);
    dy=map(df,x);
    for(int i=0; i <= n; ++i)
      dot((x[i],y[i]),5bp+blue);
    horner h=diffdiv(x,y);
    fhorner p=fhorner(h);
    draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$");
    draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
    
    xlimits(-5,5);
    ylimits(-1,1,Crop);
    
    xaxis("$x$",BottomTop,LeftTicks);
    yaxis("$y$",LeftRight,RightTicks);
    
    attach(legend(),point(10S),30S);
    
    shipout("runge1");
    
    erase();
    
    // Test 2: The Runge effect in the Hermite interpolation of 1/(x^2+1).
    
    real f(real x) {return(1/(x^2+1));}
    real df(real x) {return(-2*x/(x^2+1)^2);}
    
    real a=-5, b=5;
    int n=16;
    real[] x,y,dy;
    x=a+(b-a)*sequence(n+1)/n;
    y=map(f,x);
    dy=map(df,x);
    for(int i=0; i <= n; ++i)
      dot((x[i],y[i]),5bp+blue);
    horner h=hdiffdiv(x,y,dy);
    fhorner ph=fhorner(h);
    draw(graph(p,a,b,n=500),"$x\longmapsto{}H_{"+string(n)+"}$");
    draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
    
    unitsize(2cm);
    
    xlimits(-5,5);
    ylimits(-1,5,Crop);
    
    xaxis("$x$",BottomTop,LeftTicks);
    yaxis("$y$",LeftRight,RightTicks);
    
    attach(legend(),point(10S),30S);
    
    shipout("runge2");
    
    erase();
    
    // Test 3: The Runge effect does not occur for all functions:
    // Lagrange interpolation of a function whose successive derivatives
    // are bounded by a constant M (here M=1) is shown here to converge.
    
    real f(real x) {return(sin(x));}
    real df(real x) {return(cos(x));}
    
    real a=-5, b=5;
    int n=16;
    real[] x,y,dy;
    x=a+(b-a)*sequence(n+1)/n;
    y=map(f,x);
    dy=map(df,x);
    for(int i=0; i <= n; ++i)
      dot((x[i],y[i]),5bp+blue);
    horner h=diffdiv(x,y);
    fhorner p=fhorner(h);
    
    draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$");
    draw(graph(f,a,b),red,"$x\longmapsto{}\cos(x)$");
    
    xaxis("$x$",BottomTop,LeftTicks);
    yaxis("$y$",LeftRight,RightTicks);
    
    attach(legend(),point(10S),30S);
    
    shipout("runge3");
    
    erase();
    
    // Test 4: However, one notes here that numerical artifacts may arise
    // from limit precision (typically 1e-16).
    
    real f(real x) {return(sin(x));}
    real df(real x) {return(cos(x));}
    
    real a=-5, b=5;
    int n=72;
    real[] x,y,dy;
    x=a+(b-a)*sequence(n+1)/n;
    y=map(f,x);
    dy=map(df,x);
    for(int i=0; i <= n; ++i)
      dot((x[i],y[i]),5bp+blue);
    horner h=diffdiv(x,y);
    fhorner p=fhorner(h);
    
    draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$");
    draw(graph(f,a,b),red,"$x\longmapsto{}\cos(x)$");
    
    ylimits(-1,5,Crop);
    
    xaxis("$x$",BottomTop,LeftTicks);
    yaxis("$y$",LeftRight,RightTicks);
    
    attach(legend(),point(10S),30S);
    
    shipout("runge4");
    
    erase();
    
    // Test 5: The situation is much better using Tchebychev points.
    
    unitsize(2cm);
    
    real f(real x) {return(1/(x^2+1));}
    real df(real x) {return(-2*x/(x^2+1)^2);}
    
    real a=-5, b=5;
    int n=16;
    real[] x,y,dy;
    fhorner p,ph,ph1;
    for(int i=0; i <= n; ++i)
      x[i]=(a+b)/2+(b-a)/2*cos((2*i+1)/(2*n+2)*pi);
    y=map(f,x);
    dy=map(df,x);
    for(int i=0; i <= n; ++i)
      dot((x[i],y[i]),5bp+blue);
    horner h=diffdiv(x,y);
    fhorner p=fhorner(h);
    
    draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$");
    draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
    
    xlimits(-5,5);
    ylimits(-1,2,Crop);
    
    xaxis("$x$",BottomTop,LeftTicks);
    yaxis("$y$",LeftRight,RightTicks);
    attach(legend(),point(10S),30S);
    
    shipout("runge5");
    
    erase();
    
    // Test 6: Adding a few more Tchebychev points yields a very good result.
    
    unitsize(2cm);
    
    real f(real x) {return(1/(x^2+1));}
    real df(real x) {return(-2*x/(x^2+1)^2);}
    
    real a=-5, b=5;
    int n=26;
    real[] x,y,dy;
    for(int i=0; i <= n; ++i)
      x[i]=(a+b)/2+(b-a)/2*cos((2*i+1)/(2*n+2)*pi);
    y=map(f,x);
    dy=map(df,x);
    for(int i=0; i <= n; ++i)
      dot((x[i],y[i]),5bp+blue);
    horner h=diffdiv(x,y);
    fhorner p=fhorner(h);
    draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$");
    draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
    
    xlimits(-5,5);
    ylimits(-1,2,Crop);
    
    xaxis("$x$",BottomTop,LeftTicks);
    yaxis("$y$",LeftRight,RightTicks);
    attach(legend(),point(10S),30S);
    
    
    shipout("runge6");
    
    erase();
    
    // Test 7: Another Tchebychev example.
    
    unitsize(2cm);
    
    real f(real x) {return(sqrt(abs(x-1)));}
    
    real a=-2, b=2;
    int n=30;
    real[] x,y,dy;
    for(int i=0; i <= n; ++i)
      x[i]=(a+b)/2+(b-a)/2*cos((2*i+1)/(2*n+2)*pi);
    y=map(f,x);
    dy=map(df,x);
    for(int i=0; i <= n; ++i)
      dot((x[i],y[i]),5bp+blue);
    horner h=diffdiv(x,y);
    fhorner p=fhorner(h);
    draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$");
    draw(graph(f,a,b),red,"$x\longmapsto{}\sqrt{|x-1|}$");
    
    xlimits(-2,2);
    ylimits(-0.5,2,Crop);
    
    xaxis("$x$",BottomTop,LeftTicks);
    yaxis("$y$",LeftRight,RightTicks);
    attach(legend(),point(10S),30S);
    
    shipout("runge7");
    
     

Log in to post a comment.