<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/**
  \file    GPUSBVR.h
  \author    Jens Krueger
        SCI Institute
        University of Utah
  \date    August 2008
*/

#include "GPUSBVR.h"

#include <math.h>
#include <Basics/SysTools.h>
#include <Controller/MasterController.h>

using namespace std;

GPUSBVR::GPUSBVR(MasterController* pMasterController) :
  GLRenderer(pMasterController),
  m_iCurrentView(0),
  m_vRot(0,0),
  m_bDelayedCompleteRedraw(false),
  m_bRenderWireframe(false),
  m_pFBO3DImage(NULL),
  m_pProgram1DTrans(NULL)
{
}

GPUSBVR::~GPUSBVR() {
  delete [] m_p1DData;
  delete [] m_p2DData;
}

void GPUSBVR::Initialize() {

  m_pMasterController->DebugOut()->Message("GPUSBVR::Initialize","");

  glClearColor(m_vBackgroundColors[0].x,m_vBackgroundColors[0].y,m_vBackgroundColors[0].z,0);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_TEXTURE_2D);
  glDisable(GL_CULL_FACE);

  m_IDTex[0] = m_pMasterController->MemMan()->Load2DTextureFromFile(SysTools::GetFromResourceOnMac("RenderWin1x3.bmp").c_str());
  if (m_IDTex[0] == NULL) {
    m_pMasterController->DebugOut()->Message("GPUSBVR::Initialize","First Image load failed");
  }
  m_IDTex[1] = m_pMasterController->MemMan()->Load2DTextureFromFile(SysTools::GetFromResourceOnMac("RenderWin2x2.bmp").c_str());
  if (m_IDTex[1] == NULL) {
    m_pMasterController->DebugOut()->Message("GPUSBVR::Initialize","Second Image load failed");
  }
  m_IDTex[2] = m_pMasterController->MemMan()->Load2DTextureFromFile(SysTools::GetFromResourceOnMac("RenderWin1.bmp").c_str());
  if (m_IDTex[2] == NULL) {
    m_pMasterController->DebugOut()->Message("GPUSBVR::Initialize","Third Image load failed");
  }

  m_pProgram1DTrans = m_pMasterController->MemMan()->GetGLSLProgram(SysTools::GetFromResourceOnMac("GPUSBVR-1D-VS.glsl"),
                                                                    SysTools::GetFromResourceOnMac("GPUSBVR-1D-FS.glsl"));

  GLRenderer::Initialize();
}

void GPUSBVR::UpdateGeoGen(const std::vector<UINT64>& vLOD, const std::vector<UINT64>& vBrick) {

  UINTVECTOR3  vSize = m_pDataset->GetBrickSize(vLOD, vBrick);
  FLOATVECTOR3 vCenter, vExtension;
  m_pDataset->GetBrickCenterAndExtension(vLOD, vBrick, vCenter, vExtension);

  // TODO: transfer brick offsets to m_SBVRGeogen
  m_SBVRGeogen.SetVolumeData(vExtension, vSize);

}

void GPUSBVR::DrawLogo() {
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(-0.5, +0.5, +0.5, -0.5, 0.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    if (m_IDTex[m_iCurrentView] != NULL) m_IDTex[m_iCurrentView]->Bind();
    glDisable(GL_TEXTURE_3D);
    glEnable(GL_TEXTURE_2D);

    glBegin(GL_QUADS);
      glColor4d(1,1,1,1);
      glTexCoord2d(0,0);
      glVertex3d(0.2,  0.4, -0.5);
      glTexCoord2d(1,0);
      glVertex3d( 0.4,  0.4, -0.5);
      glTexCoord2d(1,1);
      glVertex3d( 0.4, 0.2, -0.5);
      glTexCoord2d(0,1);
      glVertex3d(0.2, 0.2, -0.5);
    glEnd();

    glDisable(GL_TEXTURE_2D);

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
}

void GPUSBVR::DrawBackGradient() {
  glDisable(GL_DEPTH_TEST);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  glOrtho(-0.5, +0.5, +0.5, -0.5, 0.0, 1.0);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();

  glDisable(GL_TEXTURE_3D);

  glBegin(GL_QUADS);
    glColor4d(m_vBackgroundColors[1].x,m_vBackgroundColors[1].y,m_vBackgroundColors[1].z,1);
    glVertex3d(-1.0,  1.0, -0.5);
    glVertex3d( 1.0,  1.0, -0.5);
    glColor4d(m_vBackgroundColors[0].x,m_vBackgroundColors[0].y,m_vBackgroundColors[0].z,1);
    glVertex3d( 1.0, -1.0, -0.5);
    glVertex3d(-1.0, -1.0, -0.5);
  glEnd();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();

  glEnable(GL_DEPTH_TEST);
}

void GPUSBVR::Paint(bool bClearDepthBuffer) {

  if (bClearDepthBuffer) glClear(GL_DEPTH_BUFFER_BIT);

  if (m_bCompleteRedraw) {
    m_pMasterController->DebugOut()->Message("GPUSBVR::Paint","Complete Redraw");

    // DEBUG: just render the smallest brick for a start
    std::vector<UINT64> vSmallestLOD = m_pDataset->GetInfo()->GetLODLevelCount();
    for (size_t i = 0;i<vSmallestLOD.size();i++) vSmallestLOD[i] -= 1;
    std::vector<UINT64> vFirstBrick(m_pDataset->GetInfo()->GetBrickCount(vSmallestLOD).size());
    for (size_t i = 0;i<vFirstBrick.size();i++) vFirstBrick[i] = 0;
    UpdateGeoGen(vSmallestLOD, vFirstBrick);

    m_pFBO3DImage->Write();

    if (m_vBackgroundColors[0] == m_vBackgroundColors[1]) {
      glClear(GL_COLOR_BUFFER_BIT);
    } else {
      DrawBackGradient();
    }

    DrawLogo();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    FLOATMATRIX4 trans, rotx, roty;
    trans.Translation(0,0,-4);
    rotx.RotationAxis(FLOATVECTOR3(0,1,0),m_vRot.x);
    roty.RotationAxis(FLOATVECTOR3(1,0,0),m_vRot.y);
    m_matModelView = trans*rotx*roty;

    //m_matModelView.setModelview();
    m_SBVRGeogen.SetTransformation(m_matModelView);

  	glEnable(GL_BLEND);
	  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // switch to wireframe
    if (m_bRenderWireframe) {
      // TODO save state
	    glDisable(GL_CULL_FACE);
	    glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
	    glEdgeFlag(true);
    }

    GLTexture3D* t = m_pMasterController->MemMan()->Get3DTexture(m_pDataset, vSmallestLOD, vFirstBrick);
    t->Bind(0);
    m_p1DTransTex->Bind(1);

    m_pProgram1DTrans->Enable();
    m_pProgram1DTrans->SetUniformVector("VolTexture",0);
    m_pProgram1DTrans->SetUniformVector("Trans1DTexture",1);

    glBegin(GL_TRIANGLES);
      glColor4f(1,1,1,1);

      for (size_t i = 0;i<m_SBVRGeogen.m_vSliceTriangles.size();i++) {
        glTexCoord3fv(m_SBVRGeogen.m_vSliceTriangles[i].m_vTex);
        glVertex3fv(m_SBVRGeogen.m_vSliceTriangles[i].m_vPos);
      }
    glEnd();

    m_pFBO3DImage->FinishWrite();

    m_pProgram1DTrans->Disable();

    glDisable(GL_BLEND);

    if (m_bRenderWireframe) {
      // TODO: restore state
    }

  } else m_pMasterController->DebugOut()->Message("GPUSBVR::Paint","Quick Redraw");

  RerenderPreviousResult();

  m_bCompleteRedraw = false;
  m_bRedraw = false;
}

void GPUSBVR::Resize(int width, int height) {
  m_pMasterController->DebugOut()->Message("GPUSBVR::Resize","");

//  int side = std::min(width, height);
//  glViewport((width - side) / 2, (height - side) / 2, side, side);

  float aspect=(float)width/(float)height;
	glViewport(0,0,width,height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(50.0,aspect,0.2,100.0); 	// Set Projection. Arguments are FOV (in degrees), aspect-ratio, near-plane, far-plane.
	glMatrixMode(GL_MODELVIEW);

  if (m_pFBO3DImage != NULL) m_pMasterController->MemMan()->FreeFBO(m_pFBO3DImage);
  m_pFBO3DImage = m_pMasterController->MemMan()->GetFBO(GL_NEAREST, GL_NEAREST, GL_CLAMP, width, height, GL_RGBA8, 8*4);

  m_bDelayedCompleteRedraw = true;
}

void GPUSBVR::Cleanup() {
  m_pMasterController->MemMan()->FreeTexture(m_IDTex[0]);
  m_pMasterController->MemMan()->FreeTexture(m_IDTex[1]);
  m_pMasterController->MemMan()->FreeTexture(m_IDTex[2]);

  m_pMasterController->MemMan()->FreeFBO(m_pFBO3DImage);
  m_pMasterController->MemMan()->FreeGLSLProgram(m_pProgram1DTrans);
}

bool GPUSBVR::CheckForRedraw() {
  if (m_bDelayedCompleteRedraw) {
    m_bDelayedCompleteRedraw = false;
    m_bCompleteRedraw = true;
    m_bRedraw = true;
  }

  return m_bRedraw;
}

void GPUSBVR::RerenderPreviousResult() {
  m_pFBO3DImage->Read(GL_TEXTURE0);
  glEnable(GL_TEXTURE_2D);

  glDisable(GL_DEPTH_TEST);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  glOrtho(-1.0, +1.0, +1.0, -1.0, 0.0, 1.0);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();

  glBegin(GL_QUADS);
    glColor4d(1,1,1,1);
    glTexCoord2d(0,0);
    glVertex3d(-1.0,  1.0, -0.5);
    glTexCoord2d(1,0);
    glVertex3d( 1.0,  1.0, -0.5);
    glTexCoord2d(1,1);
    glVertex3d( 1.0, -1.0, -0.5);
    glTexCoord2d(0,1);
    glVertex3d(-1.0, -1.0, -0.5);
  glEnd();

  m_pFBO3DImage->FinishRead();

  glPopMatrix();
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);

  glEnable(GL_DEPTH_TEST);
}
<commit_msg><commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/**
  \file    GPUSBVR.h
  \author    Jens Krueger
        SCI Institute
        University of Utah
  \date    August 2008
*/

#include "GPUSBVR.h"

#include <math.h>
#include <Basics/SysTools.h>
#include <Controller/MasterController.h>

using namespace std;

GPUSBVR::GPUSBVR(MasterController* pMasterController) :
  GLRenderer(pMasterController),
  m_iCurrentView(0),
  m_vRot(0,0),
  m_bDelayedCompleteRedraw(false),
  m_bRenderWireframe(false),
  m_pFBO3DImage(NULL),
  m_pProgram1DTrans(NULL)
{
}

GPUSBVR::~GPUSBVR() {
  delete [] m_p1DData;
  delete [] m_p2DData;
}

void GPUSBVR::Initialize() {

  m_pMasterController->DebugOut()->Message("GPUSBVR::Initialize","");

  glClearColor(m_vBackgroundColors[0].x,m_vBackgroundColors[0].y,m_vBackgroundColors[0].z,0);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_TEXTURE_2D);
  glDisable(GL_CULL_FACE);

  m_IDTex[0] = m_pMasterController->MemMan()->Load2DTextureFromFile(SysTools::GetFromResourceOnMac("RenderWin1x3.bmp").c_str());
  if (m_IDTex[0] == NULL) {
    m_pMasterController->DebugOut()->Message("GPUSBVR::Initialize","First Image load failed");
  }
  m_IDTex[1] = m_pMasterController->MemMan()->Load2DTextureFromFile(SysTools::GetFromResourceOnMac("RenderWin2x2.bmp").c_str());
  if (m_IDTex[1] == NULL) {
    m_pMasterController->DebugOut()->Message("GPUSBVR::Initialize","Second Image load failed");
  }
  m_IDTex[2] = m_pMasterController->MemMan()->Load2DTextureFromFile(SysTools::GetFromResourceOnMac("RenderWin1.bmp").c_str());
  if (m_IDTex[2] == NULL) {
    m_pMasterController->DebugOut()->Message("GPUSBVR::Initialize","Third Image load failed");
  }

  m_pProgram1DTrans = m_pMasterController->MemMan()->GetGLSLProgram(SysTools::GetFromResourceOnMac("GPUSBVR-1D-VS.glsl"),
                                                                    SysTools::GetFromResourceOnMac("GPUSBVR-1D-FS.glsl"));

  GLRenderer::Initialize();
}

