[multi_array]bug in strides calculation with some storage orderings
If I understand correctly, the multi_array storage order determines which strides are larger than others. In short: if( order[I]>order[I+1]) then stride[I]>stride[I+1] However, the output from the attached code shows that this is not always true. In the attached code, the mono_tonic_print function tests the conditions and prints out the results. The following partial output: :count=3 :permut_v={ 1, 2, 0} :permut_i={ 2, 0, 1} :ma.ordering(*)==permut_v=1 :multi_array_strides:strides()={ 12, 1, 3} :monotonically increasing={ 0, 0} :is_mono_tonic=0 :expected_strides:{ 4, 8, 1} :monotonically increasing={ 1, 1} :is_mono_tonic=1 :count=4 :permut_v={ 2, 0, 1} :permut_i={ 1, 2, 0} :ma.ordering(*)==permut_v=1 :multi_array_strides:strides()={ 4, 8, 1} :monotonically increasing={ 0, 0} :is_mono_tonic=0 :expected_strides:{ 12, 1, 3} :monotonically increasing={ 1, 1} :is_mono_tonic=1 shows that the multi_array code fails this monotonic constrait when the order is one of: :permut_v={ 1, 2, 0} :permut_v={ 2, 0, 1} The code also shows a possible solution. This possible solution uses the inverse permutation instead of the original permutation to calculate the strides, as shown in the expected_strides function. There's also a macro, NO_INVERT_PERMUT, which, if defined, has expected_strides reproduce the multi_array strides, which may help narrow down the source of the error in multi_array's stride calculation. The output is also attached. If macro INDENT_OUTPUT is defined, the code requires: http://svn.boost.org/svn/boost/sandbox/variadic_templates/boost/iostreams/fi... http://svn.boost.org/svn/boost/sandbox/variadic_templates/boost/iostreams/ut... http://svn.boost.org/svn/boost/sandbox/variadic_templates/boost/utility/trac... http://svn.boost.org/svn/boost/sandbox/variadic_templates/boost/utility/inde... If you don't want to download those, then the output will not be nicely indented as shown in the attached output. HTH. -regards, Larry
On 12/30/11 11:02, Larry Evans wrote:
If I understand correctly, the multi_array storage order determines which strides are larger than others. In short:
if( order[I]>order[I+1]) then stride[I]>stride[I+1]
However, the output from the attached code shows that this is not always true. [snip] Sorry, I should have read the example on:
http://www.boost.org/doc/libs/1_48_0/libs/multi_array/doc/user.html#sec_stor... which contains: // Store last dimension, then first, then middle array_type::size_type ordering[] = {2,0,1}; which I think implies the calculate order for the strides is the last dimension 1st(2 is last dimension), then the first dimension 2nd(0 is the middle dimension), then the middle dimension 3ird(1 is the middle dimension). which is the inverse permutation of what I was thinking the storage ordering meant. IOW, I thought storage order: {2,0,1} meant the middle dimension had the smallest stride(value 0 in above), the last dimension had the next smallest stride(value 1 in above), and the first dimension had the largest stride(value 2 in above). That interpretation would mean that the calculation order for the strides would be: the middle dimension stride would be calculated 1st, then last dimension would be calculated 2nd, then the first dimension would be calculated 3ird. However, I now realize that assumption was wrong. Sorry for noise. -regards, Larry
participants (1)
-
Larry Evans