2013-12-17 3 views
1

Интересно, есть ли у кого-нибудь предложения по улучшению производительности, презентации и/или вывода следующего кода MATLAB?Предложения по улучшению кода MATLAB?

Я написал программу, чтобы аппроксимировать грех й с помощью частичной суммы

((-1)^n)*(x.^((2*n)+1))/(factorial((2*n)+1)) 

с использованием методов LS и SL. Для LS я вычислил и суммировал термины от самого большого слагаемого сначала до наименьшего срока последнего. Для SL я сделал калоризацию в обратном порядке.

Вот моя функция:

function ret = taylorsin(x,n) 
ret = ((-1)^n)*(x.^((2*n)+1))/(factorial((2*n)+1)); 
end 

и мой короткий код:

function ret = partialsum(x,n,log) 
ret = 0; 
if log == 1 
    for i = 0:1:n 
     ret = ret + taylorsin(x,i); 
     i=i+1; 
    end 
elseif log == 0 
    for i = n:-1:0 
     ret = ret + taylorsin(x,i); 
     i = i+1; 
    end 
end 
end 

Спасибо за любой вклад.

ответ

6

На первом просмотре, несколько вещей выделяются:

  • вы даете переменная цикла такое же имя, как MATLAB встроенный (ii)
  • вы используете имя переменной это также название MATLAB встроенный (log)
  • вы изменяете переменную цикла внутри цикла (ii=ii+1 не обязательно)
  • вы не в-выравнивая функцию taylorsin в цикле (функция призывает к не-встроенным функциям может быть трудно JIT)
  • вы не проверять для других значений переменной log (это кусается)

Таким образом, быстрое улучшение будет:

function ret = partialsum(x,n,lg) 
ret = 0; 
if lg == 1 
    for ii = 0:n 
     N = cumprod(2 : 2*ii+1); 
     ret = ret + (-1)^ii * (x^(2*ii+1))/N(end); 
    end 
elseif lg == 0 
    for ii = n:-1:0 
     N = cumprod(2 : 2*ii+1); 
     ret = ret + (-1)^ii * (x^(2*ii+1))/N(end); 
    end 
else 
    error('Invalid value for lg');  
end 

Но учитывая, что результаты вычислений в цикле одинаковы (только порядок суммирования отличается), вы можете векторизации все это:

function ret = partialsum(x,n,~) 
    ii = 0:n; 
    k = 2*ii+1;  
    ret = x.^k ./ factorial(k) * (-1).^ii.'; 
end 
+1

+1 Я бы векторизовал использование 'repmat' с' n' columnwise и 'x' rollise, а затем использовал' cumsum' columnwise –

+0

@LuisMendo: я думаю, что 'repmat' не требуется; см. мое редактирование. –

+0

В общем случае я думал, что 'x' будет вектором –

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