Propuesta de solución: Proyecto 02, Mecánica de Materiales

Lo siguiente constituye una propuesta de solución para el problema planteado como proyecto de la unidad III para la asignatura de mecánica de materiales.

En el siguiente PDF incrustado se plantea de forma generalizada el problema y se establecen las ecuaciones de cortante, momento, pendiente y deflexión.

Problema C1 MDM Flexión by Pedro Jorge De los Santos on Scribd

Basado en el desarrollo anterior se hace una programa de linea de comandos utilizando Python, el cual tiene la capacidad de trabajar para N cargas puntuales y trazar el diagrama de fuerza cortante, el diagrama de momentos y la curva de la elástica de la viga.

# -*- coding: utf-8 -*-
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams["font.size"] = 6

def sifu(x,a,n):
    """ Funcion de singularidad -> piecewise form """
    return np.piecewise(a, [a > x, a <= x], [0, lambda a:(x-a)**n])

def leer_fuerzas(n):
    """ Lee las fuerzas puntuales aplicadas """
    F = []
    for x in range(n): F.append(input("P{0}= ".format(x+1)))
    return np.array(F)

def leer_coordenadas(n):
    """ Lee las coordenadas en que se aplican las fuerzas """
    A = []
    for x in range(n): A.append(input("a{0}= ".format(x+1)))
    return np.array(A)

def FV(x,MA,RA,P,a): 
    """ Devuelve el cortante para un punto x """
    return (RA)*x**0 - np.sum((P)*sifu(x,a,0))

def FM(x,MA,RA,P,a): 
    """ Devuelve el momento para un punto x """
    return -(MA)*x**0 + (RA)*x - np.sum((P)*sifu(x,a,1))

def Fm(x,E,I,MA,RA,P,a): 
    """ Devuelve la pendiente para un punto x """
    return (1/(E*I))*(-(MA)*x + (RA/2)*x**2 - np.sum((P/2)*sifu(x,a,2)))

def Fy(x,E,I,MA,RA,P,a):
    """ Devuelve la deflexión para un punto x """
    return (1/(E*I))*(-(MA/2)*x**2 + (RA/6)*x**3 - np.sum((P/6)*sifu(x,a,3)))

def mostrar_info(x0,E,I,MA,RA,P,a,c,Su):
    """ Imprime en consola la información del punto de interés y general"""
    print("V= {0}".format(FV(x0,MA,RA,P,a)))
    print("M= {0}".format(FM(x0,MA,RA,P,a)))
    print("m= {0}".format(Fm(x0,E,I,MA,RA,P,a)))
    print("y= {0}".format(Fy(x0,E,I,MA,RA,P,a)))
    Sm = MA*c/I
    FS = Su/Sm
    print("Esfuerzo max= {0}".format(Sm))
    print("Factor de seguridad= {0}".format(FS))

def main():
    """ Programa principal """
    n = input("Cantidad de fuerzas puntuales a aplicar: ")
    P = leer_fuerzas(n)
    a = leer_coordenadas(n)
    E = input("Modulo de elasticidad (E)= ")
    I = input("Momento de inercia (I)= ")
    L = input("Longitud de la viga (L)= ")
    c = input("Distancia al eje neutro (c)= ")
    Su = input("Esfuerzo ultimo (Su)= ")
    x0 = input("Coordenada de interes (x0)= ")
    #~ P = np.array([1000,800,750,1200]) # for testing
    #~ a = np.array([0.3,0.525,0.825,1.05])
    #~ L = 1.05
    #~ E, I, c, Su, x0 = 200e9, 4.16e-7, 25e-3, 450e6, L/2
    MA = np.sum(P*a)
    RA = np.sum(P)

    xx = np.linspace(0,L,2000)
    V,M,m,y = [],[],[],[]
    for x in xx:
        V += [FV(x,MA,RA,P,a)]
        M += [FM(x,MA,RA,P,a)]
        m += [Fm(x,E,I,MA,RA,P,a)]
        y += [Fy(x,E,I,MA,RA,P,a)]

    mostrar_info(x0,E,I,MA,RA,P,a,c,Su)
    fig, ax = plt.subplots(3, sharex=True)
    ax[0].fill_between(xx, V, color="#1E90FF")
    ax[1].fill_between(xx, M, color="#E35E5E")
    ax[2].plot(xx, y)
    ax[0].set_ylabel("V(x)")
    ax[1].set_ylabel("M(x)")
    ax[2].set_ylabel("y(x)")
    plt.show()

