• Publicidad

Programa de mutaciones

Perl aplicado a la bioinformática

Mutaciones random

Notapor mparrado8 » 2013-05-14 03:36 @191

¡Hola de nuevo! Estoy haciendo un programa de mutaciones aleatorias y he visto en muchos ejemplos esta orden, pero no sé lo que significa, ni si es imprescindible para el programa:

srand(time|$$)
mparrado8
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2013-04-10 12:58 @582

Publicidad

Re: Mutaciones random

Notapor explorer » 2013-05-14 05:05 @253

Esa instrucción inicializa la semilla de números aleatorios que se utilizará con rand(). Como argumento tiene la función time(), que devuelve el número de segundos que han pasado desde el uno de enero de 1970. A ese valor, le aplica la operación bit a bit OR, con el valor almacenado en la variable especial $$, que suele ser el número de proceso para ese programa, en el momento de la ejecución, para el sistema operativo (pid).

Recuerda: cuando no sepas lo que es algo, prueba a buscarlo con perldoc, en tu propio ordenador:

perldoc -f srand
Sintáxis: [ Descargar ] [ Ocultar ]
  1.     srand EXPR 
  2.     srand  Establece y devuelve la semilla de números aleatorios para el operador "rand". 
  3.  
  4.         La misión de la función es "alimentar" a la función "rand" para que "rand" pueda 
  5.         producir una secuencia diferente cada vez que ejecute su programa. Cuando se llama 
  6.         con un parámetro, "srand" la usa para la semilla; de lo contrario la elige 
  7.         (semi)-aleatoriamente. En cualquier caso, a partir de Perl 5.14, devuelve la 
  8.         semilla. Para indicar que su código funciona solo en un Perl de una cosecha 
  9.         reciente: 
  10.  
  11.           use 5.014; # así srand devuelve la semilla 
  12.  
  13.         Si "srand()" no es llamada de forma explícita, es llamada implícitamente en el primer 
  14.         uso del operador "rand". Sin embargo, esto no fue cierto para las versiones de Perl 
  15.         anteriores a la 5.004, así que si su programa se va a ejecutar en versiones 
  16.         anteriores de Perl, debería llamar a "srand"; de lo contrario, la mayor parte de los 
  17.         programas no llamarán nunca a "srand". 
  18.  
  19.         Pero hay unas pocas situaciones en programas recientes de Perl donde es probable que 
  20.         desee llamar a "srand". Uno de ellos es para la generación de resultados 
  21.         predecibles, generalmente para pruebas o depuraciones. Allí, puede utilizar 
  22.         "srand($semilla)", con la misma $semilla cada vez. Otro caso es que puede llamar a 
  23.         "srand()" después de un "fork()" para evitar que los procesos hijos compartan el 
  24.         mismo valor de semilla que la del padre (y por lo tanto, entre sí). 
  25.  
  26.         No llame a srand() (e.d., sin un argumento) más de una vez por proceso. El estado 
  27.         interno del generador de números aleatorios debería contener más entropía que la 
  28.         ofrecida por cualquier semilla, así que volver a llamar a srand() realmente hace 
  29.         perder la aleatoriedad. 
  30.  
  31.         La mayoría de las implementaciones de "srand" toman un número entero y 
  32.         silenciosamente truncará los números decimales. Esto significa que "srand(42)" 
  33.         produce los mismos resultados, generalmente, que "srand(42.1)". Para estar seguros, 
  34.         siempre pase un entero a "srand". 
  35.  
  36.         En las versiones de Perl anteriores a 5.004 la semilla por defecto era sólo el valor 
  37.         actual de "time". Esto no es una buena semilla, por lo que demasiados viejos 
  38.         programas tienen sus propias semillas (a menudo "time ^ $$" o "time ^ ($$ + ($$ << 
  39.         15))"), pero esto ya no es necesario. 
  40.  
  41.         Programas ejecutados frecuentemente (como los scripts CGI) usan, simplemente, 
  42.  
  43.           time ^ $$ 
  44.  
  45.         pero la semilla puede caer presa en la propiedad matemática 
  46.  
  47.           a^b == (a+1)^(b+1) 
  48.  
  49.         un tercio de las ocasiones. Así que no lo haga. 
  50.  
  51.         Un uso típico de la semilla devuelta es para un programa de prueba que tiene 
  52.         demasiadas combinaciones que probar, exhaustivamente, en el tiempo disponible para 
  53.         cada ejecución. Se puede probar un subconjunto aleatorio cada vez, y si ocurre un 
  54.         fallo, registre las semillas utilizadas para las que se ha ejecutado a fin de que 
  55.         más adelante se puedan utilizar para reproducir los mismos resultados. 
  56.  
  57.         "rand()" no es criptográficamente seguro. No debe confiar en él en situaciones 
  58.         delicadas de seguridad. Al escribir estas líneas, una serie de módulos de CPAN de 
  59.         terceros ofrecen generadores de números aleatorios destinados, por sus autores, a 
  60.         ser criptográficamente seguros, incluyendo Data::Entropy, Crypt::Random, 
  61.         Math::Random::Secure y Math::TrulyRandom. 

