<commit_before>// Copyright (c) 2011 The Chromium 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 "chrome/renderer/extensions/chrome_app_bindings.h"

#include "base/command_line.h"
#include "base/json/json_writer.h"
#include "base/string16.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_set.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/extension_helper.h"
#include "content/renderer/render_view.h"
#include "content/renderer/v8_value_converter.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "v8/include/v8.h"

using WebKit::WebFrame;

namespace {

bool IsCheckoutURL(const std::string& url_spec) {
  std::string checkout_url_prefix =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kAppsCheckoutURL);
  if (checkout_url_prefix.empty())
    checkout_url_prefix = "https://checkout.google.com/";

  return StartsWithASCII(url_spec, checkout_url_prefix, false);
}

bool CheckAccessToAppDetails() {
  WebFrame* frame = WebFrame::frameForCurrentContext();
  if (!frame) {
    LOG(ERROR) << "Could not get frame for current context.";
    return false;
  }

  if (!IsCheckoutURL(frame->document().url().spec())) {
    std::string error("Access denied for URL: ");
    error += frame->document().url().spec();
    v8::ThrowException(v8::String::New(error.c_str()));
    return false;
  }

  return true;
}

}

namespace extensions_v8 {

static const char* const kAppExtensionName = "v8/ChromeApp";

class ChromeAppExtensionWrapper : public v8::Extension {
 public:
  explicit ChromeAppExtensionWrapper(ExtensionDispatcher* extension_dispatcher) :
    v8::Extension(kAppExtensionName,
      "var chrome;"
      "if (!chrome)"
      "  chrome = {};"
      "if (!chrome.app) {"
      "  chrome.app = new function() {"
      "    native function GetIsInstalled();"
      "    native function Install();"
      "    native function GetDetails();"
      "    native function GetDetailsForFrame();"
      "    this.__defineGetter__('isInstalled', GetIsInstalled);"
      "    this.install = Install;"
      "    this.getDetails = GetDetails;"
      "    this.getDetailsForFrame = GetDetailsForFrame;"
      "  };"
      "}") {
    extension_dispatcher_ = extension_dispatcher;
  }

  ~ChromeAppExtensionWrapper() {
    extension_dispatcher_ = NULL;
  }

  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
      v8::Handle<v8::String> name) {
    if (name->Equals(v8::String::New("GetIsInstalled"))) {
      return v8::FunctionTemplate::New(GetIsInstalled);
    } else if (name->Equals(v8::String::New("Install"))) {
      return v8::FunctionTemplate::New(Install);
    } else if (name->Equals(v8::String::New("GetDetails"))) {
      return v8::FunctionTemplate::New(GetDetails);
    } else if (name->Equals(v8::String::New("GetDetailsForFrame"))) {
      return v8::FunctionTemplate::New(GetDetailsForFrame);
    } else {
      return v8::Handle<v8::FunctionTemplate>();
    }
  }

  static v8::Handle<v8::Value> GetIsInstalled(const v8::Arguments& args) {
    WebFrame* frame = WebFrame::frameForCurrentContext();
    if (!frame)
      return v8::Boolean::New(false);

    GURL url(frame->document().url());
    if (url.is_empty() ||
        !url.is_valid() ||
        !(url.SchemeIs("http") || url.SchemeIs("https")))
      return v8::Boolean::New(false);

    const ::Extension* extension =
        extension_dispatcher_->extensions()->GetByURL(frame->document().url());

    bool has_web_extent = extension &&
        extension_dispatcher_->IsApplicationActive(extension->id());
    return v8::Boolean::New(has_web_extent);
  }

  static v8::Handle<v8::Value> Install(const v8::Arguments& args) {
    WebFrame* frame = WebFrame::frameForCurrentContext();
    RenderView* render_view = bindings_utils::GetRenderViewForCurrentContext();
    if (frame && render_view) {
      string16 error;

      ExtensionHelper* helper = ExtensionHelper::Get(render_view);
      if (!helper->InstallWebApplicationUsingDefinitionFile(frame, &error))
        v8::ThrowException(v8::String::New(UTF16ToUTF8(error).c_str()));
    }

    return v8::Undefined();
  }

  static v8::Handle<v8::Value> GetDetails(const v8::Arguments& args) {
    return GetDetailsForFrameImpl(WebFrame::frameForCurrentContext());
  }

  static v8::Handle<v8::Value> GetDetailsForFrame(
      const v8::Arguments& args) {
    if (!CheckAccessToAppDetails())
      return v8::Undefined();

    if (args.Length() < 0)
      return v8::ThrowException(v8::String::New("Not enough arguments."));

    if (!args[0]->IsObject()) {
      return v8::ThrowException(
          v8::String::New("Argument 0 must be an object."));
    }

    v8::Local<v8::Context> context =
        v8::Local<v8::Object>::Cast(args[0])->CreationContext();
    CHECK(!context.IsEmpty());

    WebFrame* target_frame = WebFrame::frameForContext(context);
    if (!target_frame) {
      return v8::ThrowException(
          v8::String::New("Could not find frame for specified object."));
    }

    return GetDetailsForFrameImpl(target_frame);
  }

  static v8::Handle<v8::Value> GetDetailsForFrameImpl(const WebFrame* frame) {
    const ::Extension* extension =
        extension_dispatcher_->extensions()->GetByURL(frame->document().url());
    if (!extension)
      return v8::Null();

    scoped_ptr<DictionaryValue> manifest_copy(
        extension->manifest_value()->DeepCopy());
    manifest_copy->SetString("id", extension->id());
    V8ValueConverter converter;
    return converter.ToV8Value(manifest_copy.get(),
                               frame->mainWorldScriptContext());
  }

  static ExtensionDispatcher* extension_dispatcher_;
};

ExtensionDispatcher* ChromeAppExtensionWrapper::extension_dispatcher_;

v8::Extension* ChromeAppExtension::Get(
    ExtensionDispatcher* extension_dispatcher) {
  return new ChromeAppExtensionWrapper(extension_dispatcher);
}

}  // namespace extensions_v8
<commit_msg>renderer/extensions: Return v8::False() where possible.<commit_after>// Copyright (c) 2011 The Chromium 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 "chrome/renderer/extensions/chrome_app_bindings.h"

#include "base/command_line.h"
#include "base/json/json_writer.h"
#include "base/string16.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_set.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/extension_helper.h"
#include "content/renderer/render_view.h"
#include "content/renderer/v8_value_converter.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "v8/include/v8.h"

using WebKit::WebFrame;

namespace {

bool IsCheckoutURL(const std::string& url_spec) {
  std::string checkout_url_prefix =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kAppsCheckoutURL);
  if (checkout_url_prefix.empty())
    checkout_url_prefix = "https://checkout.google.com/";

  return StartsWithASCII(url_spec, checkout_url_prefix, false);
}

bool CheckAccessToAppDetails() {
  WebFrame* frame = WebFrame::frameForCurrentContext();
  if (!frame) {
    LOG(ERROR) << "Could not get frame for current context.";
    return false;
  }

  if (!IsCheckoutURL(frame->document().url().spec())) {
    std::string error("Access denied for URL: ");
    error += frame->document().url().spec();
    v8::ThrowException(v8::String::New(error.c_str()));
    return false;
  }

  return true;
}

}

namespace extensions_v8 {

static const char* const kAppExtensionName = "v8/ChromeApp";

class ChromeAppExtensionWrapper : public v8::Extension {
 public:
  explicit ChromeAppExtensionWrapper(ExtensionDispatcher* extension_dispatcher) :
    v8::Extension(kAppExtensionName,
      "var chrome;"
      "if (!chrome)"
      "  chrome = {};"
      "if (!chrome.app) {"
      "  chrome.app = new function() {"
      "    native function GetIsInstalled();"
      "    native function Install();"
      "    native function GetDetails();"
      "    native function GetDetailsForFrame();"
      "    this.__defineGetter__('isInstalled', GetIsInstalled);"
      "    this.install = Install;"
      "    this.getDetails = GetDetails;"
      "    this.getDetailsForFrame = GetDetailsForFrame;"
      "  };"
      "}") {
    extension_dispatcher_ = extension_dispatcher;
  }

  ~ChromeAppExtensionWrapper() {
    extension_dispatcher_ = NULL;
  }

  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
      v8::Handle<v8::String> name) {
    if (name->Equals(v8::String::New("GetIsInstalled"))) {
      return v8::FunctionTemplate::New(GetIsInstalled);
    } else if (name->Equals(v8::String::New("Install"))) {
      return v8::FunctionTemplate::New(Install);
    } else if (name->Equals(v8::String::New("GetDetails"))) {
      return v8::FunctionTemplate::New(GetDetails);
    } else if (name->Equals(v8::String::New("GetDetailsForFrame"))) {
      return v8::FunctionTemplate::New(GetDetailsForFrame);
    } else {
      return v8::Handle<v8::FunctionTemplate>();
    }
  }

  static v8::Handle<v8::Value> GetIsInstalled(const v8::Arguments& args) {
    WebFrame* frame = WebFrame::frameForCurrentContext();
    if (!frame)
      return v8::False();

    GURL url(frame->document().url());
    if (url.is_empty() ||
        !url.is_valid() ||
        !(url.SchemeIs("http") || url.SchemeIs("https")))
      return v8::False();

    const ::Extension* extension =
        extension_dispatcher_->extensions()->GetByURL(frame->document().url());

    bool has_web_extent = extension &&
        extension_dispatcher_->IsApplicationActive(extension->id());
    return v8::Boolean::New(has_web_extent);
  }

  static v8::Handle<v8::Value> Install(const v8::Arguments& args) {
    WebFrame* frame = WebFrame::frameForCurrentContext();
    RenderView* render_view = bindings_utils::GetRenderViewForCurrentContext();
    if (frame && render_view) {
      string16 error;

      ExtensionHelper* helper = ExtensionHelper::Get(render_view);
      if (!helper->InstallWebApplicationUsingDefinitionFile(frame, &error))
        v8::ThrowException(v8::String::New(UTF16ToUTF8(error).c_str()));
    }

    return v8::Undefined();
  }

  static v8::Handle<v8::Value> GetDetails(const v8::Arguments& args) {
    return GetDetailsForFrameImpl(WebFrame::frameForCurrentContext());
  }

  static v8::Handle<v8::Value> GetDetailsForFrame(
      const v8::Arguments& args) {
    if (!CheckAccessToAppDetails())
      return v8::Undefined();

    if (args.Length() < 0)
      return v8::ThrowException(v8::String::New("Not enough arguments."));

    if (!args[0]->IsObject()) {
      return v8::ThrowException(
          v8::String::New("Argument 0 must be an object."));
    }

    v8::Local<v8::Context> context =
        v8::Local<v8::Object>::Cast(args[0])->CreationContext();
    CHECK(!context.IsEmpty());

    WebFrame* target_frame = WebFrame::frameForContext(context);
    if (!target_frame) {
      return v8::ThrowException(
          v8::String::New("Could not find frame for specified object."));
    }

    return GetDetailsForFrameImpl(target_frame);
  }

  static v8::Handle<v8::Value> GetDetailsForFrameImpl(const WebFrame* frame) {
    const ::Extension* extension =
        extension_dispatcher_->extensions()->GetByURL(frame->document().url());
    if (!extension)
      return v8::Null();

    scoped_ptr<DictionaryValue> manifest_copy(
        extension->manifest_value()->DeepCopy());
    manifest_copy->SetString("id", extension->id());
    V8ValueConverter converter;
    return converter.ToV8Value(manifest_copy.get(),
                               frame->mainWorldScriptContext());
  }

  static ExtensionDispatcher* extension_dispatcher_;
};

ExtensionDispatcher* ChromeAppExtensionWrapper::extension_dispatcher_;

v8::Extension* ChromeAppExtension::Get(
    ExtensionDispatcher* extension_dispatcher) {
  return new ChromeAppExtensionWrapper(extension_dispatcher);
}

}  // namespace extensions_v8
<|endoftext|>


