i'm trying transfer command line code have more visual program a
gui enable easier use. original code in c++, i'm using visual c++ is
available in visual studio express 2012, have problems understanding "new"
managed c++/cli way of handling objects. being new cli , managed c++, wondering
if can explain doing wrong, , why doesn't work. here a
description of code , problem.
the program optimization program:
- there multiple boxes (modes) in system, each mode, depending on type has a
few numerical coefficients control behavior , way responds outside
excitation. - the program asks user specify number of boxes , type of each box.
- then tries find numerical coefficients minimize difference between
system response obtained experimentally.
so, ui has means user open experimental result files, specify number
of modes, , specify type of each mode. then, user can initiate processing
function clicking on start button, initiates background worker.
following example given in msdn, created class performs work:
ref class curvefit { public: ref class currentstate{ public: int percentage; int iterationno; int stage; bool done; multimode systemmodel; }; public: int modes; int returncode; array<double> ^expexcitations; array<double> ^expresults; multimode systemmodel; private: void fcn(int, int, double*, double*, int*); double totalerror(std::vector<double> &); public: delegate void fcndelegate(int, int, double*, double*, int*); public: curvefit(void); curvefit^ fit(system::componentmodel::backgroundworker^, system::componentmodel::doworkeventargs^, options^); };
multimode
container class: list of different boxes.
ref class multimode { private: collections::generic::list<genericboxmodel ^>^ models; int modes; public: multimode(void); multimode(const multimode%); int modeno(void); void add(genericboxmodel^); void clear(); genericboxmodel^ operator[](int); multimode% operator=(const multimode%); double result(double); bool isvalid(); std::vector<double> mapdata(); void mapdata(std::vector<double> &); }; multimode::multimode(void) { models = gcnew collections::generic::list<genericboxmodel ^>(); modes = 0; } multimode::multimode(const multimode% rhs) { models = gcnew collections::generic::list<genericboxmodel ^>(); for(int ind = 0; ind < rhs.modes; ind++) models->add(rhs.models[ind]); modes = rhs.modes; } int multimode::modeno(void) { return modes; } void multimode::add(genericboxmodel^ model) { models->add(model); modes++; } void multimode::clear() { models->clear(); modes = 0; } genericboxmodel^ multimode::operator[](int ind) { return models[ind]; } multimode% multimode::operator=(const multimode% rhs) { models->clear(); for(int ind = 0; ind < rhs.modes; ind++) models->add(rhs.models[ind]); modes = rhs.modes; return *this; } double multimode::result(double excitation) { double temp = 0.0; for(int ind = 0; ind < modes; ind++) temp += models[ind]->result(excitation); return temp; } bool multimode::isvalid() { bool isvalid = true; if(modes < 1) return false; for(int ind = 0; ind < modes; ind++) isvalid = (isvalid && models[ind]->isvalid()); return isvalid; } std::vector<double> multimode::fullmap() { //map model coefficients vector of doubles ... } void multimode::fullmap(std::vector<double> &data) { //map vector of doubles model coefficients ... }
and genericboxmodel
abstract class box models based on.
the curvefit::fit
function optimization based on options passed it:
curvefit^ curvefit::fit(system::componentmodel::backgroundworker^ worker, system::componentmodel::doworkeventargs^ e, options^ opts) { fcndelegate^ del = gcnew fcndelegate(this, &curvefit::fcn); std::vector<double> data; currentstate^ state = gcnew currentstate; state->done = false; state->stage = 0; state->percentage = 0; state->systemmodel = systemmodel; worker->reportprogress(state->percentage, state); switch(opts->optimizationmethod) { case 0: while(iterationno < maxiterations) { data = systemmodel.mapdata(); optimizationmethod0::step(some_parameters, data, (optmethods::costfunction)runtime::interopservices::marshal::getfunctionpointerfordelegate(del).topointer()); systemmodel.mapdata(data); iterationno++; state->percentage = 0; state->systemmodel = systemmodel; worker->reportprogress(state->percentage, state); } ... } }
i'm passing system model inside state can display results of the
latest step on screen, doesn't work, question :-)
the start button calls curvefit::fit
function after initializing system model:
private: system::void btnstart_click(system::object^ sender, system::eventargs^ e) { systemmodel.clear(); for(int mode = 0; mode < modes; mode++) { switch(model) { case 0: systemmodel.add(gcnew model0); systemmodel[mode]->coefficients[0] = 100.0 / double(mode + 1); ... break; ... } } btnstart->enabled = false; ststatustext->text = "calculating!"; application::usewaitcursor = true; curvefit^ cf = gcnew curvefit; fitcurve->runworkerasync(cf); } private: system::void fitcurve_dowork(system::object^ sender, system::componentmodel::doworkeventargs^ e) { system::componentmodel::backgroundworker^ worker; worker = dynamic_cast<system::componentmodel::backgroundworker^>(sender); curvefit^ cf = safe_cast<curvefit^>(e->argument); cf->expexcitations = gcnew array<double>(expexcitations.count); expexcitations.copyto(cf->expexcitations); cf->expresults = gcnew array<double>(expresults.count); expresults.copyto(cf->expresults); cf->systemmodel = systemmodel; cf->modes = modes; e->result = cf->fit(worker, e, options); }
this works perfectly! but, in order make optimization process faster , more
successful, wanted use results of previous optimizations initial guess
next run (if possible):
multimode oldmodel(systemmodel); systemmodel.clear(); for(int mode = 0; mode < modes; mode++) { switch(model) { case 0: if(mode < oldmodel.modeno() && oldmodel.isvalid() && (oldmodel[mode]->model == 0)) systemmodel.add(oldmodel[mode]); else { systemmodel.add(gcnew model0); systemmodel[mode]->coefficients[0] = 100.0 / double(mode + 1); ... } break; ...
now, problem is, after change, seems messages don't passed
correctly: first time start button clicked functions should,
on, if statement systemmodel.add(oldmodel[mode]);
gets executed,
results remain same initial guesses, , don't updated after fit
function called.
so, why should these 2 lines(add(oldmodel[mode])
, add(gcnew model0)
) give
such different results?
Comments
Post a Comment