Example #1
0
int main(int argc, char * argv[])
{
    
 if (argc == 1)
    {
     fprintf(stderr, "ERROR neboli zadane ziade argumenty\n"); // ak nieje zadany argument tak vypisem chybu
     return EXIT_FAILURE;
    } 
 if (argc > 6)
    {
     fprintf(stderr, "ERROR bolo zadanych vela argumentov\n");
     return EXIT_FAILURE;
    } 
 if ((strcmp(argv[1],"--help")==0))// ak je zadany argumet --help vypise napovedu 
    {
     helpmsg();
     return EXIT_SUCCESS;
    }
    else if ((strcmp(argv[1],"--tan")==0) && argc == 5) //ak je zadany argument --tan prebehne vypocet tangensu
    {  
     tang(argc,argv);
     return EXIT_SUCCESS;
    }
 else if ((strcmp(argv[1],"-m")==0) || (strcmp(argv[1],"-c")==0) ) // ak je zadany argument -m prebehne vypoccet vzdialenosti
    {
     range(argc,argv);
     return EXIT_SUCCESS;
    }
 return EXIT_SUCCESS;
}
Example #2
0
File: main.c Project: SAMOXA/calc
int main() {
	int action = 0;
	char exitFlag = 0;
	while(exitFlag == 0){
		printf("1) Add\n");
		printf("2) Sub\n");
		printf("3) Mul\n");
		printf("4) Div\n");
		printf("5) Mod\n");
		printf("6) AddMod2\n");
		printf("7) Sin\n");
		printf("8) Cos\n");
		printf("9) Tan\n");
		printf("10) ArcTan\n");
		printf("11) Factorial\n");
		printf("12) Exit\n" );
		printf("Action: ");
		scanf("%d", &action);
		getchar();
		fflush(stdin);
		sync();
		switch(action) {
			case(1): add(); break;
			case(2): sub_func(); break;
			case(3): multiplication(); break;
			case(4): Div(); break;
			case(5): mod(); break;
			case(6): modul2(); break;
			case(7): sinus(); break;
			case(8): my_cos(); break;
			case(9): tang(); break;
			case(10): arctg(); break;
			case(11): factorial(); break;
			case(12): exitFlag = 1; break;
			default: printf("Wrong index\n");
		}
	}
	return 0;
}
Example #3
0
void setGeo(
    std::vector<float> verts,
    std::vector<float> normals,
    std::vector<float> tangents,
    std::vector<float> binormals,
    std::vector<float> texcoords1,
    std::vector<float> texcoords2,
    std::vector<unsigned> indices,
    bool get_tanspace)
{
    if(indices.size() <= 0)
        throw tgException("no triangle indices supplied");
    else if(indices.size() % 3 != 0)
        throw tgException("triangle indices must come in packs of three");

    unsigned num_verts = verts.size();
    if(num_verts <= 0)
        throw tgException("no vertices supplied");
    else if(num_verts % 3 != 0)
        throw tgException("vertices must have three components each");
    num_verts /= 3;

    std::unique_ptr<int16_t[]> norms, tangs, binorms;
    float *tex1, *tex2;

    if(normals.empty())
    {
        norms = nullptr;
        tangs = nullptr;
        binorms = nullptr;
    }
    else if(normals.size() != num_verts * 3)
        throw tgException("number of normals does not match number of vertices");
    else
    {
        norms.reset(new int16_t[num_verts * 3]);
        for(unsigned i = 0; i < num_verts * 3; ++i)
        {
            norms[i] = (int16_t)(normals[i] * std::numeric_limits<int16_t>::max());
        }

        if(tangents.empty())
            tangs = nullptr;
        else if(tangents.size() != num_verts * 3)
            throw tgException("number of tangents does not match number of vertices");
        else
        {
            tangs.reset(new int16_t[num_verts * 3]);
            for(unsigned i = 0; i < num_verts * 3; ++i)
            {
                tangs[i] = (int16_t)(tangents[i] * std::numeric_limits<int16_t>::max());
            }
        }

        if(binormals.empty())
            binorms = nullptr;
        else if(binormals.size() != num_verts * 3)
            throw tgException("number of binormals does not match number of vertices");
        else
        {
            binorms.reset(new int16_t[num_verts * 3]);
            for(unsigned i = 0; i < num_verts * 3; ++i)
            {
                binorms[i] = (int16_t)(binormals[i] * std::numeric_limits<int16_t>::max());
            }
        }

        if((bool)binorms != (bool)tangs && get_tanspace)
        {
            if((bool)tangs)
            {
                binorms.reset(new int16_t[num_verts * 3]);
                for(unsigned i = 0; i < num_verts * 3; i += 3)
                {
                    Eigen::Vector3f norm(normals[i], normals[i + 1], normals[i + 2]);
                    Eigen::Vector3f tang(tangents[i], tangents[i + 1], tangents[i + 2]);
                    Eigen::Vector3f bin = norm.cross(tang);
                    binorms[i] = (int16_t)(bin[0] * std::numeric_limits<int16_t>::max());
                    binorms[i + 1] = (int16_t)(bin[1] * std::numeric_limits<int16_t>::max());
                    binorms[i + 2] = (int16_t)(bin[2] * std::numeric_limits<int16_t>::max());
                }
            }
            else
            {
                tangs.reset(new int16_t[num_verts * 3]);
                for(unsigned i = 0; i < num_verts * 3; i += 3)
                {
                    Eigen::Vector3f norm(normals[i], normals[i + 1], normals[i + 2]);
                    Eigen::Vector3f bin(binormals[i], binormals[i + 1], binormals[i + 2]);
                    Eigen::Vector3f tang = bin.cross(norm);
                    tangs[i] = (int16_t)(tang[0] * std::numeric_limits<int16_t>::max());
                    tangs[i + 1] = (int16_t)(tang[1] * std::numeric_limits<int16_t>::max());
                    tangs[i + 2] = (int16_t)(tang[2] * std::numeric_limits<int16_t>::max());
                }
            }
        }
    }

    if(texcoords1.empty())
        tex1 = nullptr;
    else if(texcoords1.size() != num_verts * 2)
        throw tgException(
            "number if texcoords stream 1 does not match number of vertices");
    else tex1 = texcoords1.data();

    if(texcoords2.empty())
        tex2 = nullptr;
    else if(texcoords2.size() != num_verts * 2)
        throw tgException(
            "number if texcoords stream 2 does not match number of vertices");
    else tex2 = texcoords2.data();

    H3DRes res;
    try
    {
        res = _makeGeometry(num_verts, verts.data(), norms.get(), tangs.get(),
                            binorms.get(), tex1, tex2, indices.size() / 3, indices.data());
    }
    catch(...)
    {
        dumpMessages();
        throw;
    }

    if(_geometry) h3dUnloadResource(_geometry);
    _geometry = res;

    if(_geometry != 0 && _shader != 0)
        Viewer::newModel(_geometry, _mat_builder->getRes());
    dumpMessages();
}
Example #4
0
//create the mesh for edges based on variable size from SizingFunction (var)
void EdgeMesher::VariableMeshing(ModelEnt *ent, int &num_edges, std::vector<double> &coords)
{
  double umin, umax, measure;
  (void) measure;
  // because of that, keep track of the first node position and last node position
  // first node position does not change, but the last node position do change
  // coords will contain all nodes, including umax in Urecord!

  SizingFunction *sf = mk_core()->sizing_function(ent->sizing_function_index());
  //get the u range for the edge
  iGeom::EntityHandle edge = ent->geom_handle();
  iGeom::Error gerr = ent->igeom_instance() ->getEntURange(edge, umin, umax);
  IBERRCHK(gerr, "Trouble get parameter range for edge.");

  if (umin == umax) throw Error(MK_BAD_GEOMETRIC_EVALUATION, "Edge evaluated to some parameter umax and umin.");

  //get the arc length
  measure = ent -> measure();

  // start advancing for each edge mesh, from the first point position
  double currentPar = umin;
  double currentPosition[3];
  gerr = ent->igeom_instance() ->getEntUtoXYZ(edge, umin, currentPosition[0],
      currentPosition[1], currentPosition[2] );

  double endPoint[3];
  gerr = ent->igeom_instance() ->getEntUtoXYZ(edge, umax, endPoint[0],
      endPoint[1], endPoint[2] );
  Vector<3> endpt(endPoint);

  double targetSize = sf->size(currentPosition);
  double startSize = targetSize;

  double endSize = sf->size(endPoint);
  // advance u such that the next point is at "currentSize" distance
  // or close to it
  // try first with a u that is coming from the (umax-umin)/number of edges
  double deltaU = (umax-umin)/num_edges;
  //coords.clear(); we do not want to clear, as the first node is still fine
  std::vector<double> URecord;    //record the values for u; we may have to adjust all
  // of them accordingly, and even add one more if we have some evenify problems.
  // keep in mind that size is just a suggestion, number of intervals is more important for
  // paver mesher
  Vector<3> pt(currentPosition);

  //bool notDone = true;
  double prevU = umin;
  while (currentPar + 1.1*deltaU < umax)
  {
    // do some binary search; actually, better, do Newton-Raphson, which should converge
    // faster
    //
    prevU = currentPar;
    currentPar += deltaU;
    // adjust current par, such that
    double point[3];
    gerr=ent->igeom_instance()->getEntUtoXYZ(edge, currentPar, point[0], point[1], point[2] );
    IBERRCHK(gerr, "Trouble getting position at parameter u.");
    Vector<3> ptCandidate(point);
    double compSize = length(ptCandidate-pt);
    int nit = 0;

    while ( (fabs(1.-compSize/targetSize)> 0.02 ) && (nit < 5))// 2% of the target size
    {
      // do Newton iteration
      double tangent[3];
      gerr=ent->igeom_instance() ->getEntTgntU(edge, currentPar, tangent[0], tangent[1], tangent[2] );
      IBERRCHK(gerr, "Trouble getting tangent at parameter u.");
      Vector<3> tang(tangent);
      double dldu = 1./compSize * ((ptCandidate-pt )%tang);
      nit++;// increase iteration count
      if (dldu!=0.)
      {
        double deu= (targetSize-compSize)/dldu;
        currentPar+=deu;
        if (prevU>currentPar)
        {
          break; // something is wrong
        }
        if (umax < currentPar)
        {
          currentPar = umax;
          break;
        }
        ent->igeom_instance()->getEntUtoXYZ(edge, currentPar, point[0], point[1], point[2]);
        Vector<3> newPt(point);
        compSize = length(newPt-pt);
        ptCandidate = newPt;
      }

    }
    // we have found an acceptable point/param
    URecord.push_back(currentPar);
    deltaU = currentPar-prevU;// should be greater than 0
    pt = ptCandidate;
    targetSize = sf->size(pt.data());// a new target size, at the current point



  }
  // when we are out of here, we need to adjust the URecords, to be more nicely
  // distributed; also, look at the evenify again
  int sizeU = (int)URecord.size();
  if ((sizeU%2==0) && ent->constrain_even() )
  {
    // add one more
    if (sizeU==0)
    {
      // just add one in the middle, and call it done
      URecord.push_back( (umin+umax)/2);
    }
    else
    {
      //at least 2 (maybe 4)
      double lastDelta = URecord[sizeU-1]-URecord[sizeU-2];
      URecord.push_back(URecord[sizeU-1]+lastDelta );
    }
  }
  // now, we have to redistribute, such as the last 2 deltas are about the same
  // so, we should have after a little work,
  // umin, umin+c*(URecord[0]-umin), ... umin+c*(URecord[size-1]-umin), umax
  // what we have now is
  // umin, URecord[0], ... ,URecord[size-1], and umax could be even outside or inside
  // keep the last sizes equal
  //  umin+c(UR[size-2]-umin) + umax = 2*( umin+c*(UR[size-1]-umin))
  //  c ( 2*(UR[size-1]-umin) -(UR[size-2]-umin) ) = umax - umin
  // c ( 2*UR[size-1] - UR[size-2] - umin ) = umax - umin
  // c = (umax-umin)/( 2*UR[size-1] - UR[size-2] - umin)
  sizeU = (int)URecord.size();// it may be bigger by one than the last time
  if (sizeU == 0)
  {
    // nothing to do, only one edge to generate
  }
  else if (sizeU == 1)
  {
    // put it according to the sizes at ends, and assume a nice variation for u
    // (u-umin) / (umax-u) = startSize / endSize
    // (u-umin)*endSize = (umax-u) * startSize
    // u(endSize+startSize)=(umax*startSize+umin*endSize)
    URecord[0] = (umax*startSize+umin*endSize)/(startSize+endSize);

  }
  else // sizeU>=2, so we can spread the param a little more, assuming nice
    // uniform mapping
  {
    double c =  (umax-umin)/( 2*URecord[sizeU-1] - URecord[sizeU-2] - umin);
    for (int i=0; i<sizeU; i++)
      URecord[i] = umin + c*(URecord[i] -umin);// some spreading out
  }
  // now, we can finally get the points for each U, U's should be spread out nicely
  URecord.push_back(umax); // just add the last u, for the end point
  //
  sizeU = (int) URecord.size(); // new size, after pushing the last u, umax
  num_edges = sizeU;// this is the new number of edges; the last one will be the end point
  // of the edge, corresponding to umax
  coords.resize(3*sizeU+3);
  // we already know that at i=0 is the first node, start vertex of edge
  // the rest will be computed from u
  // even the last one, which is an overkill
  for (int i = 1; i <= num_edges; i++)
  {
    double u = URecord[i-1];
    gerr = ent->igeom_instance()->getEntUtoXYZ(edge, u, coords[3*i], coords[3*i+1], coords[3*i+2]);
    IBERRCHK(gerr, "Trouble getting U from XYZ along the edge.");
  }
  return;

}
Example #5
0
void grgitn ( )
{

    /*	  CONTROLS MAIN ITERATIVE LOOP;  CALLS consbs TO COMPUTE    */
    /*	  INITIAL BASIS INVERSE ;  CALLS direc TO COMPUTE SEARCH    */
    /*	  DIRECTION;  CALLS ONE DIMENTIONAL SEARCH SUBROUTINE	    */
    /*	  search;  TEST FOR OPTIMALITY				    */

    /*	  Local Declarations	*/

    double  ts, tst, cons2, phhold, objtst, trubst;
    int   i, j, k, ii, jr, kk, iii, istop, msgcg, nfail, idegct;
    int   linect, iparm;

    /*	  INITIALIZE PERFORMANCE COUNTERS    */

    ncalls = 0;  /*  ncalls = NUMBER OF NEWTON CALLS  */
    nit = 0;     /*  nit    = CUMULATIVE NO. OF NEWTON ITERATIONS    */
    nftn = 1;    /*  nftn   = TOTAL NO. OF gcomp CALLS  */
    ngrad = 0;   /*  ngrad  = NO. OF GRADIENT CALLS  */
    nsear = 0;   /*  nsear  = NO. OF ONE DIMENTIONAL SEARCHES  */
    nsear0 = 0;  /*  nsear0 = VALUE OF NSEAR AT START FOR THIS NEWTON VALUE*/
    istop = 0;   /*  istop  = NO. OF CONSECUTIVE TIMES RELATIVE CHANGE  */
			  /*          IN FUNCTION IS LESS THAN epstop  */
    nbs = 0;     /*  nbs    = NO. OF TIMES BASIC VARIABLE VIOLATES BOUND  */
    nnfail = 0;  /*  nnfail = NO. TIMES NEWTON FAILD TO CONVERGE  */
    nstepc = 0;  /*  nstepc = NO. TIMES STEP SIZE CUT BACK WHEN NEWTON FAILS  */
/*08/1991 thru 11/1991*/
    scaled = 0;
    havescale = 0;
/*08/1991 thru 11/1991*/

    /*	  ADJUSTMENTS FOR USING TWO CONSTRAINT TOLERANCES    */

    epnewt = epinit;
    if ( eplast < epinit )  epstop = 10.0e0 * epstop;
    phhold = ph1eps;
    ipr = ipr3 + 1;
    linect = 60;
    iprhld = ipr;
    iprhd3 = ipr3;

    /*	  THIS IS RETURN POINT FOR epnewt LOOP	  */

w10 :
    drop = 0;		   /* COMMON LOGBLK, SRCHLG, SUPBLK */
    move = 1;
    restrt = 0;
    unbd = 0;
    jstfes = 0;
    degen = 0;
    uncon = 0;
    chngsb = 1;
    sbchng = 0;

    idegct = 0;
    nsuper = 0; 	   /* COMMOM NINTBK */
    trubst = 0.0e0;
    nsupp = 0;		   /* COMMON DIRGRG */
    ierr = 0;
    nfail = 0;
    msgcg = 1;
    stpbst = 1.0e0;
    lv = 0;
    istop = 0;
    objtst = plinfy;
    step = 0.0e0;
    cond = 1.0e0;
    ninf= 0;
    nb = 0;
    if ( iper != 0 )  {  ipr = 1;  ipr3 = 0; }
    for ( i = 1; i <= mp1; i++ )    x[n+i] = g[i];
    for ( i=1; i<=nbmax; i++ )
		for ( j=1; j<=nnbmax; j++ )  binv[i][j] = 0.0e0;

    /*	  THIS IS RETURN POINT FOR MAIN LOOP	*/

w40 : ;

    /*	  COMPUTE BASIS INVERSE, EXCEPT WHEN DEGENERATE    */

    consbs ( );

    if ( ninf == 0 || ph1eps == 0.0e0 )  goto w50;
    initph = 1;
    ph1obj();
    initph = 0;
w50 :
    if ( nsear != nsear0 )  goto w100;

    /*	INITIALIZATIONS THAT MUST BE DONE AFTER 1ST consbs CALLS  */
    /*	FOR EACH VALUE OF epnewt  */

    initph = 2;
    ph1obj();
    initph = 0;
    if ( nb == 0 )  goto w70;
    for ( i=1; i<=nb; i++ )  {
	k = ibv[i];
	xbest[i] = x[k];
    }
w70 :
    if ( nnbc == 0 )  goto w100;
    for ( i=1; i<=nnbc; i++ ) {
	k = inbc[i];
	xbest[nb+i] = g[k];
    }
    for ( i=1; i<=mp1; i++ )   gbest[i] = g[i];
w100 :
    /*	COMPUTE REDUCED GRADIENT  */

    redgra(gradf);

    if ( ipr < 4 ) goto w140;
    for ( i=1; i<=n; i++ )   xstat[i] = gradf[i];
    if ( maxim == 0 || ninf!= 0 )  goto w130;
    for ( i=1; i<=n; i++ )  xstat[i] = -xstat[i];
w130 :
    if ( ipr < 0 )  goto w140;
    fprintf ( ioout, "REDUCED GRADIENT IS\n");
    for ( i=1; i<=n; i++ )  fprintf ( ioout, "   %e\n", xstat[i] );
w140 :
    /*	===CHECK IF ANY OF THE STOP CRITERIA ARE SATISFIED===  */

    /*	UNCONDITIONAL STOP IF NUMBER OF LINEAR SEARCH > LIMSER	*/

    if ( nsear < limser )  goto w155;
    /*	DID REACH LIMIT SO QUIT  */

    if ( ipr < 0 )  goto w151;
    fprintf ( ioout, "NUMBER OF COMPLETED ONE-DIMENSIONAL SEARCHES = LIMSER");
    fprintf ( ioout, " =  %d.\nOPTIMIZATION TERMINATED.\n", nsear);
    linect++;
w151 :
    info = 3;
    ierr = 11;
    goto w520;

    /*	TEST IF KUHN-TUCKER CONDITIONS SATISFIED  */

w155 :
    for ( i=1; i<=n; i++ )  {
	ii = inbv[i];
	tst = gradf[i];
	if ( ii <= n )	goto w160;
	if ( istat[ii-n] == 1 )  goto w190;
w160 :
	if ( iub[i] == 0 )  goto w180;
	if ( iub[i] == 1 )  goto w170;
	if ( tst < -epstop )  goto w200;
	goto w190;
w170 :
	if ( tst > epstop ) goto w200;
	goto w190;
w180 :
	if ( fabs(tst) > epstop )  goto w200;
w190 :	;
    }

    /*	K-T CONDITIONS ARE SATISFIED.  GO CHECK IF epnewt AT FINAL VALUE  */

    if ( ipr < 0 )  goto w191;
    fprintf ( ioout, "TERMINATION CRITERION MET.  KUHN-TUCKER CONDITIONS");
    fprintf ( ioout, " SATISFIED TO\nWITHIN %e AT CURRENT POINT\n", epstop );
    linect++;
w191 :
    info = 0;
    goto w480;

    /*	CHECK IF RELATIVE CHANGE IN OBJECTIVE IS LESS THAN epstop  */
    /*	FOR nstop CONSECUTIVE ITERATIONS.    */

w200 :
    if ( degen == 1 )  goto w250;
    if ( fabs(g[nobj] - objtst) > fabs(objtst*epstop) )  goto w230;

    /*	FRACTIONAL CHANGE TOO SMALL.  COUNT HOW OFTEN CONSECUTIVELY.  */

    istop++;
    if ( istop < nstop )  goto w250;

    /*    FRACTIONAL CHANGE TOO SMALL nstop OR MORE TIMES.    */
    /*    SO GO CHECK IF epnewt AT FINAL VALUE  */

    if ( ipr < 0 )  goto w201;
    fprintf ( ioout, "TOTAL FRACTIONAL CHANGE IN OBJECTIVE LESS THAN %e\n", epstop);
    fprintf ( ioout, "  FOR %d CONSECUTIVE ITERATIONS\n", istop );
    linect = linect + 2;
w201 :
    ierr = 1;
    info = 1;
    goto w480;
w230 :
    istop = 0;
    chngsb = 0;
    objtst = g[nobj];

    /*	COMPUTE SEARCH DIRECTION FOR SUPERBASICS  */

w250 :
    direc();

    if ( dfail == 1 )  goto  w520;
    if ( ipr >= 4 )    {
	fprintf ( ioout, "DIRECTION VECTOR :\n" );
	for ( i=1; i<=nsuper; i++ )
	    fprintf ( ioout, "  D[%d] = %e\n", i, d[i] );
    }
    if ( nb == 0 )  goto w300;

    /*	COMPUTE TANGENT VECTOR V  */

    tang();

    if ( ipr >= 4 )  {
	fprintf ( ioout, "TANGENT VECTOR :\n" );
	for ( i=1; i<=nb; i++ )
	    fprintf ( ioout, "V[%d] = %e\n", i, v[i] );
    }

    /*	  FIND JP,  INDEX OF FIRST BASIC VARIABLE TO HIT A BOUND    */

    chuzr();

    if ( move == 1 )   goto w300;

    /*	  DEGENERATE AND NO MOVE IN BASICS IS POSSIBLE	  */

    jr = ibv[jp];
    if ( ipr >= 3 )
	fprintf (ioout, "BASIS DEGENERATE-- VARIABLE %d LEAVING BASIS\n", jr );
    lv = jp;
    degen = 1;
    idegct++;
    if ( idegct < 15 )   goto w281;
    if ( ipr < 0 )  goto w281;
    fprintf (ioout, "DEGENERATE FOR %d STEPS.  PROBABLY CYCLING.\n", idegct );

w281 :
    printdataline ( );

    /*      EXCHANGE BASIC WITH SOME SUPERBASIC AND UPDATE BINV   */

    chuzq();

    /*	  SET LOGICALS FOR USE BY DIREC    */

    restrt = 0;
    uncon = 0;
    sbchng = 1;
    mxstep = 1;

    /*	  NOW GO TO BEGIN NEW ITERATION FOR DEGENERATE CASE    */

    goto w100;

w300 :
    degen = 0;
    idegct = 0;

    printdataline ( );

    search();

    /* IF ABSOLUTE VALUE OF X'S IS VERY SMALL, CHANGE TO 0 TO AVOID UNDERFLOW */

    for ( i=1; i<=n; i++ )
	if ( fabs(x[i]) < eps )  x[i] = 0.0;

    nsear++;
    if ( nsear == ipn4 )  ipr = 4;
    if ( nsear == ipn5 )  ipr = 5;
    if ( nsear == ipn6 )  ipr = 6;
    ipr3 = ipr - 1;

    /*	IF SUPERBASIC HAS HIT BOUND, DELETE APPROPRIATE COLUMNS OF HESSIAN  */

    if ( mxstep == 0 )	goto w400;
    ii = nsuper;
    iii = nsuper;
    for ( kk=1; kk<=ii; kk++ )	{
	iparm = ii + 1 - kk;
	j = inbv[i];
	if ( fabs(x[j] - alb[j]) > epnewt && fabs(x[j] - ub[j]) >epnewt )  goto w390;
	iii--;
	if ( varmet == 1 )   delcol( &iparm );
	if ( iparm > iii )   goto w390;
	for ( k=iparm; k<=iii; k++ ) gradp[k] = gradp[k+1];
w390 :	;
    }
w400 :
    if ( succes == 1 )	 goto w440;

    /*	TROUBLE -- NO FUNCTION DECREASE  */
    /*	TRY DROPPING CONSTRAINTS ( AND GRADIENT STEP ) IF NOT DONE ALREADY  */

    if ( drop == 1 )   goto w435;
    drop = 1;
    chngsb = 1;
    goto w40;
w435 :
    /*	NO IMPROVEMENT IN LINESEARCH.  ALL REMEDIES FAILED.  */

    ierr = 2;
    if ( ipr < 0 )   goto w436;
    fprintf (ioout,"ALL REMEDIES HAVE FAILED TO FIND A BETTER POINT.");
    fprintf (ioout,"  PROGRAM TERMINATED.\n");
    linect = linect + 2;
w436 :
    info = 2;
    goto w480;
w440 :
    if ( unbd == 0 )   goto w450;

    /*	UNBOUNDED SOLUTION  */

    ierr = 20;
    if ( ipr < 0 )  goto w441;
    fprintf (ioout,"SOLUTION UNBOUNDED--FUNCTION IMPROVING AFTER DOUBLING STEP");
    fprintf (ioout," %d TIMES.\n", ndub);
    linect++;
w441 :
    info = 4;
    goto w520;
w450 :
    nfail = 0;
    restrt = 0;
    drop = 0;
    goto w40;

    /*********************************************************************/

    /*	SEGMENT CHECKS AND IF NEEDED ADJUSTS EPNEWT TO FINAL VALUE  */

w480 :
    if ( epnewt == eplast )   goto w520;
    printdataline ( );
    epnewt = eplast;
    if ( ipr < 0 )  goto w481;
    fprintf (ioout,"CONSTRAINT TOLERANCE HAS BEEN TIGHTENED TO ITS FINAL ");
    fprintf (ioout,"VALUE OF %e.\n", epnewt );
    linect = linect + 2;
w481 :
    epstop = 0.1 * epstop;
    nsear0 = nsear;
    ph1eps = 0.2;
    for ( i=1; i<=n; i++ )   {
	if ( ifix[i] != 0 )  goto w485;
	ts = ub[i] + epnewt;
	if ( x[i] > ts )  x[i] = ts;
	ts = alb[i] - epnewt;
	if ( x[i] < ts )  x[i] = ts;
w485 :	;
    }
    sclgcomp(g, x);
    nftn++;
    if ( maxim == 1 )	g[nobj] = -g[nobj];
    goto w10;

    /*************************************************************/

    /*	NORMAL TERMINATION STEP  */

w520 :
    printdataline ( );
    if ( ninf == 0 )   goto w540;

    /*	SOLUTION INFEASABLE  */

    if ( ipr < 0 )  goto w521;
    fprintf (ioout,"FEASIBLE POINT NOT FOUND.\n");
    fprintf (ioout,"  FINAL VALUE OF TRUE OBJECTIVE = %e.\n", truobj );
    fprintf (ioout,"  THE FOLLOWING %d CONSTRAINTS WERE IN VIOLATION:\n", ninf);
    linect = linect + 2;
w521 :
    info = info + 10;
    ierr = 9;
    for ( i=1; i<=nnbc; i++ )  {
	j =inbc[i];
	if ( g[j] > alb[n+j] && g[j] < ub[n+j] )   goto w530;
	if ( ipr < 0 )	goto w523;
/*08/1991 thru 11/1991*/
        if (scaled == 1)
            fprintf (ioout, "  %d    %e\n", j, g[j]*scale[n+j] );
        else
            fprintf (ioout, "  %d    %e\n", j, g[j] );
/*08/1991 thru 11/1991*/
w523 :	;
w530 :	;
    }
    g[nobj] = truobj;
w540 :
    if ( epnewt != eplast )    epstop = 0.1 * epstop;
    epnewt = eplast;
    ph1eps = phhold;

/*08/1991 thru 11/1991*/
    if ( scaled == 1 )
       /*  must unscale the x[*] and g[*] before returning */
       { for (i = 1; i <= n; i++ )
	     { x[i] /= scale[i];
	       if (ub[i]  < plinfy) ub[i]  /= scale[i];
	       if (alb[i] >-plinfy) alb[i] /= scale[i];
	     }
w1000 :
	 for (j = 1; j <= mp1; j++ )
	     { i = n + j;
	       g[j] *= scale[i];
	       if (ub[i] < plinfy)  ub[i]  *= scale[i];
	       if (alb[i] >-plinfy) alb[i] *= scale[i];
	     }
       }
w1010 :
/*08/1991 thru 11/1991*/
    return;
}