• Publicidad

Promedio con rangos para una matriz con Perl y Octave

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

Promedio con rangos para una matriz con Perl y Octave

Notapor lis » 2013-03-13 16:30 @729

Hola, amigos del foro. Tanto tiempo, espero estén todos bien. Les cuento que tengo una matriz de 365x24 (días por hora) y quiero obtener dos promedios por mes, y como saben cada mes tiene diferente cantidad de días (la matriz está en días julianos), lo que he hecho me resulta a medias ya que solo guarda el último resultado, les muestro el script:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2.  
  3. my %hash
  4.     = qw (1 15 16 31 32 45 46 59 60 74 75 90 91 105 106 120 121 135 136 151 152 166 167 181 182 196 197 212 213 227 228 243 244 258 259 273 274 288 289 304 305 319 320 334 335 349 350 365);
  5.  
  6. for my $jul ( sort { $hash{$a} <=> $hash{$b} } keys %hash ) {
  7.  
  8.     open( IN, ">graficos.m" );
  9.     print IN "clear all; clc\n";
  10.     print IN "x= load('prueba.txt');\n";
  11.     print IN "a=x(:,1);   m=x(:,2);  d=x(:,3);  h=x(:,4);  vv=x(:,5);  dv=x(:,6);\n";
  12.     print IN "V=reshape(x(:,5)',365,24); D=reshape(x(:,6)',365,24);  \n";
  13.     print IN "mv=mean(V);  md=mean(D);\n";
  14.     print IN "G2R = (pi / 180);\n";
  15.     print IN "gar = G2R * D;\n";
  16.     print IN "u = (-1) .* V .* sin(gar); v = (-1) .*V .* cos(gar);\n";
  17.     print IN "prom=[];\n";
  18.     print IN "for K = 1:365 \n";
  19.     print IN "Samp{K} = mean(V($jul:$hash{$jul},:));\n"; # realiza un promedio, por ejemplo, desde la fila 1 a la 15 para todas las columnas
  20.     print IN "end;\n";
  21.     print IN "prom=[prom; Samp(K)];\n";
  22.     print IN "save Matriz.txt prom;\n";
  23.     system("/usr/bin/octave -q graficos.m");
  24. }
  25.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Si resultara bien debería generar una matriz de 24x24, pero solo genera una matriz de 1x24.

Por favor les pido que me ayuden. Muchas gracias por su tiempo.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Publicidad

Re: Promedio con rangos para una matriz con Perl y Octave

Notapor explorer » 2013-03-13 17:21 @764

Perdón, pero... ¿seguro que es un hash lo que debes usar?

¿Qué significan los números que hay dentro de %hash?
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: Promedio con rangos para una matriz con Perl y Octave

Notapor lis » 2013-03-14 07:07 @338

Hola, explorer. El hash indica las filas a promediar, por ejemplo de la fila 1 a la 15, luego 16 a la 31 y así hasta el último promedio que sería de la fila 350 hasta la 365 para las 24 columnas. Espero haberme dado a entender. Muchas gracias.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Re: Promedio con rangos para una matriz con Perl y Octave

Notapor explorer » 2013-03-14 19:53 @870

Yo no veo problemas, salvo que no sé qué se debe generar, para el octave.

