Solved

Pulling subclasses of a superclass off of a vector....

Posted on 2003-10-31
20
852 Views
Last Modified: 2013-12-14

My problem is the following:

I define a superclass GapFunction, which is meant to encompass families of probability distributions. Those distributions (gaussian, multinomial, etc.) are subclassed to GapFunction and overload a method or two.

Within MMotif (reproduced below), I define vector<GapFunction> gaps, and then proceed to push on various subclasses of GapFunction on to it. However, when I pull them off the vector and call a method, it defaults to the skeleton methods in GapFunction, rather than the overloaded methods defined in the various subclasses. In Java, I would cast the pulled-off object to the subclass and go from there, but in C++ I am somewhat lost. All help appreciated...Antonio.

class MMotif{
public:
  vector<PWM> pwms;
  PWM backgr;
  vector<Multinomial> gaps;
  string MATRIX_DEL;
  string FUNC_DEL;
  static int const MMotif::maxlength=1000;
  static int const MMotif::minlength=1;
  /*MMotif(const vector<PWM>& p,
         const vector<GapFunction>& g) {
    if (p.size() != g.size() + 1) {
      std::cout << "PWMs and GapFunctions not numbered accordingly" << std::endl;

    } else {
      pwms.assign(p.begin(), p.end());  // no need for a loop; use stl
      gaps.assign(g.begin(), g.end());
    }
   
    }*/
  MMotif(char *name){
    MATRIX_DEL="M";
    FUNC_DEL="F";
    Multinomial m1(MMotif.min, MMotif.max);
    gaps.push_back(m1);
    //cout << "multinomial nullity is " << gaps[0].isFree()<<endl;
    ifstream readFile(name, ios::in);
    char s[100];     // declares variable to read data from file
    vector<string> matrixlines;
    bool matricing=false;
    bool done=false;
     while(!done) {
       //       cout << readFile.eof() << endl;
       readFile.getline(s, 100);
        string line(s);
        // cout << line << endl;
        string buf; // Have a buffer string
        stringstream ss(line); //insert the string into a stream
     
        vector<string> tokens; // Create vector to hold our words
     
        while (ss >> buf){
          tokens.push_back(buf);
        }
        //string::size_type firstwhitespace=line.find_first_of(" ", 0);
        //string type=line.substr(0, firstwhitespace);
        //string trunc_line=line.substr(firstwhitespace, line.size());
        string type=tokens[0];
        
        if(matricing){
          if(type==MATRIX_DEL){
            PWM pwm(matrixlines);
            pwms.push_back(pwm);
            matricing=false;
            matrixlines.erase(matrixlines.begin(), matrixlines.end());
            //            cout << "erase matrices\n";
          }
          else{
            matrixlines.push_back(line);
          }
        }else if(type==FUNC_DEL){
          //string::size_type firstwhitespace=trunc_line.find_first_of(" ", 0);
          string tok1=tokens[1];
          int functype=(int)strtol(tok1.c_str(), NULL, 10);
          //          cout << "adding function\n";
          vector<double> args;
          int start=(int) strtol(tokens[2].c_str(), NULL, 10);
          for(int i=3; i<tokens.size(); i++){
            args.push_back(strtod(tokens[3].c_str(), NULL));
          }
          if(functype==0){
            Multinomial m(start, args);
            gaps.push_back(m);
          }         
          //    else if(functype==1){
          // Gaussian g(strtod(tokens[2].c_str(), NULL), strtod(tokens[3].c_str(), NULL));
          // gaps.push_back(g);
          //}
        }
        else if(type==MATRIX_DEL){
          //cout << "matricing\n";
          matricing=true;
        }
        else if(type=="E"){
          //cout << "done sucking in\n";
          done=true;
        }
        //cout << "end of while\n";
     }
     //cout << "finished reading file\n";
     Multinomial m2(min, max);
     gaps.push_back(m2);
     //cout << "nullity at end is "<< gaps[gaps.size()-1].isFree() << endl;
     readFile.close();
  }

0
Comment
Question by:antoniogm
20 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 9659139
>>I would cast the pulled-off object to the subclass and go from there, but in C++ I am somewhat lost

In C++, you'd make the 'GapFunction' methods 'virtual' in order to achieve the desired effect.
0
 
LVL 19

Expert Comment

by:Dexstar
ID: 9659145
antoniogm:

> Within MMotif (reproduced below), I define vector<GapFunction> gaps, and then
> proceed to push on various subclasses of GapFunction on to it. However, when
> I pull them off the vector and call a method, it defaults to the skeleton
> methods in GapFunction, rather than the overloaded methods defined in the
> various subclasses. In Java, I would cast the pulled-off object to the subclass
> and go from there, but in C++ I am somewhat lost. All help appreciated...Antonio.

In C++, when you want to overload a method, you have to declare that method as being "virtual".  If you've already done that, then post the class definitions for GapFunction and Multinomial.

BTW, you said that declared "vector<GapFunction> gaps", but I see "vector<Multinomial> gaps".  Which is it supposed to be?

Hope that helps,
Dex*
0
 
LVL 86

Expert Comment

by:jkr
ID: 9659146
Lil' explanation from the VC++ docs:

Virtual Function
C++ Specific —>

A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.

END C++ Specific

Example 1

class WageEmployee
{
public:
   virtual float computePay();
};

class SalesPerson : public WageEmployee
{
public:
   float computePay();
};
You can execute different versions of computePay( ) depending on the type of object you're calling it for.

Example 2

WageEmployee aWorker;
SalesPerson aSeller;
WageEmployee *wagePtr;

wagePtr = &aWorker;
wagePtr->computePay();   // call WageEmployee::computePay
wagePtr = &aSeller;
wagePtr->computePay();   // call SalesPerson::computePay
The virtual keyword is needed only in the base class's declaration of the function; any subsequent declarations in derived classes are virtual by default.

A derived class's version of a virtual function must have the same parameter list and return type as those of the base class. If these are different, the function is not considered a redefinition of the virtual function. A redefined virtual function cannot differ from the original only by return type.
0
 
LVL 10

Expert Comment

by:Sys_Prog
ID: 9659334
Here's is a similar kind of question and some useful discussion on the same

http://experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_20783912.html


Hope this helps
0
 

Author Comment

by:antoniogm
ID: 9660553
I still get compilation errors. I am posting GapFunction.h,  Null.h ( a null prob. dist. that always returns 0.0, and with maximal range of inputs), and the new MMotif.h.


#ifndef GF_FLAG
#define GF_FLAG
#include <iostream>
#include <string>
class GapFunction{
public:

