<commit_before>// for some reason, we have to include windows.h for this to run
#ifdef _MSC_VER
#include <windows.h>
#endif

#include <wx/wx.h>
#include <audiere.h>
using namespace audiere;

bool TryDevice(const char* name);

enum {
  DEVICE_NEW_DEVICE,
  DEVICE_OPEN_STREAM,
  DEVICE_OPEN_SOUND,
  DEVICE_CREATE_TONE,
  DEVICE_CLOSE,

  STREAM_PLAY,
  STREAM_STOP,
  STREAM_RESET,
  STREAM_REPEAT,
  STREAM_VOLUME,
  STREAM_PAN,
  STREAM_POS,
  STREAM_UPDATE,
};

class StreamFrame : public wxMDIChildFrame {
public:
  StreamFrame(wxMDIParentFrame* parent, wxString& title, OutputStream* stream)
  : wxMDIChildFrame(parent, -1, title)
  {
    m_stream = stream;

    int slider_max = (m_stream->isSeekable() ? m_stream->getLength() : 1);

    m_repeating = new wxCheckBox(this, STREAM_REPEAT, "Repeating");
    m_volume_pan_label = new wxStaticText(this, -1, "Volume - Pan");
    m_volume = new wxSlider(this, STREAM_VOLUME, 100, 0,  100);
    m_pan    = new wxSlider(this, STREAM_PAN,    0, -100, 100);
    m_length_pos_label = new wxStaticText(this, -1, "Length - Pos");
    m_pos    = new wxSlider(this, STREAM_POS,    0, 0, slider_max);

    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(
      new wxButton(this, STREAM_PLAY, "Play"),
      1, wxEXPAND | wxALL, 4);
    sizer->Add(
      new wxButton(this, STREAM_STOP, "Stop"),
      1, wxEXPAND | wxALL, 4);
    sizer->Add(
      new wxButton(this, STREAM_RESET, "Reset"),
      1, wxEXPAND | wxALL, 4);
    sizer->Add(m_repeating, 1, wxEXPAND | wxALL, 4);
    sizer->Add(m_volume_pan_label, 1, wxEXPAND | wxALL, 4);
    sizer->Add(m_volume, 1, wxEXPAND | wxALL, 4);
    sizer->Add(m_pan, 1, wxEXPAND | wxALL, 4);
    sizer->Add(m_length_pos_label, 1, wxEXPAND | wxALL, 4);
    sizer->Add(m_pos, 1, wxEXPAND | wxALL, 4);

    if (!m_stream->isSeekable()) {
      m_pos->Enable(false);
    }

    UpdateVolumePanLabel();
    UpdateLengthPosLabel();

    SetAutoLayout(true);
    SetSizer(sizer);

    sizer->Fit(this);
    sizer->SetSizeHints(this);

    // create a timer to update the current position
    wxTimer* timer = new wxTimer(this, STREAM_UPDATE);
    timer->Start(200);
  }

  void OnPlay() {
    m_stream->play();
  }

  void OnStop() {
    m_stream->stop();
  }

  void OnReset() {
    m_stream->reset();
  }

  void OnRepeat() {
    m_stream->setRepeat(m_repeating->GetValue());
  }

  void OnChangeVolume() {
    m_stream->setVolume(m_volume->GetValue() / 100.0f);
    UpdateVolumePanLabel();
  }

  void OnChangePan() {
    m_stream->setPan(m_pan->GetValue() / 100.0f);
    UpdateVolumePanLabel();
  }

  void OnChangePos() {
    m_stream->setPosition(m_pos->GetValue());
  }

  void OnUpdatePosition() {
    if (m_stream->isSeekable()) {
      m_pos->SetValue(m_stream->getPosition());
    }
    UpdateLengthPosLabel();
  }

  void UpdateVolumePanLabel() {
    wxString label;
    label.Printf(
      "Volume: %1.2f   Pan: %1.2f",
      m_volume->GetValue() / 100.0f,
      m_pan->GetValue() / 100.0f);
    m_volume_pan_label->SetLabel(label);
  }

  void UpdateLengthPosLabel() {
    if (m_stream->isSeekable()) {
      wxString label;
      label.Printf(
        "Length: %d   Pos: %d",
        m_stream->getLength(),
        m_stream->getPosition());
      m_length_pos_label->SetLabel(label);
    } else {
      m_length_pos_label->SetLabel("Unseekable Stream");
    }
  }

private:
  RefPtr<OutputStream> m_stream;

  wxCheckBox*   m_repeating;
  wxStaticText* m_volume_pan_label;
  wxSlider*     m_volume;
  wxSlider*     m_pan;
  wxStaticText* m_length_pos_label;
  wxSlider*     m_pos;

  DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(StreamFrame, wxMDIChildFrame)
  EVT_BUTTON(STREAM_PLAY,  StreamFrame::OnPlay)
  EVT_BUTTON(STREAM_STOP,  StreamFrame::OnStop)
  EVT_BUTTON(STREAM_RESET, StreamFrame::OnReset)

  EVT_CHECKBOX(STREAM_REPEAT, StreamFrame::OnRepeat)

  EVT_COMMAND_SCROLL(STREAM_VOLUME, StreamFrame::OnChangeVolume)
  EVT_COMMAND_SCROLL(STREAM_PAN,    StreamFrame::OnChangePan)
  EVT_COMMAND_SCROLL(STREAM_POS,    StreamFrame::OnChangePos)

  EVT_TIMER(STREAM_UPDATE, StreamFrame::OnUpdatePosition)
END_EVENT_TABLE()

class DeviceFrame : public wxMDIParentFrame {
public:
  DeviceFrame(AudioDevice* device, const wxString& device_name)
  : wxMDIParentFrame(NULL, -1, "Device Window - " + device_name)
  {
    m_device = device;

    wxMenu* fileMenu = new wxMenu();
    fileMenu->Append(DEVICE_NEW_DEVICE,  "&New Device...");
    fileMenu->AppendSeparator();
    fileMenu->Append(DEVICE_OPEN_STREAM, "&Open Stream...");
    fileMenu->Append(DEVICE_OPEN_SOUND,  "Open &Sound...");
    fileMenu->Append(DEVICE_CREATE_TONE, "Create &Tone...");
    fileMenu->AppendSeparator();
    fileMenu->Append(DEVICE_CLOSE,       "&Close Device");

    wxMenuBar* menuBar = new wxMenuBar();
    menuBar->Append(fileMenu, "&Device");
    SetMenuBar(menuBar);
  }

  void OnDeviceNewDevice() {
    wxString name = wxGetTextFromUser(
      "New Device",
      "Enter Device Name",
      "autodetect",
      this);
    if (!name.empty()) {
      if (!TryDevice(name)) {
        wxMessageBox(
          "Could not open audio device: " + name,
          "New Device", wxOK | wxCENTRE, this);
      }
    }
  }

  wxString GetSoundFile() {
    return wxFileSelector(
      "Select a sound file", "", "", "",
      "Sound Files (*.wav,*.ogg,*.mod,*.it,*.xm,*.s3m)|"  \
      "*.wav;*.ogg;*.mod;*.it;*.xm;*.s3m",
      wxOPEN, this);
  }

  void OnDeviceOpenStream() {
    wxString filename(GetSoundFile());
    if (filename.empty()) {
      return;
    }

    OutputStream* stream = m_device->openStream(OpenSampleSource(filename));
    if (!stream) {
      wxMessageBox(
        "Could not open stream: " + filename,
        "Open Stream", wxOK | wxCENTRE, this);
      return;
    }

    // get the basename of the path for the window title
    wxString basename = wxFileNameFromPath(filename);;

    wxString title;
    title.sprintf("Stream: %s", basename.c_str());
    new StreamFrame(this, title, stream);
  }

  void OnDeviceOpenSound() {
    wxString filename(GetSoundFile());
    if (filename.empty()) {
      return;
    }

    OutputStream* stream = OpenSound(m_device.get(), filename);
    if (!stream) {
      wxMessageBox(
        "Could not open sound: " + filename,
        "Open Stream", wxOK | wxCENTRE, this);
      return;
    }

    // get the basename of the path for the window title
    wxString basename = wxFileNameFromPath(filename);;

    wxString title;
    title.sprintf("Sound: %s", basename.c_str());
    new StreamFrame(this, title, stream);
  }

  void OnDeviceCreateTone() {
    int frequency = wxGetNumberFromUser(
      "Value must be between 1 and 30000.", "Enter frequency in Hz",
      "Create Tone", 256, 1, 30000, this);
    if (frequency != -1) {
      OutputStream* stream = m_device->openStream(CreateTone(frequency));
      if (!stream) {
        wxMessageBox(
          "Could not open output stream",
          "Create Tone", wxOK | wxCENTRE, this);
      } else {
        wxString title;
        title.sprintf("Tone: %d Hz", frequency);
        new StreamFrame(this, title, stream);
      }
    }
  }

  void OnDeviceClose() {
    Close();
  }

private:
  RefPtr<AudioDevice> m_device;

  DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(DeviceFrame, wxMDIParentFrame)
  EVT_MENU(DEVICE_NEW_DEVICE,  DeviceFrame::OnDeviceNewDevice)
  EVT_MENU(DEVICE_OPEN_STREAM, DeviceFrame::OnDeviceOpenStream)
  EVT_MENU(DEVICE_OPEN_SOUND,  DeviceFrame::OnDeviceOpenSound)
  EVT_MENU(DEVICE_CREATE_TONE, DeviceFrame::OnDeviceCreateTone)
  EVT_MENU(DEVICE_CLOSE,       DeviceFrame::OnDeviceClose)
END_EVENT_TABLE()

bool TryDevice(const char* name) {
  if (RefPtr<AudioDevice> device = audiere::OpenDevice(name)) {
    DeviceFrame* frame = new DeviceFrame(device.get(), name);
    frame->Show(true);
    return true;
  } else {
    return false;
  }
}

class wxPlayer : public wxApp {
public:
  bool OnInit() {
    bool result = (TryDevice("autodetect") || TryDevice("null"));
    if (!result) {
      wxMessageBox("Could not open output device", "wxPlayer");
    }
    return result;
  }
};

IMPLEMENT_APP(wxPlayer)
<commit_msg>update wxPlayer for new OpenSound API<commit_after>// for some reason, we have to include windows.h for this to run
#ifdef _MSC_VER
#include <windows.h>
#endif

#include <wx/wx.h>
#include <audiere.h>
using namespace audiere;

bool TryDevice(const char* name);

enum {
  DEVICE_NEW_DEVICE,
  DEVICE_OPEN_STREAM,
  DEVICE_OPEN_SOUND,
  DEVICE_CREATE_TONE,
  DEVICE_CLOSE,

  STREAM_PLAY,
  STREAM_STOP,
  STREAM_RESET,
  STREAM_REPEAT,
  STREAM_VOLUME,
  STREAM_PAN,
  STREAM_POS,
  STREAM_UPDATE,
};

class StreamFrame : public wxMDIChildFrame {
public:
  StreamFrame(wxMDIParentFrame* parent, wxString& title, OutputStream* stream)
  : wxMDIChildFrame(parent, -1, title)
  {
    m_stream = stream;

    int slider_max = (m_stream->isSeekable() ? m_stream->getLength() : 1);

    m_repeating = new wxCheckBox(this, STREAM_REPEAT, "Repeating");
    m_volume_pan_label = new wxStaticText(this, -1, "Volume - Pan");
    m_volume = new wxSlider(this, STREAM_VOLUME, 100, 0,  100);
    m_pan    = new wxSlider(this, STREAM_PAN,    0, -100, 100);
    m_length_pos_label = new wxStaticText(this, -1, "Length - Pos");
    m_pos    = new wxSlider(this, STREAM_POS,    0, 0, slider_max);

    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(
      new wxButton(this, STREAM_PLAY, "Play"),
      1, wxEXPAND | wxALL, 4);
    sizer->Add(
      new wxButton(this, STREAM_STOP, "Stop"),
      1, wxEXPAND | wxALL, 4);
    sizer->Add(
      new wxButton(this, STREAM_RESET, "Reset"),
      1, wxEXPAND | wxALL, 4);
    sizer->Add(m_repeating, 1, wxEXPAND | wxALL, 4);
    sizer->Add(m_volume_pan_label, 1, wxEXPAND | wxALL, 4);
    sizer->Add(m_volume, 1, wxEXPAND | wxALL, 4);
    sizer->Add(m_pan, 1, wxEXPAND | wxALL, 4);
    sizer->Add(m_length_pos_label, 1, wxEXPAND | wxALL, 4);
    sizer->Add(m_pos, 1, wxEXPAND | wxALL, 4);

    if (!m_stream->isSeekable()) {
      m_pos->Enable(false);
    }

    UpdateVolumePanLabel();
    UpdateLengthPosLabel();

    SetAutoLayout(true);
    SetSizer(sizer);

    sizer->Fit(this);
    sizer->SetSizeHints(this);

    // create a timer to update the current position
    wxTimer* timer = new wxTimer(this, STREAM_UPDATE);
    timer->Start(200);
  }

