/*************************************************************************************** Deconvolve the B-spline basis functions from the image volume vol - a handle for the volume to deconvolve c - the coefficients (arising from the deconvolution) d - the spline degree splinc0, splinc1, splinc2 - functions for 1D deconvolutions */ static int vol_coeffs(MAPTYPE *vol, double c[], int d[], void (*splinc[])()) { double p[4], *cp; int np; int i, j, k, n; double f[10240]; /* Check that dimensions don't exceed size of f */ if (vol->dim[1]>10240 ||vol->dim[2]>10240) return(1); /* Do a straight copy */ cp = c; for(k=0; k<vol->dim[2]; k++) { double dk = k+1; for(j=0; j<vol->dim[1]; j++) { double dj = j+1; for(i=0;i<vol->dim[0];i++, cp++) { double di = i+1; resample(1,vol,cp,&di,&dj,&dk,0, 0.0); /* Not sure how best to handle NaNs */ if (!finite(*cp)) *cp = 0.0; } } } /* Deconvolve along the fastest dimension (X) */ if (d[0]>1 && vol->dim[0]>1) { if (get_poles(d[0], &np, p)) return(1); for(k=0; k<vol->dim[2]; k++) { double dk = k+1; for(j=0; j<vol->dim[1]; j++) { cp = &c[vol->dim[0]*(j+vol->dim[1]*k)]; splinc[0](cp, vol->dim[0], p, np); } } } /* Deconvolve along the middle dimension (Y) */ if (d[1]>1 && vol->dim[1]>1) { if (get_poles(d[1], &np, p)) return(1); n =vol->dim[0]; for(k=0; k<vol->dim[2]; k++) { for(i=0;i<vol->dim[0];i++) { cp = &c[i+vol->dim[0]*vol->dim[1]*k]; for(j=0; j<vol->dim[1]; j++, cp+=n) f[j] = *cp; splinc[1](f, vol->dim[1], p, np); cp = &c[i+vol->dim[0]*vol->dim[1]*k]; for(j=0; j<vol->dim[1]; j++, cp+=n) *cp = f[j]; } } } /* Deconvolve along the slowest dimension (Z) */ if (d[2]>1 && vol->dim[2]>1) { if (get_poles(d[2], &np, p)) return(1); n = vol->dim[0]*vol->dim[1]; for(j=0; j<vol->dim[1]; j++) { for(i=0;i<vol->dim[0];i++) { cp = &c[i+vol->dim[0]*j]; for(k=0; k<vol->dim[2]; k++, cp+=n) f[k] = *cp; splinc[2](f, vol->dim[2], p, np); cp = &c[i+vol->dim[0]*j]; for(k=0; k<vol->dim[2]; k++, cp+=n) *cp = f[k]; } } } return(0); }
void processArray(bool aAverageMode = false) { uint32_t nNotNans = 0; if (mScramble) { boost::uniform_int<uint32_t> ui(0, nGenes - 1); for (uint32_t k = 0; k < nGenes; k++) { double t = mBuf[k]; uint32_t h = ui(mRand); mBuf[k] = mBuf[h]; mBuf[h] = t; } } for (uint32_t i = 0; i < nGenes; i++) { mInvRanks[i] = i; nNotNans += !!finite(mBuf[i]); } double rankInflationFactor = (nGenes + 0.0) / nNotNans; // Sort indices by value, with NaNs at the top. std::sort(mInvRanks, mInvRanks + nGenes, (bll::var(mBuf)[bll::_1] < bll::var(mBuf)[bll::_2]) || (bll::bind(finite, bll::var(mBuf)[bll::_1]) && !bll::bind(finite, bll::var(mBuf)[bll::_2]))); uint32_t i; if (aAverageMode) { for (i = 0; i < nGenes && finite(mBuf[mInvRanks[i]]); i++) { mRankAvgs[i] += mBuf[mInvRanks[i]]; mRankCounts[i]++; } } else { if (mQuantileNormalisation) { for (i = 0; i < nGenes && finite(mBuf[mInvRanks[i]]); i++) // We could put code in here to deal with tied ranks by putting in median // ranks, but I doubt it would make enough difference to justify it. mRanks[mInvRanks[i]] = mRankAvgs[i]; } else { for (i = 0; i < nGenes && finite(mBuf[mInvRanks[i]]); i++) // We could put code in here to deal with tied ranks by putting in median // ranks, but I doubt it would make enough difference to justify it. mRanks[mInvRanks[i]] = i * rankInflationFactor; } for (; i < nGenes; i++) mRanks[mInvRanks[i]] = std::numeric_limits<double>::quiet_NaN(); fwrite(mRanks, sizeof(double), nGenes, mOutputFile); } }
/* Split plnode along plane. We know that plane really intersects * plnode->poly. We also know that plnode->poly is planar and convex. * * Given this assumptions we know that plnode->poly has to be split * into exactly two pieces. */ static inline void SplitPolyNode(PolyListNode *plnode, PolyListNode **front, PolyListNode **back, EdgeIntersection edges[2], struct obstack *scratch) { const void **tagged_app = plnode->tagged_app; Poly *poly = plnode->poly, savedp; VARARRAY(savedv, Vertex *, poly->n_vertices); Vertex *v0, *v1, **vpos; int istart[2], iend[2], i, nv[2]; Vertex *vstart[2], *vend[2]; #if BSPTREE_STATS ++n_tree_polys; #endif vstart[0] = vstart[1] = vend[0] = vend[1] = NULL; istart[0] = istart[1] = iend[0] = iend[1] = -1; /* first point of intersection */ if (fzero(edges[0].scp[0])) { v0 = poly->v[edges[0].v[0]]; if (fpos(edges[0].scp[1])) { istart[0] = edges[0].v[0]; iend[1] = edges[0].v[0]; } else { istart[1] = edges[0].v[0]; iend[0] = edges[0].v[0]; } } else if (fzero(edges[0].scp[1])) { v0 = poly->v[edges[0].v[1]]; if (fpos(edges[0].scp[0])) { istart[1] = edges[0].v[1]; iend[0] = edges[0].v[1]; } else { istart[0] = edges[0].v[1]; iend[1] = edges[0].v[1]; } } else { HPt3Coord mu0, mu1; Vertex *V0 = poly->v[edges[0].v[0]]; Vertex *V1 = poly->v[edges[0].v[1]]; v0 = obstack_alloc(scratch, sizeof(Vertex)); mu0 = edges[0].scp[1]/(edges[0].scp[1]-edges[0].scp[0]); #if 0 mu1 = edges[0].scp[0]/(edges[0].scp[0]-edges[0].scp[1]); #else mu1 = 1.0 - mu0; #endif /* Use denormalized variant; otherwise textures may come out wrong * because the homogeneous divisor is used for perspective * corrections. */ if (poly->flags & VERT_ST) { v0->st.s = mu0 * V0->st.s + mu1 * V1->st.s; v0->st.t = mu0 * V0->st.t + mu1 * V1->st.t; HPt3LinSumDenorm(mu0, &V0->pt, mu1, &V1->pt, &v0->pt); } else { HPt3LinSum(mu0, &V0->pt, mu1, &V1->pt, &v0->pt); } if (!finite(v0->pt.x + v0->pt.y + v0->pt.z)){ abort(); } if (poly->flags & VERT_C) { CoLinSum(mu0, &V0->vcol, mu1, &V1->vcol, &v0->vcol); } if (true || (poly->flags & VERT_N)) { /* The averaged vertex normals do not have an orientation, so * try to orient them w.r.t. the polygon normal before computing * the linear combination. */ if (Pt3Dot(&V0->vn, &poly->pn)*Pt3Dot(&V1->vn, &poly->pn) < 0) { Pt3Comb(-mu0, &V0->vn, mu1, &V1->vn, &v0->vn); } else { Pt3Comb(mu0, &V0->vn, mu1, &V1->vn, &v0->vn); } Pt3Unit(&v0->vn); } if (fpos(edges[0].scp[0])) { vstart[1] = vend[0] = v0; istart[1] = edges[0].v[1]; iend[0] = edges[0].v[0]; } else { vstart[0] = vend[1] = v0; istart[0] = edges[0].v[1]; iend[1] = edges[0].v[0]; } } /* second point of intersection */ if (fzero(edges[1].scp[0])) { v1 = poly->v[edges[1].v[0]]; if (fpos(edges[1].scp[1])) { istart[0] = edges[1].v[0]; iend[1] = edges[1].v[0]; } else { istart[1] = edges[1].v[0]; iend[0] = edges[1].v[0]; } } else if (fzero(edges[1].scp[1])) { v1 = poly->v[edges[1].v[1]]; if (fpos(edges[1].scp[0])) { istart[1] = edges[1].v[1]; iend[0] = edges[1].v[1]; } else { istart[0] = edges[1].v[1]; iend[1] = edges[1].v[1]; } } else { HPt3Coord mu0, mu1; Vertex *V0 = poly->v[edges[1].v[0]]; Vertex *V1 = poly->v[edges[1].v[1]]; v1 = obstack_alloc(scratch, sizeof(Vertex)); mu0 = edges[1].scp[1]/(edges[1].scp[1]-edges[1].scp[0]); #if 0 mu1 = edges[1].scp[0]/(edges[1].scp[0]-edges[1].scp[1]); #else mu1 = 1.0 - mu0; #endif if (poly->flags & VERT_ST) { v1->st.s = mu0 * V0->st.s + mu1 * V1->st.s; v1->st.t = mu0 * V0->st.t + mu1 * V1->st.t; HPt3LinSumDenorm(mu0, &V0->pt, mu1, &V1->pt, &v1->pt); } else { HPt3LinSum(mu0, &V0->pt, mu1, &V1->pt, &v1->pt); } if (!finite(v1->pt.x + v1->pt.y + v1->pt.z)) abort(); if (poly->flags & VERT_C) { CoLinSum(mu0, &V0->vcol, mu1, &V1->vcol, &v1->vcol); } if (true || (poly->flags & VERT_N)) { if (Pt3Dot(&V0->vn, &poly->pn)*Pt3Dot(&V1->vn, &poly->pn) < 0) { Pt3Comb(-mu0, &V0->vn, mu1, &V1->vn, &v1->vn); } else { Pt3Comb(mu0, &V0->vn, mu1, &V1->vn, &v1->vn); } Pt3Unit(&v1->vn); } if (fpos(edges[1].scp[0])) { vstart[1] = vend[0] = v1; istart[1] = edges[1].v[1]; iend[0] = edges[1].v[0]; } else { vstart[0] = vend[1] = v1; istart[0] = edges[1].v[1]; iend[1] = edges[1].v[0]; } } ListPush(*front, plnode); ListPush(*back, new_poly_list_node(tagged_app, scratch)); if ((poly->flags & POLY_NONFLAT)) { if (!(*front)->pn) { /* Compute the normal on the parent element to avoid numerical * instabilities on increasingly degenerated polygons. */ (*front)->pn = obstack_alloc(scratch, sizeof(Point3)); PolyNormal(poly, (*front)->pn, true /* 4d */, false /* evert */, NULL, NULL); } (*back)->pn = (*front)->pn; } for (i = 0; i < 2; i++) { nv[i] = iend[i] - istart[i] + 1; if (nv[i] < 0) { nv[i] += poly->n_vertices; } nv[i] += (vstart[i] != NULL) + (vend[i] != NULL); } if (poly->flags & POLY_SCRATCH) { savedp = *poly; memcpy(savedv, poly->v, poly->n_vertices*sizeof(Vertex *)); if (nv[0] <= poly->n_vertices) { poly->n_vertices = nv[0]; (*front)->poly = poly; (*back)->poly = new_poly(nv[1], NULL, scratch); } else { if (nv[1] > poly->n_vertices) { abort(); } poly->n_vertices = nv[1]; (*back)->poly = poly; (*front)->poly = new_poly(nv[0], NULL, scratch); } /* Attention: gcc had problems with this code snippet with * -fstrict-aliasing, the "#if 1" stuff seems to work. In the * "#else" version gcc somehow lost the "savedp.v = savedv" * assignment. I think this is a compiler bug. */ poly = &savedp; #if 1 poly->v = savedv; #else savedp.v = savedv; #endif } else { (*front)->poly = new_poly(nv[0], NULL, scratch); (*back)->poly = new_poly(nv[1], NULL, scratch); } for (i = 0; i < 2; i++) { PolyListNode *half = (i == 0) ? *front : *back; int j; vpos = half->poly->v; if (vstart[i] != NULL) { *vpos++ = vstart[i]; } if (istart[i] <= iend[i]) { for (j = istart[i]; j <= iend[i] && j < poly->n_vertices; j++) { *vpos++ = poly->v[j]; } } else { for (j = istart[i]; j < poly->n_vertices; j++) { *vpos++ = poly->v[j]; } for (j = 0; j <= iend[i]; j++) { *vpos++ = poly->v[j]; } } if (vend[i] != NULL) { *vpos++ = vend[i]; } half->poly->pcol = poly->pcol; half->poly->pn = poly->pn; half->poly->flags = poly->flags|POLY_SCRATCH; check_poly(half->poly); } }
void Linearizer::process_quad(int iv0, int iv1, int iv2, int iv3, int level, scalar* val, double* phx, double* phy, int* idx) { double midval[3][5]; // try not to split through the vertex with the largest value int a = (verts[iv0][2] > verts[iv1][2]) ? iv0 : iv1; int b = (verts[iv2][2] > verts[iv3][2]) ? iv2 : iv3; a = (verts[a][2] > verts[b][2]) ? a : b; int flip = (a == iv1 || a == iv3) ? 1 : 0; if (level < LIN_MAX_LEVEL) { int i; if (!(level & 1)) // this is an optimization: do the following only every other time { // obtain solution values sln->set_quad_order(1, item); val = sln->get_values(ia, ib); if (auto_max) for (i = 0; i < lin_np_quad[1]; i++) { double v = getval(i); if (finite(v) && fabs(v) > max) max = fabs(v); } // obtain physical element coordinates if (curved || disp) { RefMap* refmap = sln->get_refmap(); phx = refmap->get_phys_x(1); phy = refmap->get_phys_y(1); if (disp) { xdisp->force_transform(sln); ydisp->force_transform(sln); xdisp->set_quad_order(1, FN_VAL); ydisp->set_quad_order(1, FN_VAL); scalar* dx = xdisp->get_fn_values(); scalar* dy = ydisp->get_fn_values(); for (i = 0; i < lin_np_quad[1]; i++) { phx[i] += dmult*realpart(dx[i]); phy[i] += dmult*realpart(dy[i]); } } } idx = quad_indices[0]; } // obtain linearized values and coordinates at the midpoints for (i = 0; i < 3; i++) { midval[i][0] = (verts[iv0][i] + verts[iv1][i]) * 0.5; midval[i][1] = (verts[iv1][i] + verts[iv2][i]) * 0.5; midval[i][2] = (verts[iv2][i] + verts[iv3][i]) * 0.5; midval[i][3] = (verts[iv3][i] + verts[iv0][i]) * 0.5; midval[i][4] = (midval[i][0] + midval[i][2]) * 0.5; }; // the value of the middle point is not the average of the four vertex values, since quad == 2 triangles midval[2][4] = flip ? (verts[iv0][2] + verts[iv2][2]) * 0.5 : (verts[iv1][2] + verts[iv3][2]) * 0.5; // determine whether or not to split the element int split; if (eps >= 1.0) { // if eps > 1, the user wants a fixed number of refinements (no adaptivity) split = (level < eps) ? 3 : 0; } else { if (!auto_max && fabs(verts[iv0][2]) > max && fabs(verts[iv1][2]) > max && fabs(verts[iv2][2]) > max && fabs(verts[iv3][2]) > max) { // do not split if the whole quad is above the specified maximum value split = 0; } else { // calculate the approximate error of linearizing the normalized solution double herr = fabs(getval(idx[1]) - midval[2][1]) + fabs(getval(idx[3]) - midval[2][3]); double verr = fabs(getval(idx[0]) - midval[2][0]) + fabs(getval(idx[2]) - midval[2][2]); double err = fabs(getval(idx[4]) - midval[2][4]) + herr + verr; split = (!finite(err) || err > max*4*eps) ? 3 : 0; // decide whether to split horizontally or vertically only if (level > 0 && split) if (herr > 5*verr) split = 1; // h-split else if (verr > 5*herr) split = 2; // v-split } // also decide whether to split because of the curvature if (split != 3 && (curved || disp)) { double cm2 = sqr(cmax*5e-4); if (sqr(phx[idx[1]] - midval[0][1]) + sqr(phy[idx[1]] - midval[1][1]) > cm2 || sqr(phx[idx[3]] - midval[0][3]) + sqr(phy[idx[3]] - midval[1][3]) > cm2) split |= 1; if (sqr(phx[idx[0]] - midval[0][0]) + sqr(phy[idx[0]] - midval[1][0]) > cm2 || sqr(phx[idx[2]] - midval[0][2]) + sqr(phy[idx[2]] - midval[1][2]) > cm2) split |= 2; /*for (i = 0; i < 5; i++) if (sqr(phx[idx[i]] - midval[0][i]) + sqr(phy[idx[i]] - midval[1][i]) > sqr(cmax*1e-3)) { split = 1; break; }*/ } // do extra tests at level 0, so as not to miss some functions with zero error at edge midpoints if (level == 0 && !split) { split = ((fabs(getval(13) - 0.5*(midval[2][0] + midval[2][1])) + fabs(getval(17) - 0.5*(midval[2][1] + midval[2][2])) + fabs(getval(20) - 0.5*(midval[2][2] + midval[2][3])) + fabs(getval(9) - 0.5*(midval[2][3] + midval[2][0]))) > max*4*eps) ? 3 : 0; } } // split the quad if the error is too large, otherwise produce two linear triangles if (split) { if (curved || disp) for (i = 0; i < 5; i++) { midval[0][i] = phx[idx[i]]; midval[1][i] = phy[idx[i]]; } // obtain mid-edge and mid-element vertices int mid0, mid1, mid2, mid3, mid4; if (split != 1) mid0 = get_vertex(iv0, iv1, midval[0][0], midval[1][0], getval(idx[0])); if (split != 2) mid1 = get_vertex(iv1, iv2, midval[0][1], midval[1][1], getval(idx[1])); if (split != 1) mid2 = get_vertex(iv2, iv3, midval[0][2], midval[1][2], getval(idx[2])); if (split != 2) mid3 = get_vertex(iv3, iv0, midval[0][3], midval[1][3], getval(idx[3])); if (split == 3) mid4 = get_vertex(mid0, mid2, midval[0][4], midval[1][4], getval(idx[4])); // recur to sub-elements if (split == 3) { sln->push_transform(0); process_quad(iv0, mid0, mid4, mid3, level+1, val, phx, phy, quad_indices[1]); sln->pop_transform(); sln->push_transform(1); process_quad(mid0, iv1, mid1, mid4, level+1, val, phx, phy, quad_indices[2]); sln->pop_transform(); sln->push_transform(2); process_quad(mid4, mid1, iv2, mid2, level+1, val, phx, phy, quad_indices[3]); sln->pop_transform(); sln->push_transform(3); process_quad(mid3, mid4, mid2, iv3, level+1, val, phx, phy, quad_indices[4]); sln->pop_transform(); } else if (split == 1) // h-split { sln->push_transform(4); process_quad(iv0, iv1, mid1, mid3, level+1, val, phx, phy, quad_indices[5]); sln->pop_transform(); sln->push_transform(5); process_quad(mid3, mid1, iv2, iv3, level+1, val, phx, phy, quad_indices[6]); sln->pop_transform(); } else // v-split { sln->push_transform(6); process_quad(iv0, mid0, mid2, iv3, level+1, val, phx, phy, quad_indices[7]); sln->pop_transform(); sln->push_transform(7); process_quad(mid0, iv1, iv2, mid2, level+1, val, phx, phy, quad_indices[8]); sln->pop_transform(); } return; } } // output two linear triangles, if (!flip) { add_triangle(iv3, iv0, iv1); add_triangle(iv1, iv2, iv3); } else { add_triangle(iv0, iv1, iv2); add_triangle(iv2, iv3, iv0); } }
TEST(math, finite) { ASSERT_TRUE(finite(123.0)); ASSERT_FALSE(finite(HUGE_VAL)); }
/*++ Function: pow See MSDN. --*/ PALIMPORT double __cdecl PAL_pow(double x, double y) { double ret; PERF_ENTRY(pow); ENTRY("pow (x=%f, y=%f)\n", x, y); #if !HAVE_COMPATIBLE_POW if (y == 1.0 / 0.0 && !isnan(x)) // +Inf { if (x == 1.0 || x == -1.0) { ret = 0.0 / 0.0; // NaN } else if (x > -1.0 && x < 1.0) { ret = 0.0; } else { ret = 1.0 / 0.0; // +Inf } } else if (y == -1.0 / 0.0 && !isnan(x)) // -Inf { if (x == 1.0 || x == -1.0) { ret = 0.0 / 0.0; // NaN } else if (x > -1.0 && x < 1.0) { ret = 1.0 / 0.0; // +Inf } else { ret = 0.0; } } else if (x == 0.0 && y < 0.0) { ret = 1.0 / 0.0; // +Inf } else #endif // !HAVE_COMPATIBLE_POW if (y == 0.0 && isnan(x)) { // Windows returns NaN for pow(NaN, 0), but POSIX specifies // a return value of 1 for that case. We need to return // the same result as Windows. ret = 0.0 / 0.0; // NaN } else { ret = pow(x, y); } #if !HAVE_VALID_NEGATIVE_INF_POW if (ret == 1.0 / 0.0 && x < 0 && finite(x) && ceil(y/2) != floor(y/2)) { ret = -1.0 / 0.0; // -Inf } #endif // !HAVE_VALID_NEGATIVE_INF_POW #if !HAVE_VALID_POSITIVE_INF_POW /* * The even/odd test in the if (this one and the one above) used to be ((long long) y % 2 == 0) * on SPARC (long long) y for large y (>2**63) is always 0x7fffffff7fffffff, which * is an odd number, so the test ((long long) y % 2 == 0) will always fail for * large y. Since large double numbers are always even (e.g., the representation of * 1E20+1 is the same as that of 1E20, the last “+1” is too insignificant to be part * of the representation), this test will always return the wrong result for large y. * * The (ceil(y/2) == floor(y/2)) test is slower, but more robust. */ if (ret == -1.0 / 0.0 && x < 0 && finite(x) && ceil(y/2) == floor(y/2)) { ret = 1.0 / 0.0; // +Inf } #endif // !HAVE_VALID_POSITIVE_INF_POW LOGEXIT("pow returns double %f\n", ret); PERF_EXIT(pow); return ret; }
int main(int argc, char** argv) { double power; double A0, lA0; double Zau, Za, Zaa; double ZaInf, ZaaInf; double Ta, Taa; double lKa; double A; double openEnthalpy, openEntropy; char c, gotData; int count; char *name, *buffer, *prefix; FILE *aFile, *aaFile, *outFile; int ignore[2]; int zInfinity; time_t now; gotData = 0; name = prefix = NULL; ignore[0] = ignore[1] = 0; openEnthalpy = HUGE_VAL; openEntropy = -HUGE_VAL; power = 1.0; zInfinity = 0; /* initializations below are unnecessary but prevent compiler warnings */ lA0 = A0 = 0.0; aFile = aaFile = NULL; while ((count = getopt_long(argc, argv, "VhA:x:H:S:b:Yo:", OPTIONS, NULL)) != -1) if (count == 'V') version("concentration-same"); else if (count == 'h' || count == '?') { puts("Usage: concentration-same [options] prefix"); puts(""); puts("Options:"); puts("-V, --version"); puts("-h, --help"); puts("-A, --A0=<total A>"); puts("-x, --exclude=(A|AA)"); puts("-H, --enthalpy=<enthalpy for unfolded strands> (defaults to +infinity)"); puts("-S, --entropy=<entropy for unfolded strands> (defaults to -infinity)"); puts("-b, --power=<exponent for unfolded strands> (defaults to 1)"); puts("-o, --output=<prefix>"); puts("-Y, --infinity"); puts(""); puts("Report bugs to " PACKAGE_BUGREPORT); return EXIT_SUCCESS; } else if (count == 'A') { A0 = atof(optarg); lA0 = log(A0); gotData |= 1; } else if (count == 'x') { if (!strcmp(optarg, "A")) ignore[0] = 1; else if (!strcmp(optarg, "AA")) ignore[1] = 1; } else if (count == 'H') openEnthalpy = atof(optarg); else if (count == 'S') openEntropy = atof(optarg) / 1000; else if (count == 'b') power = atof(optarg); else if (count == 'Y') ++zInfinity; else if (count == 'o') prefix = optarg; if (gotData != 1 || optind >= argc) { fputs("Error: data not specified\nRun 'concentration-same -h' for help\n", stderr); return EXIT_FAILURE; } if (ignore[0] && ignore[1]) { fputs("Error: can't ignore everything\n", stderr); return EXIT_FAILURE; } name = argv[optind]; if (!strcmp(name + strlen(name) - 4, ".seq")) name[strlen(name) - 4] = 0; if (!ignore[0]) aFile = dgOpen(name); buffer = xmalloc(strlen(name) * 2 + 2); sprintf(buffer, "%s-%s", name, name); if (!ignore[1]) aaFile = dgOpen(buffer); if (!prefix) { prefix = xmalloc(2 * strlen(name) + 2); sprintf(prefix, "%s-%s", name, name); } buffer = xrealloc(buffer, strlen(prefix) + 10); strcpy(buffer, prefix); strcat(buffer, ".conc.run"); if (!(outFile = fopen(buffer, "wt"))) { perror(buffer); return EXIT_FAILURE; } now = time(NULL); fprintf(outFile, "concentration-same %s ran on %s at %s\n", PACKAGE_VERSION, name, ctime(&now)); fprintf(outFile, "A0 = %g\n", A0); if (ignore[0]) fputs("A ignored\n", outFile); if (ignore[1]) fputs("AA ignored\n", outFile); if (finite(openEnthalpy)) fprintf(outFile, "Enthalpy for unfolded strands: %g\n", openEnthalpy); if (finite(openEntropy)) fprintf(outFile, "Entropy for unfolded strands: %g\n", openEntropy * 1000); if (power != 1.0) fprintf(outFile, "Exponent for unfolded strands: %g\n", power); fclose(outFile); buffer[strlen(buffer) - 4] = 0; if (!(outFile = fopen(buffer, "wt"))) { perror(buffer); return EXIT_FAILURE; } free(buffer); if (zInfinity) { FILE* inf; buffer = xmalloc(strlen(name) * 2 + 6); sprintf(buffer, "%s.inf", name); if (!(inf = fopen(buffer, "rt"))) { perror(buffer); return EXIT_FAILURE; } readOrDie(1, "inf", inf, "%lf", &ZaInf); fclose(inf); sprintf(buffer, "%s-%s.inf", name, name); if (!(inf = fopen(buffer, "rt"))) { perror(buffer); return EXIT_FAILURE; } readOrDie(1, "inf", inf, "%lf", &ZaaInf); fclose(inf); } fputs("T\t[Af] (M)\t[A] (M)\t[AA] (M)\n", outFile); while (1) { Za = Zaa = 0; if ((!ignore[0] && fscanf(aFile, "%lg%*g%lg", &Ta, &Za) < 2) || (!ignore[1] && fscanf(aaFile, "%lg%*g%lg", &Taa, &Zaa) < 2)) break; if (ignore[0]) Ta = Taa; else if (ignore[1]) Taa = Ta; /* skip to end(s) of line(s) */ if (!ignore[0]) for (c = 0; c != '\n'; readOrDie(1, "dG", aFile, "%c", &c)); if (!ignore[1]) for (c = 0; c != '\n'; readOrDie(1, "dG", aaFile, "%c", &c)); printf("Calculating concentrations for %g\n", Ta); /* add 1 since hybrid-ss assumes at least one base pair */ /* Za += 1; */ /* Zau = exp(-openEnthalpy / R / (Ta + 273.15) + openEntropy / R) + 1; */ if (finite(openEnthalpy) && finite(openEntropy)) { double Zs; Zau = pow(1.0 + exp(-openEnthalpy / R / (Ta + 273.15) + openEntropy / R), power); Zs = exp(power * (-openEnthalpy / R / (Ta + 273.15) + openEntropy / R)); Za *= Zs; Zaa *= Zs * Zs; } else Zau = 1.0; Za += Zau; if (zInfinity) { Za = (Za - ZaInf) / (ZaInf + 1.0); Zaa = (Zaa - ZaaInf) / (ZaaInf + 1.0); } if (Ta != Taa) fprintf(stderr, "Warning: temperature mismatch: %g %g\n", Ta, Taa); lKa = log(Zaa) - 2.0 * log(Za); if (Zaa == 0) { A = A0; fprintf(outFile, "%g\t%g\t%g\t%g\n", Ta, A0 - A0 * Zau / Za, A0, 0.0); } else { /* A = (-1 + sqrt(1 + 8 * Ka * A0)) / 4 / Ka; */ /* A = 2.0 * A0 / (1.0 + sqrt(1.0 + 8.0 * Ka * A0)); */ A = 2.0 * exp(lA0 - ln1pex(ln1pex(log(8.0) + lKa + lA0) / 2.0)); fprintf(outFile, "%g\t%g\t%g\t%g\n", Ta, A - A * Zau / Za, A, (A0 - A) / 2.0); } } if (!ignore[0]) fclose(aFile); if (!ignore[1]) fclose(aaFile); fclose(outFile); return EXIT_SUCCESS; }
bool HHVM_FUNCTION(is_finite, double val) { return finite(val);}
MINLINE bool is_finite_v4(const float v[4]) { return (finite(v[0]) && finite(v[1]) && finite(v[2]) && finite(v[3])); }
/*--------------------------------------------------------------------------*/ int get_rect_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], double ** rect) { int m, n, first_opt = FirstOpt(_pvCtx), kopt, i; if (pos < first_opt) { int* piAddr = 0; int iType = 0; double* pdblData = NULL; getVarAddressFromPosition(_pvCtx, pos, &piAddr); getVarType(_pvCtx, piAddr, &iType); if (iType) { getMatrixOfDouble(_pvCtx, piAddr, &m, &n, &pdblData); if (m * n != 4) { Scierror(999, "%s: Wrong size for input argument #%d: %d expected\n", fname, pos, 4); return 0; } *rect = pdblData; for (i = 0; i < 4; i++) { if (finite((*rect)[i]) == 0) { Scierror(999, "%s: Wrong values (Nan or Inf) for input argument: %d finite values expected\n", fname, 4); return 0; } } } else { /** global value can be modified **/ double zeros[4] = { 0.0, 0.0, 0.0, 0.0 }; setDefRect(zeros); *rect = getDefRect(); } } else if ((kopt = FindOpt(_pvCtx, "rect", opts)) >= 0) /* named argument: rect=value */ { double* pdblData = NULL; getMatrixOfDouble(_pvCtx, opts[kopt].piAddr, &m, &n, &pdblData); if (m * n != 4) { Scierror(999, "%s: Wrong size for input argument #%d: %d expected\n", fname, kopt, 4); return 0; } *rect = pdblData; for (i = 0; i < 4; i++) { if (finite((*rect)[i]) == 0) { Scierror(999, "%s: Wrong values (Nan or Inf) for input argument: %d finite values expected\n", fname, 4); return 0; } } } else { /** global value can be modified **/ double zeros[4] = { 0.0, 0.0, 0.0, 0.0 }; setDefRect(zeros); *rect = getDefRect(); } return 1; }
/* Revamped version of LALDemod() (based on TestLALDemod() in CFS). * Compute JKS's Fa and Fb, which are ingredients for calculating the F-statistic. */ static int LocalXLALComputeFaFb ( Fcomponents *FaFb, const SFTVector *sfts, const PulsarSpins fkdot, const SSBtimes *tSSB, const AMCoeffs *amcoe, const ComputeFParams *params) /* addition computational params */ { UINT4 alpha; /* loop index over SFTs */ UINT4 spdnOrder; /* maximal spindown-orders */ UINT4 numSFTs; /* number of SFTs (M in the Notes) */ COMPLEX16 Fa, Fb; REAL8 Tsft; /* length of SFTs in seconds */ INT4 freqIndex0; /* index of first frequency-bin in SFTs */ INT4 freqIndex1; /* index of last frequency-bin in SFTs */ REAL4 *a_al, *b_al; /* pointer to alpha-arrays over a and b */ REAL8 *DeltaT_al, *Tdot_al; /* pointer to alpha-arrays of SSB-timings */ SFTtype *SFT_al; /* SFT alpha */ REAL8 norm = OOTWOPI; XLAL_CHECK ( params->Dterms == DTERMS, XLAL_EDOM ); #ifndef LAL_NDEBUG /* ----- check validity of input */ if ( !FaFb ) { XLALPrintError ("\nOutput-pointer is NULL !\n\n"); XLAL_ERROR ( XLAL_EINVAL); } if ( !sfts || !sfts->data ) { XLALPrintError ("\nInput SFTs are NULL!\n\n"); XLAL_ERROR ( XLAL_EINVAL); } if ( !tSSB || !tSSB->DeltaT || !tSSB->Tdot || !amcoe || !amcoe->a || !amcoe->b || !params) { XLALPrintError ("\nIllegal NULL in input !\n\n"); XLAL_ERROR ( XLAL_EINVAL); } #endif /* ----- prepare convenience variables */ numSFTs = sfts->length; Tsft = 1.0 / sfts->data[0].deltaF; { REAL8 dFreq = sfts->data[0].deltaF; freqIndex0 = lround ( sfts->data[0].f0 / dFreq ); /* lowest freqency-index */ freqIndex1 = freqIndex0 + sfts->data[0].data->length; } static int firstcall = 1; /* for sin/cos lookup table initialization */ if (firstcall) { /* init sin/cos lookup tables */ local_sin_cos_2PI_LUT_init(); /* make sure Dterms is what we expect */ XLAL_CHECK (DTERMS == params->Dterms, XLAL_EINVAL, "LocalXLALComputeFaFb() has been compiled with fixed DTERMS (%d) != params->Dtems (%d)\n", DTERMS, params->Dterms ); firstcall = 0; } /* find highest non-zero spindown-entry */ for ( spdnOrder = PULSAR_MAX_SPINS - 1; spdnOrder > 0 ; spdnOrder -- ) if ( fkdot[spdnOrder] != 0.0 ) break; Fa = 0.0f; Fb = 0.0f; a_al = amcoe->a->data; /* point to beginning of alpha-arrays */ b_al = amcoe->b->data; DeltaT_al = tSSB->DeltaT->data; Tdot_al = tSSB->Tdot->data; SFT_al = sfts->data; /* Loop over all SFTs */ for ( alpha = 0; alpha < numSFTs; alpha++ ) { REAL4 a_alpha, b_alpha; INT4 kstar; /* central frequency-bin k* = round(xhat_alpha) */ INT4 k0, k1; COMPLEX8 *Xalpha = SFT_al->data->data; /* pointer to current SFT-data */ REAL4 s_alpha, c_alpha; /* sin(2pi kappa_alpha) and (cos(2pi kappa_alpha)-1) */ REAL4 realQ, imagQ; /* Re and Im of Q = e^{-i 2 pi lambda_alpha} */ REAL4 realXP, imagXP; /* re/im of sum_k X_ak * P_ak */ REAL4 realQXP, imagQXP; /* Re/Im of Q_alpha R_alpha */ REAL8 lambda_alpha, kappa_star; /* ----- calculate lambda_alpha */ { UINT4 s; /* loop-index over spindown-order */ REAL8 phi_alpha, Dphi_alpha, DT_al; REAL8 Tas; /* temporary variable to calculate (DeltaT_alpha)^s */ REAL8 TAS_invfact_s; /* init for s=0 */ phi_alpha = 0.0; Dphi_alpha = 0.0; DT_al = (*DeltaT_al); Tas = 1.0; /* DeltaT_alpha ^ 0 */ TAS_invfact_s=1.0; /* TAS / s! */ for (s=0; s <= spdnOrder; s++) { REAL8 fsdot = fkdot[s]; Dphi_alpha += fsdot * TAS_invfact_s; /* here: DT^s/s! */ #ifdef EAH_CHECK_FINITE_DPHI if (!finite(Dphi_alpha)) { LogPrintf(LOG_CRITICAL, "non-finite Dphi_alpha:%e, alpha:%d, spind#:%d, fkdot:%e, Tas:%e, LAL_FACT_INV[s]:%e, LAL_FACT_INV[s+1]:%e, phi_alpha:%e. DT_al:%e\n", Dphi_alpha, alpha, s, fkdot[s], Tas, LAL_FACT_INV[s], LAL_FACT_INV[s+1], phi_alpha, DT_al); XLAL_ERROR("LocalXLALComputeFaFb", XLAL_EDOM); } #endif Tas *= DT_al; /* now: DT^(s+1) */ TAS_invfact_s= Tas * LAL_FACT_INV[s+1]; phi_alpha += fsdot * TAS_invfact_s; } /* for s <= spdnOrder */ /* Step 3: apply global factors to complete Dphi_alpha */ Dphi_alpha *= Tsft * (*Tdot_al); /* guaranteed > 0 ! */ #ifndef EAH_NO_CHECK_FINITE_DPHI if (!finite(Dphi_alpha)) { LogPrintf(LOG_CRITICAL, "non-finite Dphi_alpha:%e, alpha:%d, Tsft:%e, Tkdot_al:%e Tas:%e, DT_al:%e\n", Dphi_alpha, alpha, Tsft, (*Tdot_al), Tas, DT_al); XLAL_ERROR( XLAL_EDOM ); } #endif lambda_alpha = 0.5 * Dphi_alpha - phi_alpha; /* FIXME: that might be possible to do faster */ kstar = (INT4) (Dphi_alpha); /* k* = floor(Dphi_alpha*chi) for positive Dphi */ kappa_star = Dphi_alpha - 1.0 * kstar; /* remainder of Dphi_alpha: >= 0 ! */ /* ----- check that required frequency-bins are found in the SFTs ----- */ k0 = kstar - DTERMS + 1; /* original: k1 = k0 + 2 * DTERMS - 1; inserted k0: k1 = kstar - DTERMS + 1 + 2 * DTERMS - 1; shortened: */ k1 = kstar + DTERMS; if ( (k0 < freqIndex0) || (k1 > freqIndex1) ) { LogPrintf(LOG_CRITICAL, "Required frequency-bins [%d, %d] not covered by SFT-interval [%d, %d]\n" "\t\t[Parameters: alpha:%d, Dphi_alpha:%e, Tsft:%e, *Tdot_al:%e]\n", k0, k1, freqIndex0, freqIndex1, alpha, Dphi_alpha, Tsft, *Tdot_al); XLAL_ERROR(XLAL_EDOM); } } /* compute kappa_star, lambda_alpha */ /* ---------- calculate the (truncated to DTERMS) sum over k ---------- */ /* ---------- ATTENTION: this the "hot-loop", which will be * executed many millions of times, so anything in here * has a HUGE impact on the whole performance of the code. * * DON'T touch *anything* in here unless you really know * what you're doing !! *------------------------------------------------------------ */ { COMPLEX8 *Xalpha_l = Xalpha + k0 - freqIndex0; /* first frequency-bin in sum */ /* if no danger of denominator -> 0 */ #ifdef __GNUC__ /* somehow the branch prediction of gcc-4.1.2 terribly failes with the current case distinction in the hot-loop, having a severe impact on runtime of the E@H Linux App. So let's allow to give gcc a hint which path has a higher probablility */ if (__builtin_expect((kappa_star > LD_SMALL4) && (kappa_star < 1.0 - LD_SMALL4), (0==0))) #else if ((kappa_star > LD_SMALL4) && (kappa_star < 1.0 - LD_SMALL4)) #endif { /* WARNING: all current optimized loops rely on current implementation of COMPLEX8 and DTERMS == 8 */ #include OPT_DEMOD_SOURCE } /* if |remainder| > LD_SMALL4 */ else { /* otherwise: lim_{rem->0}P_alpha,k = 2pi delta_{k,kstar} */ UINT4 ind0; /* realQ/imagQ are calculated in the hotloop in the other case; in this case we have to do it too */ SINCOS_TRIM_X (lambda_alpha,lambda_alpha); SINCOS_2PI_TRIMMED( &imagQ, &realQ, lambda_alpha ); if ( kappa_star <= LD_SMALL4 ) { ind0 = DTERMS - 1; } else { ind0 = DTERMS; } realXP = TWOPI_FLOAT * crealf(Xalpha_l[ind0]); imagXP = TWOPI_FLOAT * cimagf(Xalpha_l[ind0]); } /* if |remainder| <= LD_SMALL4 */ } /* real- and imaginary part of e^{-i 2 pi lambda_alpha } */ realQXP = realQ * realXP - imagQ * imagXP; imagQXP = realQ * imagXP + imagQ * realXP; /* we're done: ==> combine these into Fa and Fb */ a_alpha = (*a_al); b_alpha = (*b_al); Fa += crect( a_alpha * realQXP, a_alpha * imagQXP ); Fb += crect( b_alpha * realQXP, b_alpha * imagQXP ); /* advance pointers over alpha */ a_al ++; b_al ++; DeltaT_al ++; Tdot_al ++; SFT_al ++; } /* for alpha < numSFTs */ /* return result */ FaFb->Fa = norm * Fa; FaFb->Fb = norm * Fb; return XLAL_SUCCESS; } // LocalXLALComputeFaFb()
double erfc(double x) { double R, S, P, Q, s, ax, y, z, r; if (!finite(x)) { if (isnan(x)) /* erfc(NaN) = NaN */ return(x); else if (x > 0) /* erfc(+-inf)=0,2 */ return 0.0; else return 2.0; } if ((ax = x) < 0) ax = -ax; if (ax < .84375) { /* |x|<0.84375 */ if (ax < 1.38777878078144568e-17) /* |x|<2**-56 */ return one-x; y = x*x; r = y*(p1+y*(p2+y*(p3+y*(p4+y*(p5+ y*(p6+y*(p7+y*(p8+y*(p9+y*p10))))))))); if (ax < .0625) { /* |x|<2**-4 */ return (one-(x+x*(p0+r))); } else { r = x*(p0+r); r += (x-half); return (half - r); } } if (ax < 1.25) { /* 0.84375 <= |x| < 1.25 */ s = ax-one; P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); if (x>=0) { z = one-c; return z - P/Q; } else { z = c+P/Q; return one+z; } } if (ax >= 28) /* Out of range */ if (x>0) return (tiny*tiny); else return (two-tiny); z = ax; TRUNC(z); y = z - ax; y *= (ax+z); z *= -z; /* Here z + y = -x^2 */ s = one/(-z-y); /* 1/(x*x) */ if (ax >= 4) { /* 6 <= ax */ R = s*(rd1+s*(rd2+s*(rd3+s*(rd4+s*(rd5+ s*(rd6+s*(rd7+s*(rd8+s*(rd9+s*(rd10 +s*(rd11+s*(rd12+s*rd13)))))))))))); y += rd0; } else if (ax >= 2) { R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+ s*(rb6+s*(rb7+s*(rb8+s*(rb9+s*rb10))))))))); S = one+s*(sb1+s*(sb2+s*sb3)); y += R/S; R = -.5*s; } else { R = rc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*(rc5+ s*(rc6+s*(rc7+s*(rc8+s*(rc9+s*rc10))))))))); S = one+s*(sc1+s*(sc2+s*sc3)); y += R/S; R = -.5*s; } /* return exp(-x^2 - lsqrtPI_hi + R + y)/x; */ s = ((R + y) - lsqrtPI_hi) + z; y = (((z-s) - lsqrtPI_hi) + R) + y; r = __exp__D(s, y)/x; if (x>0) return r; else return two-r; }
double svm_kernel_fisher(bow_wv *wv1, bow_wv *wv2) { bow_cdoc *cd; int max_entries; /* max number of elements that can be in both */ int nclasses; int nwords; NPair *Nvector; double rval; double tmp; bow_we *v1, *v2; double t2, pci; int i, j, k; nwords = total_num_words_occurences; nclasses = bow_barrel_num_classes(rainbow_nb_barrel); max_entries = MIN(wv1->num_entries, wv2->num_entries); Nvector = (NPair *) alloca(max_entries*sizeof(NPair)); v1 = wv1->entry; v2 = wv2->entry; /* compute the N(wi,X1)*N(wi,X2) vector */ for (i=j=k=0; (i<max_entries) && (j<max_entries); ) { if(v1[i].wi > v2[j].wi) { j++; } else if (v1[i].wi < v2[j].wi) { i++; } else { Nvector[k].index = v1[i].wi; Nvector[k].N = (v1[i].count)*(v2[j].count); k++; i++; j++; } } max_entries = k; rval = 0.0; /* now we have all of the P(X*|C*) terms - in ascending order with * regards to class index */ for (i=0; i<nclasses; i++) { for (j=0, tmp=0; j<max_entries; j++) { t2 = bow_naivebayes_pr_wi_ci(rainbow_nb_barrel, Nvector[j].index, i, -1, 0, 0, NULL, NULL); t2 = t2*t2; tmp += Nvector[j].N / (dIij[i*nclasses + Nvector[j].index] * t2); assert(finite(tmp)); } /* compute P(x[12]|ci)/P(x[12]) */ { double p_w; bow_we *v; bow_wv *w; int k,h,n; t2 = fisher_norm0; for (w=wv1, n=0; n<2; n++, w=wv2) { v = w->entry; for (h=0; h<w->num_entries; h++) { double sum, t; bow_dv *dv = bow_wi2dvf_dv(rainbow_nb_barrel->wi2dvf, v[h].wi); assert(dv); /* sum up the number of words that appeared in all of the classes */ for (k=0, sum=0.0; k<dv->length; k++) { sum += dv->entry[k].weight; } p_w = log(sum/nwords)*v[h].weight; t = (double) bow_naivebayes_pr_wi_ci (rainbow_nb_barrel, v[h].wi, i, -1, 0.0, 0.0, NULL, NULL); t = log(t) * v[h].weight; t2 += t - p_w; assert(finite(t2)); //printf("P(w%d|c%d)^%f, p_w^%f\n", v[h].wi, k, t, p_w); } } } cd = GET_CDOC_ARRAY_EL(rainbow_nb_barrel,i); pci = cd->prior; rval += exp(t2 + log(dIi[i] + (tmp*pci*pci))); assert(finite(rval)); } //rval = exp(rval); printf("kernel=%f\n",rval); return rval; }
void svm_setup_fisher(bow_barrel *old_barrel, bow_wv **docs, int nclasses, int ndocs) { double *PXk, PX; int i,j,k; rainbow_method *tmp = old_barrel->method; old_barrel->method = &bow_method_naivebayes; rainbow_nb_barrel = bow_barrel_new_vpc_merge_then_weight (old_barrel); old_barrel->method = tmp; /* set some global variables that naivebayes.c uses */ naivebayes_score_returns_doc_pr = 1; naivebayes_score_unsorted = 1; fprintf(stderr, "Finding maximum kernel value for normalizing\n"); i = bow_num_words()*nclasses; dIi = (double *) malloc(sizeof(double)*nclasses); PXk = (double *) malloc(sizeof(double)*nclasses); dIij = (double *) malloc(sizeof(double)*i); for (j=0; j<i; j++) { dIij[j] = 0.0; } for (j=0; j<nclasses; j++) { dIi[j] = 0.0; } for (i=0; i<ndocs; i++) { double max_lpr; bow_score *scores = malloc(sizeof(bow_score)*nclasses); /* compute the P(X|class) * P(class) terms (since they're used so often) */ PX = 0.0; /* NOTE: with the ...returns_doc_pr variable set, the scores are not probabilities, * but instead log probabilities */ bow_naivebayes_score(rainbow_nb_barrel, docs[i], scores, nclasses, -1); max_lpr = scores[0].weight; for (k=1; k<nclasses; k++) { if (scores[k].weight > max_lpr) max_lpr = scores[k].weight; } for (k=0; k<nclasses; k++) { bow_cdoc *cd = GET_CDOC_ARRAY_EL(rainbow_nb_barrel,k); /* the max lpr over everything is the same as multiplying both the * denominator & the numerator by some large constant */ PXk[k] = cd->prior * exp(scores[k].weight - max_lpr); /* hacky-hacky-hacky-smoothing */ #define THRESH 1e-1 if (PXk[k] < THRESH) { PXk[k] = THRESH; printf("underflow on P(X%d|C%d) - setting to small val\n",i,k); fflush(stdout); } PX += PXk[k]; assert(finite(PXk[k]) && PXk[k] != 0.0); } free(scores); /* compute term for Iij - d/d-theta_ij * log(P(X|theta)) */ for (j=0; j<docs[i]->num_entries; j++) { for (k=0; k<nclasses; k++) { double tmp; tmp = bow_naivebayes_pr_wi_ci (rainbow_nb_barrel, docs[i]->entry[j].wi, k, -1, 0.0, 0.0, NULL, NULL); dIij[k*nclasses + docs[i]->entry[j].wi] += ((((docs[i]->entry[j].count * PXk[k]) /tmp) /PX) * (((docs[i]->entry[j].count * PXk[k]) /tmp) /PX)); } } /* compute term for Ii - d/d-theta_i * log(P(X|theta)) */ for (k=0; k<nclasses; k++) { /* M is in both of these terms, so we don't need to worry about it... */ dIi[k] += (PXk[k]/ PX)*(PXk[k]/ PX); assert(finite(dIi[k])); } if (!(i % 100)) { fprintf(stderr, "\r%f%%", (float) ((double)i)/((double)ndocs)*100.0); } } free(PXk); /* now invert the values class values */ for (i=0; i<nclasses; i++) { dIi[i] = 1/dIi[i]; } fprintf(stderr,"%f%%\n",(float)100.0); /* set "fisher normalizer" */ { double max = -1; int from=0; fisher_norm0 = 0; /* keep in mind, this is log(scalar) */ for (i=0; i<ndocs; i++) { double tmp = svm_kernel_fisher(docs[i],docs[i]); if (max < tmp) { max = tmp; from = i; } } fisher_norm0 = log(1/max); } }
// feed adaptation data from an alignment into the adaptation process // note: it is possible to accumulate statistics at the Gaussian component or at the transform level // - Gaussian component level: O(n^2) per Gaussian component // - Transform level: O(n^3) per transform + O(n) per Gaussian component void FMLLREstimator::feedAdaptationData(MatrixBase<float> &mFeatures, Alignment *alignment, double *dLikelihood) { // sanity check assert((unsigned int)mFeatures.getRows() == alignment->getFrames()); m_fOccupancyTotal += mFeatures.getRows(); *dLikelihood = 0.0; for(unsigned int t=0 ; t<mFeatures.getRows() ; ++t) { VectorStatic<float> vFeatureVector = mFeatures.getRow(t); // extended observation vector Vector<double> vObsEx(vFeatureVector); vObsEx.appendFront(1.0); // for each HMM-state the observation is assigned to FrameAlignment *frameAlignment = alignment->getFrameAlignment(t); for(FrameAlignment::iterator it = frameAlignment->begin() ; it != frameAlignment->end() ; ++it) { HMMStateDecoding *hmmStateDecoding = m_hmmManager->getHMMStateDecoding((*it)->iHMMState); // compute the contribution of each Gaussian // (case 1) all the frame-level adaptation data goes to the best scoring Gaussian component (faster) if (m_bBestComponentOnly) { float fLikelihood = -FLT_MAX; GaussianDecoding *gaussian = hmmStateDecoding->getBestScoringGaussian(vFeatureVector.getData(),&fLikelihood); *dLikelihood += std::max<float>(fLikelihood,LOG_LIKELIHOOD_FLOOR); Vector<float> vCovariance(VectorStatic<float>(gaussian->fCovariance,m_iDim)); #ifdef OPTIMIZED_COMPUTATION vCovariance.mul(2.0); vCovariance.invertElements(); #endif // accumulate data for each G(i) m_matrixAux->zero(); m_matrixAux->addVecMul(1.0,vObsEx,vObsEx); for(int i=0 ; i < m_iDim; ++i) { double dCovInv = 1.0/vCovariance(i); m_matrixG[i]->add(dCovInv*1.0,*m_matrixAux); } // accumulate data for each k(i) for(int i=0 ; i < m_iDim ; ++i) { double dConstant = (gaussian->fMean[i]/vCovariance(i))*1.0; m_matrixK->getRow(i).add(dConstant,vObsEx); } } // (case 2) adaptation data is shared across all components (slightly more accurate) else { double *dProbGaussian = new double[hmmStateDecoding->getGaussianComponents()]; double dProbTotal = 0.0; for(int g=0 ; g < hmmStateDecoding->getGaussianComponents() ; ++g) { dProbGaussian[g] = exp(hmmStateDecoding->computeGaussianProbability(g,vFeatureVector.getData())); dProbTotal += dProbGaussian[g]; assert((finite(dProbGaussian[g])) && (finite(dProbTotal))); } *dLikelihood += max(log(dProbTotal),LOG_LIKELIHOOD_FLOOR); for(unsigned int iGaussian = 0 ; iGaussian < hmmStateDecoding->getMixtureSize() ; ++iGaussian) { GaussianDecoding *gaussian = hmmStateDecoding->getGaussian(iGaussian); double dGaussianOccupation = dProbGaussian[iGaussian]/dProbTotal; Vector<float> vCovariance(VectorStatic<float>(gaussian->fCovariance,m_iDim)); #ifdef OPTIMIZED_COMPUTATION vCovariance.mul(2.0); vCovariance.invertElements(); #endif // accumulate data for each G(i) m_matrixAux->zero(); m_matrixAux->addVecMul(1.0,vObsEx,vObsEx); for(int i=0 ; i < m_iDim; ++i) { double dCovInv = 1.0/vCovariance(i); m_matrixG[i]->add(dCovInv*dGaussianOccupation,*m_matrixAux); } // accumulate data for each k(i) for(int i=0 ; i < m_iDim ; ++i) { double dConstant = (gaussian->fMean[i]/vCovariance(i))*dGaussianOccupation; m_matrixK->getRow(i).add(dConstant,vObsEx); } } delete [] dProbGaussian; } } } }
int yylex() { char *p = line + linelim; int ret; static int isfunc = 0; static bool isgoto = 0; static bool colstate = 0; static int dateflag; static char *tokenst = NULL; static int tokenl; while (isspace(*p)) p++; if (*p == '\0') { isfunc = isgoto = 0; ret = -1; } else if (isalpha(*p) || (*p == '_')) { register char *la; /* lookahead pointer */ register struct key *tblp; if (!tokenst) { tokenst = p; tokenl = 0; } /* * This picks up either 1 or 2 alpha characters (a column) or * tokens made up of alphanumeric chars and '_' (a function or * token or command or a range name) */ while (isalpha(*p) && isascii(*p)) { p++; tokenl++; } la = p; while (isdigit(*la) || (*la == '$')) la++; /* * A COL is 1 or 2 char alpha with nothing but digits following * (no alpha or '_') */ if (!isdigit(*tokenst) && tokenl && tokenl <= 2 && (colstate || (isdigit(*(la-1)) && !(isalpha(*la) || (*la == '_'))))) { ret = COL; yylval.ival = atocol(tokenst, tokenl); } else { while (isalpha(*p) || (*p == '_') || isdigit(*p)) { p++; tokenl++; } ret = WORD; if (!linelim || isfunc) { if (isfunc) isfunc--; for (tblp = linelim ? experres : statres; tblp->key; tblp++) if (((tblp->key[0]^tokenst[0])&0137)==0 && tblp->key[tokenl]==0) { int i = 1; while (i<tokenl && ((tokenst[i]^tblp->key[i])&0137)==0) i++; if (i >= tokenl) { ret = tblp->val; colstate = (ret <= S_FORMAT); if (isgoto) { isfunc = isgoto = 0; if (ret != K_ERROR && ret != K_INVALID) ret = WORD; } break; } } } if (ret == WORD) { struct range *r; char *path; if (!find_range(tokenst, tokenl, (struct ent *)0, (struct ent *)0, &r)) { yylval.rval.left = r->r_left; yylval.rval.right = r->r_right; if (r->r_is_range) ret = RANGE; else ret = VAR; } else if ((path = scxmalloc((unsigned)PATHLEN)) && plugin_exists(tokenst, tokenl, path)) { strcat(path, p); yylval.sval = path; ret = PLUGIN; } else { scxfree(path); linelim = p-line; yyerror("Unintelligible word"); } } } } else if ((*p == '.') || isdigit(*p)) { #ifdef SIGVOID void (*sig_save)(); #else int (*sig_save)(); #endif double v = 0.0; int temp; char *nstart = p; sig_save = signal(SIGFPE, fpe_trap); if (setjmp(fpe_buf)) { (void) signal(SIGFPE, sig_save); yylval.fval = v; error("Floating point exception\n"); isfunc = isgoto = 0; tokenst = NULL; return FNUMBER; } if (*p=='.' && dateflag) { /* .'s in dates are returned as tokens. */ ret = *p++; dateflag--; } else { if (*p != '.') { tokenst = p; tokenl = 0; do { v = v*10.0 + (double) ((unsigned) *p - '0'); tokenl++; } while (isdigit(*++p)); if (dateflag) { ret = NUMBER; yylval.ival = (int)v; /* * If a string of digits is followed by two .'s separated by * one or two digits, assume this is a date and return the * .'s as tokens instead of interpreting them as decimal * points. dateflag counts the .'s as they're returned. */ } else if (*p=='.' && isdigit(*(p+1)) && (*(p+2)=='.' || (isdigit(*(p+2)) && *(p+3)=='.'))) { ret = NUMBER; yylval.ival = (int)v; dateflag = 2; } else if (*p == 'e' || *p == 'E') { while (isdigit(*++p)) /* */; if (isalpha(*p) || *p == '_') { linelim = p - line; return (yylex()); } else ret = FNUMBER; } else if (isalpha(*p) || *p == '_') { linelim = p - line; return (yylex()); } } if ((!dateflag && *p=='.') || ret == FNUMBER) { ret = FNUMBER; yylval.fval = strtod(nstart, &p); if (!finite(yylval.fval)) ret = K_ERR; else decimal = TRUE; } else { /* A NUMBER must hold at least MAXROW and MAXCOL */ /* This is consistent with a short row and col in struct ent */ if (v > (double)32767 || v < (double)-32768) { ret = FNUMBER; yylval.fval = v; } else { temp = (int)v; if((double)temp != v) { ret = FNUMBER; yylval.fval = v; } else { ret = NUMBER; yylval.ival = temp; } } } } (void) signal(SIGFPE, sig_save); } else if (*p=='"') { char *ptr; ptr = p+1; /* "string" or "string\"quoted\"" */ while (*ptr && ((*ptr != '"') || (*(ptr-1) == '\\'))) ptr++; ptr = scxmalloc((unsigned)(ptr-p)); yylval.sval = ptr; p++; while (*p && ((*p != '"') || (*(p-1) == '\\' && *(p+1) != '\0' && *(p+1) != '\n'))) *ptr++ = *p++; *ptr = '\0'; if (*p) p++; ret = STRING; } else if (*p=='[') { while (*p && *p!=']') p++; if (*p) p++; linelim = p-line; tokenst = NULL; return yylex(); } else ret = *p++; linelim = p-line; if (!isfunc) isfunc = ((ret == '@') + (ret == S_GOTO) - (ret == S_SET)); if (ret == S_GOTO) isgoto = TRUE; tokenst = NULL; return ret; }
/** * Validate the mesh, \a do_fixes requires \a mesh to be non-null. * * \return false if no changes needed to be made. */ bool BKE_mesh_validate_arrays(Mesh *mesh, MVert *mverts, unsigned int totvert, MEdge *medges, unsigned int totedge, MFace *mfaces, unsigned int totface, MLoop *mloops, unsigned int totloop, MPoly *mpolys, unsigned int totpoly, MDeformVert *dverts, /* assume totvert length */ const bool do_verbose, const bool do_fixes, bool *r_change) { # define REMOVE_EDGE_TAG(_me) { _me->v2 = _me->v1; do_edge_free = true; } (void)0 # define IS_REMOVED_EDGE(_me) (_me->v2 == _me->v1) # define REMOVE_LOOP_TAG(_ml) { _ml->e = INVALID_LOOP_EDGE_MARKER; do_polyloop_free = true; } (void)0 # define REMOVE_POLY_TAG(_mp) { _mp->totloop *= -1; do_polyloop_free = true; } (void)0 MVert *mv = mverts; MEdge *me; MLoop *ml; MPoly *mp; unsigned int i, j; int *v; bool is_valid = true; bool do_edge_free = false; bool do_face_free = false; bool do_polyloop_free = false; /* This regroups loops and polys! */ bool verts_fixed = false; bool vert_weights_fixed = false; bool msel_fixed = false; bool do_edge_recalc = false; EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, totedge); BLI_assert(!(do_fixes && mesh == NULL)); PRINT_MSG("%s: verts(%u), edges(%u), loops(%u), polygons(%u)\n", __func__, totvert, totedge, totloop, totpoly); if (totedge == 0 && totpoly != 0) { PRINT_ERR("\tLogical error, %u polygons and 0 edges\n", totpoly); do_edge_recalc = do_fixes; } for (i = 1; i < totvert; i++, mv++) { int fix_normal = TRUE; for (j = 0; j < 3; j++) { if (!finite(mv->co[j])) { PRINT_ERR("\tVertex %u: has invalid coordinate\n", i); if (do_fixes) { zero_v3(mv->co); verts_fixed = TRUE; } } if (mv->no[j] != 0) fix_normal = FALSE; } if (fix_normal) { PRINT_ERR("\tVertex %u: has zero normal, assuming Z-up normal\n", i); if (do_fixes) { mv->no[2] = SHRT_MAX; verts_fixed = TRUE; } } } for (i = 0, me = medges; i < totedge; i++, me++) { int remove = FALSE; if (me->v1 == me->v2) { PRINT_ERR("\tEdge %u: has matching verts, both %u\n", i, me->v1); remove = do_fixes; } if (me->v1 >= totvert) { PRINT_ERR("\tEdge %u: v1 index out of range, %u\n", i, me->v1); remove = do_fixes; } if (me->v2 >= totvert) { PRINT_ERR("\tEdge %u: v2 index out of range, %u\n", i, me->v2); remove = do_fixes; } if (BLI_edgehash_haskey(edge_hash, me->v1, me->v2)) { PRINT_ERR("\tEdge %u: is a duplicate of %d\n", i, GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, me->v1, me->v2))); remove = do_fixes; } if (remove == FALSE) { BLI_edgehash_insert(edge_hash, me->v1, me->v2, SET_INT_IN_POINTER(i)); } else { REMOVE_EDGE_TAG(me); } } if (mfaces && !mpolys) { # define REMOVE_FACE_TAG(_mf) { _mf->v3 = 0; do_face_free = TRUE; } (void)0 # define CHECK_FACE_VERT_INDEX(a, b) \ if (mf->a == mf->b) { \ PRINT_ERR(" face %u: verts invalid, " STRINGIFY(a) "/" STRINGIFY(b) " both %u\n", i, mf->a); \ remove = do_fixes; \ } (void)0 # define CHECK_FACE_EDGE(a, b) \ if (!BLI_edgehash_haskey(edge_hash, mf->a, mf->b)) { \ PRINT_ERR(" face %u: edge " STRINGIFY(a) "/" STRINGIFY(b) \ " (%u,%u) is missing edge data\n", i, mf->a, mf->b); \ do_edge_recalc = TRUE; \ } (void)0 MFace *mf; MFace *mf_prev; SortFace *sort_faces = MEM_callocN(sizeof(SortFace) * totface, "search faces"); SortFace *sf; SortFace *sf_prev; unsigned int totsortface = 0; PRINT_ERR("No Polys, only tesselated Faces\n"); for (i = 0, mf = mfaces, sf = sort_faces; i < totface; i++, mf++) { int remove = FALSE; int fidx; unsigned int fv[4]; fidx = mf->v4 ? 3 : 2; do { fv[fidx] = *(&(mf->v1) + fidx); if (fv[fidx] >= totvert) { PRINT_ERR("\tFace %u: 'v%d' index out of range, %u\n", i, fidx + 1, fv[fidx]); remove = do_fixes; } } while (fidx--); if (remove == FALSE) { if (mf->v4) { CHECK_FACE_VERT_INDEX(v1, v2); CHECK_FACE_VERT_INDEX(v1, v3); CHECK_FACE_VERT_INDEX(v1, v4); CHECK_FACE_VERT_INDEX(v2, v3); CHECK_FACE_VERT_INDEX(v2, v4); CHECK_FACE_VERT_INDEX(v3, v4); } else { CHECK_FACE_VERT_INDEX(v1, v2); CHECK_FACE_VERT_INDEX(v1, v3); CHECK_FACE_VERT_INDEX(v2, v3); } if (remove == FALSE) { if (totedge) { if (mf->v4) { CHECK_FACE_EDGE(v1, v2); CHECK_FACE_EDGE(v2, v3); CHECK_FACE_EDGE(v3, v4); CHECK_FACE_EDGE(v4, v1); } else { CHECK_FACE_EDGE(v1, v2); CHECK_FACE_EDGE(v2, v3); CHECK_FACE_EDGE(v3, v1); } } sf->index = i; if (mf->v4) { edge_store_from_mface_quad(sf->es, mf); qsort(sf->es, 4, sizeof(int64_t), int64_cmp); } else { edge_store_from_mface_tri(sf->es, mf); qsort(sf->es, 3, sizeof(int64_t), int64_cmp); } totsortface++; sf++; } } if (remove) { REMOVE_FACE_TAG(mf); } } qsort(sort_faces, totsortface, sizeof(SortFace), search_face_cmp); sf = sort_faces; sf_prev = sf; sf++; for (i = 1; i < totsortface; i++, sf++) { int remove = FALSE; /* on a valid mesh, code below will never run */ if (memcmp(sf->es, sf_prev->es, sizeof(sf_prev->es)) == 0) { mf = mfaces + sf->index; if (do_verbose) { mf_prev = mfaces + sf_prev->index; if (mf->v4) { PRINT_ERR("\tFace %u & %u: are duplicates (%u,%u,%u,%u) (%u,%u,%u,%u)\n", sf->index, sf_prev->index, mf->v1, mf->v2, mf->v3, mf->v4, mf_prev->v1, mf_prev->v2, mf_prev->v3, mf_prev->v4); } else { PRINT_ERR("\tFace %u & %u: are duplicates (%u,%u,%u) (%u,%u,%u)\n", sf->index, sf_prev->index, mf->v1, mf->v2, mf->v3, mf_prev->v1, mf_prev->v2, mf_prev->v3); } } remove = do_fixes; } else { sf_prev = sf; } if (remove) { REMOVE_FACE_TAG(mf); } } MEM_freeN(sort_faces); # undef REMOVE_FACE_TAG # undef CHECK_FACE_VERT_INDEX # undef CHECK_FACE_EDGE } /* Checking loops and polys is a bit tricky, as they are quite intricated... * * Polys must have: * - a valid loopstart value. * - a valid totloop value (>= 3 and loopstart+totloop < me.totloop). * * Loops must have: * - a valid v value. * - a valid e value (corresponding to the edge it defines with the next loop in poly). * * Also, loops not used by polys can be discarded. * And "intersecting" loops (i.e. loops used by more than one poly) are invalid, * so be sure to leave at most one poly per loop! */ { SortPoly *sort_polys = MEM_callocN(sizeof(SortPoly) * totpoly, "mesh validate's sort_polys"); SortPoly *prev_sp, *sp = sort_polys; int prev_end; for (i = 0, mp = mpolys; i < totpoly; i++, mp++, sp++) { sp->index = i; if (mp->loopstart < 0 || mp->totloop < 3) { /* Invalid loop data. */ PRINT_ERR("\tPoly %u is invalid (loopstart: %u, totloop: %u)\n", sp->index, mp->loopstart, mp->totloop); sp->invalid = TRUE; } else if (mp->loopstart + mp->totloop > totloop) { /* Invalid loop data. */ PRINT_ERR("\tPoly %u uses loops out of range (loopstart: %u, loopend: %u, max nbr of loops: %u)\n", sp->index, mp->loopstart, mp->loopstart + mp->totloop - 1, totloop - 1); sp->invalid = TRUE; } else { /* Poly itself is valid, for now. */ int v1, v2; /* v1 is prev loop vert idx, v2 is current loop one. */ sp->invalid = FALSE; sp->verts = v = MEM_mallocN(sizeof(int) * mp->totloop, "Vert idx of SortPoly"); sp->numverts = mp->totloop; sp->loopstart = mp->loopstart; /* Test all poly's loops' vert idx. */ for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++, v++) { if (ml->v >= totvert) { /* Invalid vert idx. */ PRINT_ERR("\tLoop %u has invalid vert reference (%u)\n", sp->loopstart + j, ml->v); sp->invalid = TRUE; } mverts[ml->v].flag |= ME_VERT_TMP_TAG; *v = ml->v; } /* is the same vertex used more than once */ if (!sp->invalid) { v = sp->verts; for (j = 0; j < mp->totloop; j++, v++) { if ((mverts[*v].flag & ME_VERT_TMP_TAG) == 0) { PRINT_ERR("\tPoly %u has duplicate vert reference at corner (%u)\n", i, j); sp->invalid = TRUE; } mverts[*v].flag &= ~ME_VERT_TMP_TAG; } } if (sp->invalid) continue; /* Test all poly's loops. */ for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++) { v1 = ml->v; v2 = mloops[sp->loopstart + (j + 1) % mp->totloop].v; if (!BLI_edgehash_haskey(edge_hash, v1, v2)) { /* Edge not existing. */ PRINT_ERR("\tPoly %u needs missing edge (%u, %u)\n", sp->index, v1, v2); if (do_fixes) do_edge_recalc = TRUE; else sp->invalid = TRUE; } else if (ml->e >= totedge) { /* Invalid edge idx. * We already know from previous text that a valid edge exists, use it (if allowed)! */ if (do_fixes) { int prev_e = ml->e; ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, v1, v2)); PRINT_ERR("\tLoop %u has invalid edge reference (%u), fixed using edge %u\n", sp->loopstart + j, prev_e, ml->e); } else { PRINT_ERR("\tLoop %u has invalid edge reference (%u)\n", sp->loopstart + j, ml->e); sp->invalid = TRUE; } } else { me = &medges[ml->e]; if (IS_REMOVED_EDGE(me) || !((me->v1 == v1 && me->v2 == v2) || (me->v1 == v2 && me->v2 == v1))) { /* The pointed edge is invalid (tagged as removed, or vert idx mismatch), * and we already know from previous test that a valid one exists, use it (if allowed)! */ if (do_fixes) { int prev_e = ml->e; ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, v1, v2)); PRINT_ERR("\tPoly %u has invalid edge reference (%u), fixed using edge %u\n", sp->index, prev_e, ml->e); } else { PRINT_ERR("\tPoly %u has invalid edge reference (%u)\n", sp->index, ml->e); sp->invalid = TRUE; } } } } /* Now check that that poly does not use a same vertex more than once! */ if (!sp->invalid) { int *prev_v = v = sp->verts; j = sp->numverts; qsort(sp->verts, j, sizeof(int), int_cmp); for (j--, v++; j; j--, v++) { if (*v != *prev_v) { int dlt = v - prev_v; if (dlt > 1) { PRINT_ERR("\tPoly %u is invalid, it multi-uses vertex %u (%u times)\n", sp->index, *prev_v, dlt); sp->invalid = TRUE; } prev_v = v; } } if (v - prev_v > 1) { /* Don't forget final verts! */ PRINT_ERR("\tPoly %u is invalid, it multi-uses vertex %u (%u times)\n", sp->index, *prev_v, (int)(v - prev_v)); sp->invalid = TRUE; } } } } /* Second check pass, testing polys using the same verts. */ qsort(sort_polys, totpoly, sizeof(SortPoly), search_poly_cmp); sp = prev_sp = sort_polys; sp++; for (i = 1; i < totpoly; i++, sp++) { int p1_nv = sp->numverts, p2_nv = prev_sp->numverts; int *p1_v = sp->verts, *p2_v = prev_sp->verts; short p1_sub = TRUE, p2_sub = TRUE; if (sp->invalid) break; /* Test same polys. */ #if 0 /* NOTE: This performs a sub-set test. */ /* XXX This (and the sort of verts list) is better than systematic * search of all verts of one list into the other if lists have * a fair amount of elements. * Not sure however it's worth it in this case? * But as we also need sorted vert list to check verts multi-used * (in first pass of checks)... */ /* XXX If we consider only "equal" polys (i.e. using exactly same set of verts) * as invalid, better to replace this by a simple memory cmp... */ while ((p1_nv && p2_nv) && (p1_sub || p2_sub)) { if (*p1_v < *p2_v) { if (p1_sub) p1_sub = FALSE; p1_nv--; p1_v++; } else if (*p2_v < *p1_v) { if (p2_sub) p2_sub = FALSE; p2_nv--; p2_v++; } else { /* Equality, both next verts. */ p1_nv--; p2_nv--; p1_v++; p2_v++; } } if (p1_nv && p1_sub) p1_sub = FALSE; else if (p2_nv && p2_sub) p2_sub = FALSE; if (p1_sub && p2_sub) { PRINT("\tPolys %u and %u use same vertices, considering poly %u as invalid.\n", prev_sp->index, sp->index, sp->index); sp->invalid = TRUE; } /* XXX In fact, these might be valid? :/ */ else if (p1_sub) { PRINT("\t%u is a sub-poly of %u, considering it as invalid.\n", sp->index, prev_sp->index); sp->invalid = TRUE; } else if (p2_sub) { PRINT("\t%u is a sub-poly of %u, considering it as invalid.\n", prev_sp->index, sp->index); prev_sp->invalid = TRUE; prev_sp = sp; /* sp is new reference poly. */ } #else if (0) { p1_sub += 0; p2_sub += 0; } if ((p1_nv == p2_nv) && (memcmp(p1_v, p2_v, p1_nv * sizeof(*p1_v)) == 0)) { if (do_verbose) { PRINT_ERR("\tPolys %u and %u use same vertices (%u", prev_sp->index, sp->index, *p1_v); for (j = 1; j < p1_nv; j++) PRINT_ERR(", %u", p1_v[j]); PRINT_ERR("), considering poly %u as invalid.\n", sp->index); } else { is_valid = false; } sp->invalid = TRUE; } #endif else { prev_sp = sp; } } /* Third check pass, testing loops used by none or more than one poly. */ qsort(sort_polys, totpoly, sizeof(SortPoly), search_polyloop_cmp); sp = sort_polys; prev_sp = NULL; prev_end = 0; for (i = 0; i < totpoly; i++, sp++) { /* Free this now, we don't need it anymore, and avoid us another loop! */ if (sp->verts) MEM_freeN(sp->verts); /* Note above prev_sp: in following code, we make sure it is always valid poly (or NULL). */ if (sp->invalid) { if (do_fixes) { REMOVE_POLY_TAG((&mpolys[sp->index])); /* DO NOT REMOVE ITS LOOPS!!! * As already invalid polys are at the end of the SortPoly list, the loops they * were the only users have already been tagged as "to remove" during previous * iterations, and we don't want to remove some loops that may be used by * another valid poly! */ } } /* Test loops users. */ else { /* Unused loops. */ if (prev_end < sp->loopstart) { for (j = prev_end, ml = &mloops[prev_end]; j < sp->loopstart; j++, ml++) { PRINT_ERR("\tLoop %u is unused.\n", j); if (do_fixes) REMOVE_LOOP_TAG(ml); } prev_end = sp->loopstart + sp->numverts; prev_sp = sp; } /* Multi-used loops. */ else if (prev_end > sp->loopstart) { PRINT_ERR("\tPolys %u and %u share loops from %u to %u, considering poly %u as invalid.\n", prev_sp->index, sp->index, sp->loopstart, prev_end, sp->index); if (do_fixes) { REMOVE_POLY_TAG((&mpolys[sp->index])); /* DO NOT REMOVE ITS LOOPS!!! * They might be used by some next, valid poly! * Just not updating prev_end/prev_sp vars is enough to ensure the loops * effectively no more needed will be marked as "to be removed"! */ } } else { prev_end = sp->loopstart + sp->numverts; prev_sp = sp; } } } /* We may have some remaining unused loops to get rid of! */ if (prev_end < totloop) { for (j = prev_end, ml = &mloops[prev_end]; j < totloop; j++, ml++) { PRINT_ERR("\tLoop %u is unused.\n", j); if (do_fixes) REMOVE_LOOP_TAG(ml); } } MEM_freeN(sort_polys); } BLI_edgehash_free(edge_hash, NULL); /* fix deform verts */ if (dverts) { MDeformVert *dv; for (i = 0, dv = dverts; i < totvert; i++, dv++) { MDeformWeight *dw; for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) { /* note, greater then max defgroups is accounted for in our code, but not < 0 */ if (!finite(dw->weight)) { PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight); if (do_fixes) { dw->weight = 0.0f; vert_weights_fixed = TRUE; } } else if (dw->weight < 0.0f || dw->weight > 1.0f) { PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight); if (do_fixes) { CLAMP(dw->weight, 0.0f, 1.0f); vert_weights_fixed = TRUE; } } if (dw->def_nr < 0) { PRINT_ERR("\tVertex deform %u, has invalid group %d\n", i, dw->def_nr); if (do_fixes) { defvert_remove_group(dv, dw); if (dv->dw) { /* re-allocated, the new values compensate for stepping * within the for loop and may not be valid */ j--; dw = dv->dw + j; vert_weights_fixed = TRUE; } else { /* all freed */ break; } } } } } } # undef REMOVE_EDGE_TAG # undef IS_REMOVED_EDGE # undef REMOVE_LOOP_TAG # undef REMOVE_POLY_TAG if (mesh) { if (do_face_free) { BKE_mesh_strip_loose_faces(mesh); } if (do_polyloop_free) { BKE_mesh_strip_loose_polysloops(mesh); } if (do_edge_free) { BKE_mesh_strip_loose_edges(mesh); } if (do_edge_recalc) { BKE_mesh_calc_edges(mesh, true, false); } } if (mesh && mesh->mselect) { MSelect *msel; int free_msel = FALSE; for (i = 0, msel = mesh->mselect; i < mesh->totselect; i++, msel++) { int tot_elem = 0; if (msel->index < 0) { PRINT_ERR("\tMesh select element %d type %d index is negative, " "resetting selection stack.\n", i, msel->type); free_msel = TRUE; break; } switch (msel->type) { case ME_VSEL: tot_elem = mesh->totvert; break; case ME_ESEL: tot_elem = mesh->totedge; break; case ME_FSEL: tot_elem = mesh->totface; break; } if (msel->index > tot_elem) { PRINT_ERR("\tMesh select element %d type %d index %d is larger than data array size %d, " "resetting selection stack.\n", i, msel->type, msel->index, tot_elem); free_msel = TRUE; break; } } if (free_msel) { MEM_freeN(mesh->mselect); mesh->mselect = NULL; mesh->totselect = 0; } } PRINT_MSG("%s: finished\n\n", __func__); *r_change = (verts_fixed || vert_weights_fixed || do_polyloop_free || do_edge_free || do_edge_recalc || msel_fixed); return is_valid; }
void XInputUtils::fixXInputCoords(GdkEvent* event, GtkWidget* widget) { double* axes, *px, *py; GdkDevice* device; int wx, wy, ix, iy; if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) { axes = event->button.axes; px = &(event->button.x); py = &(event->button.y); device = event->button.device; } else if (event->type == GDK_MOTION_NOTIFY) { axes = event->motion.axes; px = &(event->motion.x); py = &(event->motion.y); device = event->motion.device; } else { return; // nothing we know how to do } if (axes == NULL) { return; } #ifdef ENABLE_XINPUT_BUGFIX // fix broken events with the core pointer's location if (!finite(axes[0]) || !finite(axes[1]) || (axes[0] == 0. && axes[1] == 0.)) { gdk_window_get_pointer(GTK_WIDGET(widget)->window, &ix, &iy, NULL); *px = ix; *py = iy; } else { gdk_window_get_origin(GTK_WIDGET(widget)->window, &wx, &wy); double axis_width = device->axes[0].max - device->axes[0].min; if (axis_width > EPSILON) { *px = (axes[0] / axis_width) * screenWidth - wx; } axis_width = device->axes[1].max - device->axes[1].min; if (axis_width > EPSILON) { *py = (axes[1] / axis_width) * screenHeight - wy; } } #else if (!finite(*px) || !finite(*py) || (*px == 0. && *py == 0.)) { gdk_window_get_pointer(GTK_WIDGET(widget)->window, &ix, &iy, NULL); *px = ix; *py = iy; } else { /* with GTK+ 2.17, events come improperly translated, and the event's GdkWindow isn't even the same for ButtonDown as for MotionNotify... */ if (gtk_major_version == 2 && gtk_minor_version == 17) // GTK+ 2.17 issues !! { gdk_window_get_position(GTK_WIDGET(widget)->window, &wx, &wy); *px += wx; *py += wy; } } #endif }
static DerivedMesh *doOcean(ModifierData *md, Object *ob, DerivedMesh *derivedData, int UNUSED(useRenderParams)) { OceanModifierData *omd = (OceanModifierData *) md; DerivedMesh *dm = NULL; OceanResult ocr; MVert *mverts, *mv; MLoop *mloops; int i, j; int num_verts; int num_faces; int cfra; /* use cached & inverted value for speed * expanded this would read... * * (axis / (omd->size * omd->spatial_size)) + 0.5f) */ #define OCEAN_CO(_size_co_inv, _v) ((_v * _size_co_inv) + 0.5f) const float size_co_inv = 1.0f / (omd->size * omd->spatial_size); /* can happen in when size is small, avoid bad array lookups later and quit now */ if (!finite(size_co_inv)) { return derivedData; } /* update modifier */ if (omd->refresh & MOD_OCEAN_REFRESH_ADD) omd->ocean = BKE_add_ocean(); if (omd->refresh & MOD_OCEAN_REFRESH_RESET) init_ocean_modifier(omd); if (omd->refresh & MOD_OCEAN_REFRESH_CLEAR_CACHE) clear_cache_data(omd); omd->refresh = 0; /* do ocean simulation */ if (omd->cached == TRUE) { if (!omd->oceancache) init_cache_data(ob, omd); BKE_simulate_ocean_cache(omd->oceancache, md->scene->r.cfra); } else { simulate_ocean_modifier(omd); } if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) { dm = generate_ocean_geometry(omd); DM_ensure_normals(dm); } else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) { dm = CDDM_copy(derivedData); } cfra = md->scene->r.cfra; CLAMP(cfra, omd->bakestart, omd->bakeend); cfra -= omd->bakestart; /* shift to 0 based */ num_verts = dm->getNumVerts(dm); num_faces = dm->getNumPolys(dm); mverts = dm->getVertArray(dm); mloops = dm->getLoopArray(dm); /* add vcols before displacement - allows lookup based on position */ if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { int cdlayer = CustomData_number_of_layers(&dm->loopData, CD_MLOOPCOL); if (cdlayer < MAX_MCOL) { MLoopCol *mloopcols = CustomData_add_layer_named(&dm->loopData, CD_MLOOPCOL, CD_CALLOC, NULL, num_faces * 4, omd->foamlayername); if (mloopcols) { /* unlikely to fail */ MLoopCol *mlcol; MPoly *mpolys = dm->getPolyArray(dm); MPoly *mp; float foam; for (i = 0, mp = mpolys; i < num_faces; i++, mp++) { j = mp->totloop - 1; /* highly unlikely */ if (j <= 0) continue; do { const float *co = mverts[mloops[mp->loopstart + j].v].co; const float u = OCEAN_CO(size_co_inv, co[0]); const float v = OCEAN_CO(size_co_inv, co[1]); if (omd->oceancache && omd->cached == TRUE) { BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v); foam = ocr.foam; CLAMP(foam, 0.0f, 1.0f); } else { BKE_ocean_eval_uv(omd->ocean, &ocr, u, v); foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage); } mlcol = &mloopcols[mp->loopstart + j]; mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255); /* This needs to be set (render engine uses) */ mlcol->a = 255; } while (j--); } } } } /* displace the geometry */ /* #pragma omp parallel for private(i, ocr) if (omd->resolution > OMP_MIN_RES) */ for (i = 0, mv = mverts; i < num_verts; i++, mv++) { const float u = OCEAN_CO(size_co_inv, mv->co[0]); const float v = OCEAN_CO(size_co_inv, mv->co[1]); if (omd->oceancache && omd->cached == TRUE) BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v); else BKE_ocean_eval_uv(omd->ocean, &ocr, u, v); mv->co[2] += ocr.disp[1]; if (omd->chop_amount > 0.0f) { mv->co[0] += ocr.disp[0]; mv->co[1] += ocr.disp[2]; } } #undef OCEAN_CO return dm; }
/** Calculate a bounding box for a set of bezier points. * @param pts The bezier points * @param numpoints The number of elements in `pts' * @param extra Extra spacing information. * @param closed True if the bezier points form a closed line. * @param rect Return value: The enclosing rectangle will be stored here. * @bug This function is way too long (214 lines) and should be split. */ void polybezier_bbox(const BezPoint *pts, int numpoints, const PolyBBExtras *extra, gboolean closed, Rectangle *rect) { Point vx,vn,vsc,vp; int i,prev,next; Rectangle rt; PolyBBExtras bextra,start_bextra,end_bextra; LineBBExtras lextra,start_lextra,end_lextra,full_lextra; gboolean start,end; vp.x=0; vp.y=0; g_assert(pts[0].type == BEZ_MOVE_TO); rect->left = rect->right = pts[0].p1.x; rect->top = rect->bottom = pts[0].p1.y; /* First, we build derived BBExtras structures, so we have something to feed the primitives. */ if (!closed) { start_lextra.start_long = extra->start_long; start_lextra.start_trans = MAX(extra->start_trans,extra->middle_trans); start_lextra.end_long = 0; start_lextra.end_trans = extra->middle_trans; end_lextra.start_long = 0; end_lextra.start_trans = extra->middle_trans; end_lextra.end_long = extra->end_long; end_lextra.end_trans = MAX(extra->end_trans,extra->middle_trans); } full_lextra.start_long = extra->start_long; full_lextra.start_trans = MAX(extra->start_trans,extra->middle_trans); full_lextra.end_long = extra->end_long; full_lextra.end_trans = MAX(extra->end_trans,extra->middle_trans); if (!closed) { lextra.start_long = 0; lextra.start_trans = extra->middle_trans; lextra.end_long = 0; lextra.end_trans = extra->middle_trans; start_bextra.start_long = extra->start_long; start_bextra.start_trans = extra->start_trans; start_bextra.middle_trans = extra->middle_trans; start_bextra.end_long = 0; start_bextra.end_trans = extra->middle_trans; end_bextra.start_long = 0; end_bextra.start_trans = extra->middle_trans; end_bextra.middle_trans = extra->middle_trans; end_bextra.end_long = extra->end_long; end_bextra.end_trans = extra->end_trans; } bextra.start_long = 0; bextra.start_trans = extra->middle_trans; bextra.middle_trans = extra->middle_trans; bextra.end_long = 0; bextra.end_trans = extra->middle_trans; for (i=1;i<numpoints;i++) { next = (i+1) % numpoints; prev = (i-1) % numpoints; if (closed && (next == 0)) next=1; if (closed && (prev == 0)) prev=numpoints-1; /* We have now: i = index of current vertex. prev,next: index of previous/next vertices (of the control polygon) We want: vp, vx, vn: the previous, current and next vertices; start, end: TRUE if we're at an end of poly (then, vp and/or vn are not valid, respectively). Some values *will* be recomputed a few times across iterations (but stored in different boxes). Either gprof says it's a real problem, or gcc finally gets a clue. */ if (pts[i].type == BEZ_MOVE_TO) { continue; } switch(pts[i].type) { case BEZ_MOVE_TO: g_assert_not_reached(); break; case BEZ_LINE_TO: point_copy(&vx,&pts[i].p1); switch(pts[prev].type) { case BEZ_MOVE_TO: case BEZ_LINE_TO: point_copy(&vsc,&pts[prev].p1); point_copy(&vp,&pts[prev].p1); break; case BEZ_CURVE_TO: point_copy(&vsc,&pts[prev].p3); point_copy(&vp,&pts[prev].p3); break; } break; case BEZ_CURVE_TO: point_copy(&vx,&pts[i].p3); point_copy(&vp,&pts[i].p2); switch(pts[prev].type) { case BEZ_MOVE_TO: case BEZ_LINE_TO: point_copy(&vsc,&pts[prev].p1); break; case BEZ_CURVE_TO: point_copy(&vsc,&pts[prev].p3); break; } /* vsc is the start of the curve. */ break; } start = (pts[prev].type == BEZ_MOVE_TO); end = (pts[next].type == BEZ_MOVE_TO); point_copy(&vn,&pts[next].p1); /* whichever type pts[next] is. */ /* Now, we know about a few vertices around the one we're dealing with. Depending on the shape of the (previous,current) segment, and whether it's a middle or end segment, we'll be doing different stuff. */ if (closed) { if (pts[i].type == BEZ_LINE_TO) { line_bbox(&vsc,&vx,&full_lextra,&rt); } else { bicubicbezier2D_bbox(&vsc, &pts[i].p1,&pts[i].p2,&pts[i].p3, &bextra, &rt); } } else if (start) { if (pts[i].type == BEZ_LINE_TO) { if (end) { line_bbox(&vsc,&vx,&full_lextra,&rt); } else { line_bbox(&vsc,&vx,&start_lextra,&rt); } } else { /* BEZ_MOVE_TO */ if (end) { bicubicbezier2D_bbox(&vsc, &pts[i].p1,&pts[i].p2,&pts[i].p3, extra, &rt); } else { bicubicbezier2D_bbox(&vsc, &pts[i].p1,&pts[i].p2,&pts[i].p3, &start_bextra, &rt); } } } else if (end) { /* end but not start. Not closed anyway. */ if (pts[i].type == BEZ_LINE_TO) { line_bbox(&vsc,&vx,&end_lextra,&rt); } else { bicubicbezier2D_bbox(&vsc, &pts[i].p1,&pts[i].p2,&pts[i].p3, &end_bextra, &rt); } } else { /* normal case : middle segment (not closed shape). */ if (pts[i].type == BEZ_LINE_TO) { line_bbox(&vsc,&vx,&lextra,&rt); } else { bicubicbezier2D_bbox(&vsc, &pts[i].p1,&pts[i].p2,&pts[i].p3, &bextra, &rt); } } rectangle_union(rect,&rt); /* The following code enlarges a little the bounding box (if necessary) to account with the "pointy corners" X (and PS) add when LINEJOIN_MITER mode is in force. */ if ((!start) && (!end)) { /* We have a non-extremity vertex. */ Point vpx,vxn; real co,alpha; point_copy_add_scaled(&vpx,&vx,&vp,-1); point_normalize(&vpx); point_copy_add_scaled(&vxn,&vn,&vx,-1); point_normalize(&vxn); co = point_dot(&vpx,&vxn); alpha = acos(-co); if (co > -0.9816) { /* 0.9816 = cos(11deg) */ /* we have a pointy join. */ real overshoot; Point vovs,pto; if (finite(alpha)) overshoot = extra->middle_trans / sin(alpha/2.0); else /* prependicular? */ overshoot = extra->middle_trans; point_copy_add_scaled(&vovs,&vpx,&vxn,-1); point_normalize(&vovs); point_copy_add_scaled(&pto,&vx,&vovs,overshoot); rectangle_add_point(rect,&pto); } else { /* we don't have a pointy join. */ Point vpxt,vxnt,tmp; point_get_perp(&vpxt,&vpx); point_get_perp(&vxnt,&vxn); point_copy_add_scaled(&tmp,&vx,&vpxt,1); rectangle_add_point(rect,&tmp); point_copy_add_scaled(&tmp,&vx,&vpxt,-1); rectangle_add_point(rect,&tmp); point_copy_add_scaled(&tmp,&vx,&vxnt,1); rectangle_add_point(rect,&tmp); point_copy_add_scaled(&tmp,&vx,&vxnt,-1); rectangle_add_point(rect,&tmp); } } } }
void Linearizer::process_triangle(int iv0, int iv1, int iv2, int level, scalar* val, double* phx, double* phy, int* idx) { double midval[3][3]; if (level < LIN_MAX_LEVEL) { int i; if (!(level & 1)) { // obtain solution values sln->set_quad_order(1, item); val = sln->get_values(ia, ib); if (auto_max) for (i = 0; i < lin_np_tri[1]; i++) { double v = getval(i); if (finite(v) && fabs(v) > max) max = fabs(v); } // obtain physical element coordinates if (curved || disp) { RefMap* refmap = sln->get_refmap(); phx = refmap->get_phys_x(1); phy = refmap->get_phys_y(1); if (disp) { xdisp->force_transform(sln); ydisp->force_transform(sln); xdisp->set_quad_order(1, FN_VAL); ydisp->set_quad_order(1, FN_VAL); scalar* dx = xdisp->get_fn_values(); scalar* dy = ydisp->get_fn_values(); for (i = 0; i < lin_np_tri[1]; i++) { phx[i] += dmult*realpart(dx[i]); phy[i] += dmult*realpart(dy[i]); } } } idx = tri_indices[0]; } // obtain linearized values and coordinates at the midpoints for (i = 0; i < 3; i++) { midval[i][0] = (verts[iv0][i] + verts[iv1][i])*0.5; midval[i][1] = (verts[iv1][i] + verts[iv2][i])*0.5; midval[i][2] = (verts[iv2][i] + verts[iv0][i])*0.5; }; // determine whether or not to split the element bool split; if (eps >= 1.0) { // if eps > 1, the user wants a fixed number of refinements (no adaptivity) split = (level < eps); } else { if (!auto_max && fabs(verts[iv0][2]) > max && fabs(verts[iv1][2]) > max && fabs(verts[iv2][2]) > max) { // do not split if the whole triangle is above the specified maximum value split = false; } else { // calculate the approximate error of linearizing the normalized solution double err = fabs(getval(idx[0]) - midval[2][0]) + fabs(getval(idx[1]) - midval[2][1]) + fabs(getval(idx[2]) - midval[2][2]); split = !finite(err) || err > max*3*eps; } // do the same for the curvature if (!split && (curved || disp)) { for (i = 0; i < 3; i++) if (sqr(phx[idx[i]] - midval[0][i]) + sqr(phy[idx[i]] - midval[1][i]) > sqr(cmax*1.5e-3)) { split = true; break; } } // do extra tests at level 0, so as not to miss some functions with zero error at edge midpoints if (level == 0 && !split) { split = (fabs(getval(8) - 0.5*(midval[2][0] + midval[2][1])) + fabs(getval(9) - 0.5*(midval[2][1] + midval[2][2])) + fabs(getval(4) - 0.5*(midval[2][2] + midval[2][0]))) > max*3*eps; } } // split the triangle if the error is too large, otherwise produce a linear triangle if (split) { if (curved || disp) for (i = 0; i < 3; i++) { midval[0][i] = phx[idx[i]]; midval[1][i] = phy[idx[i]]; } // obtain mid-edge vertices int mid0 = get_vertex(iv0, iv1, midval[0][0], midval[1][0], getval(idx[0])); int mid1 = get_vertex(iv1, iv2, midval[0][1], midval[1][1], getval(idx[1])); int mid2 = get_vertex(iv2, iv0, midval[0][2], midval[1][2], getval(idx[2])); // recur to sub-elements sln->push_transform(0); process_triangle(iv0, mid0, mid2, level+1, val, phx, phy, tri_indices[1]); sln->pop_transform(); sln->push_transform(1); process_triangle(mid0, iv1, mid1, level+1, val, phx, phy, tri_indices[2]); sln->pop_transform(); sln->push_transform(2); process_triangle(mid2, mid1, iv2, level+1, val, phx, phy, tri_indices[3]); sln->pop_transform(); sln->push_transform(3); process_triangle(mid1, mid2, mid0, level+1, val, phx, phy, tri_indices[4]); sln->pop_transform(); return; } } // no splitting: output a linear triangle add_triangle(iv0, iv1, iv2); }
int Port::isFinite(double r) { return finite(r); }
void Linearizer::process_solution(MeshFunction* sln, int item, double eps, double max_abs, MeshFunction* xdisp, MeshFunction* ydisp, double dmult) { lock_data(); begin_time(); // initialization this->sln = sln; this->item = item; this->eps = eps; this->xdisp = xdisp; this->ydisp = ydisp; this->dmult = dmult; nv = nt = ne = 0; del_slot = -1; if (!item) error("'item' cannot be zero."); get_gv_a_b(item, ia, ib); if (ib >= 6) error("Invalid 'item'."); disp = (xdisp != NULL || ydisp != NULL); if (disp && (xdisp == NULL || ydisp == NULL)) error("Both displacement components must be supplied."); // estimate the required number of vertices and triangles Mesh* mesh = sln->get_mesh(); int nn = mesh->get_num_elements(); int ev = std::max(32 * nn, 10000); // todo: check this int et = std::max(64 * nn, 20000); int ee = std::max(24 * nn, 7500); // check that displacement meshes are the same if (disp) { unsigned seq1 = mesh->get_seq(); unsigned seq2 = xdisp->get_mesh()->get_seq(); unsigned seq3 = ydisp->get_mesh()->get_seq(); if (seq1 != seq2 || seq1 != seq3) error("Displacements must be defined on the same mesh as the solution."); } // reuse or allocate vertex, triangle and edge arrays lin_init_array(verts, double3, cv, ev); lin_init_array(tris, int3, ct, et); lin_init_array(edges, int3, ce, ee); info = (int4*) malloc(sizeof(int4) * cv); // initialize the hash table int size = 0x2000; while (size*2 < cv) size *= 2; hash_table = (int*) malloc(sizeof(int) * size); memset(hash_table, 0xff, sizeof(int) * size); mask = size-1; // select the linearization quadrature Quad2D *old_quad, *old_quad_x, *old_quad_y; old_quad = sln->get_quad_2d(); sln->set_quad_2d(&quad_lin); if (disp) { old_quad_x = xdisp->get_quad_2d(); old_quad_y = ydisp->get_quad_2d(); xdisp->set_quad_2d(&quad_lin); ydisp->set_quad_2d(&quad_lin); } // create all top-level vertices (corresponding to vertex nodes), with // all parent-son relations preserved; this is necessary for regularization to // work on irregular meshes nn = mesh->get_max_node_id(); int* id2id = new int[nn]; memset(id2id, 0xff, sizeof(int) * nn); bool finished; do { finished = true; Node* node; for_all_vertex_nodes(node, mesh) { if (id2id[node->id] < 0 && node->ref != TOP_LEVEL_REF) if (node->p1 < 0) id2id[node->id] = get_vertex(node->id, node->id, node->x, node->y, 0); else if (id2id[node->p1] >= 0 && id2id[node->p2] >= 0) id2id[node->id] = get_vertex(id2id[node->p1], id2id[node->p2], node->x, node->y, 0); else finished = false; } } while (!finished); auto_max = (max_abs < 0.0); max = auto_max ? 0.0 : max_abs; // obtain the solution in vertices, estimate the maximum solution value Element* e; for_all_active_elements(e, mesh) { sln->set_active_element(e); sln->set_quad_order(0, item); scalar* val = sln->get_values(ia, ib); if (val == NULL) error("item not defined in the solution."); scalar *dx, *dy; if (disp) { xdisp->set_active_element(e); ydisp->set_active_element(e); xdisp->set_quad_order(0, FN_VAL); ydisp->set_quad_order(0, FN_VAL); dx = xdisp->get_fn_values(); dy = ydisp->get_fn_values(); } for (unsigned int i = 0; i < e->nvert; i++) { double f = getval(i); if (auto_max && finite(f) && fabs(f) > max) max = fabs(f); int id = id2id[e->vn[i]->id]; verts[id][2] = f; if (disp) { verts[id][0] = e->vn[i]->x + dmult*realpart(dx[i]); verts[id][1] = e->vn[i]->y + dmult*realpart(dy[i]); } } }
void Vector::internalUpdate() { int i, i0; double sum, sum2, last, first, v; double last_v; double dv2 = 0.0, dv, no_spike_max_dv; _max = _min = sum = sum2 = _minPos = last = first = NOPOINT; _nsum = 0; if (_size > 0) { _is_rising = true; // Look for a valid (finite) point... for (i = 0; i < _size && !finite(_v[i]); i++) { // do nothing } if (i == _size) { // there were no finite points: if (!_isScalarList) { _scalars["sum"]->setValue(sum); _scalars["sumsquared"]->setValue(sum2); _scalars["max"]->setValue(_max); _scalars["min"]->setValue(_min); _scalars["minpos"]->setValue(_minPos); _scalars["last"]->setValue(last); _scalars["first"]->setValue(first); } _ns_max = _ns_min = 0; updateScalars(); return; } i0 = i; if (i0 > 0) { _is_rising = false; } _max = _min = _v[i0]; sum = sum2 = 0.0; if (_v[i0] > 0.0) { _minPos = _v[i0]; } else { _minPos = 1.0E300; } last_v = _v[i0]; for (i = i0; i < _size; i++) { v = _v[i]; // get rid of redirections if (finite(v)) { dv = v - last_v; dv2 += dv*dv; if (v <= last_v) { if (i != i0) { _is_rising = false; } } last_v = v; _nsum++; sum += v; sum2 += v*v; if (v > _max) { _max = v; } else if (v < _min) { _min = v; } if (v < _minPos && v > 0.0) { _minPos = v; } } else { _is_rising = false; } } no_spike_max_dv = 7.0*sqrt(dv2/double(_nsum)); _ns_max = _ns_min = last_v = _v[i0]; last = _v[_size-1]; first = _v[0]; for (i = i0; i < _size; i++) { v = _v[i]; // get rid of redirections if (finite(v)) { if (fabs(v - last_v) < no_spike_max_dv) { if (v > _ns_max) { _ns_max = v; } else if (v < _ns_min) { _ns_min = v; } last_v = v; } else { i += 20; if (i < _size) { last_v = _v[i]; } i++; } } } if (_isScalarList) { _max = _min = _minPos = 0.0; } else { _scalars["sum"]->setValue(sum); _scalars["sumsquared"]->setValue(sum2); _scalars["max"]->setValue(_max); _scalars["min"]->setValue(_min); _scalars["minpos"]->setValue(_minPos); _scalars["last"]->setValue(last); _scalars["first"]->setValue(first); } updateScalars(); } }
void common_options(int ch) { switch(ch) { case 'a': options |= F_AUDIBLE; break; case 'A': options |= F_ADAPTIVE; break; case 'c': npackets = atoi(optarg); if (npackets <= 0) { fprintf(stderr, "ping: bad number of packets to transmit.\n"); exit(2); } break; case 'd': options |= F_SO_DEBUG; break; case 'D': options |= F_PTIMEOFDAY; break; case 'i': /* wait between sending packets */ { double dbl; char *ep; errno = 0; dbl = strtod(optarg, &ep); if (errno || *ep != '\0' || !finite(dbl) || dbl < 0.0 || dbl >= (double)INT_MAX / 1000 - 1.0) { fprintf(stderr, "ping: bad timing interval\n"); exit(2); } interval = (int)(dbl * 1000); options |= F_INTERVAL; break; } case 'm': { char *endp; mark = (int)strtoul(optarg, &endp, 10); if (mark < 0 || *endp != '\0') { fprintf(stderr, "mark cannot be negative\n"); exit(2); } options |= F_MARK; break; } case 'w': deadline = atoi(optarg); if (deadline < 0) { fprintf(stderr, "ping: bad wait time.\n"); exit(2); } break; case 'l': preload = atoi(optarg); if (preload <= 0) { fprintf(stderr, "ping: bad preload value, should be 1..%d\n", MAX_DUP_CHK); exit(2); } if (preload > MAX_DUP_CHK) preload = MAX_DUP_CHK; if (uid && preload > 3) { fprintf(stderr, "ping: cannot set preload to value > 3\n"); exit(2); } break; case 'O': options |= F_OUTSTANDING; break; case 'S': sndbuf = atoi(optarg); if (sndbuf <= 0) { fprintf(stderr, "ping: bad sndbuf value.\n"); exit(2); } break; case 'f': options |= F_FLOOD; setbuf(stdout, (char *)NULL); /* fallthrough to numeric - avoid gethostbyaddr during flood */ case 'n': options |= F_NUMERIC; break; case 'p': /* fill buffer with user pattern */ options |= F_PINGFILLED; fill(optarg); break; case 'q': options |= F_QUIET; break; case 'r': options |= F_SO_DONTROUTE; break; case 's': /* size of packet to send */ datalen = atoi(optarg); if (datalen < 0) { fprintf(stderr, "ping: illegal negative packet size %d.\n", datalen); exit(2); } if (datalen > maxpacket - 8) { fprintf(stderr, "ping: packet size too large: %d\n", datalen); exit(2); } break; case 'v': options |= F_VERBOSE; break; case 'L': options |= F_NOLOOP; break; case 't': options |= F_TTL; ttl = atoi(optarg); if (ttl < 0 || ttl > 255) { fprintf(stderr, "ping: ttl %u out of range\n", ttl); exit(2); } break; case 'U': options |= F_LATENCY; break; case 'B': options |= F_STRICTSOURCE; break; case 'W': lingertime = atoi(optarg); if (lingertime < 0 || lingertime > INT_MAX/1000000) { fprintf(stderr, "ping: bad linger time.\n"); exit(2); } lingertime *= 1000; break; case 'V': printf("ping utility, iputils-%s\n", SNAPSHOT); exit(0); default: abort(); } }
static DataType collator_is_numeric(UChar *str, int length, int64_t *lval, double *dval, int allow_errors ) { int64_t local_lval; double local_dval; UChar *end_ptr_long, *end_ptr_double; int conv_base=10; if (!length) { return KindOfNull; } /* handle hex numbers */ if (length>=2 && str[0]=='0' && (str[1]=='x' || str[1]=='X')) { conv_base=16; } errno=0; local_lval = collator_u_strtol(str, &end_ptr_long, conv_base); if (errno != ERANGE) { if (end_ptr_long == str+length) { /* integer string */ if (lval) { *lval = local_lval; } return KindOfInt64; } else if (end_ptr_long == str && *end_ptr_long != '\0' && *str != '.' && *str != '-') { /* ignore partial string matches */ return KindOfNull; } } else { end_ptr_long = nullptr; } if (conv_base == 16) { /* hex string, under UNIX strtod() messes it up */ /* UTODO: keep compatibility with is_numeric_string() here? */ return KindOfNull; } local_dval = collator_u_strtod(str, &end_ptr_double); if (local_dval == 0 && end_ptr_double == str) { end_ptr_double = nullptr; } else { if (end_ptr_double == str+length) { /* floating point string */ if (!finite(local_dval)) { /* "inf","nan" and maybe other weird ones */ return KindOfNull; } if (dval) { *dval = local_dval; } return KindOfDouble; } } if (!allow_errors) { return KindOfNull; } if (allow_errors == -1) { raise_notice("A non well formed numeric value encountered"); } if (allow_errors) { if (end_ptr_double > end_ptr_long && dval) { *dval = local_dval; return KindOfDouble; } else if (end_ptr_long && lval) { *lval = local_lval; return KindOfInt64; } } return KindOfNull; }
int main(int argc, char *argv[]) { char **av, fname[STRLEN] ; int ac, nargs, i ; MRI *mri_flash[MAX_IMAGES], *mri_T1, *mri_PD ; char *in_fname, *out_PD_fname, *out_T1_fname ; int msec, minutes, seconds, nvolumes ; struct timeb start ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_estimate_tissue_parms.c,v 1.9 2011/03/02 00:04:15 nicks Exp $", "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; TimerStart(&start) ; parms.dt = 1e-6 ; parms.tol = 1e-5 ; parms.momentum = 0.0 ; parms.niterations = 20 ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (argc < 4) usage_exit(1) ; out_T1_fname = argv[argc-2] ; out_PD_fname = argv[argc-1] ; FileNameOnly(out_T1_fname, fname) ; FileNameRemoveExtension(fname, fname) ; strcpy(parms.base_name, fname) ; nvolumes = 0 ; for (i = 1 ; i < argc-2 ; i++) { if (argv[i][0] == '-') { if (!stricmp(argv[i]+1, "te")) te = atof(argv[i+1]) ; else if (!stricmp(argv[i]+1, "tr")) tr = atof(argv[i+1]) ; else if (!stricmp(argv[i]+1, "fa")) fa = RADIANS(atof(argv[i+1])) ; else ErrorExit(ERROR_BADPARM, "%s: unsupported MR parameter %s", Progname, argv[i]+1) ; i++ ; /* skip parameter */ continue ; } in_fname = argv[i] ; printf("reading %s...", in_fname) ; mri_flash[nvolumes] = MRIread(in_fname) ; if (!mri_flash[nvolumes]) ErrorExit(Gerror, "%s: MRIread(%s) failed", Progname, in_fname) ; if (tr > 0) { mri_flash[nvolumes]->tr = tr ; tr = 0 ; } if (te > 0) { mri_flash[nvolumes]->te = te ; te = 0 ; } if (fa > 0) { mri_flash[nvolumes]->flip_angle = fa ; fa = 0 ; } printf("TE = %2.2f, TR = %2.2f, alpha = %2.2f\n", mri_flash[nvolumes]->te, mri_flash[nvolumes]->tr, DEGREES(mri_flash[nvolumes]->flip_angle)) ; mri_flash[nvolumes]->flip_angle = mri_flash[nvolumes]->flip_angle; if (conform) { MRI *mri_tmp ; printf("embedding and interpolating volume\n") ; mri_tmp = MRIconform(mri_flash[nvolumes]) ; /* MRIfree(&mri_src) ;*/ mri_flash[nvolumes] = mri_tmp ; } if (FZERO(mri_flash[nvolumes]->tr) || FZERO(mri_flash[nvolumes]->flip_angle)) ErrorExit(ERROR_BADPARM, "%s: invalid TR or FA for image %d:%s", Progname, nvolumes, in_fname) ; nvolumes++ ; } printf("using %d FLASH volumes to estimate tissue parameters.\n", nvolumes) ; mri_T1 = MRIclone(mri_flash[0], NULL) ; mri_PD = MRIclone(mri_flash[0], NULL) ; { double sse, last_T1, last_PD, total_rms, avg_rms ; int x, y, z, width, height, depth, total_vox, ignored, nvox ; struct timeb first_slice ; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; TimerStart(&first_slice) ; last_T1 = last_PD = 1000 ; sse = 0.0 ; width = mri_T1->width ; height = mri_T1->height ; depth = mri_T1->depth ; total_vox = width*depth*height ; #if 0 estimateVoxelParameters(mri_flash, nvolumes, width/2, height/2, depth/2, mri_T1, mri_PD, last_T1, last_PD) ; #endif if (Gdiag_no == 999) { x = 130 ; y = 124 ; z = 74 ; /* CSF */ computeErrorSurface("error_surf_csf.dat",mri_flash,nvolumes,x,y,z,500,3000,500,3000); x = 161 ; y = 157 ; z = 63 ; /* wm */ computeErrorSurface("error_surf_wm.dat",mri_flash,nvolumes,x,y,z,250,3000,250,3000); x = 166 ; y = 153 ; z = 63 ; /* gm */ computeErrorSurface("error_surf_gm.dat",mri_flash,nvolumes,x,y,z,250,3000,250,3000); } avg_rms = 0 ; for (ignored = z = 0 ; z < depth ; z++) { if (z > 0) printf("z = %d, avg rms=%2.1f, T1=%2.0f, PD=%2.0f...\n", z, avg_rms, last_T1, last_PD) ; #if 0 if (z > 0 && z*width*height - ignored > 0) { int processed = z*width*height - ignored, hours ; msec = TimerStop(&first_slice) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; hours = minutes / 60 ; minutes = minutes % 60 ; printf("%02d:%02d:%02d total processing time ... ", hours,minutes,seconds); msec = (int)((float)(total_vox-ignored)*msec/(float)processed) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; hours = minutes / 60 ; minutes = minutes % 60 ; printf("estimate %02d:%02d:%02d remaining.\n", hours,minutes, seconds); } #endif if (write_iterations > 0 && z > 0 && !(z%write_iterations)) { printf("writing T1 esimates to %s...\n", out_T1_fname) ; printf("writing PD estimates to %s...\n", out_PD_fname) ; MRIwrite(mri_T1, out_T1_fname) ; MRIwrite(mri_PD, out_PD_fname) ; printf("writing residuals to %s...\n", residual_name) ; if (residual_name) { MRI *mri_res, *mri_res_total = NULL ; for (i = 0 ; i < nvolumes ; i++) { mri_res = compute_residuals(mri_flash[i], mri_T1, mri_PD) ; sprintf(fname, "%s%d.mgh", residual_name, i) ; #if 0 MRIwrite(mri_res, fname) ; #endif if (!mri_res_total) { mri_res_total = MRIcopy(mri_res, NULL) ; } else { MRIsadd(mri_res, mri_res_total, mri_res_total) ; } MRIfree(&mri_res) ; } MRIsscalarMul(mri_res_total, mri_res_total, 1.0/(float)nvolumes) ; MRIssqrt(mri_res_total, mri_res_total) ; sprintf(fname, "%s.mgh", residual_name) ; MRIwrite(mri_res_total, fname) ; } } nvox = 0 ; total_rms = 0 ; for (y = 0 ; y < height ; y++) { #if 0 if (y%32 == 0 && nvox > 0) printf("z = %d, y = %d, avg rms=%2.1f, T1=%2.0f, PD=%2.0f...\n", z, y, total_rms/(double)nvox, last_T1, last_PD) ; #endif for (x = 0 ; x < width ; x++) { #if 0 for (i = 0 ; i < nvolumes ; i++) if (MRISvox(mri_flash[i],x,y,z) > thresh) break ; if (i >= nvolumes) #else if (no_valid_data(mri_flash, nvolumes, x, y, z, thresh)) #endif { ignored++ ; MRISvox(mri_T1, x, y, z) = MRISvox(mri_PD, x, y, z) = 0 ; /* last_T1 = last_PD = 1000 ;*/ continue ; } #if 0 sse = findInitialParameters(mri_flash, nvolumes, x, y, z, last_PD-1000, last_PD+1000, last_T1-1000, last_T1+1000, &last_PD, &last_T1, 10) ; #endif #if 0 sse = findInitialParameters(mri_flash, nvolumes, x, y, z, last_PD-100, last_PD+100, last_T1-100, last_T1+100, &last_PD, &last_T1, 10) ; if (last_T1 <= MIN_T1 || last_PD <= 0) { ignored++ ; MRISvox(mri_T1, x, y, z) = MRISvox(mri_PD, x, y, z) = 0 ; /* last_T1 = last_PD = 1000 ;*/ continue ; } #endif sse = estimateVoxelParameters(mri_flash, nvolumes, x, y, z, mri_T1, mri_PD, nsteps) ; nvox++ ; last_T1 = MRISvox(mri_T1, x, y, z) ; last_PD = MRISvox(mri_PD, x, y, z) ; total_rms += sqrt(sse/nvolumes) ; if (!finite(total_rms)) DiagBreak() ; } } avg_rms = total_rms / nvox ; if (!finite(avg_rms)) DiagBreak() ; } } printf("writing T1 esimates to %s...\n", out_T1_fname) ; printf("writing PD estimates to %s...\n", out_PD_fname) ; MRIwrite(mri_T1, out_T1_fname) ; MRIwrite(mri_PD, out_PD_fname) ; if (residual_name) { MRI *mri_res_total = NULL ; for (i = 0 ; i < nvolumes ; i++) { MRI *mri_res ; mri_res = compute_residuals(mri_flash[i], mri_T1, mri_PD) ; #if 0 sprintf(fname, "%s%d.mgh", residual_name, i) ; MRIwrite(mri_res, fname) ; #endif if (!mri_res_total) { mri_res_total = MRIcopy(mri_res, NULL) ; } else { MRIsadd(mri_res, mri_res_total, mri_res_total) ; } MRIfree(&mri_res) ; } MRIsscalarMul(mri_res_total, mri_res_total, 1.0/(float)nvolumes) ; MRIssqrt(mri_res_total, mri_res_total) ; sprintf(fname, "%s.mgh", residual_name) ; MRIwrite(mri_res_total, fname) ; } MRIfree(&mri_T1) ; MRIfree(&mri_PD) ; msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf("parameter estimation took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }
Float lnn_sentence_stats(sentence_type *s, const lnn_weights_type* wt, size_t nhidden, size_t nfeatures, Float score0[], Float score1[], const lnn_weights_type* dL_dwt, Float *sum_g, Float *sum_p, Float *sum_w) { Float max_correct_score, max_score; int i, j, k; Float Z = 0, logZ, Ecorrect_score = 0; size_t best_i = lnn_sentence_scores(s, wt, nhidden, nfeatures, score0, score1, &max_correct_score, &max_score); *sum_g += s->g; *sum_p += s->parse[best_i].p; *sum_w += s->parse[best_i].w; if (s->Px == 0) /* skip statistics calculation if Px == 0 */ return 0; assert(max_correct_score <= max_score); for (i = 0; i < s->nparses; ++i) { /* compute Z and Zw */ assert(score1[i] <= max_score); Z += exp(score1[i] - max_score); assert(finite(Z)); if (s->parse[i].Pyx > 0) Ecorrect_score += s->parse[i].Pyx * score1[i]; } logZ = log(Z) + max_score; /* calculate expectations */ for (i = 0; i < s->nparses; ++i) { Float cp = exp(score1[i] - logZ); /* P_w(y|x) */ assert(finite(cp)); if (s->parse[i].Pyx > 0) /* P_e(y|x) */ cp -= s->parse[i].Pyx; assert(cp >= -1.0); assert(cp <= 1.0); cp *= s->Px; /* multiply in weight of sentence */ /* calculate derivatives */ for (j = 0; j < nhidden; ++j) { Float g = score0[i*nhidden+j]; Float dg_dx = 1 - g*g; /* for tanh activation function */ Float backward = cp * wt->w1[j] * dg_dx; dL_dwt->w1[j] += cp * score0[i*nhidden+j]; dL_dwt->b0[j] += backward; for (k = 0; k < s->parse[i].nf; ++k) /* features with 1 count */ dL_dwt->w0[j*nfeatures+s->parse[i].f[k]] += backward; for (k = 0; k < s->parse[i].nfc; ++k) /* features with arbitrary counts */ dL_dwt->w0[j*nfeatures+s->parse[i].fc[k].f] += backward * s->parse[i].fc[k].c; } } return - s->Px * (Ecorrect_score - logZ); } /* lnn_sentence_stats() */
/************************************************************ general_newton_raphson(): -- performs Newton-Rapshon method on an arbitrary system. -- inspired in part by Num. Rec.'s routine newt(); Arguements: -- x[] = set of independent variables to solve for; -- n = number of independent variables and residuals; -- funcd = name of function that calculates residuals, etc.; *****************************************************************/ static int general_newton_raphson( FTYPE x[], int n, void (*funcd) (FTYPE [], FTYPE [], FTYPE [], FTYPE [][NEWT_DIM], FTYPE *, FTYPE *, int) ) { FTYPE f, df, dx[NEWT_DIM], x_old[NEWT_DIM], resid[NEWT_DIM], jac[NEWT_DIM][NEWT_DIM]; FTYPE errx, x_orig[NEWT_DIM]; int n_iter, id, jd, i_extra, doing_extra; FTYPE dW,dvsq,vsq_old,vsq,W,W_old, rho,p,u; int keep_iterating; // Initialize various parameters and variables: errx = 1. ; df = f = 1.; i_extra = doing_extra = 0; for( id = 0; id < n ; id++) x_old[id] = x_orig[id] = x[id] ; vsq_old = vsq = W = W_old = 0.; n_iter = 0; /* Start the Newton-Raphson iterations : */ keep_iterating = 1; while( keep_iterating ) { (*funcd) (x, dx, resid, jac, &f, &df, n); /* returns with new dx, f, df */ /* Save old values before calculating the new: */ errx = 0.; for( id = 0; id < n ; id++) { x_old[id] = x[id] ; } for( id = 0; id < n ; id++) { x[id] += dx[id] ; } /****************************************/ /* Make sure that the new x[] is physical : */ /****************************************/ // METHOD specific validate_x( x, x_old ); /****************************************/ /* Calculate the convergence criterion */ /****************************************/ /* For the new criterion, always look at error in "W" : */ // METHOD specific W_old = W; W = W_of_vsq( x[0], &p, &rho, &u); errx = (W==0.) ? fabs(W-W_old) : fabs((W-W_old)/W); errx += (x[0]==0.) ? fabs(x[0]-x_old[0]) : fabs((x[0]-x_old[0])/x[0]); // fprintf(stderr,"NR: %26.20e %26.20e %26.20e %26.20e %26.20e \n", x_old[0], x[0], resid[0], jac[0][0], errx); // fflush(stderr); /*****************************************************************************/ /* If we've reached the tolerance level, then just do a few extra iterations */ /* before stopping */ /*****************************************************************************/ if( (fabs(errx) <= NEWT_TOL) && (doing_extra == 0) && (EXTRA_NEWT_ITER > 0) ) { doing_extra = 1; } if( doing_extra == 1 ) i_extra++ ; // See if we've done the extra iterations, or have done too many iterations: if( ((fabs(errx) <= NEWT_TOL)&&(doing_extra == 0)) || (i_extra > EXTRA_NEWT_ITER) || (n_iter >= (MAX_NEWT_ITER-1)) ) { keep_iterating = 0; } n_iter++; } // END of while(keep_iterating) /* Check for bad untrapped divergences : */ if( (finite(f)==0) || (finite(df)==0) ) { return(2); } // Return in different ways depending on whether a solution was found: if( fabs(errx) > MIN_NEWT_TOL){ #if(LTRACE) fprintf(stderr," totalcount = %d 0 %d %26.20e \n",n_iter,i_extra,errx); fflush(stderr); #endif return(1); } if( (fabs(errx) <= MIN_NEWT_TOL) && (fabs(errx) > NEWT_TOL) ){ //fprintf(stderr," totalcount = %d 1 %d %26.20e \n",n_iter,i_extra,errx); fflush(stderr); return(0); } if( fabs(errx) <= NEWT_TOL ){ //fprintf(stderr," totalcount = %d 2 %d %26.20e \n",n_iter,i_extra,errx); fflush(stderr); return(0); } return(0); }
int isfinite(double x) { return finite(x) && !isnan(x); }