  virtual double func(int i);
  virtual int lowerBound();
  virtual int upperBound();

};
#endif

#ifndef NULL_FLAG
#define NULL_FLAG
#include <iostream>
#include <string>
#include "GapFunction.h"
#include <math.h>
#include <vector>
#include <limits.h>

class Null: public GapFunction
{
 public:
  Null(){;}
  double func(int i){
    return 0.0;
  }
  int lowerBound(){
    cout << "calling lowerbound in null\n";
    return 1;
  }
  int upperBound(){
    return INT_MAX;
  }
};
#endif

#include <string>
#include <map>
#include <math.h>
#include <vector>
//#include <ot/util/StringTokenizer.h>
#include "PWM.h"
#include "GapFunction.h"
#include "Gaussian.h"
#include "Free.h"
#include "Multinomial.h"
#include "Null.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <limits.h>

using namespace std;
class MMotif{
public:
  vector<PWM> pwms;
  PWM backgr;
  vector<GapFunction> gaps;
  string MATRIX_DEL;
  string FUNC_DEL;
  static int const MMotif::maxlength=1000;
  static int const MMotif::minlength=1;
  /*MMotif(const vector<PWM>& p,
         const vector<GapFunction>& g) {
    if (p.size() != g.size() + 1) {
      std::cout << "PWMs and GapFunctions not numbered accordingly" << std::endl;

    } else {
      pwms.assign(p.begin(), p.end());  // no need for a loop; use stl
      gaps.assign(g.begin(), g.end());
    }
   
    }*/
  MMotif(char *name){
    MATRIX_DEL="M";
    FUNC_DEL="F";
    Null n1;
    gaps.push_back(n1);
    //cout << "multinomial nullity is " << gaps[0].isFree()<<endl;
    ifstream readFile(name, ios::in);
    char s[100];     // declares variable to read data from file
    vector<string> matrixlines;
    bool matricing=false;
    bool done=false;
     while(!done) {
       //       cout << readFile.eof() << endl;
       readFile.getline(s, 100);
        string line(s);
        // cout << line << endl;
        string buf; // Have a buffer string
        stringstream ss(line); //insert the string into a stream
     
        vector<string> tokens; // Create vector to hold our words
     
        while (ss >> buf){
          tokens.push_back(buf);
        }
        //string::size_type firstwhitespace=line.find_first_of(" ", 0);
        //string type=line.substr(0, firstwhitespace);
        //string trunc_line=line.substr(firstwhitespace, line.size());
        string type=tokens[0];
        
        if(matricing){
          if(type==MATRIX_DEL){
            PWM pwm(matrixlines);
            pwms.push_back(pwm);
            matricing=false;
            matrixlines.erase(matrixlines.begin(), matrixlines.end());
            //            cout << "erase matrices\n";
          }
          else{
            matrixlines.push_back(line);
          }
        }else if(type==FUNC_DEL){
          //string::size_type firstwhitespace=trunc_line.find_first_of(" ", 0);
          string tok1=tokens[1];
          int functype=(int)strtol(tok1.c_str(), NULL, 10);
          //          cout << "adding function\n";
          vector<double> args;
          int start=(int) strtol(tokens[2].c_str(), NULL, 10);
          for(int i=3; i<tokens.size(); i++){
            args.push_back(strtod(tokens[3].c_str(), NULL));
          }
          if(functype==0){
            Multinomial m(start, args);
            gaps.push_back(m);
          }         
              else if(functype==1){
           Gaussian g(strtod(tokens[2].c_str(), NULL), strtod(tokens[3].c_str(), NULL));
           gaps.push_back(g);
          }
        }
        else if(type==MATRIX_DEL){
          //cout << "matricing\n";
          matricing=true;
        }
        else if(type=="E"){
          //cout << "done sucking in\n";
          done=true;
        }
        //cout << "end of while\n";
     }
     //cout << "finished reading file\n";
     Null n2;
     gaps.push_back(n2);
     //cout << "nullity at end is "<< gaps[gaps.size()-1].isFree() << endl;
     readFile.close();
  }
  double scoreSeq(const std::string str){
    return score(pwms.size()-1, gaps.size()-1, str);
  }
        
            
            
