Exemplo n.º 1
0
 /**
  * Performs one heuristic step
  * @param s starting point
  * @return true if the search is completed, false if the search is interrupted
  */
 virtual bool step(std::vector<Solution>& sv)
 {
   VT v;
   mLog << "Starting ";
   if(mStartFromZero)
     mLog << "START_FROM_ZERO";
   else
     mLog << "START_FROM_X";
   mLog << "(" << mNumberOfStarts << " starts)\n";
   BNB_ASSERT(mLocOpt);
   BNB_ASSERT(sv.size() == 1);
   Solution s = sv.at(0);
   sv.pop_back();
   BNB_ASSERT(mNumberOfStarts > 0);
   for(int i = 0; i < mNumberOfStarts;) {
     pertrub(i, s.mX);
     i ++;
     if(mLocOpt->search(mAux, &mAuxV)) {
       if(mAuxV < s.mFval) {
         pushPoint(sv);
         if(mGreedy)
           break;
       }
     }        
     mLog << "OLD = " << s.mFval << "AUXV" << mAuxV << "\n";
   }
   mLog.write();
   return true;
 }
Exemplo n.º 2
0
 /**
  * The objective function itself 
  *
  * @param x argument
  *
  * @return function value
  *
  */
 double func(double* x)
 {
   int n;
   double v, y;
     
   BNB_ASSERT(mDiag);
   BNB_ASSERT(mSDiag);
   BNB_ASSERT(mKap);      
   BNB_ASSERT(mDim);
   n = mDim;
   v = 0.;
   for(int i = 0; i < n; i ++) {
     y = mDiag[i] * x[i];
     y *= x[i];
     v += y;
     y = 0.5 * mKap[i];
     y *= x[i];
     y *= x[i];
     y *= x[i];
     y *= x[i];
     v -= y;
     if(i != (n - 1)) {
       y = mSDiag[i] * x[i];
       v +=  y * x[i + 1];
     }
     if(i != 0) {
       y = mSDiag[i-1] * x[i - 1];
       v += y * x[i];
     }
   }      
   return  v;
 }
Exemplo n.º 3
0
 static void processModel(const JSONNode & nd, MatModel& model) {
     bool nlayset = false;
     bool rangeset = false;
     bool lengthset = false;
     bool heightset = false;
     bool atomsset = false;
     for (auto i = nd.begin(); i != nd.end(); i++) {
         if (i->name() == JsonNames::numlayers) {
             model.mNumLayers = i->as_int();
             nlayset = true;
         } else if (i->name() == JsonNames::range) {
             model.mRadius = i->as_float();
             rangeset = true;
         } else if (i->name() == JsonNames::length) {
             model.mLength = i->as_float();
             lengthset = true;
         } else if (i->name() == JsonNames::height) {
             model.mHeight = i->as_float();
             heightset = true;
         } else if (i->name() == JsonNames::atoms) {
             BNB_ASSERT(nlayset);
             readIntVector(*i, model.mNumLayers, model.mLayersAtoms);
             atomsset = true;
         } else {
             BNB_ERROR_REPORT("Illegal name on parsing model data");
         }
     }
     BNB_ASSERT(nlayset && rangeset && lengthset && heightset && atomsset);
 }
Exemplo n.º 4
0
 /**
  * Gradient 
  * 
  * @param x argument
  * @param g gradient
  */
 void grad(double* x, double* g)
 {
   int n;
   double v;
   double y;
     
   v = 0.;
   BNB_ASSERT(mDiag);
   BNB_ASSERT(mSDiag);
   BNB_ASSERT(mKap);
   BNB_ASSERT(mDim);
   n = mDim;
     
   for(int i = 0; i < n; i ++) {
     v = mDiag[i] * x[i];
     y =  mKap[i] * x[i];
     y *= x[i];
     y *= x[i];
     v -=  y;
     if(i != (n - 1)) {
       v += mSDiag[i] * x[i + 1];
     }
     if(i != 0) {
       v += mSDiag[i - 1] * x[i - 1];
     }
     g[i] =  2. * v;
   }
 }
