init
This commit is contained in:
267
scratch/c_legendrefn.c
Normal file
267
scratch/c_legendrefn.c
Normal file
@ -0,0 +1,267 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "c_legendrecoefs.c"
|
||||
|
||||
static const float amsleg_pif = 3.14159265359;
|
||||
static const double amsleg_pi = 3.14159265359;
|
||||
|
||||
|
||||
float amsleg_polyvalf(float x, const float *coefs, int polyorder)
|
||||
{
|
||||
float ret = 0.0f;
|
||||
float xv = 1.0f;
|
||||
int I;
|
||||
|
||||
for(I=0;I<=polyorder;I++)
|
||||
{
|
||||
//printf("debug: %d %1.6g\n",I,coefs[I]);
|
||||
ret = ret + coefs[I]*xv;
|
||||
xv = xv * x;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
double amsleg_polyval(double x, const double *coefs, int polyorder)
|
||||
{
|
||||
double ret = 0.0;
|
||||
double xv = 1.0;
|
||||
int I;
|
||||
|
||||
for(I=0;I<=polyorder;I++)
|
||||
{
|
||||
ret = ret + coefs[I]*xv;
|
||||
xv = xv * x;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Schmidt Quasi-Normalized Legendre Function P^n_m(x)
|
||||
//for degree n, and order m, m<=n
|
||||
//n from 0 to 20
|
||||
//m from 0 to n
|
||||
float amsleg_legendref(float x, int n, int m)
|
||||
{
|
||||
float ret = 0.0f;
|
||||
int I, mo2, mr, ind;
|
||||
|
||||
float mpart = 1.0f;
|
||||
float ppart = 0.0f;
|
||||
|
||||
const float *coefptr = NULL;
|
||||
|
||||
if(x<-1.0f) x=-1.0f;
|
||||
if(x>1.0f) x = 1.0f;
|
||||
|
||||
if(m<0)
|
||||
{
|
||||
m = -m;
|
||||
}
|
||||
if(m>n || n<0 || n>20)
|
||||
{
|
||||
ret = 0.0f;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(m>0)
|
||||
{
|
||||
mo2 = m/2;
|
||||
mr = (m%2==1);
|
||||
for(I=0;I<mo2;I++)
|
||||
{
|
||||
mpart = mpart*(1.0f-x*x);
|
||||
}
|
||||
if(mr==1)
|
||||
{
|
||||
mpart = mpart*sqrt(1.0f-x*x);
|
||||
}
|
||||
}
|
||||
|
||||
ind = n*(n+1)/2 + m;
|
||||
//printf("debug: ind=%d\n",ind);
|
||||
coefptr = &(amslegendrecoefsf[ind*(amslegendre_maxporder+1)]);
|
||||
|
||||
// printf("debug ");
|
||||
// for(I=0;I<amslegendre_maxporder+1;I++)
|
||||
// {
|
||||
// printf("%1.6g,",coefptr[I]);
|
||||
// }
|
||||
// printf("\n");
|
||||
|
||||
ppart = amsleg_polyvalf(x,coefptr,amslegendre_maxporder);
|
||||
|
||||
|
||||
ret = ppart*mpart;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Schmidt Quasi-Normalized Legendre Function P^n_m(x)
|
||||
//for degree n, and order m, m<=n
|
||||
//n from 0 to 20
|
||||
//m from 0 to n
|
||||
double amsleg_legendre(double x, int n, int m)
|
||||
{
|
||||
double ret = 0.0;
|
||||
int I, mo2, mr, ind;
|
||||
|
||||
double mpart = 1.0;
|
||||
double ppart = 0.0;
|
||||
|
||||
const double *coefptr = NULL;
|
||||
|
||||
if(x<-1.0f) x=-1.0f;
|
||||
if(x>1.0f) x = 1.0f;
|
||||
|
||||
if(m<0)
|
||||
{
|
||||
m = -m;
|
||||
}
|
||||
if(m>n || n<0 || n>20)
|
||||
{
|
||||
ret = 0.0f;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(m>0)
|
||||
{
|
||||
mo2 = m/2;
|
||||
mr = (m%2==1);
|
||||
for(I=0;I<mo2;I++)
|
||||
{
|
||||
mpart = mpart*(1.0f-x*x);
|
||||
}
|
||||
if(mr==1)
|
||||
{
|
||||
mpart = mpart*sqrt(1.0f-x*x);
|
||||
}
|
||||
}
|
||||
|
||||
ind = n*(n+1)/2 + m;
|
||||
coefptr = &(amslegendrecoefs[ind*(amslegendre_maxporder+1)]);
|
||||
ppart = amsleg_polyval(x,coefptr,amslegendre_maxporder);
|
||||
|
||||
|
||||
ret = ppart*mpart;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
float amsleg_rsphcosf(float theta,float phi,int n,int m)
|
||||
{
|
||||
float ret = 0.0f;
|
||||
float p;
|
||||
|
||||
ret = amsleg_legendref(cosf(theta),n,m)*cosf(m*phi);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
float amsleg_rsphsinf(float theta,float phi,int n,int m)
|
||||
{
|
||||
float ret = 0.0f;
|
||||
float p;
|
||||
|
||||
ret = amsleg_legendref(cosf(theta),n,m)*sinf(m*phi);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
float amsleg_dotprodf(int n1, int m1, int sc1, int n2, int m2, int sc2)
|
||||
{
|
||||
float ret = 0.0f;
|
||||
float p1,p2;
|
||||
int Ntheta = 360;
|
||||
int Nphi = 720;
|
||||
int I,J;
|
||||
float dtheta,dphi,theta,phi;
|
||||
float domega = 0.0f;
|
||||
|
||||
dtheta = amsleg_pif/(Ntheta);
|
||||
dphi = 2.0f*amsleg_pif/(Nphi);
|
||||
for(I=0;I<Ntheta;I++)
|
||||
{
|
||||
for(J=0;J<Nphi;J++)
|
||||
{
|
||||
theta = dtheta*I;
|
||||
phi = dphi*J;
|
||||
domega = dtheta*dphi*sin(theta);
|
||||
|
||||
if(sc1==0)
|
||||
p1 = amsleg_rsphcosf(theta,phi,n1,m1);
|
||||
else
|
||||
p1 = amsleg_rsphsinf(theta,phi,n1,m1);
|
||||
|
||||
if(sc2==0)
|
||||
p2 = amsleg_rsphcosf(theta,phi,n2,m2);
|
||||
else
|
||||
p2 = amsleg_rsphsinf(theta,phi,n2,m2);
|
||||
|
||||
ret = ret + p1*p2*domega;
|
||||
//ret = ret + domega;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void amsleg_test1()
|
||||
{
|
||||
int n = 20;
|
||||
int m = 20;
|
||||
float p;
|
||||
float x;
|
||||
|
||||
printf("Test legendre fn %d %d \n",n,m);
|
||||
for(x=-1.0f; x<=1.005f; x = x + 0.01f)
|
||||
{
|
||||
p = amsleg_legendref(x,n,m);
|
||||
printf("%1.4g\t\t%1.4g\n",x,p);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void amsleg_test2()
|
||||
{
|
||||
int n1 = 3;
|
||||
int m1 = 1;
|
||||
|
||||
int n2;
|
||||
int m2;
|
||||
|
||||
float dp;
|
||||
|
||||
//for Schmidt quasi normalized spherical harmonics:
|
||||
// 1/4pi * integral( C_mn C_MN sin(th)dthdphi ) = 1/(2n+1) del_nN del_mM
|
||||
// there is a factor of 1/(2n+1)
|
||||
|
||||
printf("dot products with (%d,%d).\n",n1,m1);
|
||||
|
||||
for(n2 = 0; n2<5; n2++)
|
||||
{
|
||||
for(m2 = 0; m2<=n2; m2++)
|
||||
{
|
||||
dp = amsleg_dotprodf(n2,m2,1,n2,m2,1);
|
||||
if(dp<1E-4) dp = 0;
|
||||
dp = dp/4.0f/amsleg_pif;
|
||||
dp = dp * (2*n2+1);
|
||||
printf("(%d,%d): %1.6g\n",n2,m2,dp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("Legendre Function Tests\n");
|
||||
|
||||
amsleg_test2();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user