Changeset 5624 for trunk/psLib/src/math/psMinimize.c
- Timestamp:
- Nov 29, 2005, 4:00:11 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psMinimize.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psMinimize.c
r5530 r5624 10 10 * @author EAM, IfA 11 11 * 12 * @version $Revision: 1.14 5$ $Name: not supported by cvs2svn $13 * @date $Date: 2005-11- 16 23:06:19 $12 * @version $Revision: 1.146 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-11-30 02:00:09 $ 14 14 * 15 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 1441 1441 } 1442 1442 1443 // here is the definition for BuildSums4D. ifdef'ed away until it is used 1444 // by psPolynomial4DFit.. 1445 # if (0) 1446 /****************************************************************************** 1447 BuildSums4D(sums, x, y, z, t, nXterm, nYterm, nZterm, nTterm). equiv to 1448 BuildSums2D(). The result is returned as a double **** 1449 *****************************************************************************/ 1450 static double ****BuildSums4D( 1451 psF64 ****sums, 1452 psF64 x, 1453 psF64 y, 1454 psF64 z, 1455 psF64 t, 1456 psS32 nXterm, 1457 psS32 nYterm, 1458 psS32 nZterm, 1459 psS32 nTterm) 1460 { 1461 psS32 nXsum = 0; 1462 psS32 nYsum = 0; 1463 psS32 nZsum = 0; 1464 psS32 nTsum = 0; 1465 psF64 xSum = 1.0; 1466 psF64 ySum = 1.0; 1467 psF64 zSum = 1.0; 1468 psF64 tSum = 1.0; 1469 1470 nXsum = 2*nXterm; 1471 nYsum = 2*nYterm; 1472 nZsum = 2*nZterm; 1473 nTsum = 2*nTterm; 1474 if (sums == NULL) { 1475 sums = (psF64 ****) psAlloc (nXsum*sizeof(psF64)); 1476 for (int i = 0; i < nXsum; i++) { 1477 sums[i] = (psF64 ***) psAlloc (nYsum*sizeof(psF64)); 1478 for (int j = 0; j < nYsum; j++) { 1479 sums[i][j] = (psF64 **) psAlloc (nZsum*sizeof(psF64)); 1480 for (int k = 0; k < nZsum; k++) { 1481 sums[i][j][k] = (psF64 *) psAlloc (nTsum*sizeof(psF64)); 1482 } 1483 } 1484 } 1485 } 1486 // careful with this function: there is no size checking and realloc for reuse 1487 1488 tSum = 1.0; 1489 for (int m = 0; m < nTsum; m++) { 1490 zSum = tSum; 1491 for (int k = 0; k < nZsum; k++) { 1492 ySum = zSum; 1493 for (int j = 0; j < nYsum; j++) { 1494 xSum = ySum; 1495 for (int i = 0; i < nXsum; i++) { 1496 sums[i][j][k][m] = xSum; 1497 xSum *= x; 1498 } 1499 ySum *= y; 1500 } 1501 zSum *= z; 1502 } 1503 tSum *= t; 1504 } 1505 return (sums); 1506 } 1507 # endif /* BuildSums4D */ 1443 1508 1444 1509 /****************************************************************************** … … 1447 1512 in the output vector. This routine works on single-precision polynomials with 1448 1513 double precision data. 1514 1515 XXX EAM : this function is now deprecated: psPolynomial2DEvalVector handles F32 and F64 1449 1516 *****************************************************************************/ 1450 1517 psVector *Polynomial2DEvalVectorD( … … 1658 1725 // xSums look like: 1, x, x^2, ... x^(2n+1) 1659 1726 // Build the B and A data structs. 1727 // XXX EAM : use temp pointers eg vB = B->data.F64 to save redirects 1728 // XXX EAM : this function is only valid for data vectors of F64 1660 1729 for (int k = 0; k < f->n; k++) { 1661 if ((mask != NULL) && mask->data.U8[k])1730 if ((mask != NULL) && (mask->data.U8[k] && maskValue)) { 1662 1731 continue; 1732 } 1663 1733 if (x != NULL) { 1664 1734 xSums = BuildSums1D(xSums, x->data.F64[k], nTerm); … … 1670 1740 wt = 1.0; 1671 1741 } else { 1672 // this should filterfErr == 0 values1673 wt = 1.0 / PS_SQR(fErr->data.F64[k]);1742 // this filters fErr == 0 values 1743 wt = (fErr->data.F64[k] == 0) ? 0.0 : 1.0 / PS_SQR(fErr->data.F64[k]); 1674 1744 } 1675 1745 for (int i = 0; i < nTerm; i++) { … … 1686 1756 } 1687 1757 1688 // GaussJordan version 1689 if (0) { 1690 // does the solution in place 1691 psGaussJordan (A, B); 1692 1693 // the first nTerm entries in B correspond directly to the desired 1694 // polynomial coefficients. this is only true for the 1D case 1695 for (int k = 0; k < nTerm; k++) { 1696 myPoly->coeff[k] = B->data.F64[k]; 1697 } 1698 } else { 1699 // LUD version of the fit 1700 psImage *ALUD = NULL; 1701 psVector* outPerm = NULL; 1702 psVector* coeffs = NULL; 1703 1704 ALUD = psImageAlloc(nTerm, nTerm, PS_TYPE_F64); 1705 ALUD = psMatrixLUD(ALUD, &outPerm, A); 1706 coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm); 1707 for (int k = 0; k < nTerm; k++) { 1708 myPoly->coeff[k] = coeffs->data.F64[k]; 1709 } 1710 psFree(ALUD); 1711 psFree(coeffs); 1712 psFree(outPerm); 1758 // does the solution in place 1759 psGaussJordan (A, B); 1760 1761 // the first nTerm entries in B correspond directly to the desired 1762 // polynomial coefficients. this is only true for the 1D case 1763 for (int k = 0; k < nTerm; k++) { 1764 myPoly->coeff[k] = B->data.F64[k]; 1713 1765 } 1714 1766 … … 1819 1871 } 1820 1872 1821 1873 // This function accepts F32 and F64 input vectors. 1822 1874 psPolynomial1D *psVectorClipFitPolynomial1D( 1823 1875 psPolynomial1D *poly, … … 1827 1879 const psVector *f, 1828 1880 const psVector *fErr, 1829 const psVector *x )1881 const psVector *xIn) 1830 1882 { 1831 1883 // Internal pointers for possibly NULL vectors. 1832 psVector *x 32= NULL;1884 psVector *x = NULL; 1833 1885 1834 1886 PS_ASSERT_POLY_NON_NULL(poly, NULL); … … 1836 1888 PS_ASSERT_PTR_NON_NULL(stats, NULL); 1837 1889 PS_ASSERT_VECTOR_NON_NULL(f, NULL); 1838 PS_ASSERT_VECTOR_TYPE (f, PS_TYPE_F32, NULL);1890 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(f, NULL); 1839 1891 if (mask != NULL) { 1840 1892 PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL); 1841 1893 PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL); 1842 1894 } 1843 if (x != NULL) {1844 PS_ASSERT_VECTORS_SIZE_EQUAL(f, x , NULL);1845 PS_ASSERT_VECTOR_TYPE (x, PS_TYPE_F32, NULL);1895 if (xIn != NULL) { 1896 PS_ASSERT_VECTORS_SIZE_EQUAL(f, xIn, NULL); 1897 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(xIn, NULL); 1846 1898 } 1847 1899 if (fErr != NULL) { 1848 1900 PS_ASSERT_VECTORS_SIZE_EQUAL(f, fErr, NULL); 1849 PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL); 1850 } 1851 1852 psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented. Returning NULL.\n"); 1901 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(fErr, NULL); 1902 } 1903 1904 // assign sequence vector if xIn is NULL 1905 if (xIn == NULL) { 1906 x = psVectorCreate (NULL, 0, f->n, 1, f->type.type); 1907 } else { 1908 x = (psVector *) xIn; 1909 } 1910 1911 // clipping range defined by min and max and/or clipSigma 1912 float minClipSigma; 1913 float maxClipSigma; 1914 if (isfinite(stats->max)) { 1915 maxClipSigma = fabs(stats->clipSigma); 1916 } else { 1917 maxClipSigma = fabs(stats->max); 1918 } 1919 if (isfinite(stats->min)) { 1920 minClipSigma = fabs(stats->clipSigma); 1921 } else { 1922 minClipSigma = fabs(stats->min); 1923 } 1924 psVector *fit = NULL; 1925 psVector *resid = psVectorAlloc (x->n, PS_TYPE_F64); 1926 1927 // eventual expansion: user supplies one of various stats option pairs, 1928 // eg (SAMPLE_MEAN | SAMPLE_STDEV) and the correct pair is used to 1929 // evaluate the clipping sigma 1930 // for now, for the SAMPLE_MEDIAN and SAMPLE_STDEV to be used 1931 stats->options |= (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 1932 1933 for (int N = 0; N < stats->clipIter; N++) { 1934 int Nkeep = 0; 1935 1936 poly = psVectorFitPolynomial1D (poly, mask, maskValue, f, fErr, x); 1937 fit = psPolynomial1DEvalVector (poly, x); 1938 resid = (psVector *) psBinaryOp (resid, (void *) f, "-", (void *) fit); 1939 1940 stats = psVectorStats (stats, resid, NULL, mask, maskValue); 1941 float minClipValue = -minClipSigma*stats->sampleStdev; 1942 float maxClipValue = +maxClipSigma*stats->sampleStdev; 1943 1944 // set mask if pts are not valid 1945 // we are masking out any point which is out of range 1946 // recovery is not allowed with this scheme 1947 for (int i = 0; i < resid->n; i++) { 1948 if ((mask != NULL) && (mask->data.U8[i] & maskValue)) { 1949 continue; 1950 } 1951 if (resid->data.F64[i] - stats->sampleMedian > maxClipValue) { 1952 if (mask != NULL) { 1953 mask->data.U8[i] |= 0x01; 1954 } 1955 continue; 1956 } 1957 if (resid->data.F64[i] - stats->sampleMedian < minClipValue) { 1958 if (mask != NULL) { 1959 mask->data.U8[i] |= 0x01; 1960 } 1961 continue; 1962 } 1963 Nkeep ++; 1964 } 1965 1966 psTrace (".psphot.VectorClipFit", 4, "keeping %d of %d pts for fit\n", 1967 Nkeep, x->n); 1968 1969 psFree (fit); 1970 } 1853 1971 // Free psVectors that were created for NULL arguments. 1854 if (x == NULL) { 1855 psFree(x32); 1856 } 1857 return(NULL); 1972 if (xIn == NULL) { 1973 psFree(x); 1974 } 1975 // Free other local temporary variables 1976 psFree (resid); 1977 1978 return (poly); 1858 1979 } 1859 1980 … … 1929 2050 // Build the B and A data structs. 1930 2051 for (int k = 0; k < x->n; k++) { 1931 if ((mask != NULL) && mask->data.U8[k])2052 if ((mask != NULL) && (mask->data.U8[k] & maskValue)) { 1932 2053 continue; 2054 } 2055 1933 2056 Sums = BuildSums2D(Sums, x->data.F64[k], y->data.F64[k], nXterm, nYterm); 1934 2057 … … 1936 2059 wt = 1.0; 1937 2060 } else { 1938 // XXX: this should probably by fErr^2 !! 1939 // this should filter fErr == 0 values 1940 // XXX: Why isn't this fErr^2? 1941 wt = 1.0 / fErr->data.F64[k]; 2061 // this filters fErr == 0 values 2062 wt = (fErr->data.F64[k] == 0.0) ? 0.0 : 1.0 / PS_SQR(fErr->data.F64[k]); 1942 2063 } 1943 2064 … … 1962 2083 1963 2084 // does the solution in place 1964 // XXX: Check return codes!1965 2085 psGaussJordan (A, B); 1966 2086 1967 // XXX: Check return codes! 1968 // ALUD = psMatrixLUD(ALUD, &outPerm, A); 1969 // coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm); 1970 2087 // select the appropriate solution entries 1971 2088 for (int n = 0; n < nXterm; n++) { 1972 2089 for (int m = 0; m < nYterm; m++) { … … 1985 2102 1986 2103 2104 // XXX EAM : I have implemented a single function to handle the mask/nomask cases 2105 // this function can be deprecated 1987 2106 psPolynomial2D* RobustFit2D_nomask( 1988 2107 psPolynomial2D* poly, … … 2251 2370 PS_ASSERT_PTR_NON_NULL(stats, NULL); 2252 2371 PS_ASSERT_VECTOR_NON_NULL(f, NULL); 2253 PS_ASSERT_VECTOR_TYPE (f, PS_TYPE_F32, NULL);2372 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(f, NULL); 2254 2373 if (mask != NULL) { 2255 2374 PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL); … … 2258 2377 PS_ASSERT_VECTOR_NON_NULL(x, NULL); 2259 2378 PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL); 2260 PS_ASSERT_VECTOR_TYPE (x, PS_TYPE_F32, NULL);2379 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(x, NULL); 2261 2380 PS_ASSERT_VECTOR_NON_NULL(y, NULL); 2262 2381 PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL); 2263 PS_ASSERT_VECTOR_TYPE (y, PS_TYPE_F32, NULL);2382 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(y, NULL); 2264 2383 if (fErr != NULL) { 2265 2384 PS_ASSERT_VECTORS_SIZE_EQUAL(f, fErr, NULL); 2266 PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL); 2267 } 2268 2269 if (mask == NULL) { 2270 // XXX: Change argument order. 2271 poly = RobustFit2D_nomask(poly, x, y, f, fErr); 2385 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(fErr, NULL); 2386 } 2387 2388 // clipping range defined by min and max and/or clipSigma 2389 float minClipSigma; 2390 float maxClipSigma; 2391 if (isfinite(stats->max)) { 2392 maxClipSigma = fabs(stats->max); 2272 2393 } else { 2273 // XXX: Use maskValue. 2274 // XXX: Change argument order. 2275 poly = RobustFit2D(poly, mask, x, y, f, fErr); 2276 } 2394 maxClipSigma = fabs(stats->clipSigma); 2395 } 2396 if (isfinite(stats->min)) { 2397 minClipSigma = fabs(stats->min); 2398 } else { 2399 minClipSigma = fabs(stats->clipSigma); 2400 } 2401 psVector *fit = NULL; 2402 psVector *resid = psVectorAlloc (x->n, PS_TYPE_F64); 2403 2404 // eventual expansion: user supplies one of various stats option pairs, 2405 // eg (SAMPLE_MEAN | SAMPLE_STDEV) and the correct pair is used to 2406 // evaluate the clipping sigma 2407 // for now, for the SAMPLE_MEDIAN and SAMPLE_STDEV to be used 2408 stats->options |= (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 2409 2410 for (int N = 0; N < stats->clipIter; N++) { 2411 int Nkeep = 0; 2412 2413 poly = psVectorFitPolynomial2D (poly, mask, maskValue, f, fErr, x, y); 2414 fit = psPolynomial2DEvalVector (poly, x, y); 2415 resid = (psVector *) psBinaryOp (resid, (void *) f, "-", (void *) fit); 2416 2417 stats = psVectorStats (stats, resid, NULL, mask, maskValue); 2418 float minClipValue = -minClipSigma*stats->sampleStdev; 2419 float maxClipValue = +maxClipSigma*stats->sampleStdev; 2420 2421 // set mask if pts are not valid 2422 // we are masking out any point which is out of range 2423 // recovery is not allowed with this scheme 2424 for (int i = 0; i < resid->n; i++) { 2425 if ((mask != NULL) && (mask->data.U8[i] & maskValue)) { 2426 continue; 2427 } 2428 if (resid->data.F64[i] - stats->sampleMedian > maxClipValue) { 2429 if (mask != NULL) { 2430 mask->data.U8[i] |= 0x01; 2431 } 2432 continue; 2433 } 2434 if (resid->data.F64[i] - stats->sampleMedian < minClipValue) { 2435 if (mask != NULL) { 2436 mask->data.U8[i] |= 0x01; 2437 } 2438 continue; 2439 } 2440 Nkeep ++; 2441 } 2442 2443 psTrace (".psphot.VectorClipFit", 4, "keeping %d of %d pts for fit\n", 2444 Nkeep, x->n); 2445 2446 psFree (fit); 2447 } 2448 // Free local temporary variables 2449 psFree (resid); 2277 2450 2278 2451 if (poly == NULL) {
Note:
See TracChangeset
for help on using the changeset viewer.
