<commit_before>#define MS_CLASS "RTC::SeqManager"
// #define MS_LOG_DEV

#include "RTC/SeqManager.hpp"
#include "Logger.hpp"

namespace RTC
{
	template<typename T>
	bool SeqManager<T>::SeqLowerThan::operator()(const T& lhs, const T& rhs) const
	{
		return ((rhs > lhs) && (rhs - lhs <= MaxValue / 2)) ||
		       ((lhs > rhs) && (lhs - rhs > MaxValue / 2));
	}

	template<typename T>
	bool SeqManager<T>::SeqHigherThan::operator()(const T& lhs, const T& rhs) const
	{
		return ((lhs > rhs) && (lhs - rhs <= MaxValue / 2)) ||
		       ((rhs > lhs) && (rhs - lhs > MaxValue / 2));
	}

	template<typename T>
	const typename SeqManager<T>::SeqLowerThan SeqManager<T>::isSeqLowerThan;

	template<typename T>
	const typename SeqManager<T>::SeqHigherThan SeqManager<T>::isSeqHigherThan;

	template<typename T>
	bool SeqManager<T>::IsSeqLowerThan(const T& lhs, const T& rhs)
	{
		return isSeqLowerThan(lhs, rhs);
	}

	template<typename T>
	bool SeqManager<T>::IsSeqHigherThan(const T& lhs, const T& rhs)
	{
		return isSeqHigherThan(lhs, rhs);
	}

	template<typename T>
	SeqManager<T>::SeqManager()
	{
	}

	template<typename T>
	void SeqManager<T>::Sync(T input)
	{
		// Update base.
		this->base = this->maxOutput - input + 1;

		// Update maxInput.
		this->maxInput = input;

		// Clear dropped set.
		this->dropped.clear();
	}

	template<typename T>
	void SeqManager<T>::Drop(T input)
	{
		// Mark as dropped if 'input' is higher than anyone already processed.
		if (SeqManager<T>::IsSeqHigherThan(input, this->maxInput))
			this->dropped.insert(input);
	}

	template<typename T>
	bool SeqManager<T>::Input(const T input, T& output)
	{
		auto base = this->base;

		// There are dropped inputs. Synchronize.
		if (!this->dropped.empty())
		{
			// Delete dropped inputs older than input - MaxValue/2.
			auto it = this->dropped.lower_bound(input - MaxValue / 2);
			this->dropped.erase(this->dropped.begin(), it);

			// Check whether this input was dropped.
			it = this->dropped.find(input);

			if (it != this->dropped.end())
			{
				MS_WARN_TAG(rtp, "trying to send a dropped input");

				return false;
			}

			// Count dropped entries before 'input' in order to adapt the base.
			size_t dropped = std::count_if(
			  this->dropped.begin(), this->dropped.end(), [&input](T i) { return i < input; });

			base -= dropped;
		}

		output = input + base;

		T idelta = input - this->maxInput;
		T odelta = output - this->maxOutput;

		// New input is higher than the maximum seen. But less than acceptable units higher.
		// Keep it as the maximum seen. See Drop().
		if (idelta < MaxValue / 2)
		{
			this->maxInput = input;
		}
		else if (idelta != 0)
		{
			MS_WARN_TAG(rtp, "trying to send a too new input");

			return false;
		}

		// New output is higher than the maximum seen. But less than acceptable units higher.
		// Keep it as the maximum seen. See Sync().
		if (odelta < MaxValue / 2)
			this->maxOutput = output;

		return true;
	}

	// Explicit instantiation to have all SeqManager definitions in this file.
	template class SeqManager<uint8_t>;
	template class SeqManager<uint16_t>;
	template class SeqManager<uint32_t>;

} // namespace RTC
<commit_msg>SeqManager: whether a seq is correct or not is not its business<commit_after>#define MS_CLASS "RTC::SeqManager"
// #define MS_LOG_DEV

#include "RTC/SeqManager.hpp"
#include "Logger.hpp"

namespace RTC
{
	template<typename T>
	bool SeqManager<T>::SeqLowerThan::operator()(const T& lhs, const T& rhs) const
	{
		return ((rhs > lhs) && (rhs - lhs <= MaxValue / 2)) ||
		       ((lhs > rhs) && (lhs - rhs > MaxValue / 2));
	}

	template<typename T>
	bool SeqManager<T>::SeqHigherThan::operator()(const T& lhs, const T& rhs) const
	{
		return ((lhs > rhs) && (lhs - rhs <= MaxValue / 2)) ||
		       ((rhs > lhs) && (rhs - lhs > MaxValue / 2));
	}

	template<typename T>
	const typename SeqManager<T>::SeqLowerThan SeqManager<T>::isSeqLowerThan;

	template<typename T>
	const typename SeqManager<T>::SeqHigherThan SeqManager<T>::isSeqHigherThan;

	template<typename T>
	bool SeqManager<T>::IsSeqLowerThan(const T& lhs, const T& rhs)
	{
		return isSeqLowerThan(lhs, rhs);
	}

	template<typename T>
	bool SeqManager<T>::IsSeqHigherThan(const T& lhs, const T& rhs)
	{
		return isSeqHigherThan(lhs, rhs);
	}

	template<typename T>
	SeqManager<T>::SeqManager()
	{
	}

	template<typename T>
	void SeqManager<T>::Sync(T input)
	{
		// Update base.
		this->base = this->maxOutput - input + 1;

		// Update maxInput.
		this->maxInput = input;

		// Clear dropped set.
		this->dropped.clear();
	}

	template<typename T>
	void SeqManager<T>::Drop(T input)
	{
		// Mark as dropped if 'input' is higher than anyone already processed.
		if (SeqManager<T>::IsSeqHigherThan(input, this->maxInput))
			this->dropped.insert(input);
	}

	template<typename T>
	bool SeqManager<T>::Input(const T input, T& output)
	{
		auto base = this->base;

		// There are dropped inputs. Synchronize.
		if (!this->dropped.empty())
		{
			// Delete dropped inputs older than input - MaxValue/2.
			auto it = this->dropped.lower_bound(input - MaxValue / 2);
			this->dropped.erase(this->dropped.begin(), it);

			// Check whether this input was dropped.
			it = this->dropped.find(input);

			if (it != this->dropped.end())
			{
				MS_WARN_TAG(rtp, "trying to send a dropped input");

				return false;
			}

			// Count dropped entries before 'input' in order to adapt the base.
			size_t dropped = std::count_if(
			  this->dropped.begin(), this->dropped.end(), [&input](T i) { return i < input; });

			base -= dropped;
		}

		output = input + base;

		T idelta = input - this->maxInput;
		T odelta = output - this->maxOutput;

		// New input is higher than the maximum seen. But less than acceptable units higher.
		// Keep it as the maximum seen. See Drop().
		if (idelta < MaxValue / 2)
		{
			this->maxInput = input;
		}

		// New output is higher than the maximum seen. But less than acceptable units higher.
		// Keep it as the maximum seen. See Sync().
		if (odelta < MaxValue / 2)
			this->maxOutput = output;

		return true;
	}

	// Explicit instantiation to have all SeqManager definitions in this file.
	template class SeqManager<uint8_t>;
	template class SeqManager<uint16_t>;
	template class SeqManager<uint32_t>;

} // namespace RTC
<|endoftext|>


