コード例 #1
0
ファイル: pgm.cpp プロジェクト: bekaus/pgmlink
    ////
    //// class FactorEntry
    ////
    void FactorEntry::set( OpengmModel::ValueType v ) {
      if( entry_ == NULL ) {
	throw runtime_error("FactorEntry: is invalid");
      }
      *entry_ = v;
    }
コード例 #2
0
void
any_l4 (gfc_array_l4 *retarray, gfc_array_l4 *array, index_type *pdim)
{
  index_type count[GFC_MAX_DIMENSIONS];
  index_type extent[GFC_MAX_DIMENSIONS];
  index_type sstride[GFC_MAX_DIMENSIONS];
  index_type dstride[GFC_MAX_DIMENSIONS];
  GFC_LOGICAL_4 *base;
  GFC_LOGICAL_4 *dest;
  index_type rank;
  index_type n;
  index_type len;
  index_type delta;
  index_type dim;

  /* Make dim zero based to avoid confusion.  */
  dim = (*pdim) - 1;
  rank = GFC_DESCRIPTOR_RANK (array) - 1;

  /* TODO:  It should be a front end job to correctly set the strides.  */

  if (array->dim[0].stride == 0)
    array->dim[0].stride = 1;

  len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
  delta = array->dim[dim].stride;

  for (n = 0; n < dim; n++)
    {
      sstride[n] = array->dim[n].stride;
      extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
    }
  for (n = dim; n < rank; n++)
    {
      sstride[n] = array->dim[n + 1].stride;
      extent[n] =
        array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
    }

  if (retarray->data == NULL)
    {
      for (n = 0; n < rank; n++)
        {
          retarray->dim[n].lbound = 0;
          retarray->dim[n].ubound = extent[n]-1;
          if (n == 0)
            retarray->dim[n].stride = 1;
          else
            retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1];
        }

      retarray->data
	 = internal_malloc_size (sizeof (GFC_LOGICAL_4)
		 		 * retarray->dim[rank-1].stride
				 * extent[rank-1]);
      retarray->base = 0;
      retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
    }
  else
    {
      if (retarray->dim[0].stride == 0)
	retarray->dim[0].stride = 1;

      if (rank != GFC_DESCRIPTOR_RANK (retarray))
	runtime_error ("rank of return array incorrect");
    }

  for (n = 0; n < rank; n++)
    {
      count[n] = 0;
      dstride[n] = retarray->dim[n].stride;
      if (extent[n] <= 0)
        len = 0;
    }

  base = array->data;
  dest = retarray->data;

  while (base)
    {
      GFC_LOGICAL_4 *src;
      GFC_LOGICAL_4 result;
      src = base;
      {

  result = 0;
        if (len <= 0)
	  *dest = 0;
	else
	  {
	    for (n = 0; n < len; n++, src += delta)
	      {

  /* Return true if any of the elements are set.  */
  if (*src)
    {
      result = 1;
      break;
    }
          }
	    *dest = result;
	  }
      }
      /* Advance to the next element.  */
      count[0]++;
      base += sstride[0];
      dest += dstride[0];
      n = 0;
      while (count[n] == extent[n])
        {
          /* When we get to the end of a dimension, reset it and increment
             the next dimension.  */
          count[n] = 0;
          /* We could precalculate these products, but this is a less
             frequently used path so proabably not worth it.  */
          base -= sstride[n] * extent[n];
          dest -= dstride[n] * extent[n];
          n++;
          if (n == rank)
            {
              /* Break out of the look.  */
              base = NULL;
              break;
            }
          else
            {
              count[n]++;
              base += sstride[n];
              dest += dstride[n];
            }
        }
    }
}
コード例 #3
0
void FixedWidthGenerator::generateCode(const std::string filename,
        const std::string& fontName)
{
    if(log) *logStream<<"Font is fixed width"<<endl;
    unsigned int height=glyphs.at(0).getHeight();
    unsigned int width=glyphs.at(0).getWidth();
    const bool aa=glyphs.at(0).isAntialiased();
    if(aa && log) *logStream<<"Font is antialiased"<<endl;

    file.open(filename.c_str());
    file<<showbase;//So that it will print 0x in front of hexadecimal numbers
    //Write header part
    file<<"#ifndef FONT_"<<toUpper(fontName)<<"_H\n"<<
          "#define FONT_"<<toUpper(fontName)<<"_H\n"<<
          "//This font has been converted from BDF/TTF font format to .h\n"<<
          "//using fontrendering utility written by Terraneo Federico.\n"<<
          "//Do not modify this file, it has been automatically generated.\n\n";

    //Calculate how many bits are necessary to store a row of a glyph
    int roundedHeight;//Height rounded to 8, 16 or 32
    if(height<=8) roundedHeight=8;
    else if(height<=16) roundedHeight=16;
    else if(height<=32) roundedHeight=32;
    else  throw(runtime_error("Character is too high for code generation."
                " Maximum allowed is 32bit"));
    if(aa) roundedHeight*=2;
    
    //Write font info data
    file<<"const bool "<<fontName<<"IsAntialiased="<<(aa?"true;\n":"false;\n")<<
          "const bool "<<fontName<<"IsFixedWidth=true;\n"<<
          "const unsigned char "<<fontName<<"StartChar="<<static_cast<int>(
            glyphs.at(0).getASCII())<<";\n"<<
          "const unsigned char "<<fontName<<"EndChar="<<static_cast<int>(
            glyphs.at(glyphs.size()-1).getASCII())<<";\n"<<
          "const unsigned char "<<fontName<<"Height="<<height<<";\n"<<
          "const unsigned char "<<fontName<<"Width="<<width<<";\n"<<
          "const unsigned char "<<fontName<<"DataSize="<<roundedHeight<<";\n\n";

    //Write font look up table
    switch(roundedHeight)
    {
        case 8:
            file<<"const unsigned char "<<fontName<<"Data[]["<<width<<"]={\n";
            break;
        case 16:
            file<<"const unsigned short "<<fontName<<"Data[]["<<width<<"]={\n";
            break;
        case 32:
            file<<"const unsigned int "<<fontName<<"Data[]["<<width<<"]={\n";
            break;
        case 64:
            file<<"const unsigned long long "<<fontName<<"Data[]["<<width<<
                    "]={\n";
            break;

    }
    for(int i=0;i<glyphs.size();i++)
    {
        Glyph glyph=glyphs.at(i);
        file<<" { //Ascii "<<static_cast<int>(glyph.getASCII())<<" ( "<<
                glyph.getASCII()<<" )\n  ";
        for(int j=0;j<width;j++)
        {
            unsigned long long column=0;
            for(int k=0;k<height;k++)
            {
                if(aa==false)
                {
                    //if(glyph.getPixelAt(j,k)) column|=1ull<<(roundedHeight-1-k);
                    if(glyph.getPixelAt(j,k)) column|=1ull<<k;
                } else {
                    unsigned char pixel=glyph.getPixelAt(j,k);
                    //if(pixel & 2) column|=1ull<<(roundedHeight-1-2*k);
                    //if(pixel & 1) column|=1ull<<(roundedHeight-1-2*k-1);
                    if(pixel & 2) column|=1ull<<2*k+1;
                    if(pixel & 1) column|=1ull<<2*k;
                }
            }
            if(j!=width-1)
                file<<hex<<column<<dec<<(roundedHeight==64?"ull":"")<<",";
            else file<<hex<<column<<dec<<(roundedHeight==64?"ull":"");
        }
        if(i!=glyphs.size()-1) file<<"\n },\n"; else file<<"\n }\n";
    }

    file<<"};\n";

    //Write last part
    file<<"\n#endif //FONT_"<<toUpper(fontName)<<"_H\n";
    file.close();
}
コード例 #4
0
ファイル: pgm.cpp プロジェクト: bekaus/pgmlink
    OpengmModel::ValueType FactorEntry::get() const {
      if( entry_ == NULL ) {
	throw runtime_error("FactorEntryPtr: is invalid");
      }
      return *entry_;
    } 
