That code as posted does not attempt to produce a 906 x 1808 x 2 x 1692 array, but it would not take a lot of changes to make it do so.
Cm = zeros(a,b, numel(channels), numel(Times), 'single');
would take half of the memory compared to double precision.
Cm = rand(a, b, numel(channels), numel(Times), 'single');
would create the entire array at one time without a loop. However, I am not completely sure at the moment whether it would only create single precision numbers, or if it would try to generate a full double precision array and then convert it to single precision. Using a loop to generate a portion at a time is not unreasonable -- though I would suggest rand(a, b, numel(channels), 'single') at a time rather than rand(a,b,'single') in order to take fewer calls.
My intuitive data structure would be hashed array tree
Unfortunately the original stackoverflow postgres related question no longer exists so we do not know what was being asked at the time. What I can say is that in MATLAB, a 4D array is the most memory efficient way that store "dense" numeric values that are logically 4 dimensional. Random numbers that are uncorrelated are barely compressible (though it would in theory be possible to compress single precision rand() results losslessly at 3 bytes instead of 4.) Hash tables and cell arrays just add overhead. Sometimes techniques such as hash tables are useful, especially in sparse situations, but at the moment I do not see any reason to use them here.