  void OnPlay() {
    m_stream->play();
  }

  void OnStop() {
    m_stream->stop();
  }

  void OnReset() {
    m_stream->reset();
  }

  void OnRepeat() {
    m_stream->setRepeat(m_repeating->GetValue());
  }

  void OnChangeVolume() {
    m_stream->setVolume(m_volume->GetValue() / 100.0f);
    UpdateVolumePanLabel();
  }

  void OnChangePan() {
    m_stream->setPan(m_pan->GetValue() / 100.0f);
    UpdateVolumePanLabel();
  }

  void OnChangePos() {
    m_stream->setPosition(m_pos->GetValue());
  }

  void OnUpdatePosition() {
    if (m_stream->isSeekable()) {
      m_pos->SetValue(m_stream->getPosition());
    }
    UpdateLengthPosLabel();
  }

  void UpdateVolumePanLabel() {
    wxString label;
    label.Printf(
      "Volume: %1.2f   Pan: %1.2f",
      m_volume->GetValue() / 100.0f,
      m_pan->GetValue() / 100.0f);
    m_volume_pan_label->SetLabel(label);
  }

  void UpdateLengthPosLabel() {
    if (m_stream->isSeekable()) {
      wxString label;
      label.Printf(
        "Length: %d   Pos: %d",
        m_stream->getLength(),
        m_stream->getPosition());
      m_length_pos_label->SetLabel(label);
    } else {
      m_length_pos_label->SetLabel("Unseekable Stream");
    }
  }

private:
  RefPtr<OutputStream> m_stream;

  wxCheckBox*   m_repeating;
  wxStaticText* m_volume_pan_label;
  wxSlider*     m_volume;
  wxSlider*     m_pan;
  wxStaticText* m_length_pos_label;
  wxSlider*     m_pos;

  DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(StreamFrame, wxMDIChildFrame)
  EVT_BUTTON(STREAM_PLAY,  StreamFrame::OnPlay)
  EVT_BUTTON(STREAM_STOP,  StreamFrame::OnStop)
  EVT_BUTTON(STREAM_RESET, StreamFrame::OnReset)

  EVT_CHECKBOX(STREAM_REPEAT, StreamFrame::OnRepeat)

  EVT_COMMAND_SCROLL(STREAM_VOLUME, StreamFrame::OnChangeVolume)
  EVT_COMMAND_SCROLL(STREAM_PAN,    StreamFrame::OnChangePan)
  EVT_COMMAND_SCROLL(STREAM_POS,    StreamFrame::OnChangePos)

  EVT_TIMER(STREAM_UPDATE, StreamFrame::OnUpdatePosition)
END_EVENT_TABLE()

class DeviceFrame : public wxMDIParentFrame {
public:
  DeviceFrame(AudioDevice* device, const wxString& device_name)
  : wxMDIParentFrame(NULL, -1, "Device Window - " + device_name)
  {
    m_device = device;

    wxMenu* fileMenu = new wxMenu();
    fileMenu->Append(DEVICE_NEW_DEVICE,  "&New Device...");
    fileMenu->AppendSeparator();
    fileMenu->Append(DEVICE_OPEN_STREAM, "&Open Stream...");
    fileMenu->Append(DEVICE_OPEN_SOUND,  "Open &Sound...");
    fileMenu->Append(DEVICE_CREATE_TONE, "Create &Tone...");
    fileMenu->AppendSeparator();
    fileMenu->Append(DEVICE_CLOSE,       "&Close Device");

    wxMenuBar* menuBar = new wxMenuBar();
    menuBar->Append(fileMenu, "&Device");
    SetMenuBar(menuBar);
  }

  void OnDeviceNewDevice() {
    wxString name = wxGetTextFromUser(
      "New Device",
      "Enter Device Name",
      "autodetect",
      this);
    if (!name.empty()) {
      if (!TryDevice(name)) {
        wxMessageBox(
          "Could not open audio device: " + name,
          "New Device", wxOK | wxCENTRE, this);
      }
    }
  }

  wxString GetSoundFile() {
    return wxFileSelector(
      "Select a sound file", "", "", "",
      "Sound Files (*.wav,*.ogg,*.mod,*.it,*.xm,*.s3m)|"  \
      "*.wav;*.ogg;*.mod;*.it;*.xm;*.s3m",
      wxOPEN, this);
  }

  void OnDeviceOpenStream() {
    wxString filename(GetSoundFile());
    if (filename.empty()) {
      return;
    }

    OutputStream* stream = OpenSound(m_device.get(), filename, true);
    if (!stream) {
      wxMessageBox(
        "Could not open stream: " + filename,
        "Open Stream", wxOK | wxCENTRE, this);
      return;
    }

    // get the basename of the path for the window title
    wxString basename = wxFileNameFromPath(filename);;

    wxString title;
    title.sprintf("Stream: %s", basename.c_str());
    new StreamFrame(this, title, stream);
  }

  void OnDeviceOpenSound() {
    wxString filename(GetSoundFile());
    if (filename.empty()) {
      return;
    }

    OutputStream* stream = OpenSound(m_device.get(), filename);
    if (!stream) {
      wxMessageBox(
        "Could not open sound: " + filename,
        "Open Stream", wxOK | wxCENTRE, this);
      return;
    }

    // get the basename of the path for the window title
    wxString basename = wxFileNameFromPath(filename);;

    wxString title;
    title.sprintf("Sound: %s", basename.c_str());
    new StreamFrame(this, title, stream);
  }

  void OnDeviceCreateTone() {
    int frequency = wxGetNumberFromUser(
      "Value must be between 1 and 30000.", "Enter frequency in Hz",
      "Create Tone", 256, 1, 30000, this);
    if (frequency != -1) {
      OutputStream* stream = m_device->openStream(CreateTone(frequency));
      if (!stream) {
        wxMessageBox(
          "Could not open output stream",
          "Create Tone", wxOK | wxCENTRE, this);
      } else {
        wxString title;
        title.sprintf("Tone: %d Hz", frequency);
        new StreamFrame(this, title, stream);
      }
    }
  }

  void OnDeviceClose() {
    Close();
  }

private:
  RefPtr<AudioDevice> m_device;

  DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(DeviceFrame, wxMDIParentFrame)
  EVT_MENU(DEVICE_NEW_DEVICE,  DeviceFrame::OnDeviceNewDevice)
  EVT_MENU(DEVICE_OPEN_STREAM, DeviceFrame::OnDeviceOpenStream)
  EVT_MENU(DEVICE_OPEN_SOUND,  DeviceFrame::OnDeviceOpenSound)
  EVT_MENU(DEVICE_CREATE_TONE, DeviceFrame::OnDeviceCreateTone)
  EVT_MENU(DEVICE_CLOSE,       DeviceFrame::OnDeviceClose)
END_EVENT_TABLE()

bool TryDevice(const char* name) {
  if (RefPtr<AudioDevice> device = audiere::OpenDevice(name)) {
    DeviceFrame* frame = new DeviceFrame(device.get(), name);
    frame->Show(true);
    return true;
  } else {
    return false;
  }
}

class wxPlayer : public wxApp {
public:
  bool OnInit() {
    bool result = (TryDevice("autodetect") || TryDevice("null"));
    if (!result) {
      wxMessageBox("Could not open output device", "wxPlayer");
    }
    return result;
  }
};

IMPLEMENT_APP(wxPlayer)
<|endoftext|>


<commit_before>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/eval/eval/fast_value.h>
#include <vespa/eval/eval/operation.h>
#include <vespa/eval/eval/tensor_function.h>
#include <vespa/eval/eval/test/eval_fixture.h>
#include <vespa/eval/eval/test/gen_spec.h>
#include <vespa/eval/instruction/dense_multi_matmul_function.h>
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/vespalib/util/stash.h>
#include <vespa/vespalib/util/stringfmt.h>

using namespace vespalib;
using namespace vespalib::eval;
using namespace vespalib::eval::test;
using namespace vespalib::eval::tensor_function;

const ValueBuilderFactory &prod_factory = FastValueBuilderFactory::get();

GenSpec G(std::vector<std::pair<const char *, size_t>> dims) {
    GenSpec result;
    for (const auto & dim : dims) {
        result.idx(dim.first, dim.second);
    }
    return result;
}

EvalFixture::ParamRepo make_params() {
    return EvalFixture::ParamRepo()
        .add_variants("A2B1C3a2d3",       G({{"A",2}, {"B",1}, {"C",3}, {"a",2}, {"d",3}}))  // inner/inner
        .add_variants("A2B1C3D1a2c1d3e1", G({{"A",2}, {"B",1}, {"C",3}, {"D",1}, {"a",2}, {"c",1}, {"d",3}, {"e",1}}))// inner/inner, extra dims
        .add_variants("B1C3a2d3",         G({{"B",1}, {"C",3}, {"a",2}, {"d",3}}))           // inner/inner, missing A
        .add_variants("A1a2d3",           G({{"A",1}, {"a",2}, {"d",3}}))                    // inner/inner, single mat
        .add_variants("A2D3a2b1c3",       G({{"A",2}, {"D",3}, {"a",2}, {"b",1}, {"c",3}}))  // inner/inner, inverted
        .add_variants("A2B1C3a2b5",       G({{"A",2}, {"B",1}, {"C",3}, {"a",2}, {"b",5}}))  // inner/outer
        .add_variants("A2B1C3b5c2",       G({{"A",2}, {"B",1}, {"C",3}, {"b",5}, {"c",2}}))  // outer/outer
        .add_variants("A2B1C3a2c3",       G({{"A",2}, {"B",1}, {"C",3}, {"a",2}, {"c",3}}))  // not matching
        //----------------------------------------------------------------------------------------
        .add_variants("A2B1C3b5d3",       G({{"A",2}, {"B",1}, {"C",3}, {"b",5}, {"d",3}}))  // fixed param
        .add_variants("B1C3b5d3",         G({{"B",1}, {"C",3}, {"b",5}, {"d",3}}))           // fixed param, missing A
        .add_variants("A1b5d3",           G({{"A",1}, {"b",5}, {"d",3}}))                    // fixed param, single mat
        .add_variants("B5D3a2b1c3",       G({{"B",5}, {"D",3}, {"a",2}, {"b",1}, {"c",3}})); // fixed param, inverted
}
EvalFixture::ParamRepo param_repo = make_params();

void verify_optimized(const vespalib::string &expr,
                      size_t lhs_size, size_t common_size, size_t rhs_size, size_t matmul_cnt,
                      bool lhs_inner, bool rhs_inner)
{
    EvalFixture slow_fixture(prod_factory, expr, param_repo, false);
    EvalFixture fixture(prod_factory, expr, param_repo, true);
    EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
    EXPECT_EQUAL(fixture.result(), slow_fixture.result());
    auto info = fixture.find_all<DenseMultiMatMulFunction>();
    ASSERT_EQUAL(info.size(), 1u);
    EXPECT_TRUE(info[0]->result_is_mutable());
    EXPECT_EQUAL(info[0]->lhs_size(), lhs_size);
    EXPECT_EQUAL(info[0]->common_size(), common_size);
    EXPECT_EQUAL(info[0]->rhs_size(), rhs_size);
    EXPECT_EQUAL(info[0]->matmul_cnt(), matmul_cnt);
    EXPECT_EQUAL(info[0]->lhs_common_inner(), lhs_inner);
    EXPECT_EQUAL(info[0]->rhs_common_inner(), rhs_inner);
}

void verify_not_optimized(const vespalib::string &expr) {
    EvalFixture slow_fixture(prod_factory, expr, param_repo, false);
    EvalFixture fixture(prod_factory, expr, param_repo, true);
    EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
    EXPECT_EQUAL(fixture.result(), slow_fixture.result());
    auto info = fixture.find_all<DenseMultiMatMulFunction>();
    EXPECT_TRUE(info.empty());
}

TEST("require that multi matmul can be optimized") {
    TEST_DO(verify_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,sum,d)", 2, 3, 5, 6, true, true));
}

TEST("require that single multi matmul can be optimized") {
    TEST_DO(verify_optimized("reduce(A1a2d3*A1b5d3,sum,d)", 2, 3, 5, 1, true, true));
}

TEST("require that multi matmul with lambda can be optimized") {
    TEST_DO(verify_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(x*y)),sum,d)", 2, 3, 5, 6, true, true));
}

TEST("require that expressions similar to multi matmul are not optimized") {
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,sum,a)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,sum,b)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,prod,d)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,sum)"));
    TEST_DO(verify_not_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(y*x)),sum,d)"));
    TEST_DO(verify_not_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(x+y)),sum,d)"));
    TEST_DO(verify_not_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(x*x)),sum,d)"));
    TEST_DO(verify_not_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(y*y)),sum,d)"));
    TEST_DO(verify_not_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(x*y*1)),sum,d)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2c3*A2B1C3b5d3,sum,d)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2c3*A2B1C3b5d3,sum,c)"));
}

