コード例 #1
0
ファイル: test.cpp プロジェクト: ajshamp/XtalOpt-ajs
bool simpleRandomNoise()
{
  XcMatrix cell1 ( 3.0, 0.0, 0.0, 2.0, 4.0, 0.0, 2.0, 5.0, 3.0 );
  XcMatrix cell2 (cell1);

  std::vector<XcVector> pos1;
  pos1.reserve(4);

  pos1.push_back(XcVector(0.0, 0.25, 0.25));
  pos1.push_back(XcVector(0.25, 0.25, 0.25));
  pos1.push_back(XcVector(0.0, 0.5, 0.25));
  pos1.push_back(XcVector(0.0, 0.25, 0.75));
  std::vector<XcVector> pos2 (pos1);

  std::vector<unsigned int> types1;
  types1.reserve(4);

  types1.push_back(1);
  types1.push_back(2);
  types1.push_back(2);
  types1.push_back(1);
  std::vector<unsigned int> types2 (types1);

  // Displace all coordinates in types2 by a random vector
  const double cartesianNoiseMax = 0.005;
  srand(0); // Intentionally seeding with zero
  for (std::vector<XcVector>::iterator it = pos2.begin(), it_end = pos2.end();
       it != it_end; ++it) {
    XcVector disp (rand() / static_cast<double>(RAND_MAX),
                   rand() / static_cast<double>(RAND_MAX),
                   rand() / static_cast<double>(RAND_MAX));
    // Convert displacement to cartesian units
    disp = cell2.transpose() * disp;
    // Normalize and set length
    disp *= (rand() / static_cast<double>(RAND_MAX))
        * cartesianNoiseMax / disp.norm();
    // Convert back to fractional units
    disp = cell2.transpose().inverse() * disp;
    // Displace vector
    (*it) += disp;
  }

  bool match = XtalComp::compare(cell1, types1, pos1,
                                 cell2, types2, pos2,
                                 NULL, 0.05, 0.25);
  if (!match)
    return false;

  // Displace an atom, ensure that comparison fails.
  pos2[0] += XcVector(0.5,0,0);
  match = XtalComp::compare(cell1, types1, pos1,
                            cell2, types2, pos2,
                            NULL, 0.05, 0.25);
  if (match)
    return false;

  return true;
}
コード例 #2
0
ファイル: test.cpp プロジェクト: ajshamp/XtalOpt-ajs
bool hexagonalCellTest()
{
  XcMatrix cell1 (3.8398, 0.0, 0.0, -1.9199, 3.32536, 0.0, 0.0, 0.0, 5.93459);

  std::vector<XcVector> pos1;
  pos1.reserve(12);
  pos1.push_back(XcVector( 0.33333,  0.66667,  0.56072));
  pos1.push_back(XcVector( 0.66667,  0.33333,  0.43928));
  pos1.push_back(XcVector( 0.66667,  0.33333,  0.06072));
  pos1.push_back(XcVector( 0.33333,  0.66667,  0.93928));
  pos1.push_back(XcVector( 0.16448,  0.83552,  0.25000));
  pos1.push_back(XcVector( 0.83552,  0.16448,  0.75000));
  pos1.push_back(XcVector( 0.00000,  0.00000,  0.00000));
  pos1.push_back(XcVector( 0.00000,  0.00000,  0.50000));
  pos1.push_back(XcVector( 0.16448,  0.32896,  0.25000));
  pos1.push_back(XcVector( 0.83552,  0.67104,  0.75000));
  pos1.push_back(XcVector( 0.67104,  0.83552,  0.25000));
  pos1.push_back(XcVector( 0.32896,  0.16448,  0.75000));

  std::vector<unsigned int> types1;
  types1.reserve(12);
  types1.push_back(1);
  types1.push_back(1);
  types1.push_back(1);
  types1.push_back(1);
  types1.push_back(2);
  types1.push_back(2);
  types1.push_back(2);
  types1.push_back(2);
  types1.push_back(3);
  types1.push_back(3);
  types1.push_back(3);
  types1.push_back(3);

  XcMatrix cell2 (cell1);
  std::vector<XcVector> pos2 (pos1);
  std::swap(pos2[4], pos2[8]);
  std::swap(pos2[5], pos2[9]);
  std::vector<unsigned int> types2 (types1);

  bool match = XtalComp::compare(cell1, types1, pos1,
                                 cell2, types2, pos2,
                                 NULL, 0.05, 0.25);
  if (!match)
    return false;

  // Displace an atom, ensure that comparison fails.
  pos2[0] += XcVector(0.5,0,0);
  match = XtalComp::compare(cell1, types1, pos1,
                            cell2, types2, pos2,
                            NULL, 0.05, 0.25);
  if (match)
    return false;

  return true;
}
コード例 #3
0
ファイル: test.cpp プロジェクト: ajshamp/XtalOpt-ajs
bool simpleNiggli()
{
  XcMatrix cell1 ( 3.0, 0.0, 0.0, 2.0, 4.0, 0.0, 2.0, 5.0, 3.0 );
  XcMatrix cell2 (cell1);

  std::vector<XcVector> pos1;
  pos1.reserve(4);

  pos1.push_back(XcVector(0.0, 0.25, 0.25));
  pos1.push_back(XcVector(0.25, 0.25, 0.25));
  pos1.push_back(XcVector(0.0, 0.5, 0.25));
  pos1.push_back(XcVector(0.0, 0.25, 0.75));
  std::vector<XcVector> pos2 (pos1);

  std::vector<unsigned int> types1;
  types1.reserve(4);

  types1.push_back(1);
  types1.push_back(2);
  types1.push_back(2);
  types1.push_back(1);
  std::vector<unsigned int> types2 (types1);

  // Modify the structure 2
  const XcMatrix linComb (1.0, 1.0, 0.0,
                          1.0, 0.0, 1.0,
                          0.0, 0.0, 1.0);
  const XcMatrix xform (0.0, -1.0, 0.0,
                        1.0, 0.0, 0.0,
                        0.0, 0.0, -1.0);
  XcMatrix fcoordUpdate (xform * cell2.transpose());
  cell2 = linComb * cell2 * xform.transpose();
  fcoordUpdate = cell2.transpose().inverse() * fcoordUpdate;
  for (std::vector<XcVector>::iterator it = pos2.begin(), it_end = pos2.end();
       it != it_end; ++it) {
    *it = fcoordUpdate * (*it);
  }

  bool match = XtalComp::compare(cell1, types1, pos1,
                                 cell2, types2, pos2,
                                 NULL, 0.05, 0.25);
  if (!match)
    return false;

  // Displace an atom, ensure that comparison fails.
  pos2[0] += XcVector(0.5,0,0);
  match = XtalComp::compare(cell1, types1, pos1,
                            cell2, types2, pos2,
                            NULL, 0.05, 0.25);
  if (match)
    return false;

  return true;
}
コード例 #4
0
float CTableWeightingSet_CRTF_Table::GetWeighting (int x1, int y1, int x2, int y2)
{
	CCellInfo cell1(x1, y1, m_Table1.GetWidth(), m_Table1.GetHeight(), GetStringRefFromTable1(x1,y1).GetData(), m_Table1Properties.IsWhiteSpace(x1,y1), m_Table1.Cell(x1,y1)->GetWidth());
	CCellInfo cell2(x2, y2, m_Table2.GetWidth(), m_Table2.GetHeight(), GetStringRefFromTable2(x2,y2).GetData(), m_Table2Properties.IsWhiteSpace(x2,y2), m_Table2.Cell(x2,y2)->GetWidth());

	float fResult = cell1.GetWeightingWith(m_pHost->GetContext(), cell2);

	if (cell1.DidFuzzyMatch())
		m_iWeightingCount++;

	return fResult;
}
コード例 #5
0
ファイル: main.cpp プロジェクト: paul-jewell/simulate
int main(int argc, char **argv)
{
    EventList eventlist;
    ProcessList processes;

    long ev_EndSimulation = 0;
    
    Traverser traverser(&eventlist);
    ColdTestCell cell1(&eventlist,&traverser);
    ColdTestCell cell2(&eventlist, &traverser);
    ColdTestCell cell3(&eventlist, &traverser);
    Source supply(&eventlist, &traverser);
    Sink derig(&eventlist);

    processes.push_back(&traverser);
    processes.push_back(&cell1);
    processes.push_back(&cell2);
    processes.push_back(&cell3);
    processes.push_back(&supply);
    processes.push_back(&derig);
    
    // Connect up production layout
    
    traverser.cell1(&cell1);
    traverser.cell2(&cell2);
    traverser.cell3(&cell3);
    traverser.infeed(&supply);
    traverser.outfeed(&derig);

    // Initialise the processes

    eventlist.push(new Event(100000,
                             nullptr,
                             ev_EndSimulation)); // End Simulation Event
    bool change;
    do {
        change = false;
        for (ProcessList::iterator i = processes.begin();
                 i != processes.end(); i++)
            change |= (*i)->run(); // Run each process until no change
    } while (change);


    // Run the event management loop.
    while (Event *event = eventlist.top()) {
        eventlist.pop(); // Remove the top element from the list
        SimulationTime += event->getTime(); // Advance simulation time
        if (event->getEventType() == ev_EndSimulation)
            break;
        event->getProcess()->HandleEvent(event);
        delete event; // no longer needed
    }
}
コード例 #6
0
ファイル: game-of-life.cpp プロジェクト: abadams/practice
int main(int argc, char **argv) {

  Halide::Func cell("cell");
  Halide::Var x, y;
  cell(x, y) = 0;
  cell(2, 1) = 1;
  cell(3, 2) = 1;
  cell(1, 3) = 1;
  cell(2, 3) = 1;
  cell(3, 3) = 1;

  Halide::Image<int32_t> output;
  output = cell.realize(NX,NY);

  Halide::ImageParam input(Halide::Int(32), 2); // int32_t 2D


  Halide::Func cell2;
  cell2(x,y)=input(x,y)+1;
  Halide::Func nbd("nbd");
  Halide::Func bc("bc");

  for (int t=0; t<10; ++t) {
    Halide::Image<int32_t> output = cell.realize(NX,NY);
    for (int j = 0; j < output.height(); j++) {
      for (int i = 0; i < output.width(); i++) {
	printf("%1d", output(i, j));
      }
      printf("\n");
    }
    printf("\n");

    bc(x,y)=select((x>=0)&&(x<NX)&&(y>=0)&&(y<NY)
		   ,output(min(NX-1,max(x,0)),min(NY-1,max(y,0))),0);
    
    nbd(x,y)=-bc(x,y);
    // staged programming!
    for(int dy=-1; dy<=1; ++dy) {   
      for(int dx=-1; dx<=1; ++dx) {
	nbd(x,y)+=bc(x+dx,y+dy);
      }
    }

    cell(x,y)=select((bc(x,y)==1&&nbd(x,y)==3)||(bc(x,y)==1&&nbd(x,y)==2)
		     || (bc(x,y)==0&&nbd(x,y)==3)
		     ,1,0);
  }

  return 0;
}
コード例 #7
0
ファイル: test.cpp プロジェクト: ajshamp/XtalOpt-ajs
bool simpleUniformTranslation()
{
  XcMatrix cell1 ( 3.0, 0.0, 0.0, 2.0, 4.0, 0.0, 2.0, 5.0, 3.0 );
  XcMatrix cell2 (cell1);

  std::vector<XcVector> pos1;
  pos1.reserve(4);

  pos1.push_back(XcVector(0.0, 0.25, 0.25));
  pos1.push_back(XcVector(0.25, 0.25, 0.25));
  pos1.push_back(XcVector(0.0, 0.5, 0.25));
  pos1.push_back(XcVector(0.0, 0.25, 0.75));
  std::vector<XcVector> pos2 (pos1);

  std::vector<unsigned int> types1;
  types1.reserve(4);

  types1.push_back(1);
  types1.push_back(2);
  types1.push_back(2);
  types1.push_back(1);
  std::vector<unsigned int> types2 (types1);

  // Displace all coordinates in types2 by a random vector
  srand(0); // Intentionally seeding with zero
  XcVector disp (rand() / static_cast<double>(RAND_MAX),
                 rand() / static_cast<double>(RAND_MAX),
                 rand() / static_cast<double>(RAND_MAX));
  for (std::vector<XcVector>::iterator it = pos2.begin(), it_end = pos2.end();
       it != it_end; ++it) {
    (*it) += disp;
  }

  bool match = XtalComp::compare(cell1, types1, pos1,
                                 cell2, types2, pos2,
                                 NULL, 0.05, 0.25);
  if (!match)
    return false;

  // Displace an atom, ensure that comparison fails.
  pos2[0] += XcVector(0.5,0,0);
  match = XtalComp::compare(cell1, types1, pos1,
                            cell2, types2, pos2,
                            NULL, 0.05, 0.25);
  if (match)
    return false;

  return true;
}
コード例 #8
0
ファイル: maze.cpp プロジェクト: gottcode/cutemaze
void KruskalMaze::generate()
{
	// Generate sets
	m_set_ids = QVector< QVector<Set*> >(columns(), QVector<Set*>(rows()));
	for (int c = 0; c < columns(); ++c) {
		for (int r = 0; r < rows(); ++r) {
			m_sets.append(QList<QPoint>() << QPoint(c, r));
			m_set_ids[c][r] = &m_sets.last();
		}
	}

	while (m_sets.size() > 1) {
		Set* set1 = &m_sets.first();

		// Find random cell
		const QPoint& cell = set1->at(randomInt(set1->size()));

		// Find random neighbor of cell
		QPoint cell2(cell);
		if (randomInt(2)) {
			cell2.rx()++;
		} else {
			cell2.ry()++;
		}
		if (cell2.x() >= columns() || cell2.y() >= rows()) {
			continue;
		}

		// Find set containing second cell
		Set* set2 = m_set_ids.at(cell2.x()).at(cell2.y());

		// Merge sets if they are different
		if (set1 != set2) {
			mergeCells(cell, cell2);
			int size = set1->size();
			for (int i = 0; i < size; ++i) {
				const QPoint& cell3 = set1->at(i);
				m_set_ids[cell3.x()][cell3.y()] = set2;
			}
			*set2 += *set1;
			m_sets.removeFirst();
		}
	}

	m_sets.clear();
	m_set_ids.clear();
}
コード例 #9
0
ファイル: test.cpp プロジェクト: ajshamp/XtalOpt-ajs
bool simpleCase()
{
  XcMatrix cell1 ( 3.0, 0.0, 0.0, 2.0, 4.0, 0.0, 2.0, 5.0, 3.0 );
  XcMatrix cell2 (cell1);

  std::vector<XcVector> pos1;
  pos1.reserve(4);

  pos1.push_back(XcVector(0.0, 0.25, 0.25));
  pos1.push_back(XcVector(0.25, 0.25, 0.25));
  pos1.push_back(XcVector(0.0, 0.5, 0.25));
  pos1.push_back(XcVector(0.0, 0.25, 0.75));
  std::vector<XcVector> pos2 (pos1);

  std::vector<unsigned int> types1;
  types1.reserve(4);

  types1.push_back(1);
  types1.push_back(2);
  types1.push_back(2);
  types1.push_back(1);
  std::vector<unsigned int> types2 (types1);

  bool match = XtalComp::compare(cell1, types1, pos1,
                                 cell2, types2, pos2,
                                 NULL, 0.05, 0.25);

  if (!match)
    return false;

  // Displace an atom, ensure that comparison fails.
  pos2[0] += XcVector(0.5,0,0);
  match = XtalComp::compare(cell1, types1, pos1,
                            cell2, types2, pos2,
                            NULL, 0.05, 0.25);
  if (match)
    return false;

  return true;
}
コード例 #10
0
ファイル: MovementHandler.cpp プロジェクト: Keader/Sunwell
void WorldSession::HandleMoveWorldportAckOpcode()
{
    // ignore unexpected far teleports
    if (!GetPlayer()->IsBeingTeleportedFar())
        return;

    GetPlayer()->SetSemaphoreTeleportFar(0);

    // get the teleport destination
    WorldLocation const& loc = GetPlayer()->GetTeleportDest();

    // possible errors in the coordinate validity check
    if (!MapManager::IsValidMapCoord(loc))
    {
        KickPlayer();
        return;
    }

    // get the destination map entry, not the current one, this will fix homebind and reset greeting
    MapEntry const* mEntry = sMapStore.LookupEntry(loc.GetMapId());
    InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(loc.GetMapId());

    Map* oldMap = GetPlayer()->GetMap();
    if (GetPlayer()->IsInWorld())
    {
        sLog->outError("Player (Name %s) is still in world when teleported from map %u to new map %u", GetPlayer()->GetName().c_str(), oldMap->GetId(), loc.GetMapId());
        oldMap->RemovePlayerFromMap(GetPlayer(), false);
    }

    // reset instance validity, except if going to an instance inside an instance
    if (GetPlayer()->m_InstanceValid == false && !mInstance)
    {
        GetPlayer()->m_InstanceValid = true;
        // pussywizard: m_InstanceValid can be false only by leaving a group in an instance => so remove temp binds that could not be removed because player was still on the map!
        if (!sInstanceSaveMgr->PlayerIsPermBoundToInstance(GetPlayer()->GetGUIDLow(), oldMap->GetId(), oldMap->GetDifficulty()))
            sInstanceSaveMgr->PlayerUnbindInstance(GetPlayer()->GetGUIDLow(), oldMap->GetId(), oldMap->GetDifficulty(), true);
    }

    // relocate the player to the teleport destination
    Map* newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer());
    // the CanEnter checks are done in TeleporTo but conditions may change
    // while the player is in transit, for example the map may get full
    if (!newMap || !newMap->CanEnter(GetPlayer()))
    {
        sLog->outError("Map %d could not be created for player %d, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUIDLow());
        GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
        return;
    }

    GetPlayer()->Relocate(loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation());

    GetPlayer()->ResetMap();
    GetPlayer()->SetMap(newMap);

    GetPlayer()->SendInitialPacketsBeforeAddToMap();
    if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer()))
    {
        sLog->outError("WORLD: failed to teleport player %s (%d) to map %d because of unknown reason!", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow(), loc.GetMapId());
        GetPlayer()->ResetMap();
        GetPlayer()->SetMap(oldMap);
        GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
        return;
    }

    oldMap->AfterPlayerUnlinkFromMap();

    // pussywizard: transport teleport couldn't teleport us to the same map (some other teleport pending, reqs not met, etc.), but we still have transport set until player moves! clear it if map differs (crashfix)
    if (Transport* t = _player->GetTransport())
        if (!t->IsInMap(_player))
        {
            t->RemovePassenger(_player);
            _player->m_transport = NULL;
            _player->m_movementInfo.transport.Reset();
            _player->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
        }

    if (!_player->getHostileRefManager().isEmpty())
        _player->getHostileRefManager().deleteReferences(); // pussywizard: multithreading crashfix

    CellCoord pair(Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()));
    Cell cell(pair);
    if (!GridCoord(cell.GridX(), cell.GridY()).IsCoordValid())
    {
        KickPlayer();
        return;
    }
    newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());

    // pussywizard: player supposed to enter bg map
    if (_player->InBattleground())
    {
        // but landed on another map, cleanup data
        if (!mEntry->IsBattlegroundOrArena())
            _player->SetBattlegroundId(0, BATTLEGROUND_TYPE_NONE, PLAYER_MAX_BATTLEGROUND_QUEUES, false, false, TEAM_NEUTRAL);
        // everything ok
        else if (Battleground* bg = _player->GetBattleground())
        {
            if (_player->IsInvitedForBattlegroundInstance()) // GMs are not invited, so they are not added to participants
                bg->AddPlayer(_player);
        }
    }

    // pussywizard: arena spectator stuff
    {
        if (newMap->IsBattleArena() && ((BattlegroundMap*)newMap)->GetBG() && _player->HasPendingSpectatorForBG(((BattlegroundMap*)newMap)->GetInstanceId()))
        {
            _player->ClearReceivedSpectatorResetFor();
            _player->SetIsSpectator(true);
            ArenaSpectator::SendCommand(_player, "%sENABLE", SPECTATOR_ADDON_PREFIX);
            ((BattlegroundMap*)newMap)->GetBG()->AddSpectator(_player);
            ArenaSpectator::HandleResetCommand(_player);
        }
        else
            _player->SetIsSpectator(false);

        GetPlayer()->SetPendingSpectatorForBG(0);
        timeWhoCommandAllowed = time(NULL) + sWorld->GetNextWhoListUpdateDelaySecs() + 1; // after exiting arena Subscribe will scan for a player and cached data says he is still in arena, so disallow until next update

        if (uint32 inviteInstanceId = _player->GetPendingSpectatorInviteInstanceId())
        {
            if (Battleground* tbg = sBattlegroundMgr->GetBattleground(inviteInstanceId))
                tbg->RemoveToBeTeleported(_player->GetGUID());
            _player->SetPendingSpectatorInviteInstanceId(0);
        }
    }

    // xinef: do this again, player can be teleported inside bg->AddPlayer(_player)!!!!
    CellCoord pair2(Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()));
    Cell cell2(pair2);
    if (!GridCoord(cell2.GridX(), cell2.GridY()).IsCoordValid())
    {
        KickPlayer();
        return;
    }
    newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());

    GetPlayer()->SendInitialPacketsAfterAddToMap();

    // resurrect character at enter into instance where his corpse exist after add to map
    Corpse* corpse = GetPlayer()->GetCorpse();
    if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId())
    {
        if (mEntry->IsDungeon())
        {
            GetPlayer()->ResurrectPlayer(0.5f, false);
            GetPlayer()->SpawnCorpseBones();
        }
    }

    bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattlegroundOrArena();
    if (mInstance)
    {
        Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid());
        if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID, diff))
            if (mapDiff->resetTime)
                if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff))
                {
                    uint32 timeleft = uint32(timeReset - time(NULL));
                    GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft, true);
                }
        allowMount = mInstance->AllowMount;
    }

    // mount allow check
    if (!allowMount)
        _player->RemoveAurasByType(SPELL_AURA_MOUNTED);

    // update zone immediately, otherwise leave channel will cause crash in mtmap
    uint32 newzone, newarea;
    GetPlayer()->GetZoneAndAreaId(newzone, newarea, true);
    GetPlayer()->UpdateZone(newzone, newarea);

    // honorless target
    if (GetPlayer()->pvpInfo.IsHostile)
        GetPlayer()->CastSpell(GetPlayer(), 2479, true);

    // in friendly area
    else if (GetPlayer()->IsPvP() && !GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP))
        GetPlayer()->UpdatePvP(false, false);

    // resummon pet
    GetPlayer()->ResummonPetTemporaryUnSummonedIfAny();

    //lets process all delayed operations on successful teleport
    GetPlayer()->ProcessDelayedOperations();
}
コード例 #11
0
ファイル: test.cpp プロジェクト: ajshamp/XtalOpt-ajs
bool allOfTheAbove()
{
  XcMatrix cell1 ( 3.0, 0.0, 0.0, 2.0, 4.0, 0.0, 2.0, 5.0, 3.0 );
  XcMatrix cell2 (cell1);

  std::vector<XcVector> pos1;
  pos1.reserve(4);

  pos1.push_back(XcVector(0.0, 0.25, 0.25));
  pos1.push_back(XcVector(0.25, 0.25, 0.25));
  pos1.push_back(XcVector(0.0, 0.5, 0.25));
  pos1.push_back(XcVector(0.0, 0.25, 0.75));
  std::vector<XcVector> pos2 (pos1);

  std::vector<unsigned int> types1;
  types1.reserve(4);

  types1.push_back(1);
  types1.push_back(2);
  types1.push_back(2);
  types1.push_back(1);
  std::vector<unsigned int> types2 (types1);

  //******************************************************************
  // From niggli test:
  // Modify the structure 2
  const XcMatrix linComb (1.0, 1.0, 0.0,
                          1.0, 0.0, 1.0,
                          0.0, 0.0, 1.0);
  const XcMatrix xform (0.0, -1.0, 0.0,
                        1.0, 0.0, 0.0,
                        0.0, 0.0, -1.0);
  XcMatrix fcoordUpdate (xform * cell2.transpose());
  cell2 = linComb * cell2 * xform.transpose();
  fcoordUpdate = cell2.transpose().inverse() * fcoordUpdate;
  for (std::vector<XcVector>::iterator it = pos2.begin(), it_end = pos2.end();
       it != it_end; ++it) {
    *it = fcoordUpdate * (*it);
  }
  //******************************************************************

  //******************************************************************
  // From uniform displacement test:
  // Displace all coordinates in types2 by a random vector
  srand(0); // Intentionally seeding with zero
  XcVector disp (rand() / static_cast<double>(RAND_MAX),
                 rand() / static_cast<double>(RAND_MAX),
                 rand() / static_cast<double>(RAND_MAX));
  for (std::vector<XcVector>::iterator it = pos2.begin(), it_end = pos2.end();
       it != it_end; ++it) {
    (*it) += disp;
  }
  //******************************************************************

  //******************************************************************
  // From noise test:
  // Displace all coordinates in types2 by a random vector
  const double cartesianNoiseMax = 0.005;
  srand(0); // Intentionally seeding with zero
  for (std::vector<XcVector>::iterator it = pos2.begin(), it_end = pos2.end();
       it != it_end; ++it) {
    XcVector disp (rand() / static_cast<double>(RAND_MAX),
                   rand() / static_cast<double>(RAND_MAX),
                   rand() / static_cast<double>(RAND_MAX));
    // Convert displacement to cartesian units
    disp = cell2.transpose() * disp;
    // Normalize and set length
    disp *= (rand() / static_cast<double>(RAND_MAX))
        * cartesianNoiseMax / disp.norm();
    // Convert back to fractional units
    disp = cell2.transpose().inverse() * disp;
    // Displace vector
    (*it) += disp;
  }
  //******************************************************************

  bool match = XtalComp::compare(cell1, types1, pos1,
                                  cell2, types2, pos2,
                                  NULL, 0.05, 0.25);
  if (!match)
    return false;

  // Displace an atom, ensure that comparison fails.
  pos2[0] += XcVector(0.5,0,0);
  match = XtalComp::compare(cell1, types1, pos1,
                            cell2, types2, pos2,
                            NULL, 0.05, 0.25);
  if (match)
    return false;

  return true;
}