Changeset 1775
- Timestamp:
- Sep 9, 2004, 4:55:59 PM (22 years ago)
- Location:
- trunk/psLib
- Files:
-
- 3 added
- 11 edited
-
src/dataManip/psFunctions.c (modified) (8 diffs)
-
src/dataManip/psFunctions.h (modified) (2 diffs)
-
src/dataManip/psMatrix.c (modified) (2 diffs)
-
src/dataManip/psMinimize.c (modified) (3 diffs)
-
src/math/psMatrix.c (modified) (2 diffs)
-
src/math/psMinimize.c (modified) (3 diffs)
-
src/math/psPolynomial.c (modified) (8 diffs)
-
src/math/psPolynomial.h (modified) (2 diffs)
-
src/math/psSpline.c (modified) (8 diffs)
-
src/math/psSpline.h (modified) (2 diffs)
-
test/dataManip/Makefile (modified) (2 diffs)
-
test/dataManip/tst_psFunc02.c (added)
-
test/dataManip/tst_psFunc03.c (added)
-
test/dataManip/tst_psFunc04.c (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/dataManip/psFunctions.c
r1765 r1775 7 7 * polynomials. It also contains a Gaussian functions. 8 8 * 9 * @version $Revision: 1.3 2$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-09- 09 23:39:36$9 * @version $Revision: 1.33 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-09-10 02:52:02 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 1593 1593 float width; 1594 1594 1595 if (fabs(max-min) < FLT_EPSILON) { 1596 psLogMsg(__func__, PS_LOG_WARN, "min and max are the same.\n"); 1597 return(NULL); 1598 } 1599 1595 1600 tmp = (psSpline1D *) psAlloc(sizeof(psSpline1D)); 1596 1597 1601 tmp->n = numSplines; 1598 1602 1599 1603 tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *)); 1600 1604 for (i=0;i<numSplines;i++) { 1601 (tmp->spline)[i] = psPolynomial1DAlloc(order , PS_POLYNOMIAL_ORD);1605 (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD); 1602 1606 } 1603 1607 … … 1626 1630 1627 1631 numSplines = bounds->n - 1; 1632 tmp->n = numSplines; 1628 1633 1629 1634 tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *)); 1630 1635 for (i=0;i<numSplines;i++) { 1631 (tmp->spline)[i] = psPolynomial1DAlloc(order , PS_POLYNOMIAL_ORD);1636 (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD); 1632 1637 } 1633 1638 … … 1668 1673 mid = (max-min)/2; 1669 1674 1670 while (min != max) { 1675 while (min+1 < max) { 1676 psTrace(".psLib.dataManip.psFunctions.VectorBinDisect", 4, "(min, max) is (%d, %d)\n", min, max); 1671 1677 mid = (max-min)/2; 1672 1678 … … 1721 1727 1722 1728 1723 psSpline1D *psSpline1D EGen(const psSpline1D *spline,1724 psVector *data)1729 psSpline1D *psSpline1DGen(const psSpline1D *spline, 1730 psVector *data) 1725 1731 { 1726 1732 int i; … … 1734 1740 } 1735 1741 // XXX: verify your math 1736 if ( 1== (spline->spline[0])->n) {1742 if (2 == (spline->spline[0])->n) { 1737 1743 for (i=0;i<spline->n;i++) { 1738 1744 slope = (data->data.F32[i+1] - data->data.F32[i]) / … … 1742 1748 (spline->spline[0])->coeff[1] = slope; 1743 1749 } 1744 1745 psLogMsg(__func__, PS_LOG_WARN, 1746 "Linear splines have not been implemented."); 1747 return(NULL); 1748 } else if (3 == (spline->spline[0])->n) { 1750 return((psSpline1D *) spline); 1751 } else if (4 == (spline->spline[0])->n) { 1749 1752 psLogMsg(__func__, PS_LOG_WARN, 1750 1753 "Cubic splines have not been implemented."); … … 1753 1756 psLogMsg(__func__, PS_LOG_WARN, 1754 1757 "Don't know how to generate %d-order splines.", 1755 (spline->spline[0])->n );1758 (spline->spline[0])->n-1); 1756 1759 return(NULL); 1757 1760 } -
trunk/psLib/src/dataManip/psFunctions.h
r1721 r1775 12 12 * @author George Gusciora, MHPCC 13 13 * 14 * @version $Revision: 1.2 0$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-09- 08 06:04:10$14 * @version $Revision: 1.21 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-09-10 02:52:02 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 402 402 const psSpline1D *spline); 403 403 404 psSpline1D *psSpline1DGen(const psSpline1D *spline, 405 psVector *data); 406 407 404 408 /* \} */// End of MathGroup Functions 405 409 -
trunk/psLib/src/dataManip/psMatrix.c
r1440 r1775 21 21 * @author Ross Harman, MHPCC 22 22 * 23 * @version $Revision: 1.1 2$ $Name: not supported by cvs2svn $24 * @date $Date: 2004-0 8-09 23:34:57$23 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $ 24 * @date $Date: 2004-09-10 02:52:02 $ 25 25 * 26 26 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 205 205 } 206 206 207 psVector* psMatrixLUSolve(psVector* outVector, const psImage* inImage, const psVector* inVector, const208 psVector* inPerm)207 psVector* psMatrixLUSolve(psVector* outVector, const psImage* inImage, 208 const psVector* inVector, const psVector* inPerm) 209 209 { 210 210 int arraySize = 0; -
trunk/psLib/src/dataManip/psMinimize.c
r1734 r1775 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.3 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-09- 08 23:32:03$11 * @version $Revision: 1.36 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-09-10 02:52:02 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 846 846 /****************************************************************************** 847 847 GUS 848 849 XXX: bug report for the psMatrix covar argument.850 848 *****************************************************************************/ 851 849 bool psMinimizeLM(psMinimization *min, … … 856 854 psMinimizeLMFunc func) 857 855 { 858 /* 859 psVector *beta = psVectorAlloc(params->n, PS_TYPE_F32); 860 psImage *alpha = psImageAlloc(params->n, params->n, PS_TYPE_F32); 861 psVector *deriv; 862 int i; 863 int k; 864 float tmp; 865 866 tmp = func(deriv, params, coords); 867 for (k=0;k<params->n;k++) { 868 beta->data.F32[k] = 0.0; 856 psVector *beta = psVectorAlloc(params->n, PS_TYPE_F32); 857 psVector *perm = psVectorAlloc(params->n, PS_TYPE_F32); 858 psVector *newParams = psVectorAlloc(params->n, PS_TYPE_F32); 859 psImage *alpha = psImageAlloc(params->n, params->n, PS_TYPE_F32); 860 psImage *A = psImageAlloc(params->n, params->n, PS_TYPE_F32); 861 psImage *aOut = psImageAlloc(params->n, params->n, PS_TYPE_F32); 862 psVector *deriv = psVectorAlloc(params->n, PS_TYPE_F32); 863 psVector *newDeriv = psVectorAlloc(params->n, PS_TYPE_F32); 864 int i; 865 int j; 866 int k; 867 float newValue; 868 float oldValue; 869 float lamda = 1.0; 870 871 min->lastDelta = -HUGE; 872 min->iter = 0; 873 min->value = func(deriv, params, coords); 874 875 while ((min->lastDelta > min->tol) && 876 (min->iter < min->maxIter)) { 877 878 for (i=0;i<params->n;i++) { 879 beta->data.F32[i] = deriv->data.F32[i]; 880 } 881 882 for (j=0;j<params->n;j++) { 883 for (k=0;k<params->n;k++) { 884 alpha->data.F32[j][k] = deriv->data.F32[j] * deriv->data.F32[j]; 885 } 886 } 887 for (j=0;j<params->n;j++) { 888 for (k=0;k<params->n;k++) { 889 if (j != k) { 890 A->data.F32[j][k] = alpha->data.F32[j][k]; 891 } else { 892 A->data.F32[j][k] = (1.0 + lamda) * alpha->data.F32[j][k]; 893 } 894 } 895 } 896 aOut = psMatrixLUD(aOut, perm, A); 897 newParams = psMatrixLUSolve(newParams, aOut, beta, perm); 898 899 oldValue = min->value; 900 newValue = func(newDeriv, newParams, coords); 901 if (oldValue > newValue) { 902 min->lastDelta = oldValue - newValue; 903 min->value = newValue; 904 869 905 for (i=0;i<params->n;i++) { 870 beta->data.F32[k]+= deriv 871 } 872 */ 906 params->data.F32[i] = newParams->data.F32[i]; 907 deriv->data.F32[i] = newDeriv->data.F32[i]; 908 } 909 min->value = func(deriv, params, coords); 910 911 lamda*= 0.1; 912 } else { 913 lamda*= 10.0; 914 } 915 min->iter++; 916 } 917 psFree(beta); 918 psFree(perm); 919 psFree(newParams); 920 psFree(alpha); 921 psFree(A); 922 psFree(aOut); 923 psFree(deriv); 924 psFree(newDeriv); 925 926 if ((min->iter < min->maxIter) || 927 (min->lastDelta <= min->tol)) { 928 return(true); 929 } 930 873 931 return(false); 874 932 } -
trunk/psLib/src/math/psMatrix.c
r1440 r1775 21 21 * @author Ross Harman, MHPCC 22 22 * 23 * @version $Revision: 1.1 2$ $Name: not supported by cvs2svn $24 * @date $Date: 2004-0 8-09 23:34:57$23 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $ 24 * @date $Date: 2004-09-10 02:52:02 $ 25 25 * 26 26 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 205 205 } 206 206 207 psVector* psMatrixLUSolve(psVector* outVector, const psImage* inImage, const psVector* inVector, const208 psVector* inPerm)207 psVector* psMatrixLUSolve(psVector* outVector, const psImage* inImage, 208 const psVector* inVector, const psVector* inPerm) 209 209 { 210 210 int arraySize = 0; -
trunk/psLib/src/math/psMinimize.c
r1734 r1775 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.3 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-09- 08 23:32:03$11 * @version $Revision: 1.36 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-09-10 02:52:02 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 846 846 /****************************************************************************** 847 847 GUS 848 849 XXX: bug report for the psMatrix covar argument.850 848 *****************************************************************************/ 851 849 bool psMinimizeLM(psMinimization *min, … … 856 854 psMinimizeLMFunc func) 857 855 { 858 /* 859 psVector *beta = psVectorAlloc(params->n, PS_TYPE_F32); 860 psImage *alpha = psImageAlloc(params->n, params->n, PS_TYPE_F32); 861 psVector *deriv; 862 int i; 863 int k; 864 float tmp; 865 866 tmp = func(deriv, params, coords); 867 for (k=0;k<params->n;k++) { 868 beta->data.F32[k] = 0.0; 856 psVector *beta = psVectorAlloc(params->n, PS_TYPE_F32); 857 psVector *perm = psVectorAlloc(params->n, PS_TYPE_F32); 858 psVector *newParams = psVectorAlloc(params->n, PS_TYPE_F32); 859 psImage *alpha = psImageAlloc(params->n, params->n, PS_TYPE_F32); 860 psImage *A = psImageAlloc(params->n, params->n, PS_TYPE_F32); 861 psImage *aOut = psImageAlloc(params->n, params->n, PS_TYPE_F32); 862 psVector *deriv = psVectorAlloc(params->n, PS_TYPE_F32); 863 psVector *newDeriv = psVectorAlloc(params->n, PS_TYPE_F32); 864 int i; 865 int j; 866 int k; 867 float newValue; 868 float oldValue; 869 float lamda = 1.0; 870 871 min->lastDelta = -HUGE; 872 min->iter = 0; 873 min->value = func(deriv, params, coords); 874 875 while ((min->lastDelta > min->tol) && 876 (min->iter < min->maxIter)) { 877 878 for (i=0;i<params->n;i++) { 879 beta->data.F32[i] = deriv->data.F32[i]; 880 } 881 882 for (j=0;j<params->n;j++) { 883 for (k=0;k<params->n;k++) { 884 alpha->data.F32[j][k] = deriv->data.F32[j] * deriv->data.F32[j]; 885 } 886 } 887 for (j=0;j<params->n;j++) { 888 for (k=0;k<params->n;k++) { 889 if (j != k) { 890 A->data.F32[j][k] = alpha->data.F32[j][k]; 891 } else { 892 A->data.F32[j][k] = (1.0 + lamda) * alpha->data.F32[j][k]; 893 } 894 } 895 } 896 aOut = psMatrixLUD(aOut, perm, A); 897 newParams = psMatrixLUSolve(newParams, aOut, beta, perm); 898 899 oldValue = min->value; 900 newValue = func(newDeriv, newParams, coords); 901 if (oldValue > newValue) { 902 min->lastDelta = oldValue - newValue; 903 min->value = newValue; 904 869 905 for (i=0;i<params->n;i++) { 870 beta->data.F32[k]+= deriv 871 } 872 */ 906 params->data.F32[i] = newParams->data.F32[i]; 907 deriv->data.F32[i] = newDeriv->data.F32[i]; 908 } 909 min->value = func(deriv, params, coords); 910 911 lamda*= 0.1; 912 } else { 913 lamda*= 10.0; 914 } 915 min->iter++; 916 } 917 psFree(beta); 918 psFree(perm); 919 psFree(newParams); 920 psFree(alpha); 921 psFree(A); 922 psFree(aOut); 923 psFree(deriv); 924 psFree(newDeriv); 925 926 if ((min->iter < min->maxIter) || 927 (min->lastDelta <= min->tol)) { 928 return(true); 929 } 930 873 931 return(false); 874 932 } -
trunk/psLib/src/math/psPolynomial.c
r1765 r1775 7 7 * polynomials. It also contains a Gaussian functions. 8 8 * 9 * @version $Revision: 1.3 2$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-09- 09 23:39:36$9 * @version $Revision: 1.33 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-09-10 02:52:02 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 1593 1593 float width; 1594 1594 1595 if (fabs(max-min) < FLT_EPSILON) { 1596 psLogMsg(__func__, PS_LOG_WARN, "min and max are the same.\n"); 1597 return(NULL); 1598 } 1599 1595 1600 tmp = (psSpline1D *) psAlloc(sizeof(psSpline1D)); 1596 1597 1601 tmp->n = numSplines; 1598 1602 1599 1603 tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *)); 1600 1604 for (i=0;i<numSplines;i++) { 1601 (tmp->spline)[i] = psPolynomial1DAlloc(order , PS_POLYNOMIAL_ORD);1605 (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD); 1602 1606 } 1603 1607 … … 1626 1630 1627 1631 numSplines = bounds->n - 1; 1632 tmp->n = numSplines; 1628 1633 1629 1634 tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *)); 1630 1635 for (i=0;i<numSplines;i++) { 1631 (tmp->spline)[i] = psPolynomial1DAlloc(order , PS_POLYNOMIAL_ORD);1636 (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD); 1632 1637 } 1633 1638 … … 1668 1673 mid = (max-min)/2; 1669 1674 1670 while (min != max) { 1675 while (min+1 < max) { 1676 psTrace(".psLib.dataManip.psFunctions.VectorBinDisect", 4, "(min, max) is (%d, %d)\n", min, max); 1671 1677 mid = (max-min)/2; 1672 1678 … … 1721 1727 1722 1728 1723 psSpline1D *psSpline1D EGen(const psSpline1D *spline,1724 psVector *data)1729 psSpline1D *psSpline1DGen(const psSpline1D *spline, 1730 psVector *data) 1725 1731 { 1726 1732 int i; … … 1734 1740 } 1735 1741 // XXX: verify your math 1736 if ( 1== (spline->spline[0])->n) {1742 if (2 == (spline->spline[0])->n) { 1737 1743 for (i=0;i<spline->n;i++) { 1738 1744 slope = (data->data.F32[i+1] - data->data.F32[i]) / … … 1742 1748 (spline->spline[0])->coeff[1] = slope; 1743 1749 } 1744 1745 psLogMsg(__func__, PS_LOG_WARN, 1746 "Linear splines have not been implemented."); 1747 return(NULL); 1748 } else if (3 == (spline->spline[0])->n) { 1750 return((psSpline1D *) spline); 1751 } else if (4 == (spline->spline[0])->n) { 1749 1752 psLogMsg(__func__, PS_LOG_WARN, 1750 1753 "Cubic splines have not been implemented."); … … 1753 1756 psLogMsg(__func__, PS_LOG_WARN, 1754 1757 "Don't know how to generate %d-order splines.", 1755 (spline->spline[0])->n );1758 (spline->spline[0])->n-1); 1756 1759 return(NULL); 1757 1760 } -
trunk/psLib/src/math/psPolynomial.h
r1722 r1775 12 12 * @author George Gusciora, MHPCC 13 13 * 14 * @version $Revision: 1.2 0$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-09- 08 06:04:10$14 * @version $Revision: 1.21 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-09-10 02:52:02 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 402 402 const psSpline1D *spline); 403 403 404 psSpline1D *psSpline1DGen(const psSpline1D *spline, 405 psVector *data); 406 407 404 408 /* \} */// End of MathGroup Functions 405 409 -
trunk/psLib/src/math/psSpline.c
r1765 r1775 7 7 * polynomials. It also contains a Gaussian functions. 8 8 * 9 * @version $Revision: 1.3 2$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-09- 09 23:39:36$9 * @version $Revision: 1.33 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-09-10 02:52:02 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 1593 1593 float width; 1594 1594 1595 if (fabs(max-min) < FLT_EPSILON) { 1596 psLogMsg(__func__, PS_LOG_WARN, "min and max are the same.\n"); 1597 return(NULL); 1598 } 1599 1595 1600 tmp = (psSpline1D *) psAlloc(sizeof(psSpline1D)); 1596 1597 1601 tmp->n = numSplines; 1598 1602 1599 1603 tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *)); 1600 1604 for (i=0;i<numSplines;i++) { 1601 (tmp->spline)[i] = psPolynomial1DAlloc(order , PS_POLYNOMIAL_ORD);1605 (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD); 1602 1606 } 1603 1607 … … 1626 1630 1627 1631 numSplines = bounds->n - 1; 1632 tmp->n = numSplines; 1628 1633 1629 1634 tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *)); 1630 1635 for (i=0;i<numSplines;i++) { 1631 (tmp->spline)[i] = psPolynomial1DAlloc(order , PS_POLYNOMIAL_ORD);1636 (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD); 1632 1637 } 1633 1638 … … 1668 1673 mid = (max-min)/2; 1669 1674 1670 while (min != max) { 1675 while (min+1 < max) { 1676 psTrace(".psLib.dataManip.psFunctions.VectorBinDisect", 4, "(min, max) is (%d, %d)\n", min, max); 1671 1677 mid = (max-min)/2; 1672 1678 … … 1721 1727 1722 1728 1723 psSpline1D *psSpline1D EGen(const psSpline1D *spline,1724 psVector *data)1729 psSpline1D *psSpline1DGen(const psSpline1D *spline, 1730 psVector *data) 1725 1731 { 1726 1732 int i; … … 1734 1740 } 1735 1741 // XXX: verify your math 1736 if ( 1== (spline->spline[0])->n) {1742 if (2 == (spline->spline[0])->n) { 1737 1743 for (i=0;i<spline->n;i++) { 1738 1744 slope = (data->data.F32[i+1] - data->data.F32[i]) / … … 1742 1748 (spline->spline[0])->coeff[1] = slope; 1743 1749 } 1744 1745 psLogMsg(__func__, PS_LOG_WARN, 1746 "Linear splines have not been implemented."); 1747 return(NULL); 1748 } else if (3 == (spline->spline[0])->n) { 1750 return((psSpline1D *) spline); 1751 } else if (4 == (spline->spline[0])->n) { 1749 1752 psLogMsg(__func__, PS_LOG_WARN, 1750 1753 "Cubic splines have not been implemented."); … … 1753 1756 psLogMsg(__func__, PS_LOG_WARN, 1754 1757 "Don't know how to generate %d-order splines.", 1755 (spline->spline[0])->n );1758 (spline->spline[0])->n-1); 1756 1759 return(NULL); 1757 1760 } -
trunk/psLib/src/math/psSpline.h
r1722 r1775 12 12 * @author George Gusciora, MHPCC 13 13 * 14 * @version $Revision: 1.2 0$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-09- 08 06:04:10$14 * @version $Revision: 1.21 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-09-10 02:52:02 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 402 402 const psSpline1D *spline); 403 403 404 psSpline1D *psSpline1DGen(const psSpline1D *spline, 405 psVector *data); 406 407 404 408 /* \} */// End of MathGroup Functions 405 409 -
trunk/psLib/test/dataManip/Makefile
r1308 r1775 3 3 ## Makefile: test/sysUtils 4 4 ## 5 ## $Revision: 1.3 5$ $Name: not supported by cvs2svn $6 ## $Date: 2004-0 7-28 02:50:38$5 ## $Revision: 1.36 $ $Name: not supported by cvs2svn $ 6 ## $Date: 2004-09-10 02:55:20 $ 7 7 ## 8 8 ## Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 22 22 tst_psFunc00 \ 23 23 tst_psFunc01 \ 24 tst_psFunc02 \ 25 tst_psFunc03 \ 26 tst_psFunc04 \ 24 27 tst_psHist00 \ 25 28 tst_psHist01 \
Note:
See TracChangeset
for help on using the changeset viewer.
