Qucs-core  0.0.19
mextrsolver.cpp
Go to the documentation of this file.
00001 #include <string>
00002 #include <qucs-core/qucs_interface.h>
00003 #include "mextrsolver.h"
00004 
00005 using namespace qucs;
00006 
00007 // function to display messages
00008 void mextrsolvermessage(int level, const char* warningmsg, ...)
00009 {
00010     // we don't use level, it is just there to match the prototype
00011     // for the function in e_trsolver
00012     (void) level;
00013 
00014     //mexWarnMsgIdAndTxt("MATLAB:trsolver", warningmsg);
00015 
00016     mexPrintf("%s\n", warningmsg);
00017 }
00018 
00019 mextrsolver::mextrsolver()
00020 {
00021     //ctor
00022     //thetrsolver = NULL;
00023 }
00024 
00025 mextrsolver::~mextrsolver()
00026 {
00027     //dtor
00028 }
00029 
00030 void mextrsolver::printx()
00031 {
00032     qtr.printSolution ();
00033 }
00034 
00035 int mextrsolver::prepare_netlist(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00036 {
00037     char *input_buf;
00038     int result;
00039 
00040     /* check for proper number of arguments */
00041     if(nrhs!=3)
00042         mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
00043                             "Three inputs required.");
00044     else if(nlhs > 0)
00045         mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
00046                             "Too many output arguments.");
00047 
00048     /* 3rd input must be a string (first two are used for the class interface) */
00049     if (mxIsChar(prhs[2]) != 1)
00050         mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
00051                             "Input must be a string containing the file name.");
00052 
00053     /* input must be a row vector */
00054     if (mxGetM(prhs[2]) != 1)
00055         mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotVector",
00056                             "Input must be a row vector.");
00057 
00058     /* copy the string data from prhs[2] into a C string input_ buf.    */
00059     input_buf = mxArrayToString (prhs[2]);
00060 
00061     // call the prepare_netlist method with the input
00062     result = qtr.prepare_netlist (input_buf);
00063 
00064     if (result == NETLIST_OK)
00065     {
00066         // get the pointer to the e_trsolver analysis
00067         qtr.getETR ();
00068     }
00069     else if (result == NETLIST_FAILED_CHECK)
00070     {
00071         mexErrMsgIdAndTxt ( "MATLAB:trsolver:netlistcheckfailure",
00072                             "The netlist file failed the netlist check.");
00073     }
00074     else if (result == NETLIST_FILE_NOT_FOUND)
00075     {
00076         mexErrMsgIdAndTxt ( "MATLAB:trsolver:netlistcheckfailure",
00077                             "The netlist was not found or could not be opened.");
00078     }
00079     else
00080     {
00081         mexErrMsgIdAndTxt ( "MATLAB:trsolver:unknownfailure",
00082                             "The qucs interface returned an unknown error code.");
00083     }
00084 
00085     if (!qtr.getIsInitialised ())
00086     {
00087         mexErrMsgIdAndTxt ( "MATLAB:trsolver:noetr",
00088                             "The transient solver could not be initialised (Is there an ETR sim in the netlist?).");
00089     }
00090     else
00091     {
00092         // make the message function mextrsolvermessage
00093         qtr.setMessageFcn (&mextrsolvermessage);
00094     }
00095 
00096     // free the char array as we are done with it
00097     mxFree (input_buf);
00098 
00099     return result;
00100 }
00101 
00102 // solves the circuit at a specified time point
00103 int mextrsolver::stepsolve_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00104 {
00105 
00106     /* check for proper number of arguments */
00107     if(nrhs!=3)
00108         mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
00109                            "One input required.");
00110     else if(nlhs > 1)
00111         mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
00112                            "Too many output arguments.");
00113 
00114     /* input must be a scalar */
00115     if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
00116         mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
00117                            "Input must be a scalar.");
00118 
00119 
00120     double synctime = mxGetScalar(prhs[2]);
00121 
00122     qtr.stepsolve_sync(synctime);
00123 
00124     return 0;
00125 }
00126 
00127 
00128 void mextrsolver::acceptstep_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00129 {
00130     /* check for proper number of arguments */
00131     if(nrhs!=2)
00132         mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
00133                            "No input required.");
00134     else if(nlhs > 0)
00135         mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
00136                            "Too many output arguments.");
00137 
00138 
00139     qtr.acceptstep_sync();
00140 }
00141 
00142 
00143 // solves the circuit at a specified time point
00144 int mextrsolver::stepsolve_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00145 {
00146 
00147     /* check for proper number of arguments */
00148     if(nrhs!=3)
00149         mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
00150                            "One input required.");
00151     else if(nlhs > 1)
00152         mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
00153                            "Too many output arguments.");
00154 
00155     /* input must be a scalar */
00156     if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
00157         mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
00158                            "Input must be a scalar.");
00159 
00160 
00161     double synctime = mxGetScalar(prhs[2]);
00162 
00163     qtr.stepsolve_async(synctime);
00164 
00165     return 0;
00166 }
00167 
00168 
00169 void mextrsolver::acceptstep_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00170 {
00171     /* check for proper number of arguments */
00172     if(nrhs!=2)
00173         mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
00174                            "No input required.");
00175     else if(nlhs > 0)
00176         mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
00177                            "Too many output arguments.");
00178 
00179 
00180     qtr.acceptstep_async();
00181 }
00182 
00183 void mextrsolver::rejectstep_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00184 {
00185     /* check for proper number of arguments */
00186     if(nrhs!=2)
00187         mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
00188                            "No input required.");
00189     else if(nlhs > 0)
00190         mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
00191                            "Too many output arguments.");
00192 
00193 
00194     qtr.rejectstep_async();
00195 }
00196 
00197 // gets the last solution calculated by the solver
00198 int mextrsolver::getsolution(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00199 {
00200     double * outpointer;
00201     int xN, xM, status = 0;
00202 
00203     /* check for proper number of arguments */
00204     if(nrhs!=2)
00205         mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
00206                            "No input required.");
00207     else if(nlhs > 2)
00208         mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
00209                            "Too many output arguments.");
00210 
00211 
00212     xN = qtr.getN();
00213     xM = qtr.getM();
00214 
00215     //mexPrintf("%d %d\n", xN, xM);
00216 
00217     if (xN <= 0)
00218     {
00219         mexErrMsgIdAndTxt( "MATLAB:trsolver:nosolution",
00220                            "There zero nodes in the circuit.");
00221     }
00222 
00223     // copy the solution
00224     plhs[0] = mxCreateDoubleMatrix( (mwSize)(xN+xM), (mwSize)(1), mxREAL);
00225 
00226     // get a pointer to the start of the actual output data array
00227     outpointer = mxGetPr(plhs[0]);
00228 
00229     // copy the data into the array
00230     qtr.getsolution(outpointer);
00231 
00232     // copy the number of nodal voltages and branch currents
00233     plhs[1] = mxCreateDoubleMatrix( (mwSize)(1), (mwSize)(2), mxREAL);
00234 
00235     // get a pointer to the start of the actual output data array
00236     outpointer = mxGetPr(plhs[1]);
00237 
00238     // copy the data into the array
00239     outpointer[0] = (double)xN;
00240     outpointer[1] = (double)xM;
00241 
00242     return status;
00243 }
00244 
00245 void mextrsolver::init_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00246 {
00247 
00248     double start;
00249 
00250     /* check for proper number of arguments */
00251     if(nrhs!=3)
00252         mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
00253                            "One input required.");
00254     else if(nlhs > 0)
00255         mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
00256                            "Too many output arguments.");
00257 
00258     /* input must be a scalar */
00259     if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
00260         mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
00261                            "Input must be a scalar.");
00262 
00263 
00264     start = mxGetScalar(prhs[2]);
00265 
00266     qtr.init(start, 1e-6, ETR_MODE_SYNC);
00267 }
00268 
00269 void mextrsolver::init_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00270 {
00271     double start, firstdelta;
00272 
00273     /* check for proper number of arguments */
00274     if(nrhs!=4)
00275         mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
00276                            "Two inputs required.");
00277     else if(nlhs > 0)
00278         mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
00279                            "Too many output arguments.");
00280 
00281     /* input must be a scalar */
00282     if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
00283         mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
00284                            "Input 1 must be a scalar.");
00285 
00286 
00287     start = mxGetScalar(prhs[2]);
00288 
00289     /* input must be a scalar */
00290     if ((mxGetM(prhs[3])!=1) | (mxGetN(prhs[3])!=1))
00291         mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
00292                            "Input 2 must be a scalar.");
00293 
00294 
00295     firstdelta = mxGetScalar(prhs[3]);
00296 
00297     qtr.init(start, firstdelta, ETR_MODE_ASYNC);
00298 }
00299 
00300 
00301 // gets the last solution calculated by the solver
00302 int mextrsolver::getN(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00303 {
00304     double * outpointer;
00305 
00306     /* check for proper number of arguments */
00307     if (nrhs!=2)
00308         mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
00309                             "No input required.");
00310     else if (nlhs > 1)
00311         mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
00312                             "Too many output arguments.");
00313 
00314 
00315     int xN = qtr.getN ();
00316 
00317     // copy the solution
00318     plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
00319 
00320     // get a pointer to the start of the actual output data array
00321     outpointer = mxGetPr (plhs[0]);
00322 
00323     // copy the data into the array
00324     outpointer[0] = (double)xN;
00325 }
00326 
00327 
00328 int mextrsolver::getM(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00329 {
00330     double * outpointer;
00331 
00332     /* check for proper number of arguments */
00333     if (nrhs!=2)
00334         mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
00335                             "No input required.");
00336     else if (nlhs > 1)
00337         mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
00338                             "Too many output arguments.");
00339 
00340 
00341     int xM = qtr.getM ();
00342 
00343     // copy the solution
00344     plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
00345 
00346     // get a pointer to the start of the actual output data array
00347     outpointer = mxGetPr (plhs[0]);
00348 
00349     // copy the data into the array
00350     outpointer[0] = (double)xM;
00351 
00352 }
00353 
00354 // Get the jacobian matriz for the circuit
00355 void mextrsolver::getJac(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00356 {
00357     double * outpointer;
00358 
00359     /* check for proper number of arguments */
00360     if (nrhs != 2)
00361         mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
00362                             "No input required.");
00363     else if (nlhs > 1)
00364         mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
00365                             "Too many output arguments.");
00366 
00367     int jrows = qtr.getJacRows ();
00368     int jcols = qtr.getJacCols ();
00369 
00370     // copy the solution
00371     plhs[0] = mxCreateDoubleMatrix ( (mwSize)(jrows), (mwSize)(jcols), mxREAL);
00372 
00373     // get a pointer to the start of the actual output data array
00374     outpointer = mxGetPr (plhs[0]);
00375 
00376     // copy the jacobian matrix data into the matlab matrix
00377     for(int c = 0; c < jcols; c++)
00378     {
00379         for(int r = 0; r < jrows; r++)
00380         {
00381             qtr.getJacData(r, c, outpointer[(c*jrows)+r]);
00382         }
00383     }
00384 
00385 }
00386 
00387 // sets the value of an externally controlled voltage source
00388 void mextrsolver::setecvs(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00389 {
00390     char *ecvsname;
00391     double newvoltage = 0;
00392     int result;
00393 
00394     /* check for proper number of arguments */
00395     if (nrhs != 4)
00396         mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
00397                             "One input required.");
00398     else if (nlhs > 0)
00399         mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
00400                             "Too many output arguments.");
00401 
00402     /* 3rd input must be a string (first two are used for the class interface) */
00403     if (mxIsChar(prhs[2]) != 1)
00404         mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
00405                             "Input must be a string containing the file name.");
00406 
00407     /* 4th input must be a scalar */
00408     if (mxIsNumeric (prhs[3]) & ((mxGetM (prhs[3]) != 1) | (mxGetN (prhs[3]) != 1)))
00409         mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotVector",
00410                             "Voltage input must be a scalar.");
00411 
00412 
00413     /* copy the string data from prhs[2] into a C string ecvsname.    */
00414     ecvsname = mxArrayToString (prhs[2]);
00415 
00416     newvoltage = mxGetScalar (prhs[3]);
00417 
00418     result = qtr.setECVSVoltage (ecvsname, newvoltage);
00419 
00420     if (result != 0)
00421     {
00422         // Throw an error if the voltage source was not found
00423         mexErrMsgIdAndTxt ( "MATLAB:trsolver:ecvsnotfound",
00424                             "The ECVS component with name %s was not found.",
00425                             ecvsname );
00426     }
00427 }
00428 
00429 
00430 // gets the value of a current probe
00431 void mextrsolver::getiprobe(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00432 {
00433     char* probename;
00434     double* outpointer;
00435     double current = 0;
00436     int result;
00437 
00438     /* check for proper number of arguments */
00439     if (nrhs != 3)
00440         mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
00441                             "One input required.");
00442     else if (nlhs > 1)
00443         mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
00444                             "Too many output arguments.");
00445 
00446     /* 3rd input must be a string (first two are used for the class interface) */
00447     if (mxIsChar(prhs[2]) != 1)
00448         mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
00449                             "Input must be a string containing the file name.");
00450 
00451 
00452     /* copy the string data from prhs[2] into a C string probename.    */
00453     probename = mxArrayToString (prhs[2]);
00454 
00455     result = qtr.getIProbeI (probename, current);
00456 
00457     if (result != 0)
00458     {
00459         // Throw an error if the current probe was not found
00460         mexErrMsgIdAndTxt ( "MATLAB:trsolver:vprobenotfound",
00461                             "The current probe with name %s was not found.",
00462                             probename );
00463     }
00464     else
00465     {
00466         // copy the solution
00467         plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
00468 
00469         // get a pointer to the start of the actual output data array
00470         outpointer = mxGetPr (plhs[0]);
00471 
00472         // copy the data into the array
00473         outpointer[0] = (double)current;
00474     }
00475 }
00476 
00477 // gets the value of a voltage probe
00478 void mextrsolver::getvprobe(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00479 {
00480     char* probename;
00481     double* outpointer;
00482     double voltage = 0;
00483     int result;
00484 
00485     /* check for proper number of arguments */
00486     if (nrhs != 3)
00487         mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
00488                             "One input required.");
00489     else if (nlhs > 1)
00490         mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
00491                             "Too many output arguments.");
00492 
00493     /* 3rd input must be a string (first two are used for the class interface) */
00494     if (mxIsChar(prhs[2]) != 1)
00495         mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
00496                             "Input must be a string containing the file name.");
00497 
00498 
00499     /* copy the string data from prhs[2] into a C string probename.    */
00500     probename = mxArrayToString (prhs[2]);
00501 
00502     result = qtr.getVProbeV (probename, voltage);
00503 
00504     if (result != 0)
00505     {
00506         // Throw an error if the voltage probe was not found
00507         mexErrMsgIdAndTxt ( "MATLAB:trsolver:vprobenotfound",
00508                             "The voltage probe with name %s was not found.",
00509                             probename );
00510     }
00511     else
00512     {
00513         // copy the solution
00514         plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
00515 
00516         // get a pointer to the start of the actual output data array
00517         outpointer = mxGetPr (plhs[0]);
00518 
00519         // copy the data into the array
00520         outpointer[0] = (double)voltage;
00521     }
00522 }
00523 
00524 
00525 // gets the value of the voltage at a named node
00526 void mextrsolver::getnodev(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00527 {
00528     char* nodename;
00529     double* outpointer;
00530     double voltage = 0;
00531     int result;
00532 
00533     /* check for proper number of arguments */
00534     if (nrhs != 3)
00535         mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
00536                             "One input required.");
00537     else if (nlhs > 1)
00538         mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
00539                             "Too many output arguments.");
00540 
00541     /* 3rd input must be a string (first two are used for the class interface) */
00542     if (mxIsChar(prhs[2]) != 1)
00543         mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
00544                             "Input must be a string containing the file name.");
00545 
00546 
00547     /* copy the string data from prhs[2] into a C string nodename. */
00548     nodename = mxArrayToString (prhs[2]);
00549     
00550     result = qtr.getNodeV (nodename, voltage);
00551 
00552     if (result != 0)
00553     {
00554         // Throw an error if the node was not found
00555         mexErrMsgIdAndTxt ( "MATLAB:trsolver:vprobenotfound",
00556                             "The voltage probe with name %s was not found.",
00557                             nodename );
00558     }
00559     else
00560     {
00561         // copy the solution
00562         plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
00563 
00564         // get a pointer to the start of the actual output data array
00565         outpointer = mxGetPr (plhs[0]);
00566 
00567         // copy the data into the array
00568         outpointer[0] = (double)voltage;
00569     }
00570 }