<commit_before>/*  This file is part of the Vc library.

    Copyright (C) 2010 Matthias Kretz <kretz@kde.org>

    Vc is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Vc is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/Vc>
#include "unittest.h"
#include <limits>
#include <algorithm>

using namespace Vc;

template<typename V1, typename V2> void testNumber(double n)
{
    typedef typename V1::EntryType T1;
    typedef typename V2::EntryType T2;

    const T1 n1 = static_cast<T1>(n);
    const T2 n2 = static_cast<T2>(n);

    V1 v1;
    V2 v2;

    v1 = n1;
    v2 = static_cast<V2>(v1);
    //std::cerr << v1 << v2 << std::endl;
    COMPARE(static_cast<V1>(v2), v1);

    v2 = n2;
    v1 = static_cast<V1>(v2);
    //std::cerr << v1 << v2 << std::endl;
    COMPARE(static_cast<V2>(v1), v2);
}

template<typename V1, typename V2> void testCast2()
{
    typedef typename V1::EntryType T1;
    typedef typename V2::EntryType T2;

    const double max = std::min(
            static_cast<double>(std::numeric_limits<T1>::max()),
            static_cast<double>(std::numeric_limits<T2>::max()));
    const double min = std::max(
            std::numeric_limits<T1>::is_integer ?
                static_cast<double>(std::numeric_limits<T1>::min()) :
                static_cast<double>(-std::numeric_limits<T1>::max()),
            std::numeric_limits<T2>::is_integer ?
                static_cast<double>(std::numeric_limits<T2>::min()) :
                static_cast<double>(-std::numeric_limits<T2>::max())
                );

    testNumber<V1, V2>(0.);
    testNumber<V1, V2>(1.);
    testNumber<V1, V2>(2.);
    testNumber<V1, V2>(max);
    testNumber<V1, V2>(min);
}

template<typename T> void testCast()
{
    testCast2<typename T::V1, typename T::V2>();
}

#define _CONCAT(A, B) A ## _ ## B
#define CONCAT(A, B) _CONCAT(A, B)
template<typename T1, typename T2>
struct T2Helper
{
    typedef T1 V1;
    typedef T2 V2;
};

int main(int argc, char **argv)
{
    initTest(argc, argv);

#define TEST(v1, v2) \
    typedef T2Helper<v1, v2> CONCAT(v1, v2); \
    runTest(testCast<CONCAT(v1, v2)>)

    TEST(float_v, float_v);
    TEST(float_v, int_v);
    TEST(float_v, uint_v);
    // needs special handling for different Size:
    //TEST(float_v, double_v);
    //TEST(float_v, short_v);
    //TEST(float_v, ushort_v);

    TEST(int_v, float_v);
    TEST(int_v, int_v);
    TEST(int_v, uint_v);

    TEST(uint_v, float_v);
    TEST(uint_v, int_v);
    TEST(uint_v, uint_v);

    TEST(ushort_v, sfloat_v);
    TEST(ushort_v, short_v);
    TEST(ushort_v, ushort_v);

    TEST(short_v, sfloat_v);
    TEST(short_v, short_v);
    TEST(short_v, ushort_v);

    TEST(sfloat_v, sfloat_v);
    TEST(sfloat_v, short_v);
    TEST(sfloat_v, ushort_v);
#undef TEST

    return 0;
}
<commit_msg>maximum of int loses precision in float and gets rounded to nearest, thus breaking the test. Fix the test<commit_after>/*  This file is part of the Vc library.

    Copyright (C) 2010 Matthias Kretz <kretz@kde.org>

    Vc is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Vc is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/Vc>
#include "unittest.h"
#include <limits>
#include <algorithm>

using namespace Vc;

template<typename V1, typename V2> void testNumber(double n)
{
    typedef typename V1::EntryType T1;
    typedef typename V2::EntryType T2;

    const T1 n1 = static_cast<T1>(n);
    const T2 n2 = static_cast<T2>(n);

    V1 v1;
    V2 v2;

    v1 = n1;
    v2 = static_cast<V2>(v1);
    //std::cerr << v1 << v2 << std::endl;
    COMPARE(static_cast<V1>(v2), v1);

    v2 = n2;
    v1 = static_cast<V1>(v2);
    //std::cerr << v1 << v2 << std::endl;
    COMPARE(static_cast<V2>(v1), v2);
}

template<typename T> double maxHelper()
{
    return static_cast<double>(std::numeric_limits<T>::max());
}

template<> double maxHelper<int>()
{
    const int intDigits = std::numeric_limits<int>::digits;
    const int floatDigits = std::numeric_limits<float>::digits;
    return static_cast<double>(((int(1) << floatDigits) - 1) << (intDigits - floatDigits));
}

template<typename V1, typename V2> void testCast2()
{
    typedef typename V1::EntryType T1;
    typedef typename V2::EntryType T2;

    const double max = std::min(maxHelper<T1>(), maxHelper<T2>());
    const double min = std::max(
            std::numeric_limits<T1>::is_integer ?
                static_cast<double>(std::numeric_limits<T1>::min()) :
                static_cast<double>(-std::numeric_limits<T1>::max()),
            std::numeric_limits<T2>::is_integer ?
                static_cast<double>(std::numeric_limits<T2>::min()) :
                static_cast<double>(-std::numeric_limits<T2>::max())
                );

    testNumber<V1, V2>(0.);
    testNumber<V1, V2>(1.);
    testNumber<V1, V2>(2.);
    testNumber<V1, V2>(max);
    testNumber<V1, V2>(min);
}

template<typename T> void testCast()
{
    testCast2<typename T::V1, typename T::V2>();
}

#define _CONCAT(A, B) A ## _ ## B
#define CONCAT(A, B) _CONCAT(A, B)
template<typename T1, typename T2>
struct T2Helper
{
    typedef T1 V1;
    typedef T2 V2;
};

int main(int argc, char **argv)
{
    initTest(argc, argv);

#define TEST(v1, v2) \
    typedef T2Helper<v1, v2> CONCAT(v1, v2); \
    runTest(testCast<CONCAT(v1, v2)>)

    TEST(float_v, float_v);
    TEST(float_v, int_v);
    TEST(float_v, uint_v);
    // needs special handling for different Size:
    //TEST(float_v, double_v);
    //TEST(float_v, short_v);
    //TEST(float_v, ushort_v);

    TEST(int_v, float_v);
    TEST(int_v, int_v);
    TEST(int_v, uint_v);

    TEST(uint_v, float_v);
    TEST(uint_v, int_v);
    TEST(uint_v, uint_v);

    TEST(ushort_v, sfloat_v);
    TEST(ushort_v, short_v);
    TEST(ushort_v, ushort_v);

    TEST(short_v, sfloat_v);
    TEST(short_v, short_v);
    TEST(short_v, ushort_v);

    TEST(sfloat_v, sfloat_v);
    TEST(sfloat_v, short_v);
    TEST(sfloat_v, ushort_v);
#undef TEST

    return 0;
}
<|endoftext|>


<commit_before>#include <UtH/Renderer/RenderTarget.hpp>
#include <UtH/Renderer/Camera.hpp>
#include <UtH/Platform/Debug.hpp>
#include <UtH/Platform/Graphics.hpp>

namespace
{
    static const unsigned int getUniqueID()
    {
        static unsigned int id = 0;

        return ++id;
    }
}

namespace uth
{
    RenderTarget::RenderTarget()
        : m_camera(nullptr),
          m_shader(nullptr),
          m_defaultCamera(),
          m_defaultShader(),
          m_viewport(),
          m_uniqueID(getUniqueID())
    {

    }

    bool RenderTarget::Bind()
    {
        updateUniforms();

        static unsigned int lastID = 0;

        if (lastID != m_uniqueID)
            return bind();
        else
            return true;
    }

    void RenderTarget::Clear(const float r, const float g, const float b, const float a)
    {
        bind();

        uth::Graphics::Clear(r, g, b, a);
    }

    void RenderTarget::SetCamera(Camera* camera)
    {
        m_camera = camera;
    }

    Camera& RenderTarget::GetCamera()
    {
        static bool set = false;

        if (!set)
        {
            m_defaultCamera.SetSize(GetSize());
            m_defaultCamera.SetPosition(0, 0);
            set = true;
        }

        if (m_camera)
            return *m_camera;

        return m_defaultCamera;
    }

    void RenderTarget::SetShader(Shader* shader)
    {
        m_shader = shader;
    }

    Shader& RenderTarget::GetShader()
    {
        static bool loaded = false;

        if (!loaded)
        {
            bool compiled = m_defaultShader.LoadShader("Shaders/vertexshader.vert", "Shaders/fragmentshader.frag");
            assert(compiled);
            loaded = true;
        }

        if (m_shader)
            return *m_shader;

        return m_defaultShader;
    }

    void RenderTarget::SetViewport(const umath::rectangle& rect)
    {
        m_viewport = rect;
    }

    const umath::rectangle& RenderTarget::GetViewport() const
    {
        return m_viewport;
    }

    void RenderTarget::updateUniforms()
    {
        if (m_shader)
        {
            m_shader->SetUniform("unifProjection", m_camera ? m_camera->GetProjectionTransform() : m_defaultCamera.GetProjectionTransform());

        }
        else
        {
            m_defaultShader.SetUniform("unifProjection", m_camera ? m_camera->GetProjectionTransform() : m_defaultCamera.GetProjectionTransform());

        }
    }
}<commit_msg>Update the last used id...<commit_after>#include <UtH/Renderer/RenderTarget.hpp>
#include <UtH/Renderer/Camera.hpp>
#include <UtH/Platform/Debug.hpp>
#include <UtH/Platform/Graphics.hpp>

namespace
{
    static const unsigned int getUniqueID()
    {
        static unsigned int id = 0;

        return ++id;
    }
}

namespace uth
{
    RenderTarget::RenderTarget()
        : m_camera(nullptr),
          m_shader(nullptr),
          m_defaultCamera(),
          m_defaultShader(),
          m_viewport(),
          m_uniqueID(getUniqueID())
    {

    }

    bool RenderTarget::Bind()
    {
        updateUniforms();

        static unsigned int lastID = 0;

        if (lastID != m_uniqueID)
        {
            lastID = m_uniqueID;
            return bind();
        }
        else
            return true;
    }

    void RenderTarget::Clear(const float r, const float g, const float b, const float a)
    {
        bind();

        uth::Graphics::Clear(r, g, b, a);
    }

    void RenderTarget::SetCamera(Camera* camera)
    {
        m_camera = camera;
    }

    Camera& RenderTarget::GetCamera()
    {
        static bool set = false;

        if (!set)
        {
            m_defaultCamera.SetSize(GetSize());
            m_defaultCamera.SetPosition(0, 0);
            set = true;
        }

        if (m_camera)
            return *m_camera;

        return m_defaultCamera;
    }

    void RenderTarget::SetShader(Shader* shader)
    {
        m_shader = shader;
    }

    Shader& RenderTarget::GetShader()
    {
        static bool loaded = false;

        if (!loaded)
        {
            bool compiled = m_defaultShader.LoadShader("Shaders/vertexshader.vert", "Shaders/fragmentshader.frag");
            assert(compiled);
            loaded = true;
        }

        if (m_shader)
            return *m_shader;

        return m_defaultShader;
    }

    void RenderTarget::SetViewport(const umath::rectangle& rect)
    {
        m_viewport = rect;
    }

    const umath::rectangle& RenderTarget::GetViewport() const
    {
        return m_viewport;
    }

    void RenderTarget::updateUniforms()
    {
        if (m_shader)
        {
            m_shader->SetUniform("unifProjection", m_camera ? m_camera->GetProjectionTransform() : m_defaultCamera.GetProjectionTransform());

        }
        else
        {
            m_defaultShader.SetUniform("unifProjection", m_camera ? m_camera->GetProjectionTransform() : m_defaultCamera.GetProjectionTransform());

        }
    }
}<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(n)

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        if (tokens.empty()) {
            return 0;
        }
        stack<string> s;
        for (const auto& tok : tokens) {
            if (!is_operator(tok)) {
                s.emplace(tok);
            } else {
                auto y = stoi(s.top());
                s.pop();
                auto x = stoi(s.top());
                s.pop();
                if (tok[0] == '+') {
                    x += y;
                } else if (tok[0] == '-') {
                    x -= y;
                } else if (tok[0] == '*') {
                    x *= y;
                } else {
                    x /= y;
                }
                s.emplace(to_string(x));
            }
        }
        return stoi(s.top());
    }

private:
    bool is_operator(const string& op) {
        return op.length() == 1 && string("+-*/").find(op) != string::npos;
    }
};
<commit_msg>Update evaluate-reverse-polish-notation.cpp<commit_after>// Time:  O(n)
// Space: O(n)

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        if (tokens.empty()) {
            return 0;
        }
        stack<string> s;
        for (const auto& tok : tokens) {
            if (!is_operator(tok)) {
                s.emplace(tok);
            } else {
                auto&& y = stoi(s.top());
                s.pop();
                auto&& x = stoi(s.top());
                s.pop();
                if (tok[0] == '+') {
                    x += y;
                } else if (tok[0] == '-') {
                    x -= y;
                } else if (tok[0] == '*') {
                    x *= y;
                } else {
                    x /= y;
                }
                s.emplace(to_string(x));
            }
        }
        return stoi(s.top());
    }

