Ticket #11572: trac_11572_new_patch_on_top_of_fdist.patch

File trac_11572_new_patch_on_top_of_fdist.patch, 29.3 KB (added by Kamhamea, 8 years ago)
  • sage/gsl/gsl_random.pxi

    # HG changeset patch
    # User Mato Nagel <mato.nagel@gmx.net>
    # Date 1310013338 -7200
    # Node ID c5dcd2852f6173487ce0923ab9622c33e1c0aab4
    # Parent  51b1b79164e97740bfe70ad05cc3319965285109
    Trac 11572: further distributions added on top of f-dist
    
    diff -r 51b1b79164e9 -r c5dcd2852f61 sage/gsl/gsl_random.pxi
    a b  
    11cdef extern from "gsl/gsl_randist.h":
     2   
    23  unsigned int gsl_ran_bernoulli ( gsl_rng * r, double p)
    34  double gsl_ran_bernoulli_pdf ( unsigned int k, double p)
    45 
     
    3536  double gsl_ran_flat_pdf (double x,  double a,  double b)
    3637 
    3738  double gsl_ran_gamma ( gsl_rng * r,  double a,  double b)
    38   double gsl_ran_gamma_int ( gsl_rng * r,  unsigned int a)
    3939  double gsl_ran_gamma_pdf ( double x,  double a,  double b)
    4040 
    4141  double gsl_ran_gaussian ( gsl_rng * r,  double sigma)
     
    249249 
    250250  double gsl_cdf_logistic_Pinv ( double P,  double a)
    251251  double gsl_cdf_logistic_Qinv ( double Q,  double a)
     252
     253  double gsl_cdf_binomial_P (unsigned int k, double p, unsigned int n)
     254  double gsl_cdf_binomial_Q (unsigned int k, double p, unsigned int n)
     255
     256  double gsl_cdf_poisson_P (unsigned int k, double mu)
     257  double gsl_cdf_poisson_Q (unsigned int k, double mu)
     258
     259  double gsl_cdf_geometric_P (unsigned int k, double p)
     260  double gsl_cdf_geometric_Q (unsigned int k, double p)
     261
     262  double gsl_cdf_negative_binomial_P (unsigned int k, double p, double n)
     263  double gsl_cdf_negative_binomial_Q (unsigned int k, double p, double n)
     264
     265  double gsl_cdf_pascal_P (unsigned int k, double p, unsigned int n)
     266  double gsl_cdf_pascal_Q (unsigned int k, double p, unsigned int n)
     267
     268  double gsl_cdf_hypergeometric_P (unsigned int k, unsigned int n1,
     269                                 unsigned int n2, unsigned int t)
     270  double gsl_cdf_hypergeometric_Q (unsigned int k, unsigned int n1,
     271                                 unsigned int n2, unsigned int t)
  • sage/gsl/probability_distribution.pyx

    diff -r 51b1b79164e9 -r c5dcd2852f61 sage/gsl/probability_distribution.pyx
    a b  
    2121
    2222- Kwankyu Lee (2010-05-29): F-distribution support.
    2323
     24- Mato Nagel (2011-07-07): several continuous and discrete distributions.
     25
    2426REFERENCES:
    2527
    2628    GNU gsl library, General discrete distributions
     
    3032    http://www.gnu.org/software/gsl/manual/html_node/Random-Number-Distributions.html
    3133"""
    3234
     35
    3336##############################################################################
    3437#         Copyright (C) 2004, 2005, 2006 Joshua Kantor <kantor.jm@gmail.com>
    3538#  Distributed under the terms of the GNU General Public License (GPL)
     
    4548import sage.rings.real_double
    4649import random
    4750import integration
     51
    4852from sage.modules.free_module_element import vector
    4953
    50 #TODO: Add more distributions available in gsl
    51 #available but not currently wrapped are exponential, laplace, cauchy, landau, gamma,
    52 #gamma, beta logistic.
     54
     55#TODO: Add more distributions
     56# still available in gsl but not currently wrapped are
     57# Erlang distribution which is simplified gamma distribution
     58# Bernoulli which is simplified binomial
     59# Dirichlet distribution which is multivariate generalization of the beta distribution
     60# flat which is identical to uniform
     61# logarithmic distribution
     62# multinomial distribution which is a generalization of the binomial distribution.
     63# Lévy distribution
     64#
     65# not available in gsl
     66# Wilcoxon distribution
    5367
    5468cdef enum:
    5569    uniform
     
    6377    exppow
    6478    weibull
    6579    beta
     80    expon
     81    laplace
     82    cauchy
     83    landau
     84    gamma
     85    logistic
     86    gumbel1
     87    gumbel2
     88    binom
     89    pois
     90    geom
     91    nbinom
     92    hyper
     93   
    6694 
    6795cdef class ProbabilityDistribution:
    6896    """
     
    378406        0.75
    379407        sage: T.cum_distribution_function_inv(.5)
    380408        0.0
    381 
     409 
    382410    The F-distribution has two parameters ``nu1`` and ``nu2``::     
    383411
    384412        sage: nu1 = 9; nu2 = 17                             
     
    429457        0.0
    430458        sage: T.cum_distribution_function(1)
    431459        1.0
     460        sage: T.cum_distribution_function_inv(1)
     461        1.0
    432462
    433463    The weibull distribution has two parameters ``a`` and ``b``::
    434464
     
    444474        sage: T.cum_distribution_function_inv(.5)
    445475        0.69314718056
    446476
     477    The exponential distribution has one parameter ``mu``::
     478
     479        sage: mu = 1
     480        sage: T = RealDistribution('exp', [mu])
     481        sage: T.get_random_element() # random
     482        0.539605826512
     483        sage: T.distribution_function(0)
     484        1.0
     485        sage: T.cum_distribution_function(1)
     486        0.632120558829
     487        sage: T.cum_distribution_function_inv(.63)
     488        0.994252273344
     489
     490    The laplace distribution has one parameter ``mu``::
     491
     492        sage: mu = 1
     493        sage: T = RealDistribution('laplace', [mu])
     494        sage: T.get_random_element() # random
     495        0.61130679195
     496        sage: T.distribution_function(0)
     497        0.5
     498        sage: T.cum_distribution_function(1)
     499        0.816060279414
     500        T.cum_distribution_function_inv(.816)
     501        0.999672340813
     502
     503    The cauchy distribution has one parameter ``a``::
     504
     505        sage: a = 1
     506        sage: T = RealDistribution('cauchy', [a])
     507        sage: T.get_random_element() # random
     508        0.244430093406
     509        sage: T.distribution_function(0)
     510        0.318309886184
     511        sage: T.cum_distribution_function(1)
     512        0.75
     513        T.cum_distribution_function_inv(.75)
     514        1.0
     515
     516    The landau distribution has no parameters::
     517
     518        sage: T = RealDistribution('landau')
     519        sage: T.get_random_element() # random
     520        4.03287345475
     521        sage: T.distribution_function(0)
     522        0.1788541609
     523
     524    The gamma distribution has two parameters ``a`` and ``b``::
     525
     526        sage: a = 9
     527        sage: b = 0.5
     528        sage: T = RealDistribution('gamma', [a, b])
     529        sage: T.get_random_element() # random
     530        7.18005786995
     531        sage: T.distribution_function(4)
     532        0.279173063901
     533        sage: T.cum_distribution_function(3)
     534        0.152762506015
     535        sage: T.cum_distribution_function_inv(.152)
     536        2.99630319428
     537
     538    The logistic distribution has 1 parameter ``sigma``::
     539 
     540        sage: sigma = 1
     541        sage: T = RealDistribution('logistic', [sigma])
     542        sage: T.get_random_element() # random
     543        2.12029493681
     544        sage: T.distribution_function(0)
     545        0.25
     546        sage: T.cum_distribution_function(1)
     547        0.73105857863
     548        sage: T.cum_distribution_function_inv(.73)
     549        0.994622575144
     550 
     551    The gumbel type 1 distribution has two parameters ``a`` and ``b``::
     552
     553        sage: a = 1
     554        sage: b = 1
     555        sage: T = RealDistribution('gumbel1', [a, b])
     556        sage: T.get_random_element() # random
     557        -1.10577509408
     558        sage: T.distribution_function(0)
     559        0.367879441171
     560        sage: T.cum_distribution_function(1)
     561        0.692200627555
     562        sage: T.cum_distribution_function_inv(.69)
     563        0.991381583151
     564
     565    The gumbel type 2 distribution has two parameters ``a`` and ``b``::
     566
     567        sage: a = 1
     568        sage: b = 1
     569        sage: T = RealDistribution('gumbel2', [a, b])
     570        sage: T.get_random_element() # random
     571        24.5074179476
     572        sage: T.distribution_function(1)
     573        0.367879441171
     574        sage: T.cum_distribution_function(3)
     575        0.716531310574
     576        sage: T.cum_distribution_function_inv(.71)
     577        2.91979064481
     578
     579    The binomial distribution has two parameters ``n`` and ``p``::
     580
     581        sage: n = 20
     582        sage: p = 0.1
     583        sage: T = RealDistribution('binom', [p, n])
     584        sage: T.get_random_element() # random
     585        2.0
     586        sage: T.distribution_function(1)
     587        0.270170343535
     588        sage: T.cum_distribution_function(3)
     589        0.867046676566
     590
     591    The poisson distribution has one parameter ``p``::
     592
     593        sage: p = 1
     594        sage: T = RealDistribution('pois', [p])
     595        sage: T.get_random_element() # random
     596        2.0
     597        sage: T.distribution_function(1)
     598        0.367879441171
     599        sage: T.cum_distribution_function(3)
     600        0.981011843124
     601
     602    The geometric distribution has one parameter ``p``::
     603
     604        sage: p = 0.2
     605        sage: T = RealDistribution('geom', [p])
     606        sage: T.get_random_element() # random
     607        1.0
     608        sage: T.distribution_function(1)
     609        0.2
     610        sage: T.cum_distribution_function(3)
     611        0.488
     612
     613    The negative binomial distribution has two parameters ``p`` and ``r``::
     614
     615        sage: p = 0.6
     616        sage: r = 1
     617        sage: T = RealDistribution('nbinom', [p,r])
     618        sage: T.get_random_element() # random
     619        1.0
     620        sage: T.distribution_function(1)
     621        0.24
     622        sage: T.cum_distribution_function(3)
     623        0.9744
     624
     625    The hypergeometric distribution has three parameters ``n1``, ``n2``, and ``t``::
     626
     627        sage: n1 = 25
     628        sage: n2 = 40
     629        sage: t = 10
     630        sage: T = RealDistribution('hyper', [n1,n2,t])
     631        sage: T.get_random_element() # random
     632        7.0
     633        sage: T.distribution_function(2)
     634        0.096
     635        sage: T.cum_distribution_function(2)
     636        0.936
     637
    447638    It is possible to select which random number generator drives the
    448639    sampling as well as the seed.  The default is the Mersenne
    449640    twister. Also available are the RANDLXS algorithm and the
     
    584775            result = gsl_ran_weibull(self.r, self.parameters[0], self.parameters[1])
    585776        elif self.distribution_type == beta:
    586777            result = gsl_ran_beta(self.r, self.parameters[0], self.parameters[1])
     778        elif self.distribution_type == expon:
     779            result = gsl_ran_exponential(self.r, self.parameters[0])
     780        elif self.distribution_type == laplace:
     781            result = gsl_ran_laplace(self.r, self.parameters[0])
     782        elif self.distribution_type == cauchy:
     783            result = gsl_ran_cauchy(self.r, self.parameters[0])
     784        elif self.distribution_type == landau:
     785            result = gsl_ran_landau(self.r)
     786        elif self.distribution_type == gamma:
     787            result = gsl_ran_gamma(self.r, self.parameters[0], self.parameters[1])
     788        elif self.distribution_type == logistic:
     789            result = gsl_ran_logistic(self.r, self.parameters[0])
     790        elif self.distribution_type == gumbel1:
     791            result = gsl_ran_gumbel1(self.r, self.parameters[0], self.parameters[1])
     792        elif self.distribution_type == gumbel2:
     793            result = gsl_ran_gumbel2(self.r, self.parameters[0], self.parameters[1])
     794        elif self.distribution_type == binom:
     795            result = gsl_ran_binomial(self.r, self.parameters[0], int(self.parameters[1]))
     796        elif self.distribution_type == pois:
     797            result = gsl_ran_poisson(self.r, self.parameters[0])
     798        elif self.distribution_type == geom:
     799            result = gsl_ran_geometric(self.r, self.parameters[0])
     800        elif self.distribution_type == nbinom:
     801            result = gsl_ran_negative_binomial(self.r, self.parameters[0], self.parameters[1])
     802        elif self.distribution_type == hyper:
     803            result = gsl_ran_hypergeometric(self.r, int(self.parameters[0]), int(self.parameters[1]), int(self.parameters[2]))
    587804        else:
    588             raise TypeError, "Not a valid probability distribution"
    589  
     805            raise TypeError, "Probability distribution not supported"
     806    
    590807        return sage.rings.real_double.RDF(result)
    591 
    592808    def set_distribution(self, name = 'uniform', parameters = []):
    593809        """
    594810        This method can be called to change the current probability distribution.
     
    648864                    float(x)
    649865                except:
    650866                    raise TypeError, "Lognormal distributions requires real parameters"
     867 
    651868            self.parameters = <double*>malloc(sizeof(double)*2)
    652869            self.parameters[0] = float(parameters[0])
    653870            self.parameters[1] = float(parameters[1])
     
    687904                    float(x)
    688905                except:
    689906                    raise TypeError, "exponential power distributions requires real parameters"
     907 
    690908            self.parameters = <double*>malloc(sizeof(double)*2)
    691909            self.parameters[0] = float(parameters[0])
    692910            self.parameters[1] = float(parameters[1])
     
    698916                map(float, parameters)
    699917            except:
    700918                raise TypeError, "weibull distribution requires real parameters"
     919
    701920            self.parameters = <double *>malloc(sizeof(double)*2)
    702921            self.parameters[0] = float(parameters[0])
    703922            self.parameters[1] = float(parameters[1])
    704923            self.distribution_type = weibull
     924 
    705925        elif name == 'beta':
    706926            if len(parameters) != 2:
    707927                raise TypeError, "beta distribution requires two real parameters"
     
    709929                map(float, parameters)
    710930            except:
    711931                raise TypeError, "beta distribution requires real parameters"
     932
    712933            self.parameters = <double *>malloc(sizeof(double)*2)
    713934            self.parameters[0] = float(parameters[0])
    714935            self.parameters[1] = float(parameters[1])
    715936            self.distribution_type = beta
     937 
     938        elif name == 'exp':
     939            if len(parameters) != 1:
     940                raise TypeError, "exponential distribution requires one real parameter"
     941            try:
     942                map(float, parameters)
     943            except:
     944                raise TypeError, "exponential distribution requires a real parameter"
     945
     946            self.parameters = <double *>malloc(sizeof(double)*1)
     947            self.parameters[0] = float(parameters[0])
     948            self.distribution_type = expon
     949 
     950        elif name == 'laplace':
     951            if len(parameters) != 1:
     952                raise TypeError, "laplace distribution requires one real parameter"
     953            try:
     954                map(float, parameters)
     955            except:
     956                raise TypeError, "laplace distribution requires a real parameter"
     957
     958            self.parameters = <double *>malloc(sizeof(double)*1)
     959            self.parameters[0] = float(parameters[0])
     960            self.distribution_type = laplace
     961 
     962        elif name == 'cauchy':
     963            if len(parameters) != 1:
     964                raise TypeError, "cauchy distribution requires one real parameter"
     965            try:
     966                map(float, parameters)
     967            except:
     968                raise TypeError, "cauchy distribution requires a real parameter"
     969
     970            self.parameters = <double *>malloc(sizeof(double)*1)
     971            self.parameters[0] = float(parameters[0])
     972            self.distribution_type = cauchy
     973 
     974        elif name == 'landau':
     975            if len(parameters) != 0:
     976                raise TypeError, "landau distribution requires no real parameter"
     977            try:
     978                map(float, parameters)
     979            except:
     980                raise TypeError, "landau distribution requires no real parameter"
     981
     982            self.parameters = <double *>malloc(sizeof(double)*1)
     983            self.distribution_type = landau
     984 
     985        elif name == 'gamma':
     986            if len(parameters) != 2:
     987                raise TypeError, "gamma distribution requires two real parameters"
     988            try:
     989                map(float, parameters)
     990            except:
     991                raise TypeError, "gamma distribution requires real parameters"
     992
     993            self.parameters = <double *>malloc(sizeof(double)*2)
     994            self.parameters[0] = float(parameters[0])
     995            self.parameters[1] = float(parameters[1])
     996            self.distribution_type = gamma
     997 
     998        elif name == 'logistic':
     999            if len(parameters) != 1:
     1000                raise TypeError, "logistic distribution requires one real parameter"
     1001            try:
     1002                map(float, parameters)
     1003            except:
     1004                raise TypeError, "logistic distribution requires one real parameter"
     1005
     1006            self.parameters = <double *>malloc(sizeof(double)*1)
     1007            self.parameters[0] = float(parameters[0])
     1008            self.distribution_type = logistic
     1009 
     1010        elif name == 'gumbel1':
     1011            if len(parameters) != 2:
     1012                raise TypeError, "gumbel type 1 distribution requires two real parameters"
     1013            try:
     1014                map(float, parameters)
     1015            except:
     1016                raise TypeError, "gumbel type 1 distribution requires real parameters"
     1017
     1018            self.parameters = <double *>malloc(sizeof(double)*2)
     1019            self.parameters[0] = float(parameters[0])
     1020            self.parameters[1] = float(parameters[1])
     1021            self.distribution_type = gumbel1
     1022
     1023        elif name == 'gumbel2':
     1024            if len(parameters) != 2:
     1025                raise TypeError, "gumbel type 2 distribution requires two real parameters"
     1026            try:
     1027                map(float, parameters)
     1028            except:
     1029                raise TypeError, "gumbel type 2 distribution requires real parameters"
     1030
     1031            self.parameters = <double *>malloc(sizeof(double)*2)
     1032            self.parameters[0] = float(parameters[0])
     1033            self.parameters[1] = float(parameters[1])
     1034            self.distribution_type = gumbel2
     1035
     1036        elif name == 'binom':
     1037            if len(parameters) != 2:
     1038                raise TypeError, "binomial distribution requires one real and one integer parameters"
     1039            try:
     1040                map(float, parameters)
     1041            except:
     1042                raise TypeError, "binomial distribution requires one real and one integer parameters"
     1043
     1044            self.parameters = <double *>malloc(sizeof(double)*2)
     1045            self.parameters[0] = float(parameters[0])
     1046            self.parameters[1] = int(parameters[1])
     1047            self.distribution_type = binom
     1048 
     1049        elif name == 'pois':
     1050            if len(parameters) != 1:
     1051                raise TypeError, "Poisson distribution requires one real parameters"
     1052            try:
     1053                map(float, parameters)
     1054            except:
     1055                raise TypeError, "Poisson distribution requires one real parameter"
     1056
     1057            self.parameters = <double *>malloc(sizeof(double)*1)
     1058            self.parameters[0] = float(parameters[0])
     1059            self.distribution_type = pois
     1060 
     1061        elif name == 'geom':
     1062            if len(parameters) != 1:
     1063                raise TypeError, "geometric distribution requires one real parameters"
     1064            try:
     1065                map(float, parameters)
     1066            except:
     1067                raise TypeError, "geometric distribution requires one real parameter"
     1068
     1069            self.parameters = <double *>malloc(sizeof(double)*1)
     1070            self.parameters[0] = float(parameters[0])
     1071            self.distribution_type = geom
     1072
     1073        elif name == 'nbinom':
     1074            if len(parameters) != 2:
     1075                raise TypeError, "negative binomial distribution requires two real parameters"
     1076            try:
     1077                map(float, parameters)
     1078            except:
     1079                raise TypeError, "negative binomial distribution requires real parameters"
     1080
     1081            self.parameters = <double *>malloc(sizeof(double)*2)
     1082            self.parameters[0] = float(parameters[0])
     1083            self.parameters[1] = float(parameters[1])
     1084            self.distribution_type = nbinom
     1085 
     1086        elif name == 'hyper':
     1087            if len(parameters) != 3:
     1088                raise TypeError, "hypergeometric distribution requires three integer parameters"
     1089            try:
     1090                map(float, parameters)
     1091            except:
     1092                raise TypeError, "hypergeometric distribution requires integer parameters"
     1093
     1094            self.parameters = <double *>malloc(sizeof(double)*3)
     1095            self.parameters[0] = int(parameters[0])
     1096            self.parameters[1] = int(parameters[1])
     1097            self.parameters[2] = int(parameters[2])
     1098            self.distribution_type = hyper
     1099 
    7161100        else:
    717             raise TypeError, "Not a valid probability distribution"
     1101            raise TypeError, "Probability distribution not supported"
    7181102 
    7191103        self.name = name
    7201104 
    721     #def _get_random_element_c():
     1105  # def _get_random_element_c():
    7221106 
     1107
    7231108    def reset_distribution(self):
    7241109        """
    7251110        This method resets the distribution.
     
    7791164            return sage.rings.real_double.RDF(gsl_ran_weibull_pdf(x, self.parameters[0], self.parameters[1]))
    7801165        elif self.distribution_type == beta:
    7811166            return sage.rings.real_double.RDF(gsl_ran_beta_pdf(x, self.parameters[0], self.parameters[1]))
     1167        elif self.distribution_type == expon:
     1168            return sage.rings.real_double.RDF(gsl_ran_exponential_pdf(x, self.parameters[0]))
     1169        elif self.distribution_type == laplace:
     1170            return sage.rings.real_double.RDF(gsl_ran_laplace_pdf(x, self.parameters[0]))
     1171        elif self.distribution_type == cauchy:
     1172            return sage.rings.real_double.RDF(gsl_ran_cauchy_pdf(x, self.parameters[0]))
     1173        elif self.distribution_type == landau:
     1174            return sage.rings.real_double.RDF(gsl_ran_landau_pdf(x))
     1175        elif self.distribution_type == gamma:
     1176            return sage.rings.real_double.RDF(gsl_ran_gamma_pdf(x, self.parameters[0], self.parameters[1]))
     1177        elif self.distribution_type == logistic:
     1178            return sage.rings.real_double.RDF(gsl_ran_logistic_pdf(x, self.parameters[0]))
     1179        elif self.distribution_type == gumbel1:
     1180            return sage.rings.real_double.RDF(gsl_ran_gumbel1_pdf(x, self.parameters[0], self.parameters[1]))
     1181        elif self.distribution_type == gumbel2:
     1182            return sage.rings.real_double.RDF(gsl_ran_gumbel2_pdf(x, self.parameters[0], self.parameters[1]))
     1183        elif self.distribution_type == binom:
     1184            return sage.rings.real_double.RDF(gsl_ran_binomial_pdf(x, self.parameters[0], int(self.parameters[1])))
     1185        elif self.distribution_type == pois:
     1186            return sage.rings.real_double.RDF(gsl_ran_poisson_pdf(x, self.parameters[0]))
     1187        elif self.distribution_type == geom:
     1188            return sage.rings.real_double.RDF(gsl_ran_geometric_pdf(x, self.parameters[0]))
     1189        elif self.distribution_type == nbinom:
     1190            return sage.rings.real_double.RDF(gsl_ran_negative_binomial_pdf(x, self.parameters[0], self.parameters[1]))
     1191        elif self.distribution_type == hyper:
     1192            return sage.rings.real_double.RDF(gsl_ran_hypergeometric_pdf(x, int(self.parameters[0]), int(self.parameters[1]), int(self.parameters[2])))
    7821193        else:
    783             raise TypeError, "Not a valid probability distribution"
     1194            raise TypeError, "Probability distribution not supported"
    7841195
    7851196    def cum_distribution_function(self, x):
    7861197        """
     
    8151226            return sage.rings.real_double.RDF(gsl_cdf_weibull_P(x, self.parameters[0], self.parameters[1]))
    8161227        elif self.distribution_type == beta:
    8171228            return sage.rings.real_double.RDF(gsl_cdf_beta_P(x, self.parameters[0], self.parameters[1]))
     1229        elif self.distribution_type == expon:
     1230            return sage.rings.real_double.RDF(gsl_cdf_exponential_P(x, self.parameters[0]))
     1231        elif self.distribution_type == laplace:
     1232            return sage.rings.real_double.RDF(gsl_cdf_laplace_P(x, self.parameters[0]))
     1233        elif self.distribution_type == cauchy:
     1234            return sage.rings.real_double.RDF(gsl_cdf_cauchy_P(x, self.parameters[0]))
     1235        elif self.distribution_type == landau:
     1236            raise TypeError, "Cumulative probability function for landau distribution not defined"
     1237        elif self.distribution_type == gamma:
     1238            return sage.rings.real_double.RDF(gsl_cdf_gamma_P(x, self.parameters[0], self.parameters[1]))
     1239        elif self.distribution_type == logistic:
     1240            return sage.rings.real_double.RDF(gsl_cdf_logistic_P(x, self.parameters[0]))
     1241        elif self.distribution_type == gumbel1:
     1242            return sage.rings.real_double.RDF(gsl_cdf_gumbel1_P(x, self.parameters[0], self.parameters[1]))
     1243        elif self.distribution_type == gumbel2:
     1244            return sage.rings.real_double.RDF(gsl_cdf_gumbel2_P(x, self.parameters[0], self.parameters[1]))
     1245        elif self.distribution_type == binom:
     1246            return sage.rings.real_double.RDF(gsl_cdf_binomial_P(x, self.parameters[0], int(self.parameters[1])))
     1247        elif self.distribution_type == pois:
     1248            return sage.rings.real_double.RDF(gsl_cdf_poisson_P(x, self.parameters[0]))
     1249        elif self.distribution_type == geom:
     1250            return sage.rings.real_double.RDF(gsl_cdf_geometric_P(x, self.parameters[0]))
     1251        elif self.distribution_type == nbinom:
     1252            return sage.rings.real_double.RDF(gsl_cdf_negative_binomial_P(x, self.parameters[0], self.parameters[1]))
     1253        elif self.distribution_type == hyper:
     1254            return sage.rings.real_double.RDF(gsl_cdf_hypergeometric_P(x, int(self.parameters[0]), int(self.parameters[1]), int(self.parameters[2])))
    8181255        else:
    819             raise TypeError, "Not a valid probability distribution"
     1256            raise TypeError, "Probability distribution not supported"
    8201257 
     1258
    8211259    def cum_distribution_function_inv(self, x):
    8221260        """
    8231261        Evaluate the inverse of the cumulative distribution
     
    8461284        elif self.distribution_type == chisquared:
    8471285            return sage.rings.real_double.RDF(gsl_cdf_chisq_Pinv(x, self.parameters[0]))
    8481286        elif self.distribution_type == exppow:
    849             raise NotImplementedError, "gsl does not provide inverse for exponential power"
    850 #            return sage.rings.real_double.RDF(gsl_cdf_exppow_Pinv(x, self.parameters[0], self.parameters[1]))
     1287            raise NotImplementedError, "Inverted cumulative probability function for exponential power distribution not defined"
    8511288        elif self.distribution_type == weibull:
    8521289            return sage.rings.real_double.RDF(gsl_cdf_weibull_Pinv(x, self.parameters[0], self.parameters[1]))
    8531290        elif self.distribution_type == beta:
    8541291            return sage.rings.real_double.RDF(gsl_cdf_beta_Pinv(x, self.parameters[0], self.parameters[1]))
     1292        elif self.distribution_type == expon:
     1293            return sage.rings.real_double.RDF(gsl_cdf_exponential_Pinv(x, self.parameters[0]))
     1294        elif self.distribution_type == laplace:
     1295            return sage.rings.real_double.RDF(gsl_cdf_laplace_Pinv(x, self.parameters[0]))
     1296        elif self.distribution_type == cauchy:
     1297            return sage.rings.real_double.RDF(gsl_cdf_cauchy_Pinv(x, self.parameters[0]))
     1298        elif self.distribution_type == landau:
     1299            raise NotImplementedError, "Inverted cumulative probability function for landau distribution not defined"
     1300        elif self.distribution_type == gamma:
     1301            return sage.rings.real_double.RDF(gsl_cdf_gamma_Pinv(x, self.parameters[0], self.parameters[1]))
     1302        elif self.distribution_type == logistic:
     1303            return sage.rings.real_double.RDF(gsl_cdf_logistic_Pinv(x, self.parameters[0]))
     1304        elif self.distribution_type == gumbel1:
     1305            return sage.rings.real_double.RDF(gsl_cdf_gumbel1_Pinv(x, self.parameters[0], self.parameters[1]))
     1306        elif self.distribution_type == gumbel2:
     1307            return sage.rings.real_double.RDF(gsl_cdf_gumbel2_Pinv(x, self.parameters[0], self.parameters[1]))
     1308        elif self.distribution_type == binom:
     1309            raise NotImplementedError, "Inverted cumulative probability function for binomial distribution not defined"
     1310        elif self.distribution_type == pois:
     1311            raise NotImplementedError, "Inverted cumulative probability function for poisson distribution not defined"
     1312        elif self.distribution_type == geom:
     1313            raise NotImplementedError, "Inverted cumulative probability function for geometric distribution not defined"
     1314        elif self.distribution_type == nbinom:
     1315            raise NotImplementedError, "Inverted cumulative probability function for negative binomial distribution not defined"
     1316        elif self.distribution_type == hyper:
     1317            raise NotImplementedError, "Inverted cumulative probability function for hypergeometric distribution not defined"
    8551318        else:
    856             raise TypeError, "Not a valid probability distribution"
     1319            raise TypeError, "Probability distribution not supported"
    8571320 
    8581321    def plot(self, *args, **kwds):
    8591322        """
     
    8661329            sage: T = RealDistribution('uniform', [0, 2])
    8671330            sage: P = T.plot()
    8681331        """
    869 
    870         return sage.plot.plot.plot(self.distribution_function, *args, **kwds)
     1332        if self.distribution_type == binom:
     1333            if len(args) == 0:
     1334                n1 = 0
     1335                n2 = int(self.parameters[1])
     1336            elif len(args) == 1:
     1337                n1 = args[0]
     1338                n2 = int(self.parameters[1])
     1339            else:
     1340                n1 = args[0]
     1341                n2 = args[1]
     1342        elif self.distribution_type == pois or self.distribution_type == geom or self.distribution_type == nbinom or self.distribution_type == hyper:
     1343            if len(args) < 2:
     1344                n1 = 0
     1345                n2 = 20
     1346            else:
     1347                n1 = args[0]
     1348                n2 = args[1]
     1349        else:
     1350            return sage.plot.plot.plot(self.distribution_function, *args, **kwds)
     1351           
     1352        L = []
     1353        for i in range (n1,n2):
     1354            L.append((i,0))
     1355            L.append((i,self.distribution_function(i)))
     1356            L.append((i,0))
     1357        return sage.plot.line.line(L, **kwds)
    8711358 
    8721359cdef class GeneralDiscreteDistribution(ProbabilityDistribution):
    8731360    """