TEST("require that multi matmul must have matching cell type") {
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3_f*A2B1C3b5d3,sum,d)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3_f,sum,d)"));
}

TEST("require that multi matmul must have matching dimension prefix") {
    TEST_DO(verify_not_optimized("reduce(B1C3a2d3*A2B1C3b5d3,sum,d)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*B1C3b5d3,sum,d)"));
}

TEST("require that multi matmul must have inner nesting of matmul dimensions") {
    TEST_DO(verify_not_optimized("reduce(A2D3a2b1c3*B5D3a2b1c3,sum,D)"));
    TEST_DO(verify_not_optimized("reduce(B5D3a2b1c3*A2D3a2b1c3,sum,D)"));
}

TEST("require that multi matmul ignores trivial dimensions") {
    TEST_DO(verify_optimized("reduce(A2B1C3D1a2c1d3e1*A2B1C3b5d3,sum,d)", 2, 3, 5, 6, true, true));
    TEST_DO(verify_optimized("reduce(A2B1C3b5d3*A2B1C3D1a2c1d3e1,sum,d)", 2, 3, 5, 6, true, true));
}

TEST("require that multi matmul function can be debug dumped") {
    EvalFixture fixture(prod_factory, "reduce(A2B1C3a2d3*A2B1C3b5d3,sum,d)", param_repo, true);
    auto info = fixture.find_all<DenseMultiMatMulFunction>();
    ASSERT_EQUAL(info.size(), 1u);
    fprintf(stderr, "%s\n", info[0]->as_string().c_str());
}

vespalib::string make_expr(const vespalib::string &a, const vespalib::string &b, const vespalib::string &common,
                           bool float_cells)
{
    return make_string("reduce(%s%s*%s%s,sum,%s)", a.c_str(), float_cells ? "_f" : "", b.c_str(), float_cells ? "_f" : "", common.c_str());
}

void verify_optimized_multi(const vespalib::string &a, const vespalib::string &b, const vespalib::string &common,
                            size_t lhs_size, size_t common_size, size_t rhs_size, size_t matmul_cnt,
                            bool lhs_inner, bool rhs_inner)
{
    for (bool float_cells: {false, true}) {
        {
            auto expr = make_expr(a, b, common, float_cells);
            TEST_STATE(expr.c_str());
            TEST_DO(verify_optimized(expr, lhs_size, common_size, rhs_size, matmul_cnt, lhs_inner, rhs_inner));
        }
        {
            auto expr = make_expr(b, a, common, float_cells);
            TEST_STATE(expr.c_str());
            TEST_DO(verify_optimized(expr, lhs_size, common_size, rhs_size, matmul_cnt, lhs_inner, rhs_inner));
        }
    }
}

TEST("require that multi matmul inner/inner works correctly") {
    TEST_DO(verify_optimized_multi("A2B1C3a2d3", "A2B1C3b5d3", "d", 2, 3, 5, 6, true, true));
}

TEST("require that multi matmul inner/outer works correctly") {
    TEST_DO(verify_optimized_multi("A2B1C3a2b5", "A2B1C3b5d3", "b", 2, 5, 3, 6, true, false));
}

TEST("require that multi matmul outer/outer works correctly") {
    TEST_DO(verify_optimized_multi("A2B1C3b5c2", "A2B1C3b5d3", "b", 2, 5, 3, 6, false, false));
}

TEST_MAIN() { TEST_RUN_ALL(); }
<commit_msg>rewrite DenseMultiMatMulFunction test<commit_after>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/eval/eval/fast_value.h>
#include <vespa/eval/eval/operation.h>
#include <vespa/eval/eval/tensor_function.h>
#include <vespa/eval/eval/test/eval_fixture.h>
#include <vespa/eval/eval/test/gen_spec.h>
#include <vespa/eval/instruction/dense_multi_matmul_function.h>
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/vespalib/util/stash.h>
#include <vespa/vespalib/util/stringfmt.h>

using namespace vespalib;
using namespace vespalib::eval;
using namespace vespalib::eval::test;
using namespace vespalib::eval::tensor_function;

const ValueBuilderFactory &prod_factory = FastValueBuilderFactory::get();

struct FunInfo {
    using LookFor = DenseMultiMatMulFunction;
    size_t lhs_size;
    size_t common_size;
    size_t rhs_size;
    size_t matmul_cnt;
    bool lhs_inner;
    bool rhs_inner;
    void verify(const LookFor &fun) const {
        EXPECT_TRUE(fun.result_is_mutable());
        EXPECT_EQUAL(fun.lhs_size(), lhs_size);
        EXPECT_EQUAL(fun.common_size(), common_size);
        EXPECT_EQUAL(fun.rhs_size(), rhs_size);
        EXPECT_EQUAL(fun.matmul_cnt(), matmul_cnt);
        EXPECT_EQUAL(fun.lhs_common_inner(), lhs_inner);
        EXPECT_EQUAL(fun.rhs_common_inner(), rhs_inner);
    }
};

void verify_optimized(const vespalib::string &expr, const FunInfo &details)
{
    TEST_STATE(expr.c_str());
    auto same_types = CellTypeSpace(CellTypeUtils::list_types(), 2).same();
    EvalFixture::verify<FunInfo>(expr, {details}, same_types);
    auto diff_types = CellTypeSpace(CellTypeUtils::list_types(), 2).different();
    EvalFixture::verify<FunInfo>(expr, {}, diff_types);
}

void verify_not_optimized(const vespalib::string &expr) {
    TEST_STATE(expr.c_str());
    CellTypeSpace just_double({CellType::DOUBLE}, 2);
    EvalFixture::verify<FunInfo>(expr, {}, just_double);
}

TEST("require that multi matmul can be optimized") {
    FunInfo details = { .lhs_size = 2, .common_size = 3, .rhs_size = 5,
                        .matmul_cnt = 6, .lhs_inner = true, .rhs_inner = true };
    TEST_DO(verify_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,sum,d)", details));
    TEST_DO(verify_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,sum,d)", details));
}

TEST("require that single multi matmul can be optimized") {
    FunInfo details = { .lhs_size = 2, .common_size = 3, .rhs_size = 5,
                        .matmul_cnt = 1, .lhs_inner = true, .rhs_inner = true };
    TEST_DO(verify_optimized("reduce(A1a2d3*A1b5d3,sum,d)", details));
}

TEST("require that multi matmul with lambda can be optimized") {
    FunInfo details = { .lhs_size = 2, .common_size = 3, .rhs_size = 5,
                        .matmul_cnt = 6, .lhs_inner = true, .rhs_inner = true };
    TEST_DO(verify_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(x*y)),sum,d)", details));
}

TEST("require that expressions similar to multi matmul are not optimized") {
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,sum,a)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,sum,b)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,prod,d)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,sum)"));
    TEST_DO(verify_not_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(y*x)),sum,d)"));
    TEST_DO(verify_not_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(x+y)),sum,d)"));
    TEST_DO(verify_not_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(x*x)),sum,d)"));
    TEST_DO(verify_not_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(y*y)),sum,d)"));
    TEST_DO(verify_not_optimized("reduce(join(A2B1C3a2d3,A2B1C3b5d3,f(x,y)(x*y*1)),sum,d)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2c3*A2B1C3b5d3,sum,d)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2c3*A2B1C3b5d3,sum,c)"));
}

TEST("require that multi matmul must have matching dimension prefix") {
    TEST_DO(verify_not_optimized("reduce(B1C3a2d3*A2B1C3b5d3,sum,d)"));
    TEST_DO(verify_not_optimized("reduce(A2B1C3a2d3*B1C3b5d3,sum,d)"));
}

TEST("require that multi matmul must have inner nesting of matmul dimensions") {
    TEST_DO(verify_not_optimized("reduce(A2D3a2b1c3*B5D3a2b1c3,sum,D)"));
    TEST_DO(verify_not_optimized("reduce(B5D3a2b1c3*A2D3a2b1c3,sum,D)"));
}

TEST("require that multi matmul ignores trivial dimensions") {
    FunInfo details = { .lhs_size = 2, .common_size = 3, .rhs_size = 5,
                        .matmul_cnt = 6, .lhs_inner = true, .rhs_inner = true };
    TEST_DO(verify_optimized("reduce(A2B1C3D1a2c1d3e1*A2B1C3b5d3,sum,d)", details));
    TEST_DO(verify_optimized("reduce(A2B1C3b5d3*A2B1C3D1a2c1d3e1,sum,d)", details));
}

TEST("require that multi matmul function can be debug dumped") {
    EvalFixture fixture(prod_factory, "reduce(m1*m2,sum,d)", EvalFixture::ParamRepo()
                        .add("m1", GenSpec::from_desc("A2B1C3a2d3"))
                        .add("m2", GenSpec::from_desc("A2B1C3b5d3")), true);
    auto info = fixture.find_all<DenseMultiMatMulFunction>();
    ASSERT_EQUAL(info.size(), 1u);
    fprintf(stderr, "%s\n", info[0]->as_string().c_str());
}

TEST("require that multi matmul inner/inner works correctly") {
    FunInfo details = { .lhs_size = 2, .common_size = 3, .rhs_size = 5,
                        .matmul_cnt = 6, .lhs_inner = true, .rhs_inner = true };
    TEST_DO(verify_optimized("reduce(A2B1C3a2d3*A2B1C3b5d3,sum,d)", details));
}

TEST("require that multi matmul inner/outer works correctly") {
    FunInfo details = { .lhs_size = 2, .common_size = 5, .rhs_size = 3,
                        .matmul_cnt = 6, .lhs_inner = true, .rhs_inner = false };
    TEST_DO(verify_optimized("reduce(A2B1C3a2b5*A2B1C3b5d3,sum,b)", details));
}

TEST("require that multi matmul outer/outer works correctly") {
    FunInfo details = { .lhs_size = 2, .common_size = 5, .rhs_size = 3,
                        .matmul_cnt = 6, .lhs_inner = false, .rhs_inner = false };
    TEST_DO(verify_optimized("reduce(A2B1C3b5c2*A2B1C3b5d3,sum,b)", details));
}

TEST_MAIN() { TEST_RUN_ALL(); }
<|endoftext|>


<commit_before>#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
#include <time.h>
#include <unistd.h>

#include <string>

using std::string;
const int kDefaultLengthSecs = 25 * 60;
const char* kDefaultDoneMessage = "";

string SocketName() {
  string socket_name;
  socket_name.append(P_tmpdir);
  socket_name.append("/.tpm-");
  socket_name.append(getenv("USER"));
  return socket_name;
}

string MakePostHookPath() {
  string post_hook;
  post_hook = getenv("HOME");
  post_hook += "/.tpm-post.sh";
  return post_hook;
}

int ClientMain(string done_message) {
  int sock_fd;
  struct sockaddr_un remote;
  if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }
  remote.sun_family = AF_UNIX;
  string socket_name = SocketName();
  strcpy(remote.sun_path, socket_name.c_str());

  int len = strlen(remote.sun_path) + sizeof(remote.sun_family) + 1;
  if (connect(sock_fd, (struct sockaddr *)&remote, len) == -1) {
    printf("%s\n", done_message.c_str());
    return 0;
  }

  int recv_length;
  char buf[100];
  if ((recv_length = recv(sock_fd, buf, 100, 0)) > 0) {
    buf[recv_length] = '\0';
    printf("%s\n", buf);
  }
  close(sock_fd);
  return 0;
}

