All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.meliorbis.numerics.io.matlab.MatlabReader Maven / Gradle / Ivy

Go to download

A library for working with large multi-dimensional arrays and the functions they represent

There is a newer version: 1.2
Show newest version
package com.meliorbis.numerics.io.matlab;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.jmatio.io.MatFileReader;
import com.jmatio.types.MLArray;
import com.jmatio.types.MLNumericArray;
import com.jmatio.types.MLStructure;
import com.meliorbis.numerics.DoubleArrayFactories;
import com.meliorbis.numerics.IntArrayFactories;
import com.meliorbis.numerics.generic.MultiDimensionalArray;
import com.meliorbis.numerics.generic.SettableIndexedIterator;
import com.meliorbis.numerics.generic.primitives.DoubleSettableIndexedIterator;
import com.meliorbis.utils.Utils;

/**
 * This class provides an API for reading from MATLAB files and returning Numerics arrays
 *
 * @author Tobias Grasl
 */
public class MatlabReader implements com.meliorbis.numerics.io.NumericsReader
{
    private final File _file;
    private Map _arrays;

    /**
     * @param file_ The file to read from
     */
    public MatlabReader(File file_)
    {
        _file = file_;
    }

    /**
     * @param path_ The path to the file to read from
     */
    public MatlabReader(String path_)
    {
        this(new File(path_));
    }

    /**
     * Returns the named array
     *
     * @param name_ The name of the array to return
     *
     * @param  The type of the array to return. Note this must coincide with the actual type in MatLab, therefore
     *           the type must be known in advance
     *
     * @return The array requested, or null if no such array has been read
     */
    @SuppressWarnings("unchecked")
	@Override
    public  MultiDimensionalArray getArray(String name_) throws IOException
    {
        // Throw an exception if no data has been read
        checkRead();

        final MLArray mlArray = _arrays.get(name_);

        if(mlArray == null)
        {
            return null;
        }

        return toNumericsArray((MLNumericArray) mlArray);
    }

    private void checkRead() throws IOException
    {
        if(_arrays == null)
        {
            final MatFileReader matFileReader = new MatFileReader();
            _arrays = matFileReader.read(_file);
        }
    }

    /**
     * @return all arrays in the matlab file that was read, mapped by name
     */
    @SuppressWarnings("unchecked")
	@Override
    public Map> getArrays() throws IOException
    {
        // Throw an exception if no data has been read
        checkRead();

        Map> results =
                new HashMap>();

        // Convert each array and set it in the result map
        for(Map.Entry entry : _arrays.entrySet())
        {
            results.put(entry.getKey(),toNumericsArray((MLNumericArray) entry.getValue()));
        }

        return results;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
	private  MultiDimensionalArray toNumericsArray(MLNumericArray mlArray_)
    {
        MultiDimensionalArray result;

        final int[] dimensions = mlArray_.getDimensions();

        if(mlArray_.isDouble())
        {
            result = (MultiDimensionalArray) DoubleArrayFactories.createArrayOfSize(dimensions);

            // Need to rearrange dimensions to account for different linear indexing in ML and numerics
            final DoubleSettableIndexedIterator targetIter =
                    (DoubleSettableIndexedIterator) result.arrangeDimensions(Utils.sequence(dimensions.length - 1, -1)).iterator();

            int index = 0;

            // Iterate over the target array, incrementing the ML array counter as we go along, and copy each value
            while(targetIter.hasNext())
            {
                targetIter.nextDouble();

                targetIter.set(((Double)mlArray_.get(index++)).doubleValue());
            }
        }
        // Note the 64-bitness might bite us
        else if(mlArray_.isInt64()||mlArray_.isInt32()||mlArray_.isInt16())
        {
            result = (MultiDimensionalArray) IntArrayFactories.createIntArrayOfSize(dimensions);

            // Need to rearrange dimensions to account for different linear indexing in ML and numerics
            final SettableIndexedIterator targetIter =
                    result.arrangeDimensions(Utils.sequence(dimensions.length - 1, -1)).iterator();

            int index = 0;

            // Iterate over the target array, incrementing the ML array counter as we go along, and copy each value
            while(targetIter.hasNext())
            {
                targetIter.next();

                targetIter.set(mlArray_.get(index++));
            }
        }
        else
        {
            throw new UnsupportedOperationException("Only double and int supported");
        }



        return result;
    }

    @SuppressWarnings("unchecked")
	@Override
    public Map> getStruct(String name_) throws IOException
    {
        checkRead();

        final MLArray structure = _arrays.get(name_);

        if(!(structure instanceof MLStructure))
        {
            throw new IllegalStateException("The named array is not a structure");
        }


        Map> results =
                new HashMap>();

        // Convert each array and set it in the result map
        for(String fieldName : ((MLStructure) structure).getFieldNames())
        {
            results.put(fieldName,toNumericsArray((MLNumericArray) ((MLStructure) structure).getField(fieldName)));
        }

        return results;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy