[Scilab-users] Si function

Federico Miyara fmiyara at fceia.unr.edu.ar
Thu Feb 6 10:41:20 CET 2020


Dear All,

Just in case somebody is interested, find attached a Scilab function to 
compute the sine integral function Si (the integral from 0 to x of the 
sinc function), which cannot be expressed in closed form with elementary 
functions.

/It is preliminary, it doesn't test for appropriate input argument.

It works for real or complex matrices or N-D arrays.

It can be easily modified to get the cosine integral function.

Regards,

Fderico Miyara
/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.scilab.org/pipermail/users/attachments/20200206/bd0a5a4a/attachment.htm>
-------------- next part --------------
function y = Si(x)
    // This function computes the sine integral function, i.e., 
    // the integral from 0 to x of the sinc function sin(x)/x
    // Usage:
    //       y = Si(x)
    // where
    //       x: Any real or complex scalar, vector, matrix  
    //          or N-D aray
    //       y: The result of applying the sine integral to
    //          each component. Its size is equal to size(x)
    //
    // Reference: 
    // Abramowitz, M. and Stegun, I. (eds.) "Handbook of 
    // Mathematical Functions". Dover. New York, 1972. 
    // ---------------------------
    // Author: Federico Miyara
    // Date:   2020-02-06
        
    siz = size(x);
    
    // Indexes to values of the argument with absolute 
    // value not greater than 20
    I = find(abs(x)<=20);
    // Indexes to values of the argument greater than 20
    // and non-negative
    J = find(abs(x)>20 & x<>-abs(x));
    // Indexes to values of the argument smaller than 20
    // and negative 
    K = find(abs(x)>20 & x==-abs(x));
    
    // Apply algorithm based on Taylor series 
    y_small = Si_small(x(I));
    
    // Apply algorithm based on asymptotic approximation
    // This approximation is not valid for negative arguments,
    // but as Si is an odd function this is easy to fix 
    y_large_pos = Si_large(x(J));
    y_large_neg = -Si_large(-x(K));
    
    // Put all together
    y = zeros(x);
    y(I) = y_small;
    y(J) = y_large_pos;
    y(K) = y_large_neg;
       
endfunction

function y = Si_small(x)
    N = 30
    coe = (-1).^(0:N)./(1:2:2*N+1)./factorial(1:2:2*N+1); 
    Sipoly = poly(coe, "u", "c");
    y = x.*horner(Sipoly, x.^2);  
endfunction

function y = Si_large(x)
    M = 15
    // Coefficients of the Laurent series of the auxilary
    // functions for the asymptotic approximation 
    sig = (-1).^(0:M);
    cf = factorial(0:2:2*M).*sig;
    cg = factorial(1:2:2*M+1).*sig; 
    
    // Polynomials with the preceding coefficients
    pf = poly(cf,"u","c");   
    pg = poly(cg,"u","c");  

    // Computation of the auxiliary functions
    f = horner(pf, 1./x.^2)./x
    g = horner(pg, 1./x.^2)./x.^2
    
    // Computation of tha asymptotic approximation
    // fo large arguments
    y = %pi/2 - f.*cos(x) - g.*sin(x)
endfunction



More information about the users mailing list