<commit_before>/*
 * Software License Agreement (Apache License)
 *
 * Copyright (c) 2014, Southwest Research Institute
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include <industrial_extrinsic_cal/basic_types.h>

namespace industrial_extrinsic_cal
{

  Pose6d::Pose6d(double tx, double ty, double tz, double aax, double aay, double aaz)
  {
    x = tx;
    y = ty;
    z = tz;
    ax = aax;
    ay = aay;
    az = aaz;
  }
  Pose6d::Pose6d()
  {
    x=y=z=ax=ay=az=0.0;
  }
  void Pose6d::setBasis( tf::Matrix3x3 & m)
  {
    // see Google ceres rotation.h for the source of these computations, I copied them
    // from the RotationMatrixToAngleAxis()
    ax = m[2][1] - m[1][2]; // R[5] - R[7]
    ay = m[0][2] - m[2][0]; // R[6] - R[2]
    az = m[1][0] - m[0][1]; // R[1] - R[3]
    double costheta = std::min(std::max((m[0][0] + m[1][1] + m[2][2] - 1.0) / 2.0, -1.0), 1.0);
    double sintheta = std::min(sqrt(ax * ax + ay*ay + az*az) / 2.0, 1.0);
    double theta = atan2(sintheta, costheta);
    static double kThreshold = 1e-12;
    if ((sintheta > kThreshold) || (sintheta < -kThreshold)) {
      double r = theta / (2.0 * sintheta);
      ax *= r;
      ay *= r;
      az *= r;
      return;
    }
    if (costheta > 0.0) {
      ax *= 0.5;
      ay *= 0.5;
      az *= 0.5;
      return;
    }
    double inv_one_minus_costheta = 1.0/ (1.0 - costheta);
    ax = theta * sqrt((m[0][0] - costheta) * inv_one_minus_costheta);
    if (((sintheta < 0.0) && (ax > 0.0)) ||((sintheta > 0.0) && (ax < 0.0))) {
      ax = -ax;
    }
    ay = theta * sqrt((m[1][1] - costheta) * inv_one_minus_costheta);
    if (((sintheta < 0.0) && (ay > 0.0)) ||((sintheta > 0.0) && (ay < 0.0))) {
      ay = -ay;
    }
    az = theta * sqrt((m[2][2] - costheta) * inv_one_minus_costheta);
    if (((sintheta < 0.0) && (az > 0.0)) ||((sintheta > 0.0) && (az < 0.0))) {
      az = -az;
    }
  }

  void Pose6d::setOrigin(tf::Vector3 & v)
  {
    x = v.m_floats[0];
    y = v.m_floats[1];
    z = v.m_floats[2];
  }

  void Pose6d::setOrigin(double tx, double ty, double tz)
  {
    x = tx;
    y = ty;
    z = tz;
  }

  void Pose6d::setEulerZYX(double ez, double ey, double ex)
  {
    double ci = cos(ex);
    double cj = cos(ey);
    double ch = cos(ez);
    double si = sin(ex);
    double sj = sin(ey);
    double sh = sin(ez);
    double cc = ci*ch;
    double cs = ci*sh;
    double sc = si*ch;
    double ss = si*sh;

    tf::Matrix3x3 m;
    m[0][0] = cj*ch;  m[0][1] = sj*sc - cs;     m[0][2] = sj*cc + ss;
    m[1][0] = cj*sh;  m[1][1] = sj*ss + cc;   m[1][2] = sj*cs - sc;
    m[2][0] = -sj;      m[2][1] = cj*si;           m[2][2] =cj*ci ;

    setBasis(m);
  }

  void Pose6d::setQuaternion(double qx, double qy, double qz, double qw)
  {
    double angle = 2.0 * acos(qw);
    ax = qx / sqrt(1-qw*qw)*angle;
    ay = qy / sqrt(1-qw*qw)*angle;
    az = qz / sqrt(1-qw*qw)*angle;
  }

  void Pose6d::setAngleAxis(double aax, double aay, double aaz)
  {
    ax = aax;
    ay = aay;
    az = aaz;
  }

  tf::Matrix3x3 Pose6d::getBasis() const
  {
    tf::Matrix3x3 R;
    double angle = sqrt(ax*ax + ay*ay + az*az);
    if(angle < .0001){
      R[0][0] = 1.0;  R[0][1] = 0.0;  R[0][2] = 0.0;
      R[1][0] = 0.0;  R[1][1] = 1.0;  R[1][2] = 0.0;
      R[2][0] = 0.0;  R[2][1] = 0.0;  R[2][2] = 1.0;
      return(R);
    }
    double ct = cos(angle);
    double st = sin(angle);
    double ux = ax/angle;
    double uy = ay/angle;
    double uz = az/angle;
    double omct = 1.0 - ct;
    R[0][0] = ct + ux*ux*omct;      R[0][1] = ux*uy*omct - uz*st;   R[0][2] = ux*uz*omct + uy*st;
    R[1][0] = uy*ux*omct + uz*st; R[1][1] =  ct+uy*uy*omct;        R[1][2] = uy*uz*omct - ux*st;
    R[2][0] = uz*ux*omct - uy*st;  R[2][1] =  uz*uy*omct + ux*st;  R[2][2] = ct + uz*uz*omct;
    return(R);
  }

  tf::Vector3 Pose6d::getOrigin() const
  {
    tf::Vector3 V(x, y, z);
    return(V);
  }

    void Pose6d::getEulerZYX(double &ez, double &ey, double &ex) const
    {
     double PI = 4*atan(1);
     double theta;
     double psi;
     double phi;
     tf::Matrix3x3 R = this->getBasis();

     if( fabs(R[2][0]) != 1.0 ){ // cos(theta) = 0.0
       theta = -asin(R[2][0]);
       double ct = cos(theta);
       psi = atan2(R[2][1]/ct, R[2][2]/ct);
       phi = atan2(R[1][0]/ct,R[0][0]/ct);
     }
     else{
       phi = 0.0; // could be anything
       if(R[2][0] == -1.0){
	 theta = PI/2.0;
	 psi = phi + atan2(R[0][1], R[0][2]);
       }
       else{
	 theta = -PI/2.0;
	 psi = -phi + atan2(-R[0][1], -R[0][2]);
       }
     } // end of cos(theta) = 0

     // Rz(phi) * Ry(theta) * Rx(psi)
     ez = phi;
     ey = theta;
     ex = psi;
   }
  void Pose6d::getQuaternion(double &qx,  double &qy, double &qz, double &qw)
  {
    // the following was taken from ceres equivalent function
    double theta_squared = ax*ax + ay*ay + az*az;
    if(theta_squared>0.0){
      double theta = sqrt(theta_squared);
      double half_theta = theta*0.5;
      double k = sin(half_theta)/theta;
      qw = cos(half_theta);
      qx = ax*k;
      qy = ay*k;
      qz = az*k;
    }
    else{ // can't do division by zeor
      double k = 0.5;
      qw = 1.0;
      qx = ax*k;
      qy = ay*k;
      qz = az*k;
    }
  }

  Pose6d Pose6d::getInverse() const
  {
    double newx,newy,newz;
    tf::Matrix3x3 R = getBasis();
    newx =-( R[0][0] * x + R[1][0] * y + R[2][0] * z);
    newy = -(R[0][1] * x + R[1][1] * y + R[2][1] * z);
    newz = -(R[0][2] * x + R[1][2] * y + R[2][2] * z);
    Pose6d new_pose(newx, newy, newz, -ax,- ay, -az);
    return(new_pose);
  }

  void Pose6d::show(std::string message)
  {
    tf::Matrix3x3 basis = this->getBasis();
    double ez_yaw, ey_pitch, ex_roll;
    double qx, qy, qz, qw;
    this->getEulerZYX(ez_yaw,ey_pitch,ex_roll);
    this->getQuaternion(qx, qy, qz, qw);
   printf("%s =[\n %6.3lf  %6.3lf  %6.3lf  %6.3lf\n  %6.3lf  %6.3lf  %6.3lf  %6.3lf\n  %6.3lf  %6.3lf %6.3lf  %6.3lf\n  %6.3lf  %6.3lf %6.3lf  %6.3lf];\n rpy= %6.3lf %6.3lf %6.3lf\n quat= %6.3lf  %6.3lf  %6.3lf %6.3lf\n ",
	      message.c_str(),
	      basis[0][0],basis[0][1], basis[0][2],this->x,
	      basis[1][0],basis[1][1], basis[1][2],this->y,
	      basis[2][0],basis[2][1], basis[2][2],this->z,
	      0.0, 0.0, 0.0, 1.0,
	      ez_yaw, ey_pitch, ex_roll,
	      qx, qy, qz, qw);
  }

  Pose6d Pose6d::operator * ( Pose6d pose2) const
  {
    tf::Matrix3x3  R1   = getBasis();
    tf::Matrix3x3 R2 = pose2.getBasis();
    tf::Vector3 T1     = getOrigin();
    tf::Vector3 T2     = pose2.getOrigin();

    tf::Matrix3x3 R3;
    R3[0][0] = R1[0][0] * R2[0][0] + R1[0][1]*R2[1][0] + R1[0][2]*R2[2][0];
    R3[1][0] = R1[1][0] * R2[0][0] + R1[1][1]*R2[1][0] + R1[1][2]*R2[2][0];
    R3[2][0] = R1[2][0] * R2[0][0] + R1[2][1]*R2[1][0] + R1[2][2]*R2[2][0];

    R3[0][1] = R1[0][0] * R2[0][1] + R1[0][1]*R2[1][1] + R1[0][2]*R2[2][1];
    R3[2][1] = R1[1][0] * R2[0][1] + R1[1][1]*R2[1][1] + R1[1][2]*R2[2][1];
    R3[2][1] = R1[2][0] * R2[0][1] + R1[2][1]*R2[1][1] + R1[2][2]*R2[2][1];

     R3[0][2] = R1[0][0] * R2[0][2] + R1[0][1]*R2[1][2] + R1[0][2]*R2[2][2];
     R3[1][2] = R1[1][0] * R2[0][2] + R1[1][1]*R2[1][2] + R1[1][2]*R2[2][2];
     R3[2][2] = R1[2][0] * R2[0][2] + R1[2][1]*R2[1][2] + R1[2][2]*R2[2][2];

    double tempx, tempy, tempz;
    tempx = R1[0][0] * T2.x() + R1[0][1]*T2.y() + R1[0][2]*T2.z() + T1.x();
    tempy = R1[1][0] * T2.x() + R1[1][1]*T2.y() + R1[1][2]*T2.z() + T1.y();
    tempz = R1[2][0] * T2.x() + R1[2][1]*T2.y() + R1[2][2]*T2.z() + T1.z();
    tf::Vector3 T3(tempx, tempy, tempz);

    Pose6d pose;
    pose.setBasis(R3);
    pose.setOrigin(T3);

    return(pose);
  }

}// end of namespace
<commit_msg>fixed bug in multiply operator<commit_after>/*
 * Software License Agreement (Apache License)
 *
 * Copyright (c) 2014, Southwest Research Institute
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include <industrial_extrinsic_cal/basic_types.h>

namespace industrial_extrinsic_cal
{

  Pose6d::Pose6d(double tx, double ty, double tz, double aax, double aay, double aaz)
  {
    x = tx;
    y = ty;
    z = tz;
    ax = aax;
    ay = aay;
    az = aaz;
  }
  Pose6d::Pose6d()
  {
    x=y=z=ax=ay=az=0.0;
  }
  void Pose6d::setBasis( tf::Matrix3x3 & m)
  {
    // see Google ceres rotation.h for the source of these computations, I copied them
    // from the RotationMatrixToAngleAxis()
    ax = m[2][1] - m[1][2]; // R[5] - R[7]
    ay = m[0][2] - m[2][0]; // R[6] - R[2]
    az = m[1][0] - m[0][1]; // R[1] - R[3]
    double costheta = std::min(std::max((m[0][0] + m[1][1] + m[2][2] - 1.0) / 2.0, -1.0), 1.0);
    double sintheta = std::min(sqrt(ax * ax + ay*ay + az*az) / 2.0, 1.0);
    double theta = atan2(sintheta, costheta);
    static double kThreshold = 1e-12;
    if ((sintheta > kThreshold) || (sintheta < -kThreshold)) {
      double r = theta / (2.0 * sintheta);
      ax *= r;
      ay *= r;
      az *= r;
      return;
    }
    if (costheta > 0.0) {
      ax *= 0.5;
      ay *= 0.5;
      az *= 0.5;
      return;
    }
    double inv_one_minus_costheta = 1.0/ (1.0 - costheta);
    ax = theta * sqrt((m[0][0] - costheta) * inv_one_minus_costheta);
    if (((sintheta < 0.0) && (ax > 0.0)) ||((sintheta > 0.0) && (ax < 0.0))) {
      ax = -ax;
    }
    ay = theta * sqrt((m[1][1] - costheta) * inv_one_minus_costheta);
    if (((sintheta < 0.0) && (ay > 0.0)) ||((sintheta > 0.0) && (ay < 0.0))) {
      ay = -ay;
    }
    az = theta * sqrt((m[2][2] - costheta) * inv_one_minus_costheta);
    if (((sintheta < 0.0) && (az > 0.0)) ||((sintheta > 0.0) && (az < 0.0))) {
      az = -az;
    }
  }

  void Pose6d::setOrigin(tf::Vector3 & v)
  {
    x = v.m_floats[0];
    y = v.m_floats[1];
    z = v.m_floats[2];
  }

  void Pose6d::setOrigin(double tx, double ty, double tz)
  {
    x = tx;
    y = ty;
    z = tz;
  }

  void Pose6d::setEulerZYX(double ez, double ey, double ex)
  {
    double ci = cos(ex);
    double cj = cos(ey);
    double ch = cos(ez);
    double si = sin(ex);
    double sj = sin(ey);
    double sh = sin(ez);
    double cc = ci*ch;
    double cs = ci*sh;
    double sc = si*ch;
    double ss = si*sh;

    tf::Matrix3x3 m;
    m[0][0] = cj*ch;  m[0][1] = sj*sc - cs;     m[0][2] = sj*cc + ss;
    m[1][0] = cj*sh;  m[1][1] = sj*ss + cc;   m[1][2] = sj*cs - sc;
    m[2][0] = -sj;      m[2][1] = cj*si;           m[2][2] =cj*ci ;

    setBasis(m);
  }

  void Pose6d::setQuaternion(double qx, double qy, double qz, double qw)
  {
    double angle = 2.0 * acos(qw);
    ax = qx / sqrt(1-qw*qw)*angle;
    ay = qy / sqrt(1-qw*qw)*angle;
    az = qz / sqrt(1-qw*qw)*angle;
  }

  void Pose6d::setAngleAxis(double aax, double aay, double aaz)
  {
    ax = aax;
    ay = aay;
    az = aaz;
  }

  tf::Matrix3x3 Pose6d::getBasis() const
  {
    tf::Matrix3x3 R;
    double angle = sqrt(ax*ax + ay*ay + az*az);
    if(angle < .0001){
      R[0][0] = 1.0;  R[0][1] = 0.0;  R[0][2] = 0.0;
      R[1][0] = 0.0;  R[1][1] = 1.0;  R[1][2] = 0.0;
      R[2][0] = 0.0;  R[2][1] = 0.0;  R[2][2] = 1.0;
      return(R);
    }
    double ct = cos(angle);
    double st = sin(angle);
    double ux = ax/angle;
    double uy = ay/angle;
    double uz = az/angle;
    double omct = 1.0 - ct;
    R[0][0] = ct + ux*ux*omct;      R[0][1] = ux*uy*omct - uz*st;   R[0][2] = ux*uz*omct + uy*st;
    R[1][0] = uy*ux*omct + uz*st; R[1][1] =  ct+uy*uy*omct;        R[1][2] = uy*uz*omct - ux*st;
    R[2][0] = uz*ux*omct - uy*st;  R[2][1] =  uz*uy*omct + ux*st;  R[2][2] = ct + uz*uz*omct;
    return(R);
  }

  tf::Vector3 Pose6d::getOrigin() const
  {
    tf::Vector3 V(x, y, z);
    return(V);
  }

    void Pose6d::getEulerZYX(double &ez, double &ey, double &ex) const
    {
     double PI = 4*atan(1);
     double theta;
     double psi;
     double phi;
     tf::Matrix3x3 R = this->getBasis();

     if( fabs(R[2][0]) != 1.0 ){ // cos(theta) = 0.0
       theta = -asin(R[2][0]);
       double ct = cos(theta);
       psi = atan2(R[2][1]/ct, R[2][2]/ct);
       phi = atan2(R[1][0]/ct,R[0][0]/ct);
     }
     else{
       phi = 0.0; // could be anything
       if(R[2][0] == -1.0){
	 theta = PI/2.0;
	 psi = phi + atan2(R[0][1], R[0][2]);
       }
       else{
	 theta = -PI/2.0;
	 psi = -phi + atan2(-R[0][1], -R[0][2]);
       }
     } // end of cos(theta) = 0

     // Rz(phi) * Ry(theta) * Rx(psi)
     ez = phi;
     ey = theta;
     ex = psi;
   }
  void Pose6d::getQuaternion(double &qx,  double &qy, double &qz, double &qw)
  {
    // the following was taken from ceres equivalent function
    double theta_squared = ax*ax + ay*ay + az*az;
    if(theta_squared>0.0){
      double theta = sqrt(theta_squared);
      double half_theta = theta*0.5;
      double k = sin(half_theta)/theta;
      qw = cos(half_theta);
      qx = ax*k;
      qy = ay*k;
      qz = az*k;
    }
    else{ // can't do division by zeor
      double k = 0.5;
      qw = 1.0;
      qx = ax*k;
      qy = ay*k;
      qz = az*k;
    }
  }

  Pose6d Pose6d::getInverse() const
  {
    double newx,newy,newz;
    tf::Matrix3x3 R = getBasis();
    newx =-( R[0][0] * x + R[1][0] * y + R[2][0] * z);
    newy = -(R[0][1] * x + R[1][1] * y + R[2][1] * z);
    newz = -(R[0][2] * x + R[1][2] * y + R[2][2] * z);
    Pose6d new_pose(newx, newy, newz, -ax,- ay, -az);
    return(new_pose);
  }

  void Pose6d::show(std::string message)
  {
    tf::Matrix3x3 basis = this->getBasis();
    double ez_yaw, ey_pitch, ex_roll;
    double qx, qy, qz, qw;
    this->getEulerZYX(ez_yaw,ey_pitch,ex_roll);
    this->getQuaternion(qx, qy, qz, qw);
   printf("%s =[\n %6.3lf  %6.3lf  %6.3lf  %6.3lf\n  %6.3lf  %6.3lf  %6.3lf  %6.3lf\n  %6.3lf  %6.3lf %6.3lf  %6.3lf\n  %6.3lf  %6.3lf %6.3lf  %6.3lf];\n rpy= %6.3lf %6.3lf %6.3lf\n quat= %6.3lf  %6.3lf  %6.3lf %6.3lf\n ",
	      message.c_str(),
	      basis[0][0],basis[0][1], basis[0][2],this->x,
	      basis[1][0],basis[1][1], basis[1][2],this->y,
	      basis[2][0],basis[2][1], basis[2][2],this->z,
	      0.0, 0.0, 0.0, 1.0,
	      ez_yaw, ey_pitch, ex_roll,
	      qx, qy, qz, qw);
  }

  Pose6d Pose6d::operator * ( Pose6d pose2) const
  {
    tf::Matrix3x3  R1   = getBasis();
    tf::Matrix3x3 R2 = pose2.getBasis();
    tf::Vector3 T1     = getOrigin();
    tf::Vector3 T2     = pose2.getOrigin();

    tf::Matrix3x3 R3;
    R3[0][0] = R1[0][0] * R2[0][0] + R1[0][1]*R2[1][0] + R1[0][2]*R2[2][0];
    R3[1][0] = R1[1][0] * R2[0][0] + R1[1][1]*R2[1][0] + R1[1][2]*R2[2][0];
    R3[2][0] = R1[2][0] * R2[0][0] + R1[2][1]*R2[1][0] + R1[2][2]*R2[2][0];

    R3[0][1] = R1[0][0] * R2[0][1] + R1[0][1]*R2[1][1] + R1[0][2]*R2[2][1];
    R3[1][1] = R1[1][0] * R2[0][1] + R1[1][1]*R2[1][1] + R1[1][2]*R2[2][1];
    R3[2][1] = R1[2][0] * R2[0][1] + R1[2][1]*R2[1][1] + R1[2][2]*R2[2][1];

     R3[0][2] = R1[0][0] * R2[0][2] + R1[0][1]*R2[1][2] + R1[0][2]*R2[2][2];
     R3[1][2] = R1[1][0] * R2[0][2] + R1[1][1]*R2[1][2] + R1[1][2]*R2[2][2];
     R3[2][2] = R1[2][0] * R2[0][2] + R1[2][1]*R2[1][2] + R1[2][2]*R2[2][2];

    double tempx, tempy, tempz;
    tempx = R1[0][0] * T2.x() + R1[0][1]*T2.y() + R1[0][2]*T2.z() + T1.x();
    tempy = R1[1][0] * T2.x() + R1[1][1]*T2.y() + R1[1][2]*T2.z() + T1.y();
    tempz = R1[2][0] * T2.x() + R1[2][1]*T2.y() + R1[2][2]*T2.z() + T1.z();
    tf::Vector3 T3(tempx, tempy, tempz);

    Pose6d pose;
    pose.setBasis(R3);
    pose.setOrigin(T3);

    return(pose);
  }

}// end of namespace
<|endoftext|>


<commit_before>#include <stdio.h>
#include <iostream>
#include <boost/assert.hpp>

#include "Pynobio.hpp"

using namespace std;

//// EnobioDataConsumer ///
EnobioDataConsumer::EnobioDataConsumer(boost::mutex* pMutex) :mpMutex(pMutex) {
	BOOST_VERIFY(mpMutex != 0);
	this->buffer = new uint32_t[BUFFER_SAMPLES*CHANNELS];
	this->nSamples = 0;
	this->hEvent = CreateEvent(NULL, false, false, NULL);
	if(this->hEvent == 0) {
		printf("CreateEvent failed (%d)\n", GetLastError());
	}
}

EnobioDataConsumer::~EnobioDataConsumer() {
	CloseHandle(this->hEvent);
	BOOST_VERIFY(this->buffer != 0);
	delete this->buffer;
}

void EnobioDataConsumer::receiveData(const PData &data) {
	BOOST_VERIFY(mpMutex != 0 && buffer != 0);
	BOOST_VERIFY(this->nSamples < BUFFER_SAMPLES);
	ChannelData *pData = (ChannelData *)data.getData();
	if (pData == 0) {
		cerr << "EnobioDataConsumer.receiveData: WARNING pData ==0 " << endl;
		return;
	}
	uint32_t *sample = reinterpret_cast<uint32_t*>(pData->data());
	if(sample == 0) {
		cerr << "EnobioDataConsumer.receiveData: WARNING samples ==0 " << endl;
		return;
	}

	mpMutex->lock();
	memcpy(this->buffer + CHANNELS*this->nSamples, sample, CHANNELS*sizeof(uint32_t));
	this->timestamp = pData->timestamp();
	this->nSamples++;
	if(this->nSamples == BUFFER_SAMPLES) {
		this->nSamples = 0;
	}
	mpMutex->unlock();
	if(!SetEvent(this->hEvent)) {
		printf("SetEvent failed (%d)\n", GetLastError());
	}
}

//// EnobioStatusConsumer ///
void EnobioStatusConsumer::receiveData(const PData &data) {
	StatusData *status = (StatusData *)data.getData();
	printf("%s\n", status->getString());
}

/// Enobio ///
Enobio::Enobio() :mutex() {

	this->enobioData = new EnobioDataConsumer(&mutex);
	this->enobioStatus = new EnobioStatusConsumer();
	this->enobio.registerConsumer(Enobio3G::ENOBIO_DATA, *this->enobioData);
	this->enobio.registerConsumer(Enobio3G::STATUS, *this->enobioStatus);

	this->opened = false;
	this->started = false;
	this->samples = new uint32_t[BUFFER_SAMPLES*CHANNELS];
}

Enobio::~Enobio() {
	if(this->started) {
		this->stop();
	}
	if(this->opened) {
		this->close();
	}

	delete this->enobioStatus;
	delete this->enobioData;
	delete this->samples;
}

bool Enobio::open(uint8_t* mac) {
	// hardcoded MAC of our Enobio 8 device
	// will not work with the StarStim. needs refactoring
	unsigned char hardcodedMac[6] = {0x61, 0x9C, 0x58, 0x80, 0x07, 0x00};
	this->opened = (uint32_t)this->enobio.openDevice(hardcodedMac);
	return this->opened;
}

bool Enobio::init(size_t channels) {
	// it does not appear as if the Enobio has a way to only request a
	// subset of channels, so we would use this to create a mask on the
	// returned sample data.
	return true;
}

size_t Enobio::channels() {
	// XXX - fix me
	return 8;
}

bool Enobio::start() {
	this->enobio.startStreaming();
	this->started = true;
	return this->started;
}

size_t Enobio::acquire() {
	BOOST_VERIFY(this->enobioData != 0 && this->enobioData->buffer != 0 && this->samples != 0);
	size_t result=0;
	result = WaitForSingleObject(this->enobioData->hEvent, 1000);
	if (result != WAIT_OBJECT_0) {
		cerr << "Pynobio: ERROR: waiting result = " << result << endl;
		return 0;
	} else {
		mutex.lock();
		int nSamples = this->enobioData->nSamples;
		memcpy(this->samples, this->enobioData->buffer, CHANNELS*nSamples*sizeof(uint32_t));
		this->enobioData->nSamples = 0;
		mutex.unlock();
		return nSamples*CHANNELS;
	}
}

void Enobio::getdata(uint32_t* buffer, size_t samples) {
	BOOST_VERIFY(buffer != 0 && this->samples != 0);
	if(samples > BUFFER_SAMPLES*CHANNELS) {
		cout << "Enobio.getdata: WARNING: number of samples requested is bigger than the buffer" << endl;
		samples = BUFFER_SAMPLES*CHANNELS;
	}
	memcpy(buffer, this->samples, samples*sizeof(uint32_t));
}

uint64_t Enobio::timestamp() {
	return this->enobioData->timestamp;
}

bool Enobio::stop() {
	this->enobio.stopStreaming();
	this->started = false;
	return true;
}

bool Enobio::close() {
	this->enobio.closeDevice();
	this->opened = false;
	return true;
}
<commit_msg>Fixed typo<commit_after>#include <stdio.h>
#include <iostream>
#include <boost/assert.hpp>

#include "Pynobio.hpp"

using namespace std;

//// EnobioDataConsumer ///
EnobioDataConsumer::EnobioDataConsumer(boost::mutex* pMutex) :mpMutex(pMutex) {
	BOOST_VERIFY(mpMutex != 0);
	this->buffer = new uint32_t[BUFFER_SAMPLES*CHANNELS];
	this->nSamples = 0;
	this->hEvent = CreateEvent(NULL, false, false, NULL);
	if(this->hEvent == 0) {
		printf("CreateEvent failed (%d)\n", GetLastError());
	}
}

EnobioDataConsumer::~EnobioDataConsumer() {
	CloseHandle(this->hEvent);
	BOOST_VERIFY(this->buffer != 0);
	delete this->buffer;
}

void EnobioDataConsumer::receiveData(const PData &data) {
	BOOST_VERIFY(mpMutex != 0 && buffer != 0);
	BOOST_VERIFY(this->nSamples < BUFFER_SAMPLES);
	ChannelData *pData = (ChannelData *)data.getData();
	if (pData == 0) {
		cerr << "EnobioDataConsumer.receiveData: WARNING pData == 0 " << endl;
		return;
	}
	uint32_t *sample = reinterpret_cast<uint32_t*>(pData->data());
	if(sample == 0) {
		cerr << "EnobioDataConsumer.receiveData: WARNING samples == 0 " << endl;
		return;
	}

	mpMutex->lock();
	memcpy(this->buffer + CHANNELS*this->nSamples, sample, CHANNELS*sizeof(uint32_t));
	this->timestamp = pData->timestamp();
	this->nSamples++;
	if(this->nSamples == BUFFER_SAMPLES) {
		this->nSamples = 0;
	}
	mpMutex->unlock();
	if(!SetEvent(this->hEvent)) {
		printf("SetEvent failed (%d)\n", GetLastError());
	}
}

//// EnobioStatusConsumer ///
void EnobioStatusConsumer::receiveData(const PData &data) {
	StatusData *status = (StatusData *)data.getData();
	printf("%s\n", status->getString());
}

/// Enobio ///
Enobio::Enobio() :mutex() {

	this->enobioData = new EnobioDataConsumer(&mutex);
	this->enobioStatus = new EnobioStatusConsumer();
	this->enobio.registerConsumer(Enobio3G::ENOBIO_DATA, *this->enobioData);
	this->enobio.registerConsumer(Enobio3G::STATUS, *this->enobioStatus);

	this->opened = false;
	this->started = false;
	this->samples = new uint32_t[BUFFER_SAMPLES*CHANNELS];
}

Enobio::~Enobio() {
	if(this->started) {
		this->stop();
	}
	if(this->opened) {
		this->close();
	}

	delete this->enobioStatus;
	delete this->enobioData;
	delete this->samples;
}

bool Enobio::open(uint8_t* mac) {
	// hardcoded MAC of our Enobio 8 device
	// will not work with the StarStim. needs refactoring
	unsigned char hardcodedMac[6] = {0x61, 0x9C, 0x58, 0x80, 0x07, 0x00};
	this->opened = (uint32_t)this->enobio.openDevice(hardcodedMac);
	return this->opened;
}

bool Enobio::init(size_t channels) {
	// it does not appear as if the Enobio has a way to only request a
	// subset of channels, so we would use this to create a mask on the
	// returned sample data.
	return true;
}

size_t Enobio::channels() {
	// XXX - fix me
	return 8;
}

bool Enobio::start() {
	this->enobio.startStreaming();
	this->started = true;
	return this->started;
}

size_t Enobio::acquire() {
	BOOST_VERIFY(this->enobioData != 0 && this->enobioData->buffer != 0 && this->samples != 0);
	size_t result=0;
	result = WaitForSingleObject(this->enobioData->hEvent, 1000);
	if (result != WAIT_OBJECT_0) {
		cerr << "Pynobio: ERROR: waiting result = " << result << endl;
		return 0;
	} else {
		mutex.lock();
		int nSamples = this->enobioData->nSamples;
		memcpy(this->samples, this->enobioData->buffer, CHANNELS*nSamples*sizeof(uint32_t));
		this->enobioData->nSamples = 0;
		mutex.unlock();
		return nSamples*CHANNELS;
	}
}

void Enobio::getdata(uint32_t* buffer, size_t samples) {
	BOOST_VERIFY(buffer != 0 && this->samples != 0);
	if(samples > BUFFER_SAMPLES*CHANNELS) {
		cout << "Enobio.getdata: WARNING: number of samples requested is bigger than the buffer" << endl;
		samples = BUFFER_SAMPLES*CHANNELS;
	}
	memcpy(buffer, this->samples, samples*sizeof(uint32_t));
}

uint64_t Enobio::timestamp() {
	return this->enobioData->timestamp;
}

bool Enobio::stop() {
	this->enobio.stopStreaming();
	this->started = false;
	return true;
}

bool Enobio::close() {
	this->enobio.closeDevice();
	this->opened = false;
	return true;
}
<|endoftext|>


<commit_before><commit_msg>Reset zoom & center on (0, 0) on 'r'<commit_after><|endoftext|>


<commit_before>#include <vexcl/vexcl.hpp>
#include <vexcl/fft.hpp>
#include <random>
#include <fftw3.h>

using namespace vex;

float hsum(cl_float2 a) { return a.s[0] + a.s[1]; }

#include <random>

std::vector<cl_float2> random_vec(size_t n, float range) {
    std::vector<cl_float2> data(n);
    std::default_random_engine gen;
    std::uniform_real_distribution<float> dist(-range, range);
    for(size_t i = 0 ; i < n ; i++)
        data[i] = cl_float2{{dist(gen), dist(gen)}};
    return data;
}

void test(Context &ctx, std::vector<size_t> ns) {
    size_t n = 1;
    for(size_t i = 0 ; i < ns.size() ; i++) n *= ns[i];

    const float range = 1000;

    // random data.
    std::vector<cl_float2> input_h = random_vec(n, range);

    // reference.
    std::vector<cl_float2> ref_h(n);
    int *ns_ = new int[ns.size()];
    std::copy(ns.begin(), ns.end(), ns_);
    fftwf_plan p1 = fftwf_plan_dft(ns.size(), ns_,
        reinterpret_cast<fftwf_complex *>(&input_h[0]),
        reinterpret_cast<fftwf_complex *>(&ref_h[0]),
        FFTW_FORWARD, FFTW_ESTIMATE);
    delete [] ns_;
    fftwf_execute(p1);
    fftwf_destroy_plan(p1);

    // test
    vector<cl_float2> input(ctx.queue(), input_h);
    vector<cl_float2> output(ctx.queue(), n);
    vector<cl_float2> ref(ctx.queue(), ref_h);
    vector<cl_float2> back(ctx.queue(), n);

    FFT<cl_float2>  fft(ctx.queue(), ns);
    output = fft(input);

    FFT<cl_float2> ifft(ctx.queue(), ns, inverse);
    back = ifft(output);

    Reductor<cl_float2, SUM> sum(ctx.queue());
    #define rms(e) (100 * std::sqrt(hsum(sum(pow(e, 2))) / n) / range)

    std::cerr << "n=[";
    for(size_t i = 0 ; i < ns.size() ; i++)
        std::cerr << ns[i] << ' ';
    std::cerr << "]        rms" << std::endl;
    std::cerr << "fftw-clfft      " << rms(output - ref) << "%" << std::endl;
    std::cerr << "x-ifft(fft(x))  " << rms(input - back) << "%" << std::endl;
}

int main() {
    Context ctx(Filter::Env && Filter::Count(1), CL_QUEUE_PROFILING_ENABLE);
    std::cout << ctx << std::endl;

    test(ctx, {16 * 16 * 2});
    test(ctx, {16 * 16 * 4});
    test(ctx, {16 * 16 * 8});
    test(ctx, {16 * 16 * 16});
    test(ctx, {4, 4});
    test(ctx, {16 * 4, 16 * 4});
    test(ctx, {16 * 16 * 2, 16 * 16 * 4});
    test(ctx, {2, 4});
    test(ctx, {2 * 16, 4 * 16, 8 * 16});
    test(ctx, {2 * 16, 4 * 16, 8 * 16, 2});
    return 0;
}

<commit_msg>fft_verify output like utests<commit_after>#include <vexcl/vexcl.hpp>
#include <vexcl/fft.hpp>
#include <random>
#include <fftw3.h>

using namespace vex;

float hsum(cl_float2 a) { return a.s[0] + a.s[1]; }

#include <random>

std::vector<cl_float2> random_vec(size_t n, float range) {
    std::vector<cl_float2> data(n);
    std::default_random_engine gen;
    std::uniform_real_distribution<float> dist(-range, range);
    for(size_t i = 0 ; i < n ; i++)
        data[i] = cl_float2{{dist(gen), dist(gen)}};
    return data;
}

void test(Context &ctx, std::vector<size_t> ns) {
    std::ostringstream name;
    for(size_t i = 0 ; i < ns.size() ; i++) {
        if(i > 0) name << 'x';
        name << ns[i];
    }
    char fc = std::cout.fill('.');
    std::cout << name.str() << ": " << std::setw(62 - name.str().size()) << "." << std::flush;
    std::cout.fill(fc);

    size_t n = 1;
    for(size_t i = 0 ; i < ns.size() ; i++) n *= ns[i];

    const float range = 1000;

    // random data.
    std::vector<cl_float2> input_h = random_vec(n, range);

    // reference.
    std::vector<cl_float2> ref_h(n);
    int *ns_ = new int[ns.size()];
    std::copy(ns.begin(), ns.end(), ns_);
    fftwf_plan p1 = fftwf_plan_dft(ns.size(), ns_,
        reinterpret_cast<fftwf_complex *>(&input_h[0]),
        reinterpret_cast<fftwf_complex *>(&ref_h[0]),
        FFTW_FORWARD, FFTW_ESTIMATE);
    delete [] ns_;
    fftwf_execute(p1);
    fftwf_destroy_plan(p1);

    // test
    vector<cl_float2> input(ctx.queue(), input_h);
    vector<cl_float2> output(ctx.queue(), n);
    vector<cl_float2> ref(ctx.queue(), ref_h);
    vector<cl_float2> back(ctx.queue(), n);

    FFT<cl_float2>  fft(ctx.queue(), ns);
    output = fft(input);

    FFT<cl_float2> ifft(ctx.queue(), ns, inverse);
    back = ifft(output);

    Reductor<cl_float2, SUM> sum(ctx.queue());
    #define rms(e) (100 * std::sqrt(hsum(sum(pow(e, 2))) / n) / range)

    const float rms_fft = rms(output - ref);
    const float rms_inv = rms(input - back);

    const bool rc = rms_fft < 0.02 && rms_inv < 1e-4;

    std::cout << (rc ? " success." : " failed.") << std::endl;

    if(!rc) {
        std::cout << "  fftw-clfft      " << rms_fft << "%" << std::endl;
        std::cout << "  x-ifft(fft(x))  " << rms_inv << "%" << std::endl;
    }
}

int main() {
    Context ctx(Filter::Env && Filter::Count(1), CL_QUEUE_PROFILING_ENABLE);
    std::cout << ctx << std::endl;

    test(ctx, {16 * 16 * 2});
    test(ctx, {16 * 16 * 4});
    test(ctx, {16 * 16 * 8});
    test(ctx, {16 * 16 * 16});
    test(ctx, {4, 4});
    test(ctx, {16 * 4, 16 * 4});
    test(ctx, {16 * 16 * 2, 16 * 16 * 4});
    test(ctx, {2, 4});
    test(ctx, {2 * 16, 4 * 16, 8 * 16});
    test(ctx, {2 * 16, 4 * 16, 8 * 16, 2});
    return 0;
}

<|endoftext|>


<commit_before>#include <silicium/http/receive_request.hpp>
#include <silicium/http/generate_response.hpp>
#include <silicium/asio/writing_observable.hpp>
#include <silicium/asio/tcp_acceptor.hpp>
#include <silicium/observable/transform.hpp>
#include <silicium/observable/spawn_coroutine.hpp>
#include <silicium/observable/spawn_observable.hpp>
#include <silicium/sink/iterator_sink.hpp>

namespace
{
	template <class YieldContext>
	void serve_client(boost::asio::ip::tcp::socket &client, YieldContext &&yield)
	{
		auto request = Si::http::receive_request(client, yield);
		if (request.is_error())
		{
			//The header was incomplete, maybe the connecting was closed.
			//If we want to know the reason, the error_extracting_source remembered it:
			boost::system::error_code error = request.error();
			boost::ignore_unused_variable_warning(error);
			return;
		}

		if (!request.get())
		{
			//syntax error in the request
			return;
		}

		std::vector<char> response;
		{
			auto response_writer = Si::make_container_sink(response);
			Si::http::generate_status_line(response_writer, "HTTP/1.0", "200", "OK");
			boost::string_ref const content = "Hello, visitor!";
			Si::http::generate_header(response_writer, "Content-Length", boost::lexical_cast<Si::noexcept_string>(content.size()));
			Si::http::finish_headers(response_writer);
			Si::append(response_writer, content);
		}

		//you can handle the error if you want
		boost::system::error_code error = Si::asio::write(client, Si::make_memory_range(response), yield);

		//ignore shutdown failures, they do not matter here
		client.shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
	}
}

int main()
{
	boost::asio::io_service io;
	Si::spawn_observable(
		Si::transform(
			Si::asio::make_tcp_acceptor(
				boost::asio::ip::tcp::acceptor(
					io,
					boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(), 8080)
				)
			),
			[](Si::asio::tcp_acceptor_result maybe_client)
			{
				auto client = maybe_client.get();
				Si::spawn_coroutine([client](Si::spawn_context yield)
				{
					serve_client(*client, yield);
				});
				return Si::nothing();
			}
		)
	);
	io.run();
}
<commit_msg>handle socket bind failure in an example<commit_after>#include <silicium/http/receive_request.hpp>
#include <silicium/http/generate_response.hpp>
#include <silicium/asio/writing_observable.hpp>
#include <silicium/asio/tcp_acceptor.hpp>
#include <silicium/observable/transform.hpp>
#include <silicium/observable/spawn_coroutine.hpp>
#include <silicium/observable/spawn_observable.hpp>
#include <silicium/sink/iterator_sink.hpp>
#include <iostream>

namespace
{
	template <class YieldContext>
	void serve_client(boost::asio::ip::tcp::socket &client, YieldContext &&yield)
	{
		auto request = Si::http::receive_request(client, yield);
		if (request.is_error())
		{
			//The header was incomplete, maybe the connecting was closed.
			//If we want to know the reason, the error_extracting_source remembered it:
			boost::system::error_code error = request.error();
			boost::ignore_unused_variable_warning(error);
			return;
		}

		if (!request.get())
		{
			//syntax error in the request
			return;
		}

		std::vector<char> response;
		{
			auto response_writer = Si::make_container_sink(response);
			Si::http::generate_status_line(response_writer, "HTTP/1.0", "200", "OK");
			boost::string_ref const content = "Hello, visitor!";
			Si::http::generate_header(response_writer, "Content-Length", boost::lexical_cast<Si::noexcept_string>(content.size()));
			Si::http::finish_headers(response_writer);
			Si::append(response_writer, content);
		}

		//you can handle the error if you want
		boost::system::error_code error = Si::asio::write(client, Si::make_memory_range(response), yield);

		//ignore shutdown failures, they do not matter here
		client.shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
	}

	boost::system::error_code spawn_server(boost::asio::io_service &io)
	{
		boost::system::error_code ec;
		boost::asio::ip::tcp::acceptor acceptor(io);

		acceptor.open(boost::asio::ip::tcp::v4(), ec);
		if (ec)
		{
			return ec;
		}

		acceptor.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(), 8080), ec);
		if (ec)
		{
			return ec;
		}

		acceptor.listen(boost::asio::ip::tcp::acceptor::max_connections, ec);
		if (ec)
		{
			return ec;
		}

		Si::spawn_observable(
			Si::transform(
				Si::asio::make_tcp_acceptor(std::move(acceptor)),
				[](Si::asio::tcp_acceptor_result maybe_client)
				{
					auto client = maybe_client.get();
					Si::spawn_coroutine([client](Si::spawn_context yield)
					{
						serve_client(*client, yield);
					});
					return Si::nothing();
				}
			)
		);

		return {};
	}
}

int main()
{
	boost::asio::io_service io;
	boost::system::error_code ec = spawn_server(io);
	if (ec)
	{
		std::cerr << ec << ": " << ec.message() << '\n';
		return 1;
	}
	io.run();
}
<|endoftext|>


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

  Program:   Visualization Library
  Module:    SetGet.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file or its
contents may be copied, reproduced or altered in any way without the express
written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
//
// Macros for setting and getting instance variables.  Macros are available
// for  built-in types; for character strings; vector arrays of built-in
// types size 2,3,4; and for setting objects (i.e., Registering objects).
// Macros enforce proper use of Debug, Modified time, and Registering objects.
//

#ifndef __vlSetGet_hh
#define __vlSetGet_hh

#include <string.h>
//
// For super speedy execution define __vlNoDebug
//
//#define __vlNoDebug

//
// Set built-in type.  Creates member Set"name"() (e.g., SetVisibility());
//
#define vlSetMacro(name,type) \
void Set##name (type _arg) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to " << _arg << "\n\n"; \
  if (name != _arg) \
    { \
    name = _arg; \
    Modified(); \
    } \
  }

//
// Get built-in type.  Creates member Get"name"() (e.g., GetVisibility());
//
#define vlGetMacro(name,type) \
type Get##name () { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): returning " << #name " of " << name << "\n\n"; \
  return name; \
  }

//
// Set character string.  Creates member Set"name"()
// (e.g., SetFilename(char *));
//
#define vlSetStringMacro(name) \
void Set##name (char* _arg) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to " << _arg << "\n\n"; \
  if ( name && _arg ) \
    if ( !strcmp(name,_arg) ) return; \
  if (name) delete [] name; \
  if (_arg) \
    { \
    name = new char[strlen(_arg)+1]; \
    strcpy(name,_arg); \
    } \
   else \
    { \
    name = 0; \
    } \
  Modified(); \
  }

//
// Get character string.  Creates member Get"name"()
// (e.g., char *GetFilename());
//
#define vlGetStringMacro(name) \
char* Get##name () { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): returning " << #name " of " << name << "\n\n"; \
  return name; \
  }

//
// Set built-in type where value is constrained between min/max limits.
// Create member Set"name"() (e.q., SetRadius()). #defines are
// convienience for clamping open-ended values.
//
#define LARGE_FLOAT 1.0e29
#define LARGE_INTEGER 2147483646 /* 2**31 - 1 */
#define vlSetClampMacro(name,type,min,max) \
void Set##name (type _arg) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to " << _arg << "\n\n"; \
  if (name != _arg) \
    { \
    name = (_arg<min?min:(_arg>max?max:_arg)); \
    Modified(); \
    } \
  }