<commit_before>/******************************************************************************\
* File:          lexers.cpp
* Purpose:       Implementation of wxExLexers classes
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 2008-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/config.h>
#include <wx/stdpaths.h>
#include <wx/tokenzr.h>
#include <wx/stc/stc.h>
#include <wx/textfile.h>
#include <wx/extension/lexers.h>
#include <wx/extension/frd.h>
#include <wx/extension/util.h> // for wxExMatchesOneOf

wxExLexers* wxExLexers::m_Self = NULL;

wxExLexers::wxExLexers(const wxFileName& filename)
  : m_FileName(filename)
{
}

const wxString wxExLexers::ApplyMacro(const wxString& text) const
{
  if (text.IsNumber() || text.Contains(","))
  {
    return text;
  }

  std::map<wxString, wxString>::const_iterator it = m_Macros.find(text);

  if (it != m_Macros.end())
  {
    return it->second;
  }
  else
  {
    wxLogError("Undefined macro: %s", text.c_str());
    return text;
  }
}

const wxString wxExLexers::BuildWildCards(const wxFileName& filename) const
{
  const wxString allfiles_wildcard =
    _("All Files") + wxString::Format(" (%s)|%s",
      wxFileSelectorDefaultWildcardStr,
      wxFileSelectorDefaultWildcardStr);

  wxString wildcards = allfiles_wildcard;

  // Build the wildcard string using all available lexers.
  for (
    std::vector<wxExLexer>::const_iterator it = m_Lexers.begin();
    it != m_Lexers.end();
    ++it)
  {
    if (!it->GetAssociations().empty())
    {
      const wxString wildcard =
        it->GetScintillaLexer() +
        " (" + it->GetAssociations() + ") |" +
        it->GetAssociations();

      if (wxExMatchesOneOf(filename, it->GetAssociations()))
      {
        wildcards = wildcard + "|" + wildcards;
      }
      else
      {
        wildcards = wildcards + "|" + wildcard;
      }
    }
  }

  return wildcards;
}

const wxExLexer wxExLexers::FindByFileName(const wxFileName& filename) const
{
  if (!filename.IsOk())
  {
    return wxExLexer();
  }

  for (
    std::vector<wxExLexer>::const_iterator it = m_Lexers.begin();
    it != m_Lexers.end();
    ++it)
  {
    if (wxExMatchesOneOf(filename, it->GetAssociations()))
    {
      return *it;
    }
  }

  return wxExLexer();
}

const wxExLexer wxExLexers::FindByName(
  const wxString& name,
  bool fail_if_not_found) const
{
  for (
    std::vector<wxExLexer>::const_iterator it = m_Lexers.begin();
    it != m_Lexers.end();
    ++it)
  {
    if (name == it->GetScintillaLexer())
    {
      return *it;
    }
  }

  if (!m_Lexers.empty() && fail_if_not_found)
  {
    wxFAIL;
  }

  return wxExLexer();
}

const wxExLexer wxExLexers::FindByText(const wxString& text) const
{
  // Add automatic lexers if text starts with some special tokens.
  const wxString text_lowercase = text.Lower();

  if (text_lowercase.StartsWith("#") ||
      // .po files that do not have comment headers, start with msgid, so set them
      text_lowercase.StartsWith("msgid"))
  {
    return FindByName("bash", false); // don't show error
  }
  else if (text_lowercase.StartsWith("<html>") ||
           text_lowercase.StartsWith("<?php"))
  {
    return FindByName("hypertext", false); // don't show error
  }
  else if (text_lowercase.StartsWith("<?xml"))
  {
    return FindByName("xml", false); // don't show error
  }
  // cpp files like #include <map> really do not have a .h extension (e.g. /usr/include/c++/3.3.5/map)
  // so add here.
  else if (text_lowercase.StartsWith("//"))
  {
    return FindByName("cpp", false); // don't show error
  }

  return wxExLexer();
}

wxExLexers* wxExLexers::Get(bool createOnDemand)
{
  if (m_Self == NULL && createOnDemand)
  {
    m_Self = new wxExLexers(wxFileName(
#ifdef wxExUSE_PORTABLE
      wxPathOnly(wxStandardPaths::Get().GetExecutablePath())
#else
      wxStandardPaths::Get().GetUserDataDir()
#endif
      + wxFileName::GetPathSeparator() + "lexers.xml")
    );

    m_Self->Read();
  }

  return m_Self;
}

const wxString wxExLexers::GetLexerAssociations() const
{
  wxString text;

  for (
    std::vector<wxExLexer>::const_iterator it = m_Lexers.begin();
    it != m_Lexers.end();
    ++it)
  {
    if (!it->GetAssociations().empty())
    {
      if (!text.empty())
      {
        text += wxExFindReplaceData::Get()->GetFieldSeparator();
      }

      text += it->GetAssociations();
    }
  }

  return text;
}

const wxString wxExLexers::ParseTagColourings(const wxXmlNode* node) const
{
  wxString text;

  wxXmlNode* child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "colouring")
    {
      wxString content = child->GetNodeContent().Strip(wxString::both);

      std::map<wxString, wxString>::const_iterator it = m_Macros.find(content);

      if (it != m_Macros.end())
      {
        content = it->second;
      }

      text +=
        ApplyMacro(
          child->GetAttribute("no", "0"))
        + "=" + content + wxTextFile::GetEOL();
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined colourings tag: %s on: %d",
        child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return text;
}

void wxExLexers::ParseTagGlobal(const wxXmlNode* node)
{
  wxXmlNode* child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else if (child->GetName() == "hex")
    {
      m_StylesHex.push_back(
        ApplyMacro(child->GetAttribute("no", "0")) + "=" +
        child->GetNodeContent().Strip(wxString::both));
    }
    else if (child->GetName() == "indicator")
    {
      m_Indicators.insert(std::make_pair(
        atoi(ApplyMacro(child->GetAttribute("no", "0")).c_str()),
        atoi(child->GetNodeContent().Strip(wxString::both).c_str())));
    }
    else if (child->GetName() == "marker")
    {
      const wxExMarker marker(ParseTagMarker(
        ApplyMacro(child->GetAttribute("no", "0")),
        child->GetNodeContent().Strip(wxString::both)));

      if (marker.GetMarkerNumber() < wxSTC_STYLE_MAX &&
          marker.GetMarkerSymbol() < wxSTC_STYLE_MAX)
      {
        m_Markers.push_back(marker);
      }
      else
      {
        wxLogError("Illegal marker number: %d or symbol: %d on: %d",
          marker.GetMarkerNumber(),
          marker.GetMarkerSymbol(),
          child->GetLineNumber());
      }
    }
    else if (child->GetName() == "style")
    {
      const wxString attrib = ApplyMacro(child->GetAttribute("no", "0"));
      const wxString content = child->GetNodeContent().Strip(wxString::both);
      int attrib_no = atoi(attrib.c_str());

      if (attrib_no == wxSTC_STYLE_DEFAULT)
      {
        m_DefaultStyle = attrib + "=" + content;
      }
      else
      {
        m_Styles.push_back(attrib + "=" + content);
      }
    }
    else if (child->GetName() == "def")
    {
      const wxString attrib = child->GetAttribute("no", "0");
      const wxString content = child->GetNodeContent().Strip(wxString::both);
      m_Macros[attrib] = content;
    }
    else
    {
      wxLogError("Undefined global tag: %s on: %d",
        child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }
}

const wxExLexer wxExLexers::ParseTagLexer(const wxXmlNode* node) const
{
  wxExLexer lexer;
  lexer.m_ScintillaLexer = node->GetAttribute("name", "");
  lexer.m_Associations = node->GetAttribute("extensions", "");

  wxXmlNode *child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "colourings")
    {
      lexer.m_Colourings = ParseTagColourings(child);
    }
    else if (child->GetName() == "keywords")
    {
      if (!lexer.SetKeywords(child->GetNodeContent().Strip(wxString::both)))
      {
        wxLogError("Keywords could not be set on: %d", child->GetLineNumber());
      }
    }
    else if (child->GetName() == "properties")
    {
      lexer.m_Properties = ParseTagProperties(child);
    }
    else if (child->GetName() == "comments")
    {
      lexer.m_CommentBegin = child->GetAttribute("begin1", "");
      lexer.m_CommentEnd = child->GetAttribute("end1", "");
      lexer.m_CommentBegin2 = child->GetAttribute("begin2", "");
      lexer.m_CommentEnd2 = child->GetAttribute("end2", "");
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined lexer tag: %s on: %d",
        child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return lexer;
}

const wxExMarker wxExLexers::ParseTagMarker(
  const wxString& number,
  const wxString& props) const
{
  wxStringTokenizer prop_fields(props, ",");

  const wxString symbol = ApplyMacro(prop_fields.GetNextToken());

  wxColour foreground;
  wxColour background;

  if (prop_fields.HasMoreTokens())
  {
    foreground = ApplyMacro(
      prop_fields.GetNextToken().Strip(wxString::both));

    if (prop_fields.HasMoreTokens())
    {
      background = ApplyMacro(
        prop_fields.GetNextToken().Strip(wxString::both));
    }
  }

  const int no = atoi(number.c_str());
  const int symbol_no = atoi(symbol.c_str());

  if (no <= wxSTC_MARKER_MAX && symbol_no <= wxSTC_MARKER_MAX)
  {
    return wxExMarker(no, symbol_no, foreground, background);
  }
  else
  {
    wxLogError("Illegal marker number: %d or symbol: %d", no, symbol_no);
    return wxExMarker(0, 0, foreground, background);
  }
}

const wxString wxExLexers::ParseTagProperties(const wxXmlNode* node) const
{
  wxString text;

  wxXmlNode *child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "property")
    {
      text +=
        child->GetAttribute("name", "0") + "=" +
        child->GetNodeContent().Strip(wxString::both) + wxTextFile::GetEOL();
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined properties tag: %s on %d",
        child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return text;
}

void wxExLexers::Read()
{
  // This test is to prevent showing an error if the lexers file does not exist,
  // as this is not required.
  if (!m_FileName.FileExists())
  {
    return;
  }

  wxXmlDocument doc;

  if (!doc.Load(m_FileName.GetFullPath()))
  {
    return;
  }

  // Initialize members.
  m_Indicators.clear();
  m_Lexers.clear();
  m_Markers.clear();
  m_SortedLexerNames.clear();
  m_Styles.clear();
  m_StylesHex.clear();

  wxXmlNode* child = doc.GetRoot()->GetChildren();

  while (child)
  {
    if (child->GetName() == "global")
    {
      ParseTagGlobal(child);
    }
    else if (child->GetName() == "lexer")
    {
      const wxExLexer& lexer = ParseTagLexer(child);

      if (!lexer.GetScintillaLexer().empty())
      {
        if (lexer.GetScintillaLexer() == "hypertext")
        {
          // As our lexers.xml files cannot use xml comments,
          // add them here.
          wxExLexer l(lexer);
          l.m_CommentBegin = "<!--";
          l.m_CommentEnd = "-->";
          m_Lexers.push_back(l);
        }
        else
        {
          m_Lexers.push_back(lexer);
          m_SortedLexerNames.Add(lexer.GetScintillaLexer());
        }
      }
    }

    child = child->GetNext();
  }

  // Add the <none> lexer.
  m_SortedLexerNames.Add(_("<none>"));

  if (!wxConfigBase::Get()->Exists(_("In files")))
  {
    wxConfigBase::Get()->Write(_("In files"), GetLexerAssociations());
  }

  if (!wxConfigBase::Get()->Exists(_("Add what")))
  {
    wxConfigBase::Get()->Write(_("Add what"), GetLexerAssociations());
  }
}

wxExLexers* wxExLexers::Set(wxExLexers* lexers)
{
  wxExLexers* old = m_Self;
  m_Self = lexers;
  return old;
}

bool wxExLexers::ShowDialog(
  wxWindow* parent,
  wxExLexer& lexer,
  const wxString& caption) const
{
  const int choice = (lexer.GetScintillaLexer().empty()) ?
    m_SortedLexerNames.Index(_("<none>")):
    m_SortedLexerNames.Index(lexer.GetScintillaLexer());

  wxSingleChoiceDialog dlg(
    parent,
    _("Input") + ":",
    caption,
    m_SortedLexerNames);

  if (choice != wxNOT_FOUND)
  {
    dlg.SetSelection(choice);
  }

  if (dlg.ShowModal() == wxID_CANCEL)
  {
    return false;
  }

  if (dlg.GetSelection() == m_SortedLexerNames.Index(_("<none>")))
  {
    lexer = wxExLexer();
  }
  else
  {
    lexer = FindByName(dlg.GetStringSelection());
  }

  return true;
}
<commit_msg>simplified code<commit_after>/******************************************************************************\
* File:          lexers.cpp
* Purpose:       Implementation of wxExLexers classes
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 2008-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/config.h>
#include <wx/stdpaths.h>
#include <wx/tokenzr.h>
#include <wx/stc/stc.h>
#include <wx/textfile.h>
#include <wx/extension/lexers.h>
#include <wx/extension/frd.h>
#include <wx/extension/util.h> // for wxExMatchesOneOf

wxExLexers* wxExLexers::m_Self = NULL;

wxExLexers::wxExLexers(const wxFileName& filename)
  : m_FileName(filename)
{
}

const wxString wxExLexers::ApplyMacro(const wxString& text) const
{
  if (text.IsNumber() || text.Contains(","))
  {
    return text;
  }

  std::map<wxString, wxString>::const_iterator it = m_Macros.find(text);

  if (it != m_Macros.end())
  {
    return it->second;
  }
  else
  {
    wxLogError("Undefined macro: %s", text.c_str());
    return text;
  }
}

const wxString wxExLexers::BuildWildCards(const wxFileName& filename) const
{
  const wxString allfiles_wildcard =
    _("All Files") + wxString::Format(" (%s)|%s",
      wxFileSelectorDefaultWildcardStr,
      wxFileSelectorDefaultWildcardStr);

  wxString wildcards = allfiles_wildcard;

  // Build the wildcard string using all available lexers.
  for (
    std::vector<wxExLexer>::const_iterator it = m_Lexers.begin();
    it != m_Lexers.end();
    ++it)
  {
    if (!it->GetAssociations().empty())
    {
      const wxString wildcard =
        it->GetScintillaLexer() +
        " (" + it->GetAssociations() + ") |" +
        it->GetAssociations();

      if (wxExMatchesOneOf(filename, it->GetAssociations()))
      {
        wildcards = wildcard + "|" + wildcards;
      }
      else
      {
        wildcards = wildcards + "|" + wildcard;
      }
    }
  }

  return wildcards;
}

const wxExLexer wxExLexers::FindByFileName(const wxFileName& filename) const
{
  if (!filename.IsOk())
  {
    return wxExLexer();
  }

  for (
    std::vector<wxExLexer>::const_iterator it = m_Lexers.begin();
    it != m_Lexers.end();
    ++it)
  {
    if (wxExMatchesOneOf(filename, it->GetAssociations()))
    {
      return *it;
    }
  }

  return wxExLexer();
}

const wxExLexer wxExLexers::FindByName(
  const wxString& name,
  bool fail_if_not_found) const
{
  for (
    std::vector<wxExLexer>::const_iterator it = m_Lexers.begin();
    it != m_Lexers.end();
    ++it)
  {
    if (name == it->GetScintillaLexer())
    {
      return *it;
    }
  }

  if (!m_Lexers.empty() && fail_if_not_found)
  {
    wxFAIL;
  }

  return wxExLexer();
}

const wxExLexer wxExLexers::FindByText(const wxString& text) const
{
  // Add automatic lexers if text starts with some special tokens.
  const wxString text_lowercase = text.Lower();

  if (text_lowercase.StartsWith("#") ||
      // .po files that do not have comment headers, start with msgid, so set them
      text_lowercase.StartsWith("msgid"))
  {
    return FindByName("bash", false); // don't show error
  }
  else if (text_lowercase.StartsWith("<html>") ||
           text_lowercase.StartsWith("<?php"))
  {
    return FindByName("hypertext", false); // don't show error
  }
  else if (text_lowercase.StartsWith("<?xml"))
  {
    return FindByName("xml", false); // don't show error
  }
  // cpp files like #include <map> really do not have a .h extension (e.g. /usr/include/c++/3.3.5/map)
  // so add here.
  else if (text_lowercase.StartsWith("//"))
  {
    return FindByName("cpp", false); // don't show error
  }

  return wxExLexer();
}

wxExLexers* wxExLexers::Get(bool createOnDemand)
{
  if (m_Self == NULL && createOnDemand)
  {
    m_Self = new wxExLexers(wxFileName(
#ifdef wxExUSE_PORTABLE
      wxPathOnly(wxStandardPaths::Get().GetExecutablePath())
#else
      wxStandardPaths::Get().GetUserDataDir()
#endif
      + wxFileName::GetPathSeparator() + "lexers.xml")
    );

    m_Self->Read();
  }

  return m_Self;
}

const wxString wxExLexers::GetLexerAssociations() const
{
  wxString text;

  for (
    std::vector<wxExLexer>::const_iterator it = m_Lexers.begin();
    it != m_Lexers.end();
    ++it)
  {
    if (!it->GetAssociations().empty())
    {
      if (!text.empty())
      {
        text += wxExFindReplaceData::Get()->GetFieldSeparator();
      }

      text += it->GetAssociations();
    }
  }

  return text;
}

const wxString wxExLexers::ParseTagColourings(const wxXmlNode* node) const
{
  wxString text;

  wxXmlNode* child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "colouring")
    {
      wxString content = child->GetNodeContent().Strip(wxString::both);

      std::map<wxString, wxString>::const_iterator it = m_Macros.find(content);

      if (it != m_Macros.end())
      {
        content = it->second;
      }

      text +=
        ApplyMacro(
          child->GetAttribute("no", "0"))
        + "=" + content + wxTextFile::GetEOL();
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined colourings tag: %s on: %d",
        child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return text;
}

void wxExLexers::ParseTagGlobal(const wxXmlNode* node)
{
  wxXmlNode* child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else if (child->GetName() == "hex")
    {
      m_StylesHex.push_back(
        ApplyMacro(child->GetAttribute("no", "0")) + "=" +
        child->GetNodeContent().Strip(wxString::both));
    }
    else if (child->GetName() == "indicator")
    {
      m_Indicators.insert(std::make_pair(
        atoi(ApplyMacro(child->GetAttribute("no", "0")).c_str()),
        atoi(child->GetNodeContent().Strip(wxString::both).c_str())));
    }
    else if (child->GetName() == "marker")
    {
      const wxExMarker marker(ParseTagMarker(
        ApplyMacro(child->GetAttribute("no", "0")),
        child->GetNodeContent().Strip(wxString::both)));

      if (marker.GetMarkerNumber() < wxSTC_STYLE_MAX &&
          marker.GetMarkerSymbol() < wxSTC_STYLE_MAX)
      {
        m_Markers.push_back(marker);
      }
      else
      {
        wxLogError("Illegal marker number: %d or symbol: %d on: %d",
          marker.GetMarkerNumber(),
          marker.GetMarkerSymbol(),
          child->GetLineNumber());
      }
    }
    else if (child->GetName() == "style")
    {
      const wxString attrib = ApplyMacro(child->GetAttribute("no", "0"));
      const wxString content = child->GetNodeContent().Strip(wxString::both);
      int attrib_no = atoi(attrib.c_str());

      if (attrib_no == wxSTC_STYLE_DEFAULT)
      {
        m_DefaultStyle = attrib + "=" + content;
      }
      else
      {
        m_Styles.push_back(attrib + "=" + content);
      }
    }
    else if (child->GetName() == "def")
    {
      const wxString attrib = child->GetAttribute("no", "0");
      const wxString content = child->GetNodeContent().Strip(wxString::both);
      m_Macros[attrib] = content;
    }
    else
    {
      wxLogError("Undefined global tag: %s on: %d",
        child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }
}

const wxExLexer wxExLexers::ParseTagLexer(const wxXmlNode* node) const
{
  wxExLexer lexer;
  lexer.m_ScintillaLexer = node->GetAttribute("name", "");
  lexer.m_Associations = node->GetAttribute("extensions", "");

  wxXmlNode *child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "colourings")
    {
      lexer.m_Colourings = ParseTagColourings(child);
    }
    else if (child->GetName() == "keywords")
    {
      if (!lexer.SetKeywords(child->GetNodeContent().Strip(wxString::both)))
      {
        wxLogError("Keywords could not be set on: %d", child->GetLineNumber());
      }
    }
    else if (child->GetName() == "properties")
    {
      lexer.m_Properties = ParseTagProperties(child);
    }
    else if (child->GetName() == "comments")
    {
      lexer.m_CommentBegin = child->GetAttribute("begin1", "");
      lexer.m_CommentEnd = child->GetAttribute("end1", "");
      lexer.m_CommentBegin2 = child->GetAttribute("begin2", "");
      lexer.m_CommentEnd2 = child->GetAttribute("end2", "");
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined lexer tag: %s on: %d",
        child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return lexer;
}

const wxExMarker wxExLexers::ParseTagMarker(
  const wxString& number,
  const wxString& props) const
{
  wxStringTokenizer prop_fields(props, ",");

  const wxString symbol = ApplyMacro(prop_fields.GetNextToken());

  wxColour foreground;
  wxColour background;

  if (prop_fields.HasMoreTokens())
  {
    foreground = ApplyMacro(
      prop_fields.GetNextToken().Strip(wxString::both));

    if (prop_fields.HasMoreTokens())
    {
      background = ApplyMacro(
        prop_fields.GetNextToken().Strip(wxString::both));
    }
  }

  const int no = atoi(number.c_str());
  const int symbol_no = atoi(symbol.c_str());

  if (no <= wxSTC_MARKER_MAX && symbol_no <= wxSTC_MARKER_MAX)
  {
    return wxExMarker(no, symbol_no, foreground, background);
  }
  else
  {
    wxLogError("Illegal marker number: %d or symbol: %d", no, symbol_no);
    return wxExMarker(0, 0, foreground, background);
  }
}

const wxString wxExLexers::ParseTagProperties(const wxXmlNode* node) const
{
  wxString text;

  wxXmlNode *child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "property")
    {
      text +=
        child->GetAttribute("name", "0") + "=" +
        child->GetNodeContent().Strip(wxString::both) + wxTextFile::GetEOL();
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined properties tag: %s on %d",
        child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return text;
}

void wxExLexers::Read()
{
  // This test is to prevent showing an error if the lexers file does not exist,
  // as this is not required.
  if (!m_FileName.FileExists())
  {
    return;
  }

  wxXmlDocument doc;

  if (!doc.Load(m_FileName.GetFullPath()))
  {
    return;
  }

  // Initialize members.
  m_Indicators.clear();
  m_Lexers.clear();
  m_Markers.clear();
  m_SortedLexerNames.clear();
  m_Styles.clear();
  m_StylesHex.clear();

  wxXmlNode* child = doc.GetRoot()->GetChildren();

  while (child)
  {
    if (child->GetName() == "global")
    {
      ParseTagGlobal(child);
    }
    else if (child->GetName() == "lexer")
    {
      const wxExLexer& lexer = ParseTagLexer(child);

      if (!lexer.GetScintillaLexer().empty())
      {
        if (lexer.GetScintillaLexer() == "hypertext")
        {
          // As our lexers.xml files cannot use xml comments,
          // add them here.
          wxExLexer l(lexer);
          l.m_CommentBegin = "<!--";
          l.m_CommentEnd = "-->";
          m_Lexers.push_back(l);
        }
        else
        {
          m_Lexers.push_back(lexer);
          m_SortedLexerNames.Add(lexer.GetScintillaLexer());
        }
      }
    }

    child = child->GetNext();
  }

  // Add the <none> lexer.
  m_SortedLexerNames.Add(_("<none>"));

  if (!wxConfigBase::Get()->Exists(_("In files")))
  {
    wxConfigBase::Get()->Write(_("In files"), GetLexerAssociations());
  }

  if (!wxConfigBase::Get()->Exists(_("Add what")))
  {
    wxConfigBase::Get()->Write(_("Add what"), GetLexerAssociations());
  }
}

wxExLexers* wxExLexers::Set(wxExLexers* lexers)
{
  wxExLexers* old = m_Self;
  m_Self = lexers;
  return old;
}

bool wxExLexers::ShowDialog(
  wxWindow* parent,
  wxExLexer& lexer,
  const wxString& caption) const
{
  const int choice = (lexer.GetScintillaLexer().empty()) ?
    m_SortedLexerNames.Index(_("<none>")):
    m_SortedLexerNames.Index(lexer.GetScintillaLexer());

  wxSingleChoiceDialog dlg(
    parent,
    _("Input") + ":",
    caption,
    m_SortedLexerNames);

  dlg.SetSelection(choice);

  if (dlg.ShowModal() == wxID_CANCEL)
  {
    return false;
  }

  lexer = (dlg.GetSelection() == m_SortedLexerNames.Index(_("<none>")) ?
    wxExLexer():
    FindByName(dlg.GetStringSelection()));

  return true;
}
<|endoftext|>


<commit_before>#include "eigen_helpers.hh"

#include "viewer/colors/viridis.hh"
#include "viewer/primitives/simple_geometry.hh"

#include <GL/glew.h>

namespace viewer {

void SimpleGeometry::add_axes(const Axes &axes) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.axes.push_back(axes);
}

void SimpleGeometry::add_line(const Line &line) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.lines.push_back(line);
}

void SimpleGeometry::add_polygon(const Polygon &polygon) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.polygons.push_back(polygon);
}

void SimpleGeometry::add_points(const Points &points) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.points.push_back(points);
}

void SimpleGeometry::add_point(const Point &point) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.raw_points.push_back(point);
}

void SimpleGeometry::add_points2d(const Points2d &points) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.points2d.push_back(points);
}

void SimpleGeometry::add_sphere(const Sphere &sphere) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.spheres.push_back(sphere);
}

void SimpleGeometry::add_ellipsoid(const Ellipsoid &ellipsoid) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.ellipsoids.push_back(ellipsoid);
}

void SimpleGeometry::add_plane(const Plane &plane) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.planes.push_back(plane);
}

void SimpleGeometry::add_triangle_mesh(const TriMesh &mesh) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.tri_meshes.push_back(mesh);
}

void SimpleGeometry::clear() {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  front_buffer_.clear();
}

void SimpleGeometry::flip() {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  front_buffer_ = std::move(back_buffer_);
  mesh_displaylists_.clear();
}

void SimpleGeometry::flush() {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  const auto insert = [](auto &into, const auto &from) {
    into.insert(into.begin(), from.begin(), from.end());
  };

  insert(front_buffer_.axes, back_buffer_.axes);
  insert(front_buffer_.lines, back_buffer_.lines);
  insert(front_buffer_.points, back_buffer_.points);
  insert(front_buffer_.raw_points, back_buffer_.raw_points);
  insert(front_buffer_.points2d, back_buffer_.points2d);
  insert(front_buffer_.spheres, back_buffer_.spheres);
  insert(front_buffer_.ellipsoids, back_buffer_.ellipsoids);
  insert(front_buffer_.planes, back_buffer_.planes);
  insert(front_buffer_.polygons, back_buffer_.polygons);
  insert(front_buffer_.colored_points, back_buffer_.colored_points);
  insert(front_buffer_.tri_meshes, back_buffer_.tri_meshes);

  back_buffer_.clear();

  // TODO: Why do we have to invalidate the whole cache?
  mesh_displaylists_.clear();
}

void SimpleGeometry::add_ray(const geometry::Ray &ray,
                             const double length,
                             const Eigen::Vector4d &color) {
  add_ray({ray.origin, ray.direction, length, color});
}

void SimpleGeometry::add_ray(const Ray &ray) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  const Eigen::Vector3d first_endpoint = ray.origin + (ray.direction * 0.9 * ray.length);
  back_buffer_.lines.push_back({ray.origin, first_endpoint, ray.color, ray.width});
  const Eigen::Vector4d new_color(ray.color.y(), ray.color.x(), ray.color.z(),
                                  ray.color.w());
  back_buffer_.lines.push_back({first_endpoint,
                                first_endpoint + (ray.direction * 0.1 * ray.length),
                                new_color, 1.1 * ray.width});
}

void SimpleGeometry::add_colored_points(const Points &points,
                                        const std::vector<double> &intensities) {
  ColoredPoints colored_points;
  colored_points.colors.reserve(intensities.size());
  assert(points.points.size() == intensities.size());

  colored_points.points = points.points;
  colored_points.size = points.size;

  double max = 0.01;
  for (std::size_t k = 0; k < intensities.size(); ++k) {
    max = std::max(intensities[k], max);
  }

  const double inv_max = 1.0 / max;
  for (std::size_t k = 0; k < intensities.size(); ++k) {
    const Vec4 color = jcc::augment(colors::viridis(intensities[k] * inv_max), 0.8);
    colored_points.colors.push_back(color);
  }

  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.colored_points.push_back(colored_points);
}

void SimpleGeometry::add_box(const AxisAlignedBox &box) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  using Vec3 = Eigen::Vector3d;

  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.lower.y(), box.upper.z()),
                                Vec3(box.lower.x(), box.upper.y(), box.upper.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.lower.y(), box.upper.z()),
                                Vec3(box.lower.x(), box.lower.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.lower.y(), box.upper.z()),
                                Vec3(box.upper.x(), box.lower.y(), box.upper.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.upper.y(), box.upper.z()),
                                Vec3(box.upper.x(), box.upper.y(), box.upper.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.upper.y(), box.upper.z()),
                                Vec3(box.lower.x(), box.upper.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.upper.y(), box.upper.z()),
                                Vec3(box.upper.x(), box.upper.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.upper.y(), box.upper.z()),
                                Vec3(box.upper.x(), box.lower.y(), box.upper.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.upper.y(), box.lower.z()),
                                Vec3(box.upper.x(), box.lower.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.upper.y(), box.lower.z()),
                                Vec3(box.lower.x(), box.upper.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.lower.y(), box.lower.z()),
                                Vec3(box.lower.x(), box.lower.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.lower.y(), box.lower.z()),
                                Vec3(box.upper.x(), box.lower.y(), box.upper.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.lower.y(), box.lower.z()),
                                Vec3(box.lower.x(), box.upper.y(), box.lower.z()),
                                box.color});
}

void SimpleGeometry::draw() const {
  const std::lock_guard<std::mutex> lk(draw_mutex_);

  for (const auto &axes : front_buffer_.axes) {
    draw_axes(axes);
  }

  for (const auto &points : front_buffer_.points) {
    draw_points(points);
  }

  for (const auto &point : front_buffer_.raw_points) {
    draw_point(point);
  }

  for (const auto &points2d : front_buffer_.points2d) {
    draw_points2d(points2d);
  }

  for (const auto &circle : front_buffer_.spheres) {
    draw_sphere(circle);
  }

  for (const auto &ellipse : front_buffer_.ellipsoids) {
    draw_ellipsoid(ellipse);
  }

  for (const auto &polygon : front_buffer_.polygons) {
    draw_polygon(polygon);
  }

  for (const auto &colored_points : front_buffer_.colored_points) {
    draw_colored_points(colored_points);
  }

  for (const auto &plane : front_buffer_.planes) {
    draw_plane_grid(plane);
  }

  constexpr bool USE_CACHE = true;
  for (std::size_t i = 0; i < front_buffer_.tri_meshes.size(); ++i) {
    if (USE_CACHE) {
      if (mesh_displaylists_.count(i) == 0) {
        const auto &tri_mesh = front_buffer_.tri_meshes[i];
        const GLuint index = glGenLists(1);
        assert(index > 0);
        mesh_displaylists_[i] = index;
        glNewList(index, GL_COMPILE);
        draw_trimesh(tri_mesh);
        glEndList();
      }
      glCallList(mesh_displaylists_.at(i));
    } else {
      const auto &tri_mesh = front_buffer_.tri_meshes[i];
      draw_trimesh(tri_mesh);
    }
  }

  draw_lines(front_buffer_.lines);
}
}  // namespace viewer
<commit_msg>Set alpha based on intensity in normalized points<commit_after>#include "eigen_helpers.hh"

#include "viewer/colors/viridis.hh"
#include "viewer/primitives/simple_geometry.hh"

#include <GL/glew.h>

namespace viewer {

void SimpleGeometry::add_axes(const Axes &axes) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.axes.push_back(axes);
}

void SimpleGeometry::add_line(const Line &line) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.lines.push_back(line);
}

void SimpleGeometry::add_polygon(const Polygon &polygon) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.polygons.push_back(polygon);
}

void SimpleGeometry::add_points(const Points &points) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.points.push_back(points);
}

void SimpleGeometry::add_point(const Point &point) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.raw_points.push_back(point);
}

void SimpleGeometry::add_points2d(const Points2d &points) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.points2d.push_back(points);
}

void SimpleGeometry::add_sphere(const Sphere &sphere) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.spheres.push_back(sphere);
}

void SimpleGeometry::add_ellipsoid(const Ellipsoid &ellipsoid) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.ellipsoids.push_back(ellipsoid);
}

void SimpleGeometry::add_plane(const Plane &plane) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.planes.push_back(plane);
}

void SimpleGeometry::add_triangle_mesh(const TriMesh &mesh) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.tri_meshes.push_back(mesh);
}

void SimpleGeometry::clear() {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  front_buffer_.clear();
}

void SimpleGeometry::flip() {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  front_buffer_ = std::move(back_buffer_);
  mesh_displaylists_.clear();
}

void SimpleGeometry::flush() {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  const auto insert = [](auto &into, const auto &from) {
    into.insert(into.begin(), from.begin(), from.end());
  };

  insert(front_buffer_.axes, back_buffer_.axes);
  insert(front_buffer_.lines, back_buffer_.lines);
  insert(front_buffer_.points, back_buffer_.points);
  insert(front_buffer_.raw_points, back_buffer_.raw_points);
  insert(front_buffer_.points2d, back_buffer_.points2d);
  insert(front_buffer_.spheres, back_buffer_.spheres);
  insert(front_buffer_.ellipsoids, back_buffer_.ellipsoids);
  insert(front_buffer_.planes, back_buffer_.planes);
  insert(front_buffer_.polygons, back_buffer_.polygons);
  insert(front_buffer_.colored_points, back_buffer_.colored_points);
  insert(front_buffer_.tri_meshes, back_buffer_.tri_meshes);

  back_buffer_.clear();

  // TODO: Why do we have to invalidate the whole cache?
  mesh_displaylists_.clear();
}

void SimpleGeometry::add_ray(const geometry::Ray &ray,
                             const double length,
                             const Eigen::Vector4d &color) {
  add_ray({ray.origin, ray.direction, length, color});
}

void SimpleGeometry::add_ray(const Ray &ray) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  const Eigen::Vector3d first_endpoint = ray.origin + (ray.direction * 0.9 * ray.length);
  back_buffer_.lines.push_back({ray.origin, first_endpoint, ray.color, ray.width});
  const Eigen::Vector4d new_color(ray.color.y(), ray.color.x(), ray.color.z(),
                                  ray.color.w());
  back_buffer_.lines.push_back({first_endpoint,
                                first_endpoint + (ray.direction * 0.1 * ray.length),
                                new_color, 1.1 * ray.width});
}

void SimpleGeometry::add_colored_points(const Points &points,
                                        const std::vector<double> &intensities) {
  ColoredPoints colored_points;
  colored_points.colors.reserve(intensities.size());
  assert(points.points.size() == intensities.size());

  colored_points.points = points.points;
  colored_points.size = points.size;

  double max = 0.01;
  for (std::size_t k = 0; k < intensities.size(); ++k) {
    max = std::max(intensities[k], max);
  }

  const double inv_max = 1.0 / max;
  for (std::size_t k = 0; k < intensities.size(); ++k) {
    const Vec4 color =
        jcc::augment(colors::viridis(intensities[k] * inv_max), intensities[k] * inv_max);
    colored_points.colors.push_back(color);
  }

  const std::lock_guard<std::mutex> lk(draw_mutex_);
  back_buffer_.colored_points.push_back(colored_points);
}

void SimpleGeometry::add_box(const AxisAlignedBox &box) {
  const std::lock_guard<std::mutex> lk(draw_mutex_);
  using Vec3 = Eigen::Vector3d;

  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.lower.y(), box.upper.z()),
                                Vec3(box.lower.x(), box.upper.y(), box.upper.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.lower.y(), box.upper.z()),
                                Vec3(box.lower.x(), box.lower.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.lower.y(), box.upper.z()),
                                Vec3(box.upper.x(), box.lower.y(), box.upper.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.upper.y(), box.upper.z()),
                                Vec3(box.upper.x(), box.upper.y(), box.upper.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.upper.y(), box.upper.z()),
                                Vec3(box.lower.x(), box.upper.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.upper.y(), box.upper.z()),
                                Vec3(box.upper.x(), box.upper.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.upper.y(), box.upper.z()),
                                Vec3(box.upper.x(), box.lower.y(), box.upper.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.upper.y(), box.lower.z()),
                                Vec3(box.upper.x(), box.lower.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.upper.y(), box.lower.z()),
                                Vec3(box.lower.x(), box.upper.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.lower.y(), box.lower.z()),
                                Vec3(box.lower.x(), box.lower.y(), box.lower.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.upper.x(), box.lower.y(), box.lower.z()),
                                Vec3(box.upper.x(), box.lower.y(), box.upper.z()),
                                box.color});
  back_buffer_.lines.push_back({Vec3(box.lower.x(), box.lower.y(), box.lower.z()),
                                Vec3(box.lower.x(), box.upper.y(), box.lower.z()),
                                box.color});
}

void SimpleGeometry::draw() const {
  const std::lock_guard<std::mutex> lk(draw_mutex_);

  for (const auto &axes : front_buffer_.axes) {
    draw_axes(axes);
  }

  for (const auto &points : front_buffer_.points) {
    draw_points(points);
  }

  for (const auto &point : front_buffer_.raw_points) {
    draw_point(point);
  }

  for (const auto &points2d : front_buffer_.points2d) {
    draw_points2d(points2d);
  }

  for (const auto &circle : front_buffer_.spheres) {
    draw_sphere(circle);
  }

  for (const auto &ellipse : front_buffer_.ellipsoids) {
    draw_ellipsoid(ellipse);
  }

  for (const auto &polygon : front_buffer_.polygons) {
    draw_polygon(polygon);
  }

  for (const auto &colored_points : front_buffer_.colored_points) {
    draw_colored_points(colored_points);
  }

  for (const auto &plane : front_buffer_.planes) {
    draw_plane_grid(plane);
  }

  constexpr bool USE_CACHE = true;
  for (std::size_t i = 0; i < front_buffer_.tri_meshes.size(); ++i) {
    if (USE_CACHE) {
      if (mesh_displaylists_.count(i) == 0) {
        const auto &tri_mesh = front_buffer_.tri_meshes[i];
        const GLuint index = glGenLists(1);
        assert(index > 0);
        mesh_displaylists_[i] = index;
        glNewList(index, GL_COMPILE);
        draw_trimesh(tri_mesh);
        glEndList();
      }
      glCallList(mesh_displaylists_.at(i));
    } else {
      const auto &tri_mesh = front_buffer_.tri_meshes[i];
      draw_trimesh(tri_mesh);
    }
  }

  draw_lines(front_buffer_.lines);
}
}  // namespace viewer
<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's 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.
//
//   * The name of Intel Corporation may not 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 Intel Corporation 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.
//
//M*/