void GPUSBVR::UpdateGeoGen(const std::vector<UINT64>& vLOD, const std::vector<UINT64>& vBrick) {

  UINTVECTOR3  vSize = m_pDataset->GetBrickSize(vLOD, vBrick);
  FLOATVECTOR3 vCenter, vExtension;
  m_pDataset->GetBrickCenterAndExtension(vLOD, vBrick, vCenter, vExtension);

  // TODO: transfer brick offsets to m_SBVRGeogen
  m_SBVRGeogen.SetVolumeData(vExtension, vSize);

}

void GPUSBVR::DrawLogo() {
    m_pMasterController->DebugOut()->Message("printf debugging","a");

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(-0.5, +0.5, +0.5, -0.5, 0.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    m_pMasterController->DebugOut()->Message("printf debugging","b");

    if (m_IDTex[m_iCurrentView] != NULL) m_IDTex[m_iCurrentView]->Bind();
    glDisable(GL_TEXTURE_3D);
    glEnable(GL_TEXTURE_2D);

    m_pMasterController->DebugOut()->Message("printf debugging","c");

    glBegin(GL_QUADS);
      glColor4d(1,1,1,1);
      glTexCoord2d(0,0);
      glVertex3d(0.2,  0.4, -0.5);
      glTexCoord2d(1,0);
      glVertex3d( 0.4,  0.4, -0.5);
      glTexCoord2d(1,1);
      glVertex3d( 0.4, 0.2, -0.5);
      glTexCoord2d(0,1);
      glVertex3d(0.2, 0.2, -0.5);
    glEnd();

    m_pMasterController->DebugOut()->Message("printf debugging","d");

    glDisable(GL_TEXTURE_2D);

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    m_pMasterController->DebugOut()->Message("printf debugging","e");

}

void GPUSBVR::DrawBackGradient() {
  glDisable(GL_DEPTH_TEST);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  glOrtho(-0.5, +0.5, +0.5, -0.5, 0.0, 1.0);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();

  glDisable(GL_TEXTURE_3D);

  glBegin(GL_QUADS);
    glColor4d(m_vBackgroundColors[1].x,m_vBackgroundColors[1].y,m_vBackgroundColors[1].z,1);
    glVertex3d(-1.0,  1.0, -0.5);
    glVertex3d( 1.0,  1.0, -0.5);
    glColor4d(m_vBackgroundColors[0].x,m_vBackgroundColors[0].y,m_vBackgroundColors[0].z,1);
    glVertex3d( 1.0, -1.0, -0.5);
    glVertex3d(-1.0, -1.0, -0.5);
  glEnd();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();

  glEnable(GL_DEPTH_TEST);
}

void GPUSBVR::Paint(bool bClearDepthBuffer) {

  if (bClearDepthBuffer) glClear(GL_DEPTH_BUFFER_BIT);

  if (m_bCompleteRedraw) {
    m_pMasterController->DebugOut()->Message("GPUSBVR::Paint","Complete Redraw");

    // DEBUG: just render the smallest brick for a start
    std::vector<UINT64> vSmallestLOD = m_pDataset->GetInfo()->GetLODLevelCount();
    for (size_t i = 0;i<vSmallestLOD.size();i++) vSmallestLOD[i] -= 1;
    std::vector<UINT64> vFirstBrick(m_pDataset->GetInfo()->GetBrickCount(vSmallestLOD).size());
    for (size_t i = 0;i<vFirstBrick.size();i++) vFirstBrick[i] = 0;
    UpdateGeoGen(vSmallestLOD, vFirstBrick);

    m_pFBO3DImage->Write();

    if (m_vBackgroundColors[0] == m_vBackgroundColors[1]) {
      glClear(GL_COLOR_BUFFER_BIT);
    } else {
      DrawBackGradient();
    }

    DrawLogo();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    FLOATMATRIX4 trans, rotx, roty;
    trans.Translation(0,0,-4);
    rotx.RotationAxis(FLOATVECTOR3(0,1,0),m_vRot.x);
    roty.RotationAxis(FLOATVECTOR3(1,0,0),m_vRot.y);
    m_matModelView = trans*rotx*roty;

    //m_matModelView.setModelview();
    m_SBVRGeogen.SetTransformation(m_matModelView);

  	glEnable(GL_BLEND);
	  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // switch to wireframe
    if (m_bRenderWireframe) {
      // TODO save state
	    glDisable(GL_CULL_FACE);
	    glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
	    glEdgeFlag(true);
    }

    GLTexture3D* t = m_pMasterController->MemMan()->Get3DTexture(m_pDataset, vSmallestLOD, vFirstBrick);
    t->Bind(0);
    m_p1DTransTex->Bind(1);

    m_pProgram1DTrans->Enable();
    m_pProgram1DTrans->SetUniformVector("VolTexture",0);
    m_pProgram1DTrans->SetUniformVector("Trans1DTexture",1);

    glBegin(GL_TRIANGLES);
      glColor4f(1,1,1,1);

      for (size_t i = 0;i<m_SBVRGeogen.m_vSliceTriangles.size();i++) {
        glTexCoord3fv(m_SBVRGeogen.m_vSliceTriangles[i].m_vTex);
        glVertex3fv(m_SBVRGeogen.m_vSliceTriangles[i].m_vPos);
      }
    glEnd();

    m_pFBO3DImage->FinishWrite();

    m_pProgram1DTrans->Disable();

    glDisable(GL_BLEND);

    if (m_bRenderWireframe) {
      // TODO: restore state
    }

  } else m_pMasterController->DebugOut()->Message("GPUSBVR::Paint","Quick Redraw");

  RerenderPreviousResult();

  m_bCompleteRedraw = false;
  m_bRedraw = false;
}

void GPUSBVR::Resize(int width, int height) {
  m_pMasterController->DebugOut()->Message("GPUSBVR::Resize","");

//  int side = std::min(width, height);
//  glViewport((width - side) / 2, (height - side) / 2, side, side);

  float aspect=(float)width/(float)height;
	glViewport(0,0,width,height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(50.0,aspect,0.2,100.0); 	// Set Projection. Arguments are FOV (in degrees), aspect-ratio, near-plane, far-plane.
	glMatrixMode(GL_MODELVIEW);

  if (m_pFBO3DImage != NULL) m_pMasterController->MemMan()->FreeFBO(m_pFBO3DImage);
  m_pFBO3DImage = m_pMasterController->MemMan()->GetFBO(GL_NEAREST, GL_NEAREST, GL_CLAMP, width, height, GL_RGBA8, 8*4);

  m_bDelayedCompleteRedraw = true;
}

void GPUSBVR::Cleanup() {
  m_pMasterController->MemMan()->FreeTexture(m_IDTex[0]);
  m_pMasterController->MemMan()->FreeTexture(m_IDTex[1]);
  m_pMasterController->MemMan()->FreeTexture(m_IDTex[2]);

  m_pMasterController->MemMan()->FreeFBO(m_pFBO3DImage);
  m_pMasterController->MemMan()->FreeGLSLProgram(m_pProgram1DTrans);
}

bool GPUSBVR::CheckForRedraw() {
  if (m_bDelayedCompleteRedraw) {
    m_bDelayedCompleteRedraw = false;
    m_bCompleteRedraw = true;
    m_bRedraw = true;
  }

  return m_bRedraw;
}

void GPUSBVR::RerenderPreviousResult() {
  m_pFBO3DImage->Read(GL_TEXTURE0);
  glEnable(GL_TEXTURE_2D);

  glDisable(GL_DEPTH_TEST);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  glOrtho(-1.0, +1.0, +1.0, -1.0, 0.0, 1.0);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();

  glBegin(GL_QUADS);
    glColor4d(1,1,1,1);
    glTexCoord2d(0,0);
    glVertex3d(-1.0,  1.0, -0.5);
    glTexCoord2d(1,0);
    glVertex3d( 1.0,  1.0, -0.5);
    glTexCoord2d(1,1);
    glVertex3d( 1.0, -1.0, -0.5);
    glTexCoord2d(0,1);
    glVertex3d(-1.0, -1.0, -0.5);
  glEnd();

  m_pFBO3DImage->FinishRead();

  glPopMatrix();
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);

  glEnable(GL_DEPTH_TEST);
}
<|endoftext|>


<commit_before>#include "Players/Genetic_AI.h"

#include <iostream>
#include <fstream>
#include <map>
#include <algorithm>

class Board;
class Clock;

#include "Game/Color.h"

#include "Utility/String.h"

#include "Exceptions/Genetic_AI_Creation_Error.h"

int Genetic_AI::next_id = 0;
size_t Genetic_AI::max_origin_pool_id = 0;

//! Generate a randomly mutated Genetic_AI
//
//! \param mutation_count The number of genome mutations to apply to the AI after construction.
Genetic_AI::Genetic_AI(int mutation_count) :
    id_number(next_id++)
{
    mutate(mutation_count);
    recalibrate_self();
}

//! Create a new Genetic_AI via sexual reproduction.
//
//! The offspring is formed by randomly taking genes from each parent.
//! \param A The first parent.
//! \param B The second parent.
Genetic_AI::Genetic_AI(const Genetic_AI& A, const Genetic_AI& B) :
    genome(A.genome, B.genome),
    id_number(next_id++)
{
    auto A_parents = A.ancestry;
    auto B_parents = B.ancestry;
    for(size_t i = 0; i <= max_origin_pool_id; ++i)
    {
        ancestry[i] = (A_parents[i] + B_parents[i])/2;
    }

    recalibrate_self();
}

//! Create a Genetic_AI from information in a text file.
//
//! \param file_name The name of the text file.
//! \throws Genetic_AI_Creation_Error if the file cannot be opened or if there is an error during reading.
Genetic_AI::Genetic_AI(const std::string& file_name)
{
    std::ifstream ifs(file_name);
    if( ! ifs)
    {
        throw Genetic_AI_Creation_Error("Could not read: " + file_name);
    }

    read_from(ifs);

    recalibrate_self();
}

//! Create a Genetic_AI from information in an input stream (std::ifstream, std::cin, etc.).
//
//! \param is Input stream.
//! \throws Genetic_AI_Creation_Error If there is an error during reading.
Genetic_AI::Genetic_AI(std::istream& is)
{
    read_from(is);

    recalibrate_self();
}

//! Create a Genetic_AI from a text file by searching for a specfic ID.
//
//! \param file_name The name of the file with the Genetic_AI data.
//! \param id_in The ID to search for.
//! \throws Genetic_AI_Creation_Error If there is an error during reading.
Genetic_AI::Genetic_AI(const std::string& file_name, int id_in) : id_number(id_in)
{
    std::ifstream ifs(file_name);
    if( ! ifs)
    {
        throw Genetic_AI_Creation_Error("Could not read: " + file_name);
    }

    std::string line;
    while(std::getline(ifs, line))
    {
        line = String::strip_comments(line, "#");
        if( ! String::starts_with(line, "ID"))
        {
            continue;
        }

        auto param_value = String::split(line, ":", 1);
        if(param_value.size() != 2 || String::trim_outer_whitespace(param_value[0]) != "ID")
        {
            throw Genetic_AI_Creation_Error("Bad ID line: " + line);
        }

        if(id_in == std::stoi(param_value[1]))
        {
            read_ancestry(ifs);
            genome.read_from(ifs);

            recalibrate_self();

            next_id = std::max(next_id, id_number + 1);

            return;
        }
    }

    throw Genetic_AI_Creation_Error("Could not locate ID " + std::to_string(id_in) + " inside file " + file_name);
}

void Genetic_AI::read_from(std::istream& is)
{
    std::string line;
    while(std::getline(is, line))
    {
        line = String::strip_comments(line, "#");
        if(line.empty())
        {
            continue;
        }

        if(String::starts_with(line, "ID"))
        {
            auto param_value = String::split(line, ":", 1);
            if(param_value.size() != 2 || String::trim_outer_whitespace(param_value[0]) != "ID")
            {
                throw Genetic_AI_Creation_Error("Bad ID line: " + line);
            }
            id_number = std::stoi(param_value[1]);
            break;
        }
        else
        {
            throw Genetic_AI_Creation_Error("Invalid Genetic_AI line: " + line);
        }
    }

    if( ! is)
    {
        throw Genetic_AI_Creation_Error("Incomplete Genetic_AI spec in file for ID " + std::to_string(id_number));
    }

    read_ancestry(is);
    genome.read_from(is);

    next_id = std::max(next_id, id_number + 1);
}

double Genetic_AI::internal_evaluate(const Board& board, Color perspective, size_t depth) const
{
    return genome.evaluate(board, perspective, depth);
}

double Genetic_AI::time_to_examine(const Board& board, const Clock& clock) const
{
    return genome.time_to_examine(board, clock);
}

double Genetic_AI::speculation_time_factor(const Board& board) const
{
    return genome.speculation_time_factor(board);
}

//! Apply random mutations to the Genome of the Genetic_AI
//
//! \param mutation_count The number of mutation actions to apply to the genome. Defaults to 1 if unspecified.
void Genetic_AI::mutate(int mutation_count)
{
    for(int i = 0; i < mutation_count; ++i)
    {
        genome.mutate();
    }

    recalibrate_self();
}

//! Prints the information defining this AI.
//
//! The printed information includes the ID number, ancestry information, and genetic data.
//! \param file_name The name of the text file to print to. If empty, print to stdout.
void Genetic_AI::print(const std::string& file_name) const
{
    if(file_name.empty())
    {
        print(std::cout);
    }
    else
    {
        auto dest = std::ofstream(file_name, std::ofstream::app);
        print(dest);
    }
}

//! Print AI information to the given std::ostream.
//
//! \param os The stream to be written to.
void Genetic_AI::print(std::ostream& os) const
{
    os << "ID: " << id() << '\n';
    os << "Name: Ancestry\n";
    for(size_t i = 0; i <= max_origin_pool_id; ++i)
    {
        auto fraction = (ancestry.count(i) > 0 ? ancestry.at(i) : 0.0);
        os << i << ": " << fraction << "\n";
    }
    os << "\n";
    genome.print(os);
    os << "END" << "\n" << std::endl;
}

//! Reports the name of the AI and ID number.
//
//! \returns "Genetic AI" plus the ID.
std::string Genetic_AI::name() const
{
    return "Genetic AI " + std::to_string(id());
}

//! Reports the author of this chess engine.
//
//! \returns "Mark Harrison"
std::string Genetic_AI::author() const
{
    return "Mark Harrison";
}

//! Reports the ID number of the Genetic_AI.
//
//! \returns The ID number.
int Genetic_AI::id() const
{
    return id_number;
}

//! A comparison function to sort Genetic_AI collections.
//
//! \param other Another Genetic_AI.
//! \returns If the other AI should go after this AI.
bool Genetic_AI::operator<(const Genetic_AI& other) const
{
    return id() < other.id();
}

//! This function identifies the first gene pool into which a newly created Genetic_AI is placed.
//
//! \param pool_id The ID number of the gene pool.
void Genetic_AI::set_origin_pool(size_t pool_id)
{
    ancestry.clear();
    ancestry[pool_id] = 1.0;
    max_origin_pool_id = std::max(max_origin_pool_id, pool_id);
}

void Genetic_AI::read_ancestry(std::istream& is)
{
    auto id_string = "(ID: " + std::to_string(id()) + ")";

    std::string line;
    while(std::getline(is, line))
    {
        line = String::strip_comments(line, "#");
        if(line.empty())
        {
            continue;
        }

        if(line != "Name: Ancestry")
        {
            throw Genetic_AI_Creation_Error("Missing ancestry data " + id_string);
        }

        break;
    }

    while(std::getline(is, line))
    {
        if(String::trim_outer_whitespace(line).empty())
        {
            break;
        }
        line = String::strip_comments(line, "#");
        if(line.empty())
        {
            continue;
        }

        auto pool_fraction = String::split(line, ":");
        if(pool_fraction.size() != 2)
        {
            throw Genetic_AI_Creation_Error("Bad ancestry line " + id_string + ": " + line);
        }

        try
        {
            auto pool = String::string_to_size_t(pool_fraction[0]);
            auto fraction = std::stod(pool_fraction[1]);
            ancestry[pool] = fraction;
            max_origin_pool_id = std::max(max_origin_pool_id, pool);
        }
        catch(const std::exception&)
        {
            throw Genetic_AI_Creation_Error("Bad ancesry line " + id_string + ": " + line);
        }
    }
}
<commit_msg>Ancestry data must be first after ID<commit_after>#include "Players/Genetic_AI.h"

#include <iostream>
#include <fstream>
#include <map>
#include <algorithm>

class Board;
class Clock;

#include "Game/Color.h"

#include "Utility/String.h"

#include "Exceptions/Genetic_AI_Creation_Error.h"

int Genetic_AI::next_id = 0;
size_t Genetic_AI::max_origin_pool_id = 0;

//! Generate a randomly mutated Genetic_AI
//
//! \param mutation_count The number of genome mutations to apply to the AI after construction.
Genetic_AI::Genetic_AI(int mutation_count) :
    id_number(next_id++)
{
    mutate(mutation_count);
    recalibrate_self();
}

//! Create a new Genetic_AI via sexual reproduction.
//
//! The offspring is formed by randomly taking genes from each parent.
//! \param A The first parent.
//! \param B The second parent.
Genetic_AI::Genetic_AI(const Genetic_AI& A, const Genetic_AI& B) :
    genome(A.genome, B.genome),
    id_number(next_id++)
{
    auto A_parents = A.ancestry;
    auto B_parents = B.ancestry;
    for(size_t i = 0; i <= max_origin_pool_id; ++i)
    {
        ancestry[i] = (A_parents[i] + B_parents[i])/2;
    }

    recalibrate_self();
}

//! Create a Genetic_AI from information in a text file.
//
//! \param file_name The name of the text file.
//! \throws Genetic_AI_Creation_Error if the file cannot be opened or if there is an error during reading.
Genetic_AI::Genetic_AI(const std::string& file_name)
{
    std::ifstream ifs(file_name);
    if( ! ifs)
    {
        throw Genetic_AI_Creation_Error("Could not read: " + file_name);
    }

    read_from(ifs);

    recalibrate_self();
}

//! Create a Genetic_AI from information in an input stream (std::ifstream, std::cin, etc.).
//
//! \param is Input stream.
//! \throws Genetic_AI_Creation_Error If there is an error during reading.
Genetic_AI::Genetic_AI(std::istream& is)
{
    read_from(is);

    recalibrate_self();
}

//! Create a Genetic_AI from a text file by searching for a specfic ID.
//
//! \param file_name The name of the file with the Genetic_AI data.
//! \param id_in The ID to search for.
//! \throws Genetic_AI_Creation_Error If there is an error during reading.
Genetic_AI::Genetic_AI(const std::string& file_name, int id_in) : id_number(id_in)
{
    std::ifstream ifs(file_name);
    if( ! ifs)
    {
        throw Genetic_AI_Creation_Error("Could not read: " + file_name);
    }

    std::string line;
    while(std::getline(ifs, line))
    {
        line = String::strip_comments(line, "#");
        if( ! String::starts_with(line, "ID"))
        {
            continue;
        }

        auto param_value = String::split(line, ":", 1);
        if(param_value.size() != 2 || String::trim_outer_whitespace(param_value[0]) != "ID")
        {
            throw Genetic_AI_Creation_Error("Bad ID line: " + line);
        }

        if(id_in == std::stoi(param_value[1]))
        {
            read_ancestry(ifs);
            genome.read_from(ifs);

            recalibrate_self();

            next_id = std::max(next_id, id_number + 1);

            return;
        }
    }

    throw Genetic_AI_Creation_Error("Could not locate ID " + std::to_string(id_in) + " inside file " + file_name);
}

void Genetic_AI::read_from(std::istream& is)
{
    std::string line;
    while(std::getline(is, line))
    {
        line = String::strip_comments(line, "#");
        if(line.empty())
        {
            continue;
        }

        if(String::starts_with(line, "ID"))
        {
            auto param_value = String::split(line, ":", 1);
            if(param_value.size() != 2 || String::trim_outer_whitespace(param_value[0]) != "ID")
            {
                throw Genetic_AI_Creation_Error("Bad ID line: " + line);
            }
            id_number = std::stoi(param_value[1]);
            break;
        }
        else
        {
            throw Genetic_AI_Creation_Error("Invalid Genetic_AI line: " + line);
        }
    }

    if( ! is)
    {
        throw Genetic_AI_Creation_Error("Incomplete Genetic_AI spec in file for ID " + std::to_string(id_number));
    }

    read_ancestry(is);
    genome.read_from(is);

    next_id = std::max(next_id, id_number + 1);
}

double Genetic_AI::internal_evaluate(const Board& board, Color perspective, size_t depth) const
{
    return genome.evaluate(board, perspective, depth);
}

double Genetic_AI::time_to_examine(const Board& board, const Clock& clock) const
{
    return genome.time_to_examine(board, clock);
}

double Genetic_AI::speculation_time_factor(const Board& board) const
{
    return genome.speculation_time_factor(board);
}

//! Apply random mutations to the Genome of the Genetic_AI
//
//! \param mutation_count The number of mutation actions to apply to the genome. Defaults to 1 if unspecified.
void Genetic_AI::mutate(int mutation_count)
{
    for(int i = 0; i < mutation_count; ++i)
    {
        genome.mutate();
    }

    recalibrate_self();
}

//! Prints the information defining this AI.
//
//! The printed information includes the ID number, ancestry information, and genetic data.
//! \param file_name The name of the text file to print to. If empty, print to stdout.
void Genetic_AI::print(const std::string& file_name) const
{
    if(file_name.empty())
    {
        print(std::cout);
    }
    else
    {
        auto dest = std::ofstream(file_name, std::ofstream::app);
        print(dest);
    }
}

//! Print AI information to the given std::ostream.
//
//! \param os The stream to be written to.
void Genetic_AI::print(std::ostream& os) const
{
    os << "ID: " << id() << '\n';
    os << "Name: Ancestry\n";
    for(size_t i = 0; i <= max_origin_pool_id; ++i)
    {
        auto fraction = (ancestry.count(i) > 0 ? ancestry.at(i) : 0.0);
        os << i << ": " << fraction << "\n";
    }
    os << "\n";
    genome.print(os);
    os << "END" << "\n" << std::endl;
}

//! Reports the name of the AI and ID number.
//
//! \returns "Genetic AI" plus the ID.
std::string Genetic_AI::name() const
{
    return "Genetic AI " + std::to_string(id());
}

//! Reports the author of this chess engine.
//
//! \returns "Mark Harrison"
std::string Genetic_AI::author() const
{
    return "Mark Harrison";
}

//! Reports the ID number of the Genetic_AI.
//
//! \returns The ID number.
int Genetic_AI::id() const
{
    return id_number;
}

//! A comparison function to sort Genetic_AI collections.
//
//! \param other Another Genetic_AI.
//! \returns If the other AI should go after this AI.
bool Genetic_AI::operator<(const Genetic_AI& other) const
{
    return id() < other.id();
}

//! This function identifies the first gene pool into which a newly created Genetic_AI is placed.
//
//! \param pool_id The ID number of the gene pool.
void Genetic_AI::set_origin_pool(size_t pool_id)
{
    ancestry.clear();
    ancestry[pool_id] = 1.0;
    max_origin_pool_id = std::max(max_origin_pool_id, pool_id);
}

void Genetic_AI::read_ancestry(std::istream& is)
{
    auto id_string = "(ID: " + std::to_string(id()) + ")";

    std::string line;
    while(std::getline(is, line))
    {
        line = String::strip_comments(line, "#");
        if(line.empty())
        {
            continue;
        }

        if(String::starts_with(line, "Name"))
        {
            auto data = String::split(line, ":", 1);
            auto header = String::trim_outer_whitespace(data.front());
            if(data.size() != 2 || header != "Name")
            {
                throw Genetic_AI_Creation_Error("Bad section header (" + id_string + "): " + line);
            }
            auto section = String::remove_extra_whitespace(data.back());
            if(section == "Ancestry")
            {
                break;
            }
            else
            {
                throw Genetic_AI_Creation_Error("Missing ancestry data " + id_string);
            }
        }
    }

    while(std::getline(is, line))
    {
        if(String::trim_outer_whitespace(line).empty())
        {
            break;
        }
        line = String::strip_comments(line, "#");
        if(line.empty())
        {
            continue;
        }

        auto pool_fraction = String::split(line, ":");
        if(pool_fraction.size() != 2)
        {
            throw Genetic_AI_Creation_Error("Bad ancestry line " + id_string + ": " + line);
        }

        try
        {
            auto pool = String::string_to_size_t(pool_fraction[0]);
            auto fraction = std::stod(pool_fraction[1]);
            ancestry[pool] = fraction;
            max_origin_pool_id = std::max(max_origin_pool_id, pool);
        }
        catch(const std::exception&)
        {
            throw Genetic_AI_Creation_Error("Bad ancesry line " + id_string + ": " + line);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Signify version number is a request, not a requirement<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "mem/ruby/buffers/MessageBufferNode.hh"

void
MessageBufferNode::print(std::ostream& out) const
{
    out << "[";
    out << m_time << ", ";
    out << m_msg_counter << ", ";
    out << m_msgptr << "; ";
    out << "]";
}
<commit_msg># User Brad Beckmann <Brad.Beckmann@amd.com> ruby: fixed msgptr print call<commit_after>/*
 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "mem/ruby/buffers/MessageBufferNode.hh"

void
MessageBufferNode::print(std::ostream& out) const
{
    out << "[";
    out << m_time << ", ";
    out << m_msg_counter << ", ";
    out << *m_msgptr << "; ";
    out << "]";
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <numeric>
#include <cstdlib>
#include <cstdio>
#include <cmath>
using namespace std;

typedef vector<vector<int> > Matrix;

void printVector(const Matrix& m)
{
    int n = m.size();
    cout << "***matirx:" << endl;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            printf("%d ", m[i][j]);
        }
        printf("\n");
    }
    printf("\n***ED***\n");
}
void flipRow(int i, Matrix& m)
{
    for (int j = 0; j < m.size(); j++)
    {
        m[i][j] = 1 - m[i][j];
    }
}
void flipCol(int j, Matrix& m)
{
    for (int i = 0; i < m.size(); ++i)
    {
        m[i][j] = 1 - m[i][j];
    }
}

int unusualSquare(const Matrix& m)
{
    int n = m.size();
    int sum = 0;
    for (int i = 0; i < n; ++i)
    {
        for (int k = 0; k < n; ++k)
        {
            sum += m[i][k] * m[k][i];
        }
    }
    return sum % 2;
}

int main()
{
    //freopen("data.txt", "r", stdin);

    int n = 0;
    scanf("%d", &n);

    vector<vector<int> > a(n, vector<int>(n, 0));
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            scanf("%d", &a[i][j]);
        }
    }

    string ans;
    int type = 0;
    int row = 0;
    int col = 0;
    int q = 0;
    scanf("%d", &q);
    for (int k = 0; k < q; ++k)
    {
        scanf("%d", &type);
        if (type == 3)
        {
            int tmp = unusualSquare(a);
            ans.push_back(tmp + '0');
            cout << "tmp" << tmp << endl;
            printVector(a);
        }
        else if (type == 1)
        {
            scanf("%d", &row);
            flipRow(row, a);
            printVector(a);
        }
        else
        {
            scanf("%d", &col);
            flipCol(col, a);
            printVector(a);
        }
    }

    cout << ans << endl;
    return 0;

}
<commit_msg>find the bug, it is because vector exceeded, Be careful next time, some sample TLE, TODO<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <numeric>
#include <cstdlib>
#include <cstdio>
#include <cmath>
using namespace std;

typedef vector<vector<int> > Matrix;

void printVector(const Matrix& m)
{
    int n = m.size();
    cout << "***matirx:" << endl;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            printf("%d ", m[i][j]);
        }
        printf("\n");
    }
    printf("\n***ED***\n");
}
// What a shame, the ith row or col correponding to i - 1 , j - 1
void flipRow(int i, Matrix& m)
{
    for (int j = 0; j < m.size(); j++)
    {
        m[i-1][j] = 1 - m[i-1][j];
    }
}
void flipCol(int j, Matrix& m)
{
    for (int i = 0; i < m.size(); ++i)
    {
        m[i][j-1] = 1 - m[i][j-1];
    }
}

