Creando Pseudo-Objetos con tlist

En primer lugar voy a crear un  Pseudo-Objeto Escalar, utilizando el comando tlist (lo voy a llamar TEscalar): 
nombrevariable = tlist(["TEscalar", "Valor", "Unid", "Alias"])
Los strings que componen el tlist, intentan ser descriptivos:
  • El primer string "TEscalar" es el nombre que le he dado a este objeto. 
  • En "Valor" se archivará el valor numérico del escalar
  • En "Unid" un string con sus unidades; o un un array de strings de 2x1; el primero de ellos será el prefijo (basado en el sistema internacional) y el segundo string la unidad del escalar
  • En "Alias" se puede almacenar un string con un nombre descriptivo del escalar 
Para hacerlo más robusto he preparado una función (como si fuera un constructor de clase) para crear estos TEscalares, el código es:
function this = escalar_new(varargin)   // v1.2  Quitar UdPref de la entrada de datos
    // Crea un pseudo-objeto TEscalar
    // type(TEscalar)= 16; typeof(TEscalar)= "TEscalar";
    [lhs ,rhs ]=argn()
    if rhs==0 then
        mprintf(" TEscalar = escalar_new(Valor,Unid,Alias,UdPref) \n")
        mprintf("    Valor : cantidad numérica \n");
        mprintf("    Unid : string con la unidad a utilizar en la presentación; \n");
        mprintf("           si es un array 1x2 de strings, p.e.: [""μ"" ""m""], el \n");
        mprintf("           prefijo recalcula la magnitud, p.e.: μ divide por 10⁶ ;\n");
        mprintf("           (el string o el array 1x2 es guardado en UdPref) \n");
        mprintf("    Alias : string para ponerle un nombre o alias \n\n");
        // UdPref no hace necesario introducirlo, se toma Unid como UdPref (para no cambiar más funciones)
        // mprintf("    UdPref : unidades de presentación utilizadas por string() \n\n");  // v1.2
        errmsg = msprintf(" La función escalar_new, necesita al menos el primer argumento")
        error ( errmsg );
    end   // if rhs==0
    //
// idea1 guardar matriz unidades, para presentarlo luego en unidades preferidas (indicadas al crearlo)
    this = tlist(["TEscalar", "Valor", "Unid", "Alias","UdPref"]);
    //
    if rhs>=1 then  // .Valor
        if type(varargin(1))==1 then
             // mprintf(" Sólo entra valor, sin unidad \n")
            this.Valor=varargin(1); 
        else // if type(varargin(1))
            // podía implementar polynom  // pendiente
            errmsg = msprintf (" escalar_new esperaba un número como argumento : %s",typeof(varargin(1)));
            error ( errmsg )
        end // if type(varargin(1))
    end // if rhs>=1 
    //
    if rhs>=2 then  // .Unid
        //idea1
        this.UdPref=varargin(2);
        if typeof(varargin(2))=="string" then
            if size(varargin(2))==[1 1] then  // sólo unidad
                this.Valor=varargin(1);
                this.Unid=varargin(2);
                this.UdPref=varargin(2); // v1.2
            elseif size(varargin(2))==[1 2] then // prefijo y unidad 
                fdE=pfSI(varargin(2)(1));
                this.Valor=varargin(1)*fdE;
                this.Unid=varargin(2)(2);
                this.UdPref=varargin(2); // v1.2
            else // if size(varargin(2)) // tamaño inesperado
                errmsg = msprintf (" escalar_new : esperaba un string 1x1 ó 1x2 : %s",size(varargin(2)));
                error ( errmsg )
            end // if size(varargin(2))
        else // if typeof(varargin(2))
            errmsg = msprintf (" escalar_new : esperaba un string 1x1 ó 1x2 : %s",typeof(varargin(2)) );
            error ( errmsg )
        end // if typeof(varargin(2))
    else // if rhs>=2 
        this.Unid=""; this.UdPref="";
    end // if rhs>=2 
    
    if rhs>=3 then  // .Alias
        //idea1
        if (rhs==3)&(typeof(varargin(3)))=="string" then
            this.Alias=varargin(3);
        else // if (rhs==3)&(typeof(varargin(3)))
            this.Alias=string(varargin(3));
        end // if (rhs==3)&(typeof(varargin(3)))
    else // if rhs>=3 
        this.Alias=""; // this.Alias="";
    end // if rhs>=3 
endfunction  // function this = escalar_new(varargin)

