fminsearch для функции, внутренне использующей матрицы - PullRequest
0 голосов
/ 29 ноября 2011

У меня проблемы с минимизацией довольно сложной функции:

% Current densities - psi is a 4x1 fourvector
j0 = @(psi) psi' * psi;

% Solutions
chi1 = @(n_,r_,kt_,theta_) ...
       1/sqrt(2) * ...
           [ exp(1i*n_*theta_) .* besselj(n_,kt_*r_); ...
             exp(1i*(n_+1)*theta_) .* besselj(n_+1,kt_*r_) ];
chi2 = @(n_,r_,kt_,theta_) ...
       1/sqrt(2) * ...
           [  exp(1i*n_*theta_) .* besselj(n_,kt_*r_); ...
             -exp(1i*(n_+1)*theta_) .* besselj(n_+1,kt_*r_) ];

uplus = @(n_,E_,m_,r_,kz_,kt_,theta_) ...
        sqrt((E_+m_)/(4*m_)) * ...
            [ chi1(n_,r_,kt_,theta_); ...
              (kz_-1i*kt_)/(E_+m_) * chi2(n_,r_,kt_,theta_) ];

Здесь: n, E, m, kz, theta - все константы для любых целей. Мне нужно вписать j0 в пошаговую функцию (1 для r = 1 ... 10), а модельной функцией будет четырехпозиционный фунт на квадратный дюйм, состоящий из суммирования прироста по kt = нулям besselj(n,kt/10*r), поэтому что besselj (0, kt * 10) равно нулю. Проблема в том, что fminsearch не нравятся мои сложные настройки:

uplus_reduced  = @(r_,kt_) uplus(0,E,m,r_,kz,kt_,0);
error_function = @(r_,coeffs_) error_j0_stepfunction(r_,coeffs_,...
                               uplus_reduced);
coeffs(1,:) = fminsearch( @(r) error_function(r',coeffs(:,1)), r);

где error_j0_stepfunction это:

function error = error_j0_stepfunction(r,coeffs,basisspinor)
% Zeros of BesselJ
Nzeros = 100;
lambda = [ besselzero(0,Nzeros,1)';
           besselzero(1,Nzeros,1)';
           besselzero(2,Nzeros,1)' ];

% calculate psi= sum over zeros
psi = zeros(4,length(r));
for k=1:length(coeffs)
    size_psi = size(psi(:,:) )
    size_coeffs = size(coeffs(k))
    size_basisspinor = size( basisspinor(r(:)', lambda(1,k)/10))
    psi(:,:) = psi(:,:) + coeffs(k) * ...
        basisspinor(r(:), lambda(1,k)/10);
end;
% calculate density (j0)
density = zeros(1,length(r));
for k=1:length(r)
    density(k) = j0(psi(:,k));
end;
% calculate square error
error = sum((1-density(:)).^2);
end

Надеюсь, я был достаточно ясен и в то же время сжат, чтобы на это можно было ответить. Спасибо за любую помощь!

РЕДАКТИРОВАТЬ: я получаю ошибку (с выводом, что делает его бессмысленным для меня):

size_psi = 4        1000
size_coeffs = 1     1
size_basisspinor = 4        1000
Error using  + 
Matrix dimensions must agree.
Error in error_j0_stepfunction (line 15)
    psi(:,:) = psi(:,:) + coeffs(k) * ...
Error in @(r_,coeffs_)error_j0_stepfunction(r_,coeffs_,uplus_reduced)
Error in @(r)error_function(r',coeffs(:,1))
Error in fminsearch (line 191)
fv(:,1) = funfcn(x,varargin{:});
Error in dirac_stepfunction (line 17)
coeffs(1,:) = fminsearch( @(r) error_function(r',coeffs(:,1)), r);
Error in dirac (line 7)
dirac_stepfunction;

Это должно иметь достаточно смысла для любого, кто читает ошибку и код выше. coeffs - это матрица 20x3, r - 1x1000 (или 1000x1)

1 Ответ

1 голос
/ 30 ноября 2011

Ваш вызов basisspinor в size -статменте имеет r(:)' в качестве первого аргумента, тогда как второй вызов basisspinor имеет только r(:). Я думаю, что первая версия была также предназначена для второго вызова.

...