visual c++ - Copying objects in C++/CLI and message passing in multithreading -


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