#include "precomp.hpp"

namespace cv { namespace ml {

ParamGrid::ParamGrid() { minVal = maxVal = 0.; logStep = 1; }
ParamGrid::ParamGrid(double _minVal, double _maxVal, double _logStep)
{
    minVal = std::min(_minVal, _maxVal);
    maxVal = std::max(_minVal, _maxVal);
    logStep = std::max(_logStep, 1.);
}

bool StatModel::empty() const { return !isTrained(); }

int StatModel::getVarCount() const { return 0; }

bool StatModel::train( const Ptr<TrainData>&, int )
{
    CV_Error(CV_StsNotImplemented, "");
    return false;
}

bool StatModel::train( InputArray samples, int layout, InputArray responses )
{
    return train(TrainData::create(samples, layout, responses));
}

float StatModel::calcError( const Ptr<TrainData>& data, bool testerr, OutputArray _resp ) const
{
    Mat samples = data->getSamples();
    int layout = data->getLayout();
    Mat sidx = testerr ? data->getTestSampleIdx() : data->getTrainSampleIdx();
    const int* sidx_ptr = sidx.ptr<int>();
    int i, n = (int)sidx.total();
    bool isclassifier = isClassifier();
    Mat responses = data->getResponses();

    if( n == 0 )
        n = data->getNSamples();

    if( n == 0 )
        return -FLT_MAX;

    Mat resp;
    if( _resp.needed() )
        resp.create(n, 1, CV_32F);

    double err = 0;
    for( i = 0; i < n; i++ )
    {
        int si = sidx_ptr ? sidx_ptr[i] : i;
        Mat sample = layout == ROW_SAMPLE ? samples.row(si) : samples.col(si);
        float val = predict(sample);
        float val0 = responses.at<float>(si);

        if( isclassifier )
            err += fabs(val - val0) > FLT_EPSILON;
        else
            err += (val - val0)*(val - val0);
        if( !resp.empty() )
            resp.at<float>(i) = val;
        /*if( i < 100 )
        {
            printf("%d. ref %.1f vs pred %.1f\n", i, val0, val);
        }*/
    }

    if( _resp.needed() )
        resp.copyTo(_resp);

    return (float)(err / n * (isclassifier ? 100 : 1));
}

/* Calculates upper triangular matrix S, where A is a symmetrical matrix A=S'*S */
static void Cholesky( const Mat& A, Mat& S )
{
    CV_Assert(A.type() == CV_32F);

    int dim = A.rows;
    S.create(dim, dim, CV_32F);

    int i, j, k;

    for( i = 0; i < dim; i++ )
    {
        for( j = 0; j < i; j++ )
            S.at<float>(i,j) = 0.f;

        float sum = 0.f;
        for( k = 0; k < i; k++ )
        {
            float val = S.at<float>(k,i);
            sum += val*val;
        }

        S.at<float>(i,i) = std::sqrt(std::max(A.at<float>(i,i) - sum, 0.f));
        float ival = 1.f/S.at<float>(i, i);

        for( j = i + 1; j < dim; j++ )
        {
            sum = 0;
            for( k = 0; k < i; k++ )
                sum += S.at<float>(k, i) * S.at<float>(k, j);

            S.at<float>(i, j) = (A.at<float>(i, j) - sum)*ival;
        }
    }
}

/* Generates <sample> from multivariate normal distribution, where <mean> - is an
   average row vector, <cov> - symmetric covariation matrix */
void randMVNormal( InputArray _mean, InputArray _cov, int nsamples, OutputArray _samples )
{
    Mat mean = _mean.getMat(), cov = _cov.getMat();
    int dim = (int)mean.total();

    _samples.create(nsamples, dim, CV_32F);
    Mat samples = _samples.getMat();
    randu(samples, 0., 1.);

    Mat utmat;
    Cholesky(cov, utmat);
    int flags = mean.cols == 1 ? 0 : GEMM_3_T;

    for( int i = 0; i < nsamples; i++ )
    {
        Mat sample = samples.row(i);
        gemm(sample, utmat, 1, mean, 1, sample, flags);
    }
}

}}