El código intenta ser auto descriptivo, y contiene una comprobación de errores interna.
Hago uso de una función propia pfSI (que proporciona unos factores de escala en función del prefijo del sistema internacional utilizado en las unidades), cuyo código es:
function [d]=pfSI(pfSU)
  // uso en printUD("Titulo",Variable/pfSI(u),"uUD",,,)
  if ~exists("pfSU") then  pfSU = ""; end
  if pfSU=="" then d=1;
  elseif pfSU=="a" then d=1e-18;  // ato
  elseif pfSU=="f" then d=1e-15;  // femto
  elseif pfSU=="p" then d=1e-12;  // pico
  elseif pfSU=="n" then d=1e-9;   // nano
  elseif (pfSU=="u")|(pfSU=="μ")|(pfSU=="µ") then d=1e-6;  // micro
  elseif pfSU=="m" then d=1e-3;  // mili
  elseif pfSU=="c" then d=1e-2;  // centi
  elseif pfSU=="d" then d=1e-1;  // deci
  elseif pfSU=="da" then d=10;  // deca
  elseif pfSU=="h" then d=100;  // hecto
  elseif pfSU=="k" then d=1e3;  // kilo
  elseif pfSU=="M" then d=1e6;  // mega
  elseif pfSU=="G" then d=1e9;  // giga
  elseif pfSU=="T" then d=1e12; // tera
  elseif pfSU=="P" then d=1e15; // peta
  elseif pfSU=="E" then d=1e18; // exa
  else
      mprintf("¡¡ Opción no implementada !! \( función prefSU \) \n")
  end
endfunction //function [d]=pfSI(pfSU)

Si creamos un objeto escalar, por ejemplo:

ε0=escalar_new(8.854187817,["p" "F/m"],"Permitividad del espacio libre : ε0");

Y comprobamos su valor, introduciendo en la consola ε0, obtendríamos

  ε0 = (TEscalar tlist) with fields:

  Valor = 8.854D-12
  Unid = "F/m"
  Alias = "Permitividad del espacio libre : ε0"
  UdPref = ["p","F/m"]

Donde se pueden ver todos los campos, que contiene el objeto TEscalar, pero no es la presentación que yo deseaba para mis Pseudo-Objetos TEscalar; por lo cual cree dos funciones más, la primera:
function str=%TEscalar_string(this)      // v1.1
    //Modificado para incluir idea 1 presentar en unidades preferidas (indicadas al crearlo)
    if this.Unid=="" then   //    if ~exists(this.UdPref(2)) then // esto no sirve
    // if ~exists(this.Unid) then  // esto tampoco
       pUnid=""; fdE=1  //
    elseif (type(this.UdPref))==10&(size(this.UdPref)(2)==1) then
       if (this.UdPref=="º")|(this.UdPref=="°") then
          pUnid=this.UdPref; fdE=1;
       else
          pUnid=" "+this.UdPref; fdE=1; 
       end
    elseif (type(this.UdPref))==10&(size(this.UdPref)(2)==2) then
       pUnid=" "+strcat(this.UdPref); fdE=pfSI(this.UdPref(1)); // mprintf(" prefijo y unidad \n");
    else //~exists("Unid") or tipos definidos
       errmsg = msprintf (" %TEscalar_string: no admite el parámetro introducido en Unid : %s",this.UdPref); 
       error ( errmsg )
    end //~exists("Unid")
    ValorEscalado=this.Valor/fdE; 
    // crea string de TEscalar
    if isreal(this.Valor) then
       str=" "+this.Alias+" = "+string(ValorEscalado)+pUnid;
    else  // número complejo
       pReal=real(ValorEscalado);pImag=imag(ValorEscalado);apImag=abs(pImag);
       if pImag<0 then txta=" - j "; else txta=" + j "; end
       str=" "+this.Alias+" = "+string(pReal)+txta+string(apImag)+" "+pUnid;
    end
endfunction // function str=%TEscalar_string(this)      // v1.1
Esta función proporciona un string (con el formato que yo deseo) de los objetos (voy a dejar de escribir pseudo) TEscalar, y es llamada por funciones que manipulen strings. 

En concreto si modificamos la función que presenta los objetos de Scilab en pantalla.
function %TEscalar_p(this)
    // presenta en pantalla el string de TEscalar
    mprintf(string(this));
endfunction
Ya se aprecia el multimorfismo que nos permite Scilab, la función _p se puede definir para diferentes tipos de objetos (en otros posts presentaré las funciones para TPuntos y TVectores).
Si ahora consultamos del valor de ε0, en la consola obtendremos:
--> ε0

 ε0 = (TEscalar tlist) with fields:

 Permitividad del espacio libre : ε0 = 8.8541878 pF/m

Obteniendo la presentación que deseaba.

En el siguiente post, desarrollaré operaciones con los TEscalares, aprovechando el multimorfismo que permite Scilab.

Postdata

Un escalar sólo tiene una magnitud o valor numérico.
Observación de Blogger: al introducir el código he tenido que cambiar el > por &gt; y < por &lt; sino Blogger lo mal interpretaba y cortaba el contenido.




Comentarios

Entradas populares de este blog

Cálculo Vectorial en Scilab 1

Cálculo simbólico con polinomios