if __name__=='__main__':
    main()

Para ciertos valores de prueba el programa produce una gráfica como la mostrada a continuación:

Implementación del MEF en problemas de ingeniería

El método del elemento finito es utilizado para resolver problemas físicos en análisis de ingeniería y diseño. La figura mostrada enseguida esquematiza el proceso del análisis por elementos finitos. El problema físico típicamente involucra una estructura o ciertos elementos mecánicos sometidos a condiciones de cargas establecidas. La conversión del problema físico a un modelo matemático correspondiente requiere que se hagan consideraciones para la simplificación y resolución de las ecuaciones diferenciales resultantes. El análisis de elementos finitos resuelve ese modelo matemático resultante. Puesto que la solución por elemento finito involucra un procedimiento por técnicas de análisis numérico es necesario evaluar la exactitud de la solución. Si no existe un criterio de exactitud o punto de comparación, la solución numérica debe repetirse refinando algunos parámetros (como la densidad de malla) hasta que las variaciones entre soluciones sean aceptables.

/img/fem_diagram.PNG

Está claro que la solución por elementos finitos resolvera sólo el modelo matemático establecido y la respuesta del sistema reflejará las consideraciones o simplificaciones realizadas a este. La selección de un modelo matemático apropiado es crucial y determina completamente la percepción actual del fenómeno físico que puede obtenerse mediante el análisis. Luego, es claro que, naturalmente, la respuesta de problemas solucionados mediante técnicas de elemento finito no corresponderán exactamente con la situación real, dado que es casi imposible reproducir las condiciones de un entorno tomando en cuenta todas las variables que inciden en el proceso, en la mayoría de los casos se tendrá una comparación basada en la correlación o correspondencia entre la respuesta matemática y la experimental.

Una vez que el modelo matemático ha sido resuelto y los resultados han sido interpretados, se puede entonces considerar la refinación o redefinición del modelo matemático para considerar otros factores que permitan obtener una solución más ajustada a la realidad.

Para definir la confiabilidad y efectividad de un modelo seleccionado debemos pensar en un modelo matemático muy completo del problema físico y medir la respuesta de nuestro modelo seleccionado contra la respuesta del modelo completo. En general, un modelo matemático completo incluye una descripción tridimensional del problema e incluye efectos no-lineales.

Para evaluar el resultado obtenido por la solución de un modelo matemático seleccionado, puede ser necesario también resolver problemas de modelado matemático de orden superior, e incluso ir incluyendo cada vez factores más complejos. Por ejemplo, una viga estructural puede primero analizarse usando la teoría de la viga de Bernoulli, luego usando la teoría de una viga de Timoshenko, siguiendo con una análisis bidimensional por la teoría de esfuerzo plano, y finalmente utilizando un modelo tridimensional continuo, y en cada caso la posibilidad de incluir efectos no lineales.

Claramente con esa jerarquía de modelos, enunciada en el párrafo anterior, el análisis incluirá cada vez respuestas más complejas, incrementando consecuentemente el costo de la solución. Es conocido que un análisis tridimensional es alrededor de un orden de magnitud más costoso que el caso bidimensional, tanto en recursos computacionales como en el tiempo de ingeniería realizada.

Programación en MATLAB, fundamentos y aplicaciones

Desde el año pasado intento escribir unos apuntes/libro sobre programación en MATLAB. El título: Programación en MATLAB, fundamentos y aplicaciones. Del cual la idea es abordar la programación en MATLAB en un nivel básico-intermedio, el libro se escribe para personas que tengan asimiladas las nociones básicas de programación, algoritmos y esas cosas necesarias para comenzar.

Uno de los detalles/cuestionamientos constantes ha sido ¿cómo escribir/editar el libro?, las opciones: Sphinx con ResT, ResT + rst2pdf (una minilibrería creada por Alsina), un editor de textos tipo WYSIWYG, Markdown + pandoc, Markdown + LeanPub, o LaTeX. Y en esa experimentación he pasado por casi todas las opciones, para al finar llegar a quedar con el odioso LaTeX, pero qué le vamos a hacer, a día de hoy (y durante muchos años) es (será) la opción más madura para la edición a partir de texto plano. Claro está que de todos es el que tiene la sintaxis más pesada.