int unusualSquare(const Matrix& m)
{
    int n = m.size();
    int sum = 0;
    for (int i = 0; i < n; ++i)
    {
        for (int k = 0; k < n; ++k)
        {
            sum += m[i][k] * m[k][i];
        }
    }
    return sum % 2;
}

int main()
{
    //freopen("data.txt", "r", stdin);

    int n = 0;
    scanf("%d", &n);

    vector<vector<int> > a(n, vector<int>(n, 0));
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            scanf("%d", &a[i][j]);
        }
    }

    string ans;
    int type = 0;
    int row = 0;
    int col = 0;
    int q = 0;
    scanf("%d", &q);
    for (int k = 0; k < q; ++k)
    {
        scanf("%d", &type);
        if (type == 3)
        {
            int tmp = unusualSquare(a);
            ans.push_back(tmp + '0');
            // cout << "tmp" << tmp << endl;
            // printVector(a);
        }
        else if (type == 1)
        {
            scanf("%d", &row);
            flipRow(row, a);
            // printVector(a);
        }
        else
        {
            scanf("%d", &col);
            flipCol(col, a);
            // printVector(a);
        }
    }

    cout << ans << endl;
    return 0;
}
<|endoftext|>


<commit_before>
#include <fstream>
#include <sstream>
#include <string>
#include <map>

