Attribute VB_Name = "bas_k0_rand" '======================================================================== ' Manuel de la Herrán Gascón - mherran@aircenter.net '======================================================================== Option Explicit Option Base 1 '------------------------------------------------------------------------ ' k: módulos comunes a más de un proyecto ' Este módulo contiene: ' Funciones pseudoaleatorias (casi azar) ' Pseudorandom functions '------------------------------------------------------------------------ ' Funciones que generan valores pseudoaleatorios ' distribuyéndose la probabilidad de los valores ' según cierta distribución estimada ' Todas las funciones se basan en la función de ruido blanco (uniforme): ' randDistContUnif01 ' Si se cambia el metodo de calcular esta función, ' se cambiará el efecto de todas las demás ' Como opciones a la hora de calcular randDistContUnif01 se ofrecen: ' - Rnd de Visual Basic ' - Los N primeros decimales del número PI contenidos en un fichero ' - El contenido de un fichero cualquiera '------------------------------------------------------------------------ ' ABREVIATURAS ' Unif=Uniforme: todos los valores tienen igual probabilidad ' Norm=Normal: las probabilidades se distribuyen en forma de campana de Gauss ' Bern=Bernoulli: discreta, dos valores con probabilidad elegida por el usuario ' User=Usuario: discreta, N valores con probabilidades elegidas por el usuario ' Disc=discreta: los valores devueltos están separados por una distancia constante conocida Step (habitualmente Step=1) ' Cont=pseudoContinua: se devuelve un valor con el máximo detalle en decimales soportado por el ordenador (double) ' Lb=Lower Bound: Límite Inferior del valor devuelto, inclusive ' Ub=Upper Bound: Límite Superior del valor devuelto, inclusive ' Step=paso: distancia entre unos y otros valores en una distribución discreta (habitualmente Step=1) ' M=media, valor medio de todos los valores devueltos (positivo o negativo) ' Dt=desviación típica, dispersión. Indica la forma de la campana de Gauss. Raiz cuadrada de la varianza ' Dt siempre es positivo, entre 0 e infinito ' Dt>1 Leptocúrtica, estirada, muy concentrados, montaña ' Dt=1 Mesocúrtica, aspecto clasico de de Normal(0,1) gaussiana, colina ' Dt<1 Platocúrtica, achatada, muy dispersos, tiende a una uniforme, duna ' Nota: La media no tiene porqué estar entre Lb y Ub ' El caso normal es Lb < M < Ub, pero no es obligatorio '------------------------------------------------------------------------ ' Notas: ' Todas las distribuciones continuas devuelven un double ' Cuando hay probabilidades como parametros de entrada, ' estas probabilidades son valores double entre 0 y 1 '------------------------------------------------------------------------ ' ===DISCRETAS=== ' randDistDiscUnifTrueFalse_b ' randDistDiscUnif01_i ' randDistDiscUnif01_l ' randDistDiscUnifLbUbStep_d ' randDistDiscUnifLbUbStepExceptionUser_d ' randDistDiscUnif1Ub1_i ' randDistDiscUnif1Ub1_l ' randDistDiscUnifLbUb1_i ' randDistDiscUnifLbUb1_l ' randDistDiscNormLbUbMDtStep_d ' randDistDiscBernTrueFalse_b ' randDistDiscBern01_i ' randDistDiscBern01_l ' randDistDiscUser_d ' randDistDiscUser_s ' randDistDiscUser_l ' randDistDiscUser_i ' ===CONTINUAS=== ' randDistContUnif01 ' randDistContUnif1Ub ' randDistContUnifLbUb ' randDistContNormLbLbUbMDt '------------------------------------------------------------------------ ' AGRADECIMIENTOS: (contributed by:) ' ' Héctor Rodrigo ' ============== ' Método de cálculo de Normal(0,1) mediante el teorema central del límite ' y ampliación del método de calculo de Normal(0,1) para el cálculo de Normal(m,v) ' (Este método es el método elegido) ' ' Phil Beffrey y Mattias Fagerlund ' ================================ ' phil@pixar.com, matfa@acacia.se ' Método de cálculo de Normal mediante el cálculo de la media ' de varios numeros (unos 12 ejemplos) generados al azar con una distribucion uniforme ' ' Evan Hughes y Antonio Carpintero Sanchez ' ======================================== ' E.J.Hughes@rmcs.cranfield.ac.uk ' http://www.rmcs.cranfield.ac.uk/~daps/daps/pgrads/e_h/hughes.htm ' amcarpintero@polar.es ' ' Box-Muller method ' Método de cálculo de Normal mediante el algoritmo obtenido de: ' author = "William H. Press and Brian P. Flannery and Saul A. Teukolsky and William T. Vetterling" ' Title = "{NUMERICAL RECIPES} The Art Of Scientific Computing ({FORTRAN}Version)" ' publisher = "Cambridge University Press" ' Year = "1989" ' Existe tambien el libro "NUMERICAL RECIPES IN C", de William H. Press) '------------------------------------------------------------------------ 'Fichero de Azar Global digitos_azar() As Integer 'chorro de numeros Global azar_en_memoria As Boolean 'dice si efectivamente esta cargada o no la serie de numeros Global indice_azar As Long 'puntero al valor actual del chorro de numeros 'Gauss Global hay_solucion_anterior_gauss As Boolean Global solucion_anterior_gauss As Double Function randDistDiscUnifTrueFalse_b() As Boolean If randDistContUnif01 < 0.5 Then randDistDiscUnifTrueFalse_b = True Else randDistDiscUnifTrueFalse_b = False End If End Function Function randDistDiscUnif01_i() As Integer 'Ojo: es int (parte entera) y no cint (convertir a integer) randDistDiscUnif01_i = Int(randDistContUnif01 + 0.5) End Function Function randDistDiscUnif01_l() As Long 'Ojo: es int (parte entera) y no cint (convertir a integer) randDistDiscUnif01_l = Int(randDistContUnif01 + 0.5) End Function Function randDistDiscUnifMemLbUbMDt_d(Lb As Double, Ub As Double, myStep As Double, M As Double, Dt As Double) As Double 'Creamos un numero con todos los decimales en continua 'Le quitamos lo que le sobra al numero para dejarlo en unidades de Step Dim continua As Double Dim cociente As Double continua = randDistContNormMemLbUbMDt(Lb, Ub, M, Dt) cociente = continua / myStep randDistDiscUnifMemLbUbMDt_d = continua - myStep * (cociente - Int(cociente)) End Function Function randDistDiscUnifLbUbStep_d(Lb As Double, Ub As Double, myStep As Double) As Double 'Creamos un numero con todos los decimales en continua 'Le quitamos lo que le sobra al numero para dejarlo en unidades de Step Dim continua As Double Dim cociente As Double continua = ((Ub - Lb + 1) * randDistContUnif01 + Lb) cociente = continua / myStep randDistDiscUnifLbUbStep_d = continua - myStep * (cociente - Int(cociente)) End Function Function randDistDiscUnifLbUbStepExceptionUser_d(Lb As Double, Ub As Double, myStep As Double, dataSet() As Double, probSet() As Double, totalExceptionProb As Double) As Double 'Con una probabilidad de totalExceptionProb 'se comporta como una distribución de probabilidad de usuario 'y en caso contrario es una normal 'El objetivo de esto es, por ejemplo, obtener una distribución 'normal con algunas excepciones con mucha probabilidad If randDistDiscBernTrueFalse_b(totalExceptionProb) Then 'Va a salir un numero que es del conjunto de excepciones randDistDiscUnifLbUbStepExceptionUser_d = randDistDiscUser_d(dataSet(), probSet()) Else randDistDiscUnifLbUbStepExceptionUser_d = randDistDiscUnifLbUbStep_d(Lb, Ub, myStep) End If End Function Function randDistDiscUnif1Ub1_i(Ub As Integer) As Integer 'Devuleve un número al azar entero 'entre 1 y fin, inclusive ambos 'La probabilidad es igual para todos los números 'Ojo: es int (parte entera) y no cint (convertir a integer) randDistDiscUnif1Ub1_i = Int(Ub * randDistContUnif01 + 1) End Function Function randDistDiscUnif1Ub1_l(Ub As Long) As Long 'Devuleve un número al azar entero 'entre 1 y fin, inclusive ambos 'La probabilidad es igual para todos los números 'Ojo: es int (parte entera) y no cint (convertir a integer) randDistDiscUnif1Ub1_l = Int(Ub * randDistContUnif01 + 1) End Function Function randDistDiscUnifLbUb1_i(Lb As Integer, Ub As Integer) As Integer 'Devuleve un número al azar entero 'entre inicio y fin, inclusive ambos 'La probabilidad es igual para todos los números 'Se admiten valores negativos 'Metodo 1 'randDistDiscUnifLbUb1_i = randDistDiscUnif1Ub1_i(Ub - Lb + 1) + Lb - 1 'Metodo 2 randDistDiscUnifLbUb1_i = Int((Ub - Lb + 1) * randDistContUnif01 + Lb) End Function Function randDistDiscUnifLbUb1_l(Lb As Long, Ub As Long) As Long 'Devuleve un número al azar entero 'entre inicio y fin, inclusive ambos 'La probabilidad es igual para todos los números 'Se admiten valores negativos 'Metodo 1 'randDistDiscUnifLbUb1_l = randDistDiscUnif1Ub1_l(Ub - Lb + 1) + Lb - 1 'Metodo 2 randDistDiscUnifLbUb1_l = Int((Ub - Lb + 1) * randDistContUnif01 + Lb) End Function Function randDistDiscNormLbUbMDtStep_d(Lb As Double, Ub As Double, M As Double, Dt As Double, myStep As Double) As Double 'Creamos un numero con todos los decimales en continua 'Le quitamos lo que le sobra al numero para dejarlo en unidades de Step 'Ejemplo de uso: 'randDistDiscNormLbUbMDtStep_d(1, 100, 50, 5, 1) 'Devuelve un numero entero (Step=1) 'entre 1 y 100 'el 50 es el mas probable (media) 'y los menos probables son el 1 y el 100 Dim continua As Double Dim cociente As Double continua = randDistContNormLbUbMDt(Lb, Ub, M, Dt) cociente = continua / myStep randDistDiscNormLbUbMDtStep_d = continua - myStep * (cociente - Int(cociente)) End Function Sub randDistDiscNorm2DLbUbMDtStep_d(Lb As Double, Ub As Double, MD1 As Double, MD2 As Double, Dt As Double, myStep As Double, retD1 As Double, retD2 As Double) Dim continua As Double Dim cociente As Double continua = randDistContNormLbUbMDt(Lb, Ub, MD1, Dt) cociente = continua / myStep retD1 = continua - myStep * (cociente - Int(cociente)) continua = randDistContNormLbUbMDt(Lb, Ub, MD2, Dt) cociente = continua / myStep retD2 = continua - myStep * (cociente - Int(cociente)) End Sub Function randDistDiscMultiNormLbUbMDtStep_d(Lb As Double, Ub As Double, M() As Double, Dt As Double, myStep As Double) As Double 'Se elige una de las medias con probabilidad uniforme Dim continua As Double Dim cociente As Double continua = randDistContNormLbUbMDt(Lb, Ub, M(randDistDiscUnifLbUb1_l(LBound(M), UBound(M))), Dt) cociente = continua / myStep randDistDiscMultiNormLbUbMDtStep_d = continua - myStep * (cociente - Int(cociente)) End Function Function randDistDiscBernTrueFalse_b(pTrue As Double) As Boolean If randDistContUnif01 < pTrue Then randDistDiscBernTrueFalse_b = True Else randDistDiscBernTrueFalse_b = False End If End Function Function randDistDiscBern01_i(pZero As Double) As Integer If randDistContUnif01 < pZero Then randDistDiscBern01_i = 0 Else randDistDiscBern01_i = 1 End If End Function Function randDistDiscBern01_l(pZero As Double) As Long If randDistContUnif01 < pZero Then randDistDiscBern01_l = 0 Else randDistDiscBern01_l = 1 End If End Function Function randDistDiscUserUnif_d(dataSet() As Double) As Double 'Devuelve uno al azar de los valores de dataSet 'con una probabilidad uniforme Dim i As Long i = randDistDiscUnifLbUb1_l(LBound(dataSet), UBound(dataSet)) randDistDiscUserUnif_d = dataSet(i) End Function Function randDistDiscUserUnif_i(dataSet() As Integer) As Integer 'Devuelve uno al azar de los valores de dataSet 'con una probabilidad uniforme Dim i As Long i = randDistDiscUnifLbUb1_l(LBound(dataSet), UBound(dataSet)) randDistDiscUserUnif_i = dataSet(i) End Function Function randDistDiscUserUnif_l(dataSet() As Long) As Long 'Devuelve uno al azar de los valores de dataSet 'con una probabilidad uniforme Dim i As Long i = randDistDiscUnifLbUb1_l(LBound(dataSet), UBound(dataSet)) randDistDiscUserUnif_l = dataSet(i) End Function Function randDistDiscUserUnif_s(dataSet() As String) As String 'Devuelve uno al azar de los valores de dataSet 'con una probabilidad uniforme Dim i As Long i = randDistDiscUnifLbUb1_l(LBound(dataSet), UBound(dataSet)) randDistDiscUserUnif_s = dataSet(i) End Function Function randDistDiscUser_d(dataSet() As Double, probSet() As Double) As Double 'Devuelve uno al azar de los valores de dataSet 'con una probabilidad que es la expresada en probSet Dim azar As Double Dim i As Long Dim numElem As Long numElem = UBound(dataSet) - LBound(dataSet) + 1 If numElem <> UBound(probSet) - LBound(probSet) + 1 Then Exit Function ReDim tope(1 To numElem) As Double If numElem = 1 Then randDistDiscUser_d = dataSet(1) Exit Function End If tope(1) = probSet(1) For i = 2 To numElem tope(i) = tope(i - 1) + probSet(i) Next i azar = randDistContUnifLbUb(0, tope(numElem)) i = 1 'Búsqueda secuencial en los rangos de probabilidades While azar >= tope(i) And i < numElem i = i + 1 Wend 'Se podria implementar una busqueda binaria en el caso 'de que numElem sea muy grande randDistDiscUser_d = dataSet(i) End Function Function randDistDiscUser_s(dataSet() As String, probSet() As Double) As String Dim azar As Double Dim i As Long Dim numElem As Long numElem = UBound(dataSet) - LBound(dataSet) + 1 ReDim tope(1 To numElem) As Double If numElem = 1 Then randDistDiscUser_s = dataSet(1) Exit Function End If tope(1) = probSet(1) For i = 2 To numElem tope(i) = tope(i - 1) + probSet(i) Next i azar = randDistContUnifLbUb(0, tope(numElem)) i = 1 'Búsqueda secuencial en los rangos de probabilidades While azar >= tope(i) And i < numElem i = i + 1 Wend 'Se podria implementar una busqueda binaria en el caso 'de que numElem sea muy grande randDistDiscUser_s = dataSet(i) End Function Function randDistDiscUser_l(dataSet() As Long, probSet() As Double) As Long Dim azar As Double Dim i As Long Dim numElem As Long numElem = UBound(dataSet) - LBound(dataSet) + 1 ReDim tope(1 To numElem) As Double If numElem = 1 Then randDistDiscUser_l = dataSet(1) Exit Function End If tope(1) = probSet(1) For i = 2 To numElem tope(i) = tope(i - 1) + probSet(i) Next i azar = randDistContUnifLbUb(0, tope(numElem)) i = 1 'Búsqueda secuencial en los rangos de probabilidades While azar >= tope(i) And i < numElem i = i + 1 Wend 'Se podria implementar una busqueda binaria en el caso 'de que numElem sea muy grande randDistDiscUser_l = dataSet(i) End Function Function randDistDiscUser_i(dataSet() As Integer, probSet() As Double) As Integer Dim azar As Double Dim i As Long Dim numElem As Long numElem = UBound(dataSet) - LBound(dataSet) + 1 ReDim tope(1 To numElem) As Double If numElem = 1 Then randDistDiscUser_i = dataSet(1) Exit Function End If tope(1) = probSet(1) For i = 2 To numElem tope(i) = tope(i - 1) + probSet(i) Next i azar = randDistContUnifLbUb(0, tope(numElem)) i = 1 'Búsqueda secuencial en los rangos de probabilidades While azar >= tope(i) And i < numElem i = i + 1 Wend 'Se podria implementar una busqueda binaria en el caso 'de que numElem sea muy grande randDistDiscUser_i = dataSet(i) End Function Function randDistContUnif01() As Double 'Devuelve un valor entre cero (incusive) y uno (exclusive) 'The Rnd function returns a value less than 1 but greater than or equal to zero. 'Before calling Rnd, use the Randomize statement without an argument to initialize the random-number generator with a seed based on the system timer. 'Rnd(number) 'Less than zero The same number every time, using number as the seed. 'Greater than zero The next random number in the sequence. 'Equal to zero The most recently generated number. 'Not supplied The next random number in the sequence. 'For any given initial seed, the same number sequence is generated because each successive call to the Rnd function uses the previous number as a seed for the next number in the sequence. Select Case tipo_funcion_azar_gcf Case CTE_AZARVB randDistContUnif01 = Rnd Case CTE_AZARFIC 'Uso los CTE_NUM_DECIMALES_EXACTITUD_AZARFIC decimales de pi 'a partir de cierta posición 'y pongo un numero que es "0,esos decimales" Dim i As Integer randDistContUnif01 = 0 For i = 1 To CTE_NUM_DECIMALES_EXACTITUD_AZARFIC randDistContUnif01 = randDistContUnif01 + (digitos_azar(indice_azar) / (10 ^ i)) 'Actualizo el indice que apunta al azar indice_azar = fl_SumCirc(azar_fichero_num_char_gcf, indice_azar, 1) Next i 'Una vez ejecutado el bucle, 'he saltado CTE_NUM_DECIMALES_EXACTITUD_AZARFIC digitos, los que he usado como decimales Case Else s_error_ger CTE_ERROR_GRAVE, "Generador de Pseudoaleatorios no existente" End Select End Function Function randDistContUnif1Ub(Ub As Double) As Double randDistContUnif1Ub = ((Ub - 1) * randDistContUnif01) + 1 End Function Function randDistContNormMemLbUbMDt(Lb As Double, Ub As Double, M As Double, Dt As Double) As Double randDistContNormMemLbUbMDt = randDistContNormLbUbMDt(Lb, Ub, M, Dt) End Function Function randDistContUnifLbUb(Lb As Double, Ub As Double) As Double randDistContUnifLbUb = ((Ub - Lb) * randDistContUnif01) + Lb End Function Function randDistContNormLbUbMDt(Lb As Double, Ub As Double, M As Double, Dt As Double) As Double 'Devuelve un numero al azar entre LI y LS 'segun una distribución normal o gaussiana (es lo mismo) 'con una cierta media y desviación tipica 'con forma de campana de gauss 'de forma que devuelve con mayor probabilidad valores 'cercanos a la media que hemos fijado Dim suma_azar As Double Dim i As Integer Dim calidad As Integer Dim metodo As Integer Dim dispersion_uniforme_generadora As Double Dim media_uniforme_generadora As Double 'Aqui aparecen programados varios metodos, pero 'el usado es el llamado 1 'Para metodo = 1 metodo = 1 calidad = 10 dispersion_uniforme_generadora = Sqr(12 / calidad) media_uniforme_generadora = calidad / 2 'Para metodo = 3 Dim devolver As Double Dim valor1 As Double Dim valor2 As Double Dim factor As Double Select Case metodo Case 1 'Metodo 1 '===================================================== 'Propuesto por Héctor Rodrigo 'Teorema central del límite '===================================================== 'Para obligar a unos limites tendre que hacer un bucle 'que la llame constantemente hasta que caiga ahí 'Esto calcula una normal entre -infinito e infinito randDistContNormLbUbMDt = Lb - 1 While randDistContNormLbUbMDt < Lb Or randDistContNormLbUbMDt > Ub suma_azar = 0 For i = 1 To calidad suma_azar = suma_azar + randDistContUnif01 DoEvents Next i randDistContNormLbUbMDt = M + (Dt * dispersion_uniforme_generadora * (suma_azar - media_uniforme_generadora)) Wend '===================================================== Case 2 'Metodo 2 '===================================================== 'Propuesto por Phil Beffrey phil@pixar.com 'y Mattias Fagerlund matfa@acacia.se 'Calcular la media de varios numeros generados al azar con una distribucion uniforme 'bastan unos 12 ejemplos 'La media de una distribución uniforme tiende a una normal 'El problema es como admitir distintas varianzas. 'Se podria hacer que los numeros generados de forma uniforme 'se generen con distintos limites inferior y superior 'Si cada vez vamos reduciendo los limites, reducimos la dispersion 'y si los ampliamos, la aumentamos. El problema es que no 'sabemos cuanto! '===================================================== 'Para obligar a unos limites tendre que hacer un bucle 'que la llame constantemente hasta que caiga ahi randDistContNormLbUbMDt = Lb - 1 While randDistContNormLbUbMDt < Lb Or randDistContNormLbUbMDt > Ub suma_azar = 0 For i = 1 To calidad suma_azar = suma_azar + randDistContUnifLbUb(Lb, Ub) Next i suma_azar = suma_azar / calidad randDistContNormLbUbMDt = suma_azar Wend '===================================================== Case 3 'Metodo 3 '=================================================== 'Obtenido de: 'author = "William H. Press and Brian P. Flannery and Saul A. Teukolsky and William T. Vetterling", 'Title = "{NUMERICAL RECIPES} The Art Of Scientific Computing ({FORTRAN}Version)" 'publisher="Cambridge University Press" 'Year = "1989" '(Existe tambien "NUMERICAL RECIPES IN C", de William H. Press, citado por Vensim) 'Gracias a 'Evan Hughes E.J.Hughes@rmcs.cranfield.ac.uk 'http://www.rmcs.cranfield.ac.uk/~daps/daps/pgrads/e_h/hughes.htm ' suma = 0 ' While suma = 0 Or suma >= 1 ' valor1 = 2 * randDistContUnif01 - 1 ' valor2 = 2 * randDistContUnif01 - 1 ' suma = valor1 * valor1 + valor2 * valor2 ' Wend ' factor = sigma * sqrt(-2 * Log(suma) / suma) ' solucion1 = valor1 * factor + media ' solucion2 = valor2 * factor + media ' '=================================================== 'Posibles errores al traducir de C 'Supongo que rand() devuelve entre 0 y RAND_MAX pero no se incluye el 0 ni el RAND_MAX 'Supongo que sqrt es identico a sqr de VB 'U1 = rand() / RAND_MAX 'U2 = rand() / RAND_MAX 'x1=2*(double)rand()/RAND_MAX-1; 'x2=2*(double)rand()/RAND_MAX-1; 'La media es 0 'y la desviacion tipica o sigma es 1 'Obtenido de Box-Muller method 'gracias a Antonio Carpintero Sanchez amcarpintero@polar.es '===================================================== 'Para obligar a unos limites tendre que hacer un bucle 'que la llame constantemente hasta que caiga ahi randDistContNormLbUbMDt = Lb - 1 While randDistContNormLbUbMDt < Lb Or randDistContNormLbUbMDt > Ub If hay_solucion_anterior_gauss Then devolver = solucion_anterior_gauss Else suma_azar = 1 While suma_azar >= 1 valor1 = 2 * randDistContUnif01 - 1 valor2 = 2 * randDistContUnif01 - 1 suma_azar = valor1 * valor1 + valor2 * valor2 Wend factor = Dt * Sqr(-2 * Log(suma_azar) / suma_azar) devolver = valor1 * factor + M solucion_anterior_gauss = valor2 * factor + M End If hay_solucion_anterior_gauss = Not hay_solucion_anterior_gauss randDistContNormLbUbMDt = devolver Wend '===================================================== End Select End Function Function randDistDiscCantorUnifLbUb(Lb As Double, Ub As Double, stepSet() As Double, probSet() As Double) As Double Dim azar As Double 'Sacamos un valor al azar con el maximo nivel de detalle 'segun una función uniforme azar = randDistContUnifLbUb(Lb, Ub) 'Ahora se discretiza ese valor segun el step indicado 'elegido segun esas probabilidades 'Por ejemplo 'stepSet(1) = 1 'stepSet(2) = 0.1 'stepSet(3) = 0.01 'probSet(1) = 50 'probSet(2) = 40 'probSet(3) = 10 randDistDiscCantorUnifLbUb = cont2disc(azar, randDistDiscUser_d(stepSet(), probSet())) End Function Function randDistDiscCantorNormLbUbMDt(Lb As Double, Ub As Double, M As Double, Dt As Double, stepSet() As Double, probSet() As Double) As Double Dim azar As Double 'Sacamos un valor al azar con el maximo nivel de detalle 'segun una función normal azar = randDistContNormLbUbMDt(Lb, Ub, M, Dt) 'Ahora se discretiza ese valor segun el step indicado 'elegido segun esas probabilidades 'Por ejemplo 'stepSet(1) = 1 'stepSet(2) = 0.1 'stepSet(3) = 0.01 'probSet(1) = 50 'probSet(2) = 40 'probSet(3) = 10 randDistDiscCantorNormLbUbMDt = cont2disc(azar, randDistDiscUser_d(stepSet(), probSet())) End Function