2015-05-21 1 views
2

Я хотел бы иметь функцию function y(x), которая, когда я вызываю y(5.12), создаст переменную y (5.12) (или как-нибудь вспомнит, что y (5.12)), которая будет доступна для использования после выполнения функции. Какой самый простой способ сделать что-то подобное?Как написать функцию, которая будет создавать и хранить переменные?

Я бы сделал массив и просто хранить каждое значение в соответствующей ячейке, но я также буду иметь нецелые и отрицательные значения, поэтому массив не будет работать :(

+0

Вы пробовали 'container.Map', возможно, в переменной' persistent'? –

+0

Я на самом деле пытался выяснить, как «стойкие» работают в течение последних нескольких дней с какой-то другой частью кода и каждый раз используют разные методы (глобальные) ... эта функция все еще очень загадочный для меня ... не могли бы вы быть более конкретными, пожалуйста? Я не совсем уверен, как это работает, пусть вместе, как применить его здесь. Я буду искать в контейнерах. Теперь сделайте это, я никогда не использовал его. – Raksha

+1

Используйте 'persistent' вместо' global'; ваш код будет работать лучше в долгосрочной перспективе. Этот документ посвящен [doco for persistent] (http://www.mathworks.com/help/matlab/ref/persistent.html). 'persistent' означает, что переменная сохраняет свое значение в нескольких вызовах функции. Очистка функции (которая происходит неявно при изменении и сохранении функции) сбрасывает значения постоянных переменных; возможно, именно здесь возникает путаница. –

ответ

3

Andrew Janke находится на месте. Используйте containers.Map. containers.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!'; 

Я добавил в 3-х ключей 5.12 -1.56 и pi с разными строками. Теперь, если вы хотите, чтобы извлечь значение, заданное ключом, просто дать правильный ключ:

>> 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' 

Следует отметить, что оба keys и values не гарантирует порядок. Это означает, что порядок, в котором вы добавили ключи и значения, не обязательно означает, что вы получите такой же порядок, когда вы вызываете keys или values. И, наконец, если вы хотите удалить пару ключ/значение из словаря, используйте remove метод:

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

k = 

    [3.1416] [5.1200] 

>> v = values(f) 

v = 

    'YES!' 'hello' 

Как вы можете видеть, ключ -1.56, связанный с Solarmew теперь удаляется из словаря.


Надеюсь, это поможет!

+0

классный материал! :] по-прежнему не совместим с функцией (где будут выполняться фактические присвоения) 'w = контейнеры.Карта ('KeyType', 'double', 'ValueType', 'char'); ' ' function wOut = w (z) wOut = w0 * sqrt (1+ (z/zr)^2); w (z) = wOut; end' – Raksha

+0

Это потому, что вы не определяете функцию должным образом. Создайте 'container.Map', как и вы, а затем используйте это как вход в функцию. Вы пытаетесь сделать имя функции и имя контейнера.Map одним и тем же именем. Сделайте это: 'функция w = f (w, z, w0, zr) w (z) = w0 * sqrt (1+ (z/zr)^2); end', то вам нужно всего лишь: w = f (w, z, w0, zr); 'в рабочей области. 'w' теперь должен быть обновлен тем, что вы в него вложили. – rayryeng

+0

все еще не работает :(... Я набрал в рабочую область «w = container.Map (« KeyType »,« double »,« ValueType »,« char »);», а затем отредактировал мою функцию «test», msgstr "функция w = test (z)% w (z) = sqrt (z); конец" и набрал "test (0.1) в рабочее пространство, и он возвратил« Попытка получить доступ (0.1), индекс должен быть положительным целым или логическим. « – Raksha

1

я представлю мое решение используя простой массив и переменную persistent.

Считайте, что у вас есть функция, которая вычисляет квадрат числа, и вы хотите сделать некоторые запоминание.

в моем коде my_hist является 2 мерным вектором. первый размер соответствует входу, а второй - квадрату inp ut (т. е. выход).

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 секунды, чтобы моделировать случай, когда расчет занимает много времени.

Теперь, если я запускаю код в первый раз, запрашивая memo_sqr(x), для вычисления требуется не более 2 секунд (включая искусственное отставание). Однако, если я попрошу его снова, постоянная справочная таблица дает мне ответ сразу.

>> 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. 

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

+0

Я думаю, что работает только с целыми значениями, нет? – Raksha

+0

@ Солярное, это всего лишь иллюстрация. Если вы используете массив ячеек вместо массива, вы можете разместить там любую структуру данных. – Nitish

+0

Мне просто нужно принять ваше слово за это +. + ... Я понятия не имею, как это будет работать. – Raksha

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

  • Нет связанных вопросов^_^