Set every element to zero in matrix unless it's 1 or 1/2
$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:
$$ $$">
How do I set every element that is not equal to 1
or 1/2
to 0
?
list-manipulation matrix sparse-arrays
$endgroup$
add a comment |
$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:
$$ $$">
How do I set every element that is not equal to 1
or 1/2
to 0
?
list-manipulation matrix sparse-arrays
$endgroup$
$begingroup$
Something likea /. {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 mya
$endgroup$
– SuperCiocia
Jan 18 at 14:19
2
$begingroup$
Look upExcept
. Also, if you want to changea
, you have to assign the result toa
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
add a comment |
$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:
$$ $$">
How do I set every element that is not equal to 1
or 1/2
to 0
?
list-manipulation matrix sparse-arrays
$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:
$$ $$">
How do I set every element that is not equal to 1
or 1/2
to 0
?
list-manipulation matrix sparse-arrays
list-manipulation matrix sparse-arrays
edited Jan 18 at 22:51
m_goldberg
86.8k872197
86.8k872197
asked Jan 18 at 14:12
SuperCiociaSuperCiocia
612412
612412
$begingroup$
Something likea /. {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 mya
$endgroup$
– SuperCiocia
Jan 18 at 14:19
2
$begingroup$
Look upExcept
. Also, if you want to changea
, you have to assign the result toa
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
add a comment |
$begingroup$
Something likea /. {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 mya
$endgroup$
– SuperCiocia
Jan 18 at 14:19
2
$begingroup$
Look upExcept
. Also, if you want to changea
, you have to assign the result toa
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
add a comment |
4 Answers
4
active
oldest
votes
$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
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
$endgroup$
1
$begingroup$
Huh, never applyNormal
toSparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)
$endgroup$
– Henrik Schumacher
Jan 18 at 15:05
add a comment |
$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.
$endgroup$
$begingroup$
(+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applyingArrayRules
instead ofNormal
is saver?
$endgroup$
– gwr
Jan 18 at 16:18
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
Jan 18 at 16:49
add a comment |
$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]
$endgroup$
add a comment |
$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)$
$endgroup$
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
$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
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
$endgroup$
1
$begingroup$
Huh, never applyNormal
toSparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)
$endgroup$
– Henrik Schumacher
Jan 18 at 15:05
add a comment |
$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
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
$endgroup$
1
$begingroup$
Huh, never applyNormal
toSparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)
$endgroup$
– Henrik Schumacher
Jan 18 at 15:05
add a comment |
$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
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
$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
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
edited Jan 18 at 16:15
answered Jan 18 at 14:29
gwrgwr
8,52322761
8,52322761
1
$begingroup$
Huh, never applyNormal
toSparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)
$endgroup$
– Henrik Schumacher
Jan 18 at 15:05
add a comment |
1
$begingroup$
Huh, never applyNormal
toSparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)
$endgroup$
– Henrik Schumacher
Jan 18 at 15:05
1
1
$begingroup$
Huh, never apply
Normal
to SparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)$endgroup$
– Henrik Schumacher
Jan 18 at 15:05
$begingroup$
Huh, never apply
Normal
to SparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)$endgroup$
– Henrik Schumacher
Jan 18 at 15:05
add a comment |
$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.
$endgroup$
$begingroup$
(+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applyingArrayRules
instead ofNormal
is saver?
$endgroup$
– gwr
Jan 18 at 16:18
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
Jan 18 at 16:49
add a comment |
$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.
$endgroup$
$begingroup$
(+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applyingArrayRules
instead ofNormal
is saver?
$endgroup$
– gwr
Jan 18 at 16:18
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
Jan 18 at 16:49
add a comment |
$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.
$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.
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 applyingArrayRules
instead ofNormal
is saver?
$endgroup$
– gwr
Jan 18 at 16:18
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
Jan 18 at 16:49
add a comment |
$begingroup$
(+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applyingArrayRules
instead ofNormal
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
add a comment |
$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]
$endgroup$
add a comment |
$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]
$endgroup$
add a comment |
$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]
$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]
answered Jan 18 at 14:51
Craig CarterCraig Carter
544412
544412
add a comment |
add a comment |
$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)$
$endgroup$
add a comment |
$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)$
$endgroup$
add a comment |
$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)$
$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)$
edited Jan 19 at 0:53
answered Jan 19 at 0:39
Okkes DulgerciOkkes Dulgerci
5,0291917
5,0291917
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
$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 changea
, you have to assign the result toa
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