Changeset 5567
- Timestamp:
- Nov 22, 2005, 8:06:10 AM (21 years ago)
- File:
-
- 1 edited
-
branches/eam_rel8_b1/psLib/src/math/psMinimize.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_rel8_b1/psLib/src/math/psMinimize.c
r5294 r5567 10 10 * @author EAM, IfA 11 11 * 12 * @version $Revision: 1.142 $ $Name: not supported by cvs2svn $13 * @date $Date: 2005-1 0-12 21:02:20 $12 * @version $Revision: 1.142.6.1 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-11-22 18:06:10 $ 14 14 * 15 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 1443 1443 1444 1444 /****************************************************************************** 1445 BuildSums4D(sums, x, y, z, t, nXterm, nYterm, nZterm, nTterm). equiv to 1446 BuildSums2D(). The result is returned as a double **** 1447 *****************************************************************************/ 1448 static psImage *BuildSums4D( 1449 psF64 ****sums, 1450 psF64 x, 1451 psF64 y, 1452 psF64 z, 1453 psF64 t, 1454 psS32 nXterm, 1455 psS32 nYterm, 1456 psS32 nZterm, 1457 psS32 nTterm) 1458 { 1459 psS32 nXsum = 0; 1460 psS32 nYsum = 0; 1461 psS32 nZsum = 0; 1462 psS32 nTsum = 0; 1463 psF64 xSum = 1.0; 1464 psF64 ySum = 1.0; 1465 psF64 zSum = 1.0; 1466 psF64 tSum = 1.0; 1467 1468 nXsum = 2*nXterm; 1469 nYsum = 2*nYterm; 1470 nZsum = 2*nZterm; 1471 nTsum = 2*nTterm; 1472 if (sums == NULL) { 1473 sums = (psF64 ****) psAlloc (nXsum*PSELEMTYPE_SIZEOF(psF64)); 1474 for (int i = 0; i < nXsum; i++) { 1475 sums[i] = (psF64 ***) psAlloc (nYsum*PSELEMTYPE_SIZEOF(psF64)); 1476 for (int j = 0; j < nYsum; j++) { 1477 sums[i][j] = (psF64 **) psAlloc (nZsum*PSELEMTYPE_SIZEOF(psF64)); 1478 for (int k = 0; k < nZsum; k++) { 1479 sums[i][j][k] = (psF64 *) psAlloc (nTsum*PSELEMTYPE_SIZEOF(psF64)); 1480 } 1481 } 1482 } 1483 } 1484 // careful with this function: there is no size checking and realloc for reuse 1485 1486 tSum = 1.0; 1487 for (int m = 0; m < nTsum; m++) { 1488 zSum = tSum; 1489 for (int k = 0; k < nZsum; k++) { 1490 ySum = zSum; 1491 for (int j = 0; j < nYsum; j++) { 1492 xSum = ySum; 1493 for (int i = 0; i < nXsum; i++) { 1494 sums[i][j][k][m] = xSum; 1495 xSum *= x; 1496 } 1497 ySum *= y; 1498 } 1499 zSum *= z; 1500 } 1501 tSum *= t; 1502 } 1503 return (sums); 1504 } 1505 1506 /****************************************************************************** 1445 1507 Polynomial2DEvalVectorD(myPoly, x, y): This routine takes as input two 1446 1508 psVectors x and y, and evaluates myPoly for each pair of (x, y), and stores it … … 1658 1720 // xSums look like: 1, x, x^2, ... x^(2n+1) 1659 1721 // Build the B and A data structs. 1722 // XXX EAM : use temp pointers eg vB = B->data.F64 to save redirects 1723 // XXX EAM : this function is only valid for data vectors of F64 1660 1724 for (int k = 0; k < f->n; k++) { 1661 if ((mask != NULL) && mask->data.U8[k])1725 if ((mask != NULL) && (mask->data.U8[k] && maskValue)) { 1662 1726 continue; 1727 } 1663 1728 if (x != NULL) { 1664 1729 xSums = BuildSums1D(xSums, x->data.F64[k], nTerm); … … 1670 1735 wt = 1.0; 1671 1736 } else { 1672 // this should filterfErr == 0 values1673 wt = 1.0 / PS_SQR(fErr->data.F64[k]);1737 // this filters fErr == 0 values 1738 wt = (fErr->data.F64[k] == 0) ? 0.0 : 1.0 / PS_SQR(fErr->data.F64[k]); 1674 1739 } 1675 1740 for (int i = 0; i < nTerm; i++) { … … 1686 1751 } 1687 1752 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); 1753 // does the solution in place 1754 psGaussJordan (A, B); 1755 1756 // the first nTerm entries in B correspond directly to the desired 1757 // polynomial coefficients. this is only true for the 1D case 1758 for (int k = 0; k < nTerm; k++) { 1759 myPoly->coeff[k] = B->data.F64[k]; 1713 1760 } 1714 1761 … … 1819 1866 } 1820 1867 1821 1868 // This function accepts F32 and F64 input vectors. 1822 1869 psPolynomial1D *psVectorClipFitPolynomial1D( 1823 1870 psPolynomial1D *poly, … … 1827 1874 const psVector *f, 1828 1875 const psVector *fErr, 1829 const psVector *x )1876 const psVector *xIn) 1830 1877 { 1831 1878 // Internal pointers for possibly NULL vectors. 1832 psVector *x 32= NULL;1879 psVector *x = NULL; 1833 1880 1834 1881 PS_ASSERT_POLY_NON_NULL(poly, NULL); … … 1836 1883 PS_ASSERT_PTR_NON_NULL(stats, NULL); 1837 1884 PS_ASSERT_VECTOR_NON_NULL(f, NULL); 1838 PS_ASSERT_VECTOR_TYPE (f, PS_TYPE_F32, NULL);1885 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(f, NULL); 1839 1886 if (mask != NULL) { 1840 1887 PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL); 1841 1888 PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL); 1842 1889 } 1843 if (x != NULL) {1844 PS_ASSERT_VECTORS_SIZE_EQUAL(f, x , NULL);1845 PS_ASSERT_VECTOR_TYPE (x, PS_TYPE_F32, NULL);1890 if (xIn != NULL) { 1891 PS_ASSERT_VECTORS_SIZE_EQUAL(f, xIn, NULL); 1892 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(xIn, NULL); 1846 1893 } 1847 1894 if (fErr != NULL) { 1848 1895 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"); 1896 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(fErr, NULL); 1897 } 1898 1899 // assign sequence vector if xIn is NULL 1900 if (xIn == NULL) { 1901 x = psVectorCreate (NULL, 0, f->n, 1, f->type); 1902 } else { 1903 x = xIn; 1904 } 1905 1906 // clipping range defined by min and max and/or clipSigma 1907 float minClipSigma; 1908 float maxClipSigma; 1909 if (finite(stats->max)) { 1910 maxClipSigma = fabs(stats->clipSigma); 1911 } else { 1912 maxClipSigma = fabs(stats->max); 1913 } 1914 if (finite(stats->min)) { 1915 minClipSigma = fabs(stats->clipSigma); 1916 } else { 1917 minClipSigma = fabs(stats->min); 1918 } 1919 psVector *fit = NULL; 1920 psVector *resid = psVectorAlloc (x->n, PS_TYPE_F64); 1921 1922 // eventual expansion: user supplies one of various stats option pairs, 1923 // eg (SAMPLE_MEAN | SAMPLE_STDEV) and the correct pair is used to 1924 // evaluate the clipping sigma 1925 // for now, for the SAMPLE_MEDIAN and SAMPLE_STDEV to be used 1926 stats->options |= (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 1927 1928 for (int N = 0; N < stats->clipIter; N++) { 1929 int Nkeep = 0; 1930 1931 poly = psVectorFitPolynomial1D (poly, mask, maskValue, f, fErr, x); 1932 fit = psPolynomial1DEvalVector (poly, x); 1933 resid = (psVector *) psBinaryOp (resid, (void *) f, "-", (void *) fit); 1934 1935 stats = psVectorStats (stats, resid, NULL, mask, maskValue); 1936 float minClipValue = -minClipSigma*stats->sampleStdev; 1937 float maxClipValue = +maxClipSigma*stats->sampleStdev; 1938 1939 // set mask if pts are not valid 1940 // we are masking out any point which is out of range 1941 // recovery is not allowed with this scheme 1942 for (int i = 0; i < resid->n; i++) { 1943 if ((mask != NULL) && (mask->data.U8[i] & maskValue)) { 1944 continue; 1945 } 1946 if (resid->data.F64[i] - stats->sampleMedian > maxClipValue) { 1947 if (mask != NULL) { 1948 mask->data.U8[i] |= 0x01; 1949 } 1950 continue; 1951 } 1952 if (resid->data.F64[i] - stats->sampleMedian < minClipValue) { 1953 if (mask != NULL) { 1954 mask->data.U8[i] |= 0x01; 1955 } 1956 continue; 1957 } 1958 Nkeep ++; 1959 } 1960 1961 psTrace (".psphot.VectorClipFit", 4, "keeping %d of %d pts for fit\n", 1962 Nkeep, x->n); 1963 1964 psFree (fit); 1965 } 1853 1966 // Free psVectors that were created for NULL arguments. 1854 if (x == NULL) { 1855 psFree(x32); 1856 } 1857 return(NULL); 1967 if (xIn == NULL) { 1968 psFree(x); 1969 } 1970 // Free other local temporary variables 1971 psFree (resid); 1972 1973 return (poly); 1858 1974 } 1859 1975 … … 1929 2045 // Build the B and A data structs. 1930 2046 for (int k = 0; k < x->n; k++) { 1931 if ((mask != NULL) && mask->data.U8[k])2047 if ((mask != NULL) && (mask->data.U8[k] & maskValue)) { 1932 2048 continue; 2049 } 2050 1933 2051 Sums = BuildSums2D(Sums, x->data.F64[k], y->data.F64[k], nXterm, nYterm); 1934 2052 … … 1936 2054 wt = 1.0; 1937 2055 } 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]; 2056 // this filters fErr == 0 values 2057 wt = (fErr->data.F64[k] == ) ? 0.0 : 1.0 / PS_SQR(fErr->data.F64[k]); 1942 2058 } 1943 2059 … … 1962 2078 1963 2079 // does the solution in place 1964 // XXX: Check return codes!1965 2080 psGaussJordan (A, B); 1966 2081 1967 // XXX: Check return codes! 1968 // ALUD = psMatrixLUD(ALUD, &outPerm, A); 1969 // coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm); 1970 2082 // select the appropriate solution entries 1971 2083 for (int n = 0; n < nXterm; n++) { 1972 2084 for (int m = 0; m < nYterm; m++) { … … 2251 2363 PS_ASSERT_PTR_NON_NULL(stats, NULL); 2252 2364 PS_ASSERT_VECTOR_NON_NULL(f, NULL); 2253 PS_ASSERT_VECTOR_TYPE (f, PS_TYPE_F32, NULL);2365 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(f, NULL); 2254 2366 if (mask != NULL) { 2255 2367 PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL); … … 2258 2370 PS_ASSERT_VECTOR_NON_NULL(x, NULL); 2259 2371 PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL); 2260 PS_ASSERT_VECTOR_TYPE (x, PS_TYPE_F32, NULL);2372 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(x, NULL); 2261 2373 PS_ASSERT_VECTOR_NON_NULL(y, NULL); 2262 2374 PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL); 2263 PS_ASSERT_VECTOR_TYPE (y, PS_TYPE_F32, NULL);2375 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(y, NULL); 2264 2376 if (fErr != NULL) { 2265 2377 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); 2378 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(fErr, NULL); 2379 } 2380 2381 // clipping range defined by min and max and/or clipSigma 2382 float minClipSigma; 2383 float maxClipSigma; 2384 if (finite(stats->max)) { 2385 maxClipSigma = fabs(stats->clipSigma); 2272 2386 } else { 2273 // XXX: Use maskValue. 2274 // XXX: Change argument order. 2275 poly = RobustFit2D(poly, mask, x, y, f, fErr); 2276 } 2387 maxClipSigma = fabs(stats->max); 2388 } 2389 if (finite(stats->min)) { 2390 minClipSigma = fabs(stats->clipSigma); 2391 } else { 2392 minClipSigma = fabs(stats->min); 2393 } 2394 psVector *fit = NULL; 2395 psVector *resid = psVectorAlloc (x->n, PS_TYPE_F64); 2396 2397 // eventual expansion: user supplies one of various stats option pairs, 2398 // eg (SAMPLE_MEAN | SAMPLE_STDEV) and the correct pair is used to 2399 // evaluate the clipping sigma 2400 // for now, for the SAMPLE_MEDIAN and SAMPLE_STDEV to be used 2401 stats->options |= (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 2402 2403 for (int N = 0; N < stats->clipIter; N++) { 2404 int Nkeep = 0; 2405 2406 poly = psVectorFitPolynomial2D (poly, mask, maskValue, f, fErr, x, y); 2407 fit = psPolynomial2DEvalVector (poly, x, y); 2408 resid = (psVector *) psBinaryOp (resid, (void *) f, "-", (void *) fit); 2409 2410 stats = psVectorStats (stats, resid, NULL, mask, maskValue); 2411 float minClipValue = -minClipSigma*stats->sampleStdev; 2412 float maxClipValue = +maxClipSigma*stats->sampleStdev; 2413 2414 // set mask if pts are not valid 2415 // we are masking out any point which is out of range 2416 // recovery is not allowed with this scheme 2417 for (int i = 0; i < resid->n; i++) { 2418 if ((mask != NULL) && (mask->data.U8[i] & maskValue)) { 2419 continue; 2420 } 2421 if (resid->data.F64[i] - stats->sampleMedian > maxClipValue) { 2422 if (mask != NULL) { 2423 mask->data.U8[i] |= 0x01; 2424 } 2425 continue; 2426 } 2427 if (resid->data.F64[i] - stats->sampleMedian < minClipValue) { 2428 if (mask != NULL) { 2429 mask->data.U8[i] |= 0x01; 2430 } 2431 continue; 2432 } 2433 Nkeep ++; 2434 } 2435 2436 psTrace (".psphot.VectorClipFit", 4, "keeping %d of %d pts for fit\n", 2437 Nkeep, x->n); 2438 2439 psFree (fit); 2440 } 2441 // Free local temporary variables 2442 psFree (resid); 2277 2443 2278 2444 if (poly == NULL) {
Note:
See TracChangeset
for help on using the changeset viewer.