コード例 #5
0
ファイル: eprog2.cpp プロジェクト: alucardxlx/polserver-zulu
void EScriptProgram::addToken( const Token& token )
{
    unsigned tokpos = 0;
	if (token.id > 255)
	{
		throw runtime_error( "Trying to write an illegal token" );
	}

    update_dbg_pos( token );
    
    switch(token.type) 
	{
		case TYP_OPERAND: // is variable name, long, double, string lit
			{
				unsigned sympos = 0;
				switch(token.id) {
					case TOK_LONG:
						symbols.append(token.lval, sympos);
						break;
					case TOK_DOUBLE:
						symbols.append(token.dval, sympos);
						break;
					case TOK_STRING: // string literal
						symbols.append(token.tokval(), sympos);
						break;
                    case INS_ADDMEMBER2:
                    case INS_ADDMEMBER_ASSIGN:
                    case TOK_IDENT:  // unclassified (ick)
						symbols.append(token.tokval(), sympos);
						break;
                    case TOK_GLOBALVAR:
                    case TOK_LOCALVAR:
                        sympos = token.lval;
                        break;
                    
                    default:
                        break;
				}
				tokens.append_tok(	StoredToken(token.module, token.id, token.type, sympos),
								&tokpos);
			}
			break;

        case TYP_USERFUNC: // these don't do anything.
            return;

        case TYP_METHOD:
			{
                if(token.id != INS_CALL_METHOD_ID)
                {
				    unsigned sympos = 0;
                    passert( token.tokval() );

                    symbols.append(token.tokval(), sympos);
                
				    tokens.append_tok(
					    StoredToken(token.module,
						    token.id, 
						    static_cast<BTokenType>(token.lval),// # of params, stored in Token.lval, saved in StoredToken.type
						    sympos),
					    &tokpos);
                }
                else
                {
                    
				tokens.append_tok(
					StoredToken(token.module,
                        token.id,
                        static_cast<BTokenType>(token.lval),
                        static_cast<unsigned>(token.dval)),
				    &tokpos);
                    
                }
			}
			break;
        case TYP_FUNC:
			{
				unsigned sympos = 0;
				if (include_debug)
                {
                    if (token.tokval())
                        symbols.append(token.tokval(), sympos);
                }
				tokens.append_tok(
					StoredToken(token.module,
						token.id, 
						static_cast<BTokenType>(token.lval),// function index, stored in Token.lval, saved in StoredToken.type
						sympos),
					&tokpos);
                
			}
			break;
			
		case TYP_RESERVED:
		case TYP_OPERATOR:
		case TYP_UNARY_OPERATOR:
            if (token.id == TOK_ARRAY_SUBSCRIPT)
			{
				// array subscript operators store their
				// array index number in offset
				tokens.append_tok(
					StoredToken( token.module,
					             token.id,
								 token.type,
								 token.lval ) );
			}
            else if (token.id == INS_GET_MEMBER ||
                     token.id == INS_SET_MEMBER ||
                     token.id == INS_SET_MEMBER_CONSUME)
            {
                unsigned sympos = 0;
               	symbols.append(token.tokval(), sympos);
				tokens.append_tok(
					StoredToken(token.module,
                        token.id,
                        token.type,
                        sympos),
				    &tokpos);

            }
			else
			{
				tokens.append_tok(
					StoredToken(token.module,
                        token.id,
                        token.type,
                        token.lval),
				    &tokpos);
			}
			break;
		case TYP_CONTROL:
			switch( token.id )
			{
				case CTRL_MAKELOCAL:
					tokens.append_tok( StoredToken( token.module, 
						                         token.id,
												 token.type ) );
					break;
				
                case CTRL_JSR_USERFUNC:
				    tokens.append_tok( StoredToken( token.module,
												token.id,
												token.type,
												0 ), &tokpos );
       				token.userfunc->forward_callers.push_back( tokpos );
					break;
                
                case INS_POP_PARAM_BYREF:
                case INS_POP_PARAM:
					{
						unsigned sympos = 0;
						symbols.append( token.tokval(), sympos );
						tokens.append_tok(	StoredToken(token.module, token.id, token.type, sympos) );
					}
					break;
				
                default:
                    cerr << "AddToken: Can't handle TYP_CONTROL: " << token << endl;
					throw runtime_error( "Unexpected token in AddToken() (1)" );
					break;
			}
			break;
		default:
            cerr << "AddToken: Can't handle " << token << endl;
            throw runtime_error( "Unexpected Token passed to AddToken() (2)" );
        break;
    }

    add_ins_dbg_info();
}
コード例 #6
0
void
mminloc1_8_r16 (gfc_array_i8 * retarray, gfc_array_r16 * array,
				  index_type *pdim, gfc_array_l4 * mask)
{
  index_type count[GFC_MAX_DIMENSIONS];
  index_type extent[GFC_MAX_DIMENSIONS];
  index_type sstride[GFC_MAX_DIMENSIONS];
  index_type dstride[GFC_MAX_DIMENSIONS];
  index_type mstride[GFC_MAX_DIMENSIONS];
  GFC_INTEGER_8 *dest;
  GFC_REAL_16 *base;
  GFC_LOGICAL_4 *mbase;
  int rank;
  int dim;
  index_type n;
  index_type len;
  index_type delta;
  index_type mdelta;

  dim = (*pdim) - 1;
  rank = GFC_DESCRIPTOR_RANK (array) - 1;

  /* TODO:  It should be a front end job to correctly set the strides.  */

  if (array->dim[0].stride == 0)
    array->dim[0].stride = 1;

  if (mask->dim[0].stride == 0)
    mask->dim[0].stride = 1;

  len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
  if (len <= 0)
    return;
  delta = array->dim[dim].stride;
  mdelta = mask->dim[dim].stride;

  for (n = 0; n < dim; n++)
    {
      sstride[n] = array->dim[n].stride;
      mstride[n] = mask->dim[n].stride;
      extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
    }
  for (n = dim; n < rank; n++)
    {
      sstride[n] = array->dim[n + 1].stride;
      mstride[n] = mask->dim[n + 1].stride;
      extent[n] =
        array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
    }

  if (retarray->data == NULL)
    {
      for (n = 0; n < rank; n++)
        {
          retarray->dim[n].lbound = 0;
          retarray->dim[n].ubound = extent[n]-1;
          if (n == 0)
            retarray->dim[n].stride = 1;
          else
            retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1];
        }

      retarray->data
	 = internal_malloc_size (sizeof (GFC_INTEGER_8)
		 		 * retarray->dim[rank-1].stride
				 * extent[rank-1]);
      retarray->offset = 0;
      retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
    }
  else
    {
      if (retarray->dim[0].stride == 0)
	retarray->dim[0].stride = 1;

      if (rank != GFC_DESCRIPTOR_RANK (retarray))
	runtime_error ("rank of return array incorrect");
    }

  for (n = 0; n < rank; n++)
    {
      count[n] = 0;
      dstride[n] = retarray->dim[n].stride;
      if (extent[n] <= 0)
        return;
    }

  dest = retarray->data;
  base = array->data;
  mbase = mask->data;

  if (GFC_DESCRIPTOR_SIZE (mask) != 4)
    {
      /* This allows the same loop to be used for all logical types.  */
      assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
      for (n = 0; n < rank; n++)
        mstride[n] <<= 1;
      mdelta <<= 1;
      mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
    }

  while (base)
    {
      GFC_REAL_16 *src;
      GFC_LOGICAL_4 *msrc;
      GFC_INTEGER_8 result;
      src = base;
      msrc = mbase;
      {

  GFC_REAL_16 minval;
  minval = GFC_REAL_16_HUGE;
  result = 0;
        if (len <= 0)
	  *dest = 0;
	else
	  {
	    for (n = 0; n < len; n++, src += delta, msrc += mdelta)
	      {

  if (*msrc && (*src < minval || !result))
    {
      minval = *src;
      result = (GFC_INTEGER_8)n + 1;
    }
              }
	    *dest = result;
	  }
      }
      /* Advance to the next element.  */
      count[0]++;
      base += sstride[0];
      mbase += mstride[0];
      dest += dstride[0];
      n = 0;
      while (count[n] == extent[n])
        {
          /* When we get to the end of a dimension, reset it and increment
             the next dimension.  */
          count[n] = 0;
          /* We could precalculate these products, but this is a less
             frequently used path so proabably not worth it.  */
          base -= sstride[n] * extent[n];
          mbase -= mstride[n] * extent[n];
          dest -= dstride[n] * extent[n];
          n++;
          if (n == rank)
            {
              /* Break out of the look.  */
              base = NULL;
              break;
            }
          else
            {
              count[n]++;
              base += sstride[n];
              mbase += mstride[n];
              dest += dstride[n];
            }
        }
    }
}
コード例 #7
0
string RuleExprAsStmt::toStringV()
{
	throw runtime_error("Exception: Tried to call toStringV. Not an expression.\n Statement: " + statement);
}
コード例 #8
0
Value* RuleExprAsStmt::value(StateTuple states)
{
	throw runtime_error("Exception: Tried to call value. Not an expression.\n Statement: " + statement);
}
コード例 #9
0
ファイル: aligncodersnv.cpp プロジェクト: zhixingfeng/iGDA
bool AlignCoderSNV::encode(string alignfile, string outfile)
{
    if (p_alignreader==NULL)
        throw runtime_error("AlignCoderSNV::encode: p_alignreader has not be set.");
    ofstream p_outfile;
    open_outfile(p_outfile, outfile);
    
    ofstream p_reffile;
    open_outfile(p_reffile, outfile + ".ref");
    
    p_alignreader->open(alignfile);
    Align align;
    int nline = 0;
    while(p_alignreader->readline(align)){
        ++nline;
        
        // expections
        int alen = (int) align.matchPattern.size();
        if ( !(align.qAlignedSeq.size()==alen && align.tAlignedSeq.size()==alen) )
            throw runtime_error("incorrect match patter in line " + to_string(nline));
        if (align.qStrand != '+')
            throw runtime_error("qStrand should be + in line " + to_string(nline));
        
        // reverse alignment if it is aligned to negative strand
        if (align.tStrand != '+'){
            align.qAlignedSeq = getrevcomp(align.qAlignedSeq);
            align.tAlignedSeq = getrevcomp(align.tAlignedSeq);
        }
        
        // encode
        int cur_pos = align.tStart;
        for (int i=0; i<alen; i++){
            if (align.tAlignedSeq[i] == 'A' || align.tAlignedSeq[i] == 'C' || align.tAlignedSeq[i] == 'G' || align.tAlignedSeq[i] == 'T'){
                if (align.qAlignedSeq[i] != '-'){
                    if (align.tAlignedSeq[i] != align.qAlignedSeq[i]){
                        p_outfile << this->binary_code(cur_pos, align.qAlignedSeq[i]) << '\t';
                    }else{
                        p_reffile << this->binary_code(cur_pos, align.tAlignedSeq[i]) << '\t';
                    }
                }
                ++cur_pos;
            }else{
                if (align.tAlignedSeq[i]!='-')
                    ++cur_pos;
            }
            
            /*if (align.tAlignedSeq[i]!=align.qAlignedSeq[i] && align.tAlignedSeq[i]!='-' && align.qAlignedSeq[i]!='-')
                p_outfile << this->binary_code(cur_pos, align.qAlignedSeq[i]) << '\t';
            if (align.tAlignedSeq[i]!='-')
                cur_pos++;*/
        }
        p_outfile << endl;
        p_reffile << endl;
    }
    
    p_alignreader->close();
    
    
    p_outfile.close();
    p_reffile.close();
    return true;
}
コード例 #10
0
ファイル: aligncodersnv.cpp プロジェクト: zhixingfeng/iGDA
bool AlignCoderSNV::recode(string m5_file, string var_file, string recode_file, int left_len, int right_len, bool is_report_ref)
{
    // load var_file
    vector<VarData> var_data;
    ifstream fs_varfile;
    int64_t max_code = -1;
    open_infile(fs_varfile, var_file);
    while(true){
        string buf;
        getline(fs_varfile, buf);
        if(fs_varfile.eof())
            break;
        vector<string> buf_vec = split(buf, '\t');
        if (buf_vec.size()!=9)
            throw runtime_error("incorrect format in " + var_file);
        var_data.push_back(VarData(stod(buf_vec[0]), buf_vec[1][0], stod(buf_vec[2])));
        
        if (stod(buf_vec[2]) > max_code)
            max_code = stod(buf_vec[2]);
    }
    fs_varfile.close();
    
    // fill template of var_data
    vector<bool> var_data_temp(max_code + 4, false);
    for (int64_t i = 0; i < var_data.size(); ++i)
        var_data_temp[var_data[i].code] = true;
    
    
    // scan m5_file and recode
    if (p_alignreader==NULL)
        throw runtime_error("AlignCoderSNV::recode(): p_alignreader has not be set.");
    ofstream p_outfile;
    open_outfile(p_outfile, recode_file);
    ofstream p_outfile_ref;
    open_outfile(p_outfile_ref, recode_file + ".ref");
    
    p_alignreader->open(m5_file);
    Align align;
    int nline = 0;
    while(p_alignreader->readline(align)){
        ++nline;
        if (nline % 100 == 0)
            cout << nline << endl;
        //cout << nline << endl;
        
        // expections
        int alen = (int) align.matchPattern.size();
        if ( !(align.qAlignedSeq.size()==alen && align.tAlignedSeq.size()==alen) )
            throw runtime_error("incorrect match patter in line " + to_string(nline));
        if (align.qStrand != '+')
            throw runtime_error("qStrand should be + in line " + to_string(nline));
        
        // reverse alignment if it is aligned to negative strand
        if (align.tStrand != '+'){
            align.qAlignedSeq = getrevcomp(align.qAlignedSeq);
            align.tAlignedSeq = getrevcomp(align.tAlignedSeq);
        }
        
        // encode
        int cur_pos = align.tStart;
        for (int i=0; i<alen; i++){
            //cout << "nline=" << nline << ", i=" <<i << endl;
            if (align.tAlignedSeq[i]=='-')
                continue;
            
            if (4*cur_pos+3 > max_code + 3)
                break;
            
            // realign if hit detected variants
            int score_A = MIN_SCORE;
            int score_C = MIN_SCORE;
            int score_G = MIN_SCORE;
            int score_T = MIN_SCORE;
            bool is_var = false;

            seqan::Align<string, seqan::ArrayGaps> cur_realign_A;
            seqan::Align<string, seqan::ArrayGaps> cur_realign_C;
            seqan::Align<string, seqan::ArrayGaps> cur_realign_G;
            seqan::Align<string, seqan::ArrayGaps> cur_realign_T;
            
            string cur_qseq;
            string cur_rseq;
            pair<string, string> context;
            char ref_base;
            
            // align local sequence to the referece
            if (var_data_temp[4*cur_pos] || var_data_temp[4*cur_pos+1] || var_data_temp[4*cur_pos+2] || var_data_temp[4*cur_pos+3]){
                bool rl = this->get_context_m5(i, left_len, right_len, align.tAlignedSeq, context);
                if (!rl){
                    ++cur_pos;
                    continue;
                }
                
                is_var = true;

                // get left query sequence length
                int64_t k = 0;
                int64_t cur_qseq_start = i;
                while(true){
                    if (align.tAlignedSeq[cur_qseq_start]!='-')
                        k++;
                    if (k >= context.first.size())
                        break;
                    --cur_qseq_start;
                }
                
                
                // get right query sequence length
                k = 0;
                int64_t cur_qseq_end = i+1;
                while(true){
                    if (align.tAlignedSeq[cur_qseq_end]!='-')
                        k++;
                    if (k >= context.second.size())
                        break;
                    ++cur_qseq_end;
                }
                
                if (cur_qseq_start < 0)
                    throw runtime_error("cur_qseq_start < 0");
                if (cur_qseq_end >= alen)
                    throw runtime_error("cur_qseq_end >= alen");
                
                for (auto j = cur_qseq_start; j <= cur_qseq_end; ++j){
                    if (align.qAlignedSeq[j]!='-')
                        cur_qseq.push_back(align.qAlignedSeq[j]);
                }
                
                cur_rseq = context.first + context.second;
                
                if (cur_qseq == ""){
                    ++cur_pos;
                    continue;
                }
                
                if (cur_rseq == "")
                    throw runtime_error("cur_rseq is empty");
                
                ref_base = cur_rseq[context.first.size()-1];
                
                // realign
                cur_rseq[context.first.size()-1] = 'A';
                score_A = this->realign(cur_realign_A, cur_qseq, cur_rseq);
                
                cur_rseq[context.first.size()-1] = 'C';
                score_C = this->realign(cur_realign_C, cur_qseq, cur_rseq);
                
                cur_rseq[context.first.size()-1] = 'G';
                score_G = this->realign(cur_realign_G, cur_qseq, cur_rseq);
                
                cur_rseq[context.first.size()-1] = 'T';
                score_T = this->realign(cur_realign_T, cur_qseq, cur_rseq);
                
                // to be removed
                /*if ((cur_pos==253 || cur_pos==319 || cur_pos==325) && nline == 7445){
                    cout << "cur_pos = " << cur_pos << endl;
                    cout << "A: " << score_A << endl << cur_realign_A;
                    cout << "C: " << score_C << endl << cur_realign_C;
                    cout << "G: " << score_G << endl << cur_realign_G;
                    cout << "T: " << score_T << endl << cur_realign_T;
                    int tmp = 0;
                }*/
            }else{
                ++cur_pos;
                continue;
            }
            
            // recode
            if (score_A == MIN_SCORE && score_C == MIN_SCORE && score_G == MIN_SCORE && score_T == MIN_SCORE)
                throw runtime_error("A,C,G,T == MIN_SCORE, no alignment was done");
            // A
            if (score_A > score_C && score_A > score_G && score_A > score_T){
                if (align.tAlignedSeq[i]!='A'){
                    p_outfile << 4*cur_pos << '\t';
                }else{
                    if (is_report_ref)
                        p_outfile_ref << 4*cur_pos << '\t';
                }
            }
            
            // C
            if (score_C > score_A && score_C > score_G && score_C > score_T){
                if (align.tAlignedSeq[i]!='C'){
                    p_outfile << 4*cur_pos+1 << '\t';
                }else{
                    if (is_report_ref)
                        p_outfile_ref << 4*cur_pos+1 << '\t';
                }
            }
            
            // G
            if (score_G > score_A && score_G > score_C && score_G > score_T){
                if (align.tAlignedSeq[i]!='G'){
                    p_outfile << 4*cur_pos+2 << '\t';
                }else{
                    if (is_report_ref)
                        p_outfile_ref << 4*cur_pos+2 << '\t';
                }
            }
            
            // T
            if (score_T > score_A && score_T > score_C && score_T > score_G){
                if (align.tAlignedSeq[i]!='T'){
                    p_outfile << 4*cur_pos+3 << '\t';
                }else{
                    if (is_report_ref)
                        p_outfile_ref << 4*cur_pos+3 << '\t';
                }
                
            }
            
            ++cur_pos;
        }
        p_outfile << endl;
        p_outfile_ref << endl;
    }
    
    p_alignreader->close();
    
    
    p_outfile.close();
    p_outfile_ref.close();
    
    return true;
}
コード例 #11
0
ファイル: transpose_generic.c プロジェクト: 0day-ci/gcc
static void
transpose_internal (gfc_array_char *ret, gfc_array_char *source)
{
  /* r.* indicates the return array.  */
  index_type rxstride, rystride;
  char *rptr;
  /* s.* indicates the source array.  */
  index_type sxstride, systride;
  const char *sptr;

  index_type xcount, ycount;
  index_type x, y;
  index_type size;

  assert (GFC_DESCRIPTOR_RANK (source) == 2
          && GFC_DESCRIPTOR_RANK (ret) == 2);

  size = GFC_DESCRIPTOR_SIZE(ret);

  if (ret->base_addr == NULL)
    {
      assert (ret->dtype == source->dtype);

      GFC_DIMENSION_SET(ret->dim[0], 0, GFC_DESCRIPTOR_EXTENT(source,1) - 1,
			1);

      GFC_DIMENSION_SET(ret->dim[1], 0, GFC_DESCRIPTOR_EXTENT(source,0) - 1,
			GFC_DESCRIPTOR_EXTENT(source, 1));

      ret->base_addr = xmallocarray (size0 ((array_t*)ret), size);
      ret->offset = 0;
    }
  else if (unlikely (compile_options.bounds_check))
    {
      index_type ret_extent, src_extent;

      ret_extent = GFC_DESCRIPTOR_EXTENT(ret,0);
      src_extent = GFC_DESCRIPTOR_EXTENT(source,1);

      if (src_extent != ret_extent)
	runtime_error ("Incorrect extent in return value of TRANSPOSE"
		       " intrinsic in dimension 1: is %ld,"
		       " should be %ld", (long int) src_extent,
		       (long int) ret_extent);

      ret_extent = GFC_DESCRIPTOR_EXTENT(ret,1);
      src_extent = GFC_DESCRIPTOR_EXTENT(source,0);

      if (src_extent != ret_extent)
	runtime_error ("Incorrect extent in return value of TRANSPOSE"
		       " intrinsic in dimension 2: is %ld,"
		       " should be %ld", (long int) src_extent,
		       (long int) ret_extent);

    }

  sxstride = GFC_DESCRIPTOR_STRIDE_BYTES(source,0);
  systride = GFC_DESCRIPTOR_STRIDE_BYTES(source,1);
  xcount = GFC_DESCRIPTOR_EXTENT(source,0);
  ycount = GFC_DESCRIPTOR_EXTENT(source,1);

  rxstride = GFC_DESCRIPTOR_STRIDE_BYTES(ret,0);
  rystride = GFC_DESCRIPTOR_STRIDE_BYTES(ret,1);

  rptr = ret->base_addr;
  sptr = source->base_addr;

  for (y = 0; y < ycount; y++)
    {
      for (x = 0; x < xcount; x++)
        {
          memcpy (rptr, sptr, size);

          sptr += sxstride;
          rptr += rystride;
        }
      sptr += systride - (sxstride * xcount);
      rptr += rxstride - (rystride * xcount);
    }
}
コード例 #12
0
RoutingPlan* RoutingPlan::normalizeRules( const string& planname )
{
	DEBUG( "Normalizing plan [" << m_Name << "] target is [" << planname << "]" );

	// check if the name is ok
	if ( m_IsTerminal || m_Exitpoint.isValid() ) 
	{
		// if it's this plan, start normalizing
		if ( planname == m_Name )
		{
			// terminal paths need no normalization
			if ( m_IsNormalized )
			{
				DEBUG( "Plan already normalized/not terminal" );
				return NULL;
			}

			m_IsNormalized = true;
			return this;
		}
		else
			return NULL;
	}

	if ( m_Name.length() > planname.length() )
	{
		TRACE( "Unable to normalize plan [not terminal]" );
		return NULL;
	}

	string nextStr = planname.substr( m_Name.length() );

	RoutingPlan* plan = NULL;

	// success plan
	if ( nextStr.substr( 0, 2 ) == string( "-1" ) )
	{
		if ( m_SuccessPlan == NULL )
			throw runtime_error( string( "Unable to find a plan with name" ) + planname );

		plan = m_SuccessPlan->normalize( planname );
		if ( plan == NULL )
			return NULL;

		for ( unsigned int i=0; i<m_ForkConditions.size(); i++ )
		{
			plan->m_SuccessConditions.push_back( m_ForkConditions[ i ] );
		}
	}
	else // fail plan
	{
		if ( m_FailPlan == NULL )
			throw runtime_error( string( "Unable to find a plan with name" ) + planname );
		
		plan = m_FailPlan->normalize( planname );
		if ( plan == NULL )
			return NULL;

		for ( unsigned int i=0; i<m_ForkConditions.size(); i++ )
		{
			plan->m_FailConditions.push_back( m_ForkConditions[ i ] );
		}
	}

	// add all rules
	for ( unsigned int i=0; i<m_Rules.size(); i++ )
	{
		( void )plan->m_Rules.insert( plan->m_Rules.begin() + i, m_Rules[ i ] );
	}

	return plan;
}
コード例 #13
0
ファイル: L3Geom.cpp プロジェクト: Sotrelius/trunk
/*
Generic function to compute L3Geom (with colinear points), used for {sphere,facet,wall}+sphere contacts now
*/
void Ig2_Sphere_Sphere_L3Geom::handleSpheresLikeContact(const shared_ptr<Interaction>& I, const State& state1, const State& state2, const Vector3r& shift2, bool is6Dof, const Vector3r& normal, const Vector3r& contPt, Real uN, Real r1, Real r2){
	// create geometry
	if(!I->geom){
		if(is6Dof) I->geom=shared_ptr<L6Geom>(new L6Geom);
		else       I->geom=shared_ptr<L3Geom>(new L3Geom);
		L3Geom& g(I->geom->cast<L3Geom>());
		g.contactPoint=contPt;
		g.refR1=r1; g.refR2=r2;
		g.normal=normal;
		// g.trsf.setFromTwoVectors(Vector3r::UnitX(),g.normal); // quaternion just from the X-axis; does not seem to work for some reason?!
		const Vector3r& locX(g.normal);
		// initial local y-axis orientation, in the xz or xy plane, depending on which component is larger to avoid singularities
		Vector3r locY=normal.cross(abs(normal[1])<abs(normal[2])?Vector3r::UnitY():Vector3r::UnitZ()); locY-=locX*locY.dot(locX); locY.normalize();
		Vector3r locZ=normal.cross(locY);
		#ifdef L3_TRSF_QUATERNION
			Matrix3r trsf; trsf.row(0)=locX; trsf.row(1)=locY; trsf.row(2)=locZ;
			g.trsf=Quaternionr(trsf); // from transformation matrix
		#else
			g.trsf.row(0)=locX; g.trsf.row(1)=locY; g.trsf.row(2)=locZ;
		#endif
		g.u=Vector3r(uN,0,0); // zero shear displacement
		if(distFactor<0) g.u0[0]=uN;
		// L6Geom::phi is initialized to Vector3r::Zero() automatically
		//cerr<<"Init trsf=\n"<<g.trsf<<endl<<"locX="<<locX<<", locY="<<locY<<", locZ="<<locZ<<endl;
		return;
	}
	
	// update geometry

	/* motion of the conctact consists in rigid motion (normRotVec, normTwistVec) and mutual motion (relShearDu);
	   they are used to update trsf and u
	*/

	L3Geom& g(I->geom->cast<L3Geom>());
	const Vector3r& currNormal(normal); const Vector3r& prevNormal(g.normal);
	// normal rotation vector, between last steps
	Vector3r normRotVec=prevNormal.cross(currNormal);
	// contrary to what ScGeom::precompute does now (r2486), we take average normal, i.e. .5*(prevNormal+currNormal),
	// so that all terms in the equation are in the previous mid-step
	// the re-normalization might not be necessary for very small increments, but better do it
	Vector3r avgNormal=(approxMask&APPROX_NO_MID_NORMAL) ? prevNormal : .5*(prevNormal+currNormal);
	if(!(approxMask&APPROX_NO_RENORM_MID_NORMAL) && !(approxMask&APPROX_NO_MID_NORMAL)) avgNormal.normalize(); // normalize only if used and if requested via approxMask
	// twist vector of the normal from the last step
	Vector3r normTwistVec=avgNormal*scene->dt*.5*avgNormal.dot(state1.angVel+state2.angVel);
	// compute relative velocity
	// noRatch: take radius or current distance as the branch vector; see discussion in ScGeom::precompute (avoidGranularRatcheting)
	Vector3r c1x=((noRatch && !r1>0) ? ( r1*normal).eval() : (contPt-state1.pos).eval()); // used only for sphere-sphere
	Vector3r c2x=(noRatch ? (-r2*normal).eval() : (contPt-state2.pos+shift2).eval());
	//Vector3r state2velCorrected=state2.vel+(scene->isPeriodic?scene->cell->intrShiftVel(I->cellDist):Vector3r::Zero()); // velocity of the second particle, corrected with meanfield velocity if necessary
	//cerr<<"correction "<<(scene->isPeriodic?scene->cell->intrShiftVel(I->cellDist):Vector3r::Zero())<<endl;
	Vector3r relShearVel=(state2.vel+state2.angVel.cross(c2x))-(state1.vel+state1.angVel.cross(c1x));
	// account for relative velocity of particles in different cell periods
	if(scene->isPeriodic) relShearVel+=scene->cell->intrShiftVel(I->cellDist);
	relShearVel-=avgNormal.dot(relShearVel)*avgNormal;
	Vector3r relShearDu=relShearVel*scene->dt;

	/* Update of quantities in global coords consists in adding 3 increments we have computed; in global coords (a is any vector)

		1. +relShearVel*scene->dt;      // mutual motion of the contact
		2. -a.cross(normRotVec);   // rigid rotation perpendicular to the normal
		3. -a.cross(normTwistVec); // rigid rotation parallel to the normal

	*/

	// compute current transformation, by updating previous axes
	// the X axis can be prescribed directly (copy of normal)
	// the mutual motion on the contact does not change transformation
	#ifdef L3_TRSF_QUATERNION
		const Matrix3r prevTrsf(g.trsf.toRotationMatrix());
		Quaternionr prevTrsfQ(g.trsf);
	#else
		const Matrix3r prevTrsf(g.trsf); // could be reference perhaps, but we need it to compute midTrsf (if applicable)
	#endif
	Matrix3r currTrsf; currTrsf.row(0)=currNormal;
	for(int i=1; i<3; i++){
		currTrsf.row(i)=prevTrsf.row(i)-prevTrsf.row(i).cross(normRotVec)-prevTrsf.row(i).cross(normTwistVec);
	}
	#ifdef L3_TRSF_QUATERNION
		Quaternionr currTrsfQ(currTrsf);
		if((scene->iter % trsfRenorm)==0 && trsfRenorm>0) currTrsfQ.normalize();
	#else
		if((scene->iter % trsfRenorm)==0 && trsfRenorm>0){
			#if 1
				currTrsf.row(0).normalize();
				currTrsf.row(1)-=currTrsf.row(0)*currTrsf.row(1).dot(currTrsf.row(0)); // take away y projected on x, to stabilize numerically
				currTrsf.row(1).normalize();
				currTrsf.row(2)=currTrsf.row(0).cross(currTrsf.row(1));
				currTrsf.row(2).normalize();
			#else
				currTrsf=Matrix3r(Quaternionr(currTrsf).normalized());
			#endif
			#ifdef YADE_DEBUG
				if(abs(currTrsf.determinant()-1)>.05){
					LOG_ERROR("##"<<I->getId1()<<"+"<<I->getId2()<<", |trsf|="<<currTrsf.determinant());
					g.trsf=currTrsf;
					throw runtime_error("Transformation matrix far from orthonormal.");
				}
			#endif
		}
	#endif

	/* Previous local trsf u'⁻ must be updated to current u'⁰. We have transformation T⁻ and T⁰,
		δ(a) denotes increment of a as defined above.  Two possibilities:

		1. convert to global, update, convert back: T⁰(T⁻*(u'⁻)+δ(T⁻*(u'⁻))). Quite heavy.
		2. update u'⁻ straight, using relShearVel in local coords; since relShearVel is computed 
			at (t-Δt/2), we would have to find intermediary transformation (same axis, half angle;
			the same as slerp at t=.5 between the two).

			This could be perhaps simplified by using T⁰ or T⁻ since they will not differ much,
			but it would have to be verified somehow.
	*/
	// if requested via approxMask, just use prevTrsf
	#ifdef L3_TRSF_QUATERNION
		Quaternionr midTrsf=(approxMask&APPROX_NO_MID_TRSF) ? prevTrsfQ : prevTrsfQ.slerp(.5,currTrsfQ);
	#else
		Quaternionr midTrsf=(approxMask&APPROX_NO_MID_TRSF) ? Quaternionr(prevTrsf) : Quaternionr(prevTrsf).slerp(.5,Quaternionr(currTrsf));
	#endif
	//cerr<<"prevTrsf=\n"<<prevTrsf<<", currTrsf=\n"<<currTrsf<<", midTrsf=\n"<<Matrix3r(midTrsf)<<endl;
	
	// updates of geom here

	// midTrsf*relShearVel should have the 0-th component (approximately) zero -- to be checked
	g.u+=midTrsf*relShearDu;
	//cerr<<"midTrsf=\n"<<midTrsf<<",relShearDu="<<relShearDu<<", transformed "<<midTrsf*relShearDu<<endl;
	g.u[0]=uN; // this does not have to be computed incrementally
	#ifdef L3_TRSF_QUATERNION
		g.trsf=currTrsfQ;
	#else
		g.trsf=currTrsf;
	#endif

	// GenericSpheresContact
	g.refR1=r1; g.refR2=r2;
	g.normal=currNormal;
	g.contactPoint=contPt;

	if(is6Dof){
		// update phi, from the difference of angular velocities
		// the difference is transformed to local coord using the midTrsf transformation
		// perhaps not consistent when spheres have different radii (depends how bending moment is computed)
		I->geom->cast<L6Geom>().phi+=midTrsf*(scene->dt*(state2.angVel-state1.angVel));
	}
};
コード例 #14
0
static void
unpack_internal (gfc_array_char *ret, const gfc_array_char *vector,
		 const gfc_array_l1 *mask, const gfc_array_char *field,
		 index_type size)
{
  /* r.* indicates the return array.  */
  index_type rstride[GFC_MAX_DIMENSIONS];
  index_type rstride0;
  index_type rs;
  char * restrict rptr;
  /* v.* indicates the vector array.  */
  index_type vstride0;
  char *vptr;
  /* f.* indicates the field array.  */
  index_type fstride[GFC_MAX_DIMENSIONS];
  index_type fstride0;
  const char *fptr;
  /* m.* indicates the mask array.  */
  index_type mstride[GFC_MAX_DIMENSIONS];
  index_type mstride0;
  const GFC_LOGICAL_1 *mptr;

  index_type count[GFC_MAX_DIMENSIONS];
  index_type extent[GFC_MAX_DIMENSIONS];
  index_type n;
  index_type dim;

  int empty;
  int mask_kind;

  empty = 0;

  mptr = mask->data;

  /* Use the same loop for all logical types, by using GFC_LOGICAL_1
     and using shifting to address size and endian issues.  */

  mask_kind = GFC_DESCRIPTOR_SIZE (mask);

  if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
#ifdef HAVE_GFC_LOGICAL_16
      || mask_kind == 16
#endif
      )
    {
      /*  Don't convert a NULL pointer as we use test for NULL below.  */
      if (mptr)
	mptr = GFOR_POINTER_TO_L1 (mptr, mask_kind);
    }
  else
    runtime_error ("Funny sized logical array");

  if (ret->data == NULL)
    {
      /* The front end has signalled that we need to populate the
	 return array descriptor.  */
      dim = GFC_DESCRIPTOR_RANK (mask);
      rs = 1;
      for (n = 0; n < dim; n++)
	{
	  count[n] = 0;
	  GFC_DIMENSION_SET(ret->dim[n], 0,
			    GFC_DESCRIPTOR_EXTENT(mask,n) - 1, rs);
	  extent[n] = GFC_DESCRIPTOR_EXTENT(ret,n);
	  empty = empty || extent[n] <= 0;
	  rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret, n);
	  fstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(field, n);
	  mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n);
	  rs *= extent[n];
	}
      ret->offset = 0;
      ret->data = internal_malloc_size (rs * size);
    }
  else
    {
      dim = GFC_DESCRIPTOR_RANK (ret);
      for (n = 0; n < dim; n++)
	{
	  count[n] = 0;
	  extent[n] = GFC_DESCRIPTOR_EXTENT(ret,n);
	  empty = empty || extent[n] <= 0;
	  rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret, n);
	  fstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(field, n);
	  mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n);
	}
    }

  if (empty)
    return;

  vstride0 = GFC_DESCRIPTOR_STRIDE_BYTES(vector,0);
  rstride0 = rstride[0];
  fstride0 = fstride[0];
  mstride0 = mstride[0];
  rptr = ret->data;
  fptr = field->data;
  vptr = vector->data;

  while (rptr)
    {
      if (*mptr)
        {
          /* From vector.  */
          memcpy (rptr, vptr, size);
          vptr += vstride0;
        }
      else
        {
          /* From field.  */
          memcpy (rptr, fptr, size);
        }
      /* Advance to the next element.  */
      rptr += rstride0;
      fptr += fstride0;
      mptr += mstride0;
      count[0]++;
      n = 0;
      while (count[n] == extent[n])
        {
          /* When we get to the end of a dimension, reset it and increment
             the next dimension.  */
          count[n] = 0;
          /* We could precalculate these products, but this is a less
             frequently used path so probably not worth it.  */
          rptr -= rstride[n] * extent[n];
          fptr -= fstride[n] * extent[n];
          mptr -= mstride[n] * extent[n];
          n++;
          if (n >= dim)
            {
              /* Break out of the loop.  */
              rptr = NULL;
              break;
            }
          else
            {
              count[n]++;
              rptr += rstride[n];
              fptr += fstride[n];
              mptr += mstride[n];
            }
        }
    }
}
コード例 #15
0
void
spread_i1 (gfc_array_i1 *ret, const gfc_array_i1 *source,
		 const index_type along, const index_type pncopies)
{
  /* r.* indicates the return array.  */
  index_type rstride[GFC_MAX_DIMENSIONS];
  index_type rstride0;
  index_type rdelta = 0;
  index_type rrank;
  index_type rs;
  GFC_INTEGER_1 *rptr;
  GFC_INTEGER_1 * restrict dest;
  /* s.* indicates the source array.  */
  index_type sstride[GFC_MAX_DIMENSIONS];
  index_type sstride0;
  index_type srank;
  const GFC_INTEGER_1 *sptr;

  index_type count[GFC_MAX_DIMENSIONS];
  index_type extent[GFC_MAX_DIMENSIONS];
  index_type n;
  index_type dim;
  index_type ncopies;

  srank = GFC_DESCRIPTOR_RANK(source);

  rrank = srank + 1;
  if (rrank > GFC_MAX_DIMENSIONS)
    runtime_error ("return rank too large in spread()");

  if (along > rrank)
      runtime_error ("dim outside of rank in spread()");

  ncopies = pncopies;

  if (ret->data == NULL)
    {
      /* The front end has signalled that we need to populate the
	 return array descriptor.  */
      ret->dtype = (source->dtype & ~GFC_DTYPE_RANK_MASK) | rrank;
      dim = 0;
      rs = 1;
      for (n = 0; n < rrank; n++)
	{
	  ret->dim[n].stride = rs;
	  ret->dim[n].lbound = 0;
	  if (n == along - 1)
	    {
	      ret->dim[n].ubound = ncopies - 1;
	      rdelta = rs;
	      rs *= ncopies;
	    }
	  else
	    {
	      count[dim] = 0;
	      extent[dim] = source->dim[dim].ubound + 1
		- source->dim[dim].lbound;
	      sstride[dim] = source->dim[dim].stride;
	      rstride[dim] = rs;

	      ret->dim[n].ubound = extent[dim]-1;
	      rs *= extent[dim];
	      dim++;
	    }
	}
      ret->offset = 0;
      if (rs > 0)
        ret->data = internal_malloc_size (rs * sizeof(GFC_INTEGER_1));
      else
	{
	  ret->data = internal_malloc_size (1);
	  return;
	}
    }
  else
    {
      int zero_sized;

      zero_sized = 0;

      dim = 0;
      if (GFC_DESCRIPTOR_RANK(ret) != rrank)
	runtime_error ("rank mismatch in spread()");

      if (unlikely (compile_options.bounds_check))
	{
	  for (n = 0; n < rrank; n++)
	    {
	      index_type ret_extent;

	      ret_extent = ret->dim[n].ubound + 1 - ret->dim[n].lbound;
	      if (n == along - 1)
		{
		  rdelta = ret->dim[n].stride;

		  if (ret_extent != ncopies)
		    runtime_error("Incorrect extent in return value of SPREAD"
				  " intrinsic in dimension %ld: is %ld,"
				  " should be %ld", (long int) n+1,
				  (long int) ret_extent, (long int) ncopies);
		}
	      else
		{
		  count[dim] = 0;
		  extent[dim] = source->dim[dim].ubound + 1
		    - source->dim[dim].lbound;
		  if (ret_extent != extent[dim])
		    runtime_error("Incorrect extent in return value of SPREAD"
				  " intrinsic in dimension %ld: is %ld,"
				  " should be %ld", (long int) n+1,
				  (long int) ret_extent,
				  (long int) extent[dim]);
		    
		  if (extent[dim] <= 0)
		    zero_sized = 1;
		  sstride[dim] = source->dim[dim].stride;
		  rstride[dim] = ret->dim[n].stride;
		  dim++;
		}
	    }
	}
      else
	{
	  for (n = 0; n < rrank; n++)
	    {
	      if (n == along - 1)
		{
		  rdelta = ret->dim[n].stride;
		}
	      else
		{
		  count[dim] = 0;
		  extent[dim] = source->dim[dim].ubound + 1
		    - source->dim[dim].lbound;
		  if (extent[dim] <= 0)
		    zero_sized = 1;
		  sstride[dim] = source->dim[dim].stride;
		  rstride[dim] = ret->dim[n].stride;
		  dim++;
		}
	    }
	}

      if (zero_sized)
	return;

      if (sstride[0] == 0)
	sstride[0] = 1;
    }
  sstride0 = sstride[0];
  rstride0 = rstride[0];
  rptr = ret->data;
  sptr = source->data;

  while (sptr)
    {
      /* Spread this element.  */
      dest = rptr;
      for (n = 0; n < ncopies; n++)
        {
	  *dest = *sptr;
          dest += rdelta;
        }
      /* Advance to the next element.  */
      sptr += sstride0;
      rptr += rstride0;
      count[0]++;
      n = 0;
      while (count[n] == extent[n])
        {
          /* When we get to the end of a dimension, reset it and increment
             the next dimension.  */
          count[n] = 0;
          /* We could precalculate these products, but this is a less
             frequently used path so probably not worth it.  */
          sptr -= sstride[n] * extent[n];
          rptr -= rstride[n] * extent[n];
          n++;
          if (n >= srank)
            {
              /* Break out of the loop.  */
              sptr = NULL;
              break;
            }
          else
            {
              count[n]++;
              sptr += sstride[n];
              rptr += rstride[n];
            }
        }
    }
}