//
// Set pointer to object; uses vlObject reference counting methodology.
// Creates method Set"name"() (e.g., SetPoints()).
//
#define vlSetObjectMacro(name,type) \
void Set##name (type* _arg) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to " << &_arg << "\n\n"; \
  if (name != _arg) \
    { \
    if (name != 0) name->UnRegister(this); \
    name = _arg; \
    name->Register(this); \
    this->Modified(); \
    } \
  }

//
// Get pointer to object.  Creates member Get"name" (e.g., GetPoints()).
//
#define vlGetObjectMacro(name,type) \
type *Get##name () \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): returning " << #name " address " << name << "\n\n"; \
  return name; \
  }

//
// Create members "name"On() and "name"Off() (e.g., DebugOn() DebugOff()).
// Set method must be defined to use this macro.
//
#define vlBooleanMacro(name,type) \
void name##On () { Set##name((type)1);}; \
void name##Off () { Set##name((type)0);}

//
// Following set macros for vectors define two members for each macro.  The first
// allows setting of individual components (e.g, SetColor(float,float,float)),
// the second allows setting from an array (e.g., SetColor(float* rgb[3])).
// The macros vary in the size of the vector they deal with.
//
#define vlSetVector2Macro(name,type) \
void Set##name (type _arg1, type _arg2) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg1 << "," << _arg2 << ")\n\n"; \
  if ((name[0] != _arg1)||(name[1] != _arg2)) \
    { \
    Modified(); \
    } \
  name[0] = _arg1; \
  name[1] = _arg2; \
  }; \
