I was going to post an answer for fast way to replace all zeros in the matrix. I was even quite happy because timings were the same order of magnitude as others.
The idea was to overwrite Identity
:
Internal`InheritedBlock[{Identity}, Unprotect[Identity]; Identity[0] = 1;
Map[Identity, {{2, 0}, {Pi, 9}}, {2}]]
{{2, 1}, {Pi, 9}}
But I've checked that for bigger matrices the result is not even close to the expected one:
Internal`InheritedBlock[{Identity}, Unprotect[Identity]; Identity[0] = 1;
m = RandomInteger[1, {100, 2}];
Map[Identity, m, {2}] ~ Shallow ~ {5, 2}]
{{0, 1}, {1, 0}, <<98>>}
It seem it breaks at size of the array of about $90$ positions:
test = Internal`InheritedBlock[{Identity}, Unprotect[Identity]; Identity[0] = 1;
Apply[
Boole[Map[Identity, RandomInteger[1, {##}], {2}] == ConstantArray[1, {##}]
]&,
Array[List, {35, 35}],
{2}]];
Show[MatrixPlot[test, DataReversed -> True, Mesh -> All],
ContourPlot[x y == 90, {x, 1, 35}, {y, 1, 35}]
, BaseStyle -> {Thickness@.01, 18}]
I hope I haven't missed anything obvious. Any ideas?
Answer
I think this is related to my own question Block attributes of Equal though the circumstance is different. As already stated in the comments:
I can only speculate, I guess that the compiler sees Identity and assumes it knows how that behaves, not looking for changed definition. – ssch Oct 24 '13 at 21:37
Map auto-compiles, basically applying Compile to your mapped function. Of course, Compile uses its own versions for compilable functions, so whatever top-level definitions you have made won't fire. – Leonid Shifrin Oct 24 '13 at 21:56
Whether it be by auto-compilation or by special optimization for Packed Arrays, one must accept that top-level definitions and attributes may not be used in some cases.
Comments
Post a Comment