Set every element to zero in matrix unless it's 1 or 1/2












11












$begingroup$


I have the following code:



max = 1;

PotentialTilde[V0_] :=
SparseArray[{Band[{1, 1}] -> V0/1, Band[{2, 1}] -> V0/2,
Band[{1, 2}] -> V0/2}, {2*max + 1, 2*max + 1 }];

a = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]] //
MatrixForm


That generates this matrix:



<span class=$$ $$">





How do I set every element that is not equal to 1 or 1/2 to 0?










share|improve this question











$endgroup$












  • $begingroup$
    Something like a /. {1 -> 0, 1/2 -> 0} should do it.
    $endgroup$
    – Carl Lange
    Jan 18 at 14:17










  • $begingroup$
    Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
    $endgroup$
    – SuperCiocia
    Jan 18 at 14:18










  • $begingroup$
    Also, your command does not change anything to my a
    $endgroup$
    – SuperCiocia
    Jan 18 at 14:19






  • 2




    $begingroup$
    Look up Except. Also, if you want to change a, you have to assign the result to a again. (In Mathematica, barely anything changes variables, most things are immutable)
    $endgroup$
    – Lukas Lang
    Jan 18 at 14:25










  • $begingroup$
    Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
    $endgroup$
    – Carl Lange
    Jan 18 at 16:32
















11












$begingroup$


I have the following code:



max = 1;

PotentialTilde[V0_] :=
SparseArray[{Band[{1, 1}] -> V0/1, Band[{2, 1}] -> V0/2,
Band[{1, 2}] -> V0/2}, {2*max + 1, 2*max + 1 }];

a = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]] //
MatrixForm


That generates this matrix:



<span class=$$ $$">





How do I set every element that is not equal to 1 or 1/2 to 0?










share|improve this question











$endgroup$












  • $begingroup$
    Something like a /. {1 -> 0, 1/2 -> 0} should do it.
    $endgroup$
    – Carl Lange
    Jan 18 at 14:17










  • $begingroup$
    Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
    $endgroup$
    – SuperCiocia
    Jan 18 at 14:18










  • $begingroup$
    Also, your command does not change anything to my a
    $endgroup$
    – SuperCiocia
    Jan 18 at 14:19






  • 2




    $begingroup$
    Look up Except. Also, if you want to change a, you have to assign the result to a again. (In Mathematica, barely anything changes variables, most things are immutable)
    $endgroup$
    – Lukas Lang
    Jan 18 at 14:25










  • $begingroup$
    Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
    $endgroup$
    – Carl Lange
    Jan 18 at 16:32














11












11








11


1



$begingroup$


I have the following code:



max = 1;

PotentialTilde[V0_] :=
SparseArray[{Band[{1, 1}] -> V0/1, Band[{2, 1}] -> V0/2,
Band[{1, 2}] -> V0/2}, {2*max + 1, 2*max + 1 }];

a = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]] //
MatrixForm


That generates this matrix:



<span class=$$ $$">





How do I set every element that is not equal to 1 or 1/2 to 0?










share|improve this question











$endgroup$




I have the following code:



max = 1;

PotentialTilde[V0_] :=
SparseArray[{Band[{1, 1}] -> V0/1, Band[{2, 1}] -> V0/2,
Band[{1, 2}] -> V0/2}, {2*max + 1, 2*max + 1 }];

a = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]] //
MatrixForm


That generates this matrix:



<span class=$$ $$">





How do I set every element that is not equal to 1 or 1/2 to 0?







list-manipulation matrix sparse-arrays






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 18 at 22:51









m_goldberg

86.8k872197




86.8k872197










asked Jan 18 at 14:12









SuperCiociaSuperCiocia

612412