// Super simple version of delegates, for handling
// passes with different return values

class Delegate {
public:
    virtual ~Delegate() {}
    virtual llvm::Pass* operator () () = 0;
};

template <typename Ret>
class Delegate0: public Delegate {
public:
    typedef Ret (*fn_ptr)();

    Delegate0(fn_ptr _fn) : fn(_fn) {}

    virtual llvm::Pass* operator () () {
        return fn();
    }

private:
    fn_ptr fn;
};

template <typename Ret>
Delegate* wrap_fn(Ret (*fn)()) {
    return new Delegate0<Ret>(fn);
}

// Special cases that can't be wrapped by delegates because they
// have default parameters that are hard to encode in fn pointers

inline llvm::Pass* _createAddressSanitizerFunctionPass() {
    return llvm::createAddressSanitizerFunctionPass();
}

inline llvm::Pass* _createGVNPass() {
    return llvm::createGVNPass();
}

inline llvm::Pass* _createLoopUnrollPass() {
    return llvm::createLoopUnrollPass();
}

inline llvm::Pass* _createLoopUnswitchPass() {
    return llvm::createLoopUnswitchPass();
}

inline llvm::Pass* _createScalarReplAggregatesPass() {
    return llvm::createScalarReplAggregatesPass();
}

inline llvm::Pass* _createSROAPass () {
    return llvm::createSROAPass();
}

inline llvm::Pass* _createSeparateConstOffsetFromGEPPass () {
    return llvm::createSeparateConstOffsetFromGEPPass();
}

// -------

void setup_passes_from_file(FunctionPassManager* FPM, const char* pass_file_name) {
    //jl_printf(JL_STDOUT, "applying llvm passes from file: %s\n", pass_file_name);

    // create a map of pass functions, for convenience
    std::map<std::string, Delegate*> ir_passes;
    ir_passes["createAddressSanitizerFunctionPass"] = wrap_fn(_createAddressSanitizerFunctionPass);
    ir_passes["createTypeBasedAliasAnalysisPass"] =   wrap_fn(llvm::createTypeBasedAliasAnalysisPass);
    ir_passes["createBasicAliasAnalysisPass"] =       wrap_fn(llvm::createBasicAliasAnalysisPass);
    ir_passes["createCFGSimplificationPass"] =        wrap_fn(llvm::createCFGSimplificationPass);
    ir_passes["createPromoteMemoryToRegisterPass"] =  wrap_fn(llvm::createPromoteMemoryToRegisterPass);
    ir_passes["createInstructionCombiningPass"] =     wrap_fn(llvm::createInstructionCombiningPass);
    ir_passes["createScalarReplAggregatesPass"] =     wrap_fn(_createScalarReplAggregatesPass);
    ir_passes["createJumpThreadingPass"] =            wrap_fn(llvm::createJumpThreadingPass);
    ir_passes["createReassociatePass"] =              wrap_fn(llvm::createReassociatePass);
    ir_passes["createEarlyCSEPass"] =                 wrap_fn(llvm::createEarlyCSEPass);
    ir_passes["createLoopIdiomPass"] =                wrap_fn(llvm::createLoopIdiomPass);
    ir_passes["createLoopRotatePass"] =               wrap_fn(llvm::createLoopRotatePass);
    ir_passes["createLowerSimdLoopPass"] =            wrap_fn(llvm::createLowerSimdLoopPass);
    ir_passes["createLICMPass"] =                     wrap_fn(llvm::createLICMPass);
    ir_passes["createLoopUnswitchPass"] =             wrap_fn(_createLoopUnswitchPass);
    ir_passes["createIndVarSimplifyPass"] =           wrap_fn(llvm::createIndVarSimplifyPass);
    ir_passes["createLoopDeletionPass"] =             wrap_fn(llvm::createLoopDeletionPass);
    ir_passes["createLoopUnrollPass"] =               wrap_fn(_createLoopUnrollPass);
    ir_passes["createLoopVectorizePass"] =            wrap_fn(llvm::createLoopVectorizePass);
    ir_passes["createGVNPass"] =                      wrap_fn(_createGVNPass);
    ir_passes["createSCCPPass"] =                     wrap_fn(llvm::createSCCPPass);
    ir_passes["createSinkingPass"] =                  wrap_fn(llvm::createSinkingPass);
    ir_passes["createInstructionSimplifierPass"] =    wrap_fn(llvm::createInstructionSimplifierPass);
    ir_passes["createDeadStoreEliminationPass"] =     wrap_fn(llvm::createDeadStoreEliminationPass);
    ir_passes["createSLPVectorizerPass"] =            wrap_fn(llvm::createSLPVectorizerPass);
    ir_passes["createAggressiveDCEPass"] =            wrap_fn(llvm::createAggressiveDCEPass);

    ir_passes["createConstantPropagationPass"] = wrap_fn(llvm::createConstantPropagationPass);
    ir_passes["createAlignmentFromAssumptionsPass"] = wrap_fn(llvm::createAlignmentFromAssumptionsPass);
    ir_passes["createDeadInstEliminationPass"] = wrap_fn(llvm::createDeadInstEliminationPass);
    ir_passes["createDeadCodeEliminationPass"] = wrap_fn(llvm::createDeadCodeEliminationPass);
    ir_passes["createBitTrackingDCEPass"] = wrap_fn(llvm::createBitTrackingDCEPass);
    ir_passes["createSROAPass"] = wrap_fn(_createSROAPass);
    ir_passes["createInductiveRangeCheckEliminationPass"] = wrap_fn(llvm::createInductiveRangeCheckEliminationPass);
    ir_passes["createLoopInterchangePass"] = wrap_fn(llvm::createLoopInterchangePass);
    ir_passes["createLoopStrengthReducePass"] = wrap_fn(llvm::createLoopStrengthReducePass);
    ir_passes["createLoopInstSimplifyPass"] = wrap_fn(llvm::createLoopInstSimplifyPass);
    ir_passes["createSimpleLoopUnrollPass"] = wrap_fn(llvm::createSimpleLoopUnrollPass);
    ir_passes["createLoopRerollPass"] = wrap_fn(llvm::createLoopRerollPass);
    ir_passes["createFlattenCFGPass"] = wrap_fn(llvm::createFlattenCFGPass);
    ir_passes["createStructurizeCFGPass"] = wrap_fn(llvm::createStructurizeCFGPass);
    ir_passes["createTailCallEliminationPass"] = wrap_fn(llvm::createTailCallEliminationPass);
    ir_passes["createMergedLoadStoreMotionPass"] = wrap_fn(llvm::createMergedLoadStoreMotionPass);
    ir_passes["createMemCpyOptPass"] = wrap_fn(llvm::createMemCpyOptPass);
    ir_passes["createConstantHoistingPass"] = wrap_fn(llvm::createConstantHoistingPass);
    ir_passes["createLowerAtomicPass"] = wrap_fn(llvm::createLowerAtomicPass);
    ir_passes["createCorrelatedValuePropagationPass"] = wrap_fn(llvm::createCorrelatedValuePropagationPass);
    ir_passes["createLowerExpectIntrinsicPass"] = wrap_fn(llvm::createLowerExpectIntrinsicPass);
    ir_passes["createPartiallyInlineLibCallsPass"] = wrap_fn(llvm::createPartiallyInlineLibCallsPass);
    ir_passes["createSampleProfileLoaderPass"] = wrap_fn(llvm::createSampleProfileLoaderPass);
    ir_passes["createScalarizerPass"] = wrap_fn(llvm::createScalarizerPass);
    ir_passes["createAddDiscriminatorsPass"] = wrap_fn(llvm::createAddDiscriminatorsPass);
    ir_passes["createSeparateConstOffsetFromGEPPass"] = wrap_fn(_createSeparateConstOffsetFromGEPPass);
    ir_passes["createSpeculativeExecutionPass"] = wrap_fn(llvm::createSpeculativeExecutionPass);
    ir_passes["createLoadCombinePass"] = wrap_fn(llvm::createLoadCombinePass);
    ir_passes["createStraightLineStrengthReducePass"] = wrap_fn(llvm::createStraightLineStrengthReducePass);
    ir_passes["createPlaceSafepointsPass"] = wrap_fn(llvm::createPlaceSafepointsPass);
    ir_passes["createRewriteStatepointsForGCPass"] = wrap_fn(llvm::createRewriteStatepointsForGCPass);
    ir_passes["createNaryReassociatePass"] = wrap_fn(llvm::createNaryReassociatePass);
    ir_passes["createLoopDistributePass"] = wrap_fn(llvm::createLoopDistributePass);

    std::ifstream pass_file(pass_file_name);
    std::string pass_name;
    while (std::getline(pass_file, pass_name)) {
        //jl_printf(JL_STDOUT, "applying pass: %s\n", pass_name.c_str());
        FPM->add((*ir_passes[pass_name])());
    }

    // clean up our pass function delegates so that we don't leak
    for (std::map<std::string, Delegate*>::iterator i = ir_passes.begin(); i != ir_passes.end(); ++i) {
        delete i->second;
    }
}
<commit_msg>only use passes available in this version of llvm<commit_after>
#include <fstream>
#include <sstream>
#include <string>
#include <map>

