2015-10-07 2 views
2

Я ищу эффективный и быстрый способ памяти для измерения размеров многомерного массива в Java.Java: элементы порядка многомерного массива

Я имею в виду, чтобы преобразовать массив double[rows][cols][slices] в массив double[slices][rows][cols]. (Сравнимого с this Matlab function) Я знаю, что все элементы строки имеют одинаковое количество перевалов и все перевалы имеют одинаковое количество кусочков.

Я всегда работаю над отдельными ломтиками, что делает массивы double[rows][cols][slices] очень неудобными. Я решил создать функцию getSlice(double[][][] array, int slice), но мой массив имеет размер несколько ГБ, и я довольно часто получаю доступ к срезам. Так что это, кажется, слишком избыточная работа.

Чтобы уточнить мой вопрос: С точки зрения скорости и использования памяти, есть ли лучший способ перестановки размеров массива, чем создание нового массива и копирование старого элемента по элементу? Или есть даже совершенно другой и более элегантный способ приблизиться к этому, которого я пропустил до сих пор?

ANSWER Я сейчас инкапсулировал данные, как было предложено. Для этого я также использовал классы ImagePlus, ImageStack и ImageProcessor от ImageJ, поскольку они уже предоставили большую часть необходимых мне функций. С точки зрения эффективности памяти они выглядят нормально.

+1

Память эффективная * и * быстрая? Что бы вы предпочли, если бы у вас был только один? –

+0

Это, наверное, глупый вопрос, но зачем вам нужны отдельные фрагменты как 'double [] []' экземпляры? Передаются ли эти срезы в качестве параметра методу, принимающему 'double [] []'? –

+0

Несколько лет назад я использовал библиотеку [cern.colt.matrix] (https://dst.lbl.gov/ACSSoftware/colt/api/index.html), которая имеет ряд полезных матричных операций, подобных этому (не уверенный в эффективности , но, вероятно, лучше, чем строить что-то с нуля). – pmorken

ответ

0

Поскольку вы не указали какую-либо информацию о том, как используются данные, это может быть не актуально, но я бы предложил инкапсулировать данные в классе, чтобы данные никогда не обращались напрямую.

Вы можете сделать это конкретным для своего случая или более общим. Я покажу общий.

public interface Array3D { 
    public double get(int x, int y, int z); 
    /** 
     * Returns a 2D view of the 3D plane for the given X, mapping (y,z) to (x,y). 
     */ 
    public Array2D forX(int x); 
    /** 
     * Returns a 2D view of the 3D plane for the given Y, mapping (x,z) to (x,y). 
     */ 
    public Array2D forY(int y); 
    /** 
     * Returns a 2D view of the 3D plane for the given Z. 
     */ 
    public Array2D forZ(int z); 
} 
public interface Array2D { 
    public double get(int x, int y); 
    /** 
     * Returns a 1D Y-axis view of the 2D plane for the given X. 
     */ 
    public Array1D forX(int x); 
    /** 
     * Returns a 1D X-axis view of the 2D plane for the given Y. 
     */ 
    public Array1D forY(int y); 
    /** 
     * Copies the data. Use sparingly. 
     */ 
    public double[][] toArray(); 
} 
public interface Array1D { 
    public double get(int index); 
    /** 
     * Copies the data. Use sparingly. 
     */ 
    public double[] toArray(); 
} 

Класс реализации для Array3D будет нести фактические данные. Классы реализации для Array2D и Array1D не будут переносить никаких данных, так как они являются «видами» на 3D-данные.

+0

Инкапсуляция данных в класс, вероятно, всегда является лучшим способом сделать это на Java. В этом контексте, однако, я обеспокоен тем, что множественные вызовы функций этого интерфейса будут слишком большими накладными расходами, –

Смежные вопросы