2016-11-02 5 views
1

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

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

function [ facn ] = cfactorial(n) 

global facs 

if n > 170 
    facn = Inf; 
elseif n == 0 
    facn = 1; 
else 
    facn = facs(n); 
end 

Я также попытался установить его настойчивое, что также не намного быстрее.

function [ facn ] = cfactorial(n) 

persistent facs 

if isempty(facs) 
    load('facs.mat') 
    facs = faccs; 
end 

if n > 170 
    facn = Inf; 
elseif n == 0 
    facn = 1; 
else 
    facn = facs(n); 
end 

В обоих случаях линия "стойкие фары" соответственно. «global facs» теперь занимает большую часть времени в профилировщике.

Есть ли другой способ сделать это? Могу ли я определить что-то вроде переменной, доступной во всем мире, без ее загрузки?

+0

Почему бы вам не предвычисление массива всех значений а затем получить их оттуда? – mpaskov

+0

Это то, что я делаю, я ищу эффективный способ совместного использования массива между всеми функциями. На данный момент я добавил дополнительный аргумент, в котором я передаю этот массив, но этого я и хотел избежать. Меня больше всего интересует, если есть более элегантный и эффективный способ, которого я еще не знаю. – kili

+0

Как использовать встроенную функцию гаммы? –

ответ

3

Избегайте вызывать функции и использовать if..else как можно больше. Векторизация - лучший подход. вы можете сделать факторный матрицу, как это:

factorials = [1 cumprod(1:170) Inf]; 

Предположим, что вы хотите назвать Факториал 5 раз со значением n с являются

ns = [3 0 56 23 456]; 

так что вы можете получить факториал, как показано ниже:

f_ns = factorials(min(ns, 171) + 1) ; 

, то вы продолжаете вычисления со значениями f_ns.

Если вы не можете предвычисление f_ns вы можете создать встроенную функцию facn внутри функции, которая нуждается в Mutiple вычисления факториала и вызвать facn несколько раз:

function myfunction 
    factorials = [1 cumprod(1:170) Inf]; 
    facn [email protected](n) factorials(min(n, 171) + 1) ; 
    facn(3); 
    facn(0); 
    facn(456); 
end 
+0

заменяет if..else на f_ns = factorials (min (ns, 171) + 1); кажется хорошей идеей. Я использую [внешние функции] (http://massey.dur.ac.uk/jdp/code.html#angmom), где есть много вложенных вызовов функций - поэтому трудно вставлять в нуль, если я хочу использовать те.Может быть, я сам их напишу, чтобы их оптимизировать – kili