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
14 hours ago
$begingroup$
Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
$endgroup$
– SuperCiocia
14 hours ago
$begingroup$
Also, your command does not change anything to mya
$endgroup$
– SuperCiocia
14 hours ago
1
$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
14 hours ago
$begingroup$
Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
$endgroup$
– Carl Lange
12 hours ago
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 6 hours ago
m_goldberg
84.8k872196
84.8k872196
asked 14 hours ago
SuperCiociaSuperCiocia
545311
545311
$begingroup$
Something likea /. {1 -> 0, 1/2 -> 0}
should do it.
$endgroup$
– Carl Lange
14 hours ago
$begingroup$
Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
$endgroup$
– SuperCiocia
14 hours ago
$begingroup$
Also, your command does not change anything to mya
$endgroup$
– SuperCiocia
14 hours ago
1
$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
14 hours ago
$begingroup$
Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
$endgroup$
– Carl Lange
12 hours ago
add a comment |
$begingroup$
Something likea /. {1 -> 0, 1/2 -> 0}
should do it.
$endgroup$
– Carl Lange
14 hours ago
$begingroup$
Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
$endgroup$
– SuperCiocia
14 hours ago
$begingroup$
Also, your command does not change anything to mya
$endgroup$
– SuperCiocia
14 hours ago
1
$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
14 hours ago
$begingroup$
Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
$endgroup$
– Carl Lange
12 hours ago
$begingroup$
Something like
a /. {1 -> 0, 1/2 -> 0}
should do it.$endgroup$
– Carl Lange
14 hours ago
$begingroup$
Something like
a /. {1 -> 0, 1/2 -> 0}
should do it.$endgroup$
– Carl Lange
14 hours ago
$begingroup$
Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
$endgroup$
– SuperCiocia
14 hours ago
$begingroup$
Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
$endgroup$
– SuperCiocia
14 hours ago
$begingroup$
Also, your command does not change anything to my
a
$endgroup$
– SuperCiocia
14 hours ago
$begingroup$
Also, your command does not change anything to my
a
$endgroup$
– SuperCiocia
14 hours ago
1
1
$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
14 hours ago
$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
14 hours ago
$begingroup$
Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
$endgroup$
– Carl Lange
12 hours ago
$begingroup$
Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
$endgroup$
– Carl Lange
12 hours ago
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
13 hours ago
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
12 hours ago
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
12 hours ago
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
13 hours ago
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
13 hours ago
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 12 hours ago
answered 14 hours ago
gwrgwr
7,87322659
7,87322659
1
$begingroup$
Huh, never applyNormal
toSparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)
$endgroup$
– Henrik Schumacher
13 hours ago
add a comment |
1
$begingroup$
Huh, never applyNormal
toSparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)
$endgroup$
– Henrik Schumacher
13 hours ago
1
1
$begingroup$
Huh, never apply
Normal
to SparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)$endgroup$
– Henrik Schumacher
13 hours ago
$begingroup$
Huh, never apply
Normal
to SparseArray
s. Hell might break loose... ;) (Anyways, +1 of course.)$endgroup$
– Henrik Schumacher
13 hours ago
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
12 hours ago
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
12 hours ago
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
12 hours ago
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
12 hours ago
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 3 hours ago
answered 13 hours ago
Henrik SchumacherHenrik Schumacher
50.7k469145
50.7k469145
$begingroup$
(+1) Very concise and elegant. I updated my solution - maybe for a pattern matching solution applyingArrayRules
instead ofNormal
is saver?
$endgroup$
– gwr
12 hours ago
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
12 hours ago
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
12 hours ago
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
12 hours ago
$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
12 hours ago
$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
12 hours ago
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
12 hours ago
$begingroup$
@gwr Jepp, it definitely is.
$endgroup$
– Henrik Schumacher
12 hours ago
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 14 hours ago
Craig CarterCraig Carter
529412
529412
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 4 hours ago
answered 4 hours ago
Okkes DulgerciOkkes Dulgerci
4,4251817
4,4251817
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
14 hours ago
$begingroup$
Yeah, but I want the opposite. Anything that is NOT equal to 1 and 1/2
$endgroup$
– SuperCiocia
14 hours ago
$begingroup$
Also, your command does not change anything to my
a
$endgroup$
– SuperCiocia
14 hours ago
1
$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
14 hours ago
$begingroup$
Ah, sorry, I misread (and I wasn't at a computer). Glad you've found the answer!
$endgroup$
– Carl Lange
12 hours ago