void CellularBasis::InitProbability(double PtsPerCell) { unsigned long X, XFactorial = 1; // assign probablilities for each possible number of feature points per cell for (X = 0; X < WCS_CELLULARBASIS_MAXPTSPERCELL; ++X) { if (X > 1) XFactorial *= X; PtProb[X] = Poisson(X, PtsPerCell, XFactorial); // make the probablilities cumulative if (X > 0) { PtProb[X] += PtProb[X - 1]; if (PtProb[X] > .99) { PtProb[X] = 1.0; break; } // if } // if } // for // just to be sure we cover the whole range of random numbers PtProb[WCS_CELLULARBASIS_MAXPTSPERCELL - 1] = 1.0; } // CellularBasis::InitProbability
/******************************************************************* * 求参数为lambda的泊松分布 * 输入: lambda--双精度实型变量,平均抽样间隔 * nSeed--长整型变量,nSeed为随机数的种子 ********************************************************************/ double Poisson(double lambda, long nSeed) { double u = Uniform(0.0, 1.0, &nSeed); double fRet = log(u) * (-1) *lambda; if(fRet < 1.0) { return Poisson(lambda, ++nSeed); } return fRet; }
long Poisson(RndState *S, double lambda) { long r; if (lambda>=15) { double m=floor(lambda*7/8); double x=Gamma(S,m); if (x>lambda) r=Binomial(S,lambda/x,m-1); else r=m+Poisson(S,lambda-x); } else { double p, elambda = exp(-lambda); for (p=1, r=-1; p>elambda; p*=Uniform(S)) r++; } return r; }
/** * Calculate fragment hit data */ tcDamageModel::FragHits tcDamageModel::CalculateFragmentImpact(float range_m, float altitude_m, const tcDamageModel::FragWeapon& weap, float targetArea_m2) const { FragHits result; result.hits = 0; result.ke_J = 0; result.v_mps = 0; // J/kg, heat of explosion for TNT from http://www.fas.org/man/dod-101/navy/docs/es310/warheads/Warheads.htm const float delta_E = 2.7e6; const float K_shape = 0.5f; // shape factor of warhead const float frag_density_kg_m3 = 8000.0f; // approx steel density const float Cgurney = sqrtf(2.0*delta_E); // http://en.wikipedia.org/wiki/Gurney_equations float rho = Aero::GetAirDensity(altitude_m); float N_frag = weap.metal_kg / weap.fragment_kg; float A_frag_m2 = powf((1.3293f * weap.fragment_kg / frag_density_kg_m3), 0.667f); float CtoM = weap.charge_kg / weap.metal_kg; // charge to metal ratio float v0_mps = Cgurney * sqrtf((CtoM / (1.0f + K_shape*CtoM))); float v_mps = v0_mps * expf(-rho*0.5f*A_frag_m2*range_m/(2.0f * weap.fragment_kg)); // model fragment speed deceleration from aero drag float ke_J = 0.5f*weap.fragment_kg*v_mps*v_mps; float avg_hits = targetArea_m2*(N_frag / (weap.spread_factor*4*C_PI*range_m*range_m)); result.hits = (float)std::min(Poisson(avg_hits), (unsigned int)50); result.ke_J = ke_J; result.v_mps = v_mps; return result; }
int ist_rule (ISTREE *ist, int *rule, double* occhyp, double* occcon, double *supp, double *conf, double *aval, double *phi, double *impli, double* normal_simi,double *entro_simi, int maxlen, int simple_impli, int Binomial_law) { /* --- extract next rule */ int i; /* loop variable */ int item; /* buffer for an item identifier */ ISNODE *isnode; /* current item set node */ ISNODE *parent; /* parent of the item set node */ unsigned s_rule; /* minimal support of a rule */ unsigned s_min; /* minimal support of a set */ float s_set; /* support of set (body & head) */ float s_sub; /* support of subset (body) */ double occ_a; double occ_b; double occ_n; double occsqa,occsqb; double pi; double pi2; double occ_abb; double occ_ab; double tmp_b,tmp_c; double alpha, beta, t, h1, h2, ii, unmb; double p_body, p_head; /* prior confidences/probabilities */ double c, v; /* confidence and measure value */ int app; /* appearance flag of head item */ assert(ist && rule && supp && conf); /* check arguments */ /* --- initialize --- */ if (ist->rulelen > ist->height) /* if the tree is not high enough */ return -1; /* for the rule length, abort */ s_rule = (unsigned)ceil(ist->setcnt *ist->supp); if (s_rule < 1) s_rule = 1; /* compute the minimal rule support */ s_min = (ist->rsdef == IST_BOTH) ? s_rule : (unsigned)ceil(ist->setcnt *ist->supp *ist->conf); if (ist->isnode) /* if this is not the first rule, */ isnode = ist->isnode; /* get the buffered item set node */ else { /* if this is the first rule */ isnode = ist->isnode = ist->levels[ist->rulelen-1]; ist->index = ist->hditem = -1; /* initialize the */ } /* rule extraction variables */ /* --- find rule --- */ while (1) { /* search for a rule */ if (ist->hditem >= 0) { /* --- select next item subset */ ist->path[ist->pathlen++] = ist->hditem; ist->hditem = ID(ist->hdnode); /* add previous head to the path */ ist->hdnode = ist->hdnode->parent;/* and get the next head item */ if (!ist->hdnode) /* if all subsets have been processed */ ist->hditem = -1; /* clear the head item to trigger the */ } /* selection of a new item set */ if (ist->hditem < 0) { /* --- select next item set */ if (++ist->index >= isnode->size) { /* if all subsets have been */ isnode = isnode->succ; /* processed, go to the successor */ if (!isnode) { /* if at the end of a level, go down */ if (++ist->rulelen > ist->height) return -1; /* if beyond the leaf level, abort */ isnode = ist->levels[ist->rulelen-1]; } /* get the 1st node of the new level */ ist->isnode = isnode; /* note the new item set node and */ ist->index = 0; /* start with the first item set */ } /* of the new item set node */ i = isnode->offs +ist->index; if ((ist->apps[i] == IST_IGNORE) || (HDONLY(isnode) && (ist->apps[i] == IST_HEAD))) continue; /* skip sets with two head only items */ ist->hditem = i; /* set the head item identifier */ ist->hdonly = HDONLY(isnode) || (ist->apps[i] == IST_HEAD); ist->hdnode = isnode; /* get the new head only flag, */ ist->pathlen = 0; /* set the new head item node, */ } /* and clear the path */ app = ist->apps[ist->hditem]; /* get head item appearance */ if (!(app & IST_HEAD) || (ist->hdonly && (app != IST_HEAD))) continue; /* if rule is not allowed, skip it */ s_set = isnode->cnts[ist->index]; /* get the item set support */ if (s_set < s_min) { /* if the set support is too low, */ ist->hditem = -1; continue; } /* skip this item set */ if (ist->pathlen <= 0) { /* if there is no path, */ parent = isnode->parent; /* get subset support from parent */ if (parent) { s_sub = parent->cnts[ID(isnode) -parent->offs]; occsqa = parent->occ_square[ID(isnode) -parent->offs]; } else { s_sub = (float)ist->setcnt; } } else { /* if there is a path (not 1st subset)*/ s_sub = _getsupp(ist->hdnode, ist->path, ist->pathlen, &occsqa); } /* get subset support using the path */ if (s_sub < s_rule) /* if the subset support is too low, */ continue; /* get the next subset/next set */ c = (double)s_set/s_sub; /* compute the rule confidence */ occ_a=s_sub; occ_b=ist->levels[0]->cnts[ist->hditem]; occsqb=ist->levels[0]->occ_square[ist->hditem]; occ_n=ist->setcnt; pi=occ_a*(occ_n-occ_b); /*pi=p(a)p(b barre)*/ pi2=occsqa*(occ_n-2*occ_b+occsqb); occ_ab=s_set; /*a et b*/ occ_abb=occ_a-occ_ab; /*a et b barre*/ tmp_b=occ_abb-pi/occ_n; *occhyp=occ_a; *occcon=occ_b; int binary_data=(occ_a==occsqa && occ_b==occsqb); if(Binomial_law) { if(binary_data && pi/occ_n*(1-pi/(double)(occ_n*occ_n))<50.) { *phi=1.-Binomiale(pi/(occ_n*occ_n),(long)occ_n,(long)occ_abb); } else { if(pi2==0) tmp_c=0; else tmp_c=tmp_b/sqrt(pi2/occ_n*(1.-pi2/(occ_n*occ_n))); *phi=1.-Normal(tmp_c); } } else { if(binary_data && (pi/occ_n<=5. ||occ_abb<48.)) { *phi=1.-Poisson(occ_a/occ_n*(occ_n-occ_b),(int)occ_abb); } else { if(pi2==0) tmp_c=0; else tmp_c=tmp_b/sqrt(pi2/occ_n); *phi=1.-Normal(tmp_c); } } alpha=(double)occ_a/occ_n; beta=(double)occ_b/occ_n; t=(double)occ_abb/occ_n; /* if (t <= alpha/2.0) h1 =-xl2xb((alpha-t)/alpha) - xl2xb(t/alpha); else h1 =1; unmb = 1.0 - beta; if (t <= unmb/2.0) h2 = -xl2xb((unmb-t)/unmb) - xl2xb(t/unmb); else h2 = 1; ii = pow((1-h1*h1)*(1-h2*h2),0.25);; *impli=sqrt(*phi*ii); */ // entropic version /* if (t <= alpha/2.0) h1 =0.5*(1+xl2xb(0.5-t/alpha) + xl2xb(0.5+t/alpha)); else if( t<=alpha) h1 =0.5*(1-xl2xb(t/alpha-0.5) - xl2xb(1.5-t/alpha)); else h1=1.; unmb = 1.0 - beta; if (t <= unmb/2.0) h2 = 0.5*(1+xl2xb(0.5-t/unmb) + xl2xb(0.5+t/unmb)); else if(t<=unmb) h2 = 0.5*(1-xl2xb(t/unmb-0.5) - xl2xb(1.5-t/unmb)); else h2=1.; ii = sqrt((1.-h1)*(1.-h2)); *impli=(1.-1./(2.*sqrt(occ_n)))*ii; */ //implifiance double occ_nonanonb=occ_n-(occ_b+occ_abb); double C1=occ_ab/occ_a; double C2=occ_nonanonb/(occ_n-occ_b); *impli=*phi*pow(C1*C2,0.25); //normal similarity double c=(occ_a*occ_b)/occ_n; *normal_simi=Normal((occ_ab-c)/sqrt(c)); if(simple_impli) { if ((ist->rulelen==maxlen && *phi < ist->conf -EPSILON) || (ist->rulelen<maxlen && ist->conf==0)) /* if the confidence is too low, */ continue; /* get the next item subset/item set */ } else { if ((ist->rulelen==maxlen && *impli < ist->conf -EPSILON) || (ist->rulelen<maxlen && ist->conf==0)) /* if the confidence is too low, */ continue; /* get the next item subset/item set */ } if (ist->arem == EM_NONE) { /* if no add. eval. measure given, */ v = 0; break; } /* abort the loop (select the rule) */ if (ist->rulelen < 2) { /* if rule has an empty antecedent, */ v = 0; break; } /* abort the loop (select the rule) */ p_body = (double)s_sub /ist->setcnt; p_head = (double)ist->levels[0]->cnts[ist->hditem] / ist->setcnt; /* compute prior probabilities */ v = _eval(ist->arem, p_head, p_body, c); if (v >= ist->minval) /* if rule value exceeds the minimal */ break; /* of the add. rule eval. measure, */ } /* while (1) */ /* abort the loop (select rule) */ /* --- build rule --- */ i = ist->rulelen; /* get rule length */ item = ist->index +isnode->offs; /* if the current item is */ if (item != ist->hditem) /* not the head of the rule, */ rule[--i] = item; /* add it to the body */ while (isnode->parent) { /* traverse path to root and */ if (ID(isnode) != ist->hditem) /* add all items on this path */ rule[--i] = ID(isnode); /* (except the head of the rule) */ isnode = isnode->parent; /* to the rule body */ } rule[0] = ist->hditem; /* set the rule head */ *supp = ((ist->rsdef == IST_BODY) ? s_sub : s_set) / (double)ist->setcnt; /* set the rule support */ *conf = c; /* and the rule confidence */ if (aval) *aval = v; /* set the value of the add. measure */ return ist->rulelen; /* return the rule length */ } /* ist_rule() */
// takes three arguments: numbins, array[short], pos // PERFORMS NO CHECKING OF PARAMETERS! PyObject * smds_core_run(PyObject *self, PyObject *args) { smds_core *s = (smds_core*)self; PyArrayObject *o; Int16 *iData; double *data; int dur, pos, i; smds_molec *m; int size, minX, maxX; double a; #ifdef CORE_INTENS double *intens = (double*)(s->intens->data); double sc_x; int numBins_x = s->numBins_x; #ifdef CORE_3D double sc_z; int numBins_z = s->numBins_z; #endif #else int r; int threshold; double b; #ifdef CORE_3D int threshold_z; double c; #endif #endif double flow_x; int dir_flow_x = s->dir_flow_x; double t_insert_avg = s->t_insert_avg; unsigned long int t_insert = s->t_insert; int t, dir, rndCounter = 0; unsigned int rnd = 0; double *binCount; double I; if (!PyArg_ParseTuple(args, "iO!i", &dur, &PyArray_Type, &o, &pos)) return NULL; s->dur += dur; data = (double*)malloc(sizeof(double)*dur); if (!data) { PyErr_SetString(PyExc_MemoryError, "Unable to allocate working space."); return NULL; } Py_BEGIN_ALLOW_THREADS if (s->bkg > 0.0) for (i=0; i < dur; i++) data[i] = s->bkg; else for (i=0; i < dur; i++) data[i] = 0.0; binCount = data; for (i=dur; i; i--) { for (t=s->steps; t; t--, t_insert--) { /* Create new molecules */ while (!t_insert) { if (s->avail) { m = s->avail; s->avail = s->avail->next; } else { m = (smds_molec*)malloc(sizeof(smds_molec)); } m->prev = NULL; smds_core_create_molec(m, s, 1); if (s->molecs) s->molecs->prev = m; m->next = s->molecs; s->molecs = m; t_insert = (int)(log(DRandom(&s->rs))*t_insert_avg); } m = s->molecs; while (m) { size = s->size[m->species]; minX = s->minX[m->species]; maxX = s->maxX[m->species]; a = s->a[m->species]; #ifdef CORE_INTENS sc_x = s->sc_x[m->species]; #ifdef CORE_3D sc_z = s->sc_z[m->species]; #endif #else threshold = s->threshold[m->species]; b = s->b[m->species]; #ifdef CORE_3D threshold_z = s->threshold_z[m->species]; c = s->c[m->species]; #endif #endif flow_x = s->flow_x[m->species]; /* Flow */ if ( ((dir_flow_x > 0) && ((m->x += flow_x) >= maxX)) || ((dir_flow_x < 0) && ((m->x -= flow_x) < minX)) ) { smds_molec *p = m; m = m->next; if (p->prev) p->prev->next = p->next; else s->molecs = p->next; // head of list if (p->next) p->next->prev = p->prev; // p->prev = NULL; s->avail is singly-linked. p->next = s->avail; s->avail = p; continue; } /* Reposition */ #ifdef CORE_3D do { if (!rndCounter) { rnd = Random(&s->rs); rndCounter = 10; } dir = rnd & 0x7; rndCounter--; rnd >>= 3; } while (dir == 6 || dir == 7); #else if (!rndCounter) { rnd = Random(&s->rs); rndCounter = 16; } dir = rnd & 0x3; rndCounter--; rnd >>= 2; #endif switch (dir) { case 0: m->x++; if (m->x >= maxX) { m->x = minX; } break; case 1: m->x--; if (m->x < minX) { m->x = maxX-1; } break; case 2: m->y++; if (m->y >= size) { m->y = -size; } break; case 3: m->y--; if (m->y < -size) { m->y = size-1; } break; #ifdef CORE_3D case 4: m->z++; if (m->z >= size) { m->z = -size; } break; case 5: m->z--; if (m->z < -size) { m->z = size-1; } break; #endif } /* Calculate Intensity */ #ifdef CORE_INTENS #ifdef CORE_3D if (abs((int)(m->x*sc_x)) <= numBins_x && abs((int)(m->y*sc_x)) <= numBins_x && abs((int)(m->z*sc_z)) <= numBins_z) { I = a * intens[ (2*numBins_x+1)*(2*numBins_x+1)*(int)(numBins_z + m->z * sc_z) + (2*numBins_x+1) * (int)(numBins_x + m->y * sc_x) + (int)(numBins_x + m->x * sc_x) ]; #else if (abs((int)(x*sc_x)) <= numBins_x && abs((int)(y*sc_x)) <= numBins_x) { I = a * intens[ (2*numBins_x+1) * (int)(numBins_x + m->y * sc_x) + (int)(numBins_x + m->x * sc_x) ]; #endif #else // not INTENS #ifdef CORE_3D if ( (r = m->x*m->x + m->y*m->y) < threshold && abs(m->z) < threshold_z) { I = a * exp(b*(double)r + c*(double)(m->z*m->z)); #else if ( (r = m->x*m->x + m->y*m->y) < threshold) { I = a * exp(b * (double)r); #endif #endif #ifdef CORE_BLEACH if ((m->photonTolerance -= I) < 0) { smds_molec *p = m; I += m->photonTolerance; s->numBleached[m->species]++; *binCount += I; m = m->next; if (p->prev) p->prev->next = p->next; else s->molecs = p->next; // head of list if (p->next) p->next->prev = p->prev; p->prev = NULL; p->next = s->avail; s->avail = p; continue; } #endif *binCount += I; } // in threshold m = m->next; } // each molecule } // each step binCount++; } // each bin s->t_insert = t_insert; iData = (Int16*)o->data + pos; for (i=0; i < dur; i++) s->I += (double)(iData[i] = Poisson(data[i], &s->rs)); Py_END_ALLOW_THREADS free(data); Py_RETURN_NONE; } PyObject * smds_core_getResults(PyObject *self) { smds_core *c = (smds_core*)self; PyObject *r, *o, *l = NULL; int i; if (!ResultsType) { PyErr_SetString(PyExc_SystemError, "Couldn't find ResultsType."); return NULL; } r = PyInstance_New(ResultsType, NULL, NULL); if (!r) return NULL; o = PyFloat_FromDouble(c->I/(double)c->dur/c->bw); if (!o) goto bail; if (PyObject_SetAttrString(r, "avg_I", o) == -1) goto bail; Py_DECREF(o); o = PyFloat_FromDouble((double)c->dur*c->bw*1e-3); if (!o) goto bail; if (PyObject_SetAttrString(r, "length", o) == -1) goto bail; Py_DECREF(o); l = PyList_New(c->numSpecies); if (!l) goto bail; for(i=0; i < c->numSpecies; i++) { o = PyInt_FromLong(c->counts[i]); if (!o) goto bail; if (PyList_SetItem(l, i, o)) goto bail; // steals reference } o = NULL; if (PyObject_SetAttrString(r, "counts", l) == -1) goto bail; Py_DECREF(l); #ifdef CORE_BLEACH l = PyList_New(c->numSpecies); if (!l) goto bail; for(i=0; i < c->numSpecies; i++) { o = PyInt_FromLong(c->numBleached[i]); if (!o) goto bail; if (PyList_SetItem(l, i, o)) goto bail; // steals reference } o = NULL; if (PyObject_SetAttrString(r, "bleached", l) == -1) goto bail; Py_DECREF(l); #endif return r; bail: Py_DECREF(r); if (o) { Py_DECREF(o); } if (l) { Py_DECREF(l); } return NULL; } void smds_core_free(smds_core *p) { smds_molec *m; if (!p) return; free(p->X); free(p->a); #ifdef CORE_BLEACH free(p->tol); #endif free(p->size); free(p->minX); free(p->maxX); #ifdef CORE_INTENS if (p->intens) { Py_DECREF((PyObject*)p->intens); } free(p->sc_x); #ifdef CORE_3D free(p->sc_z); #endif #else free(p->threshold); free(p->b); #ifdef CORE_3D free(p->c); free(p->threshold_z); #endif #endif free(p->counts); #ifdef CORE_BLEACH free(p->numBleached); #endif free(p->flow_x); while (p->molecs) { m = p->molecs; p->molecs = p->molecs->next; free(m); } while (p->avail) { m = p->avail; p->avail = p->avail->next; free(m); } p->ob_type->tp_free((PyObject*)p); } PyObject * smds_core_getParamsType(PyObject *cls) { if (ParamsType) { Py_INCREF(ParamsType); } return ParamsType; } PyObject * smds_core_getResultsType(PyObject *cls) { if (ResultsType) { Py_INCREF(ResultsType); } return ResultsType; } PyObject * smds_core_getName(PyObject *cls) { return PyString_FromString(str(CORE_NAME)); } PyObject * smds_core_sRnd(PyObject *self, PyObject *args) { if (PyTuple_Size(args) != 1) { initRnd(); } else { int seed; if (!PyArg_ParseTuple(args, "k", &seed)) return NULL; seedRnd(seed, NULL); } Py_RETURN_NONE; }