perldoc -f time
Sintáxis: [ Descargar ] [ Ocultar ]
  1.     time  Devuelve el número de segundos no bisiestos desde el momento en que el sistema 
  2.         considera que es el epoch, apto para ser alimentado a "gmtime" y "localtime". En la 
  3.         mayoría de los sistemas el epoch son las 00:00:00 UTC, del 1 de enero de 1970; una 
  4.         prominente excepción es el Mac OS Classic que utiliza las 00:00:00, del 1 de enero 
  5.         de 1904 en la actual zona horaria. 
  6.  
  7.         Para medir el tiempo con una granularidad mayor de un segundo, use el módulo 
  8.         Time::HiRes de Perl 5.8 (o desde CPAN antes de él), o si tiene gettimeofday(2), 
  9.         puede utilizar el interfaz "syscall" de Perl. Vea perlfaq8 para más detalles. 
  10.  
  11.         Para el procesado de fechas y tiempos mire en los módulos relaccionados en CPAN. 
  12.         Para una completa y actualizada representación del tiempo mire el módulo DateTime. 

La información sobre la variable $$ está dentro del documento perlvar. Más información en tu propio ordenador en perldoc perlvar, y en la Web (traducido al español).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14475
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Programa de mutaciones

Notapor eduardoemen » 2013-07-28 10:04 @461

Hola, ¿alguien por favor podría explicarme por qué dentro del bucle for, en $mutant = mutate($mutant);, dentro del paréntesis va $mutant? ¿No es una función, verdad? ¿Es como un índice o qué es?