#include <llvm/Transforms/Scalar.h>

// Super simple version of delegates, for handling
// passes with different return values

class Delegate {
public:
    virtual ~Delegate() {}
    virtual llvm::Pass* operator () () = 0;
};

template <typename Ret>
class Delegate0: public Delegate {
public:
    typedef Ret (*fn_ptr)();

    Delegate0(fn_ptr _fn) : fn(_fn) {}

    virtual llvm::Pass* operator () () {
        return fn();
    }

private:
    fn_ptr fn;
};

template <typename Ret>
Delegate* wrap_fn(Ret (*fn)()) {
    return new Delegate0<Ret>(fn);
}

// Special cases that can't be wrapped by delegates because they
// have default parameters that are hard to encode in fn pointers

inline llvm::Pass* _createAddressSanitizerFunctionPass() {
    return llvm::createAddressSanitizerFunctionPass();
}

inline llvm::Pass* _createGVNPass() {
    return llvm::createGVNPass();
}

inline llvm::Pass* _createLoopUnrollPass() {
    return llvm::createLoopUnrollPass();
}

inline llvm::Pass* _createLoopUnswitchPass() {
    return llvm::createLoopUnswitchPass();
}

inline llvm::Pass* _createScalarReplAggregatesPass() {
    return llvm::createScalarReplAggregatesPass();
}

inline llvm::Pass* _createSROAPass () {
    return llvm::createSROAPass();
}

inline llvm::Pass* _createGlobalMergePass () {
    return llvm::createGlobalMergePass();
}

// inline llvm::Pass* _createSeparateConstOffsetFromGEPPass () {
//     return llvm::createSeparateConstOffsetFromGEPPass();
// }

// -------

void setup_passes_from_file(FunctionPassManager* FPM, const char* pass_file_name) {
    //jl_printf(JL_STDOUT, "applying llvm passes from file: %s\n", pass_file_name);

    // create a map of pass functions, for convenience
    std::map<std::string, Delegate*> ir_passes;
    ir_passes["createAddressSanitizerFunctionPass"] = wrap_fn(_createAddressSanitizerFunctionPass);
    ir_passes["createTypeBasedAliasAnalysisPass"] =   wrap_fn(llvm::createTypeBasedAliasAnalysisPass);
    ir_passes["createBasicAliasAnalysisPass"] =       wrap_fn(llvm::createBasicAliasAnalysisPass);
    ir_passes["createCFGSimplificationPass"] =        wrap_fn(llvm::createCFGSimplificationPass);
    ir_passes["createPromoteMemoryToRegisterPass"] =  wrap_fn(llvm::createPromoteMemoryToRegisterPass);
    ir_passes["createInstructionCombiningPass"] =     wrap_fn(llvm::createInstructionCombiningPass);
    ir_passes["createScalarReplAggregatesPass"] =     wrap_fn(_createScalarReplAggregatesPass);
    ir_passes["createJumpThreadingPass"] =            wrap_fn(llvm::createJumpThreadingPass);
    ir_passes["createReassociatePass"] =              wrap_fn(llvm::createReassociatePass);
    ir_passes["createEarlyCSEPass"] =                 wrap_fn(llvm::createEarlyCSEPass);
    ir_passes["createLoopIdiomPass"] =                wrap_fn(llvm::createLoopIdiomPass);
    ir_passes["createLoopRotatePass"] =               wrap_fn(llvm::createLoopRotatePass);
    ir_passes["createLowerSimdLoopPass"] =            wrap_fn(llvm::createLowerSimdLoopPass);
    ir_passes["createLICMPass"] =                     wrap_fn(llvm::createLICMPass);
    ir_passes["createLoopUnswitchPass"] =             wrap_fn(_createLoopUnswitchPass);
    ir_passes["createIndVarSimplifyPass"] =           wrap_fn(llvm::createIndVarSimplifyPass);
    ir_passes["createLoopDeletionPass"] =             wrap_fn(llvm::createLoopDeletionPass);
    ir_passes["createLoopUnrollPass"] =               wrap_fn(_createLoopUnrollPass);
    ir_passes["createLoopVectorizePass"] =            wrap_fn(llvm::createLoopVectorizePass);
    ir_passes["createGVNPass"] =                      wrap_fn(_createGVNPass);
    ir_passes["createSCCPPass"] =                     wrap_fn(llvm::createSCCPPass);
    ir_passes["createSinkingPass"] =                  wrap_fn(llvm::createSinkingPass);
    ir_passes["createInstructionSimplifierPass"] =    wrap_fn(llvm::createInstructionSimplifierPass);
    ir_passes["createDeadStoreEliminationPass"] =     wrap_fn(llvm::createDeadStoreEliminationPass);
    ir_passes["createSLPVectorizerPass"] =            wrap_fn(llvm::createSLPVectorizerPass);
    ir_passes["createAggressiveDCEPass"] =            wrap_fn(llvm::createAggressiveDCEPass);

    ir_passes["createConstantPropagationPass"] = wrap_fn(llvm::createConstantPropagationPass);
    // ir_passes["createAlignmentFromAssumptionsPass"] = wrap_fn(llvm::createAlignmentFromAssumptionsPass);
    ir_passes["createDeadInstEliminationPass"] = wrap_fn(llvm::createDeadInstEliminationPass);
    ir_passes["createDeadCodeEliminationPass"] = wrap_fn(llvm::createDeadCodeEliminationPass);
    // ir_passes["createBitTrackingDCEPass"] = wrap_fn(llvm::createBitTrackingDCEPass);
    ir_passes["createSROAPass"] = wrap_fn(_createSROAPass);
    // ir_passes["createInductiveRangeCheckEliminationPass"] = wrap_fn(llvm::createInductiveRangeCheckEliminationPass);
    // ir_passes["createLoopInterchangePass"] = wrap_fn(llvm::createLoopInterchangePass);
    ir_passes["createLoopStrengthReducePass"] = wrap_fn(llvm::createLoopStrengthReducePass);
    ir_passes["createLoopInstSimplifyPass"] = wrap_fn(llvm::createLoopInstSimplifyPass);
    // ir_passes["createSimpleLoopUnrollPass"] = wrap_fn(llvm::createSimpleLoopUnrollPass);
    // ir_passes["createLoopRerollPass"] = wrap_fn(llvm::createLoopRerollPass);
    // ir_passes["createFlattenCFGPass"] = wrap_fn(llvm::createFlattenCFGPass);
    // ir_passes["createStructurizeCFGPass"] = wrap_fn(llvm::createStructurizeCFGPass);
    ir_passes["createTailCallEliminationPass"] = wrap_fn(llvm::createTailCallEliminationPass);
    // ir_passes["createMergedLoadStoreMotionPass"] = wrap_fn(llvm::createMergedLoadStoreMotionPass);
    ir_passes["createMemCpyOptPass"] = wrap_fn(llvm::createMemCpyOptPass);
    // ir_passes["createConstantHoistingPass"] = wrap_fn(llvm::createConstantHoistingPass);
    ir_passes["createLowerAtomicPass"] = wrap_fn(llvm::createLowerAtomicPass);
    ir_passes["createCorrelatedValuePropagationPass"] = wrap_fn(llvm::createCorrelatedValuePropagationPass);
    ir_passes["createLowerExpectIntrinsicPass"] = wrap_fn(llvm::createLowerExpectIntrinsicPass);
    // ir_passes["createPartiallyInlineLibCallsPass"] = wrap_fn(llvm::createPartiallyInlineLibCallsPass);
    // ir_passes["createSampleProfileLoaderPass"] = wrap_fn(llvm::createSampleProfileLoaderPass);
    // ir_passes["createScalarizerPass"] = wrap_fn(llvm::createScalarizerPass);
    // ir_passes["createAddDiscriminatorsPass"] = wrap_fn(llvm::createAddDiscriminatorsPass);
    // ir_passes["createSeparateConstOffsetFromGEPPass"] = wrap_fn(_createSeparateConstOffsetFromGEPPass);
    // ir_passes["createSpeculativeExecutionPass"] = wrap_fn(llvm::createSpeculativeExecutionPass);
    // ir_passes["createLoadCombinePass"] = wrap_fn(llvm::createLoadCombinePass);
    // ir_passes["createStraightLineStrengthReducePass"] = wrap_fn(llvm::createStraightLineStrengthReducePass);
    // ir_passes["createPlaceSafepointsPass"] = wrap_fn(llvm::createPlaceSafepointsPass);
    // ir_passes["createRewriteStatepointsForGCPass"] = wrap_fn(llvm::createRewriteStatepointsForGCPass);
    // ir_passes["createNaryReassociatePass"] = wrap_fn(llvm::createNaryReassociatePass);
    // ir_passes["createLoopDistributePass"] = wrap_fn(llvm::createLoopDistributePass);
    ir_passes["createGlobalMergePass"] = wrap_fn(_createGlobalMergePass);

    std::ifstream pass_file(pass_file_name);
    std::string pass_name;
    while (std::getline(pass_file, pass_name)) {
        //jl_printf(JL_STDOUT, "applying pass: %s\n", pass_name.c_str());
        FPM->add((*ir_passes[pass_name])());
    }

    // clean up our pass function delegates so that we don't leak
    for (std::map<std::string, Delegate*>::iterator i = ir_passes.begin(); i != ir_passes.end(); ++i) {
        delete i->second;
    }
}
<|endoftext|>


