2013-08-12 5 views
2

Резюме: Я хочу вызвать функцию, которая возвращает несколько структур n раз. Как добавить результаты в существующие поля в мои выходные структуры (т. Е. Создавать векторы) вместо создания новых полей, содержащих скаляр каждой итерации?MATLAB: Вложенные функции и структуры


Пример: Рассмотрим функцию sample_fct(x), что 1) perfroms некоторые операции по x и сохраняет результат в пару новых переменных (a и b в примере кода), а затем 2) вызывает некоторые суб- функции calculate_one(x) и calculate_two(x) с a и b как вход. Неважно, что именно делают эти функции. Затем вывод этих функций собирается в struct A и B.

function [A, B] = sample_fct(x) 
    a = 1 * x; 
    b = 2 * x; 
    [A.one, A.two] = call_functions(a); 
    [B.one, B.two] = call_functions(b); 
    function [one, two] = call_functions(input) 
     one = calculate_one(input); 
     two = calculate_two(input); 
     function one = calculate_one(input) 
      one = input.^2; 
     end 
     function two = calculate_two(input) 
      two = input.^3; 
     end 
    end 
end 

Затем я хочу вызвать эту функцию n раз с различными входными параметрами в моем сценарии

n = 3; 
for i = 1:n 
    [A(i), B(i)] = sample_fct(i); 
end 

Когда я делаю это, A и B стал 1 * п Структуры, каждое поле вновь, содержащие поля one и two. Поэтому в моем примере с n = 3 у меня есть 3 экземпляра скаляров one и two. Вывод мой пример кода выглядит следующим образом:

>> A 
A = 
1x3 struct array with fields: 
    one 
    two 
>> A.one 
ans = 
    1 
ans = 
    4 
ans = 
    9 

То, что я на самом деле хочу A и B быть 1 * 2 Структуры с 1 * п векторов one и two, так что желаемый результат должен выглядеть примерно так:

>> A 
A = 
    two: [1 8 27] 
    one: [1 4 9] 

Как именно я могу сделать это без [один, два] является выходной переменной моей функции и не вызывая мою функцию A и B по отдельности?


Почему я хочу сделать это: Я хочу запустить прогнозную модель с различными комбинациями параметров на временные рядах и вычислить некоторые Совершенства-о-формы мер и другие статистические данные за 1 минуту, 1 часов, 1 день и т. Д. В моем примере, x бы временные ряды, петля над n цикл по различным векторам параметров, a и b представлений с различным временем выборки и один и two некоторые статистические данные, которые я хочу собрать в A и структур B. Я почти уверен, что это гораздо более сложный способ сделать это, но я просто не могу обернуть вокруг себя голову.

Я знаю, что это легко сделать с векторами/матрицами вместо структур, но я хотел бы иметь возможность вызывать мой вывод с именем переменной вместо A.hourly (:, 19) или что-то в этом роде, поскольку Я вычисляю много статистики, а не только два в моем фактическом коде.

+0

Ваш вопрос довольно длинный, не могли бы вы поставить краткое резюме сверху? –

+0

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

+0

Я только что прочитал резюме: o -> предложение: поместите их в массив ячеек; хорошо, если это не вопрос о том, «как добавить данные в мою матрицу» ... как a = [a newValues] или (end + 1) = newValues ​​ –

ответ

2

Одна альтернатива будет иметь sample_fct взять А и В в качестве дополнительных аргументов и сделать эту директиву внутри sample_fct:

[A,B] = sample_fct(1) 
for i=2:n 
    [A,B] = sample_fct(i, A, B) 
end 

Вы бы тогда изменить два call_functions вызывает в sample_fct в случае вызова 3-arguments. Это может быть, например, выглядеть следующим образом:

if nargin == 3 
    [A.one(end+1), A.two(end+1)] = call_functions(a); 
    [B.one(end+1), B.two(end+1)] = call_functions(b); 
elseif nargin == 1 
    [A.one, A.two] = call_functions(a); 
    [B.one, B.two] = call_functions(b); 
end 

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

+0

Вы правы, в этом случае вложение не требуется. Ваше первое решение кажется мне чем-то другим. Мне нужно, чтобы один и два были оценены для разных входных данных (поэтому у меня есть отдельные структуры A и B). Тем не менее, ваше второе решение кажется хорошей идеей. Я постараюсь это реализовать. Большое спасибо./edit: Упс, и ваше первое решение исчезло. ;) –

3

EDIT: Обновлено на основе ошибки, упомянутой в комментариях.

Вы можете конвертировать их

A = struct('one', [A.one], 'two', [A.two]); 

В общем:

D = [fieldnames(A), cellfun(@(x) [A.(x)], fieldnames(A), 'Uni', false)].'; 
A = struct(D{:}); 

OLD ОТВЕТ:

Вы можете конвертировать их

A.one = [A.one]; 
A.two = [A.two]; 

В общем

for theField = fieldnames(A)' 
    F = theField{1}; 
    A.(F) = [A.(F)]; 
end 
+0

Это еще одно очень полезное предложение. Спасибо. –

+1

Оценка первой строки вашего ответа вызывает ошибку: 'Некорректное количество элементов правой стороны в назначении имени точки. Отсутствует [] вокруг левой руки Сторона вероятная причина. ', Хотя определенно есть []. Я предполагаю, что это связано с тем фактом, что исходный A.one является структурой 1 * 3 структур 1 * 1, которые содержат «один» и «два». Любая идея, что делать в этом случае, за исключением использования другого имени переменной? –

+1

@FredS Это происходит, когда вы пишете ответ без тестирования. Я обновил его с правильным и проверенным ответом :-) –

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