  double score(int m, int g, const std::string& str){
   
    cout << "running with motif " << m<< " gap " << g << " str  " << str << endl;
    if(g==0){
      cout << "in last gap"<<endl;
      return 0.0;
    }
    else if(str.length()==0){
      cout << "string ended\n";
      return -10000;
    }
    else{
      if(g==m+1){

      cout <<"in gap mode with gaps " << gaps.size()<< "\n";
      int lower=gaps[g].lowerBound();
      int upper=gaps[g].upperBound();
      
      double max=-10000;
      double gapvalue=-10000;
      
      cout << " lower upper " << lower << " " << upper << endl;
      for(int i=lower; i<=upper; i++){
        gapvalue=gaps[g].func(i) + score(m, g-1, str.substr(i, str.length()-1));
        cout << "value at gap "<< i << " " << gapvalue << endl;
        if(gapvalue>max){
            //      cout<< "doing comparison\n";
          max=gapvalue;
        }
      }
      return max;
      
      }else if(g==m){
      
      
      double pwmvalue=-10000;
      pwmvalue=pwms[m].score( str.substr(0, pwms[m].length() ) )
        + this->score( m-1, g, str.substr(pwms[m].length(), str.length()-pwms[m].length()));
      return pwmvalue;
      }
     
     
      /*if(pwmvalue>gapvalue){
        cout<< "went with the pwm\n";
         return pwmvalue;
      }else{
         cout<< "went with the gap\n";
         return gapvalue;
      }  
      
          //cout << gaps[l].func(k)<< endl;
          //cout << pwms[l].score( str.substr(0, pwms[l].length() ) )<< endl;
          return MMotif::max(
                 
          gaps[l].func(k + 1 ) - gaps[l].func(k)+ score(l, k + 1, str.substr(1, str.length()-1)),
          pwms[l].score(str.substr(0, pwms[l].length() ) )
                 
          
          + this->score( l - 1, 0, str.substr(pwms[l].length(), str.length()-pwms[l].length()))
          ); //  max
          
          }*/
    }
     
  }
    double max(double first, double second){
      if(first>=second){
      cout << "returning first arg " << first << endl;
      return first;
    }else{
      cout << "returning second arg " << second << endl;
      return second;
    }
  }
     private:
 

};




0
 
LVL 86

Expert Comment

by:jkr
ID: 9660565
>>I still get compilation errors

Um, my crystal ball is still on repair - what errors?
0
 

Author Comment

by:antoniogm
ID: 9660596
g++ score.cpp
/tmp/ccSDUD7r.o(.gnu.linkonce.d.__vt_8Gaussian+0x8): undefined reference to `GapFunction::func(int)'
/tmp/ccSDUD7r.o(.gnu.linkonce.d.__vt_8Gaussian+0xc): undefined reference to `GapFunction::lowerBound(void)'
/tmp/ccSDUD7r.o(.gnu.linkonce.d.__vt_8Gaussian+0x10): undefined reference to `GapFunction::upperBound(void)'
/tmp/ccSDUD7r.o: In function `GapFunction::GapFunction(void)':
/tmp/ccSDUD7r.o(.GapFunction::gnu.linkonce.t.(void)+0x8): undefined reference to `GapFunction virtual table'
/tmp/ccSDUD7r.o: In function `GapFunction::GapFunction(GapFunction const &)':
/tmp/ccSDUD7r.o(.GapFunction::gnu.linkonce.t.(GapFunction const &)+0xb): undefined reference to `GapFunction virtual table'
/tmp/ccSDUD7r.o: In function `Gaussian type_info function':
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf8Gaussian+0x10): undefined reference to `GapFunction type_info function'
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf8Gaussian+0x18): undefined reference to `GapFunction type_info node'
/tmp/ccSDUD7r.o: In function `Multinomial type_info function':
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf11Multinomial+0x10): undefined reference to `GapFunction type_info function'
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf11Multinomial+0x18): undefined reference to `GapFunction type_info node'
/tmp/ccSDUD7r.o: In function `Null type_info function':
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf4Null+0x10): undefined reference to `GapFunction type_info function'
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf4Null+0x18): undefined reference to `GapFunction type_info node'
collect2: ld returned 1 exit status