Exemplo n.º 5
0
int main(int argc, char** argv) {
    Box<double> box(2);
    initBox(box);
    Supp supp(1);
    Obj obj;
    UnconsRecStore<double> rs(3, 2);
    EigenCutFactory<double> fact(&rs, &supp, &obj, 0.68);
    std::vector< Cut<double> > cuts;
    fact.getCuts(box, cuts);

    supp.setLB(-1);
    ObjOne objone;
    EigenCutFactory<double> factone(&rs, &supp, &objone, 0.28);
    factone.getCuts(box, cuts);

    supp.setLB(0);
    ObjTwo objtwo;
    EigenCutFactory<double> facttwo(&rs, &supp, &objtwo, 0.5);
    facttwo.getCuts(box, cuts);
    for (auto o : cuts) {
        std::cout << CutUtils<double> ::toString(o) << "\n";
    }

    BNB_ASSERT((cuts[0].mType == Cut<double>::CutType::OUTER_BALL) && (BNBABS(cuts[0].mR - 0.8) < 0.001) && (cuts[0].mC[0] == 0) && (cuts[0].mC[1] == 0));
    BNB_ASSERT((cuts[1].mType == Cut<double>::CutType::INNER_BALL) && (BNBABS(cuts[1].mR - 1.6) < 0.001) && (cuts[1].mC[0] == 2) && (cuts[1].mC[1] == 0));
    BNB_ASSERT((cuts[2].mType == Cut<double>::CutType::LINEAR) &&(cuts[2].mR == 2) && (cuts[2].mC[0] == 1) && (cuts[2].mC[1] == 1));
    return 0;
}
Exemplo n.º 6
0
 static void readIntVector(const JSONNode& nd, int vecsz, int * x) {
     int k = 0;
     for (auto i = nd.begin(); i != nd.end(); i++) {
         int u = i->as_int();
         BNB_ASSERT(k < vecsz);
         x[k++] = u;
     }
     BNB_ASSERT(k == vecsz);
 }
Exemplo n.º 7
0
 static void readDoubleVector(const JSONNode& nd, int vecsz, double * x) {
     int k = 0;
     for (auto i = nd.begin(); i != nd.end(); i++) {
         double u = i->as_float();
         BNB_ASSERT(k < vecsz);
         x[k++] = u;
     }
     BNB_ASSERT(k == vecsz);
 }
Exemplo n.º 8
0
/**
 * The constructor
 *
 * @param f function to optimize
 *
 * @param dim dimension
 *
 * @param a "left" bound for the rectangle
 *
 * @param b "right" bound for the rectangle
 *
 * @param eps precision
 */
  MGOInitialData(double* a, double* b, double* eps, MultiObjective *obj)
  {
    BNB_ASSERT(obj->getNumOfParams() <= MAX_NUMBER_OF_PARAMS);
    BNB_ASSERT(obj->getNumOfCriteria() <= MAX_NUMBER_OF_CRITERIA);
    mObj = obj;
    mEps = eps;
    mA = a;
    mB = b;
  }
Exemplo n.º 9
0
    void processCommand(std::vector< std::string > &args)
    {
/*      printf("PROCESS: ");
      for(int i = 0; i < args.size(); i ++) {
        printf("[%s] ", args[i].c_str());
      }
      printf("\n");*/
      if(args.empty()) {
        *mAction = BNBActions::ERASE;
      } else if(args[0] == "forward")  {
        *mAction = BNBActions::FORWARD | BNBActions::ERASE;
        eraseCommand();
      } else if(args[0] == "drop")  {
        *mAction = BNBActions::DROP | BNBActions::ERASE;
        eraseCommand();
      } else if(args[0] == "var") {
        BNB_ASSERT(args.size() == 2);
        processVar(args[1]);
      } else if(args[0] == "set") {
        BNB_ASSERT(args.size() == 3);
        processAssign(args[1], args[2]);
      } else if(args[0] == "inc") {
        BNB_ASSERT(args.size() == 3);
        processInc(args[1], args[2]);
      } else if(args[0] == "cat") {
        BNB_ASSERT(args.size() == 3);
        processCat(args[1], args[2]);
      } else if(args[0] == "wait") {
        BNB_ASSERT(args.size() == 4);        
        processWait(args[1], args[2], args[3]);
      } else if(args[0] == "echo") {
        processEcho(args);
      } else if(args[0] == "erase") {
        *mAction = BNBActions::ERASE;
        eraseCommand();        
      } else if(args[0] == "save") {
        processSave(args[1], args[2]);
      } else if(args[0] == "append") {
        processAppend(args[1], args[2]);
      } else if(args[0] == "load") {
        processLoad(args[1], args[2]);
      } else if(args[0] == "mkdir") {
        processMkdir(args[1]);
      } else if(args[0] == "skip") {
        eraseCommand();
      } else if(args[0] == "exec") {
        processExec(args[1]);
      } else if(args[0] == "exit") {
        *mAction = BNBActions::EXIT;
        eraseCommand();
      } else {
        printf("%s\n", args[0].c_str());
        BNB_ERROR_REPORT("Unrecognized command");
      }
    }
