Most readable syntax to fill table in a for cycle
9 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
f
el 11 de Abr. de 2023
Comentada: Dr D
el 18 de Abr. de 2023
What is the clearest syntax to fill a table entry by entry in a for cycle? For instance, take the following code that checks convergence of a certain iteration.
format short e
x = rand();
T = table();
for k = 1:5
x = 1/2 * (x + 1/x);
T.x(k) = x;
T.residual(k) = abs(x - sign(x));
end
T
This code looks very readable to me, but it has the drawback of displaying lots of spurious warnings.
All other solutions I have found require specifying things in two places; for instance, setting column types and names in advance and then identifying them by position. I find this cumbersome because I would like to be able to specify things in only one place. This code should go in my lecture notes and it is meant for readability and "least surprise", not performance.
0 comentarios
Respuesta aceptada
Les Beckham
el 11 de Abr. de 2023
There probably isn't a significantly cleaner way to do this. See below for a way to suppress the warnings.
format short e
x = rand();
T = table();
warning('off', 'MATLAB:table:RowsAddedExistingVars')
for k = 1:5
x = 1/2 * (x + 1/x);
T.x(k) = x;
T.residual(k) = abs(x - sign(x));
end
T
Run the line below after running your code once to find out the warning ID, then add the warning('off', ... command above using the id
% [msg, id] = lastwarn
1 comentario
Dr D
el 18 de Abr. de 2023
Note, of course, that you've turned the warning off for the rest of the MatLab session - all code that follows this point. For robustness, MatLab makes it pretty easy to capture the current warning state, then re-set it after the loop. Like this:
oldWarn = warning( 'off', 'MATLAB:table:RowsAddedExistingVars' );
for ...
end
warning( oldWarn );
Más respuestas (2)
Antoni Garcia-Herreros
el 11 de Abr. de 2023
Hello
You could create the arrays containing x and residual beforehand and create the table afterwards. Something like this:
x=zeros(5,1);
T = table();
x(1)=rand();
for i=2:5
x(i) = 1/2 * (x(i-1) + 1/x(i-1));
end
y=abs(x - sign(x));
T.x=x;
T.residual=y
0 comentarios
Dr D
el 18 de Abr. de 2023
I know you said you don't want to specify the column names & types in advance, but there's one thing to consider for the future. If the table will become very large, adding one row at a time will make the code very slow as the table grows and large blocks of memory have to be reallocated in the background. In professional programming, the acceptable solution is to preallocate your memory. For a table, the best way to do that is to specify the table format in advance, then allocate the entire block of memory one time.
For those who are not familiar, it looks something like the below. Notice how simple it is to specify and preallocate the entire table in only two lines.
(Note, you could do it in one line by specifying a row count in the 'Size' parameter. I find that different versions of MatLab don't properly fill the table with their "missing" values when you do that so since my codes have to run on many different versions, prefer the extra step of explicitly assigning missing().)
T = table( 'Size', [0 2], 'VariableNames', {'x', 'residual'}, 'VariableTypes', {'double','double'} );
T{1:5,:} = missing();
for k = 1:height(T)
...
0 comentarios
Ver también
Categorías
Más información sobre Logical en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!