How to randomize order of functions

조회 수: 1 (최근 30일)
Erik J
Erik J 2023년 4월 26일
댓글: Erik J 2023년 5월 1일
I have a function that calls a number of sub-functions. Each of these sub-functions is a test with slight differences but the same basic purpose and a single output. A basic example is given below. What I need to do is have the 4 test functions run in a randomized order each time. I am unsure how to go about it. Any help is much appreciated. Thank you.
function [results] = runTests(testparamters)
result1 = test1(testparameters);
result2 = test2(testparameters);
result3 = test3(testparameters);
result4 = test4(testparameters);
results = [result1 result2 result3 result4];
end
  댓글 수: 2
Dyuman Joshi
Dyuman Joshi 2023년 4월 26일
"What I need to do is have the 4 test functions run in a randomized order each time."
But that wouldn't change the final output of runTests().
Do you want to get the results array with random combination of the result1, result2, result3 and result4 ? (As @Matt has shown below) If this is not what you want, please specify.
Erik J
Erik J 2023년 4월 26일
I actually want the results array in order (result 1, result 2, etc), but the functions delivered in random order.
The reason for this is that these tests deliver behavioral experiments to human subjects using different stimuli. Because humans are good at learning, the order that each subject receives the individual tests needs to be random (so it is not the same from subject to subject). This could be done manually, but there are many tests in the protocol and it would be difficult.

댓글을 달려면 로그인하십시오.

채택된 답변

James Tursa
James Tursa 2023년 4월 26일
편집: James Tursa 2023년 4월 27일
E.g., Using the cell array approach with randperm:
function [results] = runTests(testparameters)
f = {@test1,@test2,@test3,@test4};
ix = randperm(4);
result1 = f{ix(1)}(testparameters);
result2 = f{ix(2)}(testparameters);
result3 = f{ix(3)}(testparameters);
result4 = f{ix(4)}(testparameters);
results = [result1 result2 result3 result4];
end
If the results are scalars, then this could be shortened to:
function [results] = runTests(testparameters)
f = {@test1,@test2,@test3,@test4};
results = arrayfun(@(x)f{x}(testparameters),randperm(4));
end
And given that this function is now essentially a one-liner, you might just skip the function runTests altogether and simply include that results line in your calling code directly.
That all being said, if there is learning involved from one call to the next (i.e., the test functions are not independent), then you might not want to use the one-liner approach since you cannot assume arrayfun( ) is guaranteed to call the functions in a particular order. In that case, use the explicit order calling code instead (or use an explicit loop).
  댓글 수: 1
Erik J
Erik J 2023년 5월 1일
Thanks James. This works perfectly.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Matt
Matt 2023년 4월 26일
Hi,
By curiosity in what context do you need to do something like this ?
You can store the functions handles in a cell and call randomly the cells element like this :
x = 1;
N_fun = 3;
[~,random_index] = sort(rand(1,N_fun));
fun_list = {@f1,@f2,@f3};
results = nan(1,N_fun);
for ii=1:N_fun
results(ii)=fun_list{random_index(ii)}(x);
end
results
function y =f1(x)
y = 1;
end
function y =f2(x)
y = 2;
end
function y =f3(x)
y = 3;
end
  댓글 수: 1
Erik J
Erik J 2023년 4월 26일
The reason for this is that these tests deliver behavioral experiments to human subjects using different stimuli. Because humans are good at learning, the order that each subject receives the individual tests needs to be random (so it is not the same from subject to subject). This could be done manually, but there are many tests in the protocol and it would be difficult.
It seems that this approach could work.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Hypothesis Tests에 대해 자세히 알아보기

제품


릴리스

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by