612412












  • $begingroup$
    Something like a /. {1 -> 0, 1/2 -> 0} should do it.
    $endgroup$
    – Carl Lange
    Jan 18 at 14:17










  • $begingroup$
    Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
    $endgroup$
    – SuperCiocia
    Jan 18 at 14:18










  • $begingroup$
    Also, your command does not change anything to my a
    $endgroup$
    – SuperCiocia
    Jan 18 at 14:19






  • 2




    $begingroup$
    Look up Except. Also, if you want to change a, you have to assign the result to a again. (In Mathematica, barely anything changes variables, most things are immutable)
    $endgroup$
    – Lukas Lang
    Jan 18 at 14:25










  • $begingroup$
    Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
    $endgroup$
    – Carl Lange
    Jan 18 at 16:32


















  • $begingroup$
    Something like a /. {1 -> 0, 1/2 -> 0} should do it.
    $endgroup$
    – Carl Lange
    Jan 18 at 14:17










  • $begingroup$
    Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
    $endgroup$
    – SuperCiocia
    Jan 18 at 14:18










  • $begingroup$
    Also, your command does not change anything to my a
    $endgroup$
    – SuperCiocia
    Jan 18 at 14:19






  • 2




    $begingroup$
    Look up Except. Also, if you want to change a, you have to assign the result to a again. (In Mathematica, barely anything changes variables, most things are immutable)
    $endgroup$
    – Lukas Lang
    Jan 18 at 14:25










  • $begingroup$
    Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
    $endgroup$
    – Carl Lange
    Jan 18 at 16:32
















$begingroup$
Something like a /. {1 -> 0, 1/2 -> 0} should do it.
$endgroup$
– Carl Lange
Jan 18 at 14:17




$begingroup$
Something like a /. {1 -> 0, 1/2 -> 0} should do it.
$endgroup$
– Carl Lange
Jan 18 at 14:17












$begingroup$
Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
$endgroup$
– SuperCiocia
Jan 18 at 14:18




$begingroup$
Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
$endgroup$
– SuperCiocia
Jan 18 at 14:18












$begingroup$
Also, your command does not change anything to my a
$endgroup$
– SuperCiocia
Jan 18 at 14:19




$begingroup$
Also, your command does not change anything to my a
$endgroup$
– SuperCiocia
Jan 18 at 14:19




2




2




$begingroup$
Look up Except. Also, if you want to change a, you have to assign the result to a again. (In Mathematica, barely anything changes variables, most things are immutable)
$endgroup$
– Lukas Lang
Jan 18 at 14:25




$begingroup$
Look up Except. Also, if you want to change a, you have to assign the result to a again. (In Mathematica, barely anything changes variables, most things are immutable)
$endgroup$
– Lukas Lang
Jan 18 at 14:25












$begingroup$
Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
$endgroup$
– Carl Lange
Jan 18 at 16:32




$begingroup$
Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
$endgroup$
– Carl Lange
Jan 18 at 16:32










4 Answers
4






active

oldest

votes


















14












$begingroup$

Be careful with assigning a "form" (e.g. MatrixForm) to a variable. Another observation is that a is a SparseArray uses rules to store the values and since ReplaceAll works with the FullForm of an expression care has to be taken (using Normal will make the array a regular matrix again).



This should work:



max = 1;
PotentialTilde[V0_] := SparseArray[{Band[{1, 1}] -> V0/1, Band[{2, 1}] -> V0/2,
Band[{1, 2}] -> V0/2}, {2*max + 1, 2*max + 1}];

a = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
(* a // MatrixForm *)

aMod = (a // Normal) /. x_?NumericQ /; Not@MatchQ[x, 1 | 1/2] -> 0;
aMod // MatrixForm


Matrix



Lukas Lang's suggestion is even nicer:



aMod = (a // Normal) /. Except[1 | 1/2, _?NumericQ] -> 0;


UPDATE



@HenrikSchumacher is of course right in warning against the use of Normal for a SparseArray -- after all there may have been a good reason for using it in the first place. So for a pattern replacement solution the use of ArrayRules may be safer:



aMod = ( a // ArrayRules ) // RightComposition[
ReplaceAll @ Rule[
Rule[{row_?NumericQ, col_?NumericQ}, Except[ 1 | 1/2, _?NumericQ ],
Rule[{row,col}, 0]
]
, SparseArray
];
aMod // MatrixForm





share|improve this answer











$endgroup$









  • 1




    $begingroup$
    Huh, never apply Normal to SparseArrays. Hell might break loose... ;) (Anyways, +1 of course.)
    $endgroup$
    – Henrik Schumacher
    Jan 18 at 15:05





















11












$begingroup$

A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
B = A (1 - Unitize[A - 1/2] Unitize[A - 1]);
B // MatrixForm




It is even much more efficient to use machine precision numbers:



max = 100;
A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
B = A (1 - Unitize[A - 1/2] Unitize[A - 1]); // RepeatedTiming // First

NA = N[A];
NB1 = NA (1. - Unitize[NA - 0.5] Unitize[NA - 1.]); // RepeatedTiming // First

Max[Abs[B - NB]]



0.269



0.0163



0.




It is even faster (but also quite a bit more tedious, though), to operate only on the list of nonzero values by using the low-level representation of SparseArray and the following undocumented constructor:



NB2 = SparseArray[
SparseArray @@ {
Automatic,
Dimensions[NA],
NA["Background"],
{1(*version of SparseArray implementation*),
{
NA["RowPointers"],
NA["ColumnIndices"]
},
With[{vals = NA["NonzeroValues"]},
vals Subtract[1., Unitize[vals - 0.5] Unitize[vals - 1.]]
]
}
}
]; // RepeatedTiming // First



0.00670




The advantage over modifying ArrayRules is that it leaves all arrays packed (they can only be packed for machine precisision numbers or machine integers; not for symbolic entries), while ArrayRules unpacks the list of nonzero positions and nonzero values in order to generate the symbolic list of rules.



Should you wonder why SparseArray appears twice here: SparseArray@@{...} constructs the sparse array literally by the row pointers, column indices and "nonzero values" provided, even if there are actually zeroes among the "nonzero values"; wrapping this with a further SparseArray removes these "ghosts" from the internal representation, so that NB2["NonzeroValues"] returns really only the nonzero values.






share|improve this answer











$endgroup$













  • $begingroup$
    (+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applying ArrayRules instead of Normal is saver?
    $endgroup$
    – gwr
    Jan 18 at 16:18










  • $begingroup$
    @gwr Jepp, it definitely is.
    $endgroup$
    – Henrik Schumacher
    Jan 18 at 16:49



















6












$begingroup$

a cannot be a MatrixForm:



(a = KroneckerProduct[PotentialTilde[1], 
PotentialTilde[1]]) // MatrixForm


Convert to a regular Matrix:



Normal[a] /. {ij_ /; (NumberQ[
ij] && ( ij != 1/2 && ij != 1)) :> 0}

(a = Normal[
a] /. {ij_ /; (NumberQ[
ij] && ( ij != 1/2 && ij != 1)) :>
0}) // MatrixForm
a

MatrixForm[a]





share|improve this answer









$endgroup$





















    4












    $begingroup$

    a UnitStep[a - 1/2] // MatrixForm



    $left(
    begin{array}{ccccccccc}
    1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 & 0 & 0 & 0 \
    frac{1}{2} & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 & 0 & 0 \
    0 & frac{1}{2} & 1 & 0 & 0 & frac{1}{2} & 0 & 0 & 0 \
    frac{1}{2} & 0 & 0 & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 \
    0 & frac{1}{2} & 0 & frac{1}{2} & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 \
    0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 & 0 & 0 & frac{1}{2} \
    0 & 0 & 0 & frac{1}{2} & 0 & 0 & 1 & frac{1}{2} & 0 \
    0 & 0 & 0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 & frac{1}{2} \
    0 & 0 & 0 & 0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 \
    end{array}
    right)$







    share|improve this answer











    $endgroup$













      Your Answer





      StackExchange.ifUsing("editor", function () {
      return StackExchange.using("mathjaxEditing", function () {
      StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
      StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
      });
      });
      }, "mathjax-editing");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "387"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f189758%2fset-every-element-to-zero-in-matrix-unless-its-1-or-1-2%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      14












      $begingroup$

      Be careful with assigning a "form" (e.g. MatrixForm) to a variable. Another observation is that a is a SparseArray uses rules to store the values and since ReplaceAll works with the FullForm of an expression care has to be taken (using Normal will make the array a regular matrix again).



      This should work:



      max = 1;
      PotentialTilde[V0_] := SparseArray[{Band[{1, 1}] -> V0/1, Band[{2, 1}] -> V0/2,
      Band[{1, 2}] -> V0/2}, {2*max + 1, 2*max + 1}];

      a = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      (* a // MatrixForm *)

      aMod = (a // Normal) /. x_?NumericQ /; Not@MatchQ[x, 1 | 1/2] -> 0;
      aMod // MatrixForm


      Matrix



      Lukas Lang's suggestion is even nicer:



      aMod = (a // Normal) /. Except[1 | 1/2, _?NumericQ] -> 0;


      UPDATE



      @HenrikSchumacher is of course right in warning against the use of Normal for a SparseArray -- after all there may have been a good reason for using it in the first place. So for a pattern replacement solution the use of ArrayRules may be safer:



      aMod = ( a // ArrayRules ) // RightComposition[
      ReplaceAll @ Rule[
      Rule[{row_?NumericQ, col_?NumericQ}, Except[ 1 | 1/2, _?NumericQ ],
      Rule[{row,col}, 0]
      ]
      , SparseArray
      ];
      aMod // MatrixForm





      share|improve this answer











      $endgroup$









      • 1




        $begingroup$
        Huh, never apply Normal to SparseArrays. Hell might break loose... ;) (Anyways, +1 of course.)
        $endgroup$
        – Henrik Schumacher
        Jan 18 at 15:05


















      14












      $begingroup$

      Be careful with assigning a "form" (e.g. MatrixForm) to a variable. Another observation is that a is a SparseArray uses rules to store the values and since ReplaceAll works with the FullForm of an expression care has to be taken (using Normal will make the array a regular matrix again).



      This should work:



      max = 1;
      PotentialTilde[V0_] := SparseArray[{Band[{1, 1}] -> V0/1, Band[{2, 1}] -> V0/2,
      Band[{1, 2}] -> V0/2}, {2*max + 1, 2*max + 1}];

      a = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      (* a // MatrixForm *)

      aMod = (a // Normal) /. x_?NumericQ /; Not@MatchQ[x, 1 | 1/2] -> 0;
      aMod // MatrixForm


      Matrix



      Lukas Lang's suggestion is even nicer:



      aMod = (a // Normal) /. Except[1 | 1/2, _?NumericQ] -> 0;


      UPDATE



      @HenrikSchumacher is of course right in warning against the use of Normal for a SparseArray -- after all there may have been a good reason for using it in the first place. So for a pattern replacement solution the use of ArrayRules may be safer:



      aMod = ( a // ArrayRules ) // RightComposition[
      ReplaceAll @ Rule[
      Rule[{row_?NumericQ, col_?NumericQ}, Except[ 1 | 1/2, _?NumericQ ],
      Rule[{row,col}, 0]
      ]
      , SparseArray
      ];
      aMod // MatrixForm





      share|improve this answer











      $endgroup$









      • 1




        $begingroup$
        Huh, never apply Normal to SparseArrays. Hell might break loose... ;) (Anyways, +1 of course.)
        $endgroup$
        – Henrik Schumacher
        Jan 18 at 15:05
















      14












      14








      14





      $begingroup$

      Be careful with assigning a "form" (e.g. MatrixForm) to a variable. Another observation is that a is a SparseArray uses rules to store the values and since ReplaceAll works with the FullForm of an expression care has to be taken (using Normal will make the array a regular matrix again).



      This should work:



      max = 1;
      PotentialTilde[V0_] := SparseArray[{Band[{1, 1}] -> V0/1, Band[{2, 1}] -> V0/2,
      Band[{1, 2}] -> V0/2}, {2*max + 1, 2*max + 1}];

      a = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      (* a // MatrixForm *)

      aMod = (a // Normal) /. x_?NumericQ /; Not@MatchQ[x, 1 | 1/2] -> 0;
      aMod // MatrixForm


      Matrix



      Lukas Lang's suggestion is even nicer:



      aMod = (a // Normal) /. Except[1 | 1/2, _?NumericQ] -> 0;


      UPDATE



      @HenrikSchumacher is of course right in warning against the use of Normal for a SparseArray -- after all there may have been a good reason for using it in the first place. So for a pattern replacement solution the use of ArrayRules may be safer:



      aMod = ( a // ArrayRules ) // RightComposition[
      ReplaceAll @ Rule[
      Rule[{row_?NumericQ, col_?NumericQ}, Except[ 1 | 1/2, _?NumericQ ],
      Rule[{row,col}, 0]
      ]
      , SparseArray
      ];
      aMod // MatrixForm





      share|improve this answer











      $endgroup$



      Be careful with assigning a "form" (e.g. MatrixForm) to a variable. Another observation is that a is a SparseArray uses rules to store the values and since ReplaceAll works with the FullForm of an expression care has to be taken (using Normal will make the array a regular matrix again).



      This should work:



      max = 1;
      PotentialTilde[V0_] := SparseArray[{Band[{1, 1}] -> V0/1, Band[{2, 1}] -> V0/2,
      Band[{1, 2}] -> V0/2}, {2*max + 1, 2*max + 1}];

      a = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      (* a // MatrixForm *)

      aMod = (a // Normal) /. x_?NumericQ /; Not@MatchQ[x, 1 | 1/2] -> 0;
      aMod // MatrixForm


      Matrix



      Lukas Lang's suggestion is even nicer:



      aMod = (a // Normal) /. Except[1 | 1/2, _?NumericQ] -> 0;


      UPDATE



      @HenrikSchumacher is of course right in warning against the use of Normal for a SparseArray -- after all there may have been a good reason for using it in the first place. So for a pattern replacement solution the use of ArrayRules may be safer:



      aMod = ( a // ArrayRules ) // RightComposition[
      ReplaceAll @ Rule[
      Rule[{row_?NumericQ, col_?NumericQ}, Except[ 1 | 1/2, _?NumericQ ],
      Rule[{row,col}, 0]
      ]
      , SparseArray
      ];
      aMod // MatrixForm






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jan 18 at 16:15

























      answered Jan 18 at 14:29









      gwrgwr

      8,52322761




      8,52322761








      • 1




        $begingroup$
        Huh, never apply Normal to SparseArrays. Hell might break loose... ;) (Anyways, +1 of course.)
        $endgroup$
        – Henrik Schumacher
        Jan 18 at 15:05
















      • 1




        $begingroup$
        Huh, never apply Normal to SparseArrays. Hell might break loose... ;) (Anyways, +1 of course.)
        $endgroup$
        – Henrik Schumacher
        Jan 18 at 15:05










      1




      1




      $begingroup$
      Huh, never apply Normal to SparseArrays. Hell might break loose... ;) (Anyways, +1 of course.)
      $endgroup$
      – Henrik Schumacher
      Jan 18 at 15:05






      $begingroup$
      Huh, never apply Normal to SparseArrays. Hell might break loose... ;) (Anyways, +1 of course.)
      $endgroup$
      – Henrik Schumacher
      Jan 18 at 15:05













      11












      $begingroup$

      A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      B = A (1 - Unitize[A - 1/2] Unitize[A - 1]);
      B // MatrixForm




      It is even much more efficient to use machine precision numbers:



      max = 100;
      A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      B = A (1 - Unitize[A - 1/2] Unitize[A - 1]); // RepeatedTiming // First

      NA = N[A];
      NB1 = NA (1. - Unitize[NA - 0.5] Unitize[NA - 1.]); // RepeatedTiming // First

      Max[Abs[B - NB]]



      0.269



      0.0163



      0.




      It is even faster (but also quite a bit more tedious, though), to operate only on the list of nonzero values by using the low-level representation of SparseArray and the following undocumented constructor:



      NB2 = SparseArray[
      SparseArray @@ {
      Automatic,
      Dimensions[NA],
      NA["Background"],
      {1(*version of SparseArray implementation*),
      {
      NA["RowPointers"],
      NA["ColumnIndices"]
      },
      With[{vals = NA["NonzeroValues"]},
      vals Subtract[1., Unitize[vals - 0.5] Unitize[vals - 1.]]
      ]
      }
      }
      ]; // RepeatedTiming // First



      0.00670




      The advantage over modifying ArrayRules is that it leaves all arrays packed (they can only be packed for machine precisision numbers or machine integers; not for symbolic entries), while ArrayRules unpacks the list of nonzero positions and nonzero values in order to generate the symbolic list of rules.



      Should you wonder why SparseArray appears twice here: SparseArray@@{...} constructs the sparse array literally by the row pointers, column indices and "nonzero values" provided, even if there are actually zeroes among the "nonzero values"; wrapping this with a further SparseArray removes these "ghosts" from the internal representation, so that NB2["NonzeroValues"] returns really only the nonzero values.






      share|improve this answer











      $endgroup$













      • $begingroup$
        (+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applying ArrayRules instead of Normal is saver?
        $endgroup$
        – gwr
        Jan 18 at 16:18










      • $begingroup$
        @gwr Jepp, it definitely is.
        $endgroup$
        – Henrik Schumacher
        Jan 18 at 16:49
















      11












      $begingroup$

      A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      B = A (1 - Unitize[A - 1/2] Unitize[A - 1]);
      B // MatrixForm




      It is even much more efficient to use machine precision numbers:



      max = 100;
      A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      B = A (1 - Unitize[A - 1/2] Unitize[A - 1]); // RepeatedTiming // First

      NA = N[A];
      NB1 = NA (1. - Unitize[NA - 0.5] Unitize[NA - 1.]); // RepeatedTiming // First

      Max[Abs[B - NB]]



      0.269



      0.0163



      0.




      It is even faster (but also quite a bit more tedious, though), to operate only on the list of nonzero values by using the low-level representation of SparseArray and the following undocumented constructor:



      NB2 = SparseArray[
      SparseArray @@ {
      Automatic,
      Dimensions[NA],
      NA["Background"],
      {1(*version of SparseArray implementation*),
      {
      NA["RowPointers"],
      NA["ColumnIndices"]
      },
      With[{vals = NA["NonzeroValues"]},
      vals Subtract[1., Unitize[vals - 0.5] Unitize[vals - 1.]]
      ]
      }
      }
      ]; // RepeatedTiming // First



      0.00670




      The advantage over modifying ArrayRules is that it leaves all arrays packed (they can only be packed for machine precisision numbers or machine integers; not for symbolic entries), while ArrayRules unpacks the list of nonzero positions and nonzero values in order to generate the symbolic list of rules.



      Should you wonder why SparseArray appears twice here: SparseArray@@{...} constructs the sparse array literally by the row pointers, column indices and "nonzero values" provided, even if there are actually zeroes among the "nonzero values"; wrapping this with a further SparseArray removes these "ghosts" from the internal representation, so that NB2["NonzeroValues"] returns really only the nonzero values.






      share|improve this answer











      $endgroup$













      • $begingroup$
        (+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applying ArrayRules instead of Normal is saver?
        $endgroup$
        – gwr
        Jan 18 at 16:18










      • $begingroup$
        @gwr Jepp, it definitely is.
        $endgroup$
        – Henrik Schumacher
        Jan 18 at 16:49














      11












      11








      11





      $begingroup$

      A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      B = A (1 - Unitize[A - 1/2] Unitize[A - 1]);
      B // MatrixForm




      It is even much more efficient to use machine precision numbers:



      max = 100;
      A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      B = A (1 - Unitize[A - 1/2] Unitize[A - 1]); // RepeatedTiming // First

      NA = N[A];
      NB1 = NA (1. - Unitize[NA - 0.5] Unitize[NA - 1.]); // RepeatedTiming // First

      Max[Abs[B - NB]]



      0.269



      0.0163



      0.




      It is even faster (but also quite a bit more tedious, though), to operate only on the list of nonzero values by using the low-level representation of SparseArray and the following undocumented constructor:



      NB2 = SparseArray[
      SparseArray @@ {
      Automatic,
      Dimensions[NA],
      NA["Background"],
      {1(*version of SparseArray implementation*),
      {
      NA["RowPointers"],
      NA["ColumnIndices"]
      },
      With[{vals = NA["NonzeroValues"]},
      vals Subtract[1., Unitize[vals - 0.5] Unitize[vals - 1.]]
      ]
      }
      }
      ]; // RepeatedTiming // First



      0.00670




      The advantage over modifying ArrayRules is that it leaves all arrays packed (they can only be packed for machine precisision numbers or machine integers; not for symbolic entries), while ArrayRules unpacks the list of nonzero positions and nonzero values in order to generate the symbolic list of rules.



      Should you wonder why SparseArray appears twice here: SparseArray@@{...} constructs the sparse array literally by the row pointers, column indices and "nonzero values" provided, even if there are actually zeroes among the "nonzero values"; wrapping this with a further SparseArray removes these "ghosts" from the internal representation, so that NB2["NonzeroValues"] returns really only the nonzero values.






      share|improve this answer











      $endgroup$



      A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      B = A (1 - Unitize[A - 1/2] Unitize[A - 1]);
      B // MatrixForm




      It is even much more efficient to use machine precision numbers:



      max = 100;
      A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
      B = A (1 - Unitize[A - 1/2] Unitize[A - 1]); // RepeatedTiming // First

      NA = N[A];
      NB1 = NA (1. - Unitize[NA - 0.5] Unitize[NA - 1.]); // RepeatedTiming // First

      Max[Abs[B - NB]]



      0.269



      0.0163



      0.




      It is even faster (but also quite a bit more tedious, though), to operate only on the list of nonzero values by using the low-level representation of SparseArray and the following undocumented constructor:



      NB2 = SparseArray[
      SparseArray @@ {
      Automatic,
      Dimensions[NA],
      NA["Background"],
      {1(*version of SparseArray implementation*),
      {
      NA["RowPointers"],
      NA["ColumnIndices"]
      },
      With[{vals = NA["NonzeroValues"]},
      vals Subtract[1., Unitize[vals - 0.5] Unitize[vals - 1.]]
      ]
      }
      }
      ]; // RepeatedTiming // First



      0.00670




      The advantage over modifying ArrayRules is that it leaves all arrays packed (they can only be packed for machine precisision numbers or machine integers; not for symbolic entries), while ArrayRules unpacks the list of nonzero positions and nonzero values in order to generate the symbolic list of rules.



      Should you wonder why SparseArray appears twice here: SparseArray@@{...} constructs the sparse array literally by the row pointers, column indices and "nonzero values" provided, even if there are actually zeroes among the "nonzero values"; wrapping this with a further SparseArray removes these "ghosts" from the internal representation, so that NB2["NonzeroValues"] returns really only the nonzero values.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jan 19 at 1:35

























      answered Jan 18 at 14:58









      Henrik SchumacherHenrik Schumacher

      55.2k575154




      55.2k575154












      • $begingroup$
        (+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applying ArrayRules instead of Normal is saver?
        $endgroup$
        – gwr
        Jan 18 at 16:18










      • $begingroup$
        @gwr Jepp, it definitely is.
        $endgroup$
        – Henrik Schumacher
        Jan 18 at 16:49


















      • $begingroup$
        (+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applying ArrayRules instead of Normal is saver?
        $endgroup$
        – gwr
        Jan 18 at 16:18










      • $begingroup$
        @gwr Jepp, it definitely is.
        $endgroup$
        – Henrik Schumacher
        Jan 18 at 16:49
















      $begingroup$
      (+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applying ArrayRules instead of Normal is saver?
      $endgroup$
      – gwr
      Jan 18 at 16:18




      $begingroup$
      (+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applying ArrayRules instead of Normal is saver?
      $endgroup$
      – gwr
      Jan 18 at 16:18












      $begingroup$
      @gwr Jepp, it definitely is.
      $endgroup$
      – Henrik Schumacher
      Jan 18 at 16:49




      $begingroup$
      @gwr Jepp, it definitely is.
      $endgroup$
      – Henrik Schumacher
      Jan 18 at 16:49











      6












      $begingroup$

      a cannot be a MatrixForm:



      (a = KroneckerProduct[PotentialTilde[1], 
      PotentialTilde[1]]) // MatrixForm


      Convert to a regular Matrix:



      Normal[a] /. {ij_ /; (NumberQ[
      ij] && ( ij != 1/2 && ij != 1)) :> 0}

      (a = Normal[
      a] /. {ij_ /; (NumberQ[
      ij] && ( ij != 1/2 && ij != 1)) :>
      0}) // MatrixForm
      a

      MatrixForm[a]





      share|improve this answer









      $endgroup$


















        6












        $begingroup$

        a cannot be a MatrixForm:



        (a = KroneckerProduct[PotentialTilde[1], 
        PotentialTilde[1]]) // MatrixForm


        Convert to a regular Matrix:



        Normal[a] /. {ij_ /; (NumberQ[
        ij] && ( ij != 1/2 && ij != 1)) :> 0}

        (a = Normal[
        a] /. {ij_ /; (NumberQ[
        ij] && ( ij != 1/2 && ij != 1)) :>
        0}) // MatrixForm
        a

        MatrixForm[a]





        share|improve this answer









        $endgroup$
















          6












          6








          6





          $begingroup$

          a cannot be a MatrixForm:



          (a = KroneckerProduct[PotentialTilde[1], 
          PotentialTilde[1]]) // MatrixForm


          Convert to a regular Matrix:



          Normal[a] /. {ij_ /; (NumberQ[
          ij] && ( ij != 1/2 && ij != 1)) :> 0}

          (a = Normal[
          a] /. {ij_ /; (NumberQ[
          ij] && ( ij != 1/2 && ij != 1)) :>
          0}) // MatrixForm
          a

          MatrixForm[a]





          share|improve this answer









          $endgroup$



          a cannot be a MatrixForm:



          (a = KroneckerProduct[PotentialTilde[1], 
          PotentialTilde[1]]) // MatrixForm


          Convert to a regular Matrix:



          Normal[a] /. {ij_ /; (NumberQ[
          ij] && ( ij != 1/2 && ij != 1)) :> 0}

          (a = Normal[
          a] /. {ij_ /; (NumberQ[
          ij] && ( ij != 1/2 && ij != 1)) :>
          0}) // MatrixForm
          a

          MatrixForm[a]






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 18 at 14:51









          Craig CarterCraig Carter

          544412




          544412























              4












              $begingroup$

              a UnitStep[a - 1/2] // MatrixForm



              $left(
              begin{array}{ccccccccc}
              1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 & 0 & 0 & 0 \
              frac{1}{2} & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 & 0 & 0 \
              0 & frac{1}{2} & 1 & 0 & 0 & frac{1}{2} & 0 & 0 & 0 \
              frac{1}{2} & 0 & 0 & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 \
              0 & frac{1}{2} & 0 & frac{1}{2} & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 \
              0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 & 0 & 0 & frac{1}{2} \
              0 & 0 & 0 & frac{1}{2} & 0 & 0 & 1 & frac{1}{2} & 0 \
              0 & 0 & 0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 & frac{1}{2} \
              0 & 0 & 0 & 0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 \
              end{array}
              right)$







              share|improve this answer











              $endgroup$


















                4












                $begingroup$

                a UnitStep[a - 1/2] // MatrixForm



                $left(
                begin{array}{ccccccccc}
                1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 & 0 & 0 & 0 \
                frac{1}{2} & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 & 0 & 0 \
                0 & frac{1}{2} & 1 & 0 & 0 & frac{1}{2} & 0 & 0 & 0 \
                frac{1}{2} & 0 & 0 & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 \
                0 & frac{1}{2} & 0 & frac{1}{2} & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 \
                0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 & 0 & 0 & frac{1}{2} \
                0 & 0 & 0 & frac{1}{2} & 0 & 0 & 1 & frac{1}{2} & 0 \
                0 & 0 & 0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 & frac{1}{2} \
                0 & 0 & 0 & 0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 \
                end{array}
                right)$







                share|improve this answer











                $endgroup$
















                  4












                  4








                  4





                  $begingroup$

                  a UnitStep[a - 1/2] // MatrixForm



                  $left(
                  begin{array}{ccccccccc}
                  1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 & 0 & 0 & 0 \
                  frac{1}{2} & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 & 0 & 0 \
                  0 & frac{1}{2} & 1 & 0 & 0 & frac{1}{2} & 0 & 0 & 0 \
                  frac{1}{2} & 0 & 0 & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 \
                  0 & frac{1}{2} & 0 & frac{1}{2} & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 \
                  0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 & 0 & 0 & frac{1}{2} \
                  0 & 0 & 0 & frac{1}{2} & 0 & 0 & 1 & frac{1}{2} & 0 \
                  0 & 0 & 0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 & frac{1}{2} \
                  0 & 0 & 0 & 0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 \
                  end{array}
                  right)$







                  share|improve this answer











                  $endgroup$



                  a UnitStep[a - 1/2] // MatrixForm



                  $left(
                  begin{array}{ccccccccc}
                  1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 & 0 & 0 & 0 \
                  frac{1}{2} & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 & 0 & 0 \
                  0 & frac{1}{2} & 1 & 0 & 0 & frac{1}{2} & 0 & 0 & 0 \
                  frac{1}{2} & 0 & 0 & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 & 0 \
                  0 & frac{1}{2} & 0 & frac{1}{2} & 1 & frac{1}{2} & 0 & frac{1}{2} & 0 \
                  0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 & 0 & 0 & frac{1}{2} \
                  0 & 0 & 0 & frac{1}{2} & 0 & 0 & 1 & frac{1}{2} & 0 \
                  0 & 0 & 0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 & frac{1}{2} \
                  0 & 0 & 0 & 0 & 0 & frac{1}{2} & 0 & frac{1}{2} & 1 \
                  end{array}
                  right)$








                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 19 at 0:53

























                  answered Jan 19 at 0:39









                  Okkes DulgerciOkkes Dulgerci

                  5,0291917




                  5,0291917






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Mathematica Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      Use MathJax to format equations. MathJax reference.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f189758%2fset-every-element-to-zero-in-matrix-unless-its-1-or-1-2%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                      Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                      A Topological Invariant for $pi_3(U(n))$