<commit_before>/**
 * @file kmeans_main.cpp
 * @author Ryan Curtin
 *
 * Executable for running K-Means.
 */
#include <mlpack/core.hpp>

#include "kmeans.hpp"
#include "allow_empty_clusters.hpp"
#include "refined_start.hpp"
#include "elkan_kmeans.hpp"
#include "hamerly_kmeans.hpp"
#include "pelleg_moore_kmeans.hpp"
#include "dtnn_kmeans.hpp"

using namespace mlpack;
using namespace mlpack::kmeans;
using namespace std;

// Define parameters for the executable.
PROGRAM_INFO("K-Means Clustering", "This program performs K-Means clustering "
    "on the given dataset, storing the learned cluster assignments either as "
    "a column of labels in the file containing the input dataset or in a "
    "separate file.  Empty clusters are not allowed by default; when a cluster "
    "becomes empty, the point furthest from the centroid of the cluster with "
    "maximum variance is taken to fill that cluster."
    "\n\n"
    "Optionally, the Bradley and Fayyad approach (\"Refining initial points for"
    " k-means clustering\", 1998) can be used to select initial points by "
    "specifying the --refined_start (-r) option.  This approach works by taking"
    " random samples of the dataset; to specify the number of samples, the "
    "--samples parameter is used, and to specify the percentage of the dataset "
    "to be used in each sample, the --percentage parameter is used (it should "
    "be a value between 0.0 and 1.0)."
    "\n\n"
    "There are several options available for the algorithm used for each Lloyd "
    "iteration, specified with the --algorithm (-a) option.  The standard O(kN)"
    " approach can be used ('naive').  Other options include the Pelleg-Moore "
    "tree-based algorithm ('pelleg-moore'), Elkan's triangle-inequality based "
    "algorithm ('elkan'), and Hamerly's modification to Elkan's algorithm "
    "('hamerly')."
    "\n\n"
    "As of October 2014, the --overclustering option has been removed.  If you "
    "want this support back, let us know -- file a bug at "
    "http://www.mlpack.org/trac/ or get in touch through another means.");

// Required options.
PARAM_STRING_REQ("inputFile", "Input dataset to perform clustering on.", "i");
PARAM_INT_REQ("clusters", "Number of clusters to find.", "c");

// Output options.
PARAM_FLAG("in_place", "If specified, a column containing the learned cluster "
    "assignments will be added to the input dataset file.  In this case, "
    "--outputFile is overridden.", "P");
PARAM_STRING("output_file", "File to write output labels or labeled data to.",
    "o", "");
PARAM_STRING("centroid_file", "If specified, the centroids of each cluster will"
    " be written to the given file.", "C", "");

// k-means configuration options.
PARAM_FLAG("allow_empty_clusters", "Allow empty clusters to be created.", "e");
PARAM_FLAG("labels_only", "Only output labels into output file.", "l");
PARAM_INT("max_iterations", "Maximum number of iterations before K-Means "
    "terminates.", "m", 1000);
PARAM_INT("seed", "Random seed.  If 0, 'std::time(NULL)' is used.", "s", 0);
PARAM_STRING("initial_centroids", "Start with the specified initial centroids.",
             "I", "");

// Parameters for "refined start" k-means.
PARAM_FLAG("refined_start", "Use the refined initial point strategy by Bradley "
    "and Fayyad to choose initial points.", "r");
PARAM_INT("samplings", "Number of samplings to perform for refined start (use "
    "when --refined_start is specified).", "S", 100);
PARAM_DOUBLE("percentage", "Percentage of dataset to use for each refined start"
    " sampling (use when --refined_start is specified).", "p", 0.02);

PARAM_STRING("algorithm", "Algorithm to use for the Lloyd iteration ('naive', "
    "'pelleg-moore', 'elkan', 'hamerly', or 'dtnn').", "a", "naive");

// Given the type of initial partition policy, figure out the empty cluster
// policy and run k-means.
template<typename InitialPartitionPolicy>
void FindEmptyClusterPolicy(const InitialPartitionPolicy& ipp);

// Given the initial partitionining policy and empty cluster policy, figure out
// the Lloyd iteration step type and run k-means.
template<typename InitialPartitionPolicy, typename EmptyClusterPolicy>
void FindLloydStepType(const InitialPartitionPolicy& ipp);

// Given the template parameters, sanitize/load input and run k-means.
template<typename InitialPartitionPolicy,
         typename EmptyClusterPolicy,
         template<class, class> class LloydStepType>
void RunKMeans(const InitialPartitionPolicy& ipp);

int main(int argc, char** argv)
{
  CLI::ParseCommandLine(argc, argv);

  // Initialize random seed.
  if (CLI::GetParam<int>("seed") != 0)
    math::RandomSeed((size_t) CLI::GetParam<int>("seed"));
  else
    math::RandomSeed((size_t) std::time(NULL));

  // Now, start building the KMeans type that we'll be using.  Start with the
  // initial partition policy.  The call to FindEmptyClusterPolicy<> results in
  // a call to RunKMeans<> and the algorithm is completed.
  if (CLI::HasParam("refined_start"))
  {
    const int samplings = CLI::GetParam<int>("samplings");
    const double percentage = CLI::GetParam<double>("percentage");

    if (samplings < 0)
      Log::Fatal << "Number of samplings (" << samplings << ") must be "
          << "greater than 0!" << endl;
    if (percentage <= 0.0 || percentage > 1.0)
      Log::Fatal << "Percentage for sampling (" << percentage << ") must be "
          << "greater than 0.0 and less than or equal to 1.0!" << endl;

    FindEmptyClusterPolicy<RefinedStart>(RefinedStart(samplings, percentage));
  }
  else
  {
    FindEmptyClusterPolicy<RandomPartition>(RandomPartition());
  }
}

// Given the type of initial partition policy, figure out the empty cluster
// policy and run k-means.
template<typename InitialPartitionPolicy>
void FindEmptyClusterPolicy(const InitialPartitionPolicy& ipp)
{
  if (CLI::HasParam("allow_empty_clusters"))
    FindLloydStepType<InitialPartitionPolicy, AllowEmptyClusters>(ipp);
  else
    FindLloydStepType<InitialPartitionPolicy, MaxVarianceNewCluster>(ipp);
}

// Given the initial partitionining policy and empty cluster policy, figure out
// the Lloyd iteration step type and run k-means.
template<typename InitialPartitionPolicy, typename EmptyClusterPolicy>
void FindLloydStepType(const InitialPartitionPolicy& ipp)
{
  const string algorithm = CLI::GetParam<string>("algorithm");
  if (algorithm == "elkan")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy, ElkanKMeans>(ipp);
  else if (algorithm == "hamerly")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy, HamerlyKMeans>(ipp);
  else if (algorithm == "pelleg-moore")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy,
        PellegMooreKMeans>(ipp);
  else if (algorithm == "dtnn")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy,
        DefaultDTNNKMeans>(ipp);
  else if (algorithm == "naive")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy, NaiveKMeans>(ipp);
  else
    Log::Fatal << "Unknown algorithm: '" << algorithm << "'.  Supported options"
        << " are 'naive', 'pelleg-moore', 'elkan', and 'hamerly'." << endl;
}

// Given the template parameters, sanitize/load input and run k-means.
template<typename InitialPartitionPolicy,
         typename EmptyClusterPolicy,
         template<class, class> class LloydStepType>
void RunKMeans(const InitialPartitionPolicy& ipp)
{
  // Now, do validation of input options.
  const string inputFile = CLI::GetParam<string>("inputFile");
  const int clusters = CLI::GetParam<int>("clusters");
  if (clusters < 1)
  {
    Log::Fatal << "Invalid number of clusters requested (" << clusters << ")! "
        << "Must be greater than or equal to 1." << endl;
  }

  const int maxIterations = CLI::GetParam<int>("max_iterations");
  if (maxIterations < 0)
  {
    Log::Fatal << "Invalid value for maximum iterations (" << maxIterations <<
        ")! Must be greater than or equal to 0." << endl;
  }

  // Make sure we have an output file if we're not doing the work in-place.
  if (!CLI::HasParam("in_place") && !CLI::HasParam("output_file") &&
      !CLI::HasParam("centroid_file"))
  {
    Log::Warn << "--output_file, --in_place, and --centroid_file are not set; "
        << "no results will be saved." << std::endl;
  }

  // Load our dataset.
  arma::mat dataset;
  data::Load(inputFile, dataset, true); // Fatal upon failure.

  arma::mat centroids;

  const bool initialCentroidGuess = CLI::HasParam("initial_centroids");
  // Load initial centroids if the user asked for it.
  if (initialCentroidGuess)
  {
    string initialCentroidsFile = CLI::GetParam<string>("initial_centroids");
    data::Load(initialCentroidsFile, centroids, true);

    if (CLI::HasParam("refined_start"))
      Log::Warn << "Initial centroids are specified, but will be ignored "
          << "because --refined_start is also specified!" << endl;
    else
      Log::Info << "Using initial centroid guesses from '" <<
          initialCentroidsFile << "'." << endl;
  }

  KMeans<metric::EuclideanDistance,
         InitialPartitionPolicy,
         EmptyClusterPolicy,
         LloydStepType> kmeans(maxIterations, metric::EuclideanDistance(), ipp);

  if (CLI::HasParam("output_file") || CLI::HasParam("in_place"))
  {
    // We need to get the assignments.
    arma::Col<size_t> assignments;
    Timer::Start("clustering");
    kmeans.Cluster(dataset, clusters, assignments, centroids,
        false, initialCentroidGuess);
    Timer::Stop("clustering");

    // Now figure out what to do with our results.
    if (CLI::HasParam("in_place"))
    {
      // Add the column of assignments to the dataset; but we have to convert
      // them to type double first.
      arma::vec converted(assignments.n_elem);
      for (size_t i = 0; i < assignments.n_elem; i++)
        converted(i) = (double) assignments(i);

      dataset.insert_rows(dataset.n_rows, trans(converted));

      // Save the dataset.
      data::Save(inputFile, dataset);
    }
    else
    {
      if (CLI::HasParam("labels_only"))
      {
        // Save only the labels.
        string outputFile = CLI::GetParam<string>("output_file");
        arma::Mat<size_t> output = trans(assignments);
        data::Save(outputFile, output);
      }
      else
      {
        // Convert the assignments to doubles.
        arma::vec converted(assignments.n_elem);
        for (size_t i = 0; i < assignments.n_elem; i++)
          converted(i) = (double) assignments(i);

        dataset.insert_rows(dataset.n_rows, trans(converted));

        // Now save, in the different file.
        string outputFile = CLI::GetParam<string>("output_file");
        data::Save(outputFile, dataset);
      }
    }
  }
  else
  {
    // Just save the centroids.
    Timer::Start("clustering");
    kmeans.Cluster(dataset, clusters, centroids, initialCentroidGuess);
    Timer::Stop("clustering");
  }

  // Should we write the centroids to a file?
  if (CLI::HasParam("centroid_file"))
    data::Save(CLI::GetParam<std::string>("centroid_file"), centroids);
}
<commit_msg>Add DualTreeKMeans as an option to the kmeans program (and also DTNN with cover trees).<commit_after>/**
 * @file kmeans_main.cpp
 * @author Ryan Curtin
 *
 * Executable for running K-Means.
 */
#include <mlpack/core.hpp>

#include "kmeans.hpp"
#include "allow_empty_clusters.hpp"
#include "refined_start.hpp"
#include "elkan_kmeans.hpp"
#include "hamerly_kmeans.hpp"
#include "pelleg_moore_kmeans.hpp"
#include "dtnn_kmeans.hpp"
#include "dual_tree_kmeans.hpp"

using namespace mlpack;
using namespace mlpack::kmeans;
using namespace std;