private:
    bool is_operator(const string& op) {
        return op.length() == 1 && string("+-*/").find(op) != string::npos;
    }
};
<|endoftext|>


<commit_before>// Time:  O(2^n)
// Space: O(n)

class Solution {
public:
    string minAbbreviation(string target, vector<string>& dictionary) {
        vector<int> bits_dict;
        int bit_candidates = 0;
        dict_to_bits_dict(target, dictionary, &bits_dict, &bit_candidates);

        int min_len = numeric_limits<int>::max(), min_abbr = 0;
        dfs(target, bit_candidates, 1, 0, &bits_dict, &min_len, &min_abbr);

        return bits_to_abbr(target, min_abbr);
    }

private:
    void dfs(const string& target, int bit_candidates, int bits, int mask,
             vector<int> *bits_dict, int *min_len, int *min_abbr) {

        const auto len = abbr_len(target, mask);
        if (len >= *min_len) {
            return;
        }

        bool match = true;
        for (const auto& d : *bits_dict) {
            if ((mask & d) == 0) {
                match = false;
                break;
            }
        }
        if (match) {
            *min_len = len;
            *min_abbr = mask;
        } else {
            for (int b = bits; b < (1 << target.length()); b <<= 1) {
                if (bit_candidates & b) {
                    dfs(target, bit_candidates, b << 1, mask | b, bits_dict, min_len, min_abbr);
                }
            }
        }
    }

    void dict_to_bits_dict(const string& target, const vector<string>& dictionary,
                         vector<int> *bits_dict, int *bit_candidates) {
        for (const auto& w : dictionary) {
            int word = 0;
            if (w.length() != target.length()) {
                continue;
            }
            for (int i = target.length() - 1, bit = 1; i >= 0; --i, bit <<= 1) {
                if (target[i] != w[i]) {
                    word |= bit;
                }
            }
            bits_dict->emplace_back(word);
            *bit_candidates |= word;
        }
    }

    int abbr_len(const string& target, int mask) {
        int count = 0;
        for (int b = 1; b < (1 << target.length());) {
            if ((mask & b) == 0) {
                for (; b < (1 << target.length()) && (mask & b) == 0; b <<= 1);
            } else {
                b <<= 1;
            }
            ++count;
        }
        return count;
    }

    string bits_to_abbr(const string& target, int min_abbr) {
        vector<string> tmp;
        for (int i = target.length() - 1, pre = i; i >= 0; --i, min_abbr >>= 1) {
            if (min_abbr & 1) {
                if (pre - i > 0) {
                    tmp.emplace_back(to_string(pre - i));
                }
                pre = i - 1;
                tmp.emplace_back(string(1, target[i]));
            } else if (i == 0) {
                tmp.emplace_back(to_string(pre - i + 1));
            }
        }
        reverse(tmp.begin(), tmp.end());

        string abbr;
        for (const auto& s : tmp) {
            abbr += s;
        }
        return abbr;
    }
};
<commit_msg>Update minimum-unique-word-abbreviation.cpp<commit_after>// Time:  O(2^n)
// Space: O(n)

class Solution {
public:
    string minAbbreviation(string target, vector<string>& dictionary) {
        vector<int> bits_dict;
        int bit_candidates = 0;
        dict_to_bits_dict(target, dictionary, &bits_dict, &bit_candidates);

        int min_len = numeric_limits<int>::max(), min_abbr = 0;
        dfs(target, bit_candidates, 1, 0, &bits_dict, &min_len, &min_abbr);

        return bits_to_abbr(target, min_abbr);
    }

private:
    void dfs(const string& target, int bit_candidates, int bits, int mask,
             vector<int> *bits_dict, int *min_len, int *min_abbr) {

        const auto len = abbr_len(target, mask);
        if (len >= *min_len) {
            return;
        }

        bool match = true;
        for (const auto& d : *bits_dict) {
            if ((mask & d) == 0) {
                match = false;
                break;
            }
        }
        if (match) {
            *min_len = len;
            *min_abbr = mask;
        } else {
            for (int b = bits; b < (1 << target.length()); b <<= 1) {
                if (bit_candidates & b) {
                    dfs(target, bit_candidates, b << 1, mask | b, bits_dict, min_len, min_abbr);
                }
            }
        }
    }

    void dict_to_bits_dict(const string& target, const vector<string>& dictionary,
                         vector<int> *bits_dict, int *bit_candidates) {
        for (const auto& w : dictionary) {
            int bits = 0;
            if (w.length() != target.length()) {
                continue;
            }
            for (int i = target.length() - 1, bit = 1; i >= 0; --i, bit <<= 1) {
                if (target[i] != w[i]) {
                    bits |= bit;
                }
            }
            bits_dict->emplace_back(bits);
            *bit_candidates |= bits;
        }
    }

    int abbr_len(const string& target, int mask) {
        int count = 0;
        for (int b = 1; b < (1 << target.length());) {
            if ((mask & b) == 0) {
                for (; b < (1 << target.length()) && (mask & b) == 0; b <<= 1);
            } else {
                b <<= 1;
            }
            ++count;
        }
        return count;
    }

    string bits_to_abbr(const string& target, int min_abbr) {
        vector<string> tmp;
        for (int i = target.length() - 1, pre = i; i >= 0; --i, min_abbr >>= 1) {
            if (min_abbr & 1) {
                if (pre - i > 0) {
                    tmp.emplace_back(to_string(pre - i));
                }
                pre = i - 1;
                tmp.emplace_back(string(1, target[i]));
            } else if (i == 0) {
                tmp.emplace_back(to_string(pre - i + 1));
            }
        }
        reverse(tmp.begin(), tmp.end());

        string abbr;
        for (const auto& s : tmp) {
            abbr += s;
        }
        return abbr;
    }
};
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkOpenGLCamera.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 <math.h>

#include "vtkRenderWindow.h"
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLCamera.h"
#include <GL/gl.h>