/* End of file */
<commit_msg>fix randMVNormal in ML (#5469)<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's 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.
//
//   * The name of Intel Corporation may not 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 Intel Corporation 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.
//
//M*/

#include "precomp.hpp"

namespace cv { namespace ml {

ParamGrid::ParamGrid() { minVal = maxVal = 0.; logStep = 1; }
ParamGrid::ParamGrid(double _minVal, double _maxVal, double _logStep)
{
    minVal = std::min(_minVal, _maxVal);
    maxVal = std::max(_minVal, _maxVal);
    logStep = std::max(_logStep, 1.);
}

bool StatModel::empty() const { return !isTrained(); }

int StatModel::getVarCount() const { return 0; }

bool StatModel::train( const Ptr<TrainData>&, int )
{
    CV_Error(CV_StsNotImplemented, "");
    return false;
}

bool StatModel::train( InputArray samples, int layout, InputArray responses )
{
    return train(TrainData::create(samples, layout, responses));
}

float StatModel::calcError( const Ptr<TrainData>& data, bool testerr, OutputArray _resp ) const
{
    Mat samples = data->getSamples();
    int layout = data->getLayout();
    Mat sidx = testerr ? data->getTestSampleIdx() : data->getTrainSampleIdx();
    const int* sidx_ptr = sidx.ptr<int>();
    int i, n = (int)sidx.total();
    bool isclassifier = isClassifier();
    Mat responses = data->getResponses();

    if( n == 0 )
        n = data->getNSamples();

    if( n == 0 )
        return -FLT_MAX;

    Mat resp;
    if( _resp.needed() )
        resp.create(n, 1, CV_32F);

    double err = 0;
    for( i = 0; i < n; i++ )
    {
        int si = sidx_ptr ? sidx_ptr[i] : i;
        Mat sample = layout == ROW_SAMPLE ? samples.row(si) : samples.col(si);
        float val = predict(sample);
        float val0 = responses.at<float>(si);

        if( isclassifier )
            err += fabs(val - val0) > FLT_EPSILON;
        else
            err += (val - val0)*(val - val0);
        if( !resp.empty() )
            resp.at<float>(i) = val;
        /*if( i < 100 )
        {
            printf("%d. ref %.1f vs pred %.1f\n", i, val0, val);
        }*/
    }

    if( _resp.needed() )
        resp.copyTo(_resp);

    return (float)(err / n * (isclassifier ? 100 : 1));
}

/* Calculates upper triangular matrix S, where A is a symmetrical matrix A=S'*S */
static void Cholesky( const Mat& A, Mat& S )
{
    CV_Assert(A.type() == CV_32F);

    int dim = A.rows;
    S.create(dim, dim, CV_32F);

    int i, j, k;

    for( i = 0; i < dim; i++ )
    {
        for( j = 0; j < i; j++ )
            S.at<float>(i,j) = 0.f;

        float sum = 0.f;
        for( k = 0; k < i; k++ )
        {
            float val = S.at<float>(k,i);
            sum += val*val;
        }

        S.at<float>(i,i) = std::sqrt(std::max(A.at<float>(i,i) - sum, 0.f));
        float ival = 1.f/S.at<float>(i, i);

        for( j = i + 1; j < dim; j++ )
        {
            sum = 0;
            for( k = 0; k < i; k++ )
                sum += S.at<float>(k, i) * S.at<float>(k, j);

            S.at<float>(i, j) = (A.at<float>(i, j) - sum)*ival;
        }
    }
}

/* Generates <sample> from multivariate normal distribution, where <mean> - is an
   average row vector, <cov> - symmetric covariation matrix */
void randMVNormal( InputArray _mean, InputArray _cov, int nsamples, OutputArray _samples )
{
    // check mean vector and covariance matrix
    Mat mean = _mean.getMat(), cov = _cov.getMat();
    int dim = (int)mean.total();  // dimensionality
    CV_Assert(mean.rows == 1 || mean.cols == 1);
    CV_Assert(cov.rows == dim && cov.cols == dim);
    mean = mean.reshape(1,1);     // ensure a row vector

    // generate n-samples of the same dimension, from ~N(0,1)
    _samples.create(nsamples, dim, CV_32F);
    Mat samples = _samples.getMat();
    randn(samples, Scalar::all(0), Scalar::all(1));

    // decompose covariance using Cholesky: cov = U'*U
    // (cov must be square, symmetric, and positive semi-definite matrix)
    Mat utmat;
    Cholesky(cov, utmat);

    // transform random numbers using specified mean and covariance
    for( int i = 0; i < nsamples; i++ )
    {
        Mat sample = samples.row(i);
        sample = sample * utmat + mean;
    }
}

}}

/* End of file */
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
/////////////////////////////////////////////////////////////////////////////

#ifndef EASTLTEST_ALLOCATOR_H
#define EASTLTEST_ALLOCATOR_H

#include <EABase/eabase.h>
#include <EASTL/internal/config.h>
#include <new>

#if !EASTL_OPENSOURCE

	#include <PPMalloc/EAGeneralAllocator.h>
	#include <PPMalloc/EAGeneralAllocatorDebug.h>

	#if defined(EA_COMPILER_MSVC)
		#include <math.h>       // VS2008 has an acknowledged bug that requires math.h (and possibly also string.h) to be #included before intrin.h.
		#include <intrin.h>
		#pragma intrinsic(_ReturnAddress)
	#endif

	///////////////////////////////////////////////////////////////////////////////
	// gGeneralAllocator
	//
	namespace EA
	{
		namespace Allocator
		{
			#ifdef EA_DEBUG
							   GeneralAllocatorDebug  gGeneralAllocator EA_INIT_PRIORITY(1000);
				extern PPM_API GeneralAllocatorDebug* gpEAGeneralAllocatorDebug;
			#else
							   GeneralAllocator       gGeneralAllocator EA_INIT_PRIORITY(1000);
				extern PPM_API GeneralAllocator*      gpEAGeneralAllocator;
			#endif
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// gEASTLTest_AllocationCount
	//
	int gEASTLTest_AllocationCount = 0;

	///////////////////////////////////////////////////////////////////////////////
	// EASTLTest_ValidateHeap
	//
	bool EASTLTest_ValidateHeap()
	{
	#ifdef EA_DEBUG
		return EA::Allocator::gpEAGeneralAllocatorDebug->ValidateHeap(EA::Allocator::GeneralAllocator::kHeapValidationLevelBasic);
	#else
		return true;
	#endif
	}

	///////////////////////////////////////////////////////////////////////////////
	// Microsoft function parameter annotations
	// https://msdn.microsoft.com/en-CA/library/hh916382.aspx
	//
	#ifndef _Ret_maybenull_
	#define _Ret_maybenull_
	#endif

	#ifndef _Post_writable_byte_size_
	#define _Post_writable_byte_size_(x)
	#endif

	#ifndef _Ret_notnull_
	#define _Ret_notnull_
	#endif

	///////////////////////////////////////////////////////////////////////////////
	// operator new extensions
	//
	namespace
	{
		#ifdef EA_DEBUG
			const char gUnattributedNewTag[] = "Anonymous new";
		#endif

		#if defined(EA_COMPILER_MSVC)
			#define UNATTRIBUTED_NEW_FILE   "raw_return_address"
			#define UNATTRIBUTED_NEW_LINE   ((int)(uintptr_t)_ReturnAddress())
		#else
			#define UNATTRIBUTED_NEW_FILE   NULL
			#define UNATTRIBUTED_NEW_LINE   0
		#endif
	}

	_Ret_maybenull_ _Post_writable_byte_size_(size) void* operator new(size_t size, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
	{
		#ifdef EA_DEBUG
			void* const p = EA::Allocator::gGeneralAllocator.MallocDebug(size, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE);
		#else
			void* const p = EA::Allocator::gGeneralAllocator.Malloc(size);
		#endif
		return p;
	}

	void operator delete(void* p, const std::nothrow_t&) EA_THROW_SPEC_DELETE_NONE()
	{
		if(p) // The standard specifies that 'delete NULL' is a valid operation.
		{
			gEASTLTest_AllocationCount--;
			EA::Allocator::gGeneralAllocator.Free(p);
		}
	}

	_Ret_maybenull_ _Post_writable_byte_size_(size) void* operator new[](size_t size, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
	{
		gEASTLTest_AllocationCount++;

		#ifdef EA_DEBUG
			void* const p = EA::Allocator::gGeneralAllocator.MallocDebug(size, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE);
		#else
			void* const p = EA::Allocator::gGeneralAllocator.Malloc(size);
		#endif
		return p;
	}

	void operator delete[](void* p, const std::nothrow_t&) EA_THROW_SPEC_DELETE_NONE()
	{
		if(p)
		{
			gEASTLTest_AllocationCount--;
			EA::Allocator::gGeneralAllocator.Free(p);
		}
	}

	_Ret_notnull_ _Post_writable_byte_size_(size) void* operator new(size_t size) EA_THROW_SPEC_NEW(std::bad_alloc)
	{
		gEASTLTest_AllocationCount++;

		// This IsConstructed functionality is needed by some mobile platforms due to some weaknesses in their application startup.
		#if (PPMALLOC_VERSION_N >= 11602)
			const bool bConstructed = EA::Allocator::gGeneralAllocator.IsConstructed();
		#else
			const bool bConstructed = (EA::Allocator::gGeneralAllocator.GetTraceFunction(NULL) != NULL);
		#endif

		void *mem;

		if(bConstructed)
		{
			#ifdef EA_DEBUG
				mem = EA::Allocator::gGeneralAllocator.MallocDebug(size, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE);
			#else
				mem = EA::Allocator::gGeneralAllocator.Malloc(size);
			#endif
		}
		else
		{
			mem = malloc(size);
		}

	#if !defined(EA_COMPILER_NO_EXCEPTIONS)
		if (mem == NULL)
		{
			throw std::bad_alloc();
		}
	#endif

		return mem;
	}

	_Ret_notnull_ _Post_writable_byte_size_(size) void* operator new[](size_t size) EA_THROW_SPEC_NEW(std::bad_alloc)
	{
		gEASTLTest_AllocationCount++;

		// This IsConstructed functionality is needed by some mobile platforms due to some weaknesses in their application startup.
		#if (PPMALLOC_VERSION_N >= 11602)
			const bool bConstructed = EA::Allocator::gGeneralAllocator.IsConstructed();
		#else
			const bool bConstructed = (EA::Allocator::gGeneralAllocator.GetTraceFunction(NULL) != NULL);
		#endif

		void *mem;

		if(bConstructed)
		{
			#ifdef EA_DEBUG
				mem = EA::Allocator::gGeneralAllocator.MallocDebug(size, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE);
			#else
				mem = EA::Allocator::gGeneralAllocator.Malloc(size);
			#endif
		}
		else
		{
			mem = malloc(size);
		}

	#if !defined(EA_COMPILER_NO_EXCEPTIONS)
		if (mem == NULL)
		{
			throw std::bad_alloc();
		}
	#endif

		return mem;
	}

	#ifdef EA_DEBUG
	void* operator new[](size_t size, const char* name, int flags, unsigned debugFlags, const char* file, int line)
	#else
	void* operator new[](size_t size, const char* /*name*/, int flags, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/)
	#endif
	{
		gEASTLTest_AllocationCount++;

		#ifdef EA_DEBUG
			return EA::Allocator::gGeneralAllocator.MallocDebug(size, flags, debugFlags, name, file, line);
		#else
			return EA::Allocator::gGeneralAllocator.Malloc(size, flags);
		#endif
	}

	#ifdef EA_DEBUG
	void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* name, int flags, unsigned debugFlags, const char* file, int line)
	#else
	void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* /*name*/, int flags, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/)
	#endif
	{
		gEASTLTest_AllocationCount++;

		#ifdef EA_DEBUG
			return EA::Allocator::gGeneralAllocator.MallocAlignedDebug(size, alignment, alignmentOffset, flags, debugFlags, name, file, line);
		#else
			return EA::Allocator::gGeneralAllocator.MallocAligned(size, alignment, alignmentOffset, flags);
		#endif
	}

	// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
	void* operator new(size_t size, size_t alignment)
	{
		gEASTLTest_AllocationCount++;
		return EA::Allocator::gGeneralAllocator.MallocAligned(size, alignment);
	}

	// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
	void* operator new(size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
	{
		gEASTLTest_AllocationCount++;
		return EA::Allocator::gGeneralAllocator.MallocAligned(size, alignment);
	}

	// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
	void* operator new[](size_t size, size_t alignment)
	{
		gEASTLTest_AllocationCount++;
		return EA::Allocator::gGeneralAllocator.MallocAligned(size, alignment);
	}

	// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
	void* operator new[](size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
	{
		gEASTLTest_AllocationCount++;
		return EA::Allocator::gGeneralAllocator.MallocAligned(size, alignment);
	}

	void operator delete(void* p) EA_THROW_SPEC_DELETE_NONE()
	{
		if(p) // The standard specifies that 'delete NULL' is a valid operation.
		{
			gEASTLTest_AllocationCount--;

			// This IsConstructed functionality is needed by some mobile platforms due to some weaknesses in their application startup.
			#if (PPMALLOC_VERSION_N >= 11602)
				const bool bConstructed = EA::Allocator::gGeneralAllocator.IsConstructed();
			#else
				const bool bConstructed = (EA::Allocator::gGeneralAllocator.GetTraceFunction(NULL) != NULL); // Old hacky way to test this.
			#endif

			if(bConstructed)
			{
				if(EA::Allocator::gGeneralAllocator.ValidateAddress(p, EA::Allocator::GeneralAllocatorDebug::kAddressTypeOwned))
					EA::Allocator::gGeneralAllocator.Free(p);
				else
					free(p);
			}
			else
				free(p);
		}
	}

	void operator delete[](void* p) EA_THROW_SPEC_DELETE_NONE()
	{
		if(p)
		{
			gEASTLTest_AllocationCount--;

			// This IsConstructed functionality is needed by some mobile platforms due to some weaknesses in their application startup.
			#if (PPMALLOC_VERSION_N >= 11602)
				const bool bConstructed = EA::Allocator::gGeneralAllocator.IsConstructed();
			#else
				const bool bConstructed = (EA::Allocator::gGeneralAllocator.GetTraceFunction(NULL) != NULL); // Old hacky way to test this.
			#endif

			if(bConstructed)
			{
				if(EA::Allocator::gGeneralAllocator.ValidateAddress(p, EA::Allocator::GeneralAllocatorDebug::kAddressTypeOwned))
					EA::Allocator::gGeneralAllocator.Free(p);
				else
					free(p);
			}
			else
			   free(p);
		}
	}

    void EASTLTest_SetGeneralAllocator()
	{
		EA::Allocator::SetGeneralAllocator(&EA::Allocator::gGeneralAllocator);
		#ifdef EA_DEBUG
			EA::Allocator::gpEAGeneralAllocatorDebug->SetDefaultDebugDataFlag(EA::Allocator::GeneralAllocatorDebug::kDebugDataIdGuard);
		#endif
	}

#else
	#ifndef EA_PLATFORM_MICROSOFT
		#include <stdlib.h>
	#endif

	namespace Internal
	{
		void* EASTLAlignedAlloc(size_t size, size_t alignment)
		{
		#ifdef EA_PLATFORM_MICROSOFT
			return _aligned_malloc(size, alignment);
		#else
			return aligned_alloc(alignment, size);
		#endif
		}

		void EASTLAlignedFree(void* p)
		{
		#ifdef EA_PLATFORM_MICROSOFT
			_aligned_free(p);
		#else
			free(p);
		#endif
		}
	}

	void* operator new(size_t const size)
		{ return Internal::EASTLAlignedAlloc(size, 16); }

	void* operator new[](size_t size, const char* /*name*/, int /*flags*/, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/)
		{ return Internal::EASTLAlignedAlloc(size, 16); }

	void* operator new[](size_t size, size_t alignment, size_t /*alignmentOffset*/, const char* /*name*/, int /*flags*/, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/)
		{ return Internal::EASTLAlignedAlloc(size, alignment); }

	void* operator new(size_t size, size_t alignment)
		{ return Internal::EASTLAlignedAlloc(size, alignment); }

	void* operator new(size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
		{ return Internal::EASTLAlignedAlloc(size, alignment); }

	void* operator new[](size_t size, size_t alignment)
		{ return Internal::EASTLAlignedAlloc(size, alignment); }

	void* operator new[](size_t size, size_t alignment, const std::nothrow_t&)EA_THROW_SPEC_NEW_NONE()
		{ return Internal::EASTLAlignedAlloc(size, alignment); }

	void operator delete(void* p) EA_THROW_SPEC_DELETE_NONE()
		{ Internal::EASTLAlignedFree(p); }

	void operator delete[](void* p) EA_THROW_SPEC_DELETE_NONE()
		{ Internal::EASTLAlignedFree(p); }

    void EASTLTest_SetGeneralAllocator() { /* intentionally blank */ }
	bool EASTLTest_ValidateHeap() { return true; }

#endif // ....

#endif // Header include guard

<commit_msg>switch to POSIX_memalign from aligned_alloc fix build break on gcc 4.6<commit_after>/////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
/////////////////////////////////////////////////////////////////////////////

#ifndef EASTLTEST_ALLOCATOR_H
#define EASTLTEST_ALLOCATOR_H

#include <EABase/eabase.h>
#include <EASTL/internal/config.h>
#include <new>
#include <stdio.h>

#if !EASTL_OPENSOURCE

	#include <PPMalloc/EAGeneralAllocator.h>
	#include <PPMalloc/EAGeneralAllocatorDebug.h>

	#if defined(EA_COMPILER_MSVC)
		#include <math.h>       // VS2008 has an acknowledged bug that requires math.h (and possibly also string.h) to be #included before intrin.h.
		#include <intrin.h>
		#pragma intrinsic(_ReturnAddress)
	#endif

	///////////////////////////////////////////////////////////////////////////////
	// gGeneralAllocator
	//
	namespace EA
	{
		namespace Allocator
		{
			#ifdef EA_DEBUG
							   GeneralAllocatorDebug  gGeneralAllocator EA_INIT_PRIORITY(1000);
				extern PPM_API GeneralAllocatorDebug* gpEAGeneralAllocatorDebug;
			#else
							   GeneralAllocator       gGeneralAllocator EA_INIT_PRIORITY(1000);
				extern PPM_API GeneralAllocator*      gpEAGeneralAllocator;
			#endif
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// gEASTLTest_AllocationCount
	//
	int gEASTLTest_AllocationCount = 0;

	///////////////////////////////////////////////////////////////////////////////
	// EASTLTest_ValidateHeap
	//
	bool EASTLTest_ValidateHeap()
	{
	#ifdef EA_DEBUG
		return EA::Allocator::gpEAGeneralAllocatorDebug->ValidateHeap(EA::Allocator::GeneralAllocator::kHeapValidationLevelBasic);
	#else
		return true;
	#endif
	}

	///////////////////////////////////////////////////////////////////////////////
	// Microsoft function parameter annotations
	// https://msdn.microsoft.com/en-CA/library/hh916382.aspx
	//
	#ifndef _Ret_maybenull_
	#define _Ret_maybenull_
	#endif

	#ifndef _Post_writable_byte_size_
	#define _Post_writable_byte_size_(x)
	#endif

	#ifndef _Ret_notnull_
	#define _Ret_notnull_
	#endif

	///////////////////////////////////////////////////////////////////////////////
	// operator new extensions
	//
	namespace
	{
		#ifdef EA_DEBUG
			const char gUnattributedNewTag[] = "Anonymous new";
		#endif

		#if defined(EA_COMPILER_MSVC)
			#define UNATTRIBUTED_NEW_FILE   "raw_return_address"
			#define UNATTRIBUTED_NEW_LINE   ((int)(uintptr_t)_ReturnAddress())
		#else
			#define UNATTRIBUTED_NEW_FILE   NULL
			#define UNATTRIBUTED_NEW_LINE   0
		#endif
	}

	_Ret_maybenull_ _Post_writable_byte_size_(size) void* operator new(size_t size, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
	{
		#ifdef EA_DEBUG
			void* const p = EA::Allocator::gGeneralAllocator.MallocDebug(size, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE);
		#else
			void* const p = EA::Allocator::gGeneralAllocator.Malloc(size);
		#endif
		return p;
	}

	void operator delete(void* p, const std::nothrow_t&) EA_THROW_SPEC_DELETE_NONE()
	{
		if(p) // The standard specifies that 'delete NULL' is a valid operation.
		{
			gEASTLTest_AllocationCount--;
			EA::Allocator::gGeneralAllocator.Free(p);
		}
	}

	_Ret_maybenull_ _Post_writable_byte_size_(size) void* operator new[](size_t size, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
	{
		gEASTLTest_AllocationCount++;

		#ifdef EA_DEBUG
			void* const p = EA::Allocator::gGeneralAllocator.MallocDebug(size, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE);
		#else
			void* const p = EA::Allocator::gGeneralAllocator.Malloc(size);
		#endif
		return p;
	}

	void operator delete[](void* p, const std::nothrow_t&) EA_THROW_SPEC_DELETE_NONE()
	{
		if(p)
		{
			gEASTLTest_AllocationCount--;
			EA::Allocator::gGeneralAllocator.Free(p);
		}
	}

	_Ret_notnull_ _Post_writable_byte_size_(size) void* operator new(size_t size) EA_THROW_SPEC_NEW(std::bad_alloc)
	{
		gEASTLTest_AllocationCount++;

		// This IsConstructed functionality is needed by some mobile platforms due to some weaknesses in their application startup.
		#if (PPMALLOC_VERSION_N >= 11602)
			const bool bConstructed = EA::Allocator::gGeneralAllocator.IsConstructed();
		#else
			const bool bConstructed = (EA::Allocator::gGeneralAllocator.GetTraceFunction(NULL) != NULL);
		#endif

		void *mem;

		if(bConstructed)
		{
			#ifdef EA_DEBUG
				mem = EA::Allocator::gGeneralAllocator.MallocDebug(size, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE);
			#else
				mem = EA::Allocator::gGeneralAllocator.Malloc(size);
			#endif
		}
		else
		{
			mem = malloc(size);
		}

	#if !defined(EA_COMPILER_NO_EXCEPTIONS)
		if (mem == NULL)
		{
			throw std::bad_alloc();
		}
	#endif

		return mem;
	}

	_Ret_notnull_ _Post_writable_byte_size_(size) void* operator new[](size_t size) EA_THROW_SPEC_NEW(std::bad_alloc)
	{
		gEASTLTest_AllocationCount++;

		// This IsConstructed functionality is needed by some mobile platforms due to some weaknesses in their application startup.
		#if (PPMALLOC_VERSION_N >= 11602)
			const bool bConstructed = EA::Allocator::gGeneralAllocator.IsConstructed();
		#else
			const bool bConstructed = (EA::Allocator::gGeneralAllocator.GetTraceFunction(NULL) != NULL);
		#endif

		void *mem;

		if(bConstructed)
		{
			#ifdef EA_DEBUG
				mem = EA::Allocator::gGeneralAllocator.MallocDebug(size, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE);
			#else
				mem = EA::Allocator::gGeneralAllocator.Malloc(size);
			#endif
		}
		else
		{
			mem = malloc(size);
		}

	#if !defined(EA_COMPILER_NO_EXCEPTIONS)
		if (mem == NULL)
		{
			throw std::bad_alloc();
		}
	#endif

		return mem;
	}

	#ifdef EA_DEBUG
	void* operator new[](size_t size, const char* name, int flags, unsigned debugFlags, const char* file, int line)
	#else
	void* operator new[](size_t size, const char* /*name*/, int flags, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/)
	#endif
	{
		gEASTLTest_AllocationCount++;

		#ifdef EA_DEBUG
			return EA::Allocator::gGeneralAllocator.MallocDebug(size, flags, debugFlags, name, file, line);
		#else
			return EA::Allocator::gGeneralAllocator.Malloc(size, flags);
		#endif
	}

	#ifdef EA_DEBUG
	void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* name, int flags, unsigned debugFlags, const char* file, int line)
	#else
	void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* /*name*/, int flags, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/)
	#endif
	{
		gEASTLTest_AllocationCount++;

		#ifdef EA_DEBUG
			return EA::Allocator::gGeneralAllocator.MallocAlignedDebug(size, alignment, alignmentOffset, flags, debugFlags, name, file, line);
		#else
			return EA::Allocator::gGeneralAllocator.MallocAligned(size, alignment, alignmentOffset, flags);
		#endif
	}

	// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
	void* operator new(size_t size, size_t alignment)
	{
		gEASTLTest_AllocationCount++;
		return EA::Allocator::gGeneralAllocator.MallocAligned(size, alignment);
	}

	// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
	void* operator new(size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
	{
		gEASTLTest_AllocationCount++;
		return EA::Allocator::gGeneralAllocator.MallocAligned(size, alignment);
	}

	// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
	void* operator new[](size_t size, size_t alignment)
	{
		gEASTLTest_AllocationCount++;
		return EA::Allocator::gGeneralAllocator.MallocAligned(size, alignment);
	}

	// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
	void* operator new[](size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
	{
		gEASTLTest_AllocationCount++;
		return EA::Allocator::gGeneralAllocator.MallocAligned(size, alignment);
	}

	void operator delete(void* p) EA_THROW_SPEC_DELETE_NONE()
	{
		if(p) // The standard specifies that 'delete NULL' is a valid operation.
		{
			gEASTLTest_AllocationCount--;

			// This IsConstructed functionality is needed by some mobile platforms due to some weaknesses in their application startup.
			#if (PPMALLOC_VERSION_N >= 11602)
				const bool bConstructed = EA::Allocator::gGeneralAllocator.IsConstructed();
			#else
				const bool bConstructed = (EA::Allocator::gGeneralAllocator.GetTraceFunction(NULL) != NULL); // Old hacky way to test this.
			#endif

			if(bConstructed)
			{
				if(EA::Allocator::gGeneralAllocator.ValidateAddress(p, EA::Allocator::GeneralAllocatorDebug::kAddressTypeOwned))
					EA::Allocator::gGeneralAllocator.Free(p);
				else
					free(p);
			}
			else
				free(p);
		}
	}

	void operator delete[](void* p) EA_THROW_SPEC_DELETE_NONE()
	{
		if(p)
		{
			gEASTLTest_AllocationCount--;

			// This IsConstructed functionality is needed by some mobile platforms due to some weaknesses in their application startup.
			#if (PPMALLOC_VERSION_N >= 11602)
				const bool bConstructed = EA::Allocator::gGeneralAllocator.IsConstructed();
			#else
				const bool bConstructed = (EA::Allocator::gGeneralAllocator.GetTraceFunction(NULL) != NULL); // Old hacky way to test this.
			#endif

			if(bConstructed)
			{
				if(EA::Allocator::gGeneralAllocator.ValidateAddress(p, EA::Allocator::GeneralAllocatorDebug::kAddressTypeOwned))
					EA::Allocator::gGeneralAllocator.Free(p);
				else
					free(p);
			}
			else
			   free(p);
		}
	}

    void EASTLTest_SetGeneralAllocator()
	{
		EA::Allocator::SetGeneralAllocator(&EA::Allocator::gGeneralAllocator);
		#ifdef EA_DEBUG
			EA::Allocator::gpEAGeneralAllocatorDebug->SetDefaultDebugDataFlag(EA::Allocator::GeneralAllocatorDebug::kDebugDataIdGuard);
		#endif
	}

#else
	#ifndef EA_PLATFORM_MICROSOFT
		#include <stdlib.h>
	#endif

	namespace Internal
	{
		void* EASTLAlignedAlloc(size_t size, size_t alignment)
		{
		#ifdef EA_PLATFORM_MICROSOFT
			return _aligned_malloc(size, alignment);
		#else
			void *p = nullptr;
			alignment = alignment < sizeof( void *) ? sizeof( void *) : alignment;
			posix_memalign(&p, alignment, size);
			return p;
		#endif
		}

		void EASTLAlignedFree(void* p)
		{
		#ifdef EA_PLATFORM_MICROSOFT
			_aligned_free(p);
		#else
			free(p);
		#endif
		}
	}

	void* operator new(size_t const size)
		{ return Internal::EASTLAlignedAlloc(size, 16); }

	void* operator new[](size_t size, const char* /*name*/, int /*flags*/, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/)
		{ return Internal::EASTLAlignedAlloc(size, 16); }

	void* operator new[](size_t size, size_t alignment, size_t /*alignmentOffset*/, const char* /*name*/, int /*flags*/, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/)
		{ return Internal::EASTLAlignedAlloc(size, alignment); }

	void* operator new(size_t size, size_t alignment)
		{ return Internal::EASTLAlignedAlloc(size, alignment); }

	void* operator new(size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
		{ return Internal::EASTLAlignedAlloc(size, alignment); }

	void* operator new[](size_t size, size_t alignment)
		{ return Internal::EASTLAlignedAlloc(size, alignment); }

	void* operator new[](size_t size, size_t alignment, const std::nothrow_t&)EA_THROW_SPEC_NEW_NONE()
		{ return Internal::EASTLAlignedAlloc(size, alignment); }

	void operator delete(void* p) EA_THROW_SPEC_DELETE_NONE()
		{ Internal::EASTLAlignedFree(p); }

	void operator delete[](void* p) EA_THROW_SPEC_DELETE_NONE()
		{ Internal::EASTLAlignedFree(p); }

    void EASTLTest_SetGeneralAllocator() { /* intentionally blank */ }
	bool EASTLTest_ValidateHeap() { return true; }

#endif // ....

#endif // Header include guard

<|endoftext|>


<commit_before>#include <iostream>
using namespace std;
#include <ctime>
// Eigen 部分
#include <Eigen/Core>
// 稠密矩阵的代数运算（逆，特征值等）
#include <Eigen/Dense>

#define MATRIX_SIZE 50

/****************************
* 本程序演示了 Eigen 基本类型的使用
****************************/

int main( int argc, char** argv )
{
    // Eigen 中所有向量和矩阵都是Eigen::Matrix，它是一个模板类。它的前三个参数为：数据类型，行，列
    // 声明一个2*3的float矩阵
    Eigen::Matrix<float, 2, 3> matrix_23;

    // 同时，Eigen 通过 typedef 提供了许多内置类型，不过底层仍是Eigen::Matrix
    // 例如 Vector3d 实质上是 Eigen::Matrix<double, 3, 1>，即三维向量
    Eigen::Vector3d v_3d;
	// 这是一样的
    Eigen::Matrix<float,3,1> vd_3d;

    // Matrix3d 实质上是 Eigen::Matrix<double, 3, 3>
    Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero(); //初始化为零
    // 如果不确定矩阵大小，可以使用动态大小的矩阵
    Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > matrix_dynamic;
    // 更简单的
    Eigen::MatrixXd matrix_x;
    // 这种类型还有很多，我们不一一列举

    // 下面是对Eigen阵的操作
    // 输入数据（初始化）
    matrix_23 << 1, 2, 3, 4, 5, 6;
    // 输出
    cout << matrix_23 << endl;

    // 用()访问矩阵中的元素
    for (int i=0; i<2; i++) {
        for (int j=0; j<3; j++)
            cout<<matrix_23(i,j)<<"\t";
        cout<<endl;
    }

    // 矩阵和向量相乘（实际上仍是矩阵和矩阵）
    v_3d << 3, 2, 1;
    vd_3d << 4,5,6;
    // 但是在Eigen里你不能混合两种不同类型的矩阵，像这样是错的
    // Eigen::Matrix<double, 2, 1> result_wrong_type = matrix_23 * v_3d;
    // 应该显式转换
    Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d;
    cout << result << endl;

    Eigen::Matrix<float, 2, 1> result2 = matrix_23 * vd_3d;
    cout << result2 << endl;

    // 同样你不能搞错矩阵的维度
    // 试着取消下面的注释，看看Eigen会报什么错
    // Eigen::Matrix<double, 2, 3> result_wrong_dimension = matrix_23.cast<double>() * v_3d;

    // 一些矩阵运算
    // 四则运算就不演示了，直接用+-*/即可。
    matrix_33 = Eigen::Matrix3d::Random();      // 随机数矩阵
    cout << matrix_33 << endl << endl;

    cout << matrix_33.transpose() << endl;      // 转置
    cout << matrix_33.sum() << endl;            // 各元素和
    cout << matrix_33.trace() << endl;          // 迹
    cout << 10*matrix_33 << endl;               // 数乘
    cout << matrix_33.inverse() << endl;        // 逆
    cout << matrix_33.determinant() << endl;    // 行列式

    // 特征值
    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver ( matrix_33 );
    cout << "Eigen values = \n" << eigen_solver.eigenvalues() << endl;
    cout << "Eigen vectors = \n" << eigen_solver.eigenvectors() << endl;

    // 解方程
    // 我们求解 matrix_NN * x = v_Nd 这个方程
    // N的大小在前边的宏里定义，它由随机数生成
    // 直接求逆自然是最直接的，但是求逆运算量大

    Eigen::Matrix< double, MATRIX_SIZE, MATRIX_SIZE > matrix_NN;
    matrix_NN = Eigen::MatrixXd::Random( MATRIX_SIZE, MATRIX_SIZE );
    Eigen::Matrix< double, MATRIX_SIZE,  1> v_Nd;
    v_Nd = Eigen::MatrixXd::Random( MATRIX_SIZE,1 );

    clock_t time_stt = clock(); // 计时
    // 直接求逆
    Eigen::Matrix<double,MATRIX_SIZE,1> x = matrix_NN.inverse()*v_Nd;
    cout <<"time use in normal invers is " << 1000* (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms"<< endl;

	// 通常用矩阵分解来求，例如QR分解，速度会快很多
    time_stt = clock();
    x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
    cout <<"time use in Qr compsition is " <<1000*  (clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl;

    return 0;
}
<commit_msg>fixxing bugs<commit_after>#include <iostream>
using namespace std;
#include <ctime>
// Eigen 部分
#include <Eigen/Core>
// 稠密矩阵的代数运算（逆，特征值等）
#include <Eigen/Dense>

#define MATRIX_SIZE 50

/****************************
* 本程序演示了 Eigen 基本类型的使用
****************************/

int main( int argc, char** argv )
{
    // Eigen 中所有向量和矩阵都是Eigen::Matrix，它是一个模板类。它的前三个参数为：数据类型，行，列
    // 声明一个2*3的float矩阵
    Eigen::Matrix<float, 2, 3> matrix_23;

    // 同时，Eigen 通过 typedef 提供了许多内置类型，不过底层仍是Eigen::Matrix
    // 例如 Vector3d 实质上是 Eigen::Matrix<double, 3, 1>，即三维向量
    Eigen::Vector3d v_3d;
	// 这是一样的
    Eigen::Matrix<float,3,1> vd_3d;

    // Matrix3d 实质上是 Eigen::Matrix<double, 3, 3>
    Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero(); //初始化为零
    // 如果不确定矩阵大小，可以使用动态大小的矩阵
    Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > matrix_dynamic;
    // 更简单的
    Eigen::MatrixXd matrix_x;
    // 这种类型还有很多，我们不一一列举

    // 下面是对Eigen阵的操作
    // 输入数据（初始化）
    matrix_23 << 1, 2, 3, 4, 5, 6;
    // 输出
    cout << matrix_23 << endl;

    // 用()访问矩阵中的元素
    for (int i=0; i<2; i++) {
        for (int j=0; j<3; j++)
            cout<<matrix_23(i,j)<<"\t";
        cout<<endl;
    }

    // 矩阵和向量相乘（实际上仍是矩阵和矩阵）
    v_3d << 3, 2, 1;
    vd_3d << 4,5,6;
    // 但是在Eigen里你不能混合两种不同类型的矩阵，像这样是错的
    // Eigen::Matrix<double, 2, 1> result_wrong_type = matrix_23 * v_3d;
    // 应该显式转换
    Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d;
    cout << result << endl;

    Eigen::Matrix<float, 2, 1> result2 = matrix_23 * vd_3d;
    cout << result2 << endl;

    // 同样你不能搞错矩阵的维度
    // 试着取消下面的注释，看看Eigen会报什么错
    // Eigen::Matrix<double, 2, 3> result_wrong_dimension = matrix_23.cast<double>() * v_3d;

    // 一些矩阵运算
    // 四则运算就不演示了，直接用+-*/即可。
    matrix_33 = Eigen::Matrix3d::Random();      // 随机数矩阵
    cout << matrix_33 << endl << endl;

    cout << matrix_33.transpose() << endl;      // 转置
    cout << matrix_33.sum() << endl;            // 各元素和
    cout << matrix_33.trace() << endl;          // 迹
    cout << 10*matrix_33 << endl;               // 数乘
    cout << matrix_33.inverse() << endl;        // 逆
    cout << matrix_33.determinant() << endl;    // 行列式

    // 特征值
    // 实对称矩阵可以保证对角化成功
    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver ( matrix_33.transpose()*matrix_33 );
    cout << "Eigen values = \n" << eigen_solver.eigenvalues() << endl;
    cout << "Eigen vectors = \n" << eigen_solver.eigenvectors() << endl;

    // 解方程
    // 我们求解 matrix_NN * x = v_Nd 这个方程
    // N的大小在前边的宏里定义，它由随机数生成
    // 直接求逆自然是最直接的，但是求逆运算量大

    Eigen::Matrix< double, MATRIX_SIZE, MATRIX_SIZE > matrix_NN;
    matrix_NN = Eigen::MatrixXd::Random( MATRIX_SIZE, MATRIX_SIZE );
    Eigen::Matrix< double, MATRIX_SIZE,  1> v_Nd;
    v_Nd = Eigen::MatrixXd::Random( MATRIX_SIZE,1 );

    clock_t time_stt = clock(); // 计时
    // 直接求逆
    Eigen::Matrix<double,MATRIX_SIZE,1> x = matrix_NN.inverse()*v_Nd;
    cout <<"time use in normal invers is " << 1000* (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms"<< endl;

	// 通常用矩阵分解来求，例如QR分解，速度会快很多
    time_stt = clock();
    x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
    cout <<"time use in Qr compsition is " <<1000*  (clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl;

    return 0;
}
<|endoftext|>


<commit_before>
int main() {

}<commit_msg>Get Toggl API token from env<commit_after>#include <iostream>
#include <cstdlib>

int main(int argc, char* argv[]) {
	char* buf = getenv("TOGGL_API_TOKEN");
	if (!buf) {
		std::cerr << "Please set TOGGL_API_TOKEN in environment" << std::endl;
		return 1;
	}
	if (argc < 2) {
		std::cerr << "Usage: " << argv[0] << " COMMAND" << std::endl;
		return 1;
	}
	return 0;
}<|endoftext|>