Los apuntes en su versión incompleta están disponibles en la plataforma LeanPub , que permite escribir/editar y publicar/vender libros bajo un esquema muy simple. Cualquiera que guste descargar el libro ahí lo tendrá, gratis claro está. LeanPub, además, está pensado para que los lectores (o potenciales lectores) puedan acceder a libros en una etapa temprana de desarrollo y contribuir con retroalimentación sobre el mismo, lo cual suene por demás interesante, un ganar-ganar.

Sin más, les dejo el link y la portada del libro en cuestión:

https://s3.amazonaws.com/titlepages.leanpub.com/programacionmatlab/hero?1475359772

Descargar

Sobre la tesis

Después de año y medio en la maestría llega el momento de esto: escribir o terminar de escribir la tesis. Y cómo no, con el escándalo del presidente y su manera incorrecta de referenciar y dar el crédito correspondiente a sus autores, claro está que no es tema menor ni mucho menos, así que estaré preocupado por citar correctamente a cada autor implicado, nunca se sabe.

¿Y de qué va la tesis?

Lo cierto es que no es un tema o proyecto con alto de grado de exigencia científica, (ni mediano), si no más orientado hacia cuestiones de mejoras en procesos de producción y manufactura. El título: Simulación por elementos finitos del proceso de formado de un tubo de acero AISI 1018. La idea más general sobre el proyecto es la implementación de un centro de diseño, manufactura y validación de herramentales de producción utilizando tecnología actualizada que permita un desarrollo ágil. Cuestiones más, cuestiones menos.

Estatus actual

Quizá un avance del 55%, espero en noviembre terminar con eso, porque la vida sigue y hay que medio planear lo venidero, que a como va el país tampoco es que se antoje plano.

MATLAB POO II. Definiendo clases

Las clases son el alma de la POO, y suelen definirse en ficheros únicos. En MATLAB pueden crearse utilizando un fichero *.m ordinario y colocando en este la sintaxis para la definición de una clase, la cual se muestra enseguida:

classdef nombreClase
% Descripción de la clase

properties
% Atributos
end

methods
% Métodos
end

end

En la mayoría de los lenguajes que soportan POO se utiliza la palabra clave class para definir una clase, pero en MATLAB class se utiliza para identificar el tipo o clase de una variable u objeto, y en cambio se utiliza classdef para definir una clase. Los atributos de una clase se definen en un bloque properties-end, y pueden simplemente ser declarados sin asignación de valores. Los métodos de la clase se especifican dentro de un bloque methods-end, incluyendo al constructor de la clase.

El constructor de la clase


El constructor de una clase es parte esencial de la misma y en este se definen los argumentos o parámetros formales necesarios para crear un objeto de la clase, de ahí su importancia. En MATLAB el constructor se considera, de manera no estricta, un método y por tanto se define dentro del bloque correspondiente a los métodos. Así pues, incluyendo al constructor la definición de una clase sería algo similar a:

classdef nombreClase
% Descripción de la clase

properties
% Atributos
end

methods
function obj = nombreClase(args)
% Constructor de la clase
end
% ...
% Métodos
% ...
end

end

En lo anterior obj es, dentro la definición de la clase, una referencia al objeto instanciado y es obligatorio el colocarlo como valor de salida (en la terminología de funciones); claro que el identificador obj puede cambiarlo por cualesquiera otro de su comodidad (this o self podrían ser buenas opciones, claro, mucho influye el hecho de haber programado en otro lenguaje de POO en este tipo de adopciones de estilo). Tal como se ejemplifica, el nombre de la función que funge como constructor debe ser el mismo que el de la clase, además deben especificarse los argumentos que se utilizarán para crear un objeto.

La clase Persona, una primera aproximación


En la sección anterior hemos visto la sintaxis para definir una clase, pero como casi todo siempre es mejor asociar un concepto teórico con un ejemplo concreto. Para tal fin crearemos la clase Persona, de naturaleza muy sencilla pero significativa.

