bug 7566 fix: The cacsd module graphic functions (bode, black, nyquist,...)
[scilab.git] / scilab / modules / cacsd / macros / bode.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C)  1985-2010 - INRIA - Serge Steer
3 // This file must be used under the terms of the CeCILL.
4 // This source file is licensed as described in the file COPYING, which
5 // you should have received as part of this distribution.  The terms
6 // are also available at
7 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
8
9 function []=bode(varargin)
10   rhs=size(varargin)
11   if type(varargin($))==10 then
12     comments=varargin($),rhs=rhs-1;
13   else
14     comments=[];
15   end
16   fname="bode";//for error messages
17   fmax=[]
18   discr=%f //for shannon limit
19   if or(typeof(varargin(1))==["state-space" "rational"]) then
20     //sys,fmin,fmax [,pas] or sys,frq
21     refdim=1 //for error message
22     discr=varargin(1).dt<>'c';
23     if rhs==1 then //sys
24       [frq,repf]=repfreq(varargin(1),1d-3,1d3)
25     elseif rhs==2 then //sys,frq
26       if size(varargin(2),2)<2 then
27         error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"),..
28                        fname,2,1))
29       end
30       [frq,repf]=repfreq(varargin(1:rhs))
31     elseif or(rhs==(3:4)) then //sys,fmin,fmax [,pas]
32       [frq,repf]=repfreq(varargin(1:rhs))
33     else
34       error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),fname,1,5))
35     end
36     [phi,d]=phasemag(repf)
37     if rhs>=3 then fmax=varargin(3),end
38   elseif  type(varargin(1))==1 then
39     //frq,db,phi [,comments] or frq, repf [,comments]
40     refdim=2
41     select rhs
42     case 2 then //frq,repf
43       frq=varargin(1);
44       if size(frq,2)<2 then
45         error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"),..
46                        fname,1,1))
47       end
48       if size(frq,2)<>size(varargin(2),2) then
49         error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),..
50                        fname,1,2))
51       end
52       [phi,d]=phasemag(varargin(2))
53     case 3 then  //frq,db,phi
54       [frq,d,phi]=varargin(1:rhs)
55       if size(frq,2)<>size(d,2) then
56         error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),..
57                        fname,1,2))
58       end
59       if size(frq,2)<>size(phi,2) then
60         error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),..
61                        fname,1,3))
62       end
63     else
64       error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),fname,2,4))
65     end
66   else
67     error(msprintf(_("%s: Wrong type for input argument #%d: Linear dynamical system or row vector of floats expected.\n"),fname,1))
68   end;
69   frq=frq';d=d',phi=phi'
70   [n,mn]=size(d)
71
72   if comments==[] then
73     hx=0.48
74   else
75     if size(comments,"*")<>mn then
76       error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same number of elements expected.\n"),...
77                      fname,refdim,rhs+1))
78     end
79     hx=0.43
80   end;
81
82   fig=gcf();
83   immediate_drawing=fig.immediate_drawing;
84   fig.immediate_drawing="off";
85
86   sciCurAxes=gca();
87   axes=sciCurAxes;
88   wrect=axes.axes_bounds;
89
90
91   //magnitude
92   axes.axes_bounds=[wrect(1)+0,wrect(2)+0,wrect(3)*1.0,wrect(4)*hx*0.95]
93   axes.data_bounds = [min(frq),min(d);max(frq),max(d)];
94   axes.log_flags = "lnn" ;
95   axes.grid=color("lightgrey")*ones(1,3);
96   axes.axes_visible="on";
97   axes.clip_state = "clipgrf";
98   if size(d,2)>1&size(frq,2)==1 then
99     xpolys(frq(:,ones(1,mn)),d,1:mn)
100   else
101     xpolys(frq,d,1:mn)
102   end
103   //set datatips info
104   e=gce();
105
106   for i=1:size(e.children,"*")
107     datatipInitStruct(e.children(i),"formatfunction","formatBodeMagTip")
108   end
109
110   if discr&fmax<>[]&max(frq)<fmax then
111     xpoly(max(frq)*[1;1],axes.y_ticks.locations([1 $]));e=gce();
112     e.foreground=5;
113   end
114   xtitle("",_("Frequency (Hz)"),_("Magnitude (dB)"));
115
116   //phase
117
118   axes=newaxes();
119   axes.axes_bounds=[wrect(1)+0,wrect(2)+wrect(4)*hx,wrect(3)*1.0,wrect(4)*hx*0.95];
120   axes.data_bounds = [min(frq),min(phi);max(frq),max(phi)];
121   axes.log_flags = "lnn" ;
122   axes.grid=color("lightgrey")*ones(1,3);
123   axes.axes_visible="on";
124   axes.clip_state = "clipgrf";
125   if size(phi,2)>1&size(frq,2)==1 then
126     xpolys(frq(:,ones(1,mn)),phi,1:mn)
127   else
128     xpolys(frq,phi,1:mn)
129   end
130   ephi=gce()
131   //set datatips info
132   for i=1:size(ephi.children,"*")
133     datatipInitStruct(ephi.children(i),"formatfunction","formatBodePhaseTip")
134   end
135
136   if discr&fmax<>[]&max(frq)<fmax then
137     xpoly(max(frq)*[1;1],axes.y_ticks.locations([1 $]));e=gce();
138     e.foreground=5;
139   end
140   xtitle("",_("Frequency (Hz)"),_("Phase (degree)"));
141   // create legend
142   if comments<>[] then
143     c=captions(ephi.children,comments,"lower_caption")
144     c.background=get(gcf(),"background")
145   end
146   fig.immediate_drawing=immediate_drawing;
147   // return to the previous scale
148   set( "current_axes", sciCurAxes ) ;
149
150 endfunction
151
152 function str=formatBodeMagTip(curve,pt,index)
153 //this function is called by the datatips mechanism to format the tip
154 //string for the magnitude bode curves
155   str=msprintf("%.4g"+_("Hz")+"\n%.4g"+_("dB"), pt(1),pt(2))
156 endfunction
157
158 function str=formatBodePhaseTip(curve,pt,index)
159 //this function is called by the datatip mechanism to format the tip
160 //string for the bode phase curves
161   str=msprintf("%.4g"+_("Hz")+"\n %.4g"+_("dB"), pt(1),pt(2))
162 endfunction