是否有记住他们在Octave上找到的值的函数?

时间:2016-11-06 02:04:36

标签: matlab recursion wolfram-mathematica octave

是否有记住他们在Octave上找到的值的函数?

进行函数定义时,每次请求函数时都会重新计算函数的值。在某些类型的计算中,您最终可能会多次要求相同的函数值。通过让语言记住它找到的所有函数值,您可以节省时间。

对于其他语言,但是对于八度,我找不到:

  1. https://reference.wolfram.com/language/tutorial/FunctionsThatRememberValuesTheyHaveFound.html
  2. Memoized recursive functions. How to make them fool-proof?
  3. How to improve ( mathematica ) performance when dealing with recursive functions?
  4. https://mathematica.stackexchange.com/q/18783 _记住其价值的功能
  5. https://www.mathworks.com/matlabcentral/answers/163145-saving-values-in-a-recursive-function
  6. java retain information in recursive function
  7. Recursive Fibonacci memoization
  8. 这主要是为了在计算factorialFibonacci数字时优化递归函数调用。这就是为什么我们可以节省并消除他们拥有的指数复杂性。由于否则中间计算必须多次执行,导致指数复杂。

2 个答案:

答案 0 :(得分:2)

正如您在问题中的MATLAB链接中简要提到的,您可以使用persistent变量来保留以前的计算。

这是一个测试函数,使用计算阶乘的例子:

function f = persistentFactorial(n)

   % declare variable factorials to be persistent
   persistent factorials

   computed = numel(factorials);
   if computed == 0
      % function called for the first time; initialize first element
      factorials(1) = 1;
      computed = 1;
   end

   if n > computed
      % fill in uncomputed factorials between computed and n
      % fprintf('calculating factorials between %d and %d\n', computed+1, n);
      factorials(computed+1:n) = computed+1:n;
      factorials(computed:n) = cumprod(factorials(computed:n));
   end

   % return requested factorial
   f = factorials(n);
end

如果您在取消注释fprintf的情况下调用此函数,则可以得到如下内容:

>> persistentFactorial(5)
calculating factorials between 2 and 5   % <-- first call to function
ans =  120
>> persistentFactorial(5)                % <-- second call; no new values
ans =  120
>> persistentFactorial(6)
calculating factorials between 6 and 6   % <-- third call; one new value
ans =  720

请注意,如果要清除持久变量,则无法直接从任何其他函数甚至命令窗口访问它,因此您无法键入clear factorials。您必须清除功能本身(甚至只需编辑它):

clear persistentFactorial

答案 1 :(得分:0)

这是一个不同于@beaker的递归,使用Matlab / Octave persistent变量来实现记忆功能。

仅在Octave上进行测试,对于Matlab版本,您需要将评论格式#转换为%,以及其他此类小修改。< / p>

可以在此GitHub存储库中找到完整代码:https://github.com/evandrocoan/ComputerScienceGraduation/tree/master/NumericalAnalysis/2016-2/Others/11.04_class22_Chebyshev

#
# Evaluate the t variable at the k'th Chebyshev Polynom
#
# i = 1 : n
# fChebyshev( i ) = b0*T0( t(i) ) + b1*T1( t(i) ) + b2*T2( t(i) ) + b3*T3( t(i) ) + ...
#
# @param k                           , the k'th Chebyshev Polynom.
# @param t                           , the value to evaluate at the k'th Chebyshev Polynom.
# @param isToDiscartTheSavedRecursion, true to indicate the current `t`'s Chebyshev Polynom sequence
#                                      must to be discarded. You must to always discard the old
#                                      sequence when a new `t` value is provided. Use false to
#                                      preserve the `t` cached values and use the recursion remember
#                                      feature.
#
function value = getChebyshevCoefficientsNumerically( k, t, isToDiscartTheSavedRecursion = true )

    persistent chebyshevPolynomCoefficients;
    chebyshevPolynomCoefficients;

    t_size   = numel( t );
    computed = numel( chebyshevPolynomCoefficients );

    # printf( 'Calling Chebyshev Polynom Coefficients with computed = %d, k = %d', computed, k );
    # printf( 'and t_size: %d \n', t_size );

    # When the function is called for the first time, initialize the first element and also reset
    # the old data, when a new variable `t` is calculated.
    if computed == 0 || isToDiscartTheSavedRecursion

        # printf( '\n\n\n\n\n( getChebyshevCoefficientsNumerically ) Cleaning ' );
        # printf(  'chebyshevPolynomCoefficients! computed: %d, k: %d\n', computed, k );

        for i = 1 : t_size

            chebyshevPolynomCoefficient( i ).vector = 1;

        end

        computed                     = 1;
        chebyshevPolynomCoefficients = chebyshevPolynomCoefficient;

    end

    t_size;
    t;
    k;
    chebyshevPolynomCoefficients.vector;

    for i = 1 : t_size

        # printf( '( getChebyshevCoefficientsNumerically ) Calculating the %dth t''s vector point.\n', i );
        [ value( i ), chebyshevPolynomCoefficients( i ).vector ] = getnthChebyshevCoefficientsNumerically( ...
                k, t( i ), chebyshevPolynomCoefficients( i ).vector );

    end

