domingo, 12 de mayo de 2013

Entrada 15: Adaptación de scripts de Matlab a Octave II - Abril 2013

Continuando con la parte de adaptación del código a Octave:

Tamaño Long

El siguiente problema que apareció fue que a la hora de leer un fichero de forma binaria, éste aparecía con tamaño negativo. Tras analizar el script que lo cargaba e ir ejecutando a la vez las instrucciones en Matlab y Octave, comprobamos que para cada programa, a la hora de ejecutar la función fread, la longitud de las variables de tipo long tienen diferente tamaño, ya que octave cargaba 64 bits y matlab 32. La solución fue sustituir en el script long por int32:

-Código original:
nf=fread(fid,1,'long');             % number of frames
fp=fread(fid,1,'long')*1.E-7;       % frame interval
by=fread(fid,1,'short');            % bytes per frame
tc=fread(fid,1,'short');            % type code
-Código para Octave:
nf=fread(fid,1,'int32');            % number of frames
fp=fread(fid,1,'int32')*1.E-7;      % frame interval
by=fread(fid,1,'short');            % bytes per frame
tc=fread(fid,1,'short');            % type code

Java y Octave 

Varios scripts usan librerías de Java. Matlab está programado en Java, por tanto las librerías están bien integradas. Pero en Octave no pasa lo mismo. Para integrar las librerías de Java en Octave hay que instalar (con sudo apt-get install) octave-java. Con esto tenemos las librerías.

Tras dos tardes intentando que funcionasen las funciones, decidimos cambiar de estrategia. Las dos funciones para las que necesitábamos java son: guardar variables en formato gzip y hacer un hash de los path de los ficheros con el algoritmo SHA256.

El primer problema se solucionó de forma muy parecida al de guardar información en ficheros hdf5. Además, simplificó bastante el código, ya que no hace falta manejar streams. Los cambios fueron:

A la hora de crear los ficheros:

-Versión de Matlab:
a         = java.io.FileOutputStream(file_name);
b         = java.util.zip.GZIPOutputStream(a);
writer    = java.io.OutputStreamWriter(b);


for rr = 1:rows
 for cc = 1:cols
   if ~ transposed
     writer.write(sprintf('%f ', data(rr,cc)));
   else
     writer.write(sprintf('%f ', data(cc,rr)));
   end
 end
 writer.write(sprintf('\n'));
end

writer.close();
b.close();
a.close();
-Versión de Octave:
if ~ transposed
  data = data';
end

data = reshape(data,1,size(data,1)*size(data,2));
str = sprintf("save %s -z data", file_name);eval(str);

Y a la hora de cargarlos:

-Versión de Matlab:
row   = 0;

a         = java.io.FileInputStream(file_name);
b         = java.util.zip.GZIPInputStream(a);
reader    = java.io.InputStreamReader(b);
b_reader  = java.io.BufferedReader(reader);

% read line by line
line = b_reader.readLine(); 

while ~ isempty(line)
  row = row + 1;

  line = char(line);
  if ~ transposed
    x(row, :) = sscanf(line, '%f')';
  else
    x(:, row) = sscanf(line, '%f');
  end

  line = b_reader.readLine();
end

reader.close();
b.close();
a.close();
-Versión de Octave:
str=sprintf("load %s", file_name);
eval(str);

if transposed
  data=data';
end

x=data;
El segundo problema relacionado con Java lo intentamos resolver de diversas maneras. Primero con Java, después compilando la función SHA256 para Octave, la cual no nos funcionó correctamente y por último decidimos usar el algoritmo MD5 (mediante la función md5sum, la cual está totalmente integrada en Octave)

Y hasta aquí las entradas de problemas de compatibilidad entre Matlab y Octave.

No hay comentarios:

Publicar un comentario