Beispiel #1
0
static SRes SzReadPackInfo(
	CSzData *sd,
	UInt64 *dataOffset,
	UInt32 *numPackStreams,
	UInt64 **packSizes,
	Byte **packCRCsDefined,
	UInt32 **packCRCs,
	ISzAlloc *alloc)
{
	UInt32 i;
	RINOK(SzReadNumber(sd, dataOffset));
	RINOK(SzReadNumber32(sd, numPackStreams));

	RINOK(SzWaitAttribute(sd, k7zIdSize));

	MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);

	for (i = 0; i < *numPackStreams; i++)
	{
	RINOK(SzReadNumber(sd, (*packSizes) + i));
	}

	for (;;)
	{
	UInt64 type;
	RINOK(SzReadID(sd, &type));
	if (type == k7zIdEnd)
		break;
	if (type == k7zIdCRC)
	{
		RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
		continue;
	}
	RINOK(SzSkeepData(sd));
	}
	if (*packCRCsDefined == 0)
	{
	MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc);
	MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc);
	for (i = 0; i < *numPackStreams; i++)
	{
		(*packCRCsDefined)[i] = 0;
		(*packCRCs)[i] = 0;
	}
	}
	return SZ_OK;
}
static int readSuperGraph(p3d_flatSuperGraph* fsg, p3d_rob* robot, xmlNodePtr parent) {
  xmlNodePtr cur = parent, *edgeTab = NULL;
  int nbNodes = 0, nbEdges = 0;
  if (!readGraphInfos(fsg, cur)) {
    printf("Error in graph parse: Can not read the graph infos\n");
    return FALSE;
  }
  //reset the number of node and edges(we increment the graph->nnode at each node addition)
  nbNodes = fsg->nNodes;
  fsg->nNodes = 0;
  nbEdges = fsg->nEdges;
  fsg->nEdges = 0;

  edgeTab = MY_ALLOC(xmlNodePtr, nbNodes);
  for (int i = 0; i < nbNodes; i++) {
    edgeTab[i] = NULL;
  }

  cur = cur->xmlChildrenNode;
  for (;cur != NULL; cur = cur->next) {
    if (!xmlStrcmp(cur->name, xmlCharStrdup("node"))) {
      if (!readXmlNode(fsg, robot, cur, edgeTab)) {
        printf("Error in graph parse: Can not read the node\n");
        for (int i = 0; i < fsg->nNodes; i++) {
          if (edgeTab[i] != NULL) {
            MY_FREE(edgeTab[i], xmlNode, 1);
          }
        }
        return FALSE;
      }
    } else if (xmlStrcmp(cur->name, xmlCharStrdup("text"))) {
      printf("Warning in graph parse: Unknown tag %s\n", (char*)cur->name);
    }
  }
  if (nbNodes != fsg->nNodes) {//compare the nodes numbers
    printf("Error in graph parse: All nodes are not parsed\n");
    for (int i = 0; i < fsg->nNodes; i++) {
      if (edgeTab[i] != NULL) {
        MY_FREE(edgeTab[i], xmlNode, 1);
      }
    }
    return FALSE;
  }
  if (!processXmlEdges(fsg, edgeTab)) {
    printf("Error in graph parse: Can not process nodes Edges\n");
    for (int i = 0; i < fsg->nNodes; i++) {
      if (edgeTab[i] != NULL) {
        MY_FREE(edgeTab[i], xmlNode, 1);
      }
    }
    return FALSE;
  }
  for (int i = 0; i < fsg->nNodes; i++) {
    if (edgeTab[i] != NULL) {
      MY_FREE(edgeTab[i], xmlNode, 1);
    }
  }
  return TRUE;
}
Beispiel #3
0
static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, uint8_t **v, ISzAlloc *alloc)
{
   uint8_t allAreDefined;
   size_t i;
   RINOK(SzReaduint8_t(sd, &allAreDefined));
   if (allAreDefined == 0)
      return SzReadBoolVector(sd, numItems, v, alloc);
   MY_ALLOC(uint8_t, *v, numItems, alloc);
   for (i = 0; i < numItems; i++)
      (*v)[i] = 1;
   return SZ_OK;
}
Beispiel #4
0
static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
{
  if (num == 0)
  {
    p->Defs = NULL;
    p->Vals = NULL;
  }
  else
  {
    MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);
    MY_ALLOC(UInt32, p->Vals, num, alloc);
  }
  return SZ_OK;
}
Beispiel #5
0
/*! \brief Create a link with a joint.
 *
 *  \param jntPt: the joint to link with
 *
 *  \return the new link with a joint structure
 */