void Set##name (type _arg[2]) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg[0] << "," << _arg[1] << ")\n\n"; \
  if ((name[0] != _arg[0])||(name[1] != _arg[1])) \
    { \
    Modified(); \
    } \
  name[0] = _arg[0]; \
  name[1] = _arg[1]; \
  }

#define vlSetVector3Macro(name,type) \
void Set##name (type _arg1, type _arg2, type _arg3) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg1 << "," << _arg2 << "," << _arg3 << ")\n\n"; \
  if ((name[0] != _arg1)||(name[1] != _arg2)||(name[2] != _arg3)) \
    { \
    Modified(); \
    } \
  name[0] = _arg1; \
  name[1] = _arg2; \
  name[2] = _arg3; \
  }; \
void Set##name (type _arg[3]) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg[0] << "," << _arg[1] << "," << _arg[2] << ")\n\n"; \
  if ((name[0] != _arg[0])||(name[1] != _arg[1])||(name[2] != _arg[2])) \
    { \
    Modified(); \
    } \
  name[0] = _arg[0]; \
  name[1] = _arg[1]; \
  name[2] = _arg[2]; \
  }

#define vlSetVector4Macro(name,type) \
void Set##name (type _arg1, type _arg2, type _arg3, type _arg4) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg1 << "," << _arg2 << "," << _arg3 << "," << _arg4 << ")\n\n"; \
  if ((name[0] != _arg1)||(name[1] != _arg2)||(name[2] != _arg3)||(name[3] != _arg4)) \
    { \
    Modified(); \
    } \
  name[0] = _arg1; \
  name[1] = _arg2; \
  name[2] = _arg3; \
  name[3] = _arg4; \
  }; \
