9
$\begingroup$

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 -> {[email protected], 18}]

enter image description here


I hope I haven't missed anything obvious. Any ideas?

$\endgroup$
7
  • 8
    $\begingroup$ Perhaps that's when Map starts compiling $\endgroup$
    – ssch
    Commented Oct 24, 2013 at 21:25
  • 1
    $\begingroup$ I fiddled with SystemOptions["CompileOptions" -> "MapCompileLength"] and the plot changed, but now even after restarting the kernel I can't reproduce the original plot. Strange indeed :) $\endgroup$
    – ssch
    Commented Oct 24, 2013 at 21:33
  • $\begingroup$ @ssch I must admit I have not done much compiling in MMA, so could you explain, even if it is so, why Map does not care about overwritten definition? $\endgroup$
    – Kuba
    Commented Oct 24, 2013 at 21:35
  • 2
    $\begingroup$ I can only speculate, I guess that the compiler sees Identity and assumes it knows how that behaves, not looking for changed definition. $\endgroup$
    – ssch
    Commented Oct 24, 2013 at 21:37
  • 3
    $\begingroup$ 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. $\endgroup$ Commented Oct 24, 2013 at 21:56

1 Answer 1

4
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.