p3d_read_jnt_link_data * p3d_rw_jnt_create_joint_link(void)
{
  p3d_read_jnt_link_data * jnt_linkPt;
  int i;

  jnt_linkPt = MY_ALLOC(p3d_read_jnt_link_data, 1);
  if (jnt_linkPt == NULL)
    { return NULL; }
  jnt_linkPt->jnt_num    = -1;
  jnt_linkPt->robot_num  = -1;
  jnt_linkPt->jnt_link   = NULL;
  jnt_linkPt->flag_prev  = TRUE;
  for(i=0; i<NB_POS_PARAM; i++)
    { jnt_linkPt->pos_param[i] = 0.0; }
  return jnt_linkPt;
}
Beispiel #6
0
static SRes SzReadHashDigests(
      CSzData *sd,
      size_t numItems,
      uint8_t **digestsDefined,
      uint32_t **digests,
      ISzAlloc *alloc)
{
   size_t i;
   RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc));
   MY_ALLOC(uint32_t, *digests, numItems, alloc);
   for (i = 0; i < numItems; i++)
      if ((*digestsDefined)[i])
      {
         RINOK(SzReaduint32_t(sd, (*digests) + i));
      }
   return SZ_OK;
}
Beispiel #7
0
static SRes SzReadBoolVector(CSzData *sd, size_t numItems, uint8_t **v, ISzAlloc *alloc)
{
   uint8_t b = 0;
   uint8_t mask = 0;
   size_t i;
   MY_ALLOC(uint8_t, *v, numItems, alloc);
   for (i = 0; i < numItems; i++)
   {
      if (mask == 0)
      {
         RINOK(SzReaduint8_t(sd, &b));
         mask = 0x80;
      }
      (*v)[i] = (uint8_t)(((b & mask) != 0) ? 1 : 0);
      mask >>= 1;
   }
   return SZ_OK;
}
Beispiel #8
0
static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
{
  Byte b = 0;
  Byte mask = 0;
  size_t i;
  MY_ALLOC(Byte, *v, numItems, alloc);
  for (i = 0; i < numItems; i++)
  {
    if (mask == 0)
    {
      RINOK(SzReadByte(sd, &b));
      mask = 0x80;
    }
    (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
    mask >>= 1;
  }
  return SZ_OK;
}
Beispiel #9
0
static SRes SzReadHeader2(
      CSzArEx *p,   /* allocMain */
      CSzData *sd,
      uint64_t **unpackSizes,  /* allocTemp */
      uint8_t **digestsDefined,    /* allocTemp */
      uint32_t **digests,         /* allocTemp */
      uint8_t **emptyStreamVector, /* allocTemp */
      uint8_t **emptyFileVector,   /* allocTemp */
      uint8_t **lwtVector,         /* allocTemp */
      ISzAlloc *allocMain,
      ISzAlloc *allocTemp)
{
   uint64_t type;
   uint32_t numUnpackStreams = 0;
   uint32_t numFiles = 0;
   CSzFileItem *files = 0;
   uint32_t numEmptyStreams = 0;
   uint32_t i;

   RINOK(SzReadID(sd, &type));

   if (type == k7zIdArchiveProperties)
   {
      RINOK(SzReadArchiveProperties(sd));
      RINOK(SzReadID(sd, &type));
   }


   if (type == k7zIdMainStreamsInfo)
   {
      RINOK(SzReadStreamsInfo(sd,
               &p->dataPos,
               &p->db,
               &numUnpackStreams,
               unpackSizes,
               digestsDefined,
               digests, allocMain, allocTemp));
      p->dataPos += p->startPosAfterHeader;
      RINOK(SzReadID(sd, &type));
   }

   if (type == k7zIdEnd)
      return SZ_OK;
   if (type != k7zIdFilesInfo)
      return SZ_ERROR_ARCHIVE;

   RINOK(SzReadNumber32(sd, &numFiles));
   p->db.NumFiles = numFiles;

   MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);

   p->db.Files = files;
   for (i = 0; i < numFiles; i++)
      SzFile_Init(files + i);

   for (;;)
   {
      uint64_t size;
      RINOK(SzReadID(sd, &type));
      if (type == k7zIdEnd)
         break;
      RINOK(SzReadNumber(sd, &size));
      if (size > sd->Size)
         return SZ_ERROR_ARCHIVE;
      if ((uint64_t)(int)type != type)
      {
         RINOK(SzSkeepDataSize(sd, size));
      }
      else
         switch((int)type)
         {
            case k7zIdName:
               {
                  size_t namesSize;
                  RINOK(SzReadSwitch(sd));
                  namesSize = (size_t)size - 1;
                  if ((namesSize & 1) != 0)
                     return SZ_ERROR_ARCHIVE;
                  if (!Buf_Create(&p->FileNames, namesSize, allocMain))
                     return SZ_ERROR_MEM;
                  MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
                  memcpy(p->FileNames.data, sd->Data, namesSize);
                  RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets))
                     RINOK(SzSkeepDataSize(sd, namesSize));
                  break;
               }
            case k7zIdEmptyStream:
               {
                  RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp));
                  numEmptyStreams = 0;
                  for (i = 0; i < numFiles; i++)
                     if ((*emptyStreamVector)[i])
                        numEmptyStreams++;
                  break;
               }
            case k7zIdEmptyFile:
               {
                  RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
                  break;
               }
            case k7zIdWinAttributes:
               {
                  RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
                  RINOK(SzReadSwitch(sd));
                  for (i = 0; i < numFiles; i++)
                  {
                     CSzFileItem *f = &files[i];
                     uint8_t defined = (*lwtVector)[i];
                     f->AttribDefined = defined;
                     f->Attrib = 0;
                     if (defined)
                     {
                        RINOK(SzReaduint32_t(sd, &f->Attrib));
                     }
                  }
                  IAlloc_Free(allocTemp, *lwtVector);
                  *lwtVector = NULL;
                  break;
               }
            case k7zIdMTime:
               {
                  RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
                  RINOK(SzReadSwitch(sd));
                  for (i = 0; i < numFiles; i++)
                  {
                     CSzFileItem *f = &files[i];
                     uint8_t defined = (*lwtVector)[i];
                     f->MTimeDefined = defined;
                     f->MTime.Low = f->MTime.High = 0;
                     if (defined)
                     {
                        RINOK(SzReaduint32_t(sd, &f->MTime.Low));
                        RINOK(SzReaduint32_t(sd, &f->MTime.High));
                     }
                  }
                  IAlloc_Free(allocTemp, *lwtVector);
                  *lwtVector = NULL;
                  break;
               }
            default:
               {
                  RINOK(SzSkeepDataSize(sd, size));
               }
         }
   }

   {
      uint32_t emptyFileIndex = 0;
      uint32_t sizeIndex = 0;
      for (i = 0; i < numFiles; i++)
      {
         CSzFileItem *file = files + i;
         file->IsAnti = 0;
         if (*emptyStreamVector == 0)
            file->HasStream = 1;
         else
            file->HasStream = (uint8_t)((*emptyStreamVector)[i] ? 0 : 1);
         if (file->HasStream)
         {
            file->IsDir = 0;
            file->Size = (*unpackSizes)[sizeIndex];
            file->Crc = (*digests)[sizeIndex];
            file->CrcDefined = (uint8_t)(*digestsDefined)[sizeIndex];
            sizeIndex++;
         }
         else
         {
            if (*emptyFileVector == 0)
               file->IsDir = 1;
            else
               file->IsDir = (uint8_t)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
            emptyFileIndex++;
            file->Size = 0;
            file->Crc = 0;
            file->CrcDefined = 0;
         }
      }
   }
   return SzArEx_Fill(p, allocMain);
}
Beispiel #10
0
static SRes SzReadUnpackInfo(
      CSzData *sd,
      uint32_t *numFolders,
      CSzFolder **folders,  /* for alloc */
      ISzAlloc *alloc,
      ISzAlloc *allocTemp)
{
   uint32_t i;
   RINOK(SzWaitAttribute(sd, k7zIdFolder));
   RINOK(SzReadNumber32(sd, numFolders));
   {
      RINOK(SzReadSwitch(sd));

      MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);

      for (i = 0; i < *numFolders; i++)
         SzFolder_Init((*folders) + i);

      for (i = 0; i < *numFolders; i++)
      {
         RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));
      }
   }

   RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));

   for (i = 0; i < *numFolders; i++)
   {
      uint32_t j;
      CSzFolder *folder = (*folders) + i;
      uint32_t numOutStreams = SzFolder_GetNumOutStreams(folder);

      MY_ALLOC(uint64_t, folder->UnpackSizes, (size_t)numOutStreams, alloc);

      for (j = 0; j < numOutStreams; j++)
      {
         RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
      }
   }

   for (;;)
   {
      uint64_t type;
      RINOK(SzReadID(sd, &type));
      if (type == k7zIdEnd)
         return SZ_OK;
      if (type == k7zIdCRC)
      {
         SRes res;
         uint8_t *crcsDefined = 0;
         uint32_t *crcs = 0;
         res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
         if (res == SZ_OK)
         {
            for (i = 0; i < *numFolders; i++)
            {
               CSzFolder *folder = (*folders) + i;
               folder->UnpackCRCDefined = crcsDefined[i];
               folder->UnpackCRC = crcs[i];
            }
         }
         IAlloc_Free(allocTemp, crcs);
         IAlloc_Free(allocTemp, crcsDefined);
         RINOK(res);
         continue;
      }
      RINOK(SzSkeepData(sd));
   }
}
Beispiel #11
0
static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
{
   uint32_t numCoders, numBindPairs, numPackStreams, i;
   uint32_t numInStreams = 0, numOutStreams = 0;

   RINOK(SzReadNumber32(sd, &numCoders));
   if (numCoders > NUM_FOLDER_CODERS_MAX)
      return SZ_ERROR_UNSUPPORTED;
   folder->NumCoders = numCoders;

   MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc);

   for (i = 0; i < numCoders; i++)
      SzCoderInfo_Init(folder->Coders + i);

   for (i = 0; i < numCoders; i++)
   {
      uint8_t mainuint8_t;
      CSzCoderInfo *coder = folder->Coders + i;
      {
         unsigned idSize, j;
         uint8_t longID[15];
         RINOK(SzReaduint8_t(sd, &mainuint8_t));
         idSize = (unsigned)(mainuint8_t & 0xF);
         RINOK(SzReaduint8_ts(sd, longID, idSize));
         if (idSize > sizeof(coder->MethodID))
            return SZ_ERROR_UNSUPPORTED;
         coder->MethodID = 0;
         for (j = 0; j < idSize; j++)
            coder->MethodID |= (uint64_t)longID[idSize - 1 - j] << (8 * j);

         if ((mainuint8_t & 0x10) != 0)
         {
            RINOK(SzReadNumber32(sd, &coder->NumInStreams));
            RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
            if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||
                  coder->NumOutStreams > NUM_CODER_STREAMS_MAX)
               return SZ_ERROR_UNSUPPORTED;
         }
         else
         {
            coder->NumInStreams = 1;
            coder->NumOutStreams = 1;
         }
         if ((mainuint8_t & 0x20) != 0)
         {
            uint64_t propertiesSize = 0;
            RINOK(SzReadNumber(sd, &propertiesSize));
            if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))
               return SZ_ERROR_MEM;
            RINOK(SzReaduint8_ts(sd, coder->Props.data, (size_t)propertiesSize));
         }
      }
      while ((mainuint8_t & 0x80) != 0)
      {
         RINOK(SzReaduint8_t(sd, &mainuint8_t));
         RINOK(SzSkeepDataSize(sd, (mainuint8_t & 0xF)));
         if ((mainuint8_t & 0x10) != 0)
         {
            uint32_t n;
            RINOK(SzReadNumber32(sd, &n));
            RINOK(SzReadNumber32(sd, &n));
         }
         if ((mainuint8_t & 0x20) != 0)
         {
            uint64_t propertiesSize = 0;
            RINOK(SzReadNumber(sd, &propertiesSize));
            RINOK(SzSkeepDataSize(sd, propertiesSize));
         }
      }
      numInStreams += coder->NumInStreams;
      numOutStreams += coder->NumOutStreams;
   }

   if (numOutStreams == 0)
      return SZ_ERROR_UNSUPPORTED;

   folder->NumBindPairs = numBindPairs = numOutStreams - 1;
   MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);

   for (i = 0; i < numBindPairs; i++)
   {
      CSzBindPair *bp = folder->BindPairs + i;
      RINOK(SzReadNumber32(sd, &bp->InIndex));
      RINOK(SzReadNumber32(sd, &bp->OutIndex));
   }

   if (numInStreams < numBindPairs)
      return SZ_ERROR_UNSUPPORTED;

   folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
   MY_ALLOC(uint32_t, folder->PackStreams, (size_t)numPackStreams, alloc);

   if (numPackStreams == 1)
   {
      for (i = 0; i < numInStreams ; i++)
         if (SzFolder_FindBindPairForInStream(folder, i) < 0)
            break;
      if (i == numInStreams)
         return SZ_ERROR_UNSUPPORTED;
      folder->PackStreams[0] = i;
   }
   else
      for (i = 0; i < numPackStreams; i++)
      {
         RINOK(SzReadNumber32(sd, folder->PackStreams + i));
      }
   return SZ_OK;
}
Beispiel #12
0
static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
{
   uint32_t startPos = 0;
   uint64_t startPosSize = 0;
   uint32_t i;
   uint32_t folderIndex = 0;
   uint32_t indexInFolder = 0;
   MY_ALLOC(uint32_t, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc);
   for (i = 0; i < p->db.NumFolders; i++)
   {
      p->FolderStartPackStreamIndex[i] = startPos;
      startPos += p->db.Folders[i].NumPackStreams;
   }

   MY_ALLOC(uint64_t, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);

   for (i = 0; i < p->db.NumPackStreams; i++)
   {
      p->PackStreamStartPositions[i] = startPosSize;
      startPosSize += p->db.PackSizes[i];
   }

   MY_ALLOC(uint32_t, p->FolderStartFileIndex, p->db.NumFolders, alloc);
   MY_ALLOC(uint32_t, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc);

   for (i = 0; i < p->db.NumFiles; i++)
   {
      CSzFileItem *file = p->db.Files + i;
      int emptyStream = !file->HasStream;
      if (emptyStream && indexInFolder == 0)
      {
         p->FileIndexToFolderIndexMap[i] = (uint32_t)-1;
         continue;
      }
      if (indexInFolder == 0)
      {
         /*
            v3.13 incorrectly worked with empty folders
            v4.07: Loop for skipping empty folders
            */
         for (;;)
         {
            if (folderIndex >= p->db.NumFolders)
               return SZ_ERROR_ARCHIVE;
            p->FolderStartFileIndex[folderIndex] = i;
            if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
               break;
            folderIndex++;
         }
      }
      p->FileIndexToFolderIndexMap[i] = folderIndex;
      if (emptyStream)
         continue;
      indexInFolder++;
      if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
      {
         folderIndex++;
         indexInFolder = 0;
      }
   }
   return SZ_OK;
}
Beispiel #13
0
/*! \brief Create a structure to store the parameters of the joints.
 *
 * \param type: the joint type.
 *
 * \return the joint data.
 */