void Set##name (type _arg[4]) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg[0] << "," << _arg[1] << "," << _arg[2] << "," << _arg[3] << ")\n\n"; \
  if ((name[0] != _arg[0])||(name[1] != _arg[1])||(name[2] != _arg[2])||(name[3] != _arg[3])) \
    { \
    Modified(); \
    } \
  name[0] = _arg[0]; \
  name[1] = _arg[1]; \
  name[2] = _arg[2]; \
  name[3] = _arg[3]; \
  }

//
// Get vector macro returns pointer to type (i.e., array of type).
// Example: float *GetColor()
//
#define vlGetVectorMacro(name,type) \
type *Get##name () { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): returning " << #name " pointer " << name << "\n\n"; \
  return name; \
}

//
// This macro is used for  debug statements in instance methods
// vlDebugMacro(<< "this is debug info" << this->SomeVariable);
//
#define vlDebugMacro(x) \
  if (Debug) cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): " x << "\n\n"

//
// This macro is used to print out errors
// vlErrorMacro(<< "Error message" << variable);
//
#define vlErrorMacro(x) \
  cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): " x << "\n\n"

#endif
<commit_msg>*** empty log message ***<commit_after>/*=========================================================================

  Program:   Visualization Library
  Module:    SetGet.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file or its
contents may be copied, reproduced or altered in any way without the express
written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
//
// Macros for setting and getting instance variables.  Macros are available
// for  built-in types; for character strings; vector arrays of built-in
// types size 2,3,4; and for setting objects (i.e., Registering objects).
// Macros enforce proper use of Debug, Modified time, and Registering objects.
//

#ifndef __vlSetGet_hh
#define __vlSetGet_hh

#include <string.h>
//
// For super speedy execution define __vlNoDebug
//
//#define __vlNoDebug

//
// Some constants used throughout code
//
#define LARGE_FLOAT 1.0e29
#define LARGE_INTEGER 2147483646 /* 2**31 - 1 */

//
// Set built-in type.  Creates member Set"name"() (e.g., SetVisibility());
//
#define vlSetMacro(name,type) \
void Set##name (type _arg) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to " << _arg << "\n\n"; \
  if (name != _arg) \
    { \
    name = _arg; \
    Modified(); \
    } \
  }