To me at least, not particularly informative....
0
 
LVL 86

Expert Comment

by:jkr
ID: 9660625
Even though the 'GapFunction' members do nothing, they either have to be 'pure virtual' or you have to provide a minimal implementation, e.g.

// minimal impl.
class GapFunction{
public:

 virtual double func(int i) { return 0.0;};
 virtual int lowerBound() { return 0;};
 virtual int upperBound(){ return 0;};
};

// pure virtual
class GapFunction{
public:

 virtual double func(int i) = 0;
 virtual int lowerBound() = 0;
 virtual int upperBound() = 0;
};
0
 

Author Comment

by:antoniogm
ID: 9660710
I made the above changes, and now get something of the form:

cd /home/agm/C++/MPattern/
g++ score.cpp
/usr/include/g++-3/stl_construct.h: In function `void construct (_T1 *,
const _T2 &) [with _T1 = GapFunction, _T2 = GapFunction]':
/usr/include/g++-3/stl_vector.h:321:   instantiated from `vector<_Tp, _Alloc>::push_back (const _Tp &) [with _Tp = GapFunction, _Alloc = allocator<GapFunction>]'
MMotif.h:42:   instantiated from here
/usr/include/g++-3/stl_construct.h:48: cannot allocate an object of
type `GapFunction'
/usr/include/g++-3/stl_construct.h:48:   since the following virtual
functions are abstract:
GapFunction.h:10:       int GapFunction::upperBound ()
GapFunction.h:9:       int GapFunction::lowerBound ()
GapFunction.h:8:       double GapFunction::func (int)
/usr/include/g++-3/stl_vector.h: In method `void vector<_Tp,
_Alloc>::_M_insert_aux (_Tp *, const _Tp &) [with _Tp = GapFunction,
_Alloc = allocator<GapFunction>]':
/usr/include/g++-3/stl_vector.h:325:   instantiated from `vector<_Tp, _Alloc>::push_back (const _Tp &) [with _Tp = GapFunction, _Alloc = allocator<GapFunction>]'
MMotif.h:42:   instantiated from here
/usr/include/g++-3/stl_vector.h:593: cannot declare variable `__x_copy'
to be of type `GapFunction'
/usr/include/g++-3/stl_vector.h:593:   since type `GapFunction' has
abstract virtual functions
/usr/include/g++-3/stl_vector.h:593: cannot allocate an object of type
`GapFunction'
/usr/include/g++-3/stl_vector.h:593:   since type `GapFunction' has
abstract virtual functions