p3d_read_jnt_data * p3d_create_read_jnt_data(p3d_type_joint type)
{
  p3d_read_jnt_data * data;
  int i;

  data = MY_ALLOC(p3d_read_jnt_data, 1);
  if (data == NULL) {
    PrintError(("Not enough memory !!!\n"));
    return NULL;
  }

  data->type = type;
  p3d_jnt_get_nb_param(type, &(data->nb_dof), &(data->nb_param));
  data->v         = MY_ALLOC(double, data->nb_dof);
  data->v_pos0    = MY_ALLOC(double, data->nb_dof);
  data->vmin      = MY_ALLOC(double, data->nb_dof);
  data->vmax      = MY_ALLOC(double, data->nb_dof);
  data->vmin_rand = MY_ALLOC(double, data->nb_dof);
  data->vmax_rand = MY_ALLOC(double, data->nb_dof);
  data->velocity_max = MY_ALLOC(double, data->nb_dof);
  data->acceleration_max = MY_ALLOC(double, data->nb_dof);
  data->jerk_max = MY_ALLOC(double, data->nb_dof);
  
  data->torque_max = MY_ALLOC(double, data->nb_dof);
  data->is_user   = MY_ALLOC(int,    data->nb_dof);
  data->is_active_for_planner   = MY_ALLOC(int,    data->nb_dof);
 
  if ((data->nb_dof>0) && 
      ((data->v == NULL) || (data->v_pos0 == NULL) ||
       (data->vmin == NULL) || (data->vmax == NULL) || 
       (data->vmin_rand == NULL) || (data->vmax_rand == NULL) ||
       (data->is_user == NULL) || (data->is_active_for_planner == NULL) ||
           ( data->velocity_max == NULL) || (data->acceleration_max == NULL) || ( data->jerk_max == NULL) )) {
    PrintError(("Not enough memory !!!\n"));
    return NULL;
  }
  data->flag_v            = FALSE;
  data->flag_v_pos0       = FALSE;
  data->flag_vmin         = FALSE;
  data->flag_vmax         = FALSE;
  data->flag_velocity_max = FALSE;
  data->flag_acceleration_max = FALSE;
  data->flag_jerk_max = FALSE;
  data->flag_torque_max   = FALSE;
  data->flag_vmin_rand    = FALSE;
  data->flag_vmax_rand    = FALSE;
  data->flag_is_user      = FALSE;
  data->flag_is_active_for_planner   = FALSE;
  for(i=0; i<data->nb_dof; i++)
    { data->v[i] = 0.0; }

  data->param      = MY_ALLOC(double, data->nb_param);
  if ((data->nb_param>0) && (data->param == NULL)) {
    PrintError(("Not enough memory !!!\n"));
    return NULL;
  }
  data->flag_param = FALSE;
  
  data->flag_pos = FALSE;
  data->flag_relative_pos = FALSE;

  data->prev_jnt = 0;
  data->flag_prev_jnt = FALSE;

  data->flag_name = FALSE;

  data->nb_links = 0;
  data->link_array = NULL;

  return data;
}
Beispiel #14
0
/* +-----------------------------------------------------------------------+ */
/* Subroutine */ void direct_direct_(fp fcn, doublereal *x, integer *n, doublereal *eps, doublereal epsabs, integer *maxf, integer *maxt, double starttime, double maxtime, int *force_stop, doublereal *minf, doublereal *l, 
	doublereal *u, integer *algmethod, integer *ierror, FILE *logfile, 
	doublereal *fglobal, doublereal *fglper, doublereal *volper, 
	doublereal *sigmaper, void *fcn_data)
{
    /* System generated locals */
    integer i__1, i__2;
    doublereal d__1;

    /* changed by SGJ to be dynamically allocated ... would be
       even better to use realloc, below, to grow these as needed */
    integer MAXFUNC = *maxf <= 0 ? 101000 : (*maxf + 1000 + *maxf / 2);
    integer MAXDEEP = *maxt <= 0 ? MAXFUNC/5: *maxt + 1000;
    const integer MAXDIV = 5000;

    /* Local variables */
    integer increase;
    doublereal *c__ = 0	/* was [90000][64] */, *f = 0	/* 
	    was [90000][2] */;
    integer i__, j, *s = 0	/* was [3000][2] */, t;
    doublereal *w = 0;
    doublereal divfactor;
    integer ifeasiblef, iepschange, actmaxdeep;
    integer actdeep_div__, iinfesiblef;
    integer pos1, newtosample;
    integer ifree, help;
    doublereal *oldl = 0, fmax;
    integer maxi;
    doublereal kmax, *oldu = 0;
    integer oops, *list2 = 0	/* was [64][2] */, cheat;
    doublereal delta;
    integer mdeep, *point = 0, start;
    integer *anchor = 0, *length = 0	/* was [90000][64] */, *arrayi = 0;
    doublereal *levels = 0, *thirds = 0;
    integer writed;
    doublereal epsfix;
    integer oldpos, minpos, maxpos, tstart, actdeep, ifreeold, oldmaxf;
    integer numfunc, version;
    integer jones;

    /* FIXME: change sizes dynamically? */
#define MY_ALLOC(p, t, n) p = (t *) malloc(sizeof(t) * (n)); \
                          if (!(p)) { *ierror = -100; goto cleanup; }

    /* Note that I've transposed c__, length, and f relative to the 
       original Fortran code.  e.g. length was length(maxfunc,n) 
       in Fortran [ or actually length(maxfunc, maxdims), but by
       using malloc I can just allocate n ], corresponding to
       length[n][maxfunc] in C, but I've changed the code to access
       it as length[maxfunc][n].  That is, the maxfunc direction
       is the discontiguous one.  This makes it easier to resize
       dynamically (by adding contiguous rows) using realloc, without
       having to move data around manually. */
    MY_ALLOC(c__, doublereal, MAXFUNC * (*n));
    MY_ALLOC(length, integer, MAXFUNC * (*n));
    MY_ALLOC(f, doublereal, MAXFUNC * 2);
    MY_ALLOC(point, integer, MAXFUNC);
    if (*maxf <= 0) *maxf = MAXFUNC - 1000;

    MY_ALLOC(s, integer, MAXDIV * 2);

    MY_ALLOC(anchor, integer, MAXDEEP + 2);
    MY_ALLOC(levels, doublereal, MAXDEEP + 1);
    MY_ALLOC(thirds, doublereal, MAXDEEP + 1);    
    if (*maxt <= 0) *maxt = MAXDEEP;

    MY_ALLOC(w, doublereal, (*n));
    MY_ALLOC(oldl, doublereal, (*n));
    MY_ALLOC(oldu, doublereal, (*n));
    MY_ALLOC(list2, integer, (*n) * 2);
    MY_ALLOC(arrayi, integer, (*n));

/* +-----------------------------------------------------------------------+ */
/* |    SUBROUTINE Direct                                                  | */
/* | On entry                                                              | */
/* |     fcn -- The argument containing the name of the user-supplied      | */
/* |            SUBROUTINE that returns values for the function to be      | */
/* |            minimized.                                                 | */
/* |       n -- The dimension of the problem.                              | */
/* |     eps -- Exceeding value. If eps > 0, we use the same epsilon for   | */
/* |            all iterations. If eps < 0, we use the update formula from | */
/* |            Jones:                                                     | */
/* |               eps = max(1.D-4*abs(minf),epsfix),                      | */
/* |            where epsfix = abs(eps), the absolute value of eps which is| */
/* |            passed to the function.                                    | */
/* |    maxf -- The maximum number of function evaluations.                | */
/* |    maxT -- The maximum number of iterations.                          | */
/* |            Direct stops when either the maximum number of iterations  | */
/* |            is reached or more than maxf function-evalutions were made.| */
/* |       l -- The lower bounds of the hyperbox.                          | */
/* |       u -- The upper bounds of the hyperbox.                          | */
/* |algmethod-- Choose the method, that is either use the original method  | */
/* |            as described by Jones et.al. (0) or use our modification(1)| */
/* | logfile -- File-Handle for the logfile. DIRECT expects this file to be| */
/* |            opened and closed by the user outside of DIRECT. We moved  | */
/* |            this to the outside so the user can add extra information  | */
/* |            to this file before and after the call to DIRECT.          | */
/* | fglobal -- Function value of the global optimum. If this value is not | */
/* |            known (that is, we solve a real problem, not a testproblem)| */
/* |            set this value to -1.D100 and fglper (see below) to 0.D0.  | */
/* |  fglper -- Terminate the optimization when the percent error          | */
/* |                100(f_min - fglobal)/max(1,abs(fglobal)) < fglper.     | */
/* |  volper -- Terminate the optimization when the volume of the          | */
/* |            hyperrectangle S with f(c(S)) = minf is less then volper   | */
/* |            percent of the volume of the original hyperrectangle.      | */
/* |sigmaper -- Terminate the optimization when the measure of the         | */
/* |            hyperrectangle S with f(c(S)) = minf is less then sigmaper.| */
/* |                                                                       | */
/* | User data that is passed through without being changed:               | */
/* |  fcn_data - opaque pointer to any user data                           | */
/* |                                                                       | */
/* | On return                                                             | */
/* |                                                                       | */
/* |       x -- The final point obtained in the optimization process.      | */
/* |            X should be a good approximation to the global minimum     | */
/* |            for the function within the hyper-box.                     | */
/* |                                                                       | */
/* |    minf -- The value of the function at x.                            | */
/* |  Ierror -- Error flag. If Ierror is lower 0, an error has occurred. The| */
/* |            values of Ierror mean                                      | */
/* |            Fatal errors :                                             | */
/* |             -1   u(i) <= l(i) for some i.                             | */
/* |             -2   maxf is too large.                                   | */
/* |             -3   Initialization in DIRpreprc failed.                  | */
/* |             -4   Error in DIRSamplepoints, that is there was an error | */
/* |                  in the creation of the sample points.                | */
/* |             -5   Error in DIRSamplef, that is an error occurred while  | */
/* |                  the function was sampled.                            | */
/* |             -6   Error in DIRDoubleInsert, that is an error occurred   | */
/* |                  DIRECT tried to add all hyperrectangles with the same| */
/* |                  size and function value at the center. Either        | */
/* |                  increase maxdiv or use our modification (Jones = 1). | */
/* |            Termination values :                                       | */
/* |              1   Number of function evaluations done is larger then   | */
/* |                  maxf.                                                | */
/* |              2   Number of iterations is equal to maxT.               | */
/* |              3   The best function value found is within fglper of    | */
/* |                  the (known) global optimum, that is                  | */
/* |                   100(minf - fglobal/max(1,|fglobal|))  < fglper.     | */
/* |                  Note that this termination signal only occurs when   | */
/* |                  the global optimal value is known, that is, a test   | */
/* |                  function is optimized.                               | */
/* |              4   The volume of the hyperrectangle with minf at its    | */
/* |                  center is less than volper percent of the volume of  | */
/* |                  the original hyperrectangle.                         | */
/* |              5   The measure of the hyperrectangle with minf at its   | */
/* |                  center is less than sigmaper.                        | */
/* |                                                                       | */
/* | SUBROUTINEs used :                                                    | */
/* |                                                                       | */
/* | DIRheader, DIRInitSpecific, DIRInitList, DIRpreprc, DIRInit, DIRChoose| */
/* | DIRDoubleInsert, DIRGet_I, DIRSamplepoints, DIRSamplef, DIRDivide     | */
/* | DIRInsertList, DIRreplaceInf, DIRWritehistbox, DIRsummary, Findareas  | */
/* |                                                                       | */
/* | Functions used :                                                      | */
/* |                                                                       | */
/* | DIRgetMaxdeep, DIRgetlevel                                            | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | Parameters                                                            | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | The maximum of function evaluations allowed.                          | */
/* | The maximum dept of the algorithm.                                    | */
/* | The maximum number of divisions allowed.                              | */
/* | The maximal dimension of the problem.                                 | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | Global Variables.                                                     | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | EXTERNAL Variables.                                                   | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | User Variables.                                                       | */
/* | These can be used to pass user defined data to the function to be     | */
/* | optimized.                                                            | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | Place to define, if needed, some application-specific variables.      | */
/* | Note: You should try to use the arrays defined above for this.        | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | End of application - specific variables !                             | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | Internal variables :                                                  | */
/* |       f -- values of functions.                                       | */
/* |divfactor-- Factor used for termination with known global minimum.     | */
/* |  anchor -- anchors of lists with deepness i, -1 is anchor for list of | */
/* |            NaN - values.                                              | */
/* |       S -- List of potentially optimal points.                        | */
/* |   point -- lists                                                      | */
/* |    ifree -- first free position                                        | */
/* |       c -- midpoints of arrays                                        | */
/* |  thirds -- Precalculated values of 1/3^i.                             | */
/* |  levels -- Length of intervals.                                       | */
/* |  length -- Length of intervall (index)                                | */
/* |       t -- actual iteration                                           | */
/* |       j -- loop-variable                                              | */
/* | actdeep -- the actual minimal interval-length index                   | */
/* |  Minpos -- position of the actual minimum                             | */
/* |    file -- The filehandle for a datafile.                             | */
/* |  maxpos -- The number of intervalls, which are truncated.             | */
/* |    help -- A help variable.                                           | */
/* | numfunc -- The actual number of function evaluations.                 | */
/* |   file2 -- The filehandle for an other datafile.                      | */
/* |  ArrayI -- Array with the indexes of the sides with maximum length.   | */
/* |    maxi -- Number of directions with maximal side length.             | */
/* |    oops -- Flag which shows if anything went wrong in the             | */
/* |            initialisation.                                            | */
/* |   cheat -- Obsolete. If equal 1, we don't allow Ktilde > kmax.        | */
/* |  writed -- If writed=1, store final division to plot with Matlab.     | */
/* |   List2 -- List of indicies of intervalls, which are to be truncated. | */
/* |       i -- Another loop-variable.                                     | */
/* |actmaxdeep-- The actual maximum (minimum) of possible Interval length. | */
/* |  oldpos -- The old index of the minimum. Used to print only, if there | */
/* |            is a new minimum found.                                    | */
/* |  tstart -- The start of the outer loop.                               | */
/* |   start -- The postion of the starting point in the inner loop.       | */
/* | Newtosample -- The total number of points to sample in the inner loop.| */
/* |       w -- Array used to divide the intervalls                        | */
/* |    kmax -- Obsolete. If cheat = 1, Ktilde was not allowed to be larger| */
/* |            than kmax. If Ktilde > kmax, we set ktilde = kmax.         | */
/* |   delta -- The distance to new points from center of old hyperrec.    | */
/* |    pos1 -- Help variable used as an index.                            | */
/* | version -- Store the version number of DIRECT.                        | */
/* | oldmaxf -- Store the original function budget.                        | */
/* |increase -- Flag used to keep track if function budget was increased   | */
/* |            because no feasible point was found.                       | */
/* | ifreeold -- Keep track which index was free before. Used with          | */
/* |            SUBROUTINE DIRReplaceInf.                                  | */
/* |actdeep_div-- Keep track of the current depths for divisions.          | */
/* |    oldl -- Array used to store the original bounds of the domain.     | */
/* |    oldu -- Array used to store the original bounds of the domain.     | */
/* |  epsfix -- If eps < 0, we use Jones update formula. epsfix stores the | */
/* |            absolute value of epsilon.                                 | */
/* |iepschange-- flag iepschange to store if epsilon stays fixed or is     | */
/* |             changed.                                                  | */
/* |DIRgetMaxdeep-- Function to calculate the level of a hyperrectangle.   | */
/* |DIRgetlevel-- Function to calculate the level and stage of a hyperrec. | */
/* |    fmax -- Keep track of the maximum value of the function found.     | */
/* |Ifeasiblef-- Keep track if a feasible point has  been found so far.    | */
/* |             Ifeasiblef = 0 means a feasible point has been found,     | */
/* |             Ifeasiblef = 1 no feasible point has been found.          | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | JG 09/25/00 Version counter.                                          | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | JG 09/24/00 Add another actdeep to keep track of the current depths   | */
/* |             for divisions.                                            | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* |JG 01/13/01 Added epsfix for epsilon update. If eps < 0, we use Jones  | */
/* |            update formula. epsfix stores the absolute value of epsilon| */
/* |            then. Also added flag iepschange to store if epsilon stays | */
/* |            fixed or is changed.                                       | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | JG 01/22/01 fmax is used to keep track of the maximum value found.    | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | JG 01/22/01 Ifeasiblef is used to keep track if a feasible point has  | */
/* |             been found so far. Ifeasiblef = 0 means a feasible point  | */
/* |             has been found, Ifeasiblef = 1 if not.                    | */
/* | JG 03/09/01 IInfeasible is used to keep track if an infeasible point  | */
/* |             has been found. IInfeasible > 0 means a infeasible point  | */
/* |             has been found, IInfeasible = 0 if not.                   | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* |                            Start of code.                             | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
    /* Parameter adjustments */
    --u;
    --l;
    --x;

    /* Function Body */
    writed = 0;
    jones = *algmethod;
/* +-----------------------------------------------------------------------+ */
/* | Save the upper and lower bounds.                                      | */
/* +-----------------------------------------------------------------------+ */
    i__1 = *n;
    for (i__ = 1; i__ <= i__1; ++i__) {
	oldu[i__ - 1] = u[i__];
	oldl[i__ - 1] = l[i__];
/* L150: */
    }
/* +-----------------------------------------------------------------------+ */
/* | Set version.                                                          | */
/* +-----------------------------------------------------------------------+ */
    version = 204;
/* +-----------------------------------------------------------------------+ */
/* | Set parameters.                                                       | */
/* |    If cheat > 0, we do not allow \tilde{K} to be larger than kmax, and| */
/* |    set \tilde{K} to set value if necessary. Not used anymore.         | */
/* +-----------------------------------------------------------------------+ */
    cheat = 0;
    kmax = 1e10;
    mdeep = MAXDEEP;
/* +-----------------------------------------------------------------------+ */
/* | Write the header of the logfile.                                      | */
/* +-----------------------------------------------------------------------+ */
    direct_dirheader_(logfile, &version, &x[1], n, eps, maxf, maxt, &l[1], &u[1], 
	    algmethod, &MAXFUNC, &MAXDEEP, fglobal, fglper, ierror, &epsfix, &
		      iepschange, volper, sigmaper);
/* +-----------------------------------------------------------------------+ */
/* | If an error has occurred while writing the header (we do some checking | */
/* | of variables there), return to the main program.                      | */
/* +-----------------------------------------------------------------------+ */
    if (*ierror < 0) {
	goto cleanup;
    }
/* +-----------------------------------------------------------------------+ */
/* | If the known global minimum is equal 0, we cannot divide by it.       | */
/* | Therefore we set it to 1. If not, we set the divisionfactor to the    | */
/* | absolute value of the global minimum.                                 | */
/* +-----------------------------------------------------------------------+ */
    if (*fglobal == 0.) {
	divfactor = 1.;
    } else {
	divfactor = fabs(*fglobal);
    }
/* +-----------------------------------------------------------------------+ */
/* | Save the budget given by the user. The variable maxf will be changed  | */
/* | if in the beginning no feasible points are found.                     | */
/* +-----------------------------------------------------------------------+ */
    oldmaxf = *maxf;
    increase = 0;
/* +-----------------------------------------------------------------------+ */
/* | Initialiase the lists.                                                | */
/* +-----------------------------------------------------------------------+ */
    direct_dirinitlist_(anchor, &ifree, point, f, &MAXFUNC, &MAXDEEP);
/* +-----------------------------------------------------------------------+ */
/* | Call the routine to initialise the mapping of x from the n-dimensional| */
/* | unit cube to the hypercube given by u and l. If an error occurred,     | */
/* | give out a error message and return to the main program with the error| */
/* | flag set.                                                             | */
/* | JG 07/16/01 Changed call to remove unused data.                       | */
/* +-----------------------------------------------------------------------+ */
    direct_dirpreprc_(&u[1], &l[1], n, &l[1], &u[1], &oops);
    if (oops > 0) {
	if (logfile)
	     fprintf(logfile,"WARNING: Initialization in DIRpreprc failed.\n");
	*ierror = -3;
	goto cleanup;
    }
    tstart = 2;
/* +-----------------------------------------------------------------------+ */
/* | Initialise the algorithm DIRECT.                                      | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | Added variable to keep track of the maximum value found.              | */
/* +-----------------------------------------------------------------------+ */
    direct_dirinit_(f, fcn, c__, length, &actdeep, point, anchor, &ifree,
	    logfile, arrayi, &maxi, list2, w, &x[1], &l[1], &u[1], 
	    minf, &minpos, thirds, levels, &MAXFUNC, &MAXDEEP, n, n, &
	    fmax, &ifeasiblef, &iinfesiblef, ierror, fcn_data, jones,
		    starttime, maxtime, force_stop);
/* +-----------------------------------------------------------------------+ */
/* | Added error checking.                                                 | */
/* +-----------------------------------------------------------------------+ */
    if (*ierror < 0) {
	if (*ierror == -4) {
	    if (logfile)
		 fprintf(logfile, "WARNING: Error occurred in routine DIRsamplepoints.\n");
	    goto cleanup;
	}
	if (*ierror == -5) {
	    if (logfile)
		 fprintf(logfile, "WARNING: Error occurred in routine DIRsamplef..\n");
	    goto cleanup;
	}
	if (*ierror == -102) goto L100;
    }
    else if (*ierror == DIRECT_MAXTIME_EXCEEDED) goto L100;
    numfunc = maxi + 1 + maxi;
    actmaxdeep = 1;
    oldpos = 0;
    tstart = 2;
/* +-----------------------------------------------------------------------+ */
/* | If no feasible point has been found, give out the iteration, the      | */
/* | number of function evaluations and a warning. Otherwise, give out     | */
/* | the iteration, the number of function evaluations done and minf.      | */
/* +-----------------------------------------------------------------------+ */
    if (ifeasiblef > 0) {
	 if (logfile)
	      fprintf(logfile, "No feasible point found in %d iterations "
		      "and %d function evaluations.\n", tstart-1, numfunc);
    } else {
	 if (logfile)
	      fprintf(logfile, "%d, %d, %g, %g\n", 
		      tstart-1, numfunc, *minf, fmax);
    }
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | Main loop!                                                            | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
    i__1 = *maxt;
    for (t = tstart; t <= i__1; ++t) {
/* +-----------------------------------------------------------------------+ */
/* | Choose the sample points. The indices of the sample points are stored | */
/* | in the list S.                                                        | */
/* +-----------------------------------------------------------------------+ */
	actdeep = actmaxdeep;
	direct_dirchoose_(anchor, s, &MAXDEEP, f, minf, *eps, epsabs, levels, &maxpos, length, 
		&MAXFUNC, &MAXDEEP, &MAXDIV, n, logfile, &cheat, &
		kmax, &ifeasiblef, jones);
/* +-----------------------------------------------------------------------+ */
/* | Add other hyperrectangles to S, which have the same level and the same| */
/* | function value at the center as the ones found above (that are stored | */
/* | in S). This is only done if we use the original DIRECT algorithm.     | */
/* | JG 07/16/01 Added Errorflag.                                          | */
/* +-----------------------------------------------------------------------+ */
	if (*algmethod == 0) {
	     direct_dirdoubleinsert_(anchor, s, &maxpos, point, f, &MAXDEEP, &MAXFUNC,
		     &MAXDIV, ierror);
	    if (*ierror == -6) {
		if (logfile)
		     fprintf(logfile,
"WARNING: Capacity of array S in DIRDoubleInsert reached. Increase maxdiv.\n"
"This means that there are a lot of hyperrectangles with the same function\n"
"value at the center. We suggest to use our modification instead (Jones = 1)\n"
			  );
		goto cleanup;
	    }
	}
	oldpos = minpos;
/* +-----------------------------------------------------------------------+ */
/* | Initialise the number of sample points in this outer loop.            | */
/* +-----------------------------------------------------------------------+ */
	newtosample = 0;
	i__2 = maxpos;
	for (j = 1; j <= i__2; ++j) {
	    actdeep = s[j + MAXDIV-1];
/* +-----------------------------------------------------------------------+ */
/* | If the actual index is a point to sample, do it.                      | */
/* +-----------------------------------------------------------------------+ */
	    if (s[j - 1] > 0) {
/* +-----------------------------------------------------------------------+ */
/* | JG 09/24/00 Calculate the value delta used for sampling points.       | */
/* +-----------------------------------------------------------------------+ */
		actdeep_div__ = direct_dirgetmaxdeep_(&s[j - 1], length, &MAXFUNC, 
			n);
		delta = thirds[actdeep_div__ + 1];
		actdeep = s[j + MAXDIV-1];
/* +-----------------------------------------------------------------------+ */
/* | If the current dept of division is only one under the maximal allowed | */
/* | dept, stop the computation.                                           | */
/* +-----------------------------------------------------------------------+ */
		if (actdeep + 1 >= mdeep) {
		    if (logfile)
			 fprintf(logfile, "WARNING: Maximum number of levels reached. Increase maxdeep.\n");
		    *ierror = -6;
		    goto L100;
		}
		actmaxdeep = MAX(actdeep,actmaxdeep);
		help = s[j - 1];
		if (! (anchor[actdeep + 1] == help)) {
		    pos1 = anchor[actdeep + 1];
		    while(! (point[pos1 - 1] == help)) {
			pos1 = point[pos1 - 1];
		    }
		    point[pos1 - 1] = point[help - 1];
		} else {
		    anchor[actdeep + 1] = point[help - 1];
		}
		if (actdeep < 0) {
		    actdeep = (integer) f[(help << 1) - 2];
		}
/* +-----------------------------------------------------------------------+ */
/* | Get the Directions in which to decrease the intervall-length.         | */
/* +-----------------------------------------------------------------------+ */
		direct_dirget_i__(length, &help, arrayi, &maxi, n, &MAXFUNC);
/* +-----------------------------------------------------------------------+ */
/* | Sample the function. To do this, we first calculate the points where  | */
/* | we need to sample the function. After checking for errors, we then do | */
/* | the actual evaluation of the function, again followed by checking for | */
/* | errors.                                                               | */
/* +-----------------------------------------------------------------------+ */
		direct_dirsamplepoints_(c__, arrayi, &delta, &help, &start, length, 
			logfile, f, &ifree, &maxi, point, &x[
			1], &l[1], minf, &minpos, &u[1], n, &MAXFUNC, &
			MAXDEEP, &oops);
		if (oops > 0) {
		    if (logfile)
			 fprintf(logfile, "WARNING: Error occurred in routine DIRsamplepoints.\n");
		    *ierror = -4;
		    goto cleanup;
		}
		newtosample += maxi;
/* +-----------------------------------------------------------------------+ */
/* | JG 01/22/01 Added variable to keep track of the maximum value found.  | */
/* +-----------------------------------------------------------------------+ */
		direct_dirsamplef_(c__, arrayi, &delta, &help, &start, length,
			    logfile, f, &ifree, &maxi, point, fcn, &x[
			1], &l[1], minf, &minpos, &u[1], n, &MAXFUNC, &
			MAXDEEP, &oops, &fmax, &ifeasiblef, &iinfesiblef, 
				   fcn_data, force_stop);
		if (force_stop && *force_stop) {
		     *ierror = -102;
		     goto L100;
		}
		if (nlopt_stop_time_(starttime, maxtime)) {
		     *ierror = DIRECT_MAXTIME_EXCEEDED;
		     goto L100;
		}
		if (oops > 0) {
		    if (logfile)
			 fprintf(logfile, "WARNING: Error occurred in routine DIRsamplef.\n");
		    *ierror = -5;
		    goto cleanup;
		}
/* +-----------------------------------------------------------------------+ */
/* | Divide the intervalls.                                                | */
/* +-----------------------------------------------------------------------+ */
		direct_dirdivide_(&start, &actdeep_div__, length, point, arrayi, &
			help, list2, w, &maxi, f, &MAXFUNC, &MAXDEEP, n);
/* +-----------------------------------------------------------------------+ */
/* | Insert the new intervalls into the list (sorted).                     | */
/* +-----------------------------------------------------------------------+ */
		direct_dirinsertlist_(&start, anchor, point, f, &maxi, length, &
			MAXFUNC, &MAXDEEP, n, &help, jones);
/* +-----------------------------------------------------------------------+ */
/* | Increase the number of function evaluations.                          | */
/* +-----------------------------------------------------------------------+ */
		numfunc = numfunc + maxi + maxi;
	    }
/* +-----------------------------------------------------------------------+ */
/* | End of main loop.                                                     | */
/* +-----------------------------------------------------------------------+ */
/* L20: */
	}
/* +-----------------------------------------------------------------------+ */
/* | If there is a new minimum, show the actual iteration, the number of   | */
/* | function evaluations, the minimum value of f (so far) and the position| */
/* | in the array.                                                         | */
/* +-----------------------------------------------------------------------+ */
	if (oldpos < minpos) {
	    if (logfile)
		 fprintf(logfile, "%d, %d, %g, %g\n",
			 t, numfunc, *minf, fmax);
	}
/* +-----------------------------------------------------------------------+ */
/* | If no feasible point has been found, give out the iteration, the      | */
/* | number of function evaluations and a warning.                         | */
/* +-----------------------------------------------------------------------+ */
	if (ifeasiblef > 0) {
	    if (logfile)
		 fprintf(logfile, "No feasible point found in %d iterations "
			 "and %d function evaluations\n", t, numfunc);
	}
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* |                       Termination Checks                              | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | JG 01/22/01 Calculate the index for the hyperrectangle at which       | */
/* |             minf is assumed. We then calculate the volume of this     | */
/* |             hyperrectangle and store it in delta. This delta can be   | */
/* |             used to stop DIRECT once the volume is below a certain    | */
/* |             percentage of the original volume. Since the original     | */
/* |             is 1 (scaled), we can stop once delta is below a certain  | */
/* |             percentage, given by volper.                              | */
/* +-----------------------------------------------------------------------+ */
	*ierror = jones;
	jones = 0;
	actdeep_div__ = direct_dirgetlevel_(&minpos, length, &MAXFUNC, n, jones);
	jones = *ierror;
/* +-----------------------------------------------------------------------+ */
/* | JG 07/16/01 Use precalculated values to calculate volume.             | */
/* +-----------------------------------------------------------------------+ */
	delta = thirds[actdeep_div__] * 100;
	if (delta <= *volper) {
	    *ierror = 4;
	    if (logfile)
		 fprintf(logfile, "DIRECT stopped: Volume of S_min is "
			 "%g%% < %g%% of the original volume.\n",
			 delta, *volper);
	    goto L100;
	}
/* +-----------------------------------------------------------------------+ */
/* | JG 01/23/01 Calculate the measure for the hyperrectangle at which     | */
/* |             minf is assumed. If this measure is smaller then sigmaper,| */
/* |             we stop DIRECT.                                           | */
/* +-----------------------------------------------------------------------+ */
	actdeep_div__ = direct_dirgetlevel_(&minpos, length, &MAXFUNC, n, jones);
	delta = levels[actdeep_div__];
	if (delta <= *sigmaper) {
	    *ierror = 5;
	    if (logfile)
		 fprintf(logfile, "DIRECT stopped: Measure of S_min "
			 "= %g < %g.\n", delta, *sigmaper);
	    goto L100;
	}
/* +-----------------------------------------------------------------------+ */
/* | If the best found function value is within fglper of the (known)      | */
/* | global minimum value, terminate. This only makes sense if this optimal| */
/* | value is known, that is, in test problems.                            | */
/* +-----------------------------------------------------------------------+ */
	if ((*minf - *fglobal) * 100 / divfactor <= *fglper) {
	    *ierror = 3;
	    if (logfile)
		 fprintf(logfile, "DIRECT stopped: minf within fglper of global minimum.\n");
	    goto L100;
	}
/* +-----------------------------------------------------------------------+ */
/* | Find out if there are infeasible points which are near feasible ones. | */
/* | If this is the case, replace the function value at the center of the  | */
/* | hyper rectangle by the lowest function value of a nearby function.    | */
/* | If no infeasible points exist (IInfesiblef = 0), skip this.           | */
/* +-----------------------------------------------------------------------+ */
	if (iinfesiblef > 0) {
	     direct_dirreplaceinf_(&ifree, &ifreeold, f, c__, thirds, length, anchor, 
		    point, &u[1], &l[1], &MAXFUNC, &MAXDEEP, n, n, 
		    logfile, &fmax, jones);
	}
	ifreeold = ifree;
/* +-----------------------------------------------------------------------+ */
/* | If iepschange = 1, we use the epsilon change formula from Jones.      | */
/* +-----------------------------------------------------------------------+ */
	if (iepschange == 1) {
/* Computing MAX */
	    d__1 = fabs(*minf) * 1e-4;
	    *eps = MAX(d__1,epsfix);
	}
/* +-----------------------------------------------------------------------+ */
/* | If no feasible point has been found yet, set the maximum number of    | */
/* | function evaluations to the number of evaluations already done plus   | */
/* | the budget given by the user.                                         | */
/* | If the budget has already be increased, increase it again. If a       | */
/* | feasible point has been found, remark that and reset flag. No further | */
/* | increase is needed.                                                   | */
/* +-----------------------------------------------------------------------+ */
	if (increase == 1) {
	    *maxf = numfunc + oldmaxf;
	    if (ifeasiblef == 0) {
		if (logfile)
		     fprintf(logfile, "DIRECT found a feasible point.  The "
			     "adjusted budget is now set to %d.\n", *maxf);
		increase = 0;
	    }
	}
/* +-----------------------------------------------------------------------+ */
/* | Check if the number of function evaluations done is larger than the   | */
/* | allocated budget. If this is the case, check if a feasible point was  | */
/* | found. If this is a case, terminate. If no feasible point was found,  | */
/* | increase the budget and set flag increase.                            | */
/* +-----------------------------------------------------------------------+ */
	if (numfunc > *maxf) {
	    if (ifeasiblef == 0) {
		*ierror = 1;
		if (logfile)
		     fprintf(logfile, "DIRECT stopped: numfunc >= maxf.\n");
		goto L100;
	    } else {
		increase = 1;
		if (logfile)
                     fprintf(logfile, 
"DIRECT could not find a feasible point after %d function evaluations.\n"
"DIRECT continues until a feasible point is found.\n", numfunc);
		*maxf = numfunc + oldmaxf;
	    }
	}
/* L10: */
    }
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | End of main loop.                                                     | */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* +-----------------------------------------------------------------------+ */
/* | The algorithm stopped after maxT iterations.                          | */
/* +-----------------------------------------------------------------------+ */
    *ierror = 2;
    if (logfile)
	 fprintf(logfile, "DIRECT stopped: maxT iterations.\n");

L100:
/* +-----------------------------------------------------------------------+ */
/* | Store the position of the minimum in x.                               | */
/* +-----------------------------------------------------------------------+ */
    i__1 = *n;
    for (i__ = 1; i__ <= i__1; ++i__) {
	x[i__] = c__[i__ + minpos * i__1 - i__1-1] * l[i__] + l[i__] * u[i__];
	u[i__] = oldu[i__ - 1];
	l[i__] = oldl[i__ - 1];
/* L50: */
    }
/* +-----------------------------------------------------------------------+ */
/* | Store the number of function evaluations in maxf.                     | */
/* +-----------------------------------------------------------------------+ */
    *maxf = numfunc;
/* +-----------------------------------------------------------------------+ */
/* | Give out a summary of the run.                                        | */
/* +-----------------------------------------------------------------------+ */
    direct_dirsummary_(logfile, &x[1], &l[1], &u[1], n, minf, fglobal, &numfunc, 
	    ierror);
/* +-----------------------------------------------------------------------+ */
/* | Format statements.                                                    | */
/* +-----------------------------------------------------------------------+ */

 cleanup:
#define MY_FREE(p) if (p) free(p)
    MY_FREE(c__);
    MY_FREE(f);
    MY_FREE(s);
    MY_FREE(w);
    MY_FREE(oldl);
    MY_FREE(oldu);
    MY_FREE(list2);
    MY_FREE(point);
    MY_FREE(anchor);
    MY_FREE(length);
    MY_FREE(arrayi);
    MY_FREE(levels);
    MY_FREE(thirds);
} /* direct_ */