No olvides que en las ciencias un problema casi siempere puede tener diversas resoluciones, por lo tanto nosotros aquí compartimos lo más óptimo y mejor.
Solución:
Tenga cuidado con la asignación de un “formulario” (por ejemplo, MatrixForm
) a una variable. Otra observación es que a
es un SparseArray
usa reglas para almacenar los valores y desde ReplaceAll
trabaja con el FullForm
de una expresión hay que tener cuidado (usando Normal
hará el array una matriz regular de nuevo).
Esto debería funcionar:
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 /; [email protected][x, 1 | 1/2] -> 0;
aMod // MatrixForm
La sugerencia de Lukas Lang es aún mejor:
aMod = (a // Normal) /. Except[1 | 1/2, _?NumericQ] -> 0;
ACTUALIZAR
@HenrikSchumacher, por supuesto, tiene razón al advertir contra el uso de Normal
para SparseArray
— después de todo, puede haber una buena razón para usarlo en primer lugar. Entonces, para una solución de reemplazo de patrón, el uso de ArrayRules
puede ser más seguro:
aMod = ( a // ArrayRules ) // RightComposition[
ReplaceAll @ Rule[
Rule[row_?NumericQ, col_?NumericQ, Except[ 1 | 1/2, _?NumericQ ],
Rule[row,col, 0]
]
, SparseArray
];
aMod // MatrixForm
A = KroneckerProduct[PotentialTilde[1], PotentialTilde[1]];
B = A (1 - Unitize[A - 1/2] Unitize[A - 1]);
B // MatrixForm
es incluso mucho más eficiente usar números de precisión de máquina:
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.
Es aún más rápido (pero también un poco más tedioso), operar solo en la lista de valores distintos de cero usando la representación de bajo nivel de SparseArray
y lo siguiente indocumentado 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
La ventaja sobre la modificación ArrayRules
es que deja todas las matrices empaquetadas (solo se pueden empaquetar para números de precisión de máquina o enteros de máquina; no para entradas simbólicas), mientras que ArrayRules
desempaqueta la lista de posiciones distintas de cero y valores distintos de cero para generar la lista simbólica de reglas.
¿Deberías preguntarte por qué? SparseArray
aparece dos veces aquí: [email protected]@...
construye lo escaso array literalmente por los punteros de fila, los índices de columna y los “valores distintos de cero” proporcionados, incluso si en realidad hay ceros entre los “valores distintos de cero”; envolviendo esto con otro SparseArray
elimina estos “fantasmas” de la representación interna, de modo que NB2["NonzeroValues"]
devuelve realmente solo los valores distintos de cero.
a no puede ser un MatrixForm:
(a = KroneckerProduct[PotentialTilde[1],
PotentialTilde[1]]) // MatrixForm
Convertir a una matriz regular:
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]
Acuérdate de que tienes la opción de parafrasear si descubriste tu contratiempo en el momento clavado.