Drexel dragonThe Math ForumDonate to the Math Forum



Search All of the Math Forum:

Views expressed in these public forums are not endorsed by Drexel University or The Math Forum.


Math Forum » Discussions » Software » comp.soft-sys.matlab

Topic: Write binary MAT files in PERL
Replies: 3   Last Post: Mar 8, 2012 6:56 PM

Advanced Search

Back to Topic List Back to Topic List Jump to Tree View Jump to Tree View   Messages: [ Previous | Next ]
Ralph Schleicher

Posts: 29
Registered: 1/23/10
Re: Write binary MAT files in PERL
Posted: Mar 7, 2012 3:36 PM
  Click to see the message monospaced in plain text Plain Text   Click to reply to this topic Reply

"Abhi " <abhishek.xtreme@gmail.com> writes:

> I was wondering if it is possible to write binary .mat files within
> Perl. Matlab documention shows how to do this in C/C++, but I couldn't
> find using Perl.


Everything is possible! Here's a quick hack I wrote some years ago.
See mat4_main below for an example.


## Mat4.pm -- read and write version 4 MAT-file format files.

# Copyright (C) 2002, 2004 Ralph Schleicher

# Version: $Id: Mat4.pm,v 1.3 2004/03/13 12:51:16 rs Exp $

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2,
# or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

## Commentary:

# See "MAT-File Format, Version 5" from The MathWorks, for detailed
# information about the MAT-file format. This document is installed
# with Matlab as `$MATLAB/help/pdf_doc/matlab/matfile_format.pdf',
# or visit <http://www.mathworks.com/support/> and follow the links
# "Documentation" -> "Matlab" -> "Printable Documentation".

## Code:

package Mat4;

require 5.000;
require Exporter;

@ISA = qw (Exporter);

@EXPORT = qw (mat4_write
mat4_read
mat4_ctor
mat4_rtoc
mat4_main);

use Config;

# The matrix type we can read or write. We support numeric
# matrices in IEEE double precision floating-point format.
my $mat4_type = ($Config{byteorder} =~ /^1/) ? 0 : 1000;

## Write matrix to file.

sub mat4_write
{
# Variable name.
my $name = shift;

# Number of rows.
my $m = shift;

# Number of columns.
my $n = shift;

# Matrix elements in column major layout, this is the native
# Matlab storage layout for matrices.
my @a = splice (@_, 0, $m * $n);

# File handle.
my $h = shift;

# Type flag.
my $type = $mat4_type;

# No imaginary part.
my $imag = 0;

# Length of variable name including terminating null character.
my $len = length ($name) + 1;

# Encode and print matrix.
print ($h pack ('l5Z*d*', $type, $m, $n, $imag, $len, $name, @a));
}

## Read matrix from file.

sub mat4_read
{
# File handle.
my $h = shift;

# Input buffer.
my $buf;

# Read and decode matrix header.
return undef if read ($h, $buf, 20) != 20;
my ($type, $m, $n, $imag, $len) = unpack ('l5', $buf);
return undef if $type != $mat4_type || $imag != 0;

# Read and decode variable name.
return undef if read ($h, $buf, $len) != $len;
my $name = unpack ('Z*', $buf);

# Read and decode matrix elements.
$len = $m * $n * 8;
return undef if read ($h, $buf, $len) != $len;
my @a = unpack ('d*', $buf);

# Return values.
($name, $m, $n, @a);
}

## Convert column major layout to row major layout.

sub mat4_ctor
{
# Number of rows.
my $m = shift;

# Number of columns.
my $n = shift;

# Array elements.
my @a = splice (@_, 0, $m * $n);

# Row major layout.
my @b = ();

for (my $j = 0; $j < $n; ++$j)
{
for (my $i = 0; $i < $m; ++$i)
{
push (@b, $a[$i * $n + $j]);
}
}

@b;
}

## Convert row major layout to column major layout.

sub mat4_rtoc
{
# Number of rows.
my $m = shift;

# Number of columns.
my $n = shift;

# Array elements.
my @a = splice (@_, 0, $m * $n);

# Column major layout.
my @b = ();

for (my $i = 0; $i < $m; ++$i)
{
for (my $j = 0; $j < $n; ++$j)
{
push (@b, $a[$j * $m + $i]);
}
}

@b;
}

## Test program.

# $ perl -e 'use Mat4; mat4_main ()'
# foo[3][2] = {0, 1, 2, 3, 4, 5}
# bar[1][4] = {6, 7, 8, 9}
# baz[0][0] = {}
#
# >> load mat4
# >> whos
# Name Size Bytes Class
#
# bar 1x4 32 double array
# baz 0x0 0 double array
# foo 3x2 48 double array
#
# Grand total is 10 elements using 80 bytes
#
# >> foo
# foo =
# 0 3
# 1 4
# 2 5
# >> bar
# bar =
# 6 7 8 9
# >> baz
# baz =
# []
# >>

sub mat4_main
{
open (MAT, '> mat4.mat')
|| die ("mat4.mat: $!\n");

mat4_write ('foo', 3, 2, (0, 1, 2, 3, 4, 5), *MAT);
mat4_write ('bar', 1, 4, (6, 7, 8, 9), *MAT);
mat4_write ('baz', 0, 0, (), *MAT);

open (MAT, '< mat4.mat')
|| die ("mat4.mat: $!\n");

while ((($name, $m, $n, @a) = mat4_read (*MAT)) >= 3)
{
printf ("%s[%d][%d] = {%s}\n", $name, $m, $n, join (', ', @a));
}
}

1;

## Mat4.pm ends here



Point your RSS reader here for a feed of the latest messages in this topic.

[Privacy Policy] [Terms of Use]

© Drexel University 1994-2014. All Rights Reserved.
The Math Forum is a research and educational enterprise of the Drexel University School of Education.