#include <string>
#include <qucs-core/qucs_interface.h>
#include "mextrsolver.h"
using namespace qucs;
void mextrsolvermessage(int level, const char* warningmsg, ...)
{
(void) level;
mexPrintf("%s\n", warningmsg);
}
mextrsolver::mextrsolver()
{
}
mextrsolver::~mextrsolver()
{
}
void mextrsolver::printx()
{
qtr.printSolution ();
}
int mextrsolver::prepare_netlist(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
char *input_buf;
int result;
if(nrhs!=3)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
"Three inputs required.");
else if(nlhs > 0)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
if (mxIsChar(prhs[2]) != 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
"Input must be a string containing the file name.");
if (mxGetM(prhs[2]) != 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotVector",
"Input must be a row vector.");
input_buf = mxArrayToString (prhs[2]);
result = qtr.prepare_netlist (input_buf);
if (result == NETLIST_OK)
{
qtr.getETR ();
}
else if (result == NETLIST_FAILED_CHECK)
{
mexErrMsgIdAndTxt ( "MATLAB:trsolver:netlistcheckfailure",
"The netlist file failed the netlist check.");
}
else if (result == NETLIST_FILE_NOT_FOUND)
{
mexErrMsgIdAndTxt ( "MATLAB:trsolver:netlistcheckfailure",
"The netlist was not found or could not be opened.");
}
else
{
mexErrMsgIdAndTxt ( "MATLAB:trsolver:unknownfailure",
"The qucs interface returned an unknown error code.");
}
if (!qtr.getIsInitialised ())
{
mexErrMsgIdAndTxt ( "MATLAB:trsolver:noetr",
"The transient solver could not be initialised (Is there an ETR sim in the netlist?).");
}
else
{
qtr.setMessageFcn (&mextrsolvermessage);
}
mxFree (input_buf);
return result;
}
int mextrsolver::stepsolve_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if(nrhs!=3)
mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
"One input required.");
else if(nlhs > 1)
mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
"Input must be a scalar.");
double synctime = mxGetScalar(prhs[2]);
qtr.stepsolve_sync(synctime);
return 0;
}
void mextrsolver::acceptstep_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if(nrhs!=2)
mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
"No input required.");
else if(nlhs > 0)
mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
qtr.acceptstep_sync();
}
int mextrsolver::stepsolve_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if(nrhs!=3)
mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
"One input required.");
else if(nlhs > 1)
mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
"Input must be a scalar.");
double synctime = mxGetScalar(prhs[2]);
qtr.stepsolve_async(synctime);
return 0;
}
void mextrsolver::acceptstep_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if(nrhs!=2)
mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
"No input required.");
else if(nlhs > 0)
mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
qtr.acceptstep_async();
}
void mextrsolver::rejectstep_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if(nrhs!=2)
mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
"No input required.");
else if(nlhs > 0)
mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
qtr.rejectstep_async();
}
int mextrsolver::getsolution(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double * outpointer;
int xN, xM, status = 0;
if(nrhs!=2)
mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
"No input required.");
else if(nlhs > 2)
mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
xN = qtr.getN();
xM = qtr.getM();
if (xN <= 0)
{
mexErrMsgIdAndTxt( "MATLAB:trsolver:nosolution",
"There zero nodes in the circuit.");
}
plhs[0] = mxCreateDoubleMatrix( (mwSize)(xN+xM), (mwSize)(1), mxREAL);
outpointer = mxGetPr(plhs[0]);
qtr.getsolution(outpointer);
plhs[1] = mxCreateDoubleMatrix( (mwSize)(1), (mwSize)(2), mxREAL);
outpointer = mxGetPr(plhs[1]);
outpointer[0] = (double)xN;
outpointer[1] = (double)xM;
return status;
}
void mextrsolver::init_sync(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double start;
if(nrhs!=3)
mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
"One input required.");
else if(nlhs > 0)
mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
"Input must be a scalar.");
start = mxGetScalar(prhs[2]);
qtr.init(start, 1e-6, ETR_MODE_SYNC);
}
void mextrsolver::init_async(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double start, firstdelta;
if(nrhs!=4)
mexErrMsgIdAndTxt( "MATLAB:trsolver:invalidNumInputs",
"Two inputs required.");
else if(nlhs > 0)
mexErrMsgIdAndTxt( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
if ((mxGetM(prhs[2])!=1) | (mxGetN(prhs[2])!=1))
mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
"Input 1 must be a scalar.");
start = mxGetScalar(prhs[2]);
if ((mxGetM(prhs[3])!=1) | (mxGetN(prhs[3])!=1))
mexErrMsgIdAndTxt( "MATLAB:trsolver:inputNotVector",
"Input 2 must be a scalar.");
firstdelta = mxGetScalar(prhs[3]);
qtr.init(start, firstdelta, ETR_MODE_ASYNC);
}
int mextrsolver::getN(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double * outpointer;
if (nrhs!=2)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
"No input required.");
else if (nlhs > 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
int xN = qtr.getN ();
plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
outpointer = mxGetPr (plhs[0]);
outpointer[0] = (double)xN;
}
int mextrsolver::getM(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double * outpointer;
if (nrhs!=2)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
"No input required.");
else if (nlhs > 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
int xM = qtr.getM ();
plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
outpointer = mxGetPr (plhs[0]);
outpointer[0] = (double)xM;
}
void mextrsolver::getJac(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double * outpointer;
if (nrhs != 2)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
"No input required.");
else if (nlhs > 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
int jrows = qtr.getJacRows ();
int jcols = qtr.getJacCols ();
plhs[0] = mxCreateDoubleMatrix ( (mwSize)(jrows), (mwSize)(jcols), mxREAL);
outpointer = mxGetPr (plhs[0]);
for(int c = 0; c < jcols; c++)
{
for(int r = 0; r < jrows; r++)
{
qtr.getJacData(r, c, outpointer[(c*jrows)+r]);
}
}
}
void mextrsolver::setecvs(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
char *ecvsname;
double newvoltage = 0;
int result;
if (nrhs != 4)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
"One input required.");
else if (nlhs > 0)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
if (mxIsChar(prhs[2]) != 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
"Input must be a string containing the file name.");
if (mxIsNumeric (prhs[3]) & ((mxGetM (prhs[3]) != 1) | (mxGetN (prhs[3]) != 1)))
mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotVector",
"Voltage input must be a scalar.");
ecvsname = mxArrayToString (prhs[2]);
newvoltage = mxGetScalar (prhs[3]);
result = qtr.setECVSVoltage (ecvsname, newvoltage);
if (result != 0)
{
mexErrMsgIdAndTxt ( "MATLAB:trsolver:ecvsnotfound",
"The ECVS component with name %s was not found.",
ecvsname );
}
}
void mextrsolver::getiprobe(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
char* probename;
double* outpointer;
double current = 0;
int result;
if (nrhs != 3)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
"One input required.");
else if (nlhs > 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
if (mxIsChar(prhs[2]) != 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
"Input must be a string containing the file name.");
probename = mxArrayToString (prhs[2]);
result = qtr.getIProbeI (probename, current);
if (result != 0)
{
mexErrMsgIdAndTxt ( "MATLAB:trsolver:vprobenotfound",
"The current probe with name %s was not found.",
probename );
}
else
{
plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
outpointer = mxGetPr (plhs[0]);
outpointer[0] = (double)current;
}
}
void mextrsolver::getvprobe(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
char* probename;
double* outpointer;
double voltage = 0;
int result;
if (nrhs != 3)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
"One input required.");
else if (nlhs > 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
if (mxIsChar(prhs[2]) != 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
"Input must be a string containing the file name.");
probename = mxArrayToString (prhs[2]);
result = qtr.getVProbeV (probename, voltage);
if (result != 0)
{
mexErrMsgIdAndTxt ( "MATLAB:trsolver:vprobenotfound",
"The voltage probe with name %s was not found.",
probename );
}
else
{
plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
outpointer = mxGetPr (plhs[0]);
outpointer[0] = (double)voltage;
}
}
void mextrsolver::getnodev(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
char* nodename;
double* outpointer;
double voltage = 0;
int result;
if (nrhs != 3)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:invalidNumInputs",
"One input required.");
else if (nlhs > 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:maxlhs",
"Too many output arguments.");
if (mxIsChar(prhs[2]) != 1)
mexErrMsgIdAndTxt ( "MATLAB:trsolver:inputNotString",
"Input must be a string containing the file name.");
nodename = mxArrayToString (prhs[2]);
result = qtr.getNodeV (nodename, voltage);
if (result != 0)
{
mexErrMsgIdAndTxt ( "MATLAB:trsolver:vprobenotfound",
"The voltage probe with name %s was not found.",
nodename );
}
else
{
plhs[0] = mxCreateDoubleMatrix ( (mwSize)(1), (mwSize)(1), mxREAL);
outpointer = mxGetPr (plhs[0]);
outpointer[0] = (double)voltage;
}
}