Exemplo n.º 10
0
int main(int argc, char** argv) {

    Box<double> sbox(2);
    sbox.mA[0] = 0;
    sbox.mA[1] = 0;
    sbox.mB[0] = 4;
    sbox.mB[1] = 3;

    std::vector< Box<double> > bv;
    Box<double> cbox1(2);

    /** Test 1 **/
    cbox1.mA[0] = -1;
    cbox1.mA[1] = 1;
    cbox1.mB[0] = 5;
    cbox1.mB[1] = 2;

    BoxUtils::complement(sbox, cbox1, bv);
    printBoxList(bv);
    BNB_ASSERT(bv.size() == 2);
    BNB_ASSERT((bv[0].mA[0] == 0) && (bv[0].mA[1] == 0) && (bv[0].mB[0] == 4) && (bv[0].mB[1] == 1));
    BNB_ASSERT((bv[1].mA[0] == 0) && (bv[1].mA[1] == 2) && (bv[1].mB[0] == 4) && (bv[1].mB[1] == 3));

    /** Test 2 **/
    cbox1.mA[0] = 1;
    cbox1.mA[1] = 1;
    cbox1.mB[0] = 2;
    cbox1.mB[1] = 2;
    bv.clear();
    BoxUtils::complement(sbox, cbox1, bv);
    printBoxList(bv);
    BNB_ASSERT(bv.size() == 4);
    BNB_ASSERT((bv[0].mA[0] == 0) && (bv[0].mA[1] == 0) && (bv[0].mB[0] == 1) && (bv[0].mB[1] == 3));
    BNB_ASSERT((bv[1].mA[0] == 2) && (bv[1].mA[1] == 0) && (bv[1].mB[0] == 4) && (bv[1].mB[1] == 3));
    BNB_ASSERT((bv[2].mA[0] == 1) && (bv[2].mA[1] == 0) && (bv[2].mB[0] == 2) && (bv[2].mB[1] == 1));
    BNB_ASSERT((bv[3].mA[0] == 1) && (bv[3].mA[1] == 2) && (bv[3].mB[0] == 2) && (bv[3].mB[1] == 3));

    /** Test 3 **/
    cbox1.mA[0] = -2;
    cbox1.mA[1] = -2;
    cbox1.mB[0] = -1;
    cbox1.mB[1] = -1;
    bv.clear();
    BoxUtils::complement(sbox, cbox1, bv);
    printBoxList(bv);
    BNB_ASSERT(bv.size() == 1);
    BNB_ASSERT((bv[0].mA[0] == 0) && (bv[0].mA[1] == 0) && (bv[0].mB[0] == 4) && (bv[0].mB[1] == 3));

    return 0;
}
Exemplo n.º 11
0
 /**
  * Compute intersection of 2 boxes
  * @param fbox 1st box
  * @param sbox 2nd box
  * @param result resulting box
  * @return true if there is intersection
  */
 template <class FT> static bool intersect(const Box<FT> &fbox, const Box<FT> &sbox, Box<FT>& result) {
     int n = fbox.mDim;
     bool rv;
     BNB_ASSERT(sbox.mDim == n);
     BNB_ASSERT(result.mDim == n);
     for (int i = 0; i < n; i++) {
         result.mA[i] = BNBMAX(fbox.mA[i], sbox.mA[i]);
         result.mB[i] = BNBMIN(fbox.mB[i], sbox.mB[i]);
         if (result.mA[i] > result.mB[i]) {
             rv = false;
             break;
         }
     }
     return rv;
 }
