2016-01-04 4 views
1

Это если мой первый пост, я надеюсь, что я буду отвечать стандартам ...Как получить доступ к нескольким элементам массива эффективно на C++?

я перевожу в C++ (в которой я совершенно новый) программа написана в MATLAB по причинам эффективности. Часть кода, на которой я фактически работаю, возобновляет доступ к различным индексам вектора (матрицы) за один шаг. Например, если M1 представляет собой матрицу размером, скажем, 10х15, программа будет определять новый следующим образом:

idxs1 = [1 2 3]; 
idxs2 = [1 2 3 4 5]; 
M2 = M1 (idxs1 , idxs2); 

в результате M2 в виде матрицы размером 3х5. Теперь, я думаю, что MATLAB на самом деле это один за другим доступ к различным местам M1, заданный индексами, а затем построение M2 путем переустановки большого количества содержимого, полученного очень эффективно.

Мой вопрос в том, как я могу воспроизвести такой механизм в C++? Насколько я знаю, нет прямого способа доступа к ряду различных индексов массива, а цикл for, который я использую, кажется довольно громоздким. Может быть, есть разумный способ сделать это, не требуя «слишком много» процессорного времени? Кроме того, ради образовательных целей, я был бы признателен, если бы кто-нибудь мог объяснить, что на самом деле делает MATLAB, когда такая операция выполняется.

Спасибо заранее и извините за возможные неудобства!

P.S: На всякий случай он добавляет что-либо к вопросу, я работаю с MEX файлы для связи обоих языков. P.S2: Кстати, я нашел некоторые смежные вопросы, но в отношении других языков:

+0

Вам будет очень сложно улучшить эффективность Matlab. – 1201ProgramAlarm

+0

Почему вы думаете, что было бы легко победить Matlab с точки зрения эффективности? Matlab в основном использует [BLAS] (http://www.netlib.org/blas/) и [LAPACK] (http://www.netlib.org/lapack/) для операций с матрицами. Эти библиотеки были первоначально написаны в fortran. Вы можете использовать эти функции, используя некоторые [c wrappers] (http://se.mathworks.com/help/matlab/matlab_external/calling-lapack-and-blas-functions-from-mex-files.html). Matlab также использует матричный тип mxArray. Возможно, я использую другие матричные библиотеки, но вы должны избегать писать все самостоятельно, если только вы не скучаете по математике. – patrik

+0

Библиотека библиотеки C++ с [несмежными представлениями подматрицы] (http://arma.sourceforge.net/docs.html#submat). также имеет интерфейс MEX – hbrerkere

ответ

2

«Armadillo - высококачественная библиотека линейной алгебры C++, направленная на хороший баланс b между скоростью и простотой использования

Полезно для разработки алгоритмов непосредственно на C++ или быстрого преобразования кода исследования в производственные среды; синтаксис (API) намеренно похож на Matlab»

Ссылка: http://arma.sourceforge.net/

+0

Именно то, что я искал. Теперь, заставляя его работать с файлами MEX, не было кусочка торта ... Большое спасибо! –

+0

@AlejoAlberti рад слышать! Если вы удовлетворены ответом, примите его и давайте двигаться дальше –

0

Математические структуры данных программы могут быть одними из самых сложных, там я даже не могу понять, что третья строка вашего примера. на самом деле, поэтому я даже не могу догадаться, как MATLAB реализует что-либо.

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

Если у вас есть тонна операций с матрицей, которую необходимо поддерживать, и вы находитесь в большом проекте, вам может понадобиться найти библиотеку матриц C++.Мне нечего рекомендовать, но Boost - популярная библиотека C++ для многих целей, включая матрицы. (Вы также можете создать свою собственную структуру данных, но не рекомендуется для новичков.)

+0

Отличный совет, и определенно написание структуры данных не входит в мою лигу на данный момент. На самом деле, эта «библиотека матриц C++» - это предложение @Severin, patrik и hbrerkere, поэтому я думаю, что вы все нацелены на одно и то же. Несмотря на то, что я не попал в документацию Boost, я думаю, что поеду на Armadillo из-за синтаксического сходства с MATLAB (а также для вопросов скорости - http: //stackoverflow.com/questions/14414906/compare-blitz-armadillo- boostmultiarray-, хотя сравнения не очень тщательно выполняются). Спасибо за ответ! –

0

То, что MATLAB точно действительно оставлено неуказанным и может сильно отличаться от случая к случаю в зависимости от индексов и даже для данный набор индексов он может отличаться от машины к машине. Так что давайте не будем спекулировать.

В частности, остается неуказанным, физически ли MATLAB копирует M1. Такая копия может быть подделана, что экономит время. Этот метод известен как «копирование при записи».

В C++ это было бы возможно, но сложнее. Кроме того, ни один из существующих классов контейнеров не поддерживает его.

Если вы собираетесь копировать элементы, CPU не будет узким местом. Вместо этого шина памяти ограничит вас. Это особенно характерно, когда индексы не смежны. Для матрицы 3x5 время будет зависеть от накладных расходов - смежность еще не имеет значения.

+0

Спасибо за ваш ответ и полностью согласен с предположением «без спекуляций». Просто подумал, что может быть какая-то стандартная настройка, которую я проигнорировал. То, что нужно моей программе, - это сделать за один шаг (избегая явного 'for') куска матрицы, не обязательно копируя его (что-то вроде« указателя на многие пространства памяти », которое, очевидно, не существует как таковое, делать). Отличное предложение о автобусе! Хорошо, что индексы смежны. А матрицы имеют размер ~ 150000 x 100, поэтому лучше не копировать, не так ли? знак равно –

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