Post Reply 
I try to make an App...
02-11-2015, 09:46 PM (This post was last modified: 02-11-2015 09:52 PM by dg1969.)
Post: #1
I try to make an App...
Hello,

I try to make an small APP derived from FUNCTION APP to plot Bode module and phase or temporal impulse response... It need a lot of improvements but it do the job very basically.

Place your transfert function (in term of X) in symb view then press plot. Choose "module" or "phase" or "temporal"... You need to fix setup plot to fit the curve manually... My best wishes is to find some help to improve the phase function to automatically plot it in the -inf ; +inf domain (without the -pi ; +pi discontinuity)

Be careful ! there are pieces of french in the soup...

Code:

copie_les_fonctions();
replace_les_fonctions();
place_les_modules();
place_les_phases();
place_les_rep_temp();
calcule_modules();
calcule_phases();
calcule_rep_temp();
Symb();

export liste_fonctions:={};
export liste_modules:={};
export liste_phases:={};
export liste_rep_temp:={};
recalcule:={0,0,0};

export copie_les_fonctions()
begin
  local k;
  for k from 1 to 10 do
    if ISCHECK(k MOD 10) then
      IFERR liste_fonctions(k):=EXPR("F"+k MOD 10) then end;
    end;
  end;
end;

export replace_les_fonctions()
begin
  local k;
  for k from 1 to length(liste_fonctions) do
    if ISCHECK(k MOD 10) then  
      expr("F"+k MOD 10+":=liste_fonctions("+k+")");
    end;
  end;
end;

export place_les_modules()
begin
  local k;
  for k from 1 to length(liste_modules) do
     if ISCHECK(k MOD 10) then 
       expr("F"+k MOD 10+":=liste_modules("+k+")");
     end;
  end;
end;

export place_les_phases()
begin
  local k;
  for k from 1 to length(liste_phases) do
     if ISCHECK(k MOD 10) then
       expr("F"+k MOD 10+":=liste_phases("+k+")");
     end;
  end;
end;

export place_les_rep_temp()
begin
  local k;
  for k from 1 to length(liste_rep_temp) do
     if ISCHECK(k MOD 10) then
       expr("F"+k MOD 10+":=liste_rep_temp("+k+")");
     end;
  end;
end;

export calcule_modules()
begin
  local k;
    for k from 1 to length(liste_fonctions) do
       if ISCHECK(k MOD 10) then
         liste_modules(k):=20*LOG(ABS(subst(liste_fonctions(k),'X','i*ALOG(X)')));
       end;
    end;
  recalcule(1):=0;
end;

export calcule_phases()
begin
   local k;
    for k from 1 to length(liste_fonctions) do
       if ISCHECK(k MOD 10) then
         liste_phases(k):=ARG(subst(liste_fonctions(k),'X','i*ALOG(X)'));
       end;
    end;
  recalcule(2):=0;
end;

export calcule_rep_temp()
begin
   local f, k;
     for k from 1 to length(liste_fonctions) do
        if ISCHECK(k MOD 10) then
          f:="F"+k MOD 10+"(x),x,x";
          f:="'("+REPLACE(STRING(CAS.ilaplace(f)),"x","X")+")*PIECEWISE(X<0,0,X≥0,1)'";
          IF instring(f,"ilaplace") 
            THEN MSGBOX("Problème avec F"+k MOD 10); KILL;
            ELSE liste_rep_temp(k):=EXPR(f);
          END;
        end;
     end;
  recalcule(3):=0;
end;


Symb()
begin
  recalcule:={1,1,1};
  replace_les_fonctions;
  STARTVIEW(0,1);
end;

Plot()
begin
  local choix:=1;
  if ΠLIST(recalcule) then copie_les_fonctions;
  end;
  CHOOSE(choix,"Choisissez un type de tracé",{"Module","phase","réponse temporelle"});
  CASE
   IF choix==1 THEN if recalcule(1) then calcule_modules end; place_les_modules END;
   IF choix==2 THEN if recalcule(2) then calcule_phases end; place_les_phases END;
   IF choix==3 THEN if recalcule(3) then calcule_rep_temp end; place_les_rep_temp END;
   //DEFAULT
  END;
  STARTVIEW(1,1);
end;
Find all posts by this user
Quote this message in a reply
02-12-2015, 09:35 PM (This post was last modified: 02-14-2015 08:40 PM by dg1969.)
Post: #2
RE: I try to make an App...
EDIT :I change the code of the "calcule_rep_temp()" function...

Hi,

I tried to improve the code... Now the time response is a step response... Comments and criticism are welcome ...

I forgot an important comment... transfer functions must be write without float numbers. F1(X)=1/(1+0.2*X) doesn't works... but F1(X)=1/(1+1/2*X)^2 is ok...

Code:

copie_les_fonctions();
replace_les_fonctions();
place_les_modules();
place_les_phases();
place_les_rep_temp();
calcule_modules();
calcule_phases();
calcule_rep_temp();
Symb();

