MATLAB Language
Errores comunes y errores.
Buscar..
No nombre una variable con un nombre de función existente
Ya existe una función sum()
. Como resultado, si nombramos una variable con el mismo nombre
sum = 1+3;
y si intentamos usar la función mientras la variable aún existe en el área de trabajo
A = rand(2);
sum(A,1)
Obtendremos el error críptico:
Subscript indices must either be real positive integers or logicals.
clear()
la variable primero y luego usar la función
clear sum
sum(A,1)
ans =
1.0826 1.0279
¿Cómo podemos verificar si ya existe una función para evitar este conflicto?
Utilice which()
con la bandera -all
:
which sum -all
sum is a variable.
built-in (C:\Program Files\MATLAB\R2016a\toolbox\matlab\datafun\@double\sum) % Shadowed double method
...
Esta salida nos dice que la sum
es primero una variable y que los siguientes métodos (funciones) están ensombrecidos, es decir, MATLAB primero intentará aplicar nuestra sintaxis a la variable, en lugar de usar el método.
Lo que ves NO es lo que obtienes: char vs cellstring en la ventana de comandos
Este es un ejemplo básico dirigido a nuevos usuarios. No se enfoca en explicar la diferencia entre char
y cellstring
.
Puede suceder que quieras deshacerte de '
en tus cuerdas, aunque nunca las hayas agregado. De hecho, esos son artefactos que la ventana de comando usa para distinguir entre algunos tipos.
Una cadena se imprimirá
s = 'dsadasd'
s =
dsadasd
Se imprimirá una cadena de celdas .
c = {'dsadasd'};
c =
'dsadasd'
Observe cómo las comillas simples y la sangría son artefactos para notificarnos que c
es una cellstring
lugar de un char
. La cadena está de hecho contenida en la celda, es decir
c{1}
ans =
dsadasd
Los operadores de transposición.
-
.'
Es la forma correcta de transponer un vector o matriz en MATLAB. -
'
es la forma correcta de tomar el complejo transpuesto de conjugado (también conocido como conjugado de Hermitian) de un vector o matriz en MATLAB.
Tenga en cuenta que para la transposición .'
, hay un punto delante del apóstrofe. Esto está en consonancia con la sintaxis de las demás operaciones de elementos de MATLAB: *
multiplica matrices,. .*
Multiplica elementos de matrices juntos. Los dos comandos son muy similares, pero conceptualmente muy distintos. Al igual que otros comandos de MATLAB, estos operadores son "azúcar sintáctica" que se convierte en una llamada de función "adecuada" en tiempo de ejecución. Así como ==
convierte en una evaluación de la función eq , piensa en .'
como la taquigrafía para la transpose
. Si solo escribiera '
(sin el punto), de hecho está utilizando el comando ctranspose
, que calcula la transposición compleja del conjugado , que también se conoce como el conjugado de Hermitian , a menudo utilizado en la física. Mientras el vector o matriz transpuesta tenga un valor real, los dos operadores producen el mismo resultado. Pero tan pronto como tratemos con números complejos , inevitablemente tendremos problemas si no usamos la taquigrafía "correcta". Lo que es "correcto" depende de su aplicación.
Considere el siguiente ejemplo de una matriz C
contiene números complejos:
>> C = [1i, 2; 3*1i, 4]
C =
0.0000 + 1.0000i 2.0000 + 0.0000i
0.0000 + 3.0000i 4.0000 + 0.0000i
Tomemos la transposición usando la taquigrafía .'
(con el periodo). La salida es la esperada, la forma transpuesta de C
>> C.'
ans =
0.0000 + 1.0000i 0.0000 + 3.0000i
2.0000 + 0.0000i 4.0000 + 0.0000i
Ahora, vamos a usar '
(sin el punto). Vemos que, además de la transposición, los valores complejos también se han transformado en sus conjugados complejos .
>> C'
ans =
0.0000 - 1.0000i 0.0000 - 3.0000i
2.0000 + 0.0000i 4.0000 + 0.0000i
En resumen, si pretende calcular el conjugado de Hermitian, el complejo de transposición de conjugado, use '
(sin el punto). Si solo desea calcular la transposición sin conjugar complejos los valores, utilice .'
(con el periodo).
Función indefinida o método X para argumentos de entrada de tipo Y
Esta es la manera larga de MATLAB de decir que no puede encontrar la función a la que intenta llamar. Hay varias razones por las que puedes obtener este error:
Esa función fue introducida después de su versión actual de MATLAB
La documentación en línea de MATLAB proporciona una característica muy agradable que le permite determinar en qué versión se introdujo una función determinada. Se encuentra en la parte inferior izquierda de cada página de la documentación:
Compare esta versión con su propia versión actual ( ver
) para determinar si esta función está disponible en su versión particular. Si no es así, intente buscar las versiones archivadas de la documentación para encontrar una alternativa adecuada para su versión.
¡No tienes esa caja de herramientas!
La instalación base de MATLAB tiene un gran número de funciones; sin embargo, las funcionalidades más especializadas se empaquetan en cajas de herramientas y se venden por separado por Mathworks. La documentación de todas las cajas de herramientas está visible tanto si tiene la caja de herramientas como si no, así que asegúrese de verificar y ver si tiene la caja de herramientas adecuada.
Para verificar a qué caja de herramientas pertenece una función determinada, consulte la parte superior izquierda de la documentación en línea para ver si se menciona una caja de herramientas específica.
Luego, puede determinar qué cajas de herramientas ha instalado su versión de MATLAB emitiendo el comando ver
que imprimirá una lista de todas las cajas de herramientas instaladas.
Si no tiene esa caja de herramientas instalada y desea usar la función, deberá comprar una licencia para esa caja de herramientas en particular de The Mathworks.
MATLAB no puede localizar la función
Si MATLAB aún no puede encontrar su función, entonces debe ser una función definida por el usuario. Es posible que se encuentre en otro directorio y ese directorio se debe agregar a la ruta de búsqueda para que se ejecute su código. Puede verificar si MATLAB puede localizar su función usando which
que debería devolver la ruta al archivo fuente.
Tenga en cuenta la inexactitud del punto flotante
Los números de punto flotante no pueden representar todos los números reales. Esto se conoce como inexactitud de punto flotante.
Hay infinitos números de puntos flotantes y pueden ser infinitamente largos (por ejemplo, π
), por lo que ser capaz de representarlos perfectamente requeriría una cantidad infinita de memoria. Al ver que esto era un problema, se diseñó una representación especial para el almacenamiento de "número real" en computadora, el estándar IEEE 754 . En resumen, describe cómo las computadoras almacenan este tipo de números, con un exponente y una mantisa, como,
floatnum = sign * 2^exponent * mantissa
Con una cantidad limitada de bits para cada uno de estos, solo se puede lograr una precisión finita. Cuanto menor sea el número, menor será el espacio entre los posibles números (y viceversa). Puedes probar tus números reales en esta demostración en línea .
Tenga en cuenta este comportamiento e intente evitar todas las comparaciones de puntos flotantes y su uso como condiciones de detención en los bucles. Vea a continuación dos ejemplos:
Ejemplos: comparación de punto flotante MAL:
>> 0.1 + 0.1 + 0.1 == 0.3
ans =
logical
0
Es una mala práctica usar la comparación de punto flotante como se muestra en el ejemplo anterior. Puede superarlo tomando el valor absoluto de su diferencia y comparándolo con un nivel de tolerancia (pequeño).
A continuación se muestra otro ejemplo, donde se usa un número de punto flotante como condición de detención en un bucle while: **
k = 0.1;
while k <= 0.3
disp(num2str(k));
k = k + 0.1;
end
% --- Output: ---
0.1
0.2
Se pierde el último bucle esperado ( 0.3 <= 0.3
).
Ejemplo: comparación de punto flotante a la DERECHA:
x = 0.1 + 0.1 + 0.1;
y = 0.3;
tolerance = 1e-10; % A "good enough" tolerance for this case.
if ( abs( x - y ) <= tolerance )
disp('x == y');
else
disp('x ~= y');
end
% --- Output: ---
x == y
Varias cosas a tener en cuenta:
- Como era de esperar, ahora
x
ey
se tratan como equivalentes. - En el ejemplo anterior, la elección de la tolerancia se hizo de forma arbitraria. Por lo tanto, el valor elegido puede no ser adecuado para todos los casos (especialmente cuando se trabaja con números mucho más pequeños). La elección inteligente del límite se puede hacer utilizando la función
eps
, es decir,N*eps(max(x,y))
, dondeN
es un número específico del problema. Una opción razonable paraN
, que también es lo suficientemente permisiva, es1E2
(aunque, en el problema anterior,N=1
también sería suficiente).
Otras lecturas:
Vea estas preguntas para obtener más información sobre la inexactitud de punto flotante:
los argumentos de entrada no son suficientes
A menudo, los desarrolladores principiantes de MATLAB utilizarán el editor de MATLAB para escribir y editar código, en particular funciones personalizadas con entradas y salidas. Hay un botón Ejecutar en la parte superior que está disponible en las versiones recientes de MATLAB:
Una vez que el desarrollador termina con el código, a menudo se ven tentados a presionar el botón Ejecutar . Para algunas funciones esto funcionará bien, pero para otras recibirán un error de Not enough input arguments
y quedarán desconcertados acerca de por qué ocurre el error.
La razón por la que este error puede no ocurrir es porque escribió un script de MATLAB o una función que no admite argumentos de entrada. El uso del botón Ejecutar ejecutará un script de prueba o ejecutará una función suponiendo que no hay argumentos de entrada. Si su función requiere argumentos de entrada, se producirá el error Not enough input arguments
escribir una función que espera que las entradas entren dentro de la función. Por lo tanto, no puede esperar que la función se ejecute simplemente presionando el botón Ejecutar .
Para demostrar este problema, supongamos que tenemos una función mult
que simplemente multiplica dos matrices juntas:
function C = mult(A, B)
C = A * B;
end
En las versiones recientes de MATLAB, si escribió esta función y presionó el botón Ejecutar , le dará el error que esperamos:
>> mult
Not enough input arguments.
Error in mult (line 2)
C = A * B;
Hay dos formas de resolver este problema:
Método # 1 - A través del símbolo del sistema
Simplemente cree las entradas que necesita en la solicitud de comando, luego ejecute la función usando esas entradas que ha creado:
A = rand(5,5);
B = rand(5,5);
C = mult(A,B);
Método # 2 - Interactivamente a través del Editor
Debajo del botón Ejecutar , hay una flecha negra oscura. Si hace clic en esa flecha, puede especificar las variables que desea obtener del área de trabajo de MATLAB escribiendo la forma en que desea llamar a la función exactamente como lo ha visto en el método # 1. Asegúrese de que las variables que está especificando dentro de la función existen en el espacio de trabajo de MATLAB:
Cuidado con los cambios de tamaño de matriz
Algunas operaciones comunes en MATLAB, como la diferenciación o la integración , producen resultados que tienen una cantidad de elementos diferente a la que tienen los datos de entrada. Este hecho se puede pasar por alto fácilmente, lo que generalmente causaría errores, como las Matrix dimensions must agree
. Considere el siguiente ejemplo:
t = 0:0.1:10; % Declaring a time vector
y = sin(t); % Declaring a function
dy_dt = diff(y); % calculates dy/dt for y = sin(t)
Digamos que queremos trazar estos resultados. Echamos un vistazo a los tamaños de matriz y vemos:
size(y) is 1x101
size(t) is 1x101
Pero:
size(dy_dt) is 1x100
La matriz es un elemento más corto!
Ahora imagine que tiene datos de medición de posiciones a lo largo del tiempo y desea calcular el tirón (t) , obtendrá una matriz de 3 elementos menos que la matriz de tiempo (porque el tirón es la posición diferenciada 3 veces).
vel = diff(y); % calculates velocity vel=dy/dt for y = sin(t) size(vel)=1x100
acc = diff(vel); % calculates acceleration acc=d(vel)/dt size(acc)=1x99
jerk = diff(acc); % calculates jerk jerk=d(acc)/dt size(jerk)=1x98
Y luego operaciones como:
x = jerk .* t; % multiplies jerk and t element wise
Devuelve errores, porque las dimensiones de la matriz no concuerdan.
Para calcular operaciones como las anteriores, debe ajustar el tamaño del arreglo más grande para que se ajuste al tamaño más pequeño. También puede ejecutar una regresión ( polyfit
) con sus datos para obtener un polinomio para sus datos.
Errores de desajuste en la dimensión
Los errores de desajuste de dimensión suelen aparecer cuando:
- No prestar atención a la forma de las variables devueltas de las llamadas de función / método. En muchas funciones integradas de MATLAB, las matrices se convierten en vectores para acelerar los cálculos, y la variable devuelta podría ser un vector en lugar de la matriz que esperábamos. Este es también un escenario común cuando se trata de enmascaramiento lógico .
- Usar tamaños de matriz incompatibles al invocar la expansión de matriz implícita .
El uso de "i" o "j" como unidad imaginaria, índices de bucle o variable común.
Recomendación
Debido a que los símbolos i
y j
pueden representar cosas significativamente diferentes en MATLAB, su uso como índices de bucle ha dividido la comunidad de usuarios de MATLAB desde hace años. Si bien algunas razones históricas de rendimiento podrían ayudar a que el equilibrio se incline hacia un lado, este ya no es el caso y ahora la elección depende exclusivamente de usted y de las prácticas de codificación que elija seguir.
Las recomendaciones oficiales actuales de Mathworks son:
- Como
i
es una función, se puede anular y utilizar como variable. Sin embargo, es mejor evitar el uso dei
yj
para nombres de variables si pretende usarlos en aritmética compleja.- Para la velocidad y la robustez mejorada en aritmética compleja, use
1i
y1j
lugar dei
yj
.
Defecto
En MATLAB, de forma predeterminada, las letras i
y j
son nombres de function
, que se refieren a la unidad imaginaria en el dominio complejo.
Entonces, por defecto i = j = sqrt(-1)
.
>> i
ans =
0.0000 + 1.0000i
>> j
ans =
0.0000 + 1.0000i
y como es de esperar:
>> i^2
ans =
-1
Usándolos como una variable (para índices de bucle u otra variable)
MATLAB permite usar el nombre de la función incorporada como una variable estándar. En este caso, el símbolo utilizado no apuntará más a la función incorporada sino a su propia variable definida por el usuario. Esta práctica, sin embargo, generalmente no se recomienda, ya que puede generar confusión, dificultad de depuración y mantenimiento ( consulte otro ejemplo de nombre-no-nombre-una-variable-con-un-existente-función-nombre ).
Si es ultra pedante con respecto a las convenciones y las mejores prácticas, evitará usarlas como índices de bucle en este idioma. Sin embargo, el compilador lo permite y es perfectamente funcional, por lo que también puede optar por mantener los viejos hábitos y utilizarlos como iteradores de bucle.
>> A = nan(2,3);
>> for i=1:2 % perfectly legal loop construction
for j = 1:3
A(i, j) = 10 * i + j;
end
end
Tenga en cuenta que los índices de bucle no quedan fuera del alcance al final del bucle, por lo que mantienen su nuevo valor.
>> [ i ; j ]
ans =
2
3
En el caso de que los utilice como variable, asegúrese de que estén inicializados antes de que se utilicen. En el bucle anterior, MATLAB los inicializa automáticamente cuando prepara el bucle, pero si no se inicializa correctamente, puede ver rápidamente que puede introducir inadvertidamente números complex
en su resultado.
Si más adelante, necesita deshacer el sombreado de la función incorporada (= por ejemplo, desea que i
y j
representen la unidad imaginaria nuevamente), puede clear
las variables:
>> clear i j
Ahora entiende la reserva de Mathworks acerca de usarlos como índices de bucle si pretende usarlos en aritmética compleja . Su código estaría plagado de inicializaciones variables y comandos clear
, la mejor manera de confundir al programador más serio (¡ sí, allí! ... ) y los accidentes del programa que están a punto de suceder.
Si no se espera una aritmética compleja, el uso de i
y j
es perfectamente funcional y no hay penalización de rendimiento.
Usándolos como unidad imaginaria:
Si su código tiene que lidiar con números complex
, entonces i
y j
ciertamente serán útiles. Sin embargo, por motivos de desambiguación e incluso para actuaciones, se recomienda utilizar la forma completa en lugar de la sintaxis abreviada. La forma completa es 1i
(o 1j
).
>> [ i ; j ; 1i ; 1j]
ans =
0.0000 + 1.0000i
0.0000 + 1.0000i
0.0000 + 1.0000i
0.0000 + 1.0000i
Ellos representan el mismo valor sqrt(-1)
, pero la forma posterior:
- Es más explícito, de forma semántica.
- es más fácil de mantener (alguien que mire su código más adelante no tendrá que leerlo para saber si
i
oj
era una variable o la unidad imaginaria). - Es más rápido (fuente: Mathworks).
Tenga en cuenta que la sintaxis completa 1i
es válida con cualquier número que preceda al símbolo:
>> a = 3 + 7.8j
a =
3.0000 + 7.8000i
Esta es la única función que puede mantener con un número sin un operador entre ellos.
Escollos
Si bien su uso como unidad O variable imaginaria es perfectamente legal, aquí hay solo un pequeño ejemplo de lo confuso que podría resultar si se mezclan ambos usos:
Vamos a anular i
y convertirlo en una variable:
>> i=3
i =
3
Ahora i
es una variable (que contiene el valor 3
), pero solo anulamos la notación abreviada de la unidad imaginaria, la forma completa aún se interpreta correctamente:
>> 3i
ans =
0.0000 + 3.0000i
Lo que ahora nos permite construir las formulaciones más oscuras. Te dejo evaluar la legibilidad de todos los siguientes constructos:
>> [ i ; 3i ; 3*i ; i+3i ; i+3*i ]
ans =
3.0000 + 0.0000i
0.0000 + 3.0000i
9.0000 + 0.0000i
3.0000 + 3.0000i
12.0000 + 0.0000i
Como puede ver, cada valor en la matriz anterior devuelve un resultado diferente. Si bien cada resultado es válido (siempre que esa haya sido la intención inicial), la mayoría de ustedes admitirán que sería una pesadilla adecuada leer un código plagado de tales construcciones.
Usando `length` para arrays multidimensionales
Un error común que tienen los codificadores de MATLAB es usar la función de length
para las matrices (a diferencia de los vectores , para los cuales está destinada). La función de length
, como se menciona en su documentación , " devuelve la longitud de la dimensión de matriz más grande " de la entrada.
Para los vectores, el valor de retorno de la length
tiene dos significados diferentes:
- El número total de elementos en el vector.
- La dimensión más grande del vector.
A diferencia de los vectores, los valores anteriores no serían iguales para las matrices de más de una dimensión no individual (es decir, cuyo tamaño es mayor que 1
). Es por esto que el uso de la length
para matrices es ambiguo. En su lugar, se recomienda utilizar una de las siguientes funciones, incluso cuando se trabaja con vectores, para que la intención del código quede perfectamente clara:
-
size(A)
: devuelve un vector de fila cuyos elementos contienen la cantidad de elementos a lo largo de la dimensión correspondiente deA
-
numel(A)
- devuelve el número de elementos enA
Equivalente aprod(size(A))
. -
ndims(A)
: devuelve el número de dimensiones en la matrizA
Equivalente anumel(size(A))
.
Esto es especialmente importante cuando se escriben funciones de biblioteca vectorizadas "a prueba de futuro", cuyas entradas no se conocen de antemano y pueden tener varios tamaños y formas.