// Define parameters for the executable.
PROGRAM_INFO("K-Means Clustering", "This program performs K-Means clustering "
    "on the given dataset, storing the learned cluster assignments either as "
    "a column of labels in the file containing the input dataset or in a "
    "separate file.  Empty clusters are not allowed by default; when a cluster "
    "becomes empty, the point furthest from the centroid of the cluster with "
    "maximum variance is taken to fill that cluster."
    "\n\n"
    "Optionally, the Bradley and Fayyad approach (\"Refining initial points for"
    " k-means clustering\", 1998) can be used to select initial points by "
    "specifying the --refined_start (-r) option.  This approach works by taking"
    " random samples of the dataset; to specify the number of samples, the "
    "--samples parameter is used, and to specify the percentage of the dataset "
    "to be used in each sample, the --percentage parameter is used (it should "
    "be a value between 0.0 and 1.0)."
    "\n\n"
    "There are several options available for the algorithm used for each Lloyd "
    "iteration, specified with the --algorithm (-a) option.  The standard O(kN)"
    " approach can be used ('naive').  Other options include the Pelleg-Moore "
    "tree-based algorithm ('pelleg-moore'), Elkan's triangle-inequality based "
    "algorithm ('elkan'), and Hamerly's modification to Elkan's algorithm "
    "('hamerly')."
    "\n\n"
    "As of October 2014, the --overclustering option has been removed.  If you "
    "want this support back, let us know -- file a bug at "
    "http://www.mlpack.org/trac/ or get in touch through another means.");

// Required options.
PARAM_STRING_REQ("inputFile", "Input dataset to perform clustering on.", "i");
PARAM_INT_REQ("clusters", "Number of clusters to find.", "c");

// Output options.
PARAM_FLAG("in_place", "If specified, a column containing the learned cluster "
    "assignments will be added to the input dataset file.  In this case, "
    "--outputFile is overridden.", "P");
PARAM_STRING("output_file", "File to write output labels or labeled data to.",
    "o", "");
PARAM_STRING("centroid_file", "If specified, the centroids of each cluster will"
    " be written to the given file.", "C", "");

// k-means configuration options.
PARAM_FLAG("allow_empty_clusters", "Allow empty clusters to be created.", "e");
PARAM_FLAG("labels_only", "Only output labels into output file.", "l");
PARAM_INT("max_iterations", "Maximum number of iterations before K-Means "
    "terminates.", "m", 1000);
PARAM_INT("seed", "Random seed.  If 0, 'std::time(NULL)' is used.", "s", 0);
PARAM_STRING("initial_centroids", "Start with the specified initial centroids.",
             "I", "");

// Parameters for "refined start" k-means.
PARAM_FLAG("refined_start", "Use the refined initial point strategy by Bradley "
    "and Fayyad to choose initial points.", "r");
PARAM_INT("samplings", "Number of samplings to perform for refined start (use "
    "when --refined_start is specified).", "S", 100);
PARAM_DOUBLE("percentage", "Percentage of dataset to use for each refined start"
    " sampling (use when --refined_start is specified).", "p", 0.02);

PARAM_STRING("algorithm", "Algorithm to use for the Lloyd iteration ('naive', "
    "'pelleg-moore', 'elkan', 'hamerly', or 'dtnn').", "a", "naive");

// Given the type of initial partition policy, figure out the empty cluster
// policy and run k-means.
template<typename InitialPartitionPolicy>
void FindEmptyClusterPolicy(const InitialPartitionPolicy& ipp);

// Given the initial partitionining policy and empty cluster policy, figure out
// the Lloyd iteration step type and run k-means.
template<typename InitialPartitionPolicy, typename EmptyClusterPolicy>
void FindLloydStepType(const InitialPartitionPolicy& ipp);

// Given the template parameters, sanitize/load input and run k-means.
template<typename InitialPartitionPolicy,
         typename EmptyClusterPolicy,
         template<class, class> class LloydStepType>
void RunKMeans(const InitialPartitionPolicy& ipp);

int main(int argc, char** argv)
{
  CLI::ParseCommandLine(argc, argv);

  // Initialize random seed.
  if (CLI::GetParam<int>("seed") != 0)
    math::RandomSeed((size_t) CLI::GetParam<int>("seed"));
  else
    math::RandomSeed((size_t) std::time(NULL));

  // Now, start building the KMeans type that we'll be using.  Start with the
  // initial partition policy.  The call to FindEmptyClusterPolicy<> results in
  // a call to RunKMeans<> and the algorithm is completed.
  if (CLI::HasParam("refined_start"))
  {
    const int samplings = CLI::GetParam<int>("samplings");
    const double percentage = CLI::GetParam<double>("percentage");

    if (samplings < 0)
      Log::Fatal << "Number of samplings (" << samplings << ") must be "
          << "greater than 0!" << endl;
    if (percentage <= 0.0 || percentage > 1.0)
      Log::Fatal << "Percentage for sampling (" << percentage << ") must be "
          << "greater than 0.0 and less than or equal to 1.0!" << endl;

    FindEmptyClusterPolicy<RefinedStart>(RefinedStart(samplings, percentage));
  }
  else
  {
    FindEmptyClusterPolicy<RandomPartition>(RandomPartition());
  }
}

// Given the type of initial partition policy, figure out the empty cluster
// policy and run k-means.
template<typename InitialPartitionPolicy>
void FindEmptyClusterPolicy(const InitialPartitionPolicy& ipp)
{
  if (CLI::HasParam("allow_empty_clusters"))
    FindLloydStepType<InitialPartitionPolicy, AllowEmptyClusters>(ipp);
  else
    FindLloydStepType<InitialPartitionPolicy, MaxVarianceNewCluster>(ipp);
}

// Given the initial partitionining policy and empty cluster policy, figure out
// the Lloyd iteration step type and run k-means.
template<typename InitialPartitionPolicy, typename EmptyClusterPolicy>
void FindLloydStepType(const InitialPartitionPolicy& ipp)
{
  const string algorithm = CLI::GetParam<string>("algorithm");
  if (algorithm == "elkan")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy, ElkanKMeans>(ipp);
  else if (algorithm == "hamerly")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy, HamerlyKMeans>(ipp);
  else if (algorithm == "pelleg-moore")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy,
        PellegMooreKMeans>(ipp);
  else if (algorithm == "dtnn")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy,
        DefaultDTNNKMeans>(ipp);
  else if (algorithm == "dtnn-covertree")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy,
        CoverTreeDTNNKMeans>(ipp);
  else if (algorithm == "dualtree")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy,
        DefaultDualTreeKMeans>(ipp);
  else if (algorithm == "naive")
    RunKMeans<InitialPartitionPolicy, EmptyClusterPolicy, NaiveKMeans>(ipp);
  else
    Log::Fatal << "Unknown algorithm: '" << algorithm << "'.  Supported options"
        << " are 'naive', 'pelleg-moore', 'elkan', and 'hamerly'." << endl;
}

// Given the template parameters, sanitize/load input and run k-means.
template<typename InitialPartitionPolicy,
         typename EmptyClusterPolicy,
         template<class, class> class LloydStepType>
void RunKMeans(const InitialPartitionPolicy& ipp)
{
  // Now, do validation of input options.
  const string inputFile = CLI::GetParam<string>("inputFile");
  const int clusters = CLI::GetParam<int>("clusters");
  if (clusters < 1)
  {
    Log::Fatal << "Invalid number of clusters requested (" << clusters << ")! "
        << "Must be greater than or equal to 1." << endl;
  }

  const int maxIterations = CLI::GetParam<int>("max_iterations");
  if (maxIterations < 0)
  {
    Log::Fatal << "Invalid value for maximum iterations (" << maxIterations <<
        ")! Must be greater than or equal to 0." << endl;
  }

  // Make sure we have an output file if we're not doing the work in-place.
  if (!CLI::HasParam("in_place") && !CLI::HasParam("output_file") &&
      !CLI::HasParam("centroid_file"))
  {
    Log::Warn << "--output_file, --in_place, and --centroid_file are not set; "
        << "no results will be saved." << std::endl;
  }

  // Load our dataset.
  arma::mat dataset;
  data::Load(inputFile, dataset, true); // Fatal upon failure.

  arma::mat centroids;

  const bool initialCentroidGuess = CLI::HasParam("initial_centroids");
  // Load initial centroids if the user asked for it.
  if (initialCentroidGuess)
  {
    string initialCentroidsFile = CLI::GetParam<string>("initial_centroids");
    data::Load(initialCentroidsFile, centroids, true);

    if (CLI::HasParam("refined_start"))
      Log::Warn << "Initial centroids are specified, but will be ignored "
          << "because --refined_start is also specified!" << endl;
    else
      Log::Info << "Using initial centroid guesses from '" <<
          initialCentroidsFile << "'." << endl;
  }

  KMeans<metric::EuclideanDistance,
         InitialPartitionPolicy,
         EmptyClusterPolicy,
         LloydStepType> kmeans(maxIterations, metric::EuclideanDistance(), ipp);

  if (CLI::HasParam("output_file") || CLI::HasParam("in_place"))
  {
    // We need to get the assignments.
    arma::Col<size_t> assignments;
    Timer::Start("clustering");
    kmeans.Cluster(dataset, clusters, assignments, centroids,
        false, initialCentroidGuess);
    Timer::Stop("clustering");

    // Now figure out what to do with our results.
    if (CLI::HasParam("in_place"))
    {
      // Add the column of assignments to the dataset; but we have to convert
      // them to type double first.
      arma::vec converted(assignments.n_elem);
      for (size_t i = 0; i < assignments.n_elem; i++)
        converted(i) = (double) assignments(i);

      dataset.insert_rows(dataset.n_rows, trans(converted));

      // Save the dataset.
      data::Save(inputFile, dataset);
    }
    else
    {
      if (CLI::HasParam("labels_only"))
      {
        // Save only the labels.
        string outputFile = CLI::GetParam<string>("output_file");
        arma::Mat<size_t> output = trans(assignments);
        data::Save(outputFile, output);
      }
      else
      {
        // Convert the assignments to doubles.
        arma::vec converted(assignments.n_elem);
        for (size_t i = 0; i < assignments.n_elem; i++)
          converted(i) = (double) assignments(i);

        dataset.insert_rows(dataset.n_rows, trans(converted));

        // Now save, in the different file.
        string outputFile = CLI::GetParam<string>("output_file");
        data::Save(outputFile, dataset);
      }
    }
  }
  else
  {
    // Just save the centroids.
    Timer::Start("clustering");
    kmeans.Cluster(dataset, clusters, centroids, initialCentroidGuess);
    Timer::Stop("clustering");
  }

  // Should we write the centroids to a file?
  if (CLI::HasParam("centroid_file"))
    data::Save(CLI::GetParam<std::string>("centroid_file"), centroids);
}
<|endoftext|>


<commit_before>// Filename: 	decipher.cpp
// Author: 		Christopher Goes
// Course: 		CS 572 Evolutionary Computation
// Semester: 	Fall 2016
// Description:	Assignment 2 - Genetic Algorithms - Breaking a simple Substitution Cipher
// Github:		https://github.com/GhostofGoes/cgoes-cs572
// License:		AGPLv3 until end of Fall 2016 semester. Then will convert to MITv2.
// if you're in the class, don't copy the code ( ͡° ͜ʖ ͡°)

#include <fstream>
#include "evolve.h"

double eTable[26][26];		// English contact table
double cTable[26][26];		// Cipher contact table

void initETable();
void initCTable( string ciphertext );
void initPopulation();
string initKey();
void printPopulation();
bool comp( keyFitType a, keyFitType b );

vector < keyFitType > population; // The population of possible keys

int main() {
	string ciphertext, temp, plaintext;
	int par1 = 0, par2 = 0;
	string key, child;

	initRand();  	// Initialize random number generator
	initETable();	// Initialize the English contact table
	while( cin >> temp ) { ciphertext += temp; } // Input the ciphertext
	if(TESTING) { cout << "ciphertext: " << ciphertext << endl; }
	initCTable(ciphertext);
	initPopulation();
	if(TESTING) { printPopulation(); }

	for( int i = 0; i < RUNS; i++ ) {
		// Selects three individuals, returns 2 best by reference (ugh), throws away the poor soul that couldn't stand the heat
		select(par1, par2);
		child = crossover( par1, par2 );
		mutate(child);
		addToPopulation(child);
	}

	key = bestIndividual();
	cout << "** goes " << key << endl;
	return 0;
} // end main

