Changeset 8879ea8 in tol
- Timestamp:
- Mar 31, 2010, 4:02:06 PM (17 years ago)
- Branches:
- 1941-docker-image-to-test, devel, master
- Children:
- acdac1ce
- Parents:
- 69ee043
- File:
-
- 1 edited
-
tol/btol/real_type/datgrav.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
tol/btol/real_type/datgrav.cpp
r69ee043 r8879ea8 1287 1287 //-------------------------------------------------------------------- 1288 1288 { 1289 contens_ = Pol(Arg(1)).StationaryValue( );1289 contens_ = Pol(Arg(1)).StationaryValue(BFALSE); 1290 1290 } 1291 1291 … … 1695 1695 } 1696 1696 1697 struct AsymptoticSampler1D_SampleInfo 1698 { 1699 double x; 1700 double f; 1701 double g; 1702 }; 1703 1704 //-------------------------------------------------------------------- 1705 BInt AsymptoticSampler1D_cmp(const void* v1, const void* v2) 1706 //-------------------------------------------------------------------- 1707 { 1708 AsymptoticSampler1D_SampleInfo* u1 = (AsymptoticSampler1D_SampleInfo*)v1; 1709 AsymptoticSampler1D_SampleInfo* u2 = (AsymptoticSampler1D_SampleInfo*)v2; 1710 double dif = u1->f-u2->f; 1711 return((dif<0)?-1:((dif>0)?+1:0)); 1712 } 1713 1714 //-------------------------------------------------------------------- 1715 DeclareContensClass(BDat, BDatTemporary, BDatAsymptoticSampler1D); 1716 DefExtOpr(1, BDatAsymptoticSampler1D, "AsymptoticSampler1D", 3, 5, 1717 "Code Real Real Real Real", 1718 "(Code logDens, Real L, Real R [, Real numOfCandidates = 10, Real maxIter = 100])", 1719 "Este método consiste en una aproximación asintótica muy sencilla " 1720 "para simular realizaciones de una distribución de probabilidad con " 1721 "densidad arbitraria con dominio no necesariamente conexo dentro de un " 1722 "intervalo [L,R] orientativo:\n" 1723 " 1. Se toman secuencialmente valores x[k] uniformemente distribuidos en [L,R] \n" 1724 " 2. Se calcula el logaritmo de su densidad salvo una constante \n" 1725 " f[k] = log(d(x[k]))+c \n" 1726 " 3. Se descartan los que den logaritmo de densidad -Inf, para forzar, densidad no nula, o sea, \n" 1727 " d(x[k])>0 \n" 1728 " 4. Se para cuando se obtiene el número deseado de candidatos con densidad no nula o se supera el máximo de iteraciones\n" 1729 " 5. Se resta a cada uno el máximo de las f y se toma su exponencial \n" 1730 " g[k] = Exp( f[k] - max{f[i]} ) \n" 1731 " 6. Se calcula el peso relativo w[k] de cada valor de forma proporcional a su densidad \n" 1732 " w[k] = g[k] / Sum( g[i] ) \n" 1733 " 7. Se ordenan por densidad creciente \n" 1734 " w(x[k])<=w(x[k+1]) \n" 1735 " 8. Se calculan los pesos acumulados \n" 1736 " W(x[1]) = w(x[1]) \n" 1737 " W(x[k+1])=W(x[k])+w(x[k+1]) \n" 1738 " 9. Se toma un valor p uniformemente distribuido en [0,1] \n" 1739 "10. Se elige el primer valor que supera o iguala a p en peso acumulado \n" 1740 " W(x[k-1]) < p <= W(x[k]) \n" 1741 "\n" 1742 "Cuando n->Inf esto da simulación exacta, pero con valores de apenas n=10 nos " 1743 "da puede dar una buena aproximación si el intervalo es lo bastante denso como " 1744 "para que no se descarte la totalidad de los candidatos.", 1745 BOperClassify::Statistic_); 1746 void BDatAsymptoticSampler1D::CalcContens() 1747 //-------------------------------------------------------------------- 1748 { 1749 BCode& cod = Code(Arg(1)); 1750 double L = Real(Arg(2)); 1751 double R = Real(Arg(3)); 1752 int numOfCandidates = 10; 1753 int maxIter = 100; 1754 if(Arg(4)) { numOfCandidates = int(Real(Arg(4))); } 1755 if(Arg(5)) { maxIter = int(Real(Arg(5))); } 1756 1757 BText english("In AsymptoticSampler1D, "); 1758 BText spanish("En AsymptoticSampler1D, "); 1759 1760 if (!cod.Operator()) { 1761 english += "invalid code argument"; 1762 spanish += "argumento código inválido"; 1763 Error(I2(english,spanish)); 1764 return; 1765 } 1766 1767 if (cod.Operator()->MinArg()!=1 && 1768 cod.Operator()->MaxArg()!=1) { 1769 english += "invalid argument number for logf argument: should be 1"; 1770 spanish += "número de argumentos inválidos para argumento logf: debe ser 1"; 1771 Error(I2(english,spanish)); 1772 return; 1773 } 1774 1775 /* check user function's grammar */ 1776 if (cod.Grammar() != GraReal()) { 1777 english += "invalid type "; 1778 english += cod.Grammar()->Name(); 1779 english += " for logf argument: should be Real"; 1780 spanish += " tipo inválido "; 1781 spanish += cod.Grammar()->Name(); 1782 spanish += " para argumento logf: debe ser Real"; 1783 Error(I2(english,spanish)); 1784 return; 1785 } 1786 1787 /* check grammar of user function's first argument */ 1788 if (cod.Operator()->GrammarForArg(1) != GraReal()) { 1789 english += "invalid type "; 1790 english += cod.Operator()->GrammarForArg(1)->Name(); 1791 english += " for first argument of logf argument: should be Real"; 1792 spanish += "tipo inválido "; 1793 spanish += cod.Operator()->GrammarForArg(1)->Name(); 1794 spanish += " en el primer argumento del argumento logf: debe ser Real"; 1795 Error(I2(english,spanish)); 1796 return; 1797 } 1798 BUniformDist U(L,R); 1799 BUniformDist U01(0,1); 1800 BRRCode fun(cod); 1801 BArray< AsymptoticSampler1D_SampleInfo > sample; 1802 sample.AllocBuffer(numOfCandidates); 1803 int i, k; 1804 double x, f, g, w, f_max = BDat::NegInf(), g_sum = 0, W=0, p; 1805 for(i=k=0; (i<maxIter)&&(k<numOfCandidates); i++) 1806 { 1807 x = U.Random().Value(); 1808 f = (fun[x]).Value(); 1809 if(f>BDat::NegInf()) 1810 { 1811 if(f_max<f) { f_max = f; } 1812 sample[k].x = x; 1813 sample[k].f = f; 1814 k++; 1815 } 1816 } 1817 int n = k; 1818 sample.ReallocBuffer(n); 1819 sample.Sort(AsymptoticSampler1D_cmp); 1820 for(k=0; k<n; k++) 1821 { 1822 g = exp(sample[k].f-f_max); 1823 g_sum += g; 1824 sample[k].g = g; 1825 } 1826 p = U01.Random().Value(); 1827 for(k=0; k<n; k++) 1828 { 1829 w = sample[k].g / g_sum; 1830 W += w; 1831 if(W>=p) 1832 { 1833 contens_ = sample[k].x; 1834 return; 1835 } 1836 } 1837 contens_ = BDat::Unknown(); 1838 }; 1697 1839 1698 1840 //--------------------------------------------------------------------
Note: See TracChangeset
for help on using the changeset viewer.