El mismo código que tienes escrito, pero un poco más abreviado:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @array
  2.     = qw (1 15 16 31 32 45 46 59 60 74 75 90 91 105 106 120 121 135 136 151 152 166 167 181 182 196
  3.         197 212 213 227 228 243 244 258 259 273 274 288 289 304 305 319 320 334 335 349 350 365);
  4.  
  5. for (my $i = 0; exists($array[$i]) and $array[$i] < 365; $i += 2) {
  6.     say $array[$i], " -> ", $array[$i+1];
  7.  
  8.     open( IN, ">graficos.m" );
  9.     print IN <<EOF;
  10. clear all; clc
  11. x= load('prueba.txt');
  12. a=x(:,1);   m=x(:,2);  d=x(:,3);  h=x(:,4);  vv=x(:,5);  dv=x(:,6);
  13. V=reshape(x(:,5)',365,24); D=reshape(x(:,6)',365,24);
  14. mv=mean(V);  md=mean(D);
  15. G2R = (pi / 180);
  16. gar = G2R * D;
  17. u = (-1) .* V .* sin(gar); v = (-1) .*V .* cos(gar);
  18. prom=[];
  19. for K = 1:365
  20. Samp{K} = mean(V($array[$i]:$array[$i+1],:));
  21. end;
  22. prom=[prom; Samp(K)];
  23. save Matriz.txt prom;
  24. EOF
  25.     close IN;
  26.  
  27.     system("/usr/bin/octave -q graficos.m");
  28. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Lo que veo en el código es que se genera un archivo graficos.m por cada par clave/valor, y ejecuta octave para esa pareja. Pero entonces, la instrucción 'save' sobre escribirá Matrix.txt en cada pareja, por lo que al final, solo quedará el resultado de la pareja final.

Quizás sea eso: debes ir cambiando el nombre del archivo de salida.
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: Promedio con rangos para una matriz con Perl y Octave

Notapor lis » 2013-03-15 08:33 @398

Hola, explorer, muchas gracias por responder. Bueno, lo que hice fue lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2.  
  3. my %hash
  4.     = qw (1 15 16 31 32 45 46 59 60 74 75 90 91 105 106 120 121 135 136 151 152 166 167 181 182 196 197 212 213 227 228 243 244 258 259 273 274 288 289 304 305 319 320 334 335 349 350 365);
  5.  
  6. for my $jul ( sort { $hash{$a} <=> $hash{$b} } keys %hash ) {
  7.     $file = $hash{$jul} . '.txt';
  8.  
  9.     open( OUT, ">>Matriz.txt" );
  10.  
  11.     open( IN, ">matriz.m" );
  12.     print IN <<EOF;
  13. clear all; clc;
  14. x= load('prueba.txt');
  15. a=x(:,1);   m=x(:,2);  d=x(:,3);  h=x(:,4);  vv=x(:,5);  dv=x(:,6);
  16. V=reshape(x(:,5)',365,24); D=reshape(x(:,6)',365,24);
  17. mv=mean(V);  md=mean(D);
  18. G2R = (pi / 180); gar = G2R * D;
  19. u = (-1) .* V .* sin(gar); v = (-1) .*V .* cos(gar);
  20. prom=[];
  21. for K = 1:365
  22. Samp{K} = mean(V($jul:$hash{$jul},:));
  23. end;
  24. format bank;
  25. prom=[prom; Samp{K}];
  26. save $file prom '-ascii';
  27. EOF
  28.     close IN;
  29.     system("/usr/bin/octave -q matriz.m");
  30.  
  31.     open( GR, "<$file" );
  32.     while ( $lineas = <GR> ) {
  33.         chop($lineas);
  34.         @datos = split( " ", $lineas );
  35.         print OUT "@datos\n";
  36.     }
  37. }
  38.  
  39.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Mezclé de los dos scripts, ya que
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. say
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
no me funcionó. Al final resulta lo que quería pero quiero ver si al menos la última parte (donde guardo los archivos en uno solo) se pueda simplificar. Así que nuevamente muchas gracias
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Re: Promedio con rangos para una matriz con Perl y Octave

Notapor explorer » 2013-03-15 20:17 @887

say() no es más que un print(), y está disponible a partir de Perl v5.10.

La última parte creo que se puede simplificar bastante:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. my %hash
  7.     = qw (1 15 16 31 32 45 46 59 60 74 75 90 91 105 106 120 121 135 136 151 152 166 167 181 182 196
  8.             197 212 213 227 228 243 244 258 259 273 274 288 289 304 305 319 320 334 335 349 350 365);
  9.  
  10. open( OUT, ">>Matriz.txt" );
  11.  
  12. for my $jul ( sort { $hash{$a} <=> $hash{$b} } keys %hash ) {
  13.     my $file = "$hash{$jul}.txt";
  14.  
  15.     open( IN, ">matriz.m" );
  16.     print IN <<EOF;
  17. clear all; clc;
  18. x= load('prueba.txt');
  19. a=x(:,1);   m=x(:,2);  d=x(:,3);  h=x(:,4);  vv=x(:,5);  dv=x(:,6);
  20. V=reshape(x(:,5)',365,24); D=reshape(x(:,6)',365,24);
  21. mv=mean(V);  md=mean(D);
  22. G2R = (pi / 180); gar = G2R * D;
  23. u = (-1) .* V .* sin(gar); v = (-1) .*V .* cos(gar);
  24. prom=[];
  25. for K = 1:365
  26. Samp{K} = mean(V($jul:$hash{$jul},:));
  27. end;
  28. format bank;
  29. prom=[prom; Samp{K}];
  30. save $file prom '-ascii';
  31. EOF
  32.     close IN;
  33.  
  34.     system("/usr/bin/octave -q matriz.m");
  35.  
  36.     open( GR, "<$file" );
  37.     print OUT <GR>;
  38.     close GR;
  39. }
  40.  
  41. close OUT;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
ya que, realmente, lo que hacemos es copiar las líneas generadas por octave, al archivo Matrix.txt.

El proceso que hacías de, quitar el último carácter, dividir en @campos separando por los espacios en blanco, y sacando el resultado afuera reuniendo los campos con espacios en blanco, y añadiendo un carácter de fin de línea... pues me parece que sobraba.

Se podría simplificar más si supiéramos cómo decirle a octave que la salida la haga hacia la salida estándar en lugar de a un archivo, o que en vez de escribir a un archivo, vaya agregando la salida.
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: Promedio con rangos para una matriz con Perl y Octave

Notapor lis » 2013-03-19 14:42 @654

Hola, explorer, muchas gracias por tu respuesta.

He estado buscando y en vez de crear un archivo para cada resultado y luego unirlos en uno solo, hallé la forma de decirle a octave que lo haga pero me genera un error al escribir lo siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open( IN, ">matriz.m" );
  2. print IN <<EOF;
  3. clear all; clc;
  4. x= load('$file');
  5. a=x(:,1);   m=x(:,2);  d=x(:,3);  h=x(:,4);  vv=x(:,5);  dv=x(:,6);
  6. V=reshape(x(:,5),24,366)'; D=reshape(x(:,6),24,366)';
  7. mv=mean(V);  md=mean(D);
  8. G2R = (pi / 180); gar = G2R * D;
  9. u = (-1) .* V .* sin(gar); v = (-1) .*V .* cos(gar); t=1:24;
  10. fid = fopen('$name','wt');
  11. "for K = 1:365
  12. Samp_$variable{K} = mean($variable($jul:$hash{$jul},:));
  13. fprintf('%2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f\n',Samp_$variable{K});
  14. end;
  15. EOF
  16. close IN;
  17. system("/usr/bin/octave -q matriz.m");
  18.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El problema radica en que \n genera un salto de línea en Perl, y no en Octave, por lo que el archivo matriz.m no lo reconoce Octave ya que queda así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. fprintf('%2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f %2.1f
  2. ',Samp_);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Sabes cómo solucionar esto?

De antemano muchas gracias.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Re: Promedio con rangos para una matriz con Perl y Octave

Notapor explorer » 2013-03-19 16:36 @733

Prueba a escribirlo así: \\n
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: Promedio con rangos para una matriz con Perl y Octave

Notapor lis » 2013-03-20 11:07 @505

Muchas gracias, explorer, funcionó a la perfección.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946


Volver a Básico

¿Quién está conectado?

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