end

#
# Efficient Computation of Chebyshev Polynomials in Computer Algebra
# http://www.mathematik.uni-kassel.de/koepf/cheby.pdf
#
# Mathematics 4330/5344–#5 Approximation of Functions
# http://texas.math.ttu.edu/~gilliam/ttu/m4330/m4330_5.pdf
#
# Are there functions that remember values they have found on Octave?
# http://stackoverflow.com/questions/40445316/are-there-functions-that-remember-values-they-have-found-on-octave
#
# @param k                           , the k'th Chebyshev Polynom.
# @param t                           , the value to evaluate at the k'th Chebyshev Polynom.
# @param chebyshevPolynomCoefficients, a vector within the cached Chebyshev Polynom sequences.
#
function [ result, chebyshevPolynomCoefficients ] = ...
        getnthChebyshevCoefficientsNumerically( k, t, chebyshevPolynomCoefficients )

    t;
    computed = numel( chebyshevPolynomCoefficients );

    # printf( '( getnthChebyshevCoefficientsNumerically ) Calling with computed = ' );
    # printf( '%d and k = %d\n', computed, k );

    # Compute in uncomputed `chebyshevPolynomCoefficients`. The indexes are `k + 1` shifted because
    # the b's Chebyshev Polynom Coefficients starts on 0, but octave only allow indexes starting
    # at 1. This starts calculating all the missing b's Chebyshev Polynom from the index `computed`
    # until the requested coefficient `k`.
    if k + 1 > computed

        for i = computed : k

            # printf( '( getnthChebyshevCoefficientsNumerically ) Starting computing the %d ', i );
            # printf( 'coefficient of %d (k) coefficients.\n',  k );

            if i == 0

                chebyshevPolynomCoefficients( i + 1, : ) = 1;

            elseif i == 1

                chebyshevPolynomCoefficients( i + 1, : ) = t;

            elseif mod( i, 2 ) == 0

                chebyshevPolynomCoefficients( i + 1, : ) = 2.*getnthChebyshevCoefficientsNumerically( ...
                        i/2, t, chebyshevPolynomCoefficients ).^2 .- 1;

            else

                chebyshevPolynomCoefficients( i + 1, : ) = 2.*getnthChebyshevCoefficientsNumerically( ...
                        (i-1) / 2, t, chebyshevPolynomCoefficients ).*getnthChebyshevCoefficientsNumerically( ...
                        (i+1) / 2, t, chebyshevPolynomCoefficients ) - t;

            end

        end

    end

    k;
    chebyshevPolynomCoefficients;

    result = chebyshevPolynomCoefficients( k + 1 );

end

使用Remember

输出示例

这是一个示例输出,其中第9个Chebyshev系数激活了递归记忆功能,t = 0.6:

> T9_calcula = getChebyshevCoefficientsNumerically( 9, 0.6, false )

T9_correct = -0.472103423999999
Calling Chebyshev Polynom Coefficients with computed = 0, k = 9 and t_size: 1 
( getChebyshevCoefficientsNumerically ) Cleaning chebyshevPolynomCoefficients! computed: 0, k: 9
( getChebyshevCoefficientsNumerically ) Calculating the 1th t's vector point.
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 1 and k = 9
( getnthChebyshevCoefficientsNumerically ) Starting computing the 1 coefficient of 9 (k) coefficients.
( getnthChebyshevCoefficientsNumerically ) Starting computing the 2 coefficient of 9 (k) coefficients.
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 2 and k = 1
( getnthChebyshevCoefficientsNumerically ) Starting computing the 3 coefficient of 9 (k) coefficients.
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 3 and k = 1
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 3 and k = 2
( getnthChebyshevCoefficientsNumerically ) Starting computing the 4 coefficient of 9 (k) coefficients.
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 4 and k = 2
( getnthChebyshevCoefficientsNumerically ) Starting computing the 5 coefficient of 9 (k) coefficients.
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 5 and k = 2
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 5 and k = 3
( getnthChebyshevCoefficientsNumerically ) Starting computing the 6 coefficient of 9 (k) coefficients.
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 6 and k = 3
( getnthChebyshevCoefficientsNumerically ) Starting computing the 7 coefficient of 9 (k) coefficients.
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 7 and k = 3
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 7 and k = 4
( getnthChebyshevCoefficientsNumerically ) Starting computing the 8 coefficient of 9 (k) coefficients.
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 8 and k = 4
( getnthChebyshevCoefficientsNumerically ) Starting computing the 9 coefficient of 9 (k) coefficients.
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 9 and k = 4
( getnthChebyshevCoefficientsNumerically ) Calling with computed = 9 and k = 5
T9_calcula = -0.472103424000000

但也可称为:

> T9_calcula = getChebyshevCoefficientsNumerically( 9, [ 0.6, 0.7, 0.3 ], false )