int DaemonMain(int countdown_time) {
        /* Our process ID and Session ID */
        int ok;
        pid_t pid, sid;
        struct timespec ts;
        ts.tv_sec = 0;
        ts.tv_nsec = 1000 /*micro*/ * 1000 /* milli */ * 50;

        string socket_name = SocketName();

        int sock_fd;
        struct sockaddr_un local, remote;

        if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
          perror("socket");
          exit(1);
        }
        local.sun_family = AF_UNIX;
        strcpy(local.sun_path, socket_name.c_str());
        unlink(local.sun_path);
        int len = strlen(local.sun_path) + sizeof(local.sun_family) + 1;
        if (bind(sock_fd, (struct sockaddr *)&local, len) == -1) {
          perror("bind");
          exit(1);
        }
        int flags = fcntl(sock_fd,F_GETFL,0);
        fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);

        /* Fork off the parent process */
        pid = fork();
        if (pid < 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid > 0) {
                exit(EXIT_SUCCESS);
        }

        /* Change the file mode mask */
        umask(0);

        /* Open any logs here */

        /* Create a new SID for the child process */
        sid = setsid();
        if (sid < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }

        /* Change the current working directory */
        if ((chdir("/")) < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }

        /* Close out the standard file descriptors */
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);

        if (listen(sock_fd, 5) == -1) {
          exit(1);
        }

        struct timeval start_time;
        ok = gettimeofday(&start_time, NULL);
        int remote_fd = -1;

        bool wakeup = false;
        while (!wakeup) {
           struct timeval current_time;
           struct timeval diff_time;
           ok = gettimeofday(&current_time, NULL);
           timersub(&current_time, &start_time, &diff_time);
           if (diff_time.tv_sec >= countdown_time) {
             wakeup = true;
             continue;
           }
           long remaining_time = (long)countdown_time - diff_time.tv_sec;
           socklen_t t = sizeof(remote);
           while ((remote_fd = accept(sock_fd, (struct sockaddr *)&remote, &t)) != -1) {
             char message[100];
             int message_len = snprintf(message, 100, "%ld:%02ld", remaining_time / 60, remaining_time % 60);
             if (send(remote_fd, message, message_len, 0) < 0) {
              exit(1);
             }
             close(remote_fd);
           }
           // Make sure it was just EWOULDBLOCK
           if (errno != EAGAIN && errno != EWOULDBLOCK) {
             exit(1);
           }
           ok = nanosleep(&ts, NULL);
        }
   close(sock_fd);
   printf("%s\n", local.sun_path);
   unlink(local.sun_path);
   string post_hook = MakePostHookPath();
   char* argv[0];
   if (access(post_hook.c_str(), X_OK) != -1) {
     execv(post_hook.c_str(), argv);
   }
   exit(EXIT_SUCCESS);
}

int main(int argc, char** argv) {
    int c;
    int countdown_time = kDefaultLengthSecs;
    string done_message = kDefaultDoneMessage;
    int got_positional = 0;
    string command = "";
    while (1) {
      while ( (c = getopt(argc, argv, "bs:m:d:")) != -1) {
          switch (c) {
          case 's':
              countdown_time = atoi(optarg);
              break;
          case 'm':
              countdown_time = atoi(optarg) * 60;
              break;
          case 'd':
              done_message = optarg;
              break;
          }
      }
      if (optind < argc && !got_positional) {
          command = argv[optind];
          got_positional = 1;
      } else {
        break;
      }
      optind++;
    }

    if (command == "start") {
      DaemonMain(countdown_time);
    }
    else {
      return ClientMain(done_message);
    }
    exit(0);
}
<commit_msg>better execv in cpp<commit_after>#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
#include <time.h>
#include <unistd.h>

#include <string>

using std::string;
const int kDefaultLengthSecs = 25 * 60;
const char* kDefaultDoneMessage = "";

string SocketName() {
  string socket_name;
  socket_name.append(P_tmpdir);
  socket_name.append("/.tpm-");
  socket_name.append(getenv("USER"));
  return socket_name;
}

string MakePostHookPath() {
  string post_hook;
  post_hook = getenv("HOME");
  post_hook += "/.tpm-post.sh";
  return post_hook;
}

int ClientMain(string done_message) {
  int sock_fd;
  struct sockaddr_un remote;
  if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }
  remote.sun_family = AF_UNIX;
  string socket_name = SocketName();
  strcpy(remote.sun_path, socket_name.c_str());

  int len = strlen(remote.sun_path) + sizeof(remote.sun_family) + 1;
  if (connect(sock_fd, (struct sockaddr *)&remote, len) == -1) {
    printf("%s\n", done_message.c_str());
    return 0;
  }

  int recv_length;
  char buf[100];
  if ((recv_length = recv(sock_fd, buf, 100, 0)) > 0) {
    buf[recv_length] = '\0';
    printf("%s\n", buf);
  }
  close(sock_fd);
  return 0;
}

int DaemonMain(int countdown_time) {
        /* Our process ID and Session ID */
        int ok;
        pid_t pid, sid;
        struct timespec ts;
        ts.tv_sec = 0;
        ts.tv_nsec = 1000 /*micro*/ * 1000 /* milli */ * 50;

        string socket_name = SocketName();

        int sock_fd;
        struct sockaddr_un local, remote;

        if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
          perror("socket");
          exit(1);
        }
        local.sun_family = AF_UNIX;
        strcpy(local.sun_path, socket_name.c_str());
        unlink(local.sun_path);
        int len = strlen(local.sun_path) + sizeof(local.sun_family) + 1;
        if (bind(sock_fd, (struct sockaddr *)&local, len) == -1) {
          perror("bind");
          exit(1);
        }
        int flags = fcntl(sock_fd,F_GETFL,0);
        fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);

        /* Fork off the parent process */
        pid = fork();
        if (pid < 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid > 0) {
                exit(EXIT_SUCCESS);
        }

        /* Change the file mode mask */
        umask(0);

        /* Open any logs here */

        /* Create a new SID for the child process */
        sid = setsid();
        if (sid < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }

        /* Change the current working directory */
        if ((chdir("/")) < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }

        /* Close out the standard file descriptors */
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);

        if (listen(sock_fd, 5) == -1) {
          exit(1);
        }

        struct timeval start_time;
        ok = gettimeofday(&start_time, NULL);
        int remote_fd = -1;

        bool wakeup = false;
        while (!wakeup) {
           struct timeval current_time;
           struct timeval diff_time;
           ok = gettimeofday(&current_time, NULL);
           timersub(&current_time, &start_time, &diff_time);
           if (diff_time.tv_sec >= countdown_time) {
             wakeup = true;
             continue;
           }
           long remaining_time = (long)countdown_time - diff_time.tv_sec;
           socklen_t t = sizeof(remote);
           while ((remote_fd = accept(sock_fd, (struct sockaddr *)&remote, &t)) != -1) {
             char message[100];
             int message_len = snprintf(message, 100, "%ld:%02ld", remaining_time / 60, remaining_time % 60);
             if (send(remote_fd, message, message_len, 0) < 0) {
              exit(1);
             }
             close(remote_fd);
           }
           // Make sure it was just EWOULDBLOCK
           if (errno != EAGAIN && errno != EWOULDBLOCK) {
             exit(1);
           }
           ok = nanosleep(&ts, NULL);
        }
   close(sock_fd);
   printf("%s\n", local.sun_path);
   unlink(local.sun_path);
   string post_hook = MakePostHookPath();
   char* argv[] = {(char *)post_hook.c_str(), NULL};
   if (access(post_hook.c_str(), X_OK) != -1) {
     execv(post_hook.c_str(), argv);
   }
   exit(EXIT_SUCCESS);
}

int main(int argc, char** argv) {
    int c;
    int countdown_time = kDefaultLengthSecs;
    string done_message = kDefaultDoneMessage;
    int got_positional = 0;
    string command = "";
    while (1) {
      while ( (c = getopt(argc, argv, "bs:m:d:")) != -1) {
          switch (c) {
          case 's':
              countdown_time = atoi(optarg);
              break;
          case 'm':
              countdown_time = atoi(optarg) * 60;
              break;
          case 'd':
              done_message = optarg;
              break;
          }
      }
      if (optind < argc && !got_positional) {
          command = argv[optind];
          got_positional = 1;
      } else {
        break;
      }
      optind++;
    }

    if (command == "start") {
      DaemonMain(countdown_time);
    }
    else {
      return ClientMain(done_message);
    }
    exit(0);
}
<|endoftext|>


<commit_before><commit_msg>improve coverage of matrix-vector product<commit_after><|endoftext|>


<commit_before>/*
    Copyright (c) 2009 Kevin Ottens <ervin@kde.org>

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

    This library 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "quotacolorproxymodel.h"

#include <akonadi/entitytreemodel.h>
#include <akonadi/collectionquotaattribute.h>

#include <QtGui/QColor>

using namespace Akonadi;

/**
 * @internal
 */
class QuotaColorProxyModel::Private
{
  public:
    Private( QuotaColorProxyModel *parent )
      : mParent( parent ), mThreshold( 100.0 ), mColor( Qt::red )
    {
    }

    QuotaColorProxyModel *mParent;

    qreal mThreshold;
    QColor mColor;
};

QuotaColorProxyModel::QuotaColorProxyModel( QObject *parent )
  : QSortFilterProxyModel( parent ),
    d( new Private( this ) )
{
}

QuotaColorProxyModel::~QuotaColorProxyModel()
{
  delete d;
}

void QuotaColorProxyModel::setWarningThreshold( qreal threshold )
{
  d->mThreshold = threshold;
}

qreal QuotaColorProxyModel::warningThreshold() const
{
  return d->mThreshold;
}

void QuotaColorProxyModel::setWarningColor( const QColor &color )
{
  d->mColor = color;
}

QColor QuotaColorProxyModel::warningColor() const
{
  return d->mColor;
}

QVariant QuotaColorProxyModel::data( const QModelIndex & index, int role) const
{
  if ( role == Qt::ForegroundRole ) {
    const QModelIndex sourceIndex = mapToSource( index );
    const QModelIndex rowIndex = sourceIndex.sibling( sourceIndex.row(), 0 );
    Collection collection = sourceModel()->data( rowIndex, EntityTreeModel::CollectionRole ).value<Collection>();

    if ( collection.isValid() && collection.hasAttribute<CollectionQuotaAttribute>() ) {
      CollectionQuotaAttribute *quota = collection.attribute<CollectionQuotaAttribute>();

      if ( quota->currentValue() > -1 && quota->maxValue() > 0 ) {
        qreal percentage = ( 100.0 * quota->currentValue() ) / quota->maxValue();

        if ( percentage >= d->mThreshold ) {
          return d->mColor;
        }
      }
    }
  }

  return QAbstractProxyModel::data( index, role );
}