En principio vamos a definir las propiedades o atributos que habrán de caracterizar a un objeto de la clase Persona, así pues, dada la simplicidad del caso solamente utilizaremos el nombre y la edad para construir un objeto de esta clase. Por ahora no definiremos método alguno, solamente el constructor de la clase. Véase la definición resultante:

classdef Persona
% Persona
%
% Ejemplo :
% p1 = Persona('Jorge',22);
% p2 = Persona('Anna',28);
%

properties % Atributos de la clase
nombre;
edad;
end

methods
function obj = Persona(nombre,edad) % Constructor
obj.edad=edad;
obj.nombre=nombre;
end
end

end

Para testear una clase podemos crear un script en donde colocar las instrucciones necesarias para crear un objeto de la misma. No obstante, por ahora haremos esto en la ventana de comandos de la siguiente manera:

>> p = Persona('Ana',25);
>> whos
Name Size Bytes Class Attributes
p 1x1 118 Persona

MATLAB POO I. Conceptos básicos

La programación orientada a objetos (POO) es un paradigma de programación que utiliza objetos como parte esencial de sus interacciones, para el desarrollo de aplicaciones y soluciones tecnológicas. La POO está soportada por técnicas de programación tales como la herencia, el polimorfismo, el encapsulamiento, entre otras, cada una de ellas proporciona herramientas que han permitido la proliferación de este modelo de programación en las últimas décadas. Actualmente existen una variedad de lenguajes que soportan la POO, siendo los más conocidos C++, Java y C#.

El soporte moderno de MATLAB para la POO es relativamente nuevo, siendo introducido a partir de la versión 7.6 (R2008a) con notables carencias respecto a los lenguajes de referencia en ese aspecto, pero evidentemente la mejora desde entonces ha sido considerable.

Con soporte moderno se hace alusión a la notación actual que se utiliza en la definición de clases, por ejemplo classdef para crear una clase. Puesto que antes de la implementación de esta notación, existía la posibilidad de programar orientado a objetos haciendo uso de algunos artilugios, como el colocar la clase (definida mediante una función que hacía lo de unconstructor de la clase) y sus métodos dentro de una carpeta cuyo nombre debería ser el de la clase misma anteponiéndole un arroba (@).

Clases y objetos


Una clase es una definición de las propiedades y/o características de un determinado tipo de objetos, es decir, un modelo particular que sirve para crear objetos bajo esas mismas especificaciones.
Un objeto es la representación concreta derivada de una clase que está provisto de atributos y métodos, o en términos más formales: un objeto es la instancia de una clase.

A manera de ejemplo y un contexto más apegado a la realidad, consideremos a los perros como una determinada clase, es sencillo hacernos la idea de cómo es un perro y cuáles son sus características y apariencia general; luego, el perro que tenemos en casa (en caso de que así sea) es una instancia de esa clase o un objeto de la clase perro, con características más particulares pero que no les excluyen de ser un perro.

Atributos


Los atributos son las propiedades asociadas a una clase de objetos. Siguiendo con el ejemplo de los perros, estos tienen atributos como el tamaño, color, raza, temperamento, etc. Es común en la POO diferenciar entre dos tipos de atributos acorde a su accesibilidad: los privados y los públicos. Los privados son atributos disponibles solo dentro de la definición de la clase, en cambio los públicos son accesibles desde cualquier otra clase o fichero de instrucciones.

Métodos


Los métodos de una clase de objetos son algoritmos o bloques de programación que determinan el comportamiento de un objeto. Por lo general los métodos se usan para modificar los atributos de un objeto o bien generar un nuevo evento. En MATLAB los métodos son definidos mediante funciones.

Eventos


Un evento es la reacción que tiene un objeto resultante de la interacción con el usuario o bien mediante la ejecución de los métodos.

MATLAB-Java GUIs I. Una introducción

Bienvenidos, esta será una mini-serie de entradas dedicadas a introducir a los usuarios de MATLAB en el desarrollo de interfaces gráficas utilizando una combinación de controles ordinarios de MATLAB con controles de la librería Swing de Java. Es necesario que el lector tenga conocimientos sólidos en el desarrollo de interfaces gráficas en MATLAB utilizando solamente código (no GUIDE), de programación orientada a objetos en MATLAB, y bueno, sería sensacional si conoce algo de Java.