//
// Get built-in type.  Creates member Get"name"() (e.g., GetVisibility());
//
#define vlGetMacro(name,type) \
type Get##name () { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): returning " << #name " of " << name << "\n\n"; \
  return name; \
  }

//
// Set character string.  Creates member Set"name"()
// (e.g., SetFilename(char *));
//
#define vlSetStringMacro(name) \
void Set##name (char* _arg) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to " << _arg << "\n\n"; \
  if ( name && _arg ) \
    if ( !strcmp(name,_arg) ) return; \
  if (name) delete [] name; \
  if (_arg) \
    { \
    name = new char[strlen(_arg)+1]; \
    strcpy(name,_arg); \
    } \
   else \
    { \
    name = NULL; \
    } \
  Modified(); \
  }

//
// Get character string.  Creates member Get"name"()
// (e.g., char *GetFilename());
//
#define vlGetStringMacro(name) \
char* Get##name () { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): returning " << #name " of " << name << "\n\n"; \
  return name; \
  }

//
// Set built-in type where value is constrained between min/max limits.
// Create member Set"name"() (e.q., SetRadius()). #defines are
// convienience for clamping open-ended values.
//
#define vlSetClampMacro(name,type,min,max) \
void Set##name (type _arg) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to " << _arg << "\n\n"; \
  if (name != _arg) \
    { \
    name = (_arg<min?min:(_arg>max?max:_arg)); \
    Modified(); \
    } \
  }

//
// Set pointer to object; uses vlObject reference counting methodology.
// Creates method Set"name"() (e.g., SetPoints()).
//
#define vlSetObjectMacro(name,type) \
void Set##name (type* _arg) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to " << &_arg << "\n\n"; \
  if (name != _arg) \
    { \
    if (name != NULL) name->UnRegister(this); \
    name = _arg; \
    if (name != NULL) name->Register(this); \
    this->Modified(); \
    } \
  }

//
// Get pointer to object.  Creates member Get"name" (e.g., GetPoints()).
//
#define vlGetObjectMacro(name,type) \
type *Get##name () \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): returning " << #name " address " << name << "\n\n"; \
  return name; \
  }

//
// Create members "name"On() and "name"Off() (e.g., DebugOn() DebugOff()).
// Set method must be defined to use this macro.
//
#define vlBooleanMacro(name,type) \
void name##On () { Set##name((type)1);}; \
void name##Off () { Set##name((type)0);}

//
// Following set macros for vectors define two members for each macro.  The first
// allows setting of individual components (e.g, SetColor(float,float,float)),
// the second allows setting from an array (e.g., SetColor(float* rgb[3])).
// The macros vary in the size of the vector they deal with.
//
#define vlSetVector2Macro(name,type) \
void Set##name (type _arg1, type _arg2) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg1 << "," << _arg2 << ")\n\n"; \
  if ((name[0] != _arg1)||(name[1] != _arg2)) \
    { \
    Modified(); \
    } \
  name[0] = _arg1; \
  name[1] = _arg2; \
  }; \
void Set##name (type _arg[2]) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg[0] << "," << _arg[1] << ")\n\n"; \
  if ((name[0] != _arg[0])||(name[1] != _arg[1])) \
    { \
    Modified(); \
    } \
  name[0] = _arg[0]; \
  name[1] = _arg[1]; \
  }

#define vlSetVector3Macro(name,type) \
void Set##name (type _arg1, type _arg2, type _arg3) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg1 << "," << _arg2 << "," << _arg3 << ")\n\n"; \
  if ((name[0] != _arg1)||(name[1] != _arg2)||(name[2] != _arg3)) \
    { \
    Modified(); \
    } \
  name[0] = _arg1; \
  name[1] = _arg2; \
  name[2] = _arg3; \
  }; \
void Set##name (type _arg[3]) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg[0] << "," << _arg[1] << "," << _arg[2] << ")\n\n"; \
  if ((name[0] != _arg[0])||(name[1] != _arg[1])||(name[2] != _arg[2])) \
    { \
    Modified(); \
    } \
  name[0] = _arg[0]; \
  name[1] = _arg[1]; \
  name[2] = _arg[2]; \
  }

#define vlSetVector4Macro(name,type) \
void Set##name (type _arg1, type _arg2, type _arg3, type _arg4) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg1 << "," << _arg2 << "," << _arg3 << "," << _arg4 << ")\n\n"; \
  if ((name[0] != _arg1)||(name[1] != _arg2)||(name[2] != _arg3)||(name[3] != _arg4)) \
    { \
    Modified(); \
    } \
  name[0] = _arg1; \
  name[1] = _arg2; \
  name[2] = _arg3; \
  name[3] = _arg4; \
  }; \
void Set##name (type _arg[4]) \
  { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): setting " << #name " to (" << _arg[0] << "," << _arg[1] << "," << _arg[2] << "," << _arg[3] << ")\n\n"; \
  if ((name[0] != _arg[0])||(name[1] != _arg[1])||(name[2] != _arg[2])||(name[3] != _arg[3])) \
    { \
    Modified(); \
    } \
  name[0] = _arg[0]; \
  name[1] = _arg[1]; \
  name[2] = _arg[2]; \
  name[3] = _arg[3]; \
  }

//
// Get vector macro returns pointer to type (i.e., array of type).
// Example: float *GetColor()
//
#define vlGetVectorMacro(name,type) \
type *Get##name () { \
  if (Debug)   cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): returning " << #name " pointer " << name << "\n\n"; \
  return name; \
}

//
// This macro is used for  debug statements in instance methods
// vlDebugMacro(<< "this is debug info" << this->SomeVariable);
//
#define vlDebugMacro(x) \
  if (Debug) cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): " x << "\n\n"

//
// This macro is used to print out errors
// vlErrorMacro(<< "Error message" << variable);
//
#define vlErrorMacro(x) \
  cerr << "In " __FILE__ << ", line " << __LINE__ << "\n" << this->GetClassName() << " (" << this << "): " x << "\n\n"

#endif
<|endoftext|>


<commit_before>/*

	compute the Restricted Voronoi Diagram in CPU

*/

//RVD computing part
#include "Command_line.h"
#include "Mesh_io.h"
#include "Mesh.h"
#include "Points.h"
#include "Mesh_repair.h"

// Cuda part
#include "CudaHelper.h"
#include <time.h>

// Renderring part
#include "Glut_generator.h"
#include "DrawGraphics.h"

#include "RVD.h"

#define WINDOWS_WIDTH 1000
#define WINDOWS_HEIGHT 800

using namespace P_RVD;

GraphicsDrawer* m_GraphicsDrawer = new GraphicsDrawer();
Points p_in, p_out;
Mesh M_in;

/*
	call the cuda function
	pass the data to the device
*/
extern "C" void runCuda(double* host_seeds_pointer, double* host_mesh_vertex_pointer,
	int* host_facet_index, int points_nb, int mesh_vertex_nb, int mesh_facet_number);

void RenderCB(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.1f, 0.1f, 0.2f, 0.0f);

	glDisable(GL_COLOR_MATERIAL);
	glDisable(GL_LIGHTING);
	glColor3f(1.0f, 0.0f, 0.0f);
	m_GraphicsDrawer->DrawPoints(p_in);

	glColor3f(0.0f, 1.0f, 0.0f);
	m_GraphicsDrawer->DrawPoints(p_out);

	glEnable(GL_LIGHTING);
	glEnable(GL_COLOR_MATERIAL);
	glColor3f(0.8f, 0.8f, 0.8f);
	glPolygonMode(GL_FRONT, GL_LINE);
	m_GraphicsDrawer->DrawMesh(M_in);

	glFlush();
	glutSwapBuffers();
	glutPostRedisplay();
}

void myResize(int width, int height)
{

	//get the viewport of GLUI and then set the viewport back to that after the resize
	glViewport(0, 0, width, height);//viewportڴ趨һӽǵĴСһڻΪӽ
	glMatrixMode(GL_PROJECTION);

	glPushMatrix();
	glLoadIdentity();
	gluPerspective(60.0, (float)width / height, 0.5f, 20.0f);//趨ӽ
	glPopMatrix();
	gluLookAt(1.0f, 0.0f, 0.0f, 0.0f, 0.f, 0.0f, 0.0f, 1.0f, 0.0f);
	glClearColor((GLclampf)1 / 255, (GLclampf)1 / 255, (GLclampf)1 / 255, 0.0);//ˢɻɫ
	glEnable(GL_DEPTH_TEST);
}

int main(int argc, char** argv)
{
	std::vector<std::string> filenames;
	if (!Cmd::parse_argu(argc, argv, filenames))
	{
		fprintf(stderr, "cannot parse the argument into filenames!");
		return -1;
	}

	std::string mesh_filename = filenames[0];
	std::string points_filename = filenames[0];
	std::string output_filename;
	if (filenames.size() >= 2) {
		points_filename = filenames[1];
	}
	output_filename = (filenames.size() == 3) ? filenames[2] : "out.eobj";

	Mesh  M_out, points_in;
	FileType mesh_type = OBJfile;

	if (!mesh_load(mesh_filename, M_in))
	{
		fprintf(stderr, "cannot load Mesh into M_in!");
		return -1;
	}

	if (!mesh_load(points_filename, points_in, false))
	{
		fprintf(stderr, "cannot load points into points_in!");
		return -1;
	}

	mesh_repair(M_in);
	Points points(points_in);
	Points points_out(points_in);

	/*
		Kdtree
	*/

	/*
		trans the data from host to device
	*/
	double* host_points;

	trans_points(points, host_points);

	double* host_mesh_vertex;
	int* host_facet_index;

	trans_mesh(M_in, host_mesh_vertex, host_facet_index);

	long t1 = clock();
	runCuda(host_points, host_mesh_vertex, host_facet_index, points.getPointsNumber(),
		M_in.meshVertices.getPointNumber(), M_in.meshFacets.getFacetsNumber());

	printf("GPU running time : %lfms\n", (double)(clock() - t1));

	/*
		Compute the RVD in CPU
	*/
	long t2 = clock();
	RestrictedVoronoiDiagram *m_RVD = new RestrictedVoronoiDiagram(&M_in, &points_out);
	m_RVD->compute_RVD();
	printf("CPU running time : %lfms\n", (double)(clock() - t2));

	/*
		Set the Windows
		Use the GLUT lib
	*/
	GLUTBackendInit(argc, argv, true, false);
	GLUTBackendCreateWindow(WINDOWS_WIDTH, WINDOWS_HEIGHT, false, "Rvd");

	//GraphicsDrawer* m_GraphicsDrawer = new GraphicsDrawer();
	m_GraphicsDrawer->Init();
	m_GraphicsDrawer->Run();

	//p_in  records the position before
	//p_out records the position after compute RVD
	p_in = points;
	p_out = points_out;

	glutDisplayFunc(&RenderCB);
	//glutReshapeFunc(&myResize);

	glutPostRedisplay();
	glutMainLoop();

	delete m_GraphicsDrawer;

	return 0;
}
<commit_msg>update<commit_after>/*

	compute the Restricted Voronoi Diagram in CPU

*/

//RVD computing part
#include "Command_line.h"
#include "Mesh_io.h"
#include "Mesh.h"
#include "Points.h"
#include "Mesh_repair.h"

// Cuda part
#include "CudaHelper.h"
#include <time.h>

// Renderring part
#include "Glut_generator.h"
#include "DrawGraphics.h"

#include "RVD.h"

#define WINDOWS_WIDTH 1000
#define WINDOWS_HEIGHT 800

using namespace P_RVD;

GraphicsDrawer* m_GraphicsDrawer = new GraphicsDrawer();
Points p_in, p_out;
Mesh M_in;

/*
	call the cuda function
	pass the data to the device
*/
extern "C" void runCuda(double* host_seeds_pointer, double* host_mesh_vertex_pointer,
	int* host_facet_index, int points_nb, int mesh_vertex_nb, int mesh_facet_number);

void RenderCB(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.1f, 0.1f, 0.2f, 0.0f);

	glDisable(GL_COLOR_MATERIAL);
	glDisable(GL_LIGHTING);
	glColor3f(1.0f, 0.0f, 0.0f);
	m_GraphicsDrawer->DrawPoints(p_in);

	glColor3f(0.0f, 1.0f, 0.0f);
	m_GraphicsDrawer->DrawPoints(p_out);

	glEnable(GL_LIGHTING);
	glEnable(GL_COLOR_MATERIAL);
	glColor3f(0.8f, 0.8f, 0.8f);
	glPolygonMode(GL_FRONT, GL_LINE);
	m_GraphicsDrawer->DrawMesh(M_in);

	glFlush();
	glutSwapBuffers();
	glutPostRedisplay();
}