0
 
LVL 86

Expert Comment

by:jkr
ID: 9660729
OK, I forgot about that - this way, you should use the "minimal" approach
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:antoniogm
ID: 9660907
Ok, the hackery works now and the compiler doesn't complain, but I am still getting the same fundamental error of the function call going to the superclass rather than the subclass. The below test script:

#include <iostream>
#include "Null.h"
using namespace std;
void main(){
  Null n;
  cout<< n.lowerBound()<<endl;
  cout<< n.upperBound()<<endl;
  vector<GapFunction> gaps;
  gaps.push_back(n);
  cout<<gaps[0].lowerBound()<< endl;
   

}

returns:

1
2147483647
0


0
 
LVL 86

Expert Comment

by:jkr
ID: 9660940
Make it read

include <iostream>
#include "Null.h"
using namespace std;
void main(){
 Null n;
 cout<< n.lowerBound()<<endl;
 cout<< n.upperBound()<<endl;
 vector<GapFunction&> gaps; // <--!!!
 gaps.push_back(n);
 cout<<gaps[0].lowerBound()<< endl;
}

As the above explanation says:

"A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function."

As you were storing instances of 'GapFunction' objects and not pointers or references, you were still calling the base class member functions.
0
 

Author Comment

by:antoniogm
ID: 9660976

I do that and get:

cd /home/agm/C++/MPattern/
g++ test2.cpp
/usr/include/g++-3/stl_vector.h: In instantiation of `_Vector_alloc_base<GapFunction &, allocator<GapFunction &>, true>':
test2.cpp:8:   instantiated from `_Vector_base<GapFunction &, allocator<GapFunction &> >'
test2.cpp:8:   instantiated from `vector<GapFunction &, allocator<GapFunction &> >'
test2.cpp:8:   instantiated from here
/usr/include/g++-3/stl_vector.h:87: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:88: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:89: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:93: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:95: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h: In instantiation of `vector<GapFunction &, allocator<GapFunction &> >':
test2.cpp:8:   instantiated from here
/usr/include/g++-3/stl_vector.h:159: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:160: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:161: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:162: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:163: forming reference to reference
type `GapFunction &'
/usr/include/g++-3/stl_vector.h:164: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:172: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:172: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:173: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:173: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:589: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:621: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:195: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:196: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:197: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:198: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:201: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:201: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:203: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:203: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:205: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:205: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:207: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:207: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:218: forming reference to reference
type `GapFunction &'
/usr/include/g++-3/stl_vector.h:219: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:226: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:530: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:314: forming reference to reference
type `GapFunction &'
/usr/include/g++-3/stl_vector.h:315: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:316: forming reference to reference
type `GapFunction &'
/usr/include/g++-3/stl_vector.h:317: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:319: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:341: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:351: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:364: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:364: confused by earlier errors,
bailing out