Gracias de antemano, si alguien puede explicarme esto, por favor. Saludos.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. my $DNA = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
  5. my $i;
  6. my $mutant;
  7. srand( time | $$ );
  8. $mutant = mutate($DNA);
  9. print "\nMutate DNA\n\n";
  10. print "\nHere is the original DNA:\n\n";
  11. print "$DNA\n";
  12. print "\nHere is the mutant DNA:\n\n";
  13. print "$mutant\n";
  14. print "\nHere are 10 more successive mutations:\n\n";
  15.  
  16. for ( $i = 0; $i < 10; ++$i ) {
  17.     $mutant = mutate($mutant);
  18.     print "$mutant\n";
  19. }
  20. exit;
  21.  
  22. sub mutate {
  23.     my ($dna)         = @_;
  24.     my (@nucleotides) = ( 'A', 'C', 'G', 'T' );
  25.     my ($position)    = randomposition($dna);
  26.     my ($newbase)     = randomnucleotide(@nucleotides);
  27.     substr( $dna, $position, 1, $newbase );
  28.     return $dna;
  29. }
  30.  
  31. sub randomelement {
  32.     my (@array) = @_;
  33.     return $array[ rand @array ];
  34. }
  35.  
  36. sub randomnucleotide {
  37.     my (@nucleotides) = ( 'A', 'C', 'G', 'T' );
  38.     return randomelement(@nucleotides);
  39. }
  40.  
  41. sub randomposition {
  42.     my ($string) = @_;
  43.     return int rand length $string;
  44. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
eduardoemen
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2013-07-24 13:25 @601

Re: $mutant = mutate($mutant);

Notapor explorer » 2013-07-28 17:38 @776

Bienvenido a los foros de Perl en Español, eduardoemen.

Sencillamente, es una llamada a una función, mutate(), que está definida en la línea 22.

Quizás llama la atención el hecho de que le estamos pasando como argumento el nombre de una variable, que a su vez recibirá el resultado de la llamada de la función.

Pero es que precisamente es el modo de funcionamiento del programa... una cadena de ADN es mutada, una base cada vez. La cadena de ADN la pasamos como argumento a la función, y ésta nos devuelve la cadena mutada, así que la guardamos en la misma variable, para que el bucle la vuelva a mutar en la siguiente vuelta.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14475
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

srand

Notapor eduardoemen » 2013-08-03 03:33 @189

Hola, buenos días, en un par de ejemplos he visto que hay que determinar una semilla con srand, por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $semilla = 12345;
  2. srand($semilla);
  3. my $azar = rand(14);  # 3.15459917914819  
  4. my $azar = rand();    # 0.919183068533556  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

y también en:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!C:\Perl\perl.exe
  2.  
  3. my $dna = "TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT";
  4. my $i;
  5. my $mutant;
  6. srand( time | $$ );
  7. $mutant = mutate($dna);
  8. print "\nMutate DNA\n\n";
  9. print "\nHere is the original DNA:\n\n";
  10. print "$dna\n";
  11. print "\nHere is the mutant DNA:\n\n";
  12. print "$mutant\n";
  13. print "\nHere are 10 more successive mutations:\n\n";
  14.  
  15. for ( $i = 0; $i < 10; ++$i ) {
  16.     $mutant = mutate($mutant);
  17.     print "$mutant\n";
  18. }
  19. exit;
  20.  
  21. sub mutate {
  22.     my ($dna)         = @_;
  23.     my (@nucleotides) = ( 'A', 'C', 'G', 'T' );
  24.     my ($position)    = randomposition($dna);
  25.     my ($newbase)     = randomnucleotide(@nucleotides);
  26.     substr( $dna, $position, 1, $newbase );
  27.     return $dna;
  28. }
  29.  
  30. sub randomelement {
  31.     my (@array) = @_;
  32.     return $array[ rand @array ];
  33. }
  34.  
  35. sub randomnucleotide {
  36.     my (@nucleotides) = ( 'A', 'C', 'G', 'T' );
  37.     return randomelement(@nucleotides);
  38. }
  39.  
  40. sub randomposition {
  41.     my ($string) = @_;
  42.     return int rand length $string;
  43. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

El asunto es que si saco srand los programas igualmente generan números y letras ( en el segundo ejemplo ) aleatorias.

Mi pregunta es si alguien puede ayudarme, por favor, es: ¿en qué necesidad hay de srand si igual funcionan bien sin dicha función?

Sigo sin comprender srand(time|$$), es que tengo un cursito básico de introducción a la bioinformática y me gustaría compartir con mis alumnos un ejemplo que hay en un pdf llamado Scripting para bioinformáticos. Se trata de simular mutaciones de ADN, pero la explicación es un poco compleja, si podrías por favor ayudarme con una explicación más detallada y sencilla.

Gracias de antemano y un saludo.
eduardoemen
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2013-07-24 13:25 @601

Re: Mutaciones random

Notapor explorer » 2013-08-03 06:25 @309

El objetivo de srand es la de poner una semilla en el motor generador de números aleatorios, para que éste genere una secuencia de números aleatorios.

De alguna manera, si le damos una semilla diferente cada vez, tendremos -casi- garantizadas siempre una diferente secuencia.

Y lo contrario también es cierto: si siempre damos el mismo número de semilla, saldrá la misma secuencia de números, lo cual es muy interesante para la repetición de experimentos.

Por ejemplo, hace años hice un programa que generaba montañas fractales. El programa pedía al principio el número de semilla. Si al final, la escena me gustaba, me apuntaba el número de semilla que había usado. Así, podía volver a ejecutar el programa más tarde, con esa misma semilla, y salía la misma escena.

srand(time|$$) quiere decir:
  • time es la función que devuelve el número de segundos que han pasado desde 1 de enero de 1970. Ver perldoc -f time
  • el operador '|' realiza la operación lógica OR bit a bit, entre los dos operandos. Ver perldoc perlop, sección Bitwise Or and Exclusive Or
  • la variable especial $$ contiene el número de proceso dentro del sistema (el PID) del proceso que se estamos ejecutando en ese momento. Ver perldoc perlvar
  • al resultado de la operación OR, lo pasamos a srand(), como semilla
Resumen: el programador realiza un procedimiento para tener un número de semilla lo suficientemente aleatorio, ya que lo crea a partir de la fecha actual y del número de proceso en ejecución.

Si no se llama a srand(), rand() la llama de forma automática la primera vez que es llamada (ver perldoc -f rand). Dice la documentación de srand() que si no elegimos una semilla, la eligirá de forma semi-automática.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14475
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

return

Notapor eduardoemen » 2013-08-04 16:09 @714

Hola, si alguien me puede ayudar por favor con un par de sentencias que no sé exactamente cómo funcionan en detalle, comprendo más o menos de qué van pero no en profundidad y detalle.
Se trata de:

return $array[ rand @array ];

y

return int rand length $string;
eduardoemen
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2013-07-24 13:25 @601

Re: Mutaciones random

Notapor explorer » 2013-08-04 17:10 @757

Poco a poco, tenemos que ir explicando todo el programa :)

return $array[ rand @array ];

@array es una variable de array, así que guarda una serie de elementos.
rand() requiere un argumento escalar. Entonces, lo que hace Perl es ejecutar el array en contexto escalar, así que lo que obtenemos es el número de elementos que hay dentro de ese array.
rand(), con un argumento, devuelve un número aleatorio entre 0 (incluido) y el valor del argumento (excluido).
El valor aleatorio se transforma en un índice para extraer un elemento dentro del propio @array, y eso es lo que devuelve return().

En resumen: return() nos termina la subrutina actual, devolviendo un elemento de @array elegido aleatoriamente.

return int rand length $string;

length() nos devuelve el número de caracteres de $string.
rand() nos devuelve un número aleatorio entre 0 (incluido) y el valor del argumento (excluido).
int() redondea el número aleatorio a un número entero, y es este el valor que devuelve.

En resumen: return() nos termina la subrutina actual, devolviendo un número aleatorio entre 0 y la longitud de $string, menos 1 (o sea, que podemos usar ese número para sacar un carácter del interior de $string).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14475
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Programa de mutaciones

Notapor eduardoemen » 2013-08-16 12:36 @566

Hola, antes de nada, muchas gracias por tu ayuda, me está siendo de mucho provecho.

He variado un poco el programa para que me quede más claro a la hora de explicarlo.

Si puedes, por favor, ayúdame con un par de dudas que me han aparecido. Primero, ¿qué hace exactamente la subrutina 4? y segundo, ¿los resultados de $position (la posición al azar es...) ni elemento al azar ($elementoazar) tienen nada que ver con el nucleótido mutado? Ya que substr() y $newbase sí "funcionan", por ejemplo: donde había substr() se ha cambiado a $new.

De antemano, muchas gracias:

#!C:\Perl\perl.exe

my $DNA="TACGTACGTACG";

my(@nucleotides) = ('A', 'C', 'G', 'T');
my $elementoazar=randomelement(@nucleotides);
print ("el elemento al azar es:$elementoazar\n");

my($position)= randomposition($DNA);
print ("la posicion al azar es: $position\n");

$mutant=mutate ($DNA);
print ("la secuencia mutada es:$mutant\n");

my ($newbase)= randomnucleotide( @nucleotides );
print ("randomnucleotide es $newbase \n");


############
#subrutina 1#
###########
sub mutate {
my($dna) = @_;
my(@nucleotides) = ('A', 'C', 'G', 'T');
my($position) = randomposition($dna);
my($newbase) = randomnucleotide(@nucleotides);
print ("newbase es $newbase\n");
$x=substr($dna,$position,1,$newbase);
print ("el resultado del substr es: $x\n");
return $dna;
}


############
#subrutina 2#
###########
sub randomelement {
my(@array) = @_;
return $array [rand @array];
}


############
#subrutina 3#
###########
sub randomposition {
my($string) = @_; # Cuando una subrutina recibe parámetros, éstos son pasados como una lista en la variable-array especial
# @_; así recibe la subrutina los parámetros pasados, copiándolos del arreglo global @_ a variables locales.
return int rand length $string;
}


############
#subrutina 4#
###########
sub randomnucleotide{
my (@nucleotides)=("A","C","G","T");
return randomelement(@nucleotides);
}
eduardoemen
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2013-07-24 13:25 @601

Re: Programa de mutaciones

Notapor explorer » 2013-08-16 14:51 @660

eduardoemen escribiste:¿qué hace exactamente la subrutina 4?
Define el array @nucleotides con cuatro elementos, que son las cuatro famosas letras. Luego, pasa ese argumento a la función randomelement(), y el resultado de esa llamada es lo que devuelve con el return().

eduardoemen escribiste:y segundo, ¿los resultados de $position (la posición al azar es...) ni elemento al azar ($elementoazar) tienen nada que ver con el nucleótido mutado? Ya que substr() y $newbase sí "funcionan", por ejemplo: donde había substr() se ha cambiado a $new.
Los valores de $position y $elementoazar son elegidos al azar. El primero es según la longitud en caracteres, y el segundo, en función del número de elementos de un array.

Estas variables no tienen influencia en el proceso de mutación, ya que existen otras variables que se llaman igual y hacen lo mismo, dentro de mutate().
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14475
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Bioinformática

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado