2014-01-08 1 views
1

Я пытаюсь сгенерировать многочлены Laguerre, а затем оценивать их по элементу через массив координат.MATLAB R2012b - Передача массивов и ints в evalin (symengine, expression)

В настоящее время мой код выглядит примерно так:

[X,Y] = meshgrid(x_min:mesh_size:x_max,y_min:mesh_size:y_max); 

const_p=0; 

const_l=1; %At present these two values don't really matter, any integer will do 

coord_r = sqrt(X.^2 + Y.^2) 

lag_input = num2str(coord_r.^2) 

u_pl = evalin(symengine,['orthpoly::laguerre(',num2str(const_p),',',num2str(const_l),',',lag_input,')']); 

Однако, которая возвращает следующее сообщение об ошибке для последней строки;

Ошибка при помощи horzcat

Размеры матриц, сцеплены не согласуются.

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

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

+0

Вы уверены, что 'lag_input' на самом деле не является вектором столбца? Кроме того, вы можете найти 'feval' более удобным. – horchler

+0

@horchler - coord_r - квадратный массив (в настоящее время 512x512), а lag_input имеет размер 512x6650. Я проверю feval, приветствия. –

+0

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

ответ

2

Я бы об этом немного по-другому. Как насчет ниже? Обратите внимание, что я изменил const_p и const_l на ваш выбор, потому что получившийся в результате Lagnerre Polynomial впечатляюще скучен в противном случае.

const_p = 2; 
const_l = 1; 

%generate the symbolic polynomial in x 
lagpoly=feval(symengine,'orthpoly::laguerre',const_p,const_l,'x'); 

%Find the polynomical coefficients so we can evaluate using MATLAB's poly 
coeff=double(feval(symengine,'coeff',lagpoly)); 

%generate a matrix the same size as coord_r in the original question 
x=rand(512); 

%Do the evaluation 
u_pl=polyval(coeff,x); 
+0

Это похоже на работу, но он генерирует некоторый странный шум (я полагаю, из rand), должен быть в состоянии исправить Это. Это конечно быстро! –

+0

Да, вам вообще не нужен ранд. Я просто использовал это, потому что я хотел, чтобы тестовый ввод был того же размера, что и ваш coord_r.Для вашего производственного кода удалите строку 'x = rand (512)', и оценка должна выглядеть так: 'u_pl = polyvat (coeff, coord_r)' – WalkingRandomly

2

@WalkingRandomly имеет лучший способ сделать это, если вам нужны быстрые числовые результаты, что обычно бывает так. Однако, если вам нужны точные аналитические значения, есть трюк, который можно использовать, чтобы избежать цикла for: функция MuBAD map. Вот как почти все функции MuPAD должны быть векторизованы, поскольку они обычно предназначены для скалярных символических переменных, а не массивов числовых значений. Вот простой пример:

const_p = 2; 
const_l = 1; 

mesh_size = 0.2; 
x_min = 0; 
x_max = 1; 
y_min = 0; 
y_max = 1; 
[X,Y] = meshgrid(x_min:mesh_size:x_max,y_min:mesh_size:y_max); 
coord_r = sqrt(X.^2 + Y.^2); 

lagpoly = evalin(symengine,['map(' char(sym(coord_r)) ... 
          ',x->orthpoly::laguerre(' char(sym(const_p)) ... 
          ',' char(sym(const_l)) ',x))']) 

который возвращает

lagpoly = 

[  3,      121/50,     47/25,      69/50,     23/25,      1/2] 
[ 121/50,  76/25 - (3*2^(1/2))/5, 31/10 - (3*5^(1/2))/5, 16/5 - (3*2^(1/2)*5^(1/2))/5, 167/50 - (3*17^(1/2))/5, 88/25 - (3*26^(1/2))/5] 
[ 47/25,  31/10 - (3*5^(1/2))/5, 79/25 - (6*2^(1/2))/5,  163/50 - (3*13^(1/2))/5, 17/5 - (6*5^(1/2))/5, 179/50 - (3*29^(1/2))/5] 
[ 69/50, 16/5 - (3*2^(1/2)*5^(1/2))/5, 163/50 - (3*13^(1/2))/5,  84/25 - (9*2^(1/2))/5,      1/2, 92/25 - (3*34^(1/2))/5] 
[ 23/25,  167/50 - (3*17^(1/2))/5, 17/5 - (6*5^(1/2))/5,       1/2, 91/25 - (12*2^(1/2))/5, 191/50 - (3*41^(1/2))/5] 
[ 1/2,  88/25 - (3*26^(1/2))/5, 179/50 - (3*29^(1/2))/5,  92/25 - (3*34^(1/2))/5, 191/50 - (3*41^(1/2))/5,   4 - 3*2^(1/2)] 

Вызов double(lagpoly) преобразует результат с плавающей точкой, и вы увидите, что это то же самое, как решение предоставленной @@ WalkingRandomly (с учетом те же самые входы). Конечно, вы, вероятно, могли бы использовать символический полином или его коэффициенты, чтобы найти одно и то же вручную, хотя, к сожалению, polyval не перегружен для класса sym (есть evalp, но он также не векторизован, поэтому его необходимо использовать в сочетании с map).

+0

Это надежное решение, но мне потребовалось почти час для запуска (потому что я я имею дело с большими массивами), поэтому я поддержал, но решение @ WalkingRandomly является идеальным для меня. –

+0

Я поддерживаю это, потому что я не сейчас о 'карте' - Спасибо horchler – WalkingRandomly

+0

@WalkingRandomly: Вас также может заинтересовать [' zip'] (http://www.mathworks.com/help/symbolic/mupad_ref /zip.html), который полезен для векторизации функции с двумя массивами равного размера. 'symobj :: mapcatch' также полезен. См. [Здесь] (https://github.com/horchler/SHCTools/blob/master/SHCTools/stoneholmes/private/gammaincq.m) для некоторых примеров их использования. ;-) – horchler

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