export liste_fonctions:=MAKELIST(0,X,1,10);
export liste_modules:={};
export liste_phases:={};
export liste_rep_temp:={};
recalc_module:=MAKELIST(1,X,1,10);
recalc_phase:=MAKELIST(1,X,1,10);
recalc_temp:=MAKELIST(1,X,1,10);
modif:=0;

export copie_les_fonctions()
begin
  local k;
  for k from 1 to 10 do
    if ISCHECK(k MOD 10) then
      if EVAL(EXPR("F"+k MOD 10)≠liste_fonctions(k)) then
        IFERR liste_fonctions(k):=EXPR("F"+k MOD 10) then MSGBOX("Erreur de copie sur F"+k MOD 10) end;
        recalc_module(k):=1;
        recalc_phase(k):=1;
        recalc_temp(k):=1; 
      end; 
    end;
  end;
  modif:=0;
end;

export replace_les_fonctions()
begin
  local k;
  for k from 1 to length(liste_fonctions) do
    if ISCHECK(k MOD 10) then  
      expr("F"+k MOD 10+":=liste_fonctions("+k+")");
    end;
  end;
end;

export place_les_modules()
begin
  local k;
  for k from 1 to length(liste_modules) do
     if ISCHECK(k MOD 10) then 
       expr("F"+k MOD 10+":=liste_modules("+k+")");
     end;
  end;
end;

export place_les_phases()
begin
  local k;
  for k from 1 to length(liste_phases) do
     if ISCHECK(k MOD 10) then
       expr("F"+k MOD 10+":=liste_phases("+k+")");
     end;
  end;
end;

export place_les_rep_temp()
begin
  local k;
  for k from 1 to length(liste_rep_temp) do
     if ISCHECK(k MOD 10) then
       expr("F"+k MOD 10+":=liste_rep_temp("+k+")");
     end;
  end;
end;

export calcule_modules()
begin
  local k;
    for k from 1 to length(liste_fonctions) do
       if ISCHECK(k MOD 10) AND recalc_module(k) then
         liste_modules(k):=20*LOG(ABS(subst(liste_fonctions(k),'X','i*ALOG(X)')));
         recalc_module(k):=0; 
       end;
    end;
end;

export calcule_phases()
begin
   local k;
    for k from 1 to length(liste_fonctions) do
       if ISCHECK(k MOD 10) AND recalc_phase(k) then
         liste_phases(k):=ARG(subst(liste_fonctions(k),'X','i*ALOG(X)'));
         recalc_phase(k):=0;
       end;
    end;
end;

export calcule_rep_temp()
begin
   local f, k;
     for k from 1 to length(liste_fonctions) do
        if ISCHECK(k MOD 10) AND recalc_temp(k) then
          f:=REPLACE(STRING(liste_fonctions(k)),"X","x");
          f:=f+"*1/x,x,x";
          f:="'("+REPLACE(STRING(CAS.ilaplace(f)),"x","X")+")*PIECEWISE(X<0,0,X≥0,1)'";
          IF instring(f,"ilaplace") 
            THEN MSGBOX("Problème avec F"+k MOD 10); CONTINUE;
            ELSE liste_rep_temp(k):=EXPR(f);
          END;
          recalc_temp(k):=0;
        end;
     end;
end;


Symb()
begin
  modif:=1;
  replace_les_fonctions;
  STARTVIEW(0,1);
end;

Plot()
begin
  local choix;
  if modif then copie_les_fonctions end;
  CHOOSE(choix,"Choisissez un type de tracé",{"Module","phase","réponse indicielle"});
  CASE
   IF choix==1 THEN calcule_modules; place_les_modules END;
   IF choix==2 THEN calcule_phases; place_les_phases END;
   IF choix==3 THEN calcule_rep_temp; place_les_rep_temp; Xmin:=−0.2 END;
   //DEFAULT
  END;
  STARTVIEW(1,1);
end;


Attached File(s) Thumbnail(s)
           
Find all posts by this user
Quote this message in a reply
02-16-2015, 10:32 PM (This post was last modified: 02-16-2015 10:36 PM by dg1969.)
Post: #3
RE: I try to make an App...
In this last version I change the phase calc function... phase plot is done now without discontinuity.

In SYMB view you can place 1 to 10 transfer functions in term of 'X', example:
Code:

F1(X)=(1+2*X)/(1+2*X+1/10*X^2)^2*e^(-2*X)

Actually the exponential term must be at the end of the expression (see the example above) not very powerfull but it do the job to model a pure delay.

No float numbers ! only integers !

Then press PLOT to choose step response , Bode module or Bode phase (x axis is in term of LOG10(pulsation)) . There is no automatic scale. You have to escape from plot view (pressing num or symb again) if you want to choose another plot...


If you find some time I would like to learn and improve my practice through constructive criticism ... Thanks ;o)

Code:

copie_les_fonctions();
replace_les_fonctions();
place_les_modules();
place_les_phases();
place_les_rep_temp();
calcule_modules();
calcule_phases();
calcule_rep_temp();
Symb();

