efficient simplicial numbers in miscfunc

This commit is contained in:
Jiri Pittner 2024-04-02 17:54:43 +02:00
parent 8fa7194f2d
commit 2194a785da
3 changed files with 61 additions and 1 deletions

View File

@ -758,5 +758,56 @@ return(bern[n]);
//there is a closed form s(d,n) = binom(n+d-1,d)
//but that would be inefficient
//we use recurrence s(d,n) = s(d,n-1) + s(d-1,n)
//we cannot also use the above efficient binom() since here we need laerge n while d is small
//
//enlarge storage size if needed
//
#define SIMPLICIAL_MAXD 8
#define SIMPLICIAL_MAXN 1024
unsigned long long simplicial(int d, int n)
{
static unsigned long long stored[SIMPLICIAL_MAXD-2][SIMPLICIAL_MAXN]={{0,1,3}};
static int maxd=2;
static int maxn=2;
if(n<=0) return 0;
if(d==0||n==1) return 1;
if(d==1) return n;
//resize precomputed part as needed
if(n>maxn)
{
if(n>=SIMPLICIAL_MAXN) laerror("storage overflow in simplicial");
int newdim=2*n;
if(newdim<2*maxn) newdim=2*maxn;
if(newdim>=SIMPLICIAL_MAXN) newdim=SIMPLICIAL_MAXN-1;
for(int i=maxn+1; i<=newdim;++i) stored[0][i] = i*(i+1)/2;
for(int dd=1; dd<=maxd-2; ++dd)
{
for(int i=maxn+1; i<=newdim;++i) stored[dd][i] = stored[dd][i-1] + stored[dd-1][i];
}
maxn=newdim;
}
if(d>maxd)
{
if(d>=SIMPLICIAL_MAXD) laerror("storage overflow in simplicial");
for(int dd=maxd+1; dd<=d; ++dd)
{
stored[dd-2][0]=0;
stored[dd-2][1]=1;
for(int i=2; i<=maxn; ++i) stored[dd-2][i] = stored[dd-3][i] + stored[dd-2][i-1];
}
maxd=d;
}
return stored[d-2][n];
}
}//namespace

View File

@ -35,6 +35,7 @@ extern double zeta(double x);
extern double gamma(double x);
extern double gammln(double x);
extern double bernoulli_number(int n);
extern unsigned long long simplicial(int d, int n); //simplicial numbers in a precomputed efficient way

10
t.cc
View File

@ -28,6 +28,7 @@
#include "simple.h"
#include "graph.h"
#include "numbers.h"
#include "miscfunc.h"
using namespace std;
@ -3161,7 +3162,7 @@ cout <<a.rsum()<<endl;
cout <<a.csum()<<endl;
}
if(1)
if(0)
{
int n;
cin>>n;
@ -3175,5 +3176,12 @@ for(int l=1; l<k; ++l)
cout <<count<<" "<<binom(n,4)<<endl;
}
if(1)
{
int d,n;
cin>>d>>n;
cout <<simplicial(d,n)<<" "<<binom(n+d-1,d)<<endl;
}
}