Exemplo n.º 12
0
 bool pertrub(int cnt, VT* x)
 {
   BNB_ASSERT(mId);
   int s = 0;
   if(mPert) {
     mPert->pertrub(cnt, x, mAux);
   } else {
     if(mDivideCube) {
       VT h, o, alpha, delta;
       s = 1;
       h = mAmpl / mNP;
       o = - 0.5 * mAmpl + mMyId * h;
       alpha = o + h * ((double)rand() / (double)RAND_MAX);
       if(mStartFromZero)
         mAux[0] = alpha;
       else
         mAux[0] = x[0] + alpha;
     }      
     for(int i = s; i < mDim; i ++) {
       VT alpha, delta;
       alpha = mAmpl * (0.5 - ((double)rand() / (double)RAND_MAX));
       if(mStartFromZero)
         mAux[i] = alpha;
       else
         mAux[i] = x[i] + alpha;
     /*
       if(mId->mA[i] > mAux[i])
       mAux[i] = mId->mA[i];
       else if(mId->mB[i] < mAux[i])
       mAux[i] = mId->mB[i];
     */
     }
   }
   return true;
 }
Exemplo n.º 13
0
    /**
     * Constructor
     * @param n polynom degree
     * @param coeff polynom coefficient from highest degree
     */
    Polynom(int n, double *coeff) {
        BNB_ASSERT(n >= 3);
        setDim(1);
        mN = n;
        mF = (double*)malloc((n + 1) * sizeof(double));
        mDF = (double*)malloc((n + 1) * sizeof(double));
        mDDF = (double*)malloc((n + 1) * sizeof(double));
        mDDDF = (double*)malloc((n + 1) * sizeof(double));
        for(int i = 0; i <= n; i ++) {
            mF[i] = coeff[i];
        }
        derive(n, mF, mDF);
        derive(n - 1, mDF, mDDF);
        derive(n - 2, mDDF, mDDDF);
        printf("\nDF: ");
        for(int i = 0; i <= (n - 1); i ++)
            printf("%lf ", mDF[i]);
        printf("\nDDF: ");
        for(int i = 0; i <= (n - 2); i ++)
            printf("%lf ", mDDF[i]);
        printf("\nDDDF: ");
        for(int i = 0; i <= (n - 3); i ++)
            printf("%lf ", mDDDF[i]);

    }
Exemplo n.º 14
0
    /**
      * Push new segment
      *
      * @param s new segment
      */
    void push(Segment<FT>& s) 
    {
      Segment<FT> ns;
      FT a = s.mA;
      FT b = s.mB;
      ns.mA = a;
      ns.mB = b;
      BNB_ASSERT(mSize < MAX_VECSEG_SIZE);
      if(mSize == 0) {
	mArrSeg[0] = ns;
	mSize ++;
      } else {
	int l = -1, k = mSize;
	for(int i = 0; i < mSize; i ++) {
	  if(mArrSeg[i].mB <= a) 
	    l = i;
	  if(mArrSeg[i].mA >= b){
	    k = i;
	    break;
	  }
	}
	if((l + 1) <= (k - 1)) {
	  ns.mA = BNBMIN(ns.mA, mArrSeg[l+1].mA);
	  ns.mB = BNBMAX(ns.mB, mArrSeg[k-1].mB);
	  erase(l+1, k - 1);
	}
	insert(l, ns);
      }
    }
Exemplo n.º 15
0
    /**
     * Compute complement (list of boxes) of a box in a box
     * @param sbox source box 
     * @param cbox complementary box
     * @param result resulting list of boxes (list = sbox \ cbox)
     */
    template <class FT> static void complement(const Box<FT> &sbox, const Box<FT> &cbox, std::vector< Box<FT> >& result) {
        int n = sbox.mDim;
        BNB_ASSERT(cbox.mDim == n);
        Box<FT> box(n);
        
        copy(sbox, box);
        bool intersect = true;
        for (int i = 0; i < n; i++) {
            if ((cbox.mB[i] < box.mA[i]) || (cbox.mA[i] > box.mB[i])) {
                intersect = false;
            }
        }
        if (intersect) {
            for (int i = 0; i < n; i++) {

                if (cbox.mA[i] > box.mA[i]) {
                    Box<FT> nbox(n);
                    copy(box, nbox);
                    nbox.mB[i] = cbox.mA[i];
                    box.mA[i] = cbox.mA[i];
                    result.push_back(nbox);
                }
                if (cbox.mB[i] < box.mB[i]) {
                    Box<FT> nbox(n);
                    copy(box, nbox);
                    nbox.mA[i] = cbox.mB[i];
                    box.mB[i] = cbox.mB[i];
                    result.push_back(nbox);
                }

            }
        } else {
            result.push_back(box);
        }
    }