Compilation exited abnormally with code 1 at Fri Oct 31 15:40:19


0
 

Author Comment

by:antoniogm
ID: 9660994
Look, at this point maybe we need faster communication to resolve this rather than bouncing slowly via the site. I am antoniofgm on aim, or malvoglio on ymessenger. Or email me directly at agm at socrates.berkeley.edu
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 9661003
Hm, that is weird, gcc is supposed to support that. Well, then, the pointer approach

include <iostream>
#include "Null.h"
using namespace std;
void main(){
Null n;
cout<< n.lowerBound()<<endl;
cout<< n.upperBound()<<endl;
vector<GapFunction*> gaps; // <--!!!
gaps.push_back(&n); // <--!!!
cout<<gaps[0]->lowerBound()<< endl; // <--!!!
}

0
 
LVL 86

Expert Comment

by:jkr
ID: 9661015
Sorry, direct email is against the site rules :o)
0
 

Author Comment

by:antoniogm
ID: 9661019
Pointer approach worked. Thanks so much for your time and instantaneous responses...500 points on the way.
0
 

Author Comment

by:antoniogm
ID: 9661167
Just never ends....

Now it throws a segmentation fault. Seems like it doesnt' like calling functions on objects from the vector. Note that I do a test at the end of the constructor to see that the Null GapFunction works. But then later does not work inside of score()....

class MMotif{
public:
  vector<PWM> pwms;
  PWM backgr;
  vector<GapFunction*> gaps;
  string MATRIX_DEL;
  string FUNC_DEL;
  static int const MMotif::maxlength=1000;
  static int const MMotif::minlength=1;
  /*MMotif(const vector<PWM>& p,
         const vector<GapFunction>& g) {
    if (p.size() != g.size() + 1) {
      std::cout << "PWMs and GapFunctions not numbered accordingly" << std::endl;

    } else {
      pwms.assign(p.begin(), p.end());  // no need for a loop; use stl
      gaps.assign(g.begin(), g.end());
    }
   
    }*/
  MMotif(char *name){
    MATRIX_DEL="M";
    FUNC_DEL="F";
    Null n1;
    gaps.push_back(&n1);
    //cout << "multinomial nullity is " << gaps[0].isFree()<<endl;
    ifstream readFile(name, ios::in);
    char s[100];     // declares variable to read data from file
    vector<string> matrixlines;
    bool matricing=false;
    bool done=false;
     while(!done) {
       //       cout << readFile.eof() << endl;
       readFile.getline(s, 100);
        string line(s);
        // cout << line << endl;
        string buf; // Have a buffer string
        stringstream ss(line); //insert the string into a stream
     
        vector<string> tokens; // Create vector to hold our words
     
        while (ss >> buf){
          tokens.push_back(buf);
        }
        //string::size_type firstwhitespace=line.find_first_of(" ", 0);
        //string type=line.substr(0, firstwhitespace);
        //string trunc_line=line.substr(firstwhitespace, line.size());
        string type=tokens[0];
        
        if(matricing){
          if(type==MATRIX_DEL){
            PWM pwm(matrixlines);
            pwms.push_back(pwm);
            matricing=false;
            matrixlines.erase(matrixlines.begin(), matrixlines.end());
            //            cout << "erase matrices\n";
          }
          else{
            matrixlines.push_back(line);
          }
        }else if(type==FUNC_DEL){
          //string::size_type firstwhitespace=trunc_line.find_first_of(" ", 0);
          string tok1=tokens[1];
          int functype=(int)strtol(tok1.c_str(), NULL, 10);
          //          cout << "adding function\n";
          vector<double> args;
          int start=(int) strtol(tokens[2].c_str(), NULL, 10);
          for(int i=3; i<tokens.size(); i++){
            args.push_back(strtod(tokens[3].c_str(), NULL));
          }
          if(functype==0){
            Multinomial m(start, args);
            gaps.push_back(&m);
          }         
               else if(functype==1){
               Gaussian g((int) strtod(tokens[2].c_str(), NULL), strtod(tokens[3].c_str(), NULL), (int)strtod(tokens[4].c_str(), NULL), (int)strtod(tokens[5].c_str(), NULL));
           gaps.push_back(&g);
             }
        }
        else if(type==MATRIX_DEL){
          //cout << "matricing\n";
          matricing=true;
        }
        else if(type=="E"){
          //cout << "done sucking in\n";
          done=true;
        }
        //cout << "end of while\n";
     }
     //cout << "finished reading file\n";
     Null n2;
     gaps.push_back(&n2);
     cout << "gap at end is " << gaps[gaps.size()-1]->func(0) << endl;
     readFile.close();
  }
  double scoreSeq(const std::string str){
    return score(pwms.size()-1, gaps.size()-1, str);
  }
        
            
            