Para comenzar


Las interfaces gráficas en MATLAB suelen considerarse hasta cierto punto muy limitadas en cuanto a apariencia, funcionalidad y sobre todo a la poca diversidad de controles gráficos disponibles en la librería estándar. Se extraña, por poner un ejemplo, que los Static Text tengan la posibilidad de añadir una imagen, o que a un botón le podamos agregar un ícono junto al texto, o bueno, varias de esas cosas que son posibles y relativamente sencillas de implementar en muchos otros toolkits de interfaces gráficas.

No obstante, MATLAB tiene la posibilidad (y facilidad) de integrar controles gráficos de la librería Swing de Java de manera muy simple en una interfaz gráfica ordinaria. Esto puede lograrse utilizando la función javacomponent, con la cual podemos incrustar controles gráficos de Java en una figure de MATLAB.

Para ir entrando un poco en el tema vamos a mostrar un código muy simple que coloca un JLabel (similar al Static Text) dentro de una GUI:

import javax.swing.*

fig = figure('Name','Ejemplo MATLAB-Java',...
'NumberTitle','off',...
'MenuBar','none',...
'Position',[0,0,200,100]);
centerfig(fig);

lab = JLabel('JLabel Java');
hJlab = javacomponent(lab, 'East', fig);



Ahora vamos a desmenuzar el código anterior:

Primero, importamos todas las clases de la librería Swing, también hubiese sido muy recomendable sólo importar la clase Java que vamos a utilizar: import javax.swing.JLabel. Pero, normalmente (en la vida real) no sólo se utiliza una de las clases de Swing, así que podríamos dejarlo tal cual y ya está. Al importar con import javax.swing.* tenemos disponibles todas las clases de Swing en el workspace de MATLAB, así, sólo necesitamos escribir JLabel para instanciar una etiqueta en lugar del javax.swing.JLabel que deberíamos colocar si no colocamos la instrucción de importar.

Lo que sigue es crear una ventana con la función figure, en la cual colocaremos nuestros controles Java. Y claro, la función centerfig para centrar la ventana en la pantalla.

Aquí viene la parte en donde instanciamos un objeto de la clase JLabel. Normalmente, en Java, tendríamos que escribir algo como:

JLabel lab = new JLabel("JLabel Java");

Pero en MATLAB la sintaxis es más sencilla.

Una vez tenemos creado un objeto de la clase JLabel, tenemos que colocarlo dentro de la ventana que hemos definido con anterioridad, y para eso usaremos la función javacomponent. Lo primero: la función javacomponent tiene la siguiente sintaxis:

[hJ, hM] = javacomponent(javaClassName, position, parent, callback);

Donde javaClassName puede ser un objeto o una clase de Java (en este caso la etiqueta que hemos instanciado), position puede ser un vector de cuatro elementos típico de MATLAB o bien una cadena de texto: SouthWestNorth o East, indicando la ubicación del elemento dentro de la ventana, parent será la ventana o panel en el cual colocaremos el objeto gráfico, y finalmentecallback es un cell array de elementos pareados del tipo evento-handler y cuyo objetivo es especificar el comportamiento de un control gráfico ante un evento determinado, por ahora esto lo hemos dejado vacío, ya que no entraremos aún en el manejo de eventos.

La función javacomponent devuelve normalmente dos valores de salida: hJ será la referencia a la clase Java del control gráfico y a través de este podremos modificar sus características; hM es un handle cuasi ordinario de MATLAB y este nos servirá para modificar las propiedades de posición, unidades y visibilidad del objeto gráfico una vez que este haya sido agregado a la GUI MATLAB.

Modificando las propiedades de un control Java Swing


Para modificar las propiedades de un componente creado con javacomponent podemos hacerlo a través de su referencia, por ejemplo, para el JLabel que utilizamos al principio:

clear;clc;
import javax.swing.*

fig = figure('Name','Ejemplo MATLAB-Java',...
'NumberTitle','off',...
'MenuBar','none',...
'Position',[0,0,200,100]);
centerfig(fig);