Exemplo n.º 16
0
 /**
  * Copies box boundaries (must be of the same dimension)
  * @param sbox source box
  * @param dbox dest box
  */
 template <class FT> static void copy(const Box<FT> &sbox, Box<FT> &dbox) {
     int n = sbox.mDim;
     BNB_ASSERT(n == dbox.mDim);
     for (int i = 0; i < n; i++) {
         dbox.mB[i] = sbox.mB[i];
         dbox.mA[i] = sbox.mA[i];
     }
 }
Exemplo n.º 17
0
 /**
  * Morse potential
  * @param a1 the type of the first atom
  * @param a2 the type of the second atom
  * @param q the square distance
  * @return the value of potential
  */
 double morsepotent(int a1, int a2, double q) {
     BNB_ASSERT(q >= 0);
     double r = sqrt(q);
     const double rho = 14;
     double E = exp(rho * (1 - r));
     double p = E * (E - 2);
     return p;
 }
Exemplo n.º 18
0
 bool make(const  GOFactory<double>::Set& s,  GOFactory<double>::Solution& sol)
 {      
   BNB_ASSERT(mObj);
   BNB_ASSERT(mProj);
   int n = mObj->getDim();
   double* x = getX(n);
   for(int i = 0; i < n; i ++) {
     x[i] = 0.5 * (s.mA[i] + s.mB[i]);
   }
   mProj->project(x, (double*)sol.mX);
   sol.mFval = mObj->func((double*)sol.mX);
   /** TMP **/
   /*mObj->grad(sol.mX.getPtr(), x);
   double norm = VecUtils::vecNormTwo(n - 1, x);
   sol.mX[n - 1] = norm / 2.;*/
   return true;
 }
Exemplo n.º 19
0
 /**
  * The constructor
  * @param problem data
  */
 MBoxLocalSearch(MultiData<FT> &md, std::vector<FT>& coeff, LocalBoxOptimizer<FT>* opt) :
 MultiLocalSearch<FT>(md),
 mObj(md.mCriteria, coeff),
 mBox(md.mBox),
 mOptions(0),
 mOpt(opt) {
     mOpt->setObjective(&mObj);
     BNB_ASSERT(md.mConstraints.empty());
 }
Exemplo n.º 20
0
 /**
  * Initialize memory managent
  * @param memsize  maximal size per thread
  * @param maxchunks maximal memory blocks
  * @param maxsizes expected maximum of different memory blocks
  */
 void init(int memsize, int maxchunks = DEFAULT_MAX_CHUNKS, int maxsizes = DEFAULT_MAX_SIZES)
 {
   BNB_ASSERT(mNumThreads);
   for(int i = 0; i < mNumThreads; i ++) {
     SimpMemManager* mm = new SimpMemManager(memsize, maxchunks, 8);
     mManagers[i] = mm;
   }
   mAuxMemManager = new SimpMemManager(memsize, maxchunks, 8);
 }
Exemplo n.º 21
0
double ljpotent(int a1, int a2, double q) {
    BNB_ASSERT(q >= 0);
    if (q == 0)
        q = 0.00001;
    double u = q * q * q;
    double v = u * u;
    double p = 1. / v - 2. / u;
    return p;
}
Exemplo n.º 22
0
 Qubic(FT a, FT b, FT c, FT d, FT eps = 0.000001)
 {
   BNB_ASSERT(a);
   mA = a;
   mB = b;
   mC = c;
   mD = d;
   mEps = eps;
   printf("COEF: %lf, %lf, %lf, %lf\n", mA, mB, mC, mD);
 }
Exemplo n.º 23
0
    void erase(int b, int e)
    {
      int shft;
      shft = e - b + 1;
      BNB_ASSERT(shft > 0);
      for(int i = e + 1; i < mSize; i ++) {
	mArrSeg[i - shft] = mArrSeg[i];
      }
      mSize -= shft;
    }
