В этом примере показано, как сгенерировать код для алгоритма MATLAB, который запускает симуляцию возвращаемых "атомов" и возвращает результат после многих итераций. Нет никаких верхних границ на количестве атомов, которые принимает алгоритм, таким образом, этот пример использует в своих интересах динамическое выделение памяти.
Нет никаких предпосылок для этого примера.
run_atoms
Функцияrun_atoms.m
функционируйте запускает симуляцию возвращаемых атомов (также применение силы тяжести и энергетической потери).
help run_atoms
atoms = run_atoms(atoms,n) atoms = run_atoms(atoms,n,iter) Where 'atoms' the initial and final state of atoms (can be empty) 'n' is the number of atoms to simulate. 'iter' is the number of iterations for the simulation (if omitted it is defaulted to 3000 iterations.)
Создайте объект настройки генерации кода
cfg = coder.config; % Enable dynamic memory allocation for variable size matrices. cfg.DynamicMemoryAllocation = 'AllVariableSizeArrays';
Создайте структуру шаблона 'Atom', чтобы предоставить компилятору необходимую информацию о входных типах параметра. Атом является структурой с четырьмя полями (x, y, vx, vy) определение положения и скорости в Декартовых координатах.
atom = struct('x', 0, 'y', 0, 'vx', 0, 'vy', 0);
Используйте команду codegen
со следующими аргументами:
-args {coder.typeof(atom, [1 Inf]),0,0}
указывает, что первый аргумент является вектором-строкой из атомов, где количество столбцов потенциально бесконечно. Вторые и третьи аргументы являются скалярными двойными значениями.
-config cfg
включает динамическое выделение памяти, заданное переменной cfg
рабочей области
codegen run_atoms -args {coder.typeof(atom, [1 Inf]),0,0} -config cfg -o run_atoms_mex
MEX-функция симулирует 10 000 атомов приблизительно на 1 000 шагов итерации, учитывая пустой список атомов. Возвращаемое значение является состоянием всех атомов после того, как симуляция будет завершена.
atoms = repmat(atom,1,0); atoms = run_atoms_mex(atoms,10000,1000)
Iteration: 50
Iteration: 100
Iteration: 150
Iteration: 200
Iteration: 250
Iteration: 300
Iteration: 350
Iteration: 400
Iteration: 450
Iteration: 500
Iteration: 550
Iteration: 600
Iteration: 650
Iteration: 700
Iteration: 750
Iteration: 800
Iteration: 850
Iteration: 900
Iteration: 950
Iteration: 1000 Completed iterations: 1000
atoms=1×10000 struct array with fields:
x
y
vx
vy
Продолжите симуляцию еще с 500 шагами итерации
atoms = run_atoms_mex(atoms,10000,500)
Iteration: 50
Iteration: 100
Iteration: 150
Iteration: 200
Iteration: 250
Iteration: 300
Iteration: 350
Iteration: 400
Iteration: 450
Iteration: 500 Completed iterations: 500
atoms=1×10000 struct array with fields:
x
y
vx
vy
Чтобы сгенерировать библиотеку C, создайте стандартный объект настройки для библиотек:
cfg = coder.config('lib');
Включите динамическое выделение памяти
cfg.DynamicMemoryAllocation = 'AllVariableSizeArrays';
В MATLAB тип данных по умолчанию является двойным. Однако целые числа обычно используются в коде С, так передайте int32
целочисленные значения в качестве примера, чтобы представлять количество атомов и итераций.
codegen run_atoms -args {coder.typeof(atom, [1 Inf]),int32(0),int32(0)} -config cfg
При создании библиотеки код сгенерирован в папке codegen/lib/run_atoms/
. Код в этой папке сам содержавший. Чтобы взаимодействовать через интерфейс со скомпилированным кодом С, вам нужны только сгенерированные заголовочные файлы и файл библиотеки.
dir codegen/lib/run_atoms
. rt_nonfinite.c run_atoms_emxAPI.o .. rt_nonfinite.h run_atoms_emxutil.c buildInfo.mat rt_nonfinite.o run_atoms_emxutil.h codeInfo.mat rtw_proj.tmw run_atoms_emxutil.o codedescriptor.dmr rtwtypes.h run_atoms_initialize.c compileInfo.mat run_atoms.a run_atoms_initialize.h examples run_atoms.c run_atoms_initialize.o interface run_atoms.h run_atoms_ref.rsp rtGetInf.c run_atoms.o run_atoms_rtw.mk rtGetInf.h run_atoms_data.c run_atoms_terminate.c rtGetInf.o run_atoms_data.h run_atoms_terminate.h rtGetNaN.c run_atoms_data.o run_atoms_terminate.o rtGetNaN.h run_atoms_emxAPI.c run_atoms_types.h rtGetNaN.o run_atoms_emxAPI.h
Как правило, основная функция является зависимым платформой кодом, который выполняет рендеринг или некоторую другую обработку. В этом примере чистая ФУНКЦИЯ ANSI C производит файл run_atoms_state.m
который (когда запущено) содержит конечное состояние симуляции атома.
type run_atoms_main.c
/* Include standard C libraries */ #include <stdio.h> /* The interface to the main function we compiled. */ #include "codegen/exe/run_atoms/run_atoms.h" /* The interface to EMX data structures. */ #include "codegen/exe/run_atoms/run_atoms_emxAPI.h" int main(int argc, char **argv) { FILE *fid; int i; emxArray_Atom *atoms; /* Main arguments unused */ (void) argc; (void) argv; /* Initially create an empty row vector of atoms (1 row, 0 columns) */ atoms = emxCreate_Atom(1, 0); /* Call the function to simulate 10000 atoms in 1000 iteration steps */ run_atoms(atoms, 10000, 1000); /* Call the function again to do another 500 iteration steps */ run_atoms(atoms, 10000, 500); /* Print the result to a file */ fid = fopen("atoms_state.txt", "w"); for (i = 0; i < atoms->size[1]; i++) { fprintf(fid, "%f %f %f %f\n", atoms->data[i].x, atoms->data[i].y, atoms->data[i].vx, atoms->data[i].vy); } /* Close the file */ fclose(fid); /* Free memory */ emxDestroyArray_Atom(atoms); return(0); }
cfg = coder.config('exe'); cfg.DynamicMemoryAllocation = 'AllVariableSizeArrays';
Необходимо передать функцию (run_atoms.m
) а также пользовательский код С (run_atoms_main.c
) codegen
команда автоматически генерирует код С из кода MATLAB, затем вызывает компилятор C, чтобы связать этот сгенерированный код пользовательским кодом С (run_atoms_main.c
).
codegen run_atoms run_atoms_main.c -args {coder.typeof(atom, [1 Inf]),int32(0),int32(0)} -config cfg
После того, как симуляция завершена, это производит файл atoms_state.txt
. Файл TXT 10000x4 матрица, где каждая строка является положением и скоростью атома (x, y, vx, vy) представление текущего состояния целой системы.
system(['.' filesep 'run_atoms']);
Выполнение исполняемого файла произвело atoms_state.txt
. Теперь воссоздайте массив структур из сохраненной матрицы:
load atoms_state.txt -ascii clear atoms for i = 1:size(atoms_state,1) atoms(1,i).x = atoms_state(i,1); atoms(1,i).y = atoms_state(i,2); atoms(1,i).vx = atoms_state(i,3); atoms(1,i).vy = atoms_state(i,4); end
Вызовите run_atoms_mex
с нулевыми итерациями, чтобы представить только.
run_atoms_mex(atoms, 10000, 0);