如何编写将创建和存储变量的函数?

时间:2015-05-21 02:44:13

标签: matlab function memoization

我希望有一个函数function y(x),当我调用y(5.12)时会创建一个变量y(5.12)(或者不知何故记住y(5.12)是什么)可以使用功能运行完毕后。做这样的事最简单的方法是什么?

我会创建一个数组并将每个值存储在相应的单元格中,但我也会有非整数和负数值,因此数组不起作用:(

2 个答案:

答案 0 :(得分:3)

安德鲁·詹克(Andrew Janke)就是现场。使用containers.Mapcontainers.Map就是所谓的associative array。它也被称为符号表,地图或字典。关联数组背后的主干是您通过访问数组,并获得伴随此键的关联值。

最好的例子是英语词典,其中键是要查找的词,值是该特定词的定义。例如(没有任何装饰),假设我们的字典是f,并且我使用了密钥rayryeng,可能的值可能是:

f('rayryeng') --> he is awesome

现在在MATLAB中,可能的密钥类型列表是:'char', 'double', 'single', 'int32', 'uint32', 'int64', or 'uint64'。可能值列表为'char', 'logical', 'double', 'single', 'int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'int64', or 'uint64'。鉴于您的应用,听起来您希望密钥为double且值为char

因此,请初始化containers.Map以识别此键/值组合:

f = containers.Map('KeyType','double','ValueType','char')

我们得到了这个:

f = 

  Map with properties:

        Count: 0
      KeyType: double
    ValueType: char

此字典中当前没有键/值对,预期键为double,输出值为char。我们可以随意开始添加:

>> f(5.12) = 'hello';
>> f(-1.56) = 'Solarmew';
>> f(pi) = 'YES!';

我在5.12,-1.56和pi的3个键中添加了不同的字符串。现在,如果要检索给定键的值,只需给出正确的键:

>> x = f(-1.56)

x =

Solarmew

如果您尝试提供一个不存在的密钥,MATLAB将给您一个错误:

>> y = f(0)

Error using containers.Map/subsref
The specified key is not present in this container.

如果要查看字典中是否存在密钥,请使用isKey方法:

>> isKey(f, 0)

ans = 

  0

为您提供更多方法。您可以使用keys方法检索字典中的所有键:

>> k = keys(f)

k = 

    [-1.5600]    [3.1416]    [5.1200]

k是一个单元格数组,其中每个元素都是此字典中的键。同样,如果您需要值,请使用values方法:

>> v = values(f);

v = 

    'Solarmew'    'YES!'    'hello'

应该注意,keysvalues都不保证任何订单。这意味着您添加键和值的顺序并不一定意味着当您致电keysvalues时,您将获得相同的订单。最后,如果您想要从字典中删除键/值对,请使用remove方法:

>> remove(f, -1.56);
>> k = keys(f)

k = 

    [3.1416]    [5.1200]

>> v = values(f)

v = 

    'YES!'    'hello'

如您所见,与-1.56相关联的Solarmew密钥现已从字典中删除。

希望这有帮助!

答案 1 :(得分:1)

我将使用一个简单的数组和一个persistent变量来展示我的解决方案。

考虑一下你有一个计算数字平方的函数,你想做一些记忆。

在我的代码中,my_hist是一个二维向量。第一个维度对应于输入,第二个维度对应于输入的平方(即输出)。

function y = memo_sqr(x)

persistent my_hist;

if(isempty(my_hist))
 my_hist = [0 0];
end

%Find if it is already present

idx = find(my_hist(:,1)==x);

if idx
 disp('Found Entry in Table')
 y = my_hist(idx,2)
 return
end

y = x^2;

my_hist = [my_hist; x y];

pause(2); %Artifical Lag 

end

我引入了一些2秒的人为滞后来模拟计算耗时的情况。

现在,如果我第一次运行代码询问{​​{1}},计算需要花费2秒钟(包括人为滞后)。但是,如果我再次要求它,持久的查找表会立即给出答案。

memo_sqr(x)

这显然是一个非常简单的例子,但它突出了如何使用>> tic; memo_sqr(2); toc; Elapsed time is 2.056881 seconds. >> tic; memo_sqr(2); toc; Found Entry in Table y = 4 Elapsed time is 0.000545 seconds. 变量。我的代码段的各个步骤可以进行优化,以满足您的需求。