Exemplo n.º 24
0
 void processMkdir(std::string& dir)
 {
   int rc;
   std::string* dname;      
   mode_t mod;
   dname = getIdent(dir);
   mod = 0777;
   rc = mkdir(dname->c_str(), mod);
   BNB_ASSERT(rc == 0);
   eraseCommand();
 }
Exemplo n.º 25
0
 /**
  * Setup number of starts
  * @param n number of starts
  */
 void pregenerate(int n)
 {
   BNB_ASSERT(mN);
   if(n != mNOS) {
     mNOS = n;
     if(mGen != NULL) 
       free(mGen);        
     mGen = (FT*) malloc(mNOS * mN * sizeof(FT));
     BNB_ASSERT(mGen);
   }
   for(int i = 0; i < mNOS; i ++) {
     FT* y;
     y = mGen + i * mN;
     for(int j = 0; j < mN; j ++) {
       FT alpha;
       alpha = mAmpl * (0.5 - ((double)rand() / (double)RAND_MAX));
       y[j] = alpha;
     }              
   }
 }
Exemplo n.º 26
0
void testCommunicator(Communicator* comm) {
    BinarySerializer ser;
    if (comm->rank() == 0) {
        int message = MAGIC_NUMBER;
        ser << message;
        comm->send(ser, 1);
    } else if(comm->rank() == 1) {
        int message;
        comm->recv(ser, 0);
        ser >> message;
        BNB_ASSERT(message == MAGIC_NUMBER);
    }
Exemplo n.º 27
0
 void processAppend(std::string& lop, std::string& rop)
 {
   std::string *plop, *prop;
   FILE* f;
   plop = getIdent(lop);
   prop = getIdent(rop);
   f = fopen(prop->c_str(), "a");
   BNB_ASSERT(f);
   fprintf(f, "%s", plop->c_str());
   fclose(f);
   eraseCommand();
 }
Exemplo n.º 28
0
    /**
     * Reads the description from the string
     * @param json the json description as a string
     * @param kd the resulting knapsack data
     */
    static void readJson(const std::string& json, KnapData< T >& kd) {

        struct {
            bool mNSet;
            bool mCSet;
            bool mWSet;
            bool mPSet;
        } checklist = {false, false, false, false};

        JSONNode nd = libjson::parse(json);
        JSONNode::const_iterator i = nd.begin();
        kd.mN = 0;
        kd.mTP = 0;
        kd.mTW = 0;
        kd.mCoe = NULL;


        while (i != nd.end()) {
            std::string name = i->name();
            //std::cout << "node \"" << name << "\"\n";
            if (name == JSON_KNAP_N) {
                kd.mN = i->as_int();
                kd.mCoe = new KnapRecord<T>[kd.mN];
                BNB_ASSERT(kd.mCoe);
                checklist.mNSet = true;
            } else if (name == JSON_KNAP_C) {
                kd.mC = i->as_int();
                checklist.mCSet = true;
            } else if (name == JSON_KNAP_W) {
                BNB_ASSERT(kd.mCoe);
                parseW(*i, kd, checklist.mPSet);
                checklist.mWSet = true;
            } else if (name == JSON_KNAP_P) {
                BNB_ASSERT(kd.mCoe);
                parseP(*i, kd, checklist.mWSet);
                checklist.mPSet = true;
            }
            i++;
        }
    }
Exemplo n.º 29
0
 void deleteNode(BNBNode* node) {
     BNB_ASSERT(node);
     BNB_ASSERT(node->mData != NULL);
     BNBNode* next = node->mNext;
     BNBNode* prev = node->mPrev;
     BNBNode* par = node->mParent;
     /* Deletes data */
     delete node->mData;
     delete node;
     /* Check if the last child */
     if ((next == NULL) && (prev == NULL)) {
         if (par)
             deleteNode(par);
     } else {
         if (next != NULL) {
             next->mPrev = prev;
         }
         if (prev != NULL) {
             prev->mNext = next;
         }
     }
 }
Exemplo n.º 30
0
 std::string* getIdent(std::string& ident)
 {
   BNB_ASSERT(ident.size());
   if(ident[0] == '$') {
     std::string nident, *var;
     nident.assign(ident, 1, ident.size() - 1);
     var = getIdent(nident);
     return getMem(var);
   } else if(ident[0] == '@') {
     std::string nident;
     nident.assign(ident, 1, ident.size() - 1);
     return getSpecVar(&nident);
   } else 
     return &ident;
 }