Qucs-core
0.0.19
|
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 }