void myResize(int width, int height)
{

	//get the viewport of GLUI and then set the viewport back to that after the resize
	glViewport(0, 0, width, height);//viewportڴ趨һӽǵĴСһڻΪӽ
	glMatrixMode(GL_PROJECTION);

	glPushMatrix();
	glLoadIdentity();
	gluPerspective(60.0, (float)width / height, 0.5f, 20.0f);//趨ӽ
	glPopMatrix();
	gluLookAt(1.0f, 0.0f, 0.0f, 0.0f, 0.f, 0.0f, 0.0f, 1.0f, 0.0f);
	glClearColor((GLclampf)1 / 255, (GLclampf)1 / 255, (GLclampf)1 / 255, 0.0);//ˢɻɫ
	glEnable(GL_DEPTH_TEST);
}

int main(int argc, char** argv)
{
	std::vector<std::string> filenames;
	if (!Cmd::parse_argu(argc, argv, filenames))
	{
		fprintf(stderr, "cannot parse the argument into filenames!");
		return -1;
	}

	std::string mesh_filename = filenames[0];
	std::string points_filename = filenames[0];
	std::string output_filename;
	if (filenames.size() >= 2) {
		points_filename = filenames[1];
	}
	output_filename = (filenames.size() == 3) ? filenames[2] : "out.eobj";

	Mesh  M_out, points_in;
	FileType mesh_type = OBJfile;

	if (!mesh_load(mesh_filename, M_in))
	{
		fprintf(stderr, "cannot load Mesh into M_in!");
		return -1;
	}

	if (!mesh_load(points_filename, points_in, false))
	{
		fprintf(stderr, "cannot load points into points_in!");
		return -1;
	}

	mesh_repair(M_in);
	Points points(points_in);
	Points points_out(points_in);

	/*
		Kdtree
	*/

	/*
		trans the data from host to device
	*/
	double* host_points = NULL;

	trans_points(points, host_points);

	double* host_mesh_vertex = NULL;
	int* host_facet_index = NULL;

	trans_mesh(M_in, host_mesh_vertex, host_facet_index);

	long t1 = clock();
	runCuda(host_points, host_mesh_vertex, host_facet_index, points.getPointsNumber(),
		M_in.meshVertices.getPointNumber(), M_in.meshFacets.getFacetsNumber());

	printf("GPU running time : %lfms\n", (double)(clock() - t1));

	/*
		Compute the RVD in CPU
	*/
	long t2 = clock();
	RestrictedVoronoiDiagram *m_RVD = new RestrictedVoronoiDiagram(&M_in, &points_out);
	m_RVD->compute_RVD();
	printf("CPU running time : %lfms\n", (double)(clock() - t2));

	/*
		Set the Windows
		Use the GLUT lib
	*/
	GLUTBackendInit(argc, argv, true, false);
	GLUTBackendCreateWindow(WINDOWS_WIDTH, WINDOWS_HEIGHT, false, "Rvd");

	//GraphicsDrawer* m_GraphicsDrawer = new GraphicsDrawer();
	m_GraphicsDrawer->Init();
	m_GraphicsDrawer->Run();

	//p_in  records the position before
	//p_out records the position after compute RVD
	p_in = points;
	p_out = points_out;

	//glutDisplayFunc(&RenderCB);
	//glutReshapeFunc(&myResize);

	//glutPostRedisplay();
	//glutMainLoop();

	delete m_GraphicsDrawer;

	return 0;
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010 Manuel Yguel <manuel.yguel@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"
#include <unsupported/Eigen/Polynomials>
#include <iostream>
#include <algorithm>

using namespace std;

namespace Eigen {
namespace internal {
template<int Size>
struct increment_if_fixed_size
{
  enum {
    ret = (Size == Dynamic) ? Dynamic : Size+1
  };
};
}
}

template<int Deg, typename POLYNOMIAL, typename SOLVER>
bool aux_evalSolver( const POLYNOMIAL& pols, SOLVER& psolve )
{
  typedef typename POLYNOMIAL::Index Index;
  typedef typename POLYNOMIAL::Scalar Scalar;

  typedef typename SOLVER::RootsType    RootsType;
  typedef Matrix<Scalar,Deg,1>          EvalRootsType;

  const Index deg = pols.size()-1;

  // Test template constructor from coefficient vector
  SOLVER solve_constr (pols);

  psolve.compute( pols );
  const RootsType& roots( psolve.roots() );
  EvalRootsType evr( deg );
  for( int i=0; i<roots.size(); ++i ){
    evr[i] = std::abs( poly_eval( pols, roots[i] ) ); }

  bool evalToZero = evr.isZero( test_precision<Scalar>() );
  if( !evalToZero )
  {
    cerr << "WRONG root: " << endl;
    cerr << "Polynomial: " << pols.transpose() << endl;
    cerr << "Roots found: " << roots.transpose() << endl;
    cerr << "Abs value of the polynomial at the roots: " << evr.transpose() << endl;
    cerr << endl;
  }

  std::vector<Scalar> rootModuli( roots.size() );
  Map< EvalRootsType > aux( &rootModuli[0], roots.size() );
  aux = roots.array().abs();
  std::sort( rootModuli.begin(), rootModuli.end() );
  bool distinctModuli=true;
  for( size_t i=1; i<rootModuli.size() && distinctModuli; ++i )
  {
    if( internal::isApprox( rootModuli[i], rootModuli[i-1] ) ){
      distinctModuli = false; }
  }
  VERIFY( evalToZero || !distinctModuli );

  return distinctModuli;
}

template<int Deg, typename POLYNOMIAL>
void evalSolver( const POLYNOMIAL& pols )
{
  typedef typename POLYNOMIAL::Scalar Scalar;

  typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;

  PolynomialSolverType psolve;
  aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve );
}

template< int Deg, typename POLYNOMIAL, typename ROOTS, typename REAL_ROOTS >
void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const REAL_ROOTS& real_roots )
{
  using std::sqrt;
  typedef typename POLYNOMIAL::Scalar Scalar;

  typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;

  PolynomialSolverType psolve;
  if( aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve ) )
  {
    //It is supposed that
    // 1) the roots found are correct
    // 2) the roots have distinct moduli

    typedef typename POLYNOMIAL::Scalar                 Scalar;
    typedef typename REAL_ROOTS::Scalar                 Real;

    //Test realRoots
    std::vector< Real > calc_realRoots;
    psolve.realRoots( calc_realRoots );
    VERIFY( calc_realRoots.size() == (size_t)real_roots.size() );

    const Scalar psPrec = sqrt( test_precision<Scalar>() );

    for( size_t i=0; i<calc_realRoots.size(); ++i )
    {
      bool found = false;
      for( size_t j=0; j<calc_realRoots.size()&& !found; ++j )
      {
        if( internal::isApprox( calc_realRoots[i], real_roots[j], psPrec ) ){
          found = true; }
      }
      VERIFY( found );
    }

    //Test greatestRoot
    VERIFY( internal::isApprox( roots.array().abs().maxCoeff(),
          abs( psolve.greatestRoot() ), psPrec ) );

    //Test smallestRoot
    VERIFY( internal::isApprox( roots.array().abs().minCoeff(),
          abs( psolve.smallestRoot() ), psPrec ) );

    bool hasRealRoot;
    //Test absGreatestRealRoot
    Real r = psolve.absGreatestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().abs().maxCoeff(), abs(r), psPrec ) );  }

    //Test absSmallestRealRoot
    r = psolve.absSmallestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().abs().minCoeff(), abs( r ), psPrec ) ); }

    //Test greatestRealRoot
    r = psolve.greatestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().maxCoeff(), r, psPrec ) ); }

    //Test smallestRealRoot
    r = psolve.smallestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
    VERIFY( internal::isApprox( real_roots.array().minCoeff(), r, psPrec ) ); }
  }
}

template<typename _Scalar, int _Deg>
void polynomialsolver(int deg)
{
  typedef internal::increment_if_fixed_size<_Deg>            Dim;
  typedef Matrix<_Scalar,Dim::ret,1>                  PolynomialType;
  typedef Matrix<_Scalar,_Deg,1>                      EvalRootsType;

  cout << "Standard cases" << endl;
  PolynomialType pols = PolynomialType::Random(deg+1);
  evalSolver<_Deg,PolynomialType>( pols );

  cout << "Hard cases" << endl;
  _Scalar multipleRoot = internal::random<_Scalar>();
  EvalRootsType allRoots = EvalRootsType::Constant(deg,multipleRoot);
  roots_to_monicPolynomial( allRoots, pols );
  evalSolver<_Deg,PolynomialType>( pols );

  cout << "Test sugar" << endl;
  EvalRootsType realRoots = EvalRootsType::Random(deg);
  roots_to_monicPolynomial( realRoots, pols );
  evalSolverSugarFunction<_Deg>(
      pols,
      realRoots.template cast <
                    std::complex<
                         typename NumTraits<_Scalar>::Real
                         >
                    >(),
      realRoots );
}

void test_polynomialsolver()
{
  for(int i = 0; i < g_repeat; i++)
  {
    CALL_SUBTEST_1( (polynomialsolver<float,1>(1)) );
    CALL_SUBTEST_2( (polynomialsolver<double,2>(2)) );
    CALL_SUBTEST_3( (polynomialsolver<double,3>(3)) );
    CALL_SUBTEST_4( (polynomialsolver<float,4>(4)) );
    CALL_SUBTEST_5( (polynomialsolver<double,5>(5)) );
    CALL_SUBTEST_6( (polynomialsolver<float,6>(6)) );
    CALL_SUBTEST_7( (polynomialsolver<float,7>(7)) );
    CALL_SUBTEST_8( (polynomialsolver<double,8>(8)) );

    CALL_SUBTEST_9( (polynomialsolver<float,Dynamic>(
            internal::random<int>(9,13)
            )) );
    CALL_SUBTEST_10((polynomialsolver<double,Dynamic>(
            internal::random<int>(9,13)
            )) );
    CALL_SUBTEST_11((polynomialsolver<float,Dynamic>(1)) );
  }
}
<commit_msg>Extend polynomial solver unit tests to complexes<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010 Manuel Yguel <manuel.yguel@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"
#include <unsupported/Eigen/Polynomials>
#include <iostream>
#include <algorithm>

using namespace std;

namespace Eigen {
namespace internal {
template<int Size>
struct increment_if_fixed_size
{
  enum {
    ret = (Size == Dynamic) ? Dynamic : Size+1
  };
};
}
}

template<int Deg, typename POLYNOMIAL, typename SOLVER>
bool aux_evalSolver( const POLYNOMIAL& pols, SOLVER& psolve )
{
  typedef typename POLYNOMIAL::Index Index;
  typedef typename POLYNOMIAL::Scalar Scalar;
  typedef typename POLYNOMIAL::RealScalar RealScalar;

  typedef typename SOLVER::RootsType    RootsType;
  typedef Matrix<RealScalar,Deg,1>      EvalRootsType;

  const Index deg = pols.size()-1;

  // Test template constructor from coefficient vector
  SOLVER solve_constr (pols);

  psolve.compute( pols );
  const RootsType& roots( psolve.roots() );
  EvalRootsType evr( deg );
  for( int i=0; i<roots.size(); ++i ){
    evr[i] = std::abs( poly_eval( pols, roots[i] ) ); }

  bool evalToZero = evr.isZero( test_precision<Scalar>() );
  if( !evalToZero )
  {
    cerr << "WRONG root: " << endl;
    cerr << "Polynomial: " << pols.transpose() << endl;
    cerr << "Roots found: " << roots.transpose() << endl;
    cerr << "Abs value of the polynomial at the roots: " << evr.transpose() << endl;
    cerr << endl;
  }

  std::vector<RealScalar> rootModuli( roots.size() );
  Map< EvalRootsType > aux( &rootModuli[0], roots.size() );
  aux = roots.array().abs();
  std::sort( rootModuli.begin(), rootModuli.end() );
  bool distinctModuli=true;
  for( size_t i=1; i<rootModuli.size() && distinctModuli; ++i )
  {
    if( internal::isApprox( rootModuli[i], rootModuli[i-1] ) ){
      distinctModuli = false; }
  }
  VERIFY( evalToZero || !distinctModuli );

  return distinctModuli;
}

template<int Deg, typename POLYNOMIAL>
void evalSolver( const POLYNOMIAL& pols )
{
  typedef typename POLYNOMIAL::Scalar Scalar;

  typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;

  PolynomialSolverType psolve;
  aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve );
}

