Changeset 20021


Ignore:
Timestamp:
01/29/16 17:15:13 (9 years ago)
Author:
Eric.Larour
Message:

CHG: replace legendre.cpp by a better routine.

Location:
issm/trunk-jpl/src/c/shared/Numerics
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/shared/Numerics/legendre.cpp

    r19979 r20021  
    137137#include "./types.h"
    138138#include "../Exceptions/exceptions.h"
     139#include "../MemOps/MemOps.h"
    139140#include "./recast.h"
    140141
    141 IssmDouble legendre(IssmDouble Pn1, IssmDouble Pn2, IssmDouble x, int n){
    142 
    143         if (n<0)_error_("legendre error message: order required should be >0");
    144 
    145         if(n==0)return 1;
    146         if(n==1)return x;
    147 
    148         return ( (2*n-1)*x*Pn1 - (n-1)*Pn2 ) /n;
     142double *p_polynomial_value ( int m, int n, IssmDouble* x){
     143
     144        /******************************************************************************{{{/
     145        Purpose:
     146
     147        P_POLYNOMIAL_VALUE evaluates the Legendre polynomials P(n,x).
     148
     149        Discussion:
     150
     151        P(n,1) = 1.
     152        P(n,-1) = (-1)^N.
     153        | P(n,x) | <= 1 in [-1,1].
     154
     155        The N zeroes of P(n,x) are the abscissas used for Gauss-Legendre
     156        quadrature of the integral of a function F(X) with weight function 1
     157        over the interval [-1,1].
     158
     159        The Legendre polynomials are orthogonal under the inner product defined
     160        as integration from -1 to 1:
     161
     162        Integral ( -1 <= X <= 1 ) P(I,X) * P(J,X) dX
     163        = 0 if I =/= J
     164        = 2 / ( 2*I+1 ) if I = J.
     165
     166        Except for P(0,X), the integral of P(I,X) from -1 to 1 is 0.
     167
     168        A function F(X) defined on [-1,1] may be approximated by the series
     169        C0*P(0,x) + C1*P(1,x) + ... + CN*P(n,x)
     170        where
     171        C(I) = (2*I+1)/(2) * Integral ( -1 <= X <= 1 ) F(X) P(I,x) dx.
     172
     173        The formula is:
     174
     175        P(n,x) = (1/2^N) * sum ( 0 <= M <= N/2 ) C(N,M) C(2N-2M,N) X^(N-2*M)
     176
     177        Differential equation:
     178
     179        (1-X*X) * P(n,x)'' - 2 * X * P(n,x)' + N * (N+1) = 0
     180
     181        First terms:
     182
     183        P( 0,x) =      1
     184        P( 1,x) =      1 X
     185        P( 2,x) = (    3 X^2 -       1)/2
     186        P( 3,x) = (    5 X^3 -     3 X)/2
     187        P( 4,x) = (   35 X^4 -    30 X^2 +     3)/8
     188        P( 5,x) = (   63 X^5 -    70 X^3 +    15 X)/8
     189        P( 6,x) = (  231 X^6 -   315 X^4 +   105 X^2 -     5)/16
     190        P( 7,x) = (  429 X^7 -   693 X^5 +   315 X^3 -    35 X)/16
     191        P( 8,x) = ( 6435 X^8 - 12012 X^6 +  6930 X^4 -  1260 X^2 +   35)/128
     192        P( 9,x) = (12155 X^9 - 25740 X^7 + 18018 X^5 -  4620 X^3 +  315 X)/128
     193        P(10,x) = (46189 X^10-109395 X^8 + 90090 X^6 - 30030 X^4 + 3465 X^2-63)/256
     194
     195        Recursion:
     196
     197        P(0,x) = 1
     198        P(1,x) = x
     199        P(n,x) = ( (2*n-1)*x*P(n-1,x)-(n-1)*P(n-2,x) ) / n
     200
     201        P'(0,x) = 0
     202        P'(1,x) = 1
     203        P'(N,x) = ( (2*N-1)*(P(N-1,x)+X*P'(N-1,x)-(N-1)*P'(N-2,x) ) / N
     204
     205        Licensing:
     206
     207        This code is distributed under the GNU LGPL license.
     208
     209        Modified:
     210
     211        08 August 2013
     212
     213        Author:
     214
     215                John Burkardt
     216
     217                        Reference:
     218
     219                        Milton Abramowitz, Irene Stegun,
     220                                   Handbook of Mathematical Functions,
     221                                   National Bureau of Standards, 1964,
     222                                   ISBN: 0-486-61272-4,
     223                                   LC: QA47.A34.
     224
     225                                           Daniel Zwillinger, editor,
     226                                   CRC Standard Mathematical Tables and Formulae,
     227                                   30th Edition,
     228                                   CRC Press, 1996.
     229
     230                                           Parameters:
     231
     232                                           Input, int M, the number of evaluation points.
     233
     234                                           Input, int N, the highest order polynomial to evaluate.
     235                                           Note that polynomials 0 through N will be evaluated.
     236
     237                                           Input, double X[M], the evaluation points.
     238
     239                                           Output, double P_POLYNOMIAL_VALUE[M*(N+1)], the values of the Legendre
     240                                           polynomials of order 0 through N.
     241        }}}*/
    149242       
     243        int i;
     244        int j;
     245        IssmDouble* v=NULL;
     246
     247        if ( n < 0 ) return NULL;
     248
     249        v = xNew<IssmDouble>(m*(n+1));
     250
     251        for ( i = 0; i < m; i++ ) v[i+0*m] = 1.0;
     252        if ( n < 1 ) return v;
     253
     254        for ( i = 0; i < m; i++ ) v[i+1*m] = x[i];
     255
     256        for ( j = 2; j <= n; j++ ) {
     257                for ( i = 0; i < m; i++ ) {
     258                        v[i+j*m] = ( ( IssmDouble ) ( 2 * j - 1 ) * x[i] * v[i+(j-1)*m]
     259                                        - ( IssmDouble ) (     j - 1 ) *        v[i+(j-2)*m] )
     260                                / ( IssmDouble ) (     j     );
     261                }
     262        }
     263
     264        return v;
    150265}
  • issm/trunk-jpl/src/c/shared/Numerics/numerics.h

    r19979 r20021  
    3434void        XZvectorsToCoordinateSystem(IssmDouble *T,IssmDouble*xzvectors);
    3535int         cubic(IssmDouble a, IssmDouble b, IssmDouble c, IssmDouble d,IssmDouble X[3], int *num);
    36 IssmDouble  legendre(IssmDouble Pn1, IssmDouble Pn2, IssmDouble x, int i);
     36IssmDouble  legendre(IssmDouble Pn1, IssmDouble Pn2, IssmDouble x, int n);
     37IssmDouble*  p_polynomial_value ( int m, int n, IssmDouble* x);
    3738
    3839int         NewtonSolveDnorm(IssmDouble* pdnorm,IssmDouble c1,IssmDouble c2,IssmDouble c3,IssmDouble n,IssmDouble dnorm);
Note: See TracChangeset for help on using the changeset viewer.