  double score(int m, int g, const std::string& str){
   
    cout << "running with motif " << m<< " gap " << g << " str  " << str << endl;
    if(g==0){
      cout << "in last gap"<<endl;
      return 0.0;
    }
    else if(str.length()==0){
      cout << "string ended\n";
      return -10000;
    }
    else{
      if(g==m+1){

      cout <<"in gap mode with gaps " << g << "and no of gaps "<<gaps.size()<<"\n";
      gaps[0]->func(0);
      cout << "finished stupid thing\n";
      cout<<gaps[0]->lowerBound()<<endl;
      int lower=gaps[g]->lowerBound();
      int upper=gaps[g]->upperBound();
      
      double max=-10000;
      double gapvalue=-10000;
      
      cout << " lower upper " << lower << " " << upper << endl;
      for(int i=lower; i<=upper; i++){
        gapvalue=gaps[g]->func(i) + score(m, g-1, str.substr(i, str.length()-1));
        cout << "value at gap "<< i << " " << gapvalue << endl;
        if(gapvalue>max){
            //      cout<< "doing comparison\n";
          max=gapvalue;
        }
      }
      return max;
      
      }else if(g==m){
      
      
      double pwmvalue=-10000;
      pwmvalue=pwms[m].score( str.substr(0, pwms[m].length() ) )
        + this->score( m-1, g, str.substr(pwms[m].length(), str.length()-pwms[m].length()));
      return pwmvalue;
      }
     
     
      /*if(pwmvalue>gapvalue){
        cout<< "went with the pwm\n";
         return pwmvalue;
      }else{
         cout<< "went with the gap\n";
         return gapvalue;
      }  
      
          //cout << gaps[l].func(k)<< endl;
          //cout << pwms[l].score( str.substr(0, pwms[l].length() ) )<< endl;
          return MMotif::max(
                 
          gaps[l].func(k + 1 ) - gaps[l].func(k)+ score(l, k + 1, str.substr(1, str.length()-1)),
          pwms[l].score(str.substr(0, pwms[l].length() ) )
                 
          
          + this->score( l - 1, 0, str.substr(pwms[l].length(), str.length()-pwms[l].length()))
          ); //  max
          
          }*/
    }
     
  }
    double max(double first, double second){
      if(first>=second){
      cout << "returning first arg " << first << endl;
      return first;
    }else{
      cout << "returning second arg " << second << endl;
      return second;
    }
  }
     private:
 

};


produces

gap at end is 0
running with motif 1 gap 2 str  AGCTAAAAGCT
Segmentation fault
0
 
LVL 86

Expert Comment

by:jkr
ID: 9661839
Hope you don't mind if I check that tomorrow, but it's about 1am here&now :o)
0
 

Author Comment

by:antoniogm
ID: 9668677
I am afraid I rather need an answer quickly. I am reposting a question with the new code...feel free to respond.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org (http://seleniumhq.org) Go to that link and select download selenium in the right hand columnThat will then direct you to their downlo…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now