template< int Deg, typename POLYNOMIAL, typename ROOTS, typename REAL_ROOTS >
void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const REAL_ROOTS& real_roots )
{
  using std::sqrt;
  typedef typename POLYNOMIAL::Scalar Scalar;
  typedef typename POLYNOMIAL::RealScalar RealScalar;

  typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;

  PolynomialSolverType psolve;
  if( aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve ) )
  {
    //It is supposed that
    // 1) the roots found are correct
    // 2) the roots have distinct moduli

    //Test realRoots
    std::vector< RealScalar > calc_realRoots;
    psolve.realRoots( calc_realRoots,  test_precision<RealScalar>());
    VERIFY_IS_EQUAL( calc_realRoots.size() , (size_t)real_roots.size() );

    const RealScalar psPrec = sqrt( test_precision<RealScalar>() );

    for( size_t i=0; i<calc_realRoots.size(); ++i )
    {
      bool found = false;
      for( size_t j=0; j<calc_realRoots.size()&& !found; ++j )
      {
        if( internal::isApprox( calc_realRoots[i], real_roots[j], psPrec ) ){
          found = true; }
      }
      VERIFY( found );
    }

    //Test greatestRoot
    VERIFY( internal::isApprox( roots.array().abs().maxCoeff(),
          abs( psolve.greatestRoot() ), psPrec ) );

    //Test smallestRoot
    VERIFY( internal::isApprox( roots.array().abs().minCoeff(),
          abs( psolve.smallestRoot() ), psPrec ) );

    bool hasRealRoot;
    //Test absGreatestRealRoot
    RealScalar r = psolve.absGreatestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().abs().maxCoeff(), abs(r), psPrec ) );  }

    //Test absSmallestRealRoot
    r = psolve.absSmallestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().abs().minCoeff(), abs( r ), psPrec ) ); }

    //Test greatestRealRoot
    r = psolve.greatestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
      VERIFY( internal::isApprox( real_roots.array().maxCoeff(), r, psPrec ) ); }

    //Test smallestRealRoot
    r = psolve.smallestRealRoot( hasRealRoot );
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
    if( hasRealRoot ){
    VERIFY( internal::isApprox( real_roots.array().minCoeff(), r, psPrec ) ); }
  }
}

template<typename _Scalar, int _Deg>
void polynomialsolver(int deg)
{
  typedef typename NumTraits<_Scalar>::Real RealScalar;
  typedef internal::increment_if_fixed_size<_Deg>     Dim;
  typedef Matrix<_Scalar,Dim::ret,1>                  PolynomialType;
  typedef Matrix<_Scalar,_Deg,1>                      EvalRootsType;
  typedef Matrix<RealScalar,_Deg,1>                   RealRootsType;

  cout << "Standard cases" << endl;
  PolynomialType pols = PolynomialType::Random(deg+1);
  evalSolver<_Deg,PolynomialType>( pols );

  cout << "Hard cases" << endl;
  _Scalar multipleRoot = internal::random<_Scalar>();
  EvalRootsType allRoots = EvalRootsType::Constant(deg,multipleRoot);
  roots_to_monicPolynomial( allRoots, pols );
  evalSolver<_Deg,PolynomialType>( pols );

  cout << "Test sugar" << endl;
  RealRootsType realRoots = RealRootsType::Random(deg);
  roots_to_monicPolynomial( realRoots, pols );
  evalSolverSugarFunction<_Deg>(
      pols,
      realRoots.template cast <std::complex<RealScalar> >().eval(),
      realRoots );
}

void test_polynomialsolver()
{
  for(int i = 0; i < g_repeat; i++)
  {
    CALL_SUBTEST_1( (polynomialsolver<float,1>(1)) );
    CALL_SUBTEST_2( (polynomialsolver<double,2>(2)) );
    CALL_SUBTEST_3( (polynomialsolver<double,3>(3)) );
    CALL_SUBTEST_4( (polynomialsolver<float,4>(4)) );
    CALL_SUBTEST_5( (polynomialsolver<double,5>(5)) );
    CALL_SUBTEST_6( (polynomialsolver<float,6>(6)) );
    CALL_SUBTEST_7( (polynomialsolver<float,7>(7)) );
    CALL_SUBTEST_8( (polynomialsolver<double,8>(8)) );

    CALL_SUBTEST_9( (polynomialsolver<float,Dynamic>(
            internal::random<int>(9,13)
            )) );
    CALL_SUBTEST_10((polynomialsolver<double,Dynamic>(
            internal::random<int>(9,13)
            )) );
    CALL_SUBTEST_11((polynomialsolver<float,Dynamic>(1)) );
    CALL_SUBTEST_12((polynomialsolver<std::complex<double>,Dynamic>(internal::random<int>(2,13))) );
  }
}
<|endoftext|>


<commit_before>#include <system_log>
#include <kernel.hpp>
#include <os.hpp>
#include <kernel/memory.hpp>
#include <ringbuffer>
#include <kprint>

struct Log_buffer {
  uint64_t magic;
  int32_t  capacity;
  uint32_t flags;
  char     vla[0];

  static const uint64_t MAGIC = 0xDEADC0DEDEADC0DE;

  MemoryRingBuffer* get_mrb()
  { return reinterpret_cast<MemoryRingBuffer*>(&vla[0]); }
};

static FixedRingBuffer<16384> temp_mrb;
#define MRB_AREA_SIZE (65536) // 64kb
#define MRB_LOG_SIZE  (MRB_AREA_SIZE - sizeof(MemoryRingBuffer) - sizeof(Log_buffer))
static MemoryRingBuffer* mrb = nullptr;
static inline RingBuffer* get_mrb()
{
  if (mrb != nullptr) return mrb;
  return &temp_mrb;
}

inline static char* get_system_log_loc()
{
#ifdef ARCH_x86_64
  return (char*) ((1ull << 45) - MRB_AREA_SIZE);
#else
  return (char*) OS::liveupdate_storage_area() - MRB_AREA_SIZE;
#endif
}
inline static auto* get_ringbuffer_data()
{
  return get_system_log_loc() + sizeof(Log_buffer) + sizeof(MemoryRingBuffer);
}
inline static auto& get_log_buffer()
{
  return *(Log_buffer*) get_system_log_loc();
}

uint32_t SystemLog::get_flags()
{
  return get_log_buffer().flags;
}

void SystemLog::set_flags(uint32_t new_flags)
{
  get_log_buffer().flags |= new_flags;
}

void SystemLog::clear_flags()
{
  get_log_buffer().flags = 0;
}

void SystemLog::write(const char* buffer, size_t length)
{
  size_t free = get_mrb()->free_space();
  if (free < length) {
    get_mrb()->discard(length - free);
  }
  get_mrb()->write(buffer, length);
}

std::vector<char> SystemLog::copy()
{
  const auto* buffer = get_mrb()->sequentialize();
  return {buffer, buffer + get_mrb()->size()};
}

void SystemLog::initialize()
{
  INFO("SystemLog", "Initializing System Log");

#ifdef ARCH_x86_64
  using namespace util::bitops;
  const uintptr_t syslog_area = (uintptr_t) get_system_log_loc();
  const uintptr_t lu_phys = os::mem::virt_to_phys((uintptr_t) kernel::liveupdate_storage_area());
  // move systemlog to high memory and unpresent physical
  os::mem::virtual_move(lu_phys - MRB_AREA_SIZE, MRB_AREA_SIZE,
                        syslog_area, "SystemLog");
#endif

  auto& buffer = get_log_buffer();
  mrb = buffer.get_mrb();

  // There isn't one, so we have to create
  if(buffer.magic != Log_buffer::MAGIC)
  {
    new (mrb) MemoryRingBuffer(get_ringbuffer_data(), MRB_LOG_SIZE);
    buffer.magic = Log_buffer::MAGIC;
    buffer.capacity = mrb->capacity();
    buffer.flags    = 0;

    INFO2("Created @ %p (%i kB)", get_system_log_loc(), mrb->capacity() / 1024);
    INFO2("Data @ %p (%i bytes)", mrb->data(), mrb->capacity());
  }
  // Correct magic means (hopefully) existing system log
  else
  {
    auto* state = (int*)(&buffer.vla);
    assert(state[0] >= 16);

    new (mrb) MemoryRingBuffer(get_ringbuffer_data(),
                    state[0], state[1], state[2], state[3]);

    INFO2("Restored @ %p (%i kB) Flags: 0x%x",
      mrb->data(), mrb->capacity() / 1024, buffer.flags);
  }
  Ensures(mrb != nullptr);
  Expects(buffer.capacity == mrb->capacity());
  Expects(mrb->is_valid());

  // copy from temp RB
  SystemLog::write(temp_mrb.sequentialize(), temp_mrb.size());
}

__attribute__((constructor))
static void system_log_gconstr()
{
  os::add_stdout(SystemLog::write);
}
<commit_msg>plugins: change to reflect HAL api change<commit_after>#include <system_log>
#include <kernel.hpp>
#include <os.hpp>
#include <kernel/memory.hpp>
#include <ringbuffer>
#include <kprint>

struct Log_buffer {
  uint64_t magic;
  int32_t  capacity;
  uint32_t flags;
  char     vla[0];

  static const uint64_t MAGIC = 0xDEADC0DEDEADC0DE;

  MemoryRingBuffer* get_mrb()
  { return reinterpret_cast<MemoryRingBuffer*>(&vla[0]); }
};

static FixedRingBuffer<16384> temp_mrb;
#define MRB_AREA_SIZE (65536) // 64kb
#define MRB_LOG_SIZE  (MRB_AREA_SIZE - sizeof(MemoryRingBuffer) - sizeof(Log_buffer))
static MemoryRingBuffer* mrb = nullptr;
static inline RingBuffer* get_mrb()
{
  if (mrb != nullptr) return mrb;
  return &temp_mrb;
}

inline static char* get_system_log_loc()
{
#ifdef ARCH_x86_64
  return (char*) ((1ull << 45) - MRB_AREA_SIZE);
#else
  return (char*) kernel::liveupdate_storage_area() - MRB_AREA_SIZE;
#endif
}
inline static auto* get_ringbuffer_data()
{
  return get_system_log_loc() + sizeof(Log_buffer) + sizeof(MemoryRingBuffer);
}
inline static auto& get_log_buffer()
{
  return *(Log_buffer*) get_system_log_loc();
}

uint32_t SystemLog::get_flags()
{
  return get_log_buffer().flags;
}

void SystemLog::set_flags(uint32_t new_flags)
{
  get_log_buffer().flags |= new_flags;
}

void SystemLog::clear_flags()
{
  get_log_buffer().flags = 0;
}

void SystemLog::write(const char* buffer, size_t length)
{
  size_t free = get_mrb()->free_space();
  if (free < length) {
    get_mrb()->discard(length - free);
  }
  get_mrb()->write(buffer, length);
}

std::vector<char> SystemLog::copy()
{
  const auto* buffer = get_mrb()->sequentialize();
  return {buffer, buffer + get_mrb()->size()};
}

void SystemLog::initialize()
{
  INFO("SystemLog", "Initializing System Log");

#ifdef ARCH_x86_64
  using namespace util::bitops;
  const uintptr_t syslog_area = (uintptr_t) get_system_log_loc();
  const uintptr_t lu_phys = os::mem::virt_to_phys((uintptr_t) kernel::liveupdate_storage_area());
  // move systemlog to high memory and unpresent physical
  os::mem::virtual_move(lu_phys - MRB_AREA_SIZE, MRB_AREA_SIZE,
                        syslog_area, "SystemLog");
#endif

  auto& buffer = get_log_buffer();
  mrb = buffer.get_mrb();

  // There isn't one, so we have to create
  if(buffer.magic != Log_buffer::MAGIC)
  {
    new (mrb) MemoryRingBuffer(get_ringbuffer_data(), MRB_LOG_SIZE);
    buffer.magic = Log_buffer::MAGIC;
    buffer.capacity = mrb->capacity();
    buffer.flags    = 0;

    INFO2("Created @ %p (%i kB)", get_system_log_loc(), mrb->capacity() / 1024);
    INFO2("Data @ %p (%i bytes)", mrb->data(), mrb->capacity());
  }
  // Correct magic means (hopefully) existing system log
  else
  {
    auto* state = (int*)(&buffer.vla);
    assert(state[0] >= 16);

    new (mrb) MemoryRingBuffer(get_ringbuffer_data(),
                    state[0], state[1], state[2], state[3]);

    INFO2("Restored @ %p (%i kB) Flags: 0x%x",
      mrb->data(), mrb->capacity() / 1024, buffer.flags);
  }
  Ensures(mrb != nullptr);
  Expects(buffer.capacity == mrb->capacity());
  Expects(mrb->is_valid());

  // copy from temp RB
  SystemLog::write(temp_mrb.sequentialize(), temp_mrb.size());
}

__attribute__((constructor))
static void system_log_gconstr()
{
  os::add_stdout(SystemLog::write);
}
<|endoftext|>