• Publicidad

Error getdim en PDL::Opt::Simplex

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Error getdim en PDL::Opt::Simplex

Notapor LAS_GC » 2011-07-22 06:51 @327

Hola a todos,

Os escribo porque no tengo mucha experiencia en Perl y necesito optimizar una función, por ejemplo, f(x1,x2)=x1**2+x2**2 a partir de (4,5). He encontrado la librería SIMPLEX, pero no consigo que me funcione y creo que la culpa es del vector $init.

¿Alguien puede ayudarme?

Información sobre PDL::Opt::Simplex
http://search.cpan.org/~chm/PDL-2.4.9_0 ... Simplex.pm

Esto es lo que he escrito:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use PDL;
  4. use PDL::Opt::Simplex;
  5.  
  6. $init = ( 4, 5 );
  7.  
  8. $initsize = 2;
  9. $minsize  = 1e-6;
  10. $maxiter  = 500;
  11.  
  12. sub evaluate_func_at {
  13.     my ($xv) = @_;
  14.     my $x1   = $xv->slice("(0)");
  15.     my $x2   = $xv->slice("(1)");
  16.     return $x1**2 + $x2**2;
  17. }
  18.  
  19. ( $optimum, $ssize, $optval ) = simplex(
  20.     $init, $initsize, $minsize, $maxiter,
  21.     sub { evaluate_func_at( $_[0] ) },
  22.     sub { display_simplex( $_[0] ) }
  23. );
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Error: Can't call method "getdim" on an undefined value at /usr/lib64/perl5/PDL/Opt/Simplex.pm line 116.

Muchas gracias de antemano
Verónica
LAS_GC
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2011-07-22 06:43 @321

Publicidad

Re: Error getdim en PDL::Opt::Simplex

Notapor explorer » 2011-07-22 07:14 @343

Bienvenida a los foros de Perl en español, LAS_GC.

Mirando el código fuente de PDL::Opt::Simplex, en, aproximadamente esa línea, sale algo como

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my ( $nd, $nd2 ) = ( dims($init), 1 );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y vemos lo que pasa: el $init que le has pasado a simplex() debería ser un objeto pdl, pero no lo es. Has creado el $init como una referencia a un array de dos elementos, pero no como objeto pdl.

Prueba a cambiar la línea 6 por esta:

$init = pdl( 4, 5 );

Tienes más información en la sección 'pdl' de la página de manual de PDL::Core.

A propósito, me parece que tienes una versión antigua de PDL. Al menos, no coincide con la versión v2.4.9_003 que está en CPAN.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Error getdim en PDL::Opt::Simplex

Notapor LAS_GC » 2011-07-22 07:31 @354

Hola de nuevo y muchas gracias, explorer, por responder tan rápido. :)

He probado lo que me has dicho y me sale otro error:
Undefined subroutine &main::display_simplex called at ./ejemplo.pl line 21.

Este error es lógico porque no tengo esta subrutina añadida sub {display_simplex($_[0])) y no tengo ni idea de cómo hacerla :(

En la ayuda no he visto nada sobre esto. Igual es tan básico que ni se molestaron.

Yo he utilizado en C++ esta librería y normalmente el vector de entrada inicial son N+1 valores para cada variable. Pero aquí parece ser que solo es uno. Me refiero por ejemplo a x1=(4,1,3) y x2=(5,2,6).
$init=[(4,5) (1,2) (3,6)]. ¿A lo mejor el error viene de ahí?

Saludos
Verónica
LAS_GC
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2011-07-22 06:43 @321

Re: Error getdim en PDL::Opt::Simplex

Notapor explorer » 2011-07-22 11:32 @522

Según el código del módulo, esa subrutina es opcional, así que la puedes quitar.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. ( $optimum, $ssize, $optval ) = simplex(
  2.     $init, $initsize, $minsize, $maxiter,
  3.     sub { evaluate_func_at( $_[0] ) },
  4. );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y sí, la documentación de PDL es muy escasa... casi la única manera de obtener asistencia -casi- inmediata es uniéndose a su lista de correo.

En cuanto a las dimensiones de $init, según el código (te aconsejo que, al menos, lo mires), si el cardinal de la segunda dimensión de $init es 1, entonces lo resuelve de la forma clásica (construir un tetraedro, bucle por los valores, y reduciendo el tamaño del tetraedro hasta encontrar el punto de equilibrio). Si el cardinal de la segunda dimensión es igual al cardinal de la primera dimensión más uno, entonces aplica otro método más genérico (para más dimensiones). Si no se cumple la condición de $nd2 == $nd +1, entonces sale sin calcular nada.

Te aconsejo que te unas a la lista de correo de PDL. Es en inglés, pero hay gente muy buena, y suele dar respuestas rápidas.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Error getdim en PDL::Opt::Simplex

Notapor LAS_GC » 2011-07-25 07:22 @348

Hola de nuevo,
Con tu ayuda ya lo he resuelto. He quitado esa subrutina y lo que hago es un simple print() de x1, x2 y la función, que al final es lo que me interesa ver.

En cuanto a $initsize, fue un poco más complicado. Con este método se dibuja inicialmente un triángulo. Para cada uno de los tres vértices se calcula la función y el punto de mayor valor se cambia (a través de expansiones). Con $init le damos el centro de este triángulo y se utiliza $initsize para encontrar los tres vértices.

Muchas gracias de nuevo. Gracias por tus consejos.
Saludos

LAS_GC

--------------------------------------------------

El script final es:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use PDL;
  4. use PDL::Opt::Simplex;
  5.  
  6. my $Bext   = -1e-3;
  7. my $theta0 = -0.20;
  8. my $DB     = 0.9e-3;
  9. my $Dt     = 0.02;
  10.  
  11. my $init = pdl( $Bext, $theta0 );
  12.  
  13. my $initsize = pdl( $DB, $Dt );
  14. my $minsize  = 1e-6;
  15. my $maxiter  = 500;
  16.  
  17. sub evaluate_func_at {
  18.     my ($xv) = @_;
  19.  
  20.     my $x1 = $xv->slice("(0)");
  21.     print "x1 = $x1 \n";
  22.     my $x2 = $xv->slice("(1)");
  23.     print "x2 = $x2 \n";
  24.  
  25.     $rfx = $rx1**2 + $rx2**2;
  26.     print "F(x1,x2) = $rfx \n";
  27.  
  28.     return $rfx;
  29.  
  30. }
  31.  
  32. ( $optimum, $ssize, $optval )
  33.     = simplex( $init, $initsize, $minsize, $maxiter,
  34.     sub { evaluate_func_at( $_[0] ) } );
  35.  
  36. print "OPTIMUM = $optimum \n";
  37. print "SSIZE   = $ssize\n";
  38. print "OPTVAL  = $optval\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2011-07-25 08:54 @413, editado 1 vez en total
Razón: Formateado de código con Perltidy y poner marcas Perl
LAS_GC
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2011-07-22 06:43 @321


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 34 invitados