lab = JLabel('JLabel Java');
[hJLab,hMLab] = javacomponent(lab, 'North', fig);
hJLab.setOpaque(true);
hJLab.setForeground(java.awt.Color.RED);
hJLab.setBackground(java.awt.Color.YELLOW)
hJLab.setHorizontalAlignment(JLabel.CENTER);



Como puede notar, las propiedades se modifican a través de métodos. Todos estos métodos disponibles para los controles de Java Swing puede consultarlos en la documentación oficial de Java.

Para aprender más...


La referencia obligatoria y necesaria será siempre el blog Undocumented MATLAB del gran Yair Altman, que es sin duda el lugar donde más información online encontraremos sobre la integración MATLAB-Java y muchas otras utilidades no documentadas de MATLAB.

También existe el libro Undocumented Secrets of MATLAB-Java Programming del mismo Yair Altman, muy recomendable.




Sumario del curso


Esta lista de se irá actualizando conforme se publiquen nuevas entradas:

Convirtiendo matrices MATLAB a formato LaTeX

En este post vamos a ver cómo convertir una matriz de MATLAB a un string en formato LaTeX, proponiendo en primera instancia un código muy simple y poco robusto, y posteriormente les compartiré un código desarrollado por Toby Driscoll que puede descargarse desde el File Exchange de MathWorks.

Sabrá que las matrices/arreglos en LaTeX suelen tener la sintaxis:

\begin{matrix}
a & b & c \\
d & e & f \\
g & h & i
\end{matrix}

Así, la idea en principio parece muy básica: recorrer todos los elementos de la matriz MATLAB por filas y columnas e ir formando el string final que se retornará como salida.

Vamos mostrando el código:

function out = matrix2latex(M,fmt)
%
% Argumentos de entrada:
%
% M - Matriz
% fmt - Cadena para especificar el formato ('%0.4f' default)
%
if nargin<2, fmt='%0.4f'; end;
out = ['begin{matrix}',sprintf('\n')];
for ii=1:size(M,1)
for jj=1:size(M,2)
ce = sprintf([fmt,blanks(2),'&',blanks(2)],M(ii,jj));
out = [out,ce]; %#ok
end
out = [out(1:end-3),'\\',sprintf('\n')];
end
out = [out(1:end-3), sprintf('\n\\end{matrix}')];
end

Esta función debe ejecutarse, pasando como argumento la matriz de la cual quiere obtenerse la representación LaTeX.

>> A=rand(3)

A =

0.1067 0.7749 0.0844
0.9619 0.8173 0.3998
0.0046 0.8687 0.2599

>> matrix2latex(A)

ans =

begin{matrix}
0.1067 & 0.7749 & 0.0844 \\
0.9619 & 0.8173 & 0.3998 \\
0.0046 & 0.8687 & 0.2599
\end{matrix}

¿Bastante bien, cierto?, sí, hasta cierto punto, pero es una porción de código sin testear más allá de algunos casos básicos considerados.

Por ello les adjunto enseguida un código compartido por Toby Driscoll en File Exchange el cual contiene al menos sentencias que verifican que los argumentos pasados sean del tipo esperado, y eso es bastante bueno, al menos para empezar.


function s = latex(M,varargin)
%LATEX Print a matrix in LaTeX tabular format.
% LATEX(M) prints out the numeric matrix M in a LaTeX tabular
% format. The '&' character appears between entries in a row, '\\'
% is appended to the ends of rows, and each entry is set in math
% mode. Complex numbers are understood, and exponentials will be
% converted to a suitable format.
%
% LATEX(M,'nomath') does not include the $$ needed to put each
% entry in math mode (e.g., for use with the amsmath matrix modes).
%
% LATEX(M,FMT) uses a format specifier FMT of the SPRINTF type for
% each entry.
%
% LATEX(M,FMT1,FMT2,...) works through the given format specifiers
% on each row of M. If fewer are given than the column size of M,
% the last is used repeatedly for the rest of the row.
%
% S = LATEX(M,...) does not display output but returns a character
% array S.
%
% Examples:
% latex( magic(4) )
% latex( magic(4), '%i', 'nomath' )
% latex( magic(4), '%i', '%.2f' )
%
% See also SPRINTF, SYM/LATEX.