bool QuotaColorProxyModel::dropMimeData( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
{
  Q_ASSERT(sourceModel());
  const QModelIndex sourceParent = mapToSource(parent);
  return sourceModel()->dropMimeData(data, action, row, column, sourceParent);
}

QMimeData* QuotaColorProxyModel::mimeData( const QModelIndexList & indexes ) const
{
  Q_ASSERT(sourceModel());
  QModelIndexList sourceIndexes;
  foreach(const QModelIndex& index, indexes)
    sourceIndexes << mapToSource(index);
  return sourceModel()->mimeData(sourceIndexes);
}

QStringList QuotaColorProxyModel::mimeTypes() const
{
  Q_ASSERT(sourceModel());
  return sourceModel()->mimeTypes();
}

#include "quotacolorproxymodel.moc"

<commit_msg>Fix the build CCMAIL: ervin@kde.org<commit_after>/*
    Copyright (c) 2009 Kevin Ottens <ervin@kde.org>

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

    This library 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "quotacolorproxymodel.h"

#include <akonadi/entitytreemodel.h>
#include <akonadi/collectionquotaattribute.h>

#include <QtGui/QColor>

using namespace Akonadi;

/**
 * @internal
 */
class QuotaColorProxyModel::Private
{
  public:
    Private( QuotaColorProxyModel *parent )
      : mParent( parent ), mThreshold( 100.0 ), mColor( Qt::red )
    {
    }

    QuotaColorProxyModel *mParent;

    qreal mThreshold;
    QColor mColor;
};

QuotaColorProxyModel::QuotaColorProxyModel( QObject *parent )
  : QSortFilterProxyModel( parent ),
    d( new Private( this ) )
{
}

QuotaColorProxyModel::~QuotaColorProxyModel()
{
  delete d;
}

void QuotaColorProxyModel::setWarningThreshold( qreal threshold )
{
  d->mThreshold = threshold;
}

qreal QuotaColorProxyModel::warningThreshold() const
{
  return d->mThreshold;
}

void QuotaColorProxyModel::setWarningColor( const QColor &color )
{
  d->mColor = color;
}

QColor QuotaColorProxyModel::warningColor() const
{
  return d->mColor;
}

QVariant QuotaColorProxyModel::data( const QModelIndex & index, int role) const
{
  if ( role == Qt::ForegroundRole ) {
    const QModelIndex sourceIndex = mapToSource( index );
    const QModelIndex rowIndex = sourceIndex.sibling( sourceIndex.row(), 0 );
    Collection collection = sourceModel()->data( rowIndex, EntityTreeModel::CollectionRole ).value<Collection>();

    if ( collection.isValid() && collection.hasAttribute<CollectionQuotaAttribute>() ) {
      CollectionQuotaAttribute *quota = collection.attribute<CollectionQuotaAttribute>();

      if ( quota->currentValue() > -1 && quota->maximumValue() > 0 ) {
        qreal percentage = ( 100.0 * quota->currentValue() ) / quota->maximumValue();

        if ( percentage >= d->mThreshold ) {
          return d->mColor;
        }
      }
    }
  }

  return QAbstractProxyModel::data( index, role );
}

bool QuotaColorProxyModel::dropMimeData( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
{
  Q_ASSERT(sourceModel());
  const QModelIndex sourceParent = mapToSource(parent);
  return sourceModel()->dropMimeData(data, action, row, column, sourceParent);
}

QMimeData* QuotaColorProxyModel::mimeData( const QModelIndexList & indexes ) const
{
  Q_ASSERT(sourceModel());
  QModelIndexList sourceIndexes;
  foreach(const QModelIndex& index, indexes)
    sourceIndexes << mapToSource(index);
  return sourceModel()->mimeData(sourceIndexes);
}

QStringList QuotaColorProxyModel::mimeTypes() const
{
  Q_ASSERT(sourceModel());
  return sourceModel()->mimeTypes();
}

#include "quotacolorproxymodel.moc"

<|endoftext|>


<commit_before>/*
 * =====================================================================================
 *
 *       Filename:  3.cpp
 *
 *    Description:  Solution to the third problem of the `evens' section.
 *
 *        Version:  1.0
 *        Created:  28.01.2015  6,00,07
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Radoslav Georgiev (sid), rgeorgiev583@gmail.com
 *        Company:  Faculty of Mathematics and Informatics at Sofia University
 *
 * =====================================================================================
 */

#include <iostream>
#include <cstring>

using namespace std;

const int MAX_SIZE = 1000;
const char diff = 'a' - 'A';

bool isInnerWordChar(char c)
{
    return c == '-' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';
}

bool isBeginWordChar(char c)
{
    return isInnerWordChar(c) || c == '"' || c == '\'' || c == '(';
}

bool isEndWordChar(char c)
{
    return isInnerWordChar(c) || c == '"' || c == '\'' || c == ')';
}

char toUpper(char c)
{
    return c >= 'a' && c <= 'z' ? c - diff : c;
}

char toLower(char c)
{
    return c >= 'A' && c <= 'Z' ? c + diff : c;
}

void swap(char* a, char* b)
{
    char x = *a;
    *a = *b;
    *b = x;
}

const char* goToEnd(const char* s)
{
    while (*s)
        s++;

    return s;
}

// Ако изречението е невалидно, връщаме NULL
char* reverseSentence(char* rev, const char* s)
{
    if (!s)
        return NULL;

    const char* end = goToEnd(s);
    end--;

    if (end < s || *end != '!' && *end != '.' && *end != '?')
        return NULL;

    const char* stop = end;
    end--;

    if (end < s)
        return NULL;

    do
    {
        const char *beg = end;

        if (!isEndWordChar(*beg))
            return NULL;

        beg--;

        while (beg >= s && isInnerWordChar(*beg))
            beg--;

        if (beg < s || !isBeginWordChar(*beg))
            beg++;

        if (isInnerWordChar(*beg) && !isInnerWordChar(*end))
            if (*end != ')')
                strncat(rev, end, 1);
            else
                strcat(rev, "(");

        if (isInnerWordChar(*end) && !isInnerWordChar(*beg))
            beg++;

        if (beg == s)
        {
            char first[2];
            first[0] = *beg;
            first[1] = 0;
            first[0] = toLower(first[0]);
            strcat(rev, first);
            strncat(rev, beg + 1, end - beg);
        }
        else
        {
            strncat(rev, beg, end - beg + 1);
            beg--;

            if (isInnerWordChar(*end) && isBeginWordChar(*beg) && !isInnerWordChar(*beg))
                beg--;

            if (*beg != ' ')
                return NULL;

            beg--;

            if (beg < s)
                return NULL;

            if (*beg == ',' || *beg == ':' || *beg == ';' || *beg == '(' || *beg == ')')
                strncat(rev, beg, 1);

            strncat(rev, beg + 1, 1);
            beg += 2;
        }

        if (isInnerWordChar(*end) && isBeginWordChar(*beg) && !isInnerWordChar(*beg))
            if (*beg != '(')
                strncat(rev, beg, 1);
            else
                strcat(rev, ")");

        end = beg - 2;
    }
    while (end >= s);

    strncat(rev, stop, 1);
    *rev = toUpper(*rev);
/*    char *p = rev, *lp = NULL;
    int b = 0;

    while (*p)
    {
        if (*p == '(')
        {
            b++;

            if (lp && b == 0)
            {
                swap(p, lp);
                lp = NULL;
            }
        }
        else if (*p == ')')
        {
            b--;

            if (b == -1)
                lp = p;
        }

        p++;
    }
*/
    return rev;
}

int main()
{
    char s[MAX_SIZE], rev[MAX_SIZE];
    cin.getline(s, MAX_SIZE);

    cout << reverseSentence(rev, s) << endl;

    return 0;
}
<commit_msg>added appending function<commit_after>/*
 * =====================================================================================
 *
 *       Filename:  3.cpp
 *
 *    Description:  Solution to the third problem of the `evens' section.
 *
 *        Version:  1.0
 *        Created:  28.01.2015  6,00,07
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Radoslav Georgiev (sid), rgeorgiev583@gmail.com
 *        Company:  Faculty of Mathematics and Informatics at Sofia University
 *
 * =====================================================================================
 */

#include <iostream>
#include <cstring>

using namespace std;

const int MAX_SIZE = 1000;
const char diff = 'a' - 'A';

bool isInnerWordChar(char c)
{
    return c == '-' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';
}

bool isBeginWordChar(char c)
{
    return isInnerWordChar(c) || c == '"' || c == '\'' || c == '(';
}

bool isEndWordChar(char c)
{
    return isInnerWordChar(c) || c == '"' || c == '\'' || c == ')';
}

char toUpper(char c)
{
    return c >= 'a' && c <= 'z' ? c - diff : c;
}

char toLower(char c)
{
    return c >= 'A' && c <= 'Z' ? c + diff : c;
}

void swap(char* a, char* b)
{
    char x = *a;
    *a = *b;
    *b = x;
}

const char* goToEnd(const char* s)
{
    while (*s)
        s++;

    return s;
}

char* appendBegin(char* rev, const char* beg, const char* end)
{
    if (isInnerWordChar(*end) && isBeginWordChar(*beg) && !isInnerWordChar(*beg))
        if (*beg != '(')
            strncat(rev, beg, 1);
        else
            strcat(rev, ")");

    return rev;
}

// Ако изречението е невалидно, връщаме NULL
char* reverseSentence(char* rev, const char* s)
{
    if (!s)
        return NULL;

    const char* end = goToEnd(s);
    end--;

    if (end < s || *end != '!' && *end != '.' && *end != '?')
        return NULL;

    const char* stop = end;
    end--;

    if (end < s)
        return NULL;

    do
    {
        const char *beg = end;

        if (!isEndWordChar(*beg))
            return NULL;

        beg--;

        while (beg >= s && isInnerWordChar(*beg))
            beg--;

        if (beg < s || !isBeginWordChar(*beg))
            beg++;

        if (isInnerWordChar(*beg) && !isInnerWordChar(*end))
            if (*end != ')')
                strncat(rev, end, 1);
            else
                strcat(rev, "(");

        if (isInnerWordChar(*end) && !isInnerWordChar(*beg))
            beg++;

        if (beg == s)
        {
            char first[2];
            first[0] = *beg;
            first[1] = 0;
            first[0] = toLower(first[0]);
            strcat(rev, first);
            strncat(rev, beg + 1, (!isInnerWordChar(*end) ? end - 1 : end) - beg);
            appendBegin(rev, beg - 1, end);
        }
        else
        {
            strncat(rev, beg, end - beg + 1);
            beg--;

            if (isInnerWordChar(*end) && isBeginWordChar(*beg) && !isInnerWordChar(*beg))
                beg--;

            if (*beg != ' ')
                return NULL;

            beg--;

            if (beg < s)
                return NULL;

            if (*beg == ',' || *beg == ':' || *beg == ';' || *beg == '(' || *beg == ')')
                strncat(rev, beg, 1);

            strncat(rev, beg + 1, 1);
            beg += 2;
            appendBegin(rev, beg, end);
            strncat(rev, beg - 1, 1);
        }

        end = beg - 2;
    }
    while (end >= s);

    strncat(rev, stop, 1);
    *rev = toUpper(*rev);
/*    char *p = rev, *lp = NULL;
    int b = 0;

    while (*p)
    {
        if (*p == '(')
        {
            b++;

            if (lp && b == 0)
            {
                swap(p, lp);
                lp = NULL;
            }
        }
        else if (*p == ')')
        {
            b--;

            if (b == -1)
                lp = p;
        }

        p++;
    }
*/
    return rev;
}

int main()
{
    char s[MAX_SIZE], rev[MAX_SIZE];
    cin.getline(s, MAX_SIZE);

    cout << reverseSentence(rev, s) << endl;

    return 0;
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include <utility>

#include "OsiSolverInterface.hpp"
#include "OsiClpSolverInterface.hpp"
#include "CoinPackedMatrix.hpp"
#include "CoinModel.hpp"

#include "coin_helpers.h"
#include "exchange_graph.h"
#include "equality_helpers.h"
#include "prog_translator.h"
#include "solver_factory.h"
#include "logger.h"

namespace cyclus {

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST(ProgTranslatorTests, translation) {
  // Logger::ReportLevel() = Logger::ToLogLevel("LEV_DEBUG2");

  int narcs = 5;
  int nfaux = 2;
  int nrows = 8;
  int nexcl = 3;

  double prefs [] = {0.2, 1.2, 4, 5, 1.3, -1, -1};
  double ucaps_a_0 [] = {0.5, 0.4};
  double ucaps_a_3 [] = {0.3, 0.6};
  double ucaps_b_1 [] = {0.9};
  double ucaps_b_2 [] = {0.8};
  double ucaps_b_4 [] = {0.7};
  double ucaps_c_0 [] = {0.7};
  double ucaps_c_1 [] = {0.8};
  double ucaps_c_2 [] = {0.9};
  double ucaps_d_3 [] = {1.3, 2};
  double ucaps_d_4 [] = {1.4, 1.9};
  double ucaps_5 [] = {1.0};
  double ucaps_6 [] = {1.0};

  double dem_a [] = {5.0, 4.9};
  double dem_b [] = {4.0};
  double sup_c [] = {10.0};
  double sup_d [] = {10.1, 9.1};

  int excl_arcs [] = {1, 2, 4};
  double excl_flow [] = {0, 2, 2, 0, 2, 0, 0};

  std::vector<double> obj_coeffs;
  for (int i = 0; i != narcs + nfaux; i++) {
    obj_coeffs.push_back((excl_flow[i] != 0) ?
                         excl_flow[i] * prefs[i] : prefs[i]);
  }

  ExchangeNode::Ptr a0(new ExchangeNode());
  ExchangeNode::Ptr a1(new ExchangeNode());
  ExchangeNode::Ptr b0(new ExchangeNode());
  ExchangeNode::Ptr b1(new ExchangeNode());
  ExchangeNode::Ptr c0(new ExchangeNode());
  ExchangeNode::Ptr c1(new ExchangeNode());
  ExchangeNode::Ptr c2(new ExchangeNode());
  ExchangeNode::Ptr d0(new ExchangeNode());
  ExchangeNode::Ptr d1(new ExchangeNode());

  Arc x0(a0, c0);
  Arc x1(b0, c1, true, excl_flow[1]);
  Arc x2(b1, c2, true, excl_flow[2]);
  Arc x3(a1, d0);
  Arc x4(b1, d1, true, excl_flow[4]);

  a0->unit_capacities[x0] = std::vector<double>(
      ucaps_a_0, ucaps_a_0 + sizeof(ucaps_a_0) / sizeof(ucaps_a_0[0]) );
  a1->unit_capacities[x3] = std::vector<double>(
      ucaps_a_3, ucaps_a_3 + sizeof(ucaps_a_3) / sizeof(ucaps_a_3[0]) );
  b0->unit_capacities[x1] = std::vector<double>(
      ucaps_b_1, ucaps_b_1 + sizeof(ucaps_b_1) / sizeof(ucaps_b_1[0]) );
  b1->unit_capacities[x2] = std::vector<double>(
      ucaps_b_2, ucaps_b_2 + sizeof(ucaps_b_2) / sizeof(ucaps_b_2[0]) );
  b1->unit_capacities[x4] = std::vector<double>(
      ucaps_b_4, ucaps_b_4 + sizeof(ucaps_b_4) / sizeof(ucaps_b_4[0]) );
  c0->unit_capacities[x0] = std::vector<double>(
      ucaps_c_0, ucaps_c_0 + sizeof(ucaps_c_0) / sizeof(ucaps_c_0[0]) );
  c1->unit_capacities[x1] = std::vector<double>(
      ucaps_c_1, ucaps_c_1 + sizeof(ucaps_c_1) / sizeof(ucaps_c_1[0]) );
  c2->unit_capacities[x2] = std::vector<double>(
      ucaps_c_2, ucaps_c_2 + sizeof(ucaps_c_2) / sizeof(ucaps_c_2[0]) );
  d0->unit_capacities[x3] = std::vector<double>(
      ucaps_d_3, ucaps_d_3 + sizeof(ucaps_d_3) / sizeof(ucaps_d_3[0]) );
  d1->unit_capacities[x4] = std::vector<double>(
      ucaps_d_4, ucaps_d_4 + sizeof(ucaps_d_4) / sizeof(ucaps_d_4[0]) );

  a0->prefs[x0] = prefs[0];
  b0->prefs[x1] = prefs[1];
  b1->prefs[x2] = prefs[2];
  a1->prefs[x3] = prefs[3];
  b1->prefs[x4] = prefs[4];

  RequestGroup::Ptr a(new RequestGroup()); // new RequestGroup(dem_a[0])?
  a->AddExchangeNode(a0);
  a->AddExchangeNode(a1);
  a->AddCapacity(dem_a[0]);
  a->AddCapacity(dem_a[1]);
  RequestGroup::Ptr b(new RequestGroup()); // new RequestGroup(dem_b[0])?
  b->AddExchangeNode(b0);
  b->AddExchangeNode(b1);
  b->AddCapacity(dem_b[0]);
  ExchangeNodeGroup::Ptr c(new ExchangeNodeGroup());
  c->AddExchangeNode(c0);
  c->AddExchangeNode(c1);
  c->AddExchangeNode(c2);
  c->AddCapacity(sup_c[0]);
  ExchangeNodeGroup::Ptr d(new ExchangeNodeGroup());
  d->AddExchangeNode(d0);
  d->AddExchangeNode(d1);
  d->AddCapacity(sup_d[0]);
  d->AddCapacity(sup_d[1]);

  ExchangeGraph g;
  g.AddRequestGroup(a);
  g.AddRequestGroup(b);
  g.AddSupplyGroup(c);
  g.AddSupplyGroup(d);
  g.AddArc(x0);
  g.AddArc(x1);
  g.AddArc(x2);
  g.AddArc(x3);
  g.AddArc(x4);

  SolverFactory sf;
  sf.solver_t("cbc");
  OsiSolverInterface* iface = sf.get();
  CoinMessageHandler h;
  h.setLogLevel(0);
  iface->passInMessageHandler(&h);
  bool excl = true;
  ProgTranslator pt(&g, iface, excl);
  EXPECT_NO_THROW(pt.Translate());

  double inf = iface->getInfinity();

  // test non-coin xlate members
  double col_lbs [] = {0, 0, 0, 0, 0, 0, 0};
  double col_ubs [] = {inf, 1, 1, inf, 1, inf, inf};
  double row_lbs [] = {0, 0, 0, dem_a[0], dem_a[1], dem_b[0], 0, 0};
  double row_ubs [] = {sup_c[0], sup_d[0], sup_d[1], inf, inf, inf, 1, 1};
  array_double_eq(&obj_coeffs[0], &pt.ctx().obj_coeffs[0], narcs + nfaux, "obj");
  array_double_eq(col_ubs, &pt.ctx().col_ubs[0], narcs + nfaux, "col_ub");
  array_double_eq(col_lbs, &pt.ctx().col_lbs[0], narcs + nfaux, "col_lb");
  array_double_eq(row_ubs, &pt.ctx().row_ubs[0], nrows, "row_ub");
  array_double_eq(row_lbs, &pt.ctx().row_lbs[0], nrows, "row_lb");

  for (int i = 0; i != 7; i++) {
    EXPECT_DOUBLE_EQ(col_lbs[i], pt.ctx().col_lbs[i]);
  }

  // test coin xlate members
  CoinPackedMatrix m(false, 0, 0);
  m.setDimensions(0, narcs + nfaux);

  int row_ind_0 [] = {0, 1, 2};
  double row_val_0 [] = {ucaps_c_0[0],
                         ucaps_c_1[0] * excl_flow[1],
                         ucaps_c_2[0] * excl_flow[2]};
  m.appendRow(3, row_ind_0, row_val_0);

  int row_ind_1 [] = {3, 4};
  double row_val_1 [] = {ucaps_d_3[0],
                         ucaps_d_4[0] * excl_flow[4]};
  m.appendRow(2, row_ind_1, row_val_1);

  int row_ind_2 [] = {3, 4};
  double row_val_2 [] = {ucaps_d_3[1],
                         ucaps_d_4[1] * excl_flow[4]};
  m.appendRow(2, row_ind_2, row_val_2);

  int row_ind_3 [] = {0, 3, 5};
  double row_val_3 [] = {ucaps_a_0[0], ucaps_a_3[0], 1};
  m.appendRow(3, row_ind_3, row_val_3);

  int row_ind_4 [] = {0, 3, 5};
  double row_val_4 [] = {ucaps_a_0[1], ucaps_a_3[1], 1};
  m.appendRow(3, row_ind_4, row_val_4);

  int row_ind_5 [] = {1, 2, 4, 6};
  double row_val_5 [] = {ucaps_b_1[0] * excl_flow[1],
                         ucaps_b_2[0] * excl_flow[2],
                         ucaps_b_4[0] * excl_flow[4],
                         1};
  m.appendRow(4, row_ind_5, row_val_5);

  int row_ind_6 [] = {1};
  double row_val_6 [] = {1};
  m.appendRow(1, row_ind_6, row_val_6);

  int row_ind_7 [] = {2, 4};
  double row_val_7 [] = {1, 1};
  m.appendRow(2, row_ind_7, row_val_7);

  EXPECT_TRUE(m.isEquivalent2(pt.ctx().m));

  // test population
  EXPECT_NO_THROW(pt.Populate());

  for (int i = 0; i != nexcl; i++) {
    EXPECT_TRUE(iface->isInteger(excl_arcs[i]));
  }

  // verify problem instance
  OsiClpSolverInterface checkface;
  checkface.loadProblem(m, &col_lbs[0], &col_ubs[0],
                        &obj_coeffs[0], &row_lbs[0], &row_ubs[0]);
  for (int i = 0; i != nexcl; i++) {
    checkface.setInteger(excl_arcs[i]);
  }
  EXPECT_EQ(0, differentModel(*iface, checkface));
  differentModel(*iface, checkface);

  checkface.passInMessageHandler(&h);
  checkface.setObjSense(-1.0);
  checkface.initialSolve();
  checkface.branchAndBound();

  // verify solution
  EXPECT_NO_THROW(Solve(iface));
  const double* soln = iface->getColSolution();
  const double* check = checkface.getColSolution();
  array_double_eq(soln, check, narcs + nfaux);

  // validate solution
  double x0_flow = (sup_c[0] -
                    ucaps_c_1[0] * excl_flow[1] - ucaps_c_2[0] * excl_flow[2]) /
                   ucaps_c_0[0]; // 9.42857..
  double x1_flow = excl_flow[1];
  double x2_flow = excl_flow[2];
  double x3_flow = sup_d[1] / ucaps_d_3[1]; // 4.55
  double x4_flow = 0;

  // first faux arc
  double x5_flow = 0;
  // second faux arc
  double x6_flow = dem_b[0] -
                   ucaps_b_1[0] * excl_flow[1] -
                   ucaps_b_2[0] * excl_flow[2]; // 0.6;

  EXPECT_DOUBLE_EQ(soln[0], x0_flow);
  EXPECT_EQ(soln[1], 1);
  EXPECT_EQ(soln[2], 1);
  EXPECT_DOUBLE_EQ(soln[3], x3_flow);
  EXPECT_EQ(soln[4], 0);
  EXPECT_DOUBLE_EQ(soln[5], 0);
  EXPECT_DOUBLE_EQ(soln[6], x6_flow);

  // check back translation
  pt.FromProg();
  const std::vector<Match>& matches = g.matches();
  EXPECT_EQ(4, matches.size());
  pair_double_eq(matches[0], std::pair<Arc, double>(x0, x0_flow));
  pair_double_eq(matches[1], std::pair<Arc, double>(x1, x1_flow));
  pair_double_eq(matches[2], std::pair<Arc, double>(x2, x2_flow));
  pair_double_eq(matches[3], std::pair<Arc, double>(x3, x3_flow));

  delete iface;
};

} // namespace cyclus
<commit_msg>expect->assert eq<commit_after>#include <gtest/gtest.h>

#include <utility>

#include "OsiSolverInterface.hpp"
#include "OsiClpSolverInterface.hpp"
#include "CoinPackedMatrix.hpp"
#include "CoinModel.hpp"

#include "coin_helpers.h"
#include "exchange_graph.h"
#include "equality_helpers.h"
#include "prog_translator.h"
#include "solver_factory.h"
#include "logger.h"

namespace cyclus {

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST(ProgTranslatorTests, translation) {
  // Logger::ReportLevel() = Logger::ToLogLevel("LEV_DEBUG2");

  int narcs = 5;
  int nfaux = 2;
  int nrows = 8;
  int nexcl = 3;

  double prefs [] = {0.2, 1.2, 4, 5, 1.3, -1, -1};
  double ucaps_a_0 [] = {0.5, 0.4};
  double ucaps_a_3 [] = {0.3, 0.6};
  double ucaps_b_1 [] = {0.9};
  double ucaps_b_2 [] = {0.8};
  double ucaps_b_4 [] = {0.7};
  double ucaps_c_0 [] = {0.7};
  double ucaps_c_1 [] = {0.8};
  double ucaps_c_2 [] = {0.9};
  double ucaps_d_3 [] = {1.3, 2};
  double ucaps_d_4 [] = {1.4, 1.9};
  double ucaps_5 [] = {1.0};
  double ucaps_6 [] = {1.0};

  double dem_a [] = {5.0, 4.9};
  double dem_b [] = {4.0};
  double sup_c [] = {10.0};
  double sup_d [] = {10.1, 9.1};

  int excl_arcs [] = {1, 2, 4};
  double excl_flow [] = {0, 2, 2, 0, 2, 0, 0};

  std::vector<double> obj_coeffs;
  for (int i = 0; i != narcs + nfaux; i++) {
    obj_coeffs.push_back((excl_flow[i] != 0) ?
                         excl_flow[i] * prefs[i] : prefs[i]);
  }

  ExchangeNode::Ptr a0(new ExchangeNode());
  ExchangeNode::Ptr a1(new ExchangeNode());
  ExchangeNode::Ptr b0(new ExchangeNode());
  ExchangeNode::Ptr b1(new ExchangeNode());
  ExchangeNode::Ptr c0(new ExchangeNode());
  ExchangeNode::Ptr c1(new ExchangeNode());
  ExchangeNode::Ptr c2(new ExchangeNode());
  ExchangeNode::Ptr d0(new ExchangeNode());
  ExchangeNode::Ptr d1(new ExchangeNode());

  Arc x0(a0, c0);
  Arc x1(b0, c1, true, excl_flow[1]);
  Arc x2(b1, c2, true, excl_flow[2]);
  Arc x3(a1, d0);
  Arc x4(b1, d1, true, excl_flow[4]);

  a0->unit_capacities[x0] = std::vector<double>(
      ucaps_a_0, ucaps_a_0 + sizeof(ucaps_a_0) / sizeof(ucaps_a_0[0]) );
  a1->unit_capacities[x3] = std::vector<double>(
      ucaps_a_3, ucaps_a_3 + sizeof(ucaps_a_3) / sizeof(ucaps_a_3[0]) );
  b0->unit_capacities[x1] = std::vector<double>(
      ucaps_b_1, ucaps_b_1 + sizeof(ucaps_b_1) / sizeof(ucaps_b_1[0]) );
  b1->unit_capacities[x2] = std::vector<double>(
      ucaps_b_2, ucaps_b_2 + sizeof(ucaps_b_2) / sizeof(ucaps_b_2[0]) );
  b1->unit_capacities[x4] = std::vector<double>(
      ucaps_b_4, ucaps_b_4 + sizeof(ucaps_b_4) / sizeof(ucaps_b_4[0]) );
  c0->unit_capacities[x0] = std::vector<double>(
      ucaps_c_0, ucaps_c_0 + sizeof(ucaps_c_0) / sizeof(ucaps_c_0[0]) );
  c1->unit_capacities[x1] = std::vector<double>(
      ucaps_c_1, ucaps_c_1 + sizeof(ucaps_c_1) / sizeof(ucaps_c_1[0]) );
  c2->unit_capacities[x2] = std::vector<double>(
      ucaps_c_2, ucaps_c_2 + sizeof(ucaps_c_2) / sizeof(ucaps_c_2[0]) );
  d0->unit_capacities[x3] = std::vector<double>(
      ucaps_d_3, ucaps_d_3 + sizeof(ucaps_d_3) / sizeof(ucaps_d_3[0]) );
  d1->unit_capacities[x4] = std::vector<double>(
      ucaps_d_4, ucaps_d_4 + sizeof(ucaps_d_4) / sizeof(ucaps_d_4[0]) );

  a0->prefs[x0] = prefs[0];
  b0->prefs[x1] = prefs[1];
  b1->prefs[x2] = prefs[2];
  a1->prefs[x3] = prefs[3];
  b1->prefs[x4] = prefs[4];

  RequestGroup::Ptr a(new RequestGroup()); // new RequestGroup(dem_a[0])?
  a->AddExchangeNode(a0);
  a->AddExchangeNode(a1);
  a->AddCapacity(dem_a[0]);
  a->AddCapacity(dem_a[1]);
  RequestGroup::Ptr b(new RequestGroup()); // new RequestGroup(dem_b[0])?
  b->AddExchangeNode(b0);
  b->AddExchangeNode(b1);
  b->AddCapacity(dem_b[0]);
  ExchangeNodeGroup::Ptr c(new ExchangeNodeGroup());
  c->AddExchangeNode(c0);
  c->AddExchangeNode(c1);
  c->AddExchangeNode(c2);
  c->AddCapacity(sup_c[0]);
  ExchangeNodeGroup::Ptr d(new ExchangeNodeGroup());
  d->AddExchangeNode(d0);
  d->AddExchangeNode(d1);
  d->AddCapacity(sup_d[0]);
  d->AddCapacity(sup_d[1]);

  ExchangeGraph g;
  g.AddRequestGroup(a);
  g.AddRequestGroup(b);
  g.AddSupplyGroup(c);
  g.AddSupplyGroup(d);
  g.AddArc(x0);
  g.AddArc(x1);
  g.AddArc(x2);
  g.AddArc(x3);
  g.AddArc(x4);

  SolverFactory sf;
  sf.solver_t("cbc");
  OsiSolverInterface* iface = sf.get();
  CoinMessageHandler h;
  h.setLogLevel(0);
  iface->passInMessageHandler(&h);
  bool excl = true;
  ProgTranslator pt(&g, iface, excl);
  EXPECT_NO_THROW(pt.Translate());

  double inf = iface->getInfinity();

  // test non-coin xlate members
  double col_lbs [] = {0, 0, 0, 0, 0, 0, 0};
  double col_ubs [] = {inf, 1, 1, inf, 1, inf, inf};
  double row_lbs [] = {0, 0, 0, dem_a[0], dem_a[1], dem_b[0], 0, 0};
  double row_ubs [] = {sup_c[0], sup_d[0], sup_d[1], inf, inf, inf, 1, 1};
  array_double_eq(&obj_coeffs[0], &pt.ctx().obj_coeffs[0], narcs + nfaux, "obj");
  array_double_eq(col_ubs, &pt.ctx().col_ubs[0], narcs + nfaux, "col_ub");
  array_double_eq(col_lbs, &pt.ctx().col_lbs[0], narcs + nfaux, "col_lb");
  array_double_eq(row_ubs, &pt.ctx().row_ubs[0], nrows, "row_ub");
  array_double_eq(row_lbs, &pt.ctx().row_lbs[0], nrows, "row_lb");

  for (int i = 0; i != 7; i++) {
    EXPECT_DOUBLE_EQ(col_lbs[i], pt.ctx().col_lbs[i]);
  }

  // test coin xlate members
  CoinPackedMatrix m(false, 0, 0);
  m.setDimensions(0, narcs + nfaux);

  int row_ind_0 [] = {0, 1, 2};
  double row_val_0 [] = {ucaps_c_0[0],
                         ucaps_c_1[0] * excl_flow[1],
                         ucaps_c_2[0] * excl_flow[2]};
  m.appendRow(3, row_ind_0, row_val_0);

  int row_ind_1 [] = {3, 4};
  double row_val_1 [] = {ucaps_d_3[0],
                         ucaps_d_4[0] * excl_flow[4]};
  m.appendRow(2, row_ind_1, row_val_1);

  int row_ind_2 [] = {3, 4};
  double row_val_2 [] = {ucaps_d_3[1],
                         ucaps_d_4[1] * excl_flow[4]};
  m.appendRow(2, row_ind_2, row_val_2);

  int row_ind_3 [] = {0, 3, 5};
  double row_val_3 [] = {ucaps_a_0[0], ucaps_a_3[0], 1};
  m.appendRow(3, row_ind_3, row_val_3);

  int row_ind_4 [] = {0, 3, 5};
  double row_val_4 [] = {ucaps_a_0[1], ucaps_a_3[1], 1};
  m.appendRow(3, row_ind_4, row_val_4);

  int row_ind_5 [] = {1, 2, 4, 6};
  double row_val_5 [] = {ucaps_b_1[0] * excl_flow[1],
                         ucaps_b_2[0] * excl_flow[2],
                         ucaps_b_4[0] * excl_flow[4],
                         1};
  m.appendRow(4, row_ind_5, row_val_5);

  int row_ind_6 [] = {1};
  double row_val_6 [] = {1};
  m.appendRow(1, row_ind_6, row_val_6);

  int row_ind_7 [] = {2, 4};
  double row_val_7 [] = {1, 1};
  m.appendRow(2, row_ind_7, row_val_7);

  EXPECT_TRUE(m.isEquivalent2(pt.ctx().m));

  // test population
  EXPECT_NO_THROW(pt.Populate());

  for (int i = 0; i != nexcl; i++) {
    EXPECT_TRUE(iface->isInteger(excl_arcs[i]));
  }

  // verify problem instance
  OsiClpSolverInterface checkface;
  checkface.loadProblem(m, &col_lbs[0], &col_ubs[0],
                        &obj_coeffs[0], &row_lbs[0], &row_ubs[0]);
  for (int i = 0; i != nexcl; i++) {
    checkface.setInteger(excl_arcs[i]);
  }
  EXPECT_EQ(0, differentModel(*iface, checkface));
  differentModel(*iface, checkface);

  checkface.passInMessageHandler(&h);
  checkface.setObjSense(-1.0);
  checkface.initialSolve();
  checkface.branchAndBound();

  // verify solution
  EXPECT_NO_THROW(Solve(iface));
  const double* soln = iface->getColSolution();
  const double* check = checkface.getColSolution();
  array_double_eq(soln, check, narcs + nfaux);

  // validate solution
  double x0_flow = (sup_c[0] -
                    ucaps_c_1[0] * excl_flow[1] - ucaps_c_2[0] * excl_flow[2]) /
                   ucaps_c_0[0]; // 9.42857..
  double x1_flow = excl_flow[1];
  double x2_flow = excl_flow[2];
  double x3_flow = sup_d[1] / ucaps_d_3[1]; // 4.55
  double x4_flow = 0;

  // first faux arc
  double x5_flow = 0;
  // second faux arc
  double x6_flow = dem_b[0] -
                   ucaps_b_1[0] * excl_flow[1] -
                   ucaps_b_2[0] * excl_flow[2]; // 0.6;

  EXPECT_DOUBLE_EQ(soln[0], x0_flow);
  EXPECT_EQ(soln[1], 1);
  EXPECT_EQ(soln[2], 1);
  EXPECT_DOUBLE_EQ(soln[3], x3_flow);
  EXPECT_EQ(soln[4], 0);
  EXPECT_DOUBLE_EQ(soln[5], 0);
  EXPECT_DOUBLE_EQ(soln[6], x6_flow);

  // check back translation
  pt.FromProg();
  const std::vector<Match>& matches = g.matches();
  ASSERT_EQ(4, matches.size());
  pair_double_eq(matches[0], std::pair<Arc, double>(x0, x0_flow));
  pair_double_eq(matches[1], std::pair<Arc, double>(x1, x1_flow));
  pair_double_eq(matches[2], std::pair<Arc, double>(x2, x2_flow));
  pair_double_eq(matches[3], std::pair<Arc, double>(x3, x3_flow));

  delete iface;
};

} // namespace cyclus
<|endoftext|>


<commit_before>/**
 * @file
 */
#include "bi/type/FunctionType.hpp"

#include "bi/visitor/all.hpp"

bi::FunctionType::FunctionType(Type* params, Type* returnType, Location* loc,
    const bool assignable) :
    Type(loc, assignable),
    ReturnTyped(returnType),
    params(params) {
  //
}

bi::FunctionType::~FunctionType() {
  //
}

bool bi::FunctionType::isFunction() const {
  return true;
}

bi::Type* bi::FunctionType::resolve(Type* args) {
  if (args->definitely(*params)) {
    return returnType;
  } else {
    return nullptr;
  }
}

bi::Type* bi::FunctionType::accept(Cloner* visitor) const {
  return visitor->clone(this);
}

bi::Type* bi::FunctionType::accept(Modifier* visitor) {
  return visitor->modify(this);
}

void bi::FunctionType::accept(Visitor* visitor) const {
  return visitor->visit(this);
}

bool bi::FunctionType::dispatchDefinitely(const Type& o) const {
  return o.definitely(*this);
}

bool bi::FunctionType::definitely(const AliasType& o) const {
  return definitely(*o.target->base);
}

bool bi::FunctionType::definitely(const FunctionType& o) const {
  return params->definitely(*o.params);
}

bool bi::FunctionType::definitely(const OptionalType& o) const {
  return definitely(*o.single);
}

bool bi::FunctionType::definitely(const ParenthesesType& o) const {
  return definitely(*o.single);
}

bool bi::FunctionType::dispatchPossibly(const Type& o) const {
  return o.possibly(*this);
}

bool bi::FunctionType::possibly(const AliasType& o) const {
  return possibly(*o.target->base);
}

bool bi::FunctionType::possibly(const FunctionType& o) const {
  return params->possibly(*o.params);
}

bool bi::FunctionType::possibly(const OptionalType& o) const {
  return possibly(*o.single);
}

bool bi::FunctionType::possibly(const ParenthesesType& o) const {
  return possibly(*o.single);
}
<commit_msg>Added return type to function type comparisons (needed for e.g. lambdas, posets of functions use only the type of parameters for ordering anyway).<commit_after>/**
 * @file
 */
#include "bi/type/FunctionType.hpp"

#include "bi/visitor/all.hpp"

bi::FunctionType::FunctionType(Type* params, Type* returnType, Location* loc,
    const bool assignable) :
    Type(loc, assignable),
    ReturnTyped(returnType),
    params(params) {
  //
}

bi::FunctionType::~FunctionType() {
  //
}

bool bi::FunctionType::isFunction() const {
  return true;
}

bi::Type* bi::FunctionType::resolve(Type* args) {
  if (args->definitely(*params)) {
    return returnType;
  } else {
    return nullptr;
  }
}

bi::Type* bi::FunctionType::accept(Cloner* visitor) const {
  return visitor->clone(this);
}

bi::Type* bi::FunctionType::accept(Modifier* visitor) {
  return visitor->modify(this);
}

void bi::FunctionType::accept(Visitor* visitor) const {
  return visitor->visit(this);
}

bool bi::FunctionType::dispatchDefinitely(const Type& o) const {
  return o.definitely(*this);
}

bool bi::FunctionType::definitely(const AliasType& o) const {
  return definitely(*o.target->base);
}

bool bi::FunctionType::definitely(const FunctionType& o) const {
  return params->definitely(*o.params)
      && returnType->definitely(*o.returnType);
}

bool bi::FunctionType::definitely(const OptionalType& o) const {
  return definitely(*o.single);
}

bool bi::FunctionType::definitely(const ParenthesesType& o) const {
  return definitely(*o.single);
}

bool bi::FunctionType::dispatchPossibly(const Type& o) const {
  return o.possibly(*this);
}

bool bi::FunctionType::possibly(const AliasType& o) const {
  return possibly(*o.target->base);
}

bool bi::FunctionType::possibly(const FunctionType& o) const {
  return params->possibly(*o.params) && returnType->possibly(*o.returnType);
}

bool bi::FunctionType::possibly(const OptionalType& o) const {
  return possibly(*o.single);
}

bool bi::FunctionType::possibly(const ParenthesesType& o) const {
  return possibly(*o.single);
}
<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// Software Guide : BeginLatex
//
// After having generated a classification map, it is possible to
// regularize such a labeled image in order to obtain more homogeneous
// areas, which makes the interpretation of its classes easier. For this
// purpose, the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter} was
// implemented. Like a morphological filter, this filter uses majority
// voting in a ball shaped neighborhood in order to set each pixel of the
// classification map to the more representative label value in its
// neighborhood.
//
// In this example we will illustrate its use. We start by including the
// appropriate header file.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbNeighborhoodMajorityVotingImageFilter.h"
// Software Guide : EndCodeSnippet

#include "itkMacro.h"
#include "otbImage.h"
#include <iostream>

#include <otbImageFileReader.h>
#include "otbImageFileWriter.h"

#include "itkTimeProbe.h"

int main(int argc, char * argv[])
{
// Software Guide : BeginLatex
//
// Since the input image is a classification map, we will assume a
// single band input image for which each pixel value is a label coded
// on 8 bits as an integer between 0 and 255.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef unsigned char InputLabelPixelType;
  typedef unsigned char OutputLabelPixelType;
  const unsigned int Dimension = 2;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Thus, both input and output images are single band labeled images,
// which are composed of the same type of pixels in this example
// (unsigned char).
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef otb::Image<InputLabelPixelType, Dimension> InputLabelImageType;
  typedef otb::Image<OutputLabelPixelType, Dimension> OutputLabelImageType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// We can now define the type for the neighborhood majority voting filter,
// which is templated over its input and output images types and over its
// structuring element type.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  // Neighborhood majority voting filter type
  typedef otb::NeighborhoodMajorityVotingImageFilter<InputLabelImageType,
   OutputLabelImageType> NeighborhoodMajorityVotingFilterType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Since the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter} is a
// neighborhood based image filter, it is necessary to set the structuring
// element which will be used for the majority voting process. By default, the
// structuring element is a ball
// (\doxygen{itk}{BinaryBallStructuringElement}) with a radius defined by two sizes
// (respectively along X and Y). Thus, it is possible to handle anisotropic
// structuring elements such as ovals.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  // Binary ball Structuring Element type
  typedef NeighborhoodMajorityVotingFilterType::KernelType StructuringType;
  typedef StructuringType::RadiusType RadiusType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Finally, we define the reader and the writer.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef otb::ImageFileReader<InputLabelImageType> ReaderType;
  typedef otb::ImageFileWriter<OutputLabelImageType> WriterType;
// Software Guide : EndCodeSnippet

  const char * inputFileName = argv[1];
  const char * outputFileName = argv[2];

// Software Guide : BeginLatex
//
// We instantiate the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter} and the
// reader objects.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  // Neighborhood majority voting filter
  NeighborhoodMajorityVotingFilterType::Pointer NeighMajVotingFilter;
  NeighMajVotingFilter = NeighborhoodMajorityVotingFilterType::New();

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(inputFileName);
// Software Guide : EndCodeSnippet

  std::string KeepOriginalLabelBoolStr = argv[3];
  unsigned int radiusX = atoi(argv[4]);
  unsigned int radiusY = atoi(argv[5]);
  OutputLabelPixelType noDataValue = atoi(argv[6]);
  OutputLabelPixelType undecidedValue = atoi(argv[7]);

// Software Guide : BeginLatex
//
// The ball shaped structuring element seBall is instantiated and its
// two radii along X and Y are initialized.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  StructuringType seBall;
  RadiusType rad;

  rad[0] = radiusX;
  rad[1] = radiusY;

  seBall.SetRadius(rad);
  seBall.CreateStructuringElement();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Then, this ball shaped neighborhood is used as the kernel structuring element
// for the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter}.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetKernel(seBall);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Not classified input pixels are assumed to have the noDataValue label
// and will keep this label in the output image.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetLabelForNoDataPixels(noDataValue);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Moreover, since the majority voting regularization may lead to not unique
// majority labels in the neighborhood, it is important to define which behaviour
// the filter must have in this case. For this purpose, a Boolean parameter is used
// in the filter to choose whether pixels with more than one majority class are set
// to undecidedValue (true), or to their Original labels (false = default value)
// in the output image.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetLabelForUndecidedPixels(undecidedValue);

  if (KeepOriginalLabelBoolStr.compare("true") == 0)
  {
    NeighMajVotingFilter->SetKeepOriginalLabelBool(true);
  }
  else
  {
    NeighMajVotingFilter->SetKeepOriginalLabelBool(false);
  }
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// We plug the pipeline and
// trigger its execution by updating the output of the writer.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetInput(reader->GetOutput());

  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName(outputFileName);
  writer->SetInput(NeighMajVotingFilter->GetOutput());
  writer->Update();
// Software Guide : EndCodeSnippet

  return EXIT_SUCCESS;
}
<commit_msg>STYLE<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// Software Guide : BeginLatex
//
// After having generated a classification map, it is possible to
// regularize such a labeled image in order to obtain more homogeneous
// areas, which makes the interpretation of its classes easier. For this
// purpose, the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter} was
// implemented. Like a morphological filter, this filter uses majority
// voting in a ball shaped neighborhood in order to set each pixel of the
// classification map to the more representative label value in its
// neighborhood.
//
// In this example we will illustrate its use. We start by including the
// appropriate header file.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbNeighborhoodMajorityVotingImageFilter.h"
// Software Guide : EndCodeSnippet

#include "itkMacro.h"
#include "otbImage.h"
#include <iostream>

#include <otbImageFileReader.h>
#include "otbImageFileWriter.h"

#include "itkTimeProbe.h"

int main(int argc, char * argv[])
{
// Software Guide : BeginLatex
//
// Since the input image is a classification map, we will assume a
// single band input image for which each pixel value is a label coded
// on 8 bits as an integer between 0 and 255.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef unsigned char InputLabelPixelType;
  typedef unsigned char OutputLabelPixelType;
  const unsigned int Dimension = 2;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Thus, both input and output images are single band labeled images,
// which are composed of the same type of pixels in this example
// (unsigned char).
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef otb::Image<InputLabelPixelType, Dimension> InputLabelImageType;
  typedef otb::Image<OutputLabelPixelType, Dimension> OutputLabelImageType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// We can now define the type for the neighborhood majority voting filter,
// which is templated over its input and output images types and over its
// structuring element type.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  // Neighborhood majority voting filter type
  typedef otb::NeighborhoodMajorityVotingImageFilter<InputLabelImageType,
   OutputLabelImageType> NeighborhoodMajorityVotingFilterType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Since the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter} is a
// neighborhood based image filter, it is necessary to set the structuring
// element which will be used for the majority voting process. By default, the
// structuring element is a ball
// (\doxygen{itk}{BinaryBallStructuringElement}) with a radius defined by two sizes
// (respectively along X and Y). Thus, it is possible to handle anisotropic
// structuring elements such as ovals.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  // Binary ball Structuring Element type
  typedef NeighborhoodMajorityVotingFilterType::KernelType StructuringType;
  typedef StructuringType::RadiusType RadiusType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Finally, we define the reader and the writer.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef otb::ImageFileReader<InputLabelImageType> ReaderType;
  typedef otb::ImageFileWriter<OutputLabelImageType> WriterType;
// Software Guide : EndCodeSnippet

  const char * inputFileName = argv[1];
  const char * outputFileName = argv[2];

// Software Guide : BeginLatex
//
// We instantiate the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter} and the
// reader objects.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  // Neighborhood majority voting filter
  NeighborhoodMajorityVotingFilterType::Pointer NeighMajVotingFilter;
  NeighMajVotingFilter = NeighborhoodMajorityVotingFilterType::New();

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(inputFileName);
// Software Guide : EndCodeSnippet

  std::string KeepOriginalLabelBoolStr = argv[3];
  unsigned int radiusX = atoi(argv[4]);
  unsigned int radiusY = atoi(argv[5]);
  OutputLabelPixelType noDataValue = atoi(argv[6]);
  OutputLabelPixelType undecidedValue = atoi(argv[7]);

// Software Guide : BeginLatex
//
// The ball shaped structuring element seBall is instantiated and its
// two radii along X and Y are initialized.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  StructuringType seBall;
  RadiusType rad;

  rad[0] = radiusX;
  rad[1] = radiusY;

  seBall.SetRadius(rad);
  seBall.CreateStructuringElement();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Then, this ball shaped neighborhood is used as the kernel structuring element
// for the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter}.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetKernel(seBall);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Not classified input pixels are assumed to have the noDataValue label
// and will keep this label in the output image.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetLabelForNoDataPixels(noDataValue);
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Moreover, since the majority voting regularization may lead to not unique
// majority labels in the neighborhood, it is important to define which behaviour
// the filter must have in this case. For this purpose, a Boolean parameter is used
// in the filter to choose whether pixels with more than one majority class are set
// to undecidedValue (true), or to their Original labels (false = default value)
// in the output image.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetLabelForUndecidedPixels(undecidedValue);

  if (KeepOriginalLabelBoolStr.compare("true") == 0)
  {
    NeighMajVotingFilter->SetKeepOriginalLabelBool(true);
  }
  else
  {
    NeighMajVotingFilter->SetKeepOriginalLabelBool(false);
  }
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// We plug the pipeline and
// trigger its execution by updating the output of the writer.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetInput(reader->GetOutput());

  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName(outputFileName);
  writer->SetInput(NeighMajVotingFilter->GetOutput());
  writer->Update();
// Software Guide : EndCodeSnippet

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "orbiteventiterator.h"

#include "absl/strings/str_format.h"
#include "ui_orbiteventiterator.h"

//-----------------------------------------------------------------------------
OrbitEventIterator::OrbitEventIterator(QWidget* parent)
    : QFrame(parent), ui(new Ui::OrbitEventIterator) {
  ui->setupUi(this);
}

//-----------------------------------------------------------------------------
OrbitEventIterator::~OrbitEventIterator() { delete ui; }

//-----------------------------------------------------------------------------
void OrbitEventIterator::on_NextButton_clicked() {
  if (next_button_callback_) {
    next_button_callback_();
  }
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::on_PreviousButton_clicked() {
  if (previous_button_callback_) {
    previous_button_callback_();
  }
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::on_DeleteButton_clicked() {
  if (delete_button_callback_) {
    delete_button_callback_();
  }
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::SetFunctionName(const std::string& function_name) {
  ui->Label->setTextWithElision(QString::fromStdString(function_name));
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::SetMaxCount(int max_count) {
  max_count_ = max_count;
  UpdateCountLabel();
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::SetIndex(int current_index) {
  current_index_ = 0;
  UpdateCountLabel();
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::IncrementIndex() {
  if (current_index_ < max_count_ - 1) {
    ++current_index_;
    UpdateCountLabel();
  }
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::DecrementIndex() {
  if (current_index_ > 0) {
    --current_index_;
    UpdateCountLabel();
  }
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::UpdateCountLabel() {
  ui->CountLabel->setText(QString::fromStdString(
      absl::StrFormat("%d / %d", current_index_, max_count_)));
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::HideDeleteButton() { ui->DeleteButton->hide(); }

//-----------------------------------------------------------------------------
void OrbitEventIterator::EnableButtons() {
  ui->NextButton->setEnabled(true);
  ui->PreviousButton->setEnabled(true);
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::DisableButtons() {
  ui->NextButton->setEnabled(false);
  ui->PreviousButton->setEnabled(false);
}<commit_msg>Show instances of function calls starting at 1 not at index 0<commit_after>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "orbiteventiterator.h"

#include "absl/strings/str_format.h"
#include "ui_orbiteventiterator.h"

//-----------------------------------------------------------------------------
OrbitEventIterator::OrbitEventIterator(QWidget* parent)
    : QFrame(parent), ui(new Ui::OrbitEventIterator) {
  ui->setupUi(this);
}

//-----------------------------------------------------------------------------
OrbitEventIterator::~OrbitEventIterator() { delete ui; }

//-----------------------------------------------------------------------------
void OrbitEventIterator::on_NextButton_clicked() {
  if (next_button_callback_) {
    next_button_callback_();
  }
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::on_PreviousButton_clicked() {
  if (previous_button_callback_) {
    previous_button_callback_();
  }
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::on_DeleteButton_clicked() {
  if (delete_button_callback_) {
    delete_button_callback_();
  }
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::SetFunctionName(const std::string& function_name) {
  ui->Label->setTextWithElision(QString::fromStdString(function_name));
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::SetMaxCount(int max_count) {
  max_count_ = max_count;
  UpdateCountLabel();
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::SetIndex(int current_index) {
  current_index_ = 0;
  UpdateCountLabel();
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::IncrementIndex() {
  if (current_index_ < max_count_ - 1) {
    ++current_index_;
    UpdateCountLabel();
  }
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::DecrementIndex() {
  if (current_index_ > 0) {
    --current_index_;
    UpdateCountLabel();
  }
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::UpdateCountLabel() {
  // Indices start at 0, so we display index + 1 in the UI.
  ui->CountLabel->setText(QString::fromStdString(
      absl::StrFormat("%d / %d", current_index_ + 1, max_count_)));
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::HideDeleteButton() { ui->DeleteButton->hide(); }

//-----------------------------------------------------------------------------
void OrbitEventIterator::EnableButtons() {
  ui->NextButton->setEnabled(true);
  ui->PreviousButton->setEnabled(true);
}

//-----------------------------------------------------------------------------
void OrbitEventIterator::DisableButtons() {
  ui->NextButton->setEnabled(false);
  ui->PreviousButton->setEnabled(false);
}<|endoftext|>