// Initializes the English contact table from a file
void initETable() {
	char a = 0, b = 0;
	double num = 0, sum = 0;
	ifstream inf("freq.txt");

	// Initialize the table
	for(int i = 0; i < 26; i++) {
		for(int j = 0; j < 26; j++) {
			eTable[i][j] = 0;
		}
	}

	// Input the english language frequencies
	while(inf) {
		inf >> a >> b >> num;
		sum += num;
		eTable[convert(a)][convert(b)] = num;
	}
	//printTable(eTable, "eTable: post-load");

	// Normalize the frequencies
	for(int i = 0; i < 26; i++) {
		for(int j = 0; j< 26; j++) {
			if(eTable[i][j] != 0)
				eTable[i][j] /= sum;
		}
	}
	//printTable(eTable, "eTable: post-normalize");
	inf.close();
 } // end initETables

// Initializes the Ciphertext contact table by counting occurances of pairs of letters in the ciphertext
void initCTable( string ciphertext ) {
	// Initialize the table
	for(int i = 0; i < 26; i++) {
		for(int j = 0; j < 26; j++) {
			cTable[i][j] = 0;
		}
	}

	// Count the number of times each pair of characters occurs in the ciphertext input
	// length - 1 = total number of pairs in the ciphertext
	for( unsigned int i = 0; i < ciphertext.length() - 1; i++ ) {
		cTable[convert(ciphertext[i])][convert(ciphertext[i + 1])] += 1;
	}
	//printTable(cTable, "cTable: post-load");
	// Normalize the frequencies
	for(int i = 0; i < 26; i++) {
		for(int j = 0; j< 26; j++) {
			if(cTable[i][j] != 0)
				cTable[i][j] /= (double)(ciphertext.length() - 1);
		}
	}
	//printTable(cTable, "cTable: post-normalize");
} // end initCTable

void initPopulation() {
	keyFitType member;
	for( int i = 0; i < POPSIZE; i++ ) {
		member.key = initKey();
		member.fit = 0;
		population.push_back(member);
	}
}

string initKey() {
	string key("abcdefghijklmnopqrstuvwxyz");
	for( int i = 0; i < 26; i++ ) {
		swap(key[i], key[randMod(26)]);
	}
	cout << key << endl;
	return key;
}

bool comp( keyFitType a, keyFitType b ) {
	return (a.fit < b.fit);
}

string bestIndividual() {
	sort(population.begin(), population.end(), comp);
	if(TESTING) { cout << "Best fitness:\t" << population[0].fit << endl; }
	return population[0].key;
}

// Converts an ASCII letter to an int to be used to index a table
int convert( char c ) {
	return (int)(c - 97);
}

// Reverts an int back to the ASCII letter it originally was
char revert( int i ) {
	return (char)(i + 97);
}

// Print 26 x 26 table
void printTable( double table[][26], string title = "Table" ) {
	cout << "\n** " << title << " **" << endl;
	for( int i = 0; i < 26; i++ ) {
		for( int j = 0; j < 26; j++ ) {
			cout << table[i][j] << " ";
		}
		cout << endl;
	}
}

void printPopulation() {
	cout << "\n** Current Population **" << endl;
	for( unsigned int i = 0; i < population.size(); i++ ) {
		cout << "Key:\t" << population[i].key << "\tFitness:\t" << population[i].fit << endl;
	}
}
<commit_msg>Fixed comparison for sort<commit_after>// Filename: 	decipher.cpp
// Author: 		Christopher Goes
// Course: 		CS 572 Evolutionary Computation
// Semester: 	Fall 2016
// Description:	Assignment 2 - Genetic Algorithms - Breaking a simple Substitution Cipher
// Github:		https://github.com/GhostofGoes/cgoes-cs572
// License:		AGPLv3 until end of Fall 2016 semester. Then will convert to MITv2.
// if you're in the class, don't copy the code ( ͡° ͜ʖ ͡°)

#include <fstream>
#include "evolve.h"

double eTable[26][26];		// English contact table
double cTable[26][26];		// Cipher contact table

void initETable();
void initCTable( string ciphertext );
void initPopulation();
string initKey();
void printPopulation();
bool comp( keyFitType a, keyFitType b );

vector < keyFitType > population; // The population of possible keys

int main() {
	string ciphertext, temp, plaintext;
	int par1 = 0, par2 = 0;
	string key, child;

	initRand();  	// Initialize random number generator
	initETable();	// Initialize the English contact table
	while( cin >> temp ) { ciphertext += temp; } // Input the ciphertext
	if(TESTING) { cout << "ciphertext: " << ciphertext << endl; }
	initCTable(ciphertext);
	initPopulation();
	if(TESTING) { printPopulation(); }

	for( int i = 0; i < RUNS; i++ ) {
		// Selects three individuals, returns 2 best by reference (ugh), throws away the poor soul that couldn't stand the heat
		select(par1, par2);
		child = crossover( par1, par2 );
		mutate(child);
		addToPopulation(child);
	}

	key = bestIndividual();
	cout << "** goes " << key << endl;
	return 0;
} // end main

// Initializes the English contact table from a file
void initETable() {
	char a = 0, b = 0;
	double num = 0, sum = 0;
	ifstream inf("freq.txt");

	// Initialize the table
	for(int i = 0; i < 26; i++) {
		for(int j = 0; j < 26; j++) {
			eTable[i][j] = 0;
		}
	}

	// Input the english language frequencies
	while(inf) {
		inf >> a >> b >> num;
		sum += num;
		eTable[convert(a)][convert(b)] = num;
	}
	//printTable(eTable, "eTable: post-load");

	// Normalize the frequencies
	for(int i = 0; i < 26; i++) {
		for(int j = 0; j< 26; j++) {
			if(eTable[i][j] != 0)
				eTable[i][j] /= sum;
		}
	}
	//printTable(eTable, "eTable: post-normalize");
	inf.close();
 } // end initETables

// Initializes the Ciphertext contact table by counting occurances of pairs of letters in the ciphertext
void initCTable( string ciphertext ) {
	// Initialize the table
	for(int i = 0; i < 26; i++) {
		for(int j = 0; j < 26; j++) {
			cTable[i][j] = 0;
		}
	}

	// Count the number of times each pair of characters occurs in the ciphertext input
	// length - 1 = total number of pairs in the ciphertext
	for( unsigned int i = 0; i < ciphertext.length() - 1; i++ ) {
		cTable[convert(ciphertext[i])][convert(ciphertext[i + 1])] += 1;
	}
	//printTable(cTable, "cTable: post-load");
	// Normalize the frequencies
	for(int i = 0; i < 26; i++) {
		for(int j = 0; j< 26; j++) {
			if(cTable[i][j] != 0)
				cTable[i][j] /= (double)(ciphertext.length() - 1);
		}
	}
	//printTable(cTable, "cTable: post-normalize");
} // end initCTable

void initPopulation() {
	keyFitType member;
	for( int i = 0; i < POPSIZE; i++ ) {
		member.key = initKey();
		member.fit = 0;
		population.push_back(member);
	}
}

string initKey() {
	string key("abcdefghijklmnopqrstuvwxyz");
	for( int i = 0; i < 26; i++ ) {
		swap(key[i], key[randMod(26)]);
	}
	cout << key << endl;
	return key;
}

bool comp( keyFitType a, keyFitType b ) {
	return (a.fit > b.fit);
}

string bestIndividual() {
	sort(population.begin(), population.end(), comp);
	if(TESTING) { cout << "Best fitness:\t" << population[0].fit << endl; }
	return population[0].key;
}

// Converts an ASCII letter to an int to be used to index a table
int convert( char c ) {
	return (int)(c - 97);
}

// Reverts an int back to the ASCII letter it originally was
char revert( int i ) {
	return (char)(i + 97);
}

// Print 26 x 26 table
void printTable( double table[][26], string title = "Table" ) {
	cout << "\n** " << title << " **" << endl;
	for( int i = 0; i < 26; i++ ) {
		for( int j = 0; j < 26; j++ ) {
			cout << table[i][j] << " ";
		}
		cout << endl;
	}
}

void printPopulation() {
	cout << "\n** Current Population **" << endl;
	for( unsigned int i = 0; i < population.size(); i++ ) {
		cout << "Key:\t" << population[i].key << "\tFitness:\t" << population[i].fit << endl;
	}
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkMutexLock.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkMutexLock.h"

// Construct a new vtkMutexLock
vtkMutexLock::vtkMutexLock()
{
#ifdef VTK_USE_SPROC
  init_lock( &this->MutexLock );
#endif

#ifdef _WIN32
  this->MutexLock = CreateMutex( NULL, FALSE, NULL );
#endif

#ifdef VTK_USE_PTHREADS
  pthread_mutex_init(&(this->MutexLock), NULL);
#endif

}

// Destruct the vtkMutexVariable
vtkMutexLock::~vtkMutexLock()
{
#ifdef _WIN32
  CloseHandle(this->MutexLock);
#endif

#ifdef VTK_USE_PTHREADS
  pthread_mutex_destroy( &this->MutexLock);
#endif
}

// Lock the vtkMutexLock
void vtkMutexLock::Lock()
{
#ifdef VTK_USE_SPROC
  spin_lock( &this->MutexLock );
#endif

#ifdef _WIN32
  WaitForSingleObject( this->MutexLock, INFINITE );
#endif

#ifdef VTK_USE_PTHREADS
  pthread_mutex_lock( &this->MutexLock);
#endif
}

// Unlock the vtkMutexLock
void vtkMutexLock::Unlock()
{
#ifdef VTK_USE_SPROC
  release_lock( &this->MutexLock );
#endif

#ifdef _WIN32
  ReleaseMutex( this->MutexLock );
#endif

#ifdef VTK_USE_PTHREADS
  pthread_mutex_unlock( &this->MutexLock);
#endif
}

// Print method for vtkMutexLock
void vtkMutexLock::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkObject::PrintSelf(os,indent);
}
<commit_msg>FIXED: pthread_mutex_init() call for hpux<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkMutexLock.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkMutexLock.h"

// Construct a new vtkMutexLock
vtkMutexLock::vtkMutexLock()
{
#ifdef VTK_USE_SPROC
  init_lock( &this->MutexLock );
#endif

#ifdef _WIN32
  this->MutexLock = CreateMutex( NULL, FALSE, NULL );
#endif

#ifdef VTK_USE_PTHREADS
#ifdef VTK_HP_PTHREADS
  pthread_mutex_init(&(this->MutexLock), pthread_mutexattr_default);
#else
  pthread_mutex_init(&(this->MutexLock), NULL);
#endif
#endif

}

// Destruct the vtkMutexVariable
vtkMutexLock::~vtkMutexLock()
{
#ifdef _WIN32
  CloseHandle(this->MutexLock);
#endif

#ifdef VTK_USE_PTHREADS
  pthread_mutex_destroy( &this->MutexLock);
#endif
}

// Lock the vtkMutexLock
void vtkMutexLock::Lock()
{
#ifdef VTK_USE_SPROC
  spin_lock( &this->MutexLock );
#endif

#ifdef _WIN32
  WaitForSingleObject( this->MutexLock, INFINITE );
#endif

#ifdef VTK_USE_PTHREADS
  pthread_mutex_lock( &this->MutexLock);
#endif
}

// Unlock the vtkMutexLock
void vtkMutexLock::Unlock()
{
#ifdef VTK_USE_SPROC
  release_lock( &this->MutexLock );
#endif

#ifdef _WIN32
  ReleaseMutex( this->MutexLock );
#endif

#ifdef VTK_USE_PTHREADS
  pthread_mutex_unlock( &this->MutexLock);
#endif
}

// Print method for vtkMutexLock
void vtkMutexLock::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkObject::PrintSelf(os,indent);
}
<|endoftext|>