% Copyright 2002 by Toby Driscoll. Last updated 12/06/02.

if ~isa(M,'double')
error('Works only for arrays of numbers.')
elseif ndims(M) > 2
error('Works only for 2D arrays.')
end

if nargin < 2
fmt = {'%#.5g'};
mathstr = '$';
else
fmt = varargin;
idx = strmatch('nomath',fmt);
if isempty(idx)
mathstr = '$';
else
mathstr = '';
fmt = fmt([1:idx-1 idx+1:end]);
if isempty(fmt), fmt = {'%#.5g'}; end
end
end

% Extend the format specifiers.
[m,n] = size(M);
if n > length(fmt)
[fmt{end:n}] = deal(fmt{end});
end

% Create one format for a row.
rowfmt = '';
for p = 1:n
% Remove blanks.
thisfmt = deblank(fmt{p});

% Add on imaginary part if needed.
if ~isreal(M(:,p))
% Use the same format as for the real part, but force a + sign for
% positive numbers.
ifmt = thisfmt;
j = findstr(ifmt,'%');
if ~any(strcmp(ifmt(j+1),['-';'+';' ';'#']))
ifmt = [ifmt(1:j) '+' ifmt(j+1:end)];
else
ifmt(j+1) = '+';
end
ifmt = [ifmt 'i'];
thisfmt = [thisfmt ifmt];
end

% Add to row.
rowfmt = [rowfmt mathstr thisfmt mathstr ' & '];
end

% After last column, remove column separator and put in newline.
rowfmt(end-1:end) = [];
rowfmt = [rowfmt '\\\\\n'];

