Solved

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

Posted on 2003-10-31
20
853 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org Go to that link and select download selenium in the right hand columnThat will then direct you to their download page.From that page s…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

912 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

26 Experts available now in Live!

Get 1:1 Help Now