// Description:
// Implement base class method.
void vtkOpenGLCamera::Render(vtkRenderer *ren)
{
  float aspect[2];
  float *vport;
  float *bg_color;
  int left,right,bottom,top;
  int  *size;
  vtkMatrix4x4 matrix;

  // get the bounds of the window
  size = (ren->GetRenderWindow())->GetSize();

  // find out if we should stereo render
  this->Stereo = (ren->GetRenderWindow())->GetStereoRender();
  vport = ren->GetViewport();

  left = (int)(vport[0]*(size[0] -1));
  right = (int)(vport[2]*(size[0] - 1));

  // if were on a stereo renderer draw to special parts of screen
#ifndef sparc
  if (this->Stereo)
    {
    switch ((ren->GetRenderWindow())->GetStereoType())
      {
      case VTK_STEREO_CRYSTAL_EYES:
	if (this->LeftEye)
	  {
	  bottom = (int)(532 + (1023-532)*vport[1]);
	  top = (int)(532 + (1023-532)*vport[3]);
	  }
	else
	  {
	  bottom = (int)(491*vport[1]);
	  top = (int)(491*vport[3]);
	  }
	break;
      default:
	bottom = (int)(vport[1]*(size[1] -1));
	top = (int)(vport[3]*(size[1] - 1));
      }
    }
  else
    {
    bottom = (int)(vport[1]*(size[1] -1));
    top = (int)(vport[3]*(size[1] - 1));
    }
#else
  if (this->Stereo)
    {
    switch ((ren->GetRenderWindow())->GetStereoType())
      {
      case VTK_STEREO_CRYSTAL_EYES:
        if (this->LeftEye)
          {
          glDrawBuffer(GL_BACK_LEFT);
          }
        else
          {
          glDrawBuffer(GL_BACK_RIGHT);
          }
        break;
      default:
        break;
      }
    }
  else
    {
    if (ren->GetRenderWindow()->GetDoubleBuffer())
      {
      glDrawBuffer(GL_BACK);
      }
    else
      {
      glDrawBuffer(GL_FRONT);
      }
    }

  // we will set this for all modes on the sparc
  bottom = (int)(vport[1]*(size[1] -1));
  top = (int)(vport[3]*(size[1] - 1));
#endif

  glViewport(left,bottom,(right-left+1),(top-bottom+1));
  glEnable( GL_SCISSOR_TEST );
  glScissor( left, bottom,(right-left+1),(top-bottom+1));

  /* for stereo we have to fiddle with aspect */
  if (this->Stereo)
    {
    switch ((ren->GetRenderWindow())->GetStereoType())
      {
      case VTK_STEREO_CRYSTAL_EYES:
#ifndef sparc
	aspect[0] = (float)(right-left+1)/(float)(2.0*(top-bottom+1));
#else
	aspect[0] = (float)(right-left+1)/(float)(top-bottom+1);
#endif
	aspect[1] = 1.0;
	break;
      default:
	aspect[0] = (float)(right-left+1)/(float)(top-bottom+1);
	aspect[1] = 1.0;
      }
    }
  else
    {
    aspect[0] = (float)(right-left+1)/(float)(top-bottom+1);
    aspect[1] = 1.0;
    }

  ren->SetAspect(aspect);

  glMatrixMode( GL_PROJECTION);
  matrix = this->GetPerspectiveTransform(aspect[0]/aspect[1],-1,1);
  matrix.Transpose();
  // insert camera view transformation
  glLoadMatrixf(matrix[0]);

  // since lookat modifies the model view matrix do a push
  // first and set the mmode.  This will be undone in the
  // render action after the actors! message sis sent
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();

  matrix = this->GetViewTransform();
  matrix.Transpose();

  // insert camera view transformation
  glMultMatrixf(matrix[0]);

  // get the background color
  bg_color = ren->GetBackground();

  if ((ren->GetRenderWindow())->GetErase())
    {
    glClearColor( ((GLclampf)(bg_color[0])),
		  ((GLclampf)(bg_color[1])),
		  ((GLclampf)(bg_color[2])),
		  ((GLclampf)(1.0)) );

    glClearDepth( (GLclampd)( 1.0 ) );
    vtkDebugMacro(<< "glClear\n");
    glClear((GLbitfield)(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
    }

  // if we have a stereo renderer, draw other eye next time
  if (this->Stereo)
    {
    if (this->LeftEye) this->LeftEye = 0;
    else this->LeftEye = 1;
    }
}
<commit_msg>ENH: added win32 quad buffer support - ken<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkOpenGLCamera.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 <math.h>

#include "vtkRenderWindow.h"
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLCamera.h"
#include <GL/gl.h>

// Description:
// Implement base class method.
void vtkOpenGLCamera::Render(vtkRenderer *ren)
{
  float aspect[2];
  float *vport;
  float *bg_color;
  int left,right,bottom,top;
  int  *size;
  vtkMatrix4x4 matrix;

  // get the bounds of the window
  size = (ren->GetRenderWindow())->GetSize();

  // find out if we should stereo render
  this->Stereo = (ren->GetRenderWindow())->GetStereoRender();
  vport = ren->GetViewport();

  left = (int)(vport[0]*(size[0] -1));
  right = (int)(vport[2]*(size[0] - 1));

  // if were on a stereo renderer draw to special parts of screen
#if defined(sparc) || defined( _WIN32)
  if (this->Stereo)
    {
    switch ((ren->GetRenderWindow())->GetStereoType())
      {
      case VTK_STEREO_CRYSTAL_EYES:
        if (this->LeftEye)
          {
          glDrawBuffer(GL_BACK_LEFT);
          }
        else
          {
          glDrawBuffer(GL_BACK_RIGHT);
          }
        break;
      default:
        break;
      }
    }
  else
    {
    if (ren->GetRenderWindow()->GetDoubleBuffer())
      {
      glDrawBuffer(GL_BACK);
      }
    else
      {
      glDrawBuffer(GL_FRONT);
      }
    }

  // we will set this for all modes on the sparc
  bottom = (int)(vport[1]*(size[1] -1));
  top = (int)(vport[3]*(size[1] - 1));
#else
  if (this->Stereo)
    {
    switch ((ren->GetRenderWindow())->GetStereoType())
      {
      case VTK_STEREO_CRYSTAL_EYES:
	if (this->LeftEye)
	  {
	  bottom = (int)(532 + (1023-532)*vport[1]);
	  top = (int)(532 + (1023-532)*vport[3]);
	  }
	else
	  {
	  bottom = (int)(491*vport[1]);
	  top = (int)(491*vport[3]);
	  }
	break;
      default:
	bottom = (int)(vport[1]*(size[1] -1));
	top = (int)(vport[3]*(size[1] - 1));
      }
    }
  else
    {
    bottom = (int)(vport[1]*(size[1] -1));
    top = (int)(vport[3]*(size[1] - 1));
    }
#endif

  glViewport(left,bottom,(right-left+1),(top-bottom+1));
  glEnable( GL_SCISSOR_TEST );
  glScissor( left, bottom,(right-left+1),(top-bottom+1));

  /* for stereo we have to fiddle with aspect */
  if (this->Stereo)
    {
    switch ((ren->GetRenderWindow())->GetStereoType())
      {
      case VTK_STEREO_CRYSTAL_EYES:
#if defined(sparc) || defined(_WIN32)
	aspect[0] = (float)(right-left+1)/(float)(top-bottom+1);
#else
	aspect[0] = (float)(right-left+1)/(float)(2.0*(top-bottom+1));
#endif
	aspect[1] = 1.0;
	break;
      default:
	aspect[0] = (float)(right-left+1)/(float)(top-bottom+1);
	aspect[1] = 1.0;
      }
    }
  else
    {
    aspect[0] = (float)(right-left+1)/(float)(top-bottom+1);
    aspect[1] = 1.0;
    }

  ren->SetAspect(aspect);

  glMatrixMode( GL_PROJECTION);
  matrix = this->GetPerspectiveTransform(aspect[0]/aspect[1],-1,1);
  matrix.Transpose();
  // insert camera view transformation
  glLoadMatrixf(matrix[0]);

  // since lookat modifies the model view matrix do a push
  // first and set the mmode.  This will be undone in the
  // render action after the actors! message sis sent
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();

  matrix = this->GetViewTransform();
  matrix.Transpose();

  // insert camera view transformation
  glMultMatrixf(matrix[0]);

  // get the background color
  bg_color = ren->GetBackground();

  if ((ren->GetRenderWindow())->GetErase())
    {
    glClearColor( ((GLclampf)(bg_color[0])),
		  ((GLclampf)(bg_color[1])),
		  ((GLclampf)(bg_color[2])),
		  ((GLclampf)(1.0)) );

    glClearDepth( (GLclampd)( 1.0 ) );
    vtkDebugMacro(<< "glClear\n");
    glClear((GLbitfield)(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
    }

  // if we have a stereo renderer, draw other eye next time
  if (this->Stereo)
    {
    if (this->LeftEye) this->LeftEye = 0;
    else this->LeftEye = 1;
    }
}
<|endoftext|>


<commit_before>/*
 * MpdAudioSource.cpp
 *
 * Created on: Jul 30, 2015
 *     Author: dpayne
 */

#include "Source/MpdAudioSource.h"
#include "Utils/Logger.h"
#include <string.h>
#include <iostream>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

namespace
{
static const int32_t k_read_attempts = 100;
static const int64_t k_read_attempt_sleep_interval_nanosecs =
    1L * 1000000L; // 1 millisecond
static struct timespec k_read_attempt_sleep_timespec = {
    0, k_read_attempt_sleep_interval_nanosecs};
}

vis::MpdAudioSource::MpdAudioSource(const Settings *const settings)
    : m_settings{settings}
{
    open_mpd_fifo();
}

bool vis::MpdAudioSource::open_mpd_fifo()
{
    m_mpd_fifo_fd = ::open(m_settings->get_mpd_fifo_path().c_str(), O_RDONLY);

    if (m_mpd_fifo_fd < 0)
    {
        VIS_LOG(vis::LogLevel::WARN, "Error reading file: %s", strerror(errno));
        m_mpd_fifo_fd = -1;
        return false;
    }

    auto flags = fcntl(m_mpd_fifo_fd, F_GETFL, 0);
    fcntl(m_mpd_fifo_fd, F_SETFL, flags | O_NONBLOCK);

    return true;
}

bool vis::MpdAudioSource::read(pcm_stereo_sample *buffer,
                               const uint32_t buffer_size)
{
    // try to re-open the stream if it has been closed
    if (m_mpd_fifo_fd < 0)
    {
        open_mpd_fifo();
    }

    size_t buffer_size_bytes =
        static_cast<size_t>(sizeof(pcm_stereo_sample) * buffer_size);
    size_t bytes_left = buffer_size_bytes;

    if (m_mpd_fifo_fd >= 0)
    {
        auto attempts = 0;
        while (bytes_left > 0)
        {
            // Read buffer
            int64_t bytes_read = ::read(m_mpd_fifo_fd, buffer, bytes_left);

            // No bytes left
            if (bytes_read == 0)
            {
                VIS_LOG(vis::LogLevel::WARN, "Could not read any bytes");
                return false;
            }
            // Error reading file. Since non-blocking is set, it's possible
            // there's not enough data yet
            else if (bytes_read == -1)
            {
                auto error_code = errno;

                // EAGAIN means data is not ready yet
                if (error_code == EAGAIN)
                {

                    // Try up to k_read_attempts before quiting
                    if (attempts > k_read_attempts)
                    {
                        VIS_LOG(vis::LogLevel::WARN,
                                "Could not finish reading "
                                "buffer, bytes read: %d    "
                                "buffer size: ",
                                bytes_read, buffer_size_bytes);

                        // zero out buffer
                        memset(buffer, 0, buffer_size_bytes);
                        ::close(m_mpd_fifo_fd);
                        m_mpd_fifo_fd = -1;
                        return false;
                    }

                    nanosleep(&k_read_attempt_sleep_timespec, NULL);
                    ++attempts;
                }
                else
                {
                    VIS_LOG(vis::LogLevel::WARN, "Error reading file: %d %s",
                            error_code, strerror(error_code));
                }
            }
            // Bytes were read fine, continue until buffer is full
            else
            {
                bytes_left -= static_cast<size_t>(bytes_read);
            }
        }

        // Success fully read entire buffer
        return true;
    }

    return false;
}

vis::MpdAudioSource::~MpdAudioSource()
{
    if (m_mpd_fifo_fd >= 0)
    {
        ::close(m_mpd_fifo_fd);
    }
}
<commit_msg>Fixed build on linux<commit_after>/*
 * MpdAudioSource.cpp
 *
 * Created on: Jul 30, 2015
 *     Author: dpayne
 */

#include "Source/MpdAudioSource.h"
#include "Utils/Logger.h"
#include <string.h>
#include <iostream>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#ifdef _LINUX
#include <unistd.h>
#endif

namespace
{
static const int32_t k_read_attempts = 100;
static const int64_t k_read_attempt_sleep_interval_nanosecs =
    1L * 1000000L; // 1 millisecond
static struct timespec k_read_attempt_sleep_timespec = {
    0, k_read_attempt_sleep_interval_nanosecs};
}

vis::MpdAudioSource::MpdAudioSource(const Settings *const settings)
    : m_settings{settings}
{
    open_mpd_fifo();
}

bool vis::MpdAudioSource::open_mpd_fifo()
{
    m_mpd_fifo_fd = ::open(m_settings->get_mpd_fifo_path().c_str(), O_RDONLY);

    if (m_mpd_fifo_fd < 0)
    {
        VIS_LOG(vis::LogLevel::WARN, "Error reading file: %s", strerror(errno));
        m_mpd_fifo_fd = -1;
        return false;
    }

    auto flags = fcntl(m_mpd_fifo_fd, F_GETFL, 0);
    fcntl(m_mpd_fifo_fd, F_SETFL, flags | O_NONBLOCK);

    return true;
}

bool vis::MpdAudioSource::read(pcm_stereo_sample *buffer,
                               const uint32_t buffer_size)
{
    // try to re-open the stream if it has been closed
    if (m_mpd_fifo_fd < 0)
    {
        open_mpd_fifo();
    }

    size_t buffer_size_bytes =
        static_cast<size_t>(sizeof(pcm_stereo_sample) * buffer_size);
    size_t bytes_left = buffer_size_bytes;

    if (m_mpd_fifo_fd >= 0)
    {
        auto attempts = 0;
        while (bytes_left > 0)
        {
            // Read buffer
            int64_t bytes_read = ::read(m_mpd_fifo_fd, buffer, bytes_left);

            // No bytes left
            if (bytes_read == 0)
            {
                VIS_LOG(vis::LogLevel::WARN, "Could not read any bytes");
                return false;
            }
            // Error reading file. Since non-blocking is set, it's possible
            // there's not enough data yet
            else if (bytes_read == -1)
            {
                auto error_code = errno;

                // EAGAIN means data is not ready yet
                if (error_code == EAGAIN)
                {

                    // Try up to k_read_attempts before quiting
                    if (attempts > k_read_attempts)
                    {
                        VIS_LOG(vis::LogLevel::WARN,
                                "Could not finish reading "
                                "buffer, bytes read: %d    "
                                "buffer size: ",
                                bytes_read, buffer_size_bytes);

                        // zero out buffer
                        memset(buffer, 0, buffer_size_bytes);
                        ::close(m_mpd_fifo_fd);
                        m_mpd_fifo_fd = -1;
                        return false;
                    }

                    nanosleep(&k_read_attempt_sleep_timespec, NULL);
                    ++attempts;
                }
                else
                {
                    VIS_LOG(vis::LogLevel::WARN, "Error reading file: %d %s",
                            error_code, strerror(error_code));
                }
            }
            // Bytes were read fine, continue until buffer is full
            else
            {
                bytes_left -= static_cast<size_t>(bytes_read);
            }
        }

        // Success fully read entire buffer
        return true;
    }

    return false;
}

vis::MpdAudioSource::~MpdAudioSource()
{
    if (m_mpd_fifo_fd >= 0)
    {
        ::close(m_mpd_fifo_fd);
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2018 Google, Inc.
 *
 * 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.
 *
 * Authors: Gabe Black
 */

#ifndef __SYSTEMC_CORE_EXT_SC_MODULE_HH__
#define __SYSTEMC_CORE_EXT_SC_MODULE_HH__

#include <vector>

#include "sc_object.hh"
#include "sc_sensitive.hh"
#include "sc_time.hh"

namespace sc_core
{

template <class T>
class sc_in;
template <class T>
class sc_out;
template <class T>
class sc_inout;
template <class T>
class sc_signal_in_if;

class sc_event;
class sc_event_and_list;
class sc_event_or_list;
class sc_module_name;

class sc_bind_proxy
{
  public:
    sc_bind_proxy(const sc_interface &interface);
    sc_bind_proxy(const sc_port_base &port);
};

extern const sc_bind_proxy SC_BIND_PROXY_NIL;

class sc_module : public sc_object
{
  public:
    virtual ~sc_module();

    virtual const char *kind() const;

    void operator () (const sc_bind_proxy &p001,
                      const sc_bind_proxy &p002 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p003 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p004 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p005 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p006 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p007 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p008 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p009 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p010 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p011 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p012 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p013 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p014 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p015 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p016 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p017 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p018 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p019 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p020 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p021 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p022 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p023 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p024 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p025 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p026 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p027 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p028 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p029 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p030 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p031 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p032 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p033 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p034 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p035 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p036 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p037 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p038 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p039 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p040 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p041 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p042 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p043 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p044 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p045 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p046 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p047 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p048 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p049 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p050 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p051 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p052 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p053 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p054 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p055 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p056 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p057 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p058 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p059 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p060 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p061 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p062 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p063 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p064 = SC_BIND_PROXY_NIL);

    virtual const std::vector<sc_object *> &get_child_objects() const;
    virtual const std::vector<sc_event *> &get_child_events() const;

  protected:
    sc_module(const sc_module_name &);
    sc_module();

    void reset_signal_is(const sc_in<bool> &, bool);
    void reset_signal_is(const sc_inout<bool> &, bool);
    void reset_signal_is(const sc_out<bool> &, bool);
    void reset_signal_is(const sc_signal_in_if<bool> &, bool);

    void async_reset_signal_is(const sc_in<bool> &, bool);
    void async_reset_signal_is(const sc_inout<bool> &, bool);
    void async_reset_signal_is(const sc_out<bool> &, bool);
    void async_reset_signal_is(const sc_signal_in_if<bool> &, bool);

    sc_sensitive sensitive;

    void dont_initialize();
    void set_stack_size(size_t);

    void next_trigger();
    void next_trigger(const sc_event &);
    void next_trigger(const sc_event_or_list &);
    void next_trigger(const sc_event_and_list &);
    void next_trigger(const sc_time &);
    void next_trigger(double, sc_time_unit);
    void next_trigger(const sc_time &, const sc_event &);
    void next_trigger(double, sc_time_unit, const sc_event &);
    void next_trigger(const sc_time &, const sc_event_or_list &);
    void next_trigger(double, sc_time_unit, const sc_event_or_list &);
    void next_trigger(const sc_time &, const sc_event_and_list &);
    void next_trigger(double, sc_time_unit, const sc_event_and_list &);

    void wait();
    void wait(int);
    void wait(const sc_event &);
    void wait(const sc_event_or_list &);
    void wait(const sc_event_and_list &);
    void wait(const sc_time &);
    void wait(double, sc_time_unit);
    void wait(const sc_time &, const sc_event &);
    void wait(double, sc_time_unit, const sc_event &);
    void wait(const sc_time &, const sc_event_or_list &);
    void wait(double, sc_time_unit, const sc_event_or_list &);
    void wait(const sc_time &, const sc_event_and_list &);
    void wait(double, sc_time_unit, const sc_event_and_list &);

    virtual void before_end_of_elaboration() {}
    virtual void end_of_elaboration() {}
    virtual void start_of_simulation() {}
    virtual void end_of_simulation() {}

  private:
    // Disabled
    sc_module(const sc_module &) : sc_object() {};
    sc_module &operator = (const sc_module &) { return *this; }
};

void next_trigger();
void next_trigger(const sc_event &);
void next_trigger(const sc_event_or_list &);
void next_trigger(const sc_event_and_list &);
void next_trigger(const sc_time &);
void next_trigger(double, sc_time_unit);
void next_trigger(const sc_time &, const sc_event &);
void next_trigger(double, sc_time_unit, const sc_event &);
void next_trigger(const sc_time &, const sc_event_or_list &);
void next_trigger(double, sc_time_unit, const sc_event_or_list &);
void next_trigger(const sc_time &, const sc_event_and_list &);
void next_trigger(double, sc_time_unit, const sc_event_and_list &);

void wait();
void wait(int);
void wait(const sc_event &);
void wait(const sc_event_or_list &);
void wait(const sc_event_and_list &);
void wait(const sc_time &);
void wait(double, sc_time_unit);
void wait(const sc_time &, const sc_event &);
void wait(double, sc_time_unit, const sc_event &);
void wait(const sc_time &, const sc_event_or_list &);
void wait(double, sc_time_unit, const sc_event_or_list &);
void wait(const sc_time &, const sc_event_and_list &);
void wait(double, sc_time_unit, const sc_event_and_list &);

#define SC_MODULE(name) struct name : ::sc_core::sc_module

#define SC_CTOR(name) \
    typedef name SC_CURRENT_USER_MODULE; \
    name(::sc_core::sc_module_name)

#define SC_HAS_PROCESS(name) typedef name SC_CURRENT_USER_MODULE

#define SC_METHOD(name) /* Implementation defined */
#define SC_THREAD(name) /* Implementation defined */
#define SC_CTHREAD(name, clk) /* Implementation defined */

const char *sc_gen_unique_name(const char *);

typedef sc_module sc_behavior;
typedef sc_module sc_channel;

bool sc_start_of_simulation_invoked();
bool sc_end_of_simulation_invoked();

} // namespace sc_core

#endif  //__SYSTEMC_EXT_CORE_SC_MODULE_HH__
<commit_msg>systemc: Add the deprecated sc_module::end_module function.<commit_after>/*
 * Copyright 2018 Google, Inc.
 *
 * 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.
 *
 * Authors: Gabe Black
 */

#ifndef __SYSTEMC_CORE_EXT_SC_MODULE_HH__
#define __SYSTEMC_CORE_EXT_SC_MODULE_HH__

#include <vector>

#include "sc_object.hh"
#include "sc_sensitive.hh"
#include "sc_time.hh"

namespace sc_core
{

template <class T>
class sc_in;
template <class T>
class sc_out;
template <class T>
class sc_inout;
template <class T>
class sc_signal_in_if;

class sc_event;
class sc_event_and_list;
class sc_event_or_list;
class sc_module_name;

class sc_bind_proxy
{
  public:
    sc_bind_proxy(const sc_interface &interface);
    sc_bind_proxy(const sc_port_base &port);
};

extern const sc_bind_proxy SC_BIND_PROXY_NIL;

class sc_module : public sc_object
{
  public:
    virtual ~sc_module();

    virtual const char *kind() const;

    void operator () (const sc_bind_proxy &p001,
                      const sc_bind_proxy &p002 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p003 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p004 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p005 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p006 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p007 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p008 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p009 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p010 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p011 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p012 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p013 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p014 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p015 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p016 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p017 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p018 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p019 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p020 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p021 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p022 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p023 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p024 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p025 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p026 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p027 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p028 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p029 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p030 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p031 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p032 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p033 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p034 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p035 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p036 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p037 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p038 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p039 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p040 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p041 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p042 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p043 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p044 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p045 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p046 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p047 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p048 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p049 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p050 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p051 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p052 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p053 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p054 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p055 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p056 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p057 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p058 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p059 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p060 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p061 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p062 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p063 = SC_BIND_PROXY_NIL,
                      const sc_bind_proxy &p064 = SC_BIND_PROXY_NIL);

    virtual const std::vector<sc_object *> &get_child_objects() const;
    virtual const std::vector<sc_event *> &get_child_events() const;

  protected:
    sc_module(const sc_module_name &);
    sc_module();

    /* Deprecated, but used in the regression tests. */
    void end_module() {}

    void reset_signal_is(const sc_in<bool> &, bool);
    void reset_signal_is(const sc_inout<bool> &, bool);
    void reset_signal_is(const sc_out<bool> &, bool);
    void reset_signal_is(const sc_signal_in_if<bool> &, bool);

    void async_reset_signal_is(const sc_in<bool> &, bool);
    void async_reset_signal_is(const sc_inout<bool> &, bool);
    void async_reset_signal_is(const sc_out<bool> &, bool);
    void async_reset_signal_is(const sc_signal_in_if<bool> &, bool);

    sc_sensitive sensitive;

    void dont_initialize();
    void set_stack_size(size_t);

    void next_trigger();
    void next_trigger(const sc_event &);
    void next_trigger(const sc_event_or_list &);
    void next_trigger(const sc_event_and_list &);
    void next_trigger(const sc_time &);
    void next_trigger(double, sc_time_unit);
    void next_trigger(const sc_time &, const sc_event &);
    void next_trigger(double, sc_time_unit, const sc_event &);
    void next_trigger(const sc_time &, const sc_event_or_list &);
    void next_trigger(double, sc_time_unit, const sc_event_or_list &);
    void next_trigger(const sc_time &, const sc_event_and_list &);
    void next_trigger(double, sc_time_unit, const sc_event_and_list &);

    void wait();
    void wait(int);
    void wait(const sc_event &);
    void wait(const sc_event_or_list &);
    void wait(const sc_event_and_list &);
    void wait(const sc_time &);
    void wait(double, sc_time_unit);
    void wait(const sc_time &, const sc_event &);
    void wait(double, sc_time_unit, const sc_event &);
    void wait(const sc_time &, const sc_event_or_list &);
    void wait(double, sc_time_unit, const sc_event_or_list &);
    void wait(const sc_time &, const sc_event_and_list &);
    void wait(double, sc_time_unit, const sc_event_and_list &);

    virtual void before_end_of_elaboration() {}
    virtual void end_of_elaboration() {}
    virtual void start_of_simulation() {}
    virtual void end_of_simulation() {}

  private:
    // Disabled
    sc_module(const sc_module &) : sc_object() {};
    sc_module &operator = (const sc_module &) { return *this; }
};

void next_trigger();
void next_trigger(const sc_event &);
void next_trigger(const sc_event_or_list &);
void next_trigger(const sc_event_and_list &);
void next_trigger(const sc_time &);
void next_trigger(double, sc_time_unit);
void next_trigger(const sc_time &, const sc_event &);
void next_trigger(double, sc_time_unit, const sc_event &);
void next_trigger(const sc_time &, const sc_event_or_list &);
void next_trigger(double, sc_time_unit, const sc_event_or_list &);
void next_trigger(const sc_time &, const sc_event_and_list &);
void next_trigger(double, sc_time_unit, const sc_event_and_list &);

void wait();
void wait(int);
void wait(const sc_event &);
void wait(const sc_event_or_list &);
void wait(const sc_event_and_list &);
void wait(const sc_time &);
void wait(double, sc_time_unit);
void wait(const sc_time &, const sc_event &);
void wait(double, sc_time_unit, const sc_event &);
void wait(const sc_time &, const sc_event_or_list &);
void wait(double, sc_time_unit, const sc_event_or_list &);
void wait(const sc_time &, const sc_event_and_list &);
void wait(double, sc_time_unit, const sc_event_and_list &);

#define SC_MODULE(name) struct name : ::sc_core::sc_module

#define SC_CTOR(name) \
    typedef name SC_CURRENT_USER_MODULE; \
    name(::sc_core::sc_module_name)

#define SC_HAS_PROCESS(name) typedef name SC_CURRENT_USER_MODULE

#define SC_METHOD(name) /* Implementation defined */
#define SC_THREAD(name) /* Implementation defined */
#define SC_CTHREAD(name, clk) /* Implementation defined */

const char *sc_gen_unique_name(const char *);

typedef sc_module sc_behavior;
typedef sc_module sc_channel;

bool sc_start_of_simulation_invoked();
bool sc_end_of_simulation_invoked();

} // namespace sc_core

#endif  //__SYSTEMC_EXT_CORE_SC_MODULE_HH__
<|endoftext|>


<commit_before>//
// Created by Danni on 09.06.15.
//

#include "TweeCompiler.h"
#include "ZAssemblyGenerator.h"
#include "exceptions.h"
#include <sstream>
#include <iostream>
#include <Passage/Body/Link.h>
#include <Passage/Body/Text.h>
#include <Passage/Body/FormattedText.h>
#include <Passage/Body/Variable.h>

using namespace std;

static const string PASSAGE_GLOB = "PASSAGE_PTR",
        JUMP_TABLE_LABEL = "JUMP_TABLE_START",
        JUMP_TABLE_END_LABEL = "JUMP_TABLE_END",
        MAIN_ROUTINE = "main",
        USER_INPUT = "USER_INPUT",
        READ_BEGIN = "READ_BEGIN";

static const unsigned int ZSCII_NUM_OFFSET = 49;

//#define ZAS_DEBUG

void maskString(std::string& string) {
    std::replace( string.begin(), string.end(), ' ', '_');
}

string routineNameForPassageName(std::string passageName) {
    stringstream ss;
    maskString(passageName);
    ss << "R_" << passageName;
    return ss.str();
}

string routineNameForPassage(Passage& passage) {
    return routineNameForPassageName(passage.getHead().getName());
}

string labelForPassage(Passage& passage) {
    stringstream ss;
    string passageName = passage.getHead().getName();
    maskString(passageName);
    ss << "L_" << passageName;
    return ss.str();
}

void TweeCompiler::compile(TweeFile &tweeFile, std::ostream &out) {
    ZAssemblyGenerator assgen(out);
    vector<Passage> passages = tweeFile.getPassages();

    {
        int i = 0;
        for (auto passage = passages.begin(); passage != passages.end(); ++passage) {
            passageName2id[passage->getHead().getName()] = i;
            i++;
        }
    }

    // main routine
    {
        // globals
        assgen.addGlobal(PASSAGE_GLOB)
                .addGlobal(USER_INPUT);

        // call start routine first
        assgen.addRoutine(MAIN_ROUTINE)
                .markStart()
                .call(routineNameForPassageName("start"), PASSAGE_GLOB)
                .addLabel(JUMP_TABLE_LABEL);

        for(auto passage = passages.begin(); passage != passages.end(); ++passage) {
            int passageId = passageName2id.at(passage->getHead().getName());

            assgen.jumpEquals(ZAssemblyGenerator::makeArgs({std::to_string(passageId), PASSAGE_GLOB}), labelForPassage(*passage));
        }

        for(auto passage = passages.begin(); passage != passages.end(); ++passage) {
            assgen.addLabel(labelForPassage(*passage))
                    .call(routineNameForPassage(*passage), PASSAGE_GLOB)
                    .jump(JUMP_TABLE_LABEL);
        }

        assgen.addLabel(JUMP_TABLE_END_LABEL);

        assgen.quit();
    }

    // passage routines
    {
        for(auto passage = passages.begin(); passage != passages.end(); ++passage) {
            const vector<unique_ptr<BodyPart>>& bodyParts = passage->getBody().getBodyParts();

            // declare passage routine
            assgen.addRoutine(routineNameForPassage(*passage));

            assgen.println(string("***** ") + passage->getHead().getName() + string(" *****"));

            //  print passage contents
            for(auto it = bodyParts.begin(); it != bodyParts.end(); it++) {
                BodyPart* bodyPart = it->get();
                if(Text* text = dynamic_cast<Text*>(bodyPart)) {
                    assgen.print(text->getContent());
                } else if (FormattedText * formText = dynamic_cast<FormattedText *>(bodyPart)) {
                    assgen.setTextStyle(formText->isItalic(), formText->isBold(), formText->isUnderlined());
                    assgen.print(formText->getContent());
                    assgen.setTextStyle(false, false, false);
                } else if (Variable * variable = dynamic_cast<Variable *>(bodyPart)) {
                    assgen.variable(variable->getName());
                }
            }

            assgen.newline();

            vector<Link*> links;
            // get links from passage
            for(auto it = bodyParts.begin(); it != bodyParts.end(); ++it)
            {
                BodyPart* bodyPart = it->get();
                if(Link* link = dynamic_cast<Link*>(bodyPart)) {
                    links.push_back(link);
                }
            }

            // present choices to user
            assgen.println("Select one of the following options");
            int i = 1;
            for (auto link = links.begin(); link != links.end(); link++) {
                assgen.println(string("    ") + to_string(i) + string(") ") + (*link)->getTarget() );
                i++;
            }

            assgen.addLabel(READ_BEGIN);

            // read user input
            assgen.read_char(USER_INPUT);

            // jump to according link selection
            i = 0;
            for (auto link = links.begin(); link != links.end(); link++) {
                string label = string("L") + to_string(i);
                assgen.jumpEquals(ZAssemblyGenerator::makeArgs({to_string(ZSCII_NUM_OFFSET + i), USER_INPUT}), label);

                i++;
            }

            // no proper selection was made
            assgen.jump(READ_BEGIN);

            i = 0;
            for (auto link = links.begin(); link != links.end(); link++) {
                string label = string("L") + to_string(i);
                try {
                    int targetPassageId = passageName2id.at((*link)->getTarget());
                    assgen.addLabel(label);
                    #ifdef ZAS_DEBUG
                    assgen.print(string("selected ") + to_string(targetPassageId) );
                    #endif
                    assgen.ret(to_string(targetPassageId));
                } catch (const out_of_range &err) {
                    cerr << "could not find passage for link target \"" << (*link)->getTarget() << "\"" << endl;
                    throw TweeDocumentException();
                }
                i++;
            }
        }
    }
}
<commit_msg>Update TweeCompiler.cpp<commit_after>//
// Created by Danni on 09.06.15.
//

#include "TweeCompiler.h"
#include "ZAssemblyGenerator.h"
#include "exceptions.h"
#include <sstream>
#include <iostream>
#include <Passage/Body/Link.h>
#include <Passage/Body/Text.h>
#include <Passage/Body/Newline.h>
#include <Passage/Body/Variable.h>

using namespace std;

static const string PASSAGE_GLOB = "PASSAGE_PTR",
        JUMP_TABLE_LABEL = "JUMP_TABLE_START",
        JUMP_TABLE_END_LABEL = "JUMP_TABLE_END",
        MAIN_ROUTINE = "main",
        USER_INPUT = "USER_INPUT",
        READ_BEGIN = "READ_BEGIN";

static const unsigned int ZSCII_NUM_OFFSET = 49;

//#define ZAS_DEBUG

void maskString(std::string& string) {
    std::replace( string.begin(), string.end(), ' ', '_');
}

string routineNameForPassageName(std::string passageName) {
    stringstream ss;
    maskString(passageName);
    ss << "R_" << passageName;
    return ss.str();
}

string routineNameForPassage(Passage& passage) {
    return routineNameForPassageName(passage.getHead().getName());
}

string labelForPassage(Passage& passage) {
    stringstream ss;
    string passageName = passage.getHead().getName();
    maskString(passageName);
    ss << "L_" << passageName;
    return ss.str();
}

void TweeCompiler::compile(TweeFile &tweeFile, std::ostream &out) {
    ZAssemblyGenerator assgen(out);
    vector<Passage> passages = tweeFile.getPassages();

    {
        int i = 0;
        for (auto passage = passages.begin(); passage != passages.end(); ++passage) {
            passageName2id[passage->getHead().getName()] = i;
            i++;
        }
    }

    // main routine
    {
        // globals
        assgen.addGlobal(PASSAGE_GLOB)
                .addGlobal(USER_INPUT);

        // call start routine first
        assgen.addRoutine(MAIN_ROUTINE)
                .markStart()
                .call(routineNameForPassageName("start"), PASSAGE_GLOB)
                .addLabel(JUMP_TABLE_LABEL);

        for(auto passage = passages.begin(); passage != passages.end(); ++passage) {
            int passageId = passageName2id.at(passage->getHead().getName());

            assgen.jumpEquals(ZAssemblyGenerator::makeArgs({std::to_string(passageId), PASSAGE_GLOB}), labelForPassage(*passage));
        }

        for(auto passage = passages.begin(); passage != passages.end(); ++passage) {
            assgen.addLabel(labelForPassage(*passage))
                    .call(routineNameForPassage(*passage), PASSAGE_GLOB)
                    .jump(JUMP_TABLE_LABEL);
        }

        assgen.addLabel(JUMP_TABLE_END_LABEL);

        assgen.quit();
    }

    // passage routines
    {
        for(auto passage = passages.begin(); passage != passages.end(); ++passage) {
            const vector<unique_ptr<BodyPart>>& bodyParts = passage->getBody().getBodyParts();

            // declare passage routine
            assgen.addRoutine(routineNameForPassage(*passage));

            assgen.println(string("***** ") + passage->getHead().getName() + string(" *****"));

            //  print passage contents
            for(auto it = bodyParts.begin(); it != bodyParts.end(); it++) {
                BodyPart* bodyPart = it->get();
                if(Text* text = dynamic_cast<Text*>(bodyPart)) {
                    assgen.print(text->getContent());
                } else if(Newline* text = dynamic_cast<Newline*>(bodyPart)) {
                    assgen.newline();
                } else if (Variable * variable = dynamic_cast<Variable *>(bodyPart)) {
                    assgen.variable(variable->getName());
                }
            }

            assgen.newline();

            vector<Link*> links;
            // get links from passage
            for(auto it = bodyParts.begin(); it != bodyParts.end(); ++it)
            {
                BodyPart* bodyPart = it->get();
                if(Link* link = dynamic_cast<Link*>(bodyPart)) {
                    links.push_back(link);
                }
            }

            // present choices to user
            assgen.println("Select one of the following options");
            int i = 1;
            for (auto link = links.begin(); link != links.end(); link++) {
                assgen.println(string("    ") + to_string(i) + string(") ") + (*link)->getTarget() );
                i++;
            }

            assgen.addLabel(READ_BEGIN);

            // read user input
            assgen.read_char(USER_INPUT);

            // jump to according link selection
            i = 0;
            for (auto link = links.begin(); link != links.end(); link++) {
                string label = string("L") + to_string(i);
                assgen.jumpEquals(ZAssemblyGenerator::makeArgs({to_string(ZSCII_NUM_OFFSET + i), USER_INPUT}), label);

                i++;
            }

            // no proper selection was made
            assgen.jump(READ_BEGIN);

            i = 0;
            for (auto link = links.begin(); link != links.end(); link++) {
                string label = string("L") + to_string(i);
                try {
                    int targetPassageId = passageName2id.at((*link)->getTarget());
                    assgen.addLabel(label);
                    #ifdef ZAS_DEBUG
                    assgen.print(string("selected ") + to_string(targetPassageId) );
                    #endif
                    assgen.ret(to_string(targetPassageId));
                } catch (const out_of_range &err) {
                    cerr << "could not find passage for link target \"" << (*link)->getTarget() << "\"" << endl;
                    throw TweeDocumentException();
                }
                i++;
            }
        }
    }
}
<|endoftext|>


<commit_before>/**
 * \file TransistorClassAFilter.cpp
 */

#include "TransistorClassAFilter.h"

#include <cassert>

#include <ATK/Utility/SimplifiedVectorizedNewtonRaphson.h>
#include <ATK/Utility/VectorizedNewtonRaphson.h>

namespace ATK
{
  template <typename DataType_>
  class TransistorClassAFilter<DataType_>::TransistorClassAFunction
  {
    const DataType_ Rp;
    const DataType_ Rg1;
    const DataType_ Rg2;
    const DataType_ Ro;
    const DataType_ Rk;
    const DataType_ VBias;
    const DataType_ Cg;
    const DataType_ Co;
    const DataType_ Ck;

    const DataType_ Is;
    const DataType_ Vt;
    const DataType_ Br;
    const DataType_ Bf;

    DataType ickeq;
    DataType icgeq;
    DataType icoeq;

    DataType_ Lb(const std::pair<DataType_, DataType_>& exp)
    {
      return Is * ((exp.first - 1) / Bf + (exp.second - 1) / Br);
    }

    DataType_ Lb_Vbe(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * (exp.first / Bf + exp.second / Br);
    }

    DataType_ Lb_Vce(const std::pair<DataType_, DataType_>& exp)
    {
      return -Is / Vt * (exp.second / Br);
    }

    DataType_ Lc(const std::pair<DataType_, DataType_>& exp)
    {
      return Is * ((exp.first - exp.second) - (exp.second - 1) / Br);
    }

    DataType_ Lc_Vbe(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * ((exp.first - exp.second) - exp.second / Br);
    }

    DataType_ Lc_Vce(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * (exp.second + exp.second / Br);
    }

  public:
    typedef DataType_ DataType;
    typedef Eigen::Matrix<DataType, 4, 1> Vector;
    typedef Eigen::Matrix<DataType, 4, 4> Matrix;

    std::pair<DataType, DataType> exp_y0;

    TransistorClassAFunction(DataType dt, DataType Rp, DataType Rg1, DataType Rg2, DataType Ro, DataType Rk, DataType VBias, DataType Cg, DataType Co, DataType Ck, DataType Is, DataType Vt, DataType Br, DataType Bf, const std::vector<DataType>& default_output)
    :Rp(Rp), Rg1(Rg1), Rg2(Rg2), Ro(Ro), Rk(Rk), VBias(VBias), Cg(2 / dt * Cg), Co(2 / dt * Co), Ck(2 / dt * Ck), Is(Is), Vt(Vt), Br(Br), Bf(Bf), ickeq(2 / dt * Ck * default_output[1]), icgeq(2 / dt * -Cg * default_output[4]), icoeq(-2 / dt * Co * default_output[2])
    {
    }

    Vector estimate(int64_t i, const DataType* const * ATK_RESTRICT input, DataType* const * ATK_RESTRICT output)
    {
      Vector y0 = Vector::Zero();
      for(int j = 0; j < 4; ++j)
      {
        y0.data()[j] = output[j][i-1];
      }

      return y0;
    }

    void update_state(int64_t i, const DataType* const * ATK_RESTRICT input, DataType* const * ATK_RESTRICT output)
    {
      ickeq = 2 * Ck * output[1][i] - ickeq;
      icgeq = 2 * Cg * (input[0][i] - output[4][i]) - icgeq;
      icoeq = -2 * Co * output[2][i] - icoeq;
    }

    std::pair<Vector, Matrix> operator()(int64_t i, const DataType* const * ATK_RESTRICT input, DataType* const * ATK_RESTRICT output, const Vector& y1)
    {
      std::pair<DataType, DataType> exp_y1 = std::make_pair(std::exp((y1(3) - y1(0)) / Vt), std::exp((y1(3) - y1(2)) / Vt));

      auto Ib = Lb(exp_y1);
      auto Ic = Lc(exp_y1);

      auto Ib_Vbe = Lb_Vbe(exp_y1);
      auto Ib_Vbc = Lb_Vce(exp_y1);

      auto Ic_Vbe = Lc_Vbe(exp_y1);
      auto Ic_Vbc = Lc_Vce(exp_y1);

      auto f1 = Ib + Ic + ickeq - y1(0) * (1/Rk + Ck);
      auto f2 = icoeq + (y1(1) + y1(2)) / Ro + y1(1) * Co;
      auto f3 = Ic + (y1(1) + y1(2)) / Ro + (y1(2) - VBias) / Rp;
      auto f4 = Ib + icgeq + y1(3) / Rg2 + (y1(3) - VBias) / Rg1 + (y1(3) - input[0][i]) * Cg;

      Vector F(Vector::Zero());
      F << f1,
           f2,
           f3,
           f4;

      Matrix M(Matrix::Zero());
      M << -(Ib_Vbe + Ic_Vbe) - (1/Rk + Ck), 0, -(Ib_Vbc + Ic_Vbc), (Ib_Vbe + Ic_Vbe + Ib_Vbc + Ic_Vbc),
            0, 1/Ro + Co, 1/Ro, 0,
            -Ic_Vbe, 1/Ro, -Ic_Vbc + 1/Ro + 1/Rp, (Ic_Vbe + Ic_Vbc),
            -Ib_Vbe, 0, -Ib_Vbc, (Ib_Vbc + Ib_Vbe) + 1/Rg2 + 1/Rg1 + Cg;

      return std::make_pair(F, M);
    }

  };

  template <typename DataType_>
  class TransistorClassAInitialFunction
  {
    const DataType_ Rp;
    const DataType_ Rg1;
    const DataType_ Rg2;
    const DataType_ Ro;
    const DataType_ Rk;
    const DataType_ VBias;

    const DataType_ Is;
    const DataType_ Vt;
    const DataType_ Br;
    const DataType_ Bf;

    DataType_ Lb(const std::pair<DataType_, DataType_>& exp)
    {
      return Is * ((exp.first - 1) / Bf + (exp.second - 1) / Br);
    }

    DataType_ Lb_Vbe(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * (exp.first / Bf + exp.second / Br);
    }

    DataType_ Lb_Vce(const std::pair<DataType_, DataType_>& exp)
    {
      return -Is / Vt * (exp.second / Br);
    }

    DataType_ Lc(const std::pair<DataType_, DataType_>& exp)
    {
      return Is * ((exp.first - exp.second) - (exp.second - 1) / Br);
    }

    DataType_ Lc_Vbe(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * ((exp.first - exp.second) - exp.second / Br);
    }

    DataType_ Lc_Vce(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * (exp.second + exp.second / Br);
    }

  public:
    typedef DataType_ DataType;
    typedef Eigen::Matrix<DataType, 3, 1> Vector;
    typedef Eigen::Matrix<DataType, 3, 3> Matrix;

    TransistorClassAInitialFunction(DataType Rp, DataType Rg1, DataType Rg2, DataType Ro, DataType Rk, DataType VBias, DataType Is, DataType Vt, DataType Br, DataType Bf)
    :Rp(Rp), Rg1(Rg1), Rg2(Rg2), Ro(Ro), Rk(Rk), VBias(VBias), Is(Is), Vt(Vt), Br(Br), Bf(Bf)
    {
    }

    std::pair<Vector, Matrix> operator()(const Vector& y1)
    {
      std::pair<DataType, DataType> exp_y1 = std::make_pair(std::exp((y1(2) - y1(1)) / Vt), std::exp((y1(2) - y1(0)) / Vt));

      auto Ib = Lb(exp_y1);
      auto Ic = Lc(exp_y1);

      auto Ib_Vbe = Lb_Vbe(exp_y1);
      auto Ib_Vbc = Lb_Vce(exp_y1);

      auto Ic_Vbe = Lc_Vbe(exp_y1);
      auto Ic_Vbc = Lc_Vce(exp_y1);

      Vector F(Vector::Zero());
      auto R = 1/(1/Rg1 + 1/Rg2);
      F << y1(0) - VBias + Ic * Rp, y1(1) - (Ib + Ic) * Rk, Ib * R + y1(2) - VBias / Rg1 * R;

      Matrix M(Matrix::Zero());
      M << 1 - Ic_Vbc * Rp, -Ic_Vbe * Rp, (Ic_Vbe + Ic_Vbc) * Rp,
           (Ib_Vbc + Ic_Vbc) * Rk, 1 + (Ib_Vbe + Ic_Vbe + Ib_Vbc + Ic_Vbc) * Rk, -(Ib_Vbe + Ic_Vbe + Ib_Vbc + Ic_Vbc) * Rk,
           -Ib_Vbc * R, -Ib_Vbe * R, 1 + (Ib_Vbe + Ib_Vbc) * R;

      return std::make_pair(F, M);
    }
  };

  template <typename DataType>
  TransistorClassAFilter<DataType>::TransistorClassAFilter(DataType Rp, DataType Rg1, DataType Rg2, DataType Ro, DataType Rk, DataType VBias, DataType Cg, DataType Co, DataType Ck, DataType Is, DataType Vt, DataType Br, DataType Bf)
    :Parent(1, 5), Rp(Rp), Rg1(Rg1), Rg2(Rg2), Ro(Ro), Rk(Rk), VBias(VBias), Cg(Cg), Co(Co), Ck(Ck), Is(Is), Vt(Vt), Br(Br), Bf(Bf)
  {
    input_delay = output_delay = 1;
  }

  template <typename DataType>
  TransistorClassAFilter<DataType>::TransistorClassAFilter(TransistorClassAFilter&& other)
  :Parent(std::move(other)), Rp(other.Rp), Rg1(other.Rg1), Rg2(other.Rg2), Ro(other.Ro), Rk(other.Rk), VBias(other.VBias), Cg(other.Cg), Co(other.Co), Ck(other.Ck), Is(other.Is), Vt(other.Vt), Br(other.Br), Bf(other.Bf)
  {

  }

  template <typename DataType>
  TransistorClassAFilter<DataType>::~TransistorClassAFilter()
  {
  }

  template<typename DataType_>
  void TransistorClassAFilter<DataType_>::setup()
  {
    Parent::setup();
    optimizer.reset(new VectorizedNewtonRaphson<TransistorClassAFunction, 4, nb_max_iter, true>(TransistorClassAFunction(static_cast<DataType>(1. / input_sampling_rate),
                    Rp, Rg1, Rg2, Ro, Rk, //R
                    VBias, // VBias
                    Cg, Co, Ck, // C
                    Is, Vt, Br, Bf, // transistor
                    default_output)));
  }

  template<typename DataType_>
  void TransistorClassAFilter<DataType_>::full_setup()
  {
    Parent::full_setup();
    // setup default_output

    SimplifiedVectorizedNewtonRaphson<TransistorClassAInitialFunction<DataType_>, 3, 10> custom(TransistorClassAInitialFunction<DataType_>(
                    Rp, Rg1, Rg2, Ro, Rk, //R
                    VBias, // VBias
                    Is, Vt, Br, Bf // transistor
                    ));

    auto stable = custom.optimize();

    default_output[0] = 0;
    default_output[1] = stable(1);
    default_output[2] = -stable(0);
    default_output[3] = stable(0);
    default_output[4] = stable(2);

    setup();
  }

  template<typename DataType_>
  void TransistorClassAFilter<DataType_>::process_impl(int64_t size) const
  {
    assert(input_sampling_rate == output_sampling_rate);

    for(int64_t i = 0; i < size; ++i)
    {
      optimizer->optimize(i, converted_inputs.data(), outputs.data() + 1);
      outputs[0][i] = outputs[2][i] + outputs[3][i];
      optimizer->get_function().update_state(i, converted_inputs.data(), outputs.data());
    }
  }

  template<typename DataType_>
  TransistorClassAFilter<DataType_> TransistorClassAFilter<DataType_>::build_standard_filter()
  {
    return TransistorClassAFilter<DataType_>(1e3, 15e3, 1.5e3, 22e3, 100, //R
                                                 5, // VBias
                                                 3.3e-6, 1e-6, 160e-6, // C
                                                 1e-12, 26e-3, 1, 100 // transistor
);
  }

  template class TransistorClassAFilter<float>;
  template class TransistorClassAFilter<double>;
}
<commit_msg>Don't need that call<commit_after>/**
 * \file TransistorClassAFilter.cpp
 */

#include "TransistorClassAFilter.h"

#include <cassert>

#include <ATK/Utility/SimplifiedVectorizedNewtonRaphson.h>
#include <ATK/Utility/VectorizedNewtonRaphson.h>

namespace ATK
{
  template <typename DataType_>
  class TransistorClassAFilter<DataType_>::TransistorClassAFunction
  {
    const DataType_ Rp;
    const DataType_ Rg1;
    const DataType_ Rg2;
    const DataType_ Ro;
    const DataType_ Rk;
    const DataType_ VBias;
    const DataType_ Cg;
    const DataType_ Co;
    const DataType_ Ck;

    const DataType_ Is;
    const DataType_ Vt;
    const DataType_ Br;
    const DataType_ Bf;

    DataType ickeq;
    DataType icgeq;
    DataType icoeq;

    DataType_ Lb(const std::pair<DataType_, DataType_>& exp)
    {
      return Is * ((exp.first - 1) / Bf + (exp.second - 1) / Br);
    }

    DataType_ Lb_Vbe(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * (exp.first / Bf + exp.second / Br);
    }

    DataType_ Lb_Vce(const std::pair<DataType_, DataType_>& exp)
    {
      return -Is / Vt * (exp.second / Br);
    }

    DataType_ Lc(const std::pair<DataType_, DataType_>& exp)
    {
      return Is * ((exp.first - exp.second) - (exp.second - 1) / Br);
    }

    DataType_ Lc_Vbe(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * ((exp.first - exp.second) - exp.second / Br);
    }

    DataType_ Lc_Vce(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * (exp.second + exp.second / Br);
    }

  public:
    typedef DataType_ DataType;
    typedef Eigen::Matrix<DataType, 4, 1> Vector;
    typedef Eigen::Matrix<DataType, 4, 4> Matrix;

    std::pair<DataType, DataType> exp_y0;

    TransistorClassAFunction(DataType dt, DataType Rp, DataType Rg1, DataType Rg2, DataType Ro, DataType Rk, DataType VBias, DataType Cg, DataType Co, DataType Ck, DataType Is, DataType Vt, DataType Br, DataType Bf, const std::vector<DataType>& default_output)
    :Rp(Rp), Rg1(Rg1), Rg2(Rg2), Ro(Ro), Rk(Rk), VBias(VBias), Cg(2 / dt * Cg), Co(2 / dt * Co), Ck(2 / dt * Ck), Is(Is), Vt(Vt), Br(Br), Bf(Bf), ickeq(2 / dt * Ck * default_output[1]), icgeq(2 / dt * -Cg * default_output[4]), icoeq(-2 / dt * Co * default_output[2])
    {
    }

    Vector estimate(int64_t i, const DataType* const * ATK_RESTRICT input, DataType* const * ATK_RESTRICT output)
    {
      Vector y0 = Vector::Zero();
      for(int j = 0; j < 4; ++j)
      {
        y0.data()[j] = output[j][i-1];
      }

      return y0;
    }

    void update_state(int64_t i, const DataType* const * ATK_RESTRICT input, DataType* const * ATK_RESTRICT output)
    {
      ickeq = 2 * Ck * output[1][i] - ickeq;
      icgeq = 2 * Cg * (input[0][i] - output[4][i]) - icgeq;
      icoeq = -2 * Co * output[2][i] - icoeq;
    }

    std::pair<Vector, Matrix> operator()(int64_t i, const DataType* const * ATK_RESTRICT input, DataType* const * ATK_RESTRICT output, const Vector& y1)
    {
      std::pair<DataType, DataType> exp_y1 = std::make_pair(std::exp((y1(3) - y1(0)) / Vt), std::exp((y1(3) - y1(2)) / Vt));

      auto Ib = Lb(exp_y1);
      auto Ic = Lc(exp_y1);

      auto Ib_Vbe = Lb_Vbe(exp_y1);
      auto Ib_Vbc = Lb_Vce(exp_y1);

      auto Ic_Vbe = Lc_Vbe(exp_y1);
      auto Ic_Vbc = Lc_Vce(exp_y1);

      auto f1 = Ib + Ic + ickeq - y1(0) * (1/Rk + Ck);
      auto f2 = icoeq + (y1(1) + y1(2)) / Ro + y1(1) * Co;
      auto f3 = Ic + (y1(1) + y1(2)) / Ro + (y1(2) - VBias) / Rp;
      auto f4 = Ib + icgeq + y1(3) / Rg2 + (y1(3) - VBias) / Rg1 + (y1(3) - input[0][i]) * Cg;

      Vector F(Vector::Zero());
      F << f1,
           f2,
           f3,
           f4;

      Matrix M(Matrix::Zero());
      M << -(Ib_Vbe + Ic_Vbe) - (1/Rk + Ck), 0, -(Ib_Vbc + Ic_Vbc), (Ib_Vbe + Ic_Vbe + Ib_Vbc + Ic_Vbc),
            0, 1/Ro + Co, 1/Ro, 0,
            -Ic_Vbe, 1/Ro, -Ic_Vbc + 1/Ro + 1/Rp, (Ic_Vbe + Ic_Vbc),
            -Ib_Vbe, 0, -Ib_Vbc, (Ib_Vbc + Ib_Vbe) + 1/Rg2 + 1/Rg1 + Cg;

      return std::make_pair(F, M);
    }

  };

  template <typename DataType_>
  class TransistorClassAInitialFunction
  {
    const DataType_ Rp;
    const DataType_ Rg1;
    const DataType_ Rg2;
    const DataType_ Ro;
    const DataType_ Rk;
    const DataType_ VBias;

    const DataType_ Is;
    const DataType_ Vt;
    const DataType_ Br;
    const DataType_ Bf;

    DataType_ Lb(const std::pair<DataType_, DataType_>& exp)
    {
      return Is * ((exp.first - 1) / Bf + (exp.second - 1) / Br);
    }

    DataType_ Lb_Vbe(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * (exp.first / Bf + exp.second / Br);
    }

    DataType_ Lb_Vce(const std::pair<DataType_, DataType_>& exp)
    {
      return -Is / Vt * (exp.second / Br);
    }

    DataType_ Lc(const std::pair<DataType_, DataType_>& exp)
    {
      return Is * ((exp.first - exp.second) - (exp.second - 1) / Br);
    }

    DataType_ Lc_Vbe(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * ((exp.first - exp.second) - exp.second / Br);
    }

    DataType_ Lc_Vce(const std::pair<DataType_, DataType_>& exp)
    {
      return Is / Vt * (exp.second + exp.second / Br);
    }

  public:
    typedef DataType_ DataType;
    typedef Eigen::Matrix<DataType, 3, 1> Vector;
    typedef Eigen::Matrix<DataType, 3, 3> Matrix;

    TransistorClassAInitialFunction(DataType Rp, DataType Rg1, DataType Rg2, DataType Ro, DataType Rk, DataType VBias, DataType Is, DataType Vt, DataType Br, DataType Bf)
    :Rp(Rp), Rg1(Rg1), Rg2(Rg2), Ro(Ro), Rk(Rk), VBias(VBias), Is(Is), Vt(Vt), Br(Br), Bf(Bf)
    {
    }

    std::pair<Vector, Matrix> operator()(const Vector& y1)
    {
      std::pair<DataType, DataType> exp_y1 = std::make_pair(std::exp((y1(2) - y1(1)) / Vt), std::exp((y1(2) - y1(0)) / Vt));

      auto Ib = Lb(exp_y1);
      auto Ic = Lc(exp_y1);

      auto Ib_Vbe = Lb_Vbe(exp_y1);
      auto Ib_Vbc = Lb_Vce(exp_y1);

      auto Ic_Vbe = Lc_Vbe(exp_y1);
      auto Ic_Vbc = Lc_Vce(exp_y1);

      Vector F(Vector::Zero());
      auto R = 1/(1/Rg1 + 1/Rg2);
      F << y1(0) - VBias + Ic * Rp, y1(1) - (Ib + Ic) * Rk, Ib * R + y1(2) - VBias / Rg1 * R;

      Matrix M(Matrix::Zero());
      M << 1 - Ic_Vbc * Rp, -Ic_Vbe * Rp, (Ic_Vbe + Ic_Vbc) * Rp,
           (Ib_Vbc + Ic_Vbc) * Rk, 1 + (Ib_Vbe + Ic_Vbe + Ib_Vbc + Ic_Vbc) * Rk, -(Ib_Vbe + Ic_Vbe + Ib_Vbc + Ic_Vbc) * Rk,
           -Ib_Vbc * R, -Ib_Vbe * R, 1 + (Ib_Vbe + Ib_Vbc) * R;

      return std::make_pair(F, M);
    }
  };

  template <typename DataType>
  TransistorClassAFilter<DataType>::TransistorClassAFilter(DataType Rp, DataType Rg1, DataType Rg2, DataType Ro, DataType Rk, DataType VBias, DataType Cg, DataType Co, DataType Ck, DataType Is, DataType Vt, DataType Br, DataType Bf)
    :Parent(1, 5), Rp(Rp), Rg1(Rg1), Rg2(Rg2), Ro(Ro), Rk(Rk), VBias(VBias), Cg(Cg), Co(Co), Ck(Ck), Is(Is), Vt(Vt), Br(Br), Bf(Bf)
  {
    input_delay = output_delay = 1;
  }

  template <typename DataType>
  TransistorClassAFilter<DataType>::TransistorClassAFilter(TransistorClassAFilter&& other)
  :Parent(std::move(other)), Rp(other.Rp), Rg1(other.Rg1), Rg2(other.Rg2), Ro(other.Ro), Rk(other.Rk), VBias(other.VBias), Cg(other.Cg), Co(other.Co), Ck(other.Ck), Is(other.Is), Vt(other.Vt), Br(other.Br), Bf(other.Bf)
  {

  }

  template <typename DataType>
  TransistorClassAFilter<DataType>::~TransistorClassAFilter()
  {
  }

  template<typename DataType_>
  void TransistorClassAFilter<DataType_>::setup()
  {
    Parent::setup();
    optimizer.reset(new VectorizedNewtonRaphson<TransistorClassAFunction, 4, nb_max_iter, true>(TransistorClassAFunction(static_cast<DataType>(1. / input_sampling_rate),
                    Rp, Rg1, Rg2, Ro, Rk, //R
                    VBias, // VBias
                    Cg, Co, Ck, // C
                    Is, Vt, Br, Bf, // transistor
                    default_output)));
  }

  template<typename DataType_>
  void TransistorClassAFilter<DataType_>::full_setup()
  {
    Parent::full_setup();
    // setup default_output

    SimplifiedVectorizedNewtonRaphson<TransistorClassAInitialFunction<DataType_>, 3, 10> custom(TransistorClassAInitialFunction<DataType_>(
                    Rp, Rg1, Rg2, Ro, Rk, //R
                    VBias, // VBias
                    Is, Vt, Br, Bf // transistor
                    ));

    auto stable = custom.optimize();

    default_output[0] = 0;
    default_output[1] = stable(1);
    default_output[2] = -stable(0);
    default_output[3] = stable(0);
    default_output[4] = stable(2);
  }

  template<typename DataType_>
  void TransistorClassAFilter<DataType_>::process_impl(int64_t size) const
  {
    assert(input_sampling_rate == output_sampling_rate);

    for(int64_t i = 0; i < size; ++i)
    {
      optimizer->optimize(i, converted_inputs.data(), outputs.data() + 1);
      outputs[0][i] = outputs[2][i] + outputs[3][i];
      optimizer->get_function().update_state(i, converted_inputs.data(), outputs.data());
    }
  }

  template<typename DataType_>
  TransistorClassAFilter<DataType_> TransistorClassAFilter<DataType_>::build_standard_filter()
  {
    return TransistorClassAFilter<DataType_>(1e3, 15e3, 1.5e3, 22e3, 100, //R
                                                 5, // VBias
                                                 3.3e-6, 1e-6, 160e-6, // C
                                                 1e-12, 26e-3, 1, 100 // transistor
);
  }

  template class TransistorClassAFilter<float>;
  template class TransistorClassAFilter<double>;
}
<|endoftext|>