% Use it.
A = M.';
if isreal(M)
S = sprintf(rowfmt,A);
else
S = sprintf(rowfmt,[real(A(:)) imag(A(:))].');
end

% Remove extraneous imaginary part for real entries.
if ~isreal(M)
zi = sprintf(ifmt,0);
S = strrep(S,zi,blanks(length(zi)));
end

% Remove NaNs.
S = strrep(S,'$NaN$','--');
S = strrep(S,'NaN','--');

% Convert 'e' exponents to LaTeX form. This is probably really slow, but
% what can you do without regular expressions?
S = strrep(S,'e','E');
ex = min(findstr(S,'E'));
while ~isempty(ex)
% Find first non-digit character. Where is ISDIGIT?
j = ex+2;
while ~isempty(str2num(S(j))) & ~strcmp(S(j),'i')
j = j+1;
end

% This strips off leading '+' and zeros.
num = sprintf('%i',str2num(S(ex+1:j-1)));

ee = ['\times 10^{' num '}'];
S = [S(1:ex-1) ee S(j:end)];

ex = ex + min(findstr(S(ex+1:end),'E'));
end

% For good form, remove that last '\\'.
S(end-2:end-1) = ' ';

% Display or output?
if nargout==0
disp(S)
else
s = S;
end

La ejecución de la función anterior es prácticamente similar a nuestra función propuesta:

>> A=rand(3)

A =

0.5499 0.6221 0.4018
0.1450 0.3510 0.0760
0.8530 0.5132 0.2399

>> latex(A)
$0.54986$ & $0.62206$ & $0.40181$ \\
$0.14495$ & $0.35095$ & $0.075967$ \\
$0.85303$ & $0.51325$ & $0.23992$

La salida, un tanto similar, si, cosas más cosas menos, pero la idea central es la misma.

Y bueno, en el siguiente link podrá encontrar más funciones similares que exportan cosas de MATLAB a código LaTeX, lo cual nunca está de más.

http://www.mathworks.com/matlabcentral/fileexchange/?term=latex&sort=ratings_desc

Métodos estáticos en una clase MATLAB

Los métodos estáticos son aquellos que pueden ser ejecutados sin necesidad de crear una instancia de la clase. En MATLAB pueden utilizarse para agrupar funciones dentro de una misma clase que haga las veces de una librería de funciones.

En la definición de una clase MATLAB se pueden crear diversos bloques de metodos (methods) o propiedades (properties), con diferentes configuraciones, por ejemplo, se puede definir un bloque de métodos ordinarios y otro bloque de métodos estáticos. Un bloque de métodos estáticos se indica colocando el modificador (Static=true) como sigue:

classdef Clase

properties
% Propiedades de clase
end

methods
% Métodos ordinarios
end

methods (Static=true)
% Métodos estáticos
end
end

Para ejemplificar cómo funcionan los métodos estáticos vamos a crear una clase Math que contendrá los métodos estáticos minimo y maximo, que calcularán el valor mínimo y máximo de dos valores pasados como argumento. A continuación se coloca el contenido del fichero de la clase Math que hemos creado:

classdef Math

properties (Constant=true)
PI = pi; % Constante "pi"
E = exp(1); % Constante "e"
end

methods (Static=true)
function m = maximo(a,b)
% Determina el máximo de dos valores
if a>b
m = a;
else
m = b;
end
end

function m = minimo(a,b)
% Determina el mínimo de dos valores
if a<b
m = a;
else
m = b;
end
end
end
end

Podemos entonces llamar a los métodos maximo y minimo sin necesidad de crear una instancia:

>> Math.minimo(10,20)
ans =
10
>> Math.maximo(10,20)
ans =
20

Utilizando clases de la librería estándar de Java en MATLAB

MATLAB tiene una facilidad inherente para la integración simple de código Java en un script ordinario. Es posible instanciar objetos de una clase Java de la librería estándar o de terceros, y utilizarlas dentro del espacio de trabajo.

Lo anterior puede resultar muy útil en casos donde ciertas características del lenguaje Java no implementadas nativamente en MATLAB sean requeridas. En este caso vamos a ver cómo importar, instanciar y utilizar algunas clases y sus métodos de la librería estándar de Java.

Lo primero que debemos hacer para utilizar una clase Java es importar esta en nuestro espacio de trabajo, por ejemplo, si queremos utilizar las clases de la librería lang de Java:

>> import java.lang.*;

Ahora instanciaremos un objeto de la clase String de Java:

>> cadena=String('Hola Java')
cadena =
Hola Java

Podemos verificar la clase del objeto cadena utilizando la función class de MATLAB.

>> class(cadena)
ans =
java.lang.String

O directamente utilizando el método getClass:

>> cadena.getClass()
ans =
class java.lang.String

De la misma forma podemos utilizar algunos de los métodos disponibles para este objeto:

>> cadena.length() % Longitud de la cadena
ans =
9
>> cadena.replace('a','o') % Remplazando caracteres
ans =
Holo Jovo
>> cadena.toUpperCase() % Todas mayúsculas
ans =
HOLA JAVA
>> cadena.concat(' y MATLAB') % Concatenando caracteres al final
ans =
Hola Java y MATLAB

Es posible instanciar un objeto Java sin necesidad de importar las librerías, en cambio es necesario indicar el nombre/ruta completo de la clase:

>> cad=java.lang.String('Hola!!!')
cad =
Hola!!!

Bueno, pero, ¿no tiene MATLAB un tipo de dato String nativo que hace lo mismo? o ¿para qué nos servirá entonces utilizar objetos Java?.

Si, MATLAB tiene un tipo char equivalente al String de MATLAB, pero existen algunos estructuras de datos como las Hashtables que no tienen un equivalente en MATLAB, y es ahí donde podríamos aprovechar algunas versatilidades proporcionadas por Java.

¿Y qué es una Hashtable?, en resumen, es un estructura que permite almacenar variables mediante las características clave-valor (como un diccionario en Python, por si vienen de Python). Por ejemplo:

>> import java.util.*; % Importamos las clases de java.util
>> ht=Hashtable(); % Instanciamos un objeto de la clase Hashtable
>> ht.put('A',10); % Agregamos un clave-valor
>> ht.put('B',15); % Agregamos un clave-valor
>> ht.put('C',5); % Agregamos un clave-valor
>> ht
ht =
{A=10.0, C=5.0, B=15.0}
>> class(ht)
ans =
java.util.Hashtable

Ahora podemos acceder al valor guardado en un determinado campo de la Hashtable:

>> ht.get('B')  % Tomando el valor de la clave B
ans =
15

Y bueno, hasta aquí un poco de este tema sobre cómo utilizar clases de la librería estándar de Java en MATLAB. En entradas posteriores veremos cómo añadir controles gráficos de la librería Swing en una GUI MATLAB.