export liste_fonctions:=MAKELIST(0,X,1,10);
export liste_modules:={};
export liste_phases:={};
export liste_rep_temp:={};
recalc_module:=MAKELIST(1,X,1,10);
recalc_phase:=MAKELIST(1,X,1,10);
recalc_temp:=MAKELIST(1,X,1,10);
modif:=0;

export copie_les_fonctions()
begin
  local k;
  for k from 1 to 10 do
    if ISCHECK(k MOD 10) then
      if EVAL(EXPR("F"+k MOD 10)≠liste_fonctions(k)) then
        IFERR liste_fonctions(k):=EXPR("F"+k MOD 10) then MSGBOX("Erreur de copie sur F"+k MOD 10) end;
        recalc_module(k):=1;
        recalc_phase(k):=1;
        recalc_temp(k):=1; 
      end; 
    end;
  end;
  modif:=0;
end;

export replace_les_fonctions()
begin
  local k;
  for k from 1 to length(liste_fonctions) do
    if ISCHECK(k MOD 10) then  
      expr("F"+k MOD 10+":=liste_fonctions("+k+")");
    end;
  end;
end;

export place_les_modules()
begin
  local k;
  for k from 1 to length(liste_modules) do
     if ISCHECK(k MOD 10) then 
       expr("F"+k MOD 10+":=liste_modules("+k+")");
     end;
  end;
end;

export place_les_phases()
begin
  local k;
  for k from 1 to length(liste_phases) do
     if ISCHECK(k MOD 10) then
       expr("F"+k MOD 10+":=liste_phases("+k+")");
     end;
  end;
end;

export place_les_rep_temp()
begin
  local k;
  for k from 1 to length(liste_rep_temp) do
     if ISCHECK(k MOD 10) then
       expr("F"+k MOD 10+":=liste_rep_temp("+k+")");
     end;
  end;
end;

export calcule_modules()
begin
  local k;
    for k from 1 to length(liste_fonctions) do
       if ISCHECK(k MOD 10) AND recalc_module(k) then
         liste_modules(k):=20*LOG(ABS(subst(liste_fonctions(k),'X','i*ALOG(X)')));
         recalc_module(k):=0; 
       end;
    end;
end;

export calcule_phases()
BEGIN
local k,j,r,retard;
local f, a,num,denomi,cnum,cdenom,phi;
  for k from 1 to length(liste_fonctions) do
     if ISCHECK(k MOD 10) AND recalc_phase(k) then
       f:=replace(string(liste_fonctions(k)),"X","x");
       r:=instring(f,"e");
       if r then
                retard:=right(f,size(f)-1-r);
                f:=left(f,r-2);
       end;       
       a:=CAS.froot(f,"x");
       num:=string(CAS.numer(f));
       denomi:=string(CAS.denom(f));
       cnum:=CAS.lcoeff(num,"x");
       cdenom:=CAS.lcoeff(denomi,"x");
       phi:=string(ARG(cnum/cdenom)); 
       FOR j FROM 1 TO length(a) STEP 2 DO
           IF RE(a(j))<>0 THEN 
                phi:=phi+"+"+a(j+1)+"*ATAN(("+IM(a(j))+"-X)/("+RE(a(j))+"))";
           END; //fin IF
       END; //fin FOR j
     if r then phi:=phi+"+"+replace(retard,"x","X") end;
     phi:="'"+replace(phi,"X","ALOG(X)")+"'";
    liste_phases(k):=EXPR(phi);
    recalc_phase(k):=0;
   end; //fin if ischek
 end; //fin for k

END;


export calcule_rep_temp()
begin
   local f, k;
     for k from 1 to length(liste_fonctions) do
        if ISCHECK(k MOD 10) AND recalc_temp(k) then
          f:=REPLACE(STRING(liste_fonctions(k)),"X","x");
          f:=f+"*1/x,x,x";
          f:="'("+REPLACE(STRING(CAS.ilaplace(f)),"x","X")+")*PIECEWISE(X<0,0,X≥0,1)'";
          IF instring(f,"ilaplace") 
            THEN MSGBOX("Problème avec F"+k MOD 10); CONTINUE;
            ELSE liste_rep_temp(k):=EXPR(f);
          END;
          recalc_temp(k):=0;
        end;
     end;
end;


Symb()
begin
  modif:=1;
  replace_les_fonctions;
  STARTVIEW(0,1);
end;

Plot()
begin
  local choix;
  if modif then copie_les_fonctions end;
  CHOOSE(choix,"Choisissez un type de tracé",{"Module","phase","réponse indicielle"});
  CASE
   IF choix==1 THEN calcule_modules; place_les_modules END;
   IF choix==2 THEN calcule_phases; place_les_phases END;
   IF choix==3 THEN calcule_rep_temp; place_les_rep_temp; Xmin:=−0.2 END;
   //DEFAULT
  END;
  STARTVIEW(1,1);
end;
Find all posts by this user
Quote this message in a reply
02-18-2015, 07:08 AM
Post: #4
RE: I try to make an App...
Nice work!
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: