]> Creatis software - CreaPhase.git/blob - octave_packages/ocs-0.1.3/prs/prs_iff.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / ocs-0.1.3 / prs / prs_iff.m
1 ## Copyright (C) 2006,2007,2008  Carlo de Falco            
2 ##
3 ## This file is part of:
4 ## OCS - A Circuit Simulator for Octave
5 ##
6 ## OCS is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation.
9 ##
10 ## This program is distributed in the hope that it will be useful,
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 ## GNU General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with OCS; If not, see <http://www.gnu.org/licenses/>.
17 ##
18 ## author: Carlo de Falco     <cdf _AT_ users.sourceforge.net> 
19 ## author: Massimiliano Culpo <culpo _AT_ users.sourceforge.net>
20
21 ## -*- texinfo -*-
22 ## @deftypefn{Function File} @var{outstruct} = prs_iff(@var{name})
23 ## Parse a netlist in IFF format and produce the system description
24 ## structure @var{outstruct}.
25 ##
26 ## @var{name} is the basename of the CIR and NMS files to
27 ## be parsed.
28 ##
29 ## See the @cite{IFF file format specifications} (distributed together
30 ## with the OCS package) for more details on the file format.
31 ##
32 ## @var{outstruct} has the following fields:
33 ##
34 ## @example
35 ## outstruct =
36 ## @{
37 ##  LCR:  struct      % the fields of LCR are shown below
38 ##  NLC:  struct      % NLC has the same fields as LCR
39 ##  namesn: matrix    % numbers of vars named in .nms file
40 ##  namess: cell      % the names corresponding to the vars above
41 ##  totextvar: scalar % the total number of external variables
42 ##  totintvar: scalar % the total number of internal variables
43 ## @}
44 ##
45 ## outstruct.LCR =
46 ## outstruct.NLC =
47 ## @{
48 ##  struct array containing the fields: % array has one element per block
49 ##
50 ##    func     % name of the sbn file corresponding to each block
51 ##    section  % string parameter to be passed to the sbn files
52 ##    nextvar  % number of external variables for each element of the block
53 ##    vnmatrix % numbers of the external variables of each element
54 ##    nintvar  % number of internal variables for each element of the block
55 ##    osintvar % number of the first internal variable
56 ##    npar     % number of parameters
57 ##    nparnames% number of parameter names
58 ##    nrows    % number of rows in the block
59 ##    parnames % list of parameter names
60 ##    pvmatrix % list of parameter values for each element
61 ##
62 ## @}
63 ## @end example
64 ##
65 ## See the @cite{IFF file format specifications} for details about 
66 ## the output structures.
67 ## @seealso{prs_spice}
68 ## @end deftypefn
69
70 function outstruct = prs_iff(name)
71   
72   ## Check input
73   if (nargin != 1 || !ischar(name))
74     error("prs_iff: wrong input.")
75   endif
76
77   ## Initialization
78   version ="0.1b1";
79   outstruct = struct("NLC",[],\
80                      "LCR",[],\
81                      "totextvar",0);
82   
83   ## Open cir file
84   filename = [name ".cir"];
85   if isempty(file_in_path(".",filename))
86     error(["prs_iff: .cir file not found:" filename]);
87   endif
88   fid = fopen(filename,"r");
89
90   ## Check version
91   ## FIXME: this part can be improved a lot!!
92   line = fgetl(fid);
93   
94   if line(1)!="%"
95     error(["prs_iff: missing version number in file " filename]);
96   endif
97   
98   if ~strcmp(version,sscanf(line(2:end),"%s"));
99     error(["prs_iff: conflicting version number in file " filename]);
100   endif
101   
102   ndsvec = []; # Vector of circuit nodes
103   intvar = 0;  # Number of internal variables
104   
105   ## NLC section
106   NLCcount = 0;
107   while !strcmp(line,"END")
108
109     ## Skip  comments
110     while line(1)=="%"
111       line = fgetl(fid);
112     endwhile
113
114     if strcmp(line,"END")
115       break
116     else
117       NLCcount++;
118     endif
119     
120     ## parse NLC block
121     [outstruct,intvar] = parseNLCblock(fid,line,outstruct,NLCcount,intvar);
122
123     ndsvec = [ndsvec ; \
124               outstruct.NLC(NLCcount).vnmatrix(:)];
125
126     ## skip the newline char after the matrix
127     line = fgetl(fid);
128     
129     ## proceed to next line
130     line = fgetl(fid);
131
132   endwhile
133
134   ## LCR section
135   LCRcount = 0;
136   line     = fgetl(fid);
137
138   while (!strcmp(line,"END"))
139
140     ## Skip  comments
141     while line(1)=="%"
142       line = fgetl(fid);
143     endwhile
144
145     if strcmp(line,"END")
146       break
147     else
148       LCRcount++;
149     endif
150     
151     ## parse block header
152     [outstruct,intvar] = parseLCRblock(fid,line,outstruct,LCRcount,intvar);
153     
154     ndsvec = [ndsvec ; \
155               outstruct.LCR(LCRcount).vnmatrix(:)];
156     
157     ## skip the newline char after the matrix
158     line = fgetl(fid);
159     
160     ## proceed to next line
161     line = fgetl(fid);
162
163   endwhile
164
165   ## Set the number of internal and external variables
166   outstruct.totintvar = intvar;
167   nnodes = length(unique(ndsvec));
168   maxidx = max(ndsvec);
169
170   if  nnodes <= (maxidx+1)
171     ## If the valid file is a subcircuit it may happen 
172     ## that nnodes == maxidx, otherwise nnodes == (maxidx+1)
173     outstruct.totextvar = max(ndsvec);
174   else
175     error("prs_iff: hanging nodes in circuit %s",name);
176   endif
177   ## fclose cir file
178   fclose(fid); 
179
180   ## Open nms file
181   filename = [name ".nms"];
182   if isempty(file_in_path(".",filename))
183     error(["prs_iff: .nms file not found:" filename]);
184   endif
185   fid = fopen(filename,"r");
186
187   ## Check version
188   line = fgetl(fid);
189   
190   if line(1)~="%"
191     error(["prs_iff: missing version number in file " filename]);
192   endif
193   
194   if ~strcmp(version,sscanf(line(2:end),"%s"));
195     error(["prs_iff: conflicting version number in file " filename]);
196   endif
197
198   ## Initialization
199   cnt = 1;
200   outstruct.namesn = [];
201   outstruct.namess = {};
202   nnames = 0;
203
204   while cnt
205     [nn,cnt] = fscanf(fid,"%d","C");
206     [ns,cnt] = fscanf(fid,"%s","C");
207     
208     if cnt
209       outstruct.namesn(++nnames)=nn;
210       outstruct.namess{nnames}=ns;
211     endif
212   endwhile
213   
214   ## fclose nms file
215   fclose(fid);
216
217 endfunction
218
219
220 ##############################################
221 function [outstruct,intvar] = parseNLCblock(fid,line,outstruct,NLCcount,intvar);
222
223   ## Parse first line of the header and retrieve:
224   ## 1 - SBN function name
225   ## 2 - Section
226   ## 3 - Number of external variables
227   ## 4 - Number of parameters
228   [func,section,nextvar,npar]     = sscanf(line,"%s %s %g %g","C");
229   outstruct.NLC(NLCcount).func    = func;
230   outstruct.NLC(NLCcount).section = section;
231   outstruct.NLC(NLCcount).nextvar = nextvar;
232   outstruct.NLC(NLCcount).npar    = npar;
233   ## Parse second line of the header and retrieve:
234   ## 1 - Number of elements of this type
235   ## 2 - Number of parameter names to be parsed
236   [nrows,nparnames]                 = fscanf(fid,"%g %g","C");
237   outstruct.NLC(NLCcount).nrows     = nrows;
238   outstruct.NLC(NLCcount).nparnames = nparnames;
239   outstruct.NLC(NLCcount).parnames  = {};
240   for ii=1:nparnames
241     outstruct.NLC(NLCcount).parnames{ii} = fscanf(fid,"%s","C");
242   endfor
243
244   ## Parse the matrix containing the values of parameters
245   [outstruct.NLC(NLCcount).pvmatrix] = fscanf(fid,"%g",[npar,nrows])';
246
247   ## Parse the connectivity matrix
248   [outstruct.NLC(NLCcount).vnmatrix] = fscanf(fid,"%g",[nextvar,nrows])';
249
250   ## Compute internal variables cycling over each 
251   ## element in the section
252   for iel = 1:nrows
253     [a,b,c] = feval(func,section,outstruct.NLC(NLCcount).pvmatrix(iel,:),\
254                     outstruct.NLC(NLCcount).parnames,zeros(nextvar,1),[],0);
255
256     ## FIXME: if all the element in the same section share the
257     ## same number of internal variables, the for cycle can be 
258     ## substituted by only one call
259     outstruct.NLC(NLCcount).nintvar(iel)  = columns(a) - outstruct.NLC(NLCcount).nextvar;
260     outstruct.NLC(NLCcount).osintvar(iel) = intvar;
261     
262     intvar += outstruct.NLC(NLCcount).nintvar(iel);
263   endfor
264
265 endfunction
266
267 ##############################################
268 function [outstruct,intvar] = parseLCRblock(fid,line,outstruct,LCRcount,intvar);
269
270   ## Parse first line of the header and retrieve:
271   ## 1 - SBN function name
272   ## 2 - Section
273   ## 3 - Number of external variables
274   ## 4 - Number of parameters
275   [func,section,nextvar,npar]     = sscanf(line,"%s %s %g %g","C");
276   outstruct.LCR(LCRcount).func    = func;
277   outstruct.LCR(LCRcount).section = section;
278   outstruct.LCR(LCRcount).nextvar = nextvar;
279   outstruct.LCR(LCRcount).npar    = npar;
280   ## Parse second line of the header and retrieve:
281   ## 1 - Number of elements of this type
282   ## 2 - Number of parameter names to be parsed
283   [nrows,nparnames]                 = fscanf(fid,"%g %g","C");
284   outstruct.LCR(LCRcount).nrows     = nrows;
285   outstruct.LCR(LCRcount).nparnames = nparnames;
286   outstruct.LCR(LCRcount).parnames  = {};
287   for ii=1:nparnames
288     outstruct.LCR(LCRcount).parnames{ii} = fscanf(fid,"%s","C");
289   endfor
290   
291   ## Parse the matrix containing the values of parameters
292   [outstruct.LCR(LCRcount).pvmatrix] = fscanf(fid,"%g",[npar,nrows])';
293   
294   ## Parse the connectivity matrix
295   [outstruct.LCR(LCRcount).vnmatrix] = fscanf(fid,"%g",[nextvar,nrows])';
296
297   ## Compute internal variables cycling over each 
298   ## element in the section
299   for iel = 1:nrows
300     [a,b,c] = feval(func,section,outstruct.LCR(LCRcount).pvmatrix(iel,:),\
301                     outstruct.LCR(LCRcount).parnames,zeros(nextvar,1),[],0);
302
303     ## FIXME: if all the element in the same section share the
304     ## same number of internal variables, the for cycle can be 
305     ## substituted by only one call
306     outstruct.LCR(LCRcount).nintvar(iel)  = columns(a) - outstruct.LCR(LCRcount).nextvar;
307     outstruct.LCR(LCRcount).osintvar(iel) = intvar;
308     
309     intvar += outstruct.LCR(LCRcount).nintvar(iel);
310   endfor
311
312 endfunction