Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mextrsolver.cpp
Go to the documentation of this file.
1 #include <string>
2 #include <qucs-core/qucs_interface.h>
3 #include "mextrsolver.h"
4 
5 using namespace qucs;
6 
7 // function to display messages
8 void mextrsolvermessage(int level, const char* warningmsg, ...)
9 {
10  // we don't use level, it is just there to match the prototype
11  // for the function in e_trsolver
12  (void) level;
13 
14  //mexWarnMsgIdAndTxt("MATLAB:trsolver", warningmsg);
15 
16  mexPrintf("%s\n", warningmsg);
17 }
18 
20 {
21  //ctor
22  //thetrsolver = NULL;
23 }
24 
26 {
27  //dtor
28 }
29 
31 {
32  qtr.printSolution ();
33 }
34 
35 int mextrsolver::prepare_netlist(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
36 {
37  char *input_buf;
38  int result;
39 
40  /* check for proper number of arguments */
41  if(nrhs!=3)
42  mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
43  "Three inputs required.");
44  else if(nlhs > 0)
45  mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
46  "Too many output arguments.");
47 
48  /* 3rd input must be a string (first two are used for the class interface) */
49  if (mxIsChar(prhs[2]) != 1)
50  mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
51  "Input must be a string containing the file name.");
52 
53  /* input must be a row vector */
54  if (mxGetM(prhs[2]) != 1)
55  mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotVector",
56  "Input must be a row vector.");
57 
58  /* copy the string data from prhs[2] into a C string input_ buf. */
59  input_buf = mxArrayToString (prhs[2]);
60 
61  // call the prepare_netlist method with the input
62  result = qtr.prepare_netlist (input_buf);
63 
64  if (result == NETLIST_OK)
65  {
66  // get the pointer to the e_trsolver analysis
67  qtr.getETR ();
68  }
69  else if (result == NETLIST_FAILED_CHECK)
70  {
71  mexErrMsgIdAndTxt ( "MATLAB:trsolver:netlistcheckfailure",
72  "The netlist file failed the netlist check.");
73  }
74  else if (result == NETLIST_FILE_NOT_FOUND)
75  {
76  mexErrMsgIdAndTxt ( "MATLAB:trsolver:netlistcheckfailure",
77  "The netlist was not found or could not be opened.");
78  }
79  else
80  {
81  mexErrMsgIdAndTxt ( "MATLAB:trsolver:unknownfailure",
82  "The qucs interface returned an unknown error code.");
83  }
84 
85  if (!qtr.getIsInitialised ())
86  {
87  mexErrMsgIdAndTxt ( "MATLAB:trsolver:noetr",
88  "The transient solver could not be initialised (Is there an ETR sim in the netlist?).");
89  }
90  else
91  {
92  // make the message function mextrsolvermessage
93  qtr.setMessageFcn (&mextrsolvermessage);
94  }
95 
96  // free the char array as we are done with it
97  mxFree (input_buf);
98 
99  return result;
100 }
101 
102 // solves the circuit at a specified time point
103 int mextrsolver::stepsolve_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
104 {
105 
106  /* check for proper number of arguments */
107  if(nrhs!=3)
108  mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
109  "One input required.");
110  else if(nlhs > 1)
111  mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
112  "Too many output arguments.");
113 
114  /* input must be a scalar */
115  if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
116  mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
117  "Input must be a scalar.");
118 
119 
120  double synctime = mxGetScalar(prhs[2]);
121 
122  qtr.stepsolve_sync(synctime);
123 
124  return 0;
125 }
126 
127 
128 void mextrsolver::acceptstep_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
129 {
130  /* check for proper number of arguments */
131  if(nrhs!=2)
132  mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
133  "No input required.");
134  else if(nlhs > 0)
135  mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
136  "Too many output arguments.");
137 
138 
139  qtr.acceptstep_sync();
140 }
141 
142 
143 // solves the circuit at a specified time point
144 int mextrsolver::stepsolve_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
145 {
146 
147  /* check for proper number of arguments */
148  if(nrhs!=3)
149  mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
150  "One input required.");
151  else if(nlhs > 1)
152  mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
153  "Too many output arguments.");
154 
155  /* input must be a scalar */
156  if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
157  mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
158  "Input must be a scalar.");
159 
160 
161  double synctime = mxGetScalar(prhs[2]);
162 
163  qtr.stepsolve_async(synctime);
164 
165  return 0;
166 }
167 
168 
169 void mextrsolver::acceptstep_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
170 {
171  /* check for proper number of arguments */
172  if(nrhs!=2)
173  mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
174  "No input required.");
175  else if(nlhs > 0)
176  mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
177  "Too many output arguments.");
178 
179 
180  qtr.acceptstep_async();
181 }
182 
183 void mextrsolver::rejectstep_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
184 {
185  /* check for proper number of arguments */
186  if(nrhs!=2)
187  mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
188  "No input required.");
189  else if(nlhs > 0)
190  mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
191  "Too many output arguments.");
192 
193 
194  qtr.rejectstep_async();
195 }
196 
197 // gets the last solution calculated by the solver
198 int mextrsolver::getsolution(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
199 {
200  double * outpointer;
201  int xN, xM, status = 0;
202 
203  /* check for proper number of arguments */
204  if(nrhs!=2)
205  mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
206  "No input required.");
207  else if(nlhs > 2)
208  mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
209  "Too many output arguments.");
210 
211 
212  xN = qtr.getN();
213  xM = qtr.getM();
214 
215  //mexPrintf("%d %d\n", xN, xM);
216 
217  if (xN <= 0)
218  {
219  mexErrMsgIdAndTxt( "MATLAB:trsolver:nosolution",
220  "There zero nodes in the circuit.");
221  }
222 
223  // copy the solution
224  plhs[0] = mxCreateDoubleMatrix( (mwSize)(xN+xM), (mwSize)(1), mxREAL);
225 
226  // get a pointer to the start of the actual output data array
227  outpointer = mxGetPr(plhs[0]);
228 
229  // copy the data into the array
230  qtr.getsolution(outpointer);
231 
232  // copy the number of nodal voltages and branch currents
233  plhs[1] = mxCreateDoubleMatrix( (mwSize)(1), (mwSize)(2), mxREAL);
234 
235  // get a pointer to the start of the actual output data array
236  outpointer = mxGetPr(plhs[1]);
237 
238  // copy the data into the array
239  outpointer[0] = (double)xN;
240  outpointer[1] = (double)xM;
241 
242  return status;
243 }
244 
245 void mextrsolver::init_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
246 {
247 
248  double start;
249 
250  /* check for proper number of arguments */
251  if(nrhs!=3)
252  mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
253  "One input required.");
254  else if(nlhs > 0)
255  mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
256  "Too many output arguments.");
257 
258  /* input must be a scalar */
259  if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
260  mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
261  "Input must be a scalar.");
262 
263 
264  start = mxGetScalar(prhs[2]);
265 
266  qtr.init(start, 1e-6, ETR_MODE_SYNC);
267 }
268 
269 void mextrsolver::init_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
270 {
271  double start, firstdelta;
272 
273  /* check for proper number of arguments */
274  if(nrhs!=4)
275  mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
276  "Two inputs required.");
277  else if(nlhs > 0)
278  mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
279  "Too many output arguments.");
280 
281  /* input must be a scalar */
282  if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
283  mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
284  "Input 1 must be a scalar.");
285 
286 
287  start = mxGetScalar(prhs[2]);
288 
289  /* input must be a scalar */
290  if ((mxGetM(prhs[3])!=1) | (mxGetN(prhs[3])!=1))
291  mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
292  "Input 2 must be a scalar.");
293 
294 
295  firstdelta = mxGetScalar(prhs[3]);
296 
297  qtr.init(start, firstdelta, ETR_MODE_ASYNC);
298 }
299 
300 
301 // gets the last solution calculated by the solver
302 int mextrsolver::getN(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
303 {
304  double * outpointer;
305 
306  /* check for proper number of arguments */
307  if (nrhs!=2)
308  mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
309  "No input required.");
310  else if (nlhs > 1)
311  mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
312  "Too many output arguments.");
313 
314 
315  int xN = qtr.getN ();
316 
317  // copy the solution
318  plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
319 
320  // get a pointer to the start of the actual output data array
321  outpointer = mxGetPr (plhs[0]);
322 
323  // copy the data into the array
324  outpointer[0] = (double)xN;
325 }
326 
327 
328 int mextrsolver::getM(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
329 {
330  double * outpointer;
331 
332  /* check for proper number of arguments */
333  if (nrhs!=2)
334  mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
335  "No input required.");
336  else if (nlhs > 1)
337  mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
338  "Too many output arguments.");
339 
340 
341  int xM = qtr.getM ();
342 
343  // copy the solution
344  plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
345 
346  // get a pointer to the start of the actual output data array
347  outpointer = mxGetPr (plhs[0]);
348 
349  // copy the data into the array
350  outpointer[0] = (double)xM;
351 
352 }
353 
354 // Get the jacobian matriz for the circuit
355 void mextrsolver::getJac(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
356 {
357  double * outpointer;
358 
359  /* check for proper number of arguments */
360  if (nrhs != 2)
361  mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
362  "No input required.");
363  else if (nlhs > 1)
364  mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
365  "Too many output arguments.");
366 
367  int jrows = qtr.getJacRows ();
368  int jcols = qtr.getJacCols ();
369 
370  // copy the solution
371  plhs[0] = mxCreateDoubleMatrix ( (mwSize)(jrows), (mwSize)(jcols), mxREAL);
372 
373  // get a pointer to the start of the actual output data array
374  outpointer = mxGetPr (plhs[0]);
375 
376  // copy the jacobian matrix data into the matlab matrix
377  for(int c = 0; c < jcols; c++)
378  {
379  for(int r = 0; r < jrows; r++)
380  {
381  qtr.getJacData(r, c, outpointer[(c*jrows)+r]);
382  }
383  }
384 
385 }
386 
387 // sets the value of an externally controlled voltage source
388 void mextrsolver::setecvs(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
389 {
390  char *ecvsname;
391  double newvoltage = 0;
392  int result;
393 
394  /* check for proper number of arguments */
395  if (nrhs != 4)
396  mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
397  "One input required.");
398  else if (nlhs > 0)
399  mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
400  "Too many output arguments.");
401 
402  /* 3rd input must be a string (first two are used for the class interface) */
403  if (mxIsChar(prhs[2]) != 1)
404  mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
405  "Input must be a string containing the file name.");
406 
407  /* 4th input must be a scalar */
408  if (mxIsNumeric (prhs[3]) & ((mxGetM (prhs[3]) != 1) | (mxGetN (prhs[3]) != 1)))
409  mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotVector",
410  "Voltage input must be a scalar.");
411 
412 
413  /* copy the string data from prhs[2] into a C string ecvsname. */
414  ecvsname = mxArrayToString (prhs[2]);
415 
416  newvoltage = mxGetScalar (prhs[3]);
417 
418  result = qtr.setECVSVoltage (ecvsname, newvoltage);
419 
420  if (result != 0)
421  {
422  // Throw an error if the voltage source was not found
423  mexErrMsgIdAndTxt ( "MATLAB:trsolver:ecvsnotfound",
424  "The ECVS component with name %s was not found.",
425  ecvsname );
426  }
427 }
428 
429 
430 // gets the value of a current probe
431 void mextrsolver::getiprobe(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
432 {
433  char* probename;
434  double* outpointer;
435  double current = 0;
436  int result;
437 
438  /* check for proper number of arguments */
439  if (nrhs != 3)
440  mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
441  "One input required.");
442  else if (nlhs > 1)
443  mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
444  "Too many output arguments.");
445 
446  /* 3rd input must be a string (first two are used for the class interface) */
447  if (mxIsChar(prhs[2]) != 1)
448  mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
449  "Input must be a string containing the file name.");
450 
451 
452  /* copy the string data from prhs[2] into a C string probename. */
453  probename = mxArrayToString (prhs[2]);
454 
455  result = qtr.getIProbeI (probename, current);
456 
457  if (result != 0)
458  {
459  // Throw an error if the current probe was not found
460  mexErrMsgIdAndTxt ( "MATLAB:trsolver:vprobenotfound",
461  "The current probe with name %s was not found.",
462  probename );
463  }
464  else
465  {
466  // copy the solution
467  plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
468 
469  // get a pointer to the start of the actual output data array
470  outpointer = mxGetPr (plhs[0]);
471 
472  // copy the data into the array
473  outpointer[0] = (double)current;
474  }
475 }
476 
477 // gets the value of a voltage probe
478 void mextrsolver::getvprobe(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
479 {
480  char* probename;
481  double* outpointer;
482  double voltage = 0;
483  int result;
484 
485  /* check for proper number of arguments */
486  if (nrhs != 3)
487  mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
488  "One input required.");
489  else if (nlhs > 1)
490  mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
491  "Too many output arguments.");
492 
493  /* 3rd input must be a string (first two are used for the class interface) */
494  if (mxIsChar(prhs[2]) != 1)
495  mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
496  "Input must be a string containing the file name.");
497 
498 
499  /* copy the string data from prhs[2] into a C string probename. */
500  probename = mxArrayToString (prhs[2]);
501 
502  result = qtr.getVProbeV (probename, voltage);
503 
504  if (result != 0)
505  {
506  // Throw an error if the voltage probe was not found
507  mexErrMsgIdAndTxt ( "MATLAB:trsolver:vprobenotfound",
508  "The voltage probe with name %s was not found.",
509  probename );
510  }
511  else
512  {
513  // copy the solution
514  plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
515 
516  // get a pointer to the start of the actual output data array
517  outpointer = mxGetPr (plhs[0]);
518 
519  // copy the data into the array
520  outpointer[0] = (double)voltage;
521  }
522 }
523 
524 
525 // gets the value of the voltage at a named node
526 void mextrsolver::getnodev(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
527 {
528  char* nodename;
529  double* outpointer;
530  double voltage = 0;
531  int result;
532 
533  /* check for proper number of arguments */
534  if (nrhs != 3)
535  mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
536  "One input required.");
537  else if (nlhs > 1)
538  mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
539  "Too many output arguments.");
540 
541  /* 3rd input must be a string (first two are used for the class interface) */
542  if (mxIsChar(prhs[2]) != 1)
543  mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
544  "Input must be a string containing the file name.");
545 
546 
547  /* copy the string data from prhs[2] into a C string nodename. */
548  nodename = mxArrayToString (prhs[2]);
549 
550  result = qtr.getNodeV (nodename, voltage);
551 
552  if (result != 0)
553  {
554  // Throw an error if the node was not found
555  mexErrMsgIdAndTxt ( "MATLAB:trsolver:vprobenotfound",
556  "The voltage probe with name %s was not found.",
557  nodename );
558  }
559  else
560  {
561  // copy the solution
562  plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
563 
564  // get a pointer to the start of the actual output data array
565  outpointer = mxGetPr (plhs[0]);
566 
567  // copy the data into the array
568  outpointer[0] = (double)voltage;
569  }
570 }
start
Definition: parse_zvr.y:126
void printx(void)
Definition: mextrsolver.cpp:30
int stepsolve_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
void getiprobe(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
int stepsolve_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
virtual ~mextrsolver()
Definition: mextrsolver.cpp:25
r
Definition: parse_mdl.y:515
void acceptstep_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
int prepare_netlist(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Definition: mextrsolver.cpp:35
void mextrsolvermessage(int level, const char *warningmsg,...)
Definition: mextrsolver.cpp:8
void getJac(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
void getnodev(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
int getsolution(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
void init_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
void init_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
result
void rejectstep_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
void getvprobe(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
void acceptstep_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
void setecvs(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
int getM(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
int getN(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])