<commit_before>// Copyright (c) 2012 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/browser/chromeos/login/rounded_rect_painter.h"

#include "base/logging.h"
#include "chrome/browser/chromeos/login/helper.h"
#include "third_party/skia/include/effects/SkBlurMaskFilter.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/border.h"
#include "ui/views/painter.h"

namespace chromeos {

namespace {

const SkColor kScreenTopColor = SkColorSetRGB(250, 251, 251);
const SkColor kScreenBottomColor = SkColorSetRGB(204, 209, 212);
const SkColor kScreenShadowColor = SkColorSetARGB(64, 34, 54, 115);
const int kScreenShadow = 10;

void DrawRoundedRect(gfx::Canvas* canvas,
                     const SkRect& rect,
                     int corner_radius,
                     SkColor top_color,
                     SkColor bottom_color) {
  SkPath path;
  path.addRoundRect(rect,
                    SkIntToScalar(corner_radius), SkIntToScalar(corner_radius));
  SkPaint paint;
  paint.setStyle(SkPaint::kFill_Style);
  paint.setFlags(SkPaint::kAntiAlias_Flag);
  if (top_color != bottom_color) {
    SkPoint p[2];
    p[0].set(SkIntToScalar(rect.left()), SkIntToScalar(rect.top()));
    p[1].set(SkIntToScalar(rect.left()), SkIntToScalar(rect.bottom()));
    SkColor colors[2] = { top_color, bottom_color };
    SkShader* s = SkGradientShader::CreateLinear(p, colors, NULL, 2,
        SkShader::kClamp_TileMode, NULL);
    paint.setShader(s);
    // Need to unref shader, otherwise never deleted.
    s->unref();
  } else {
    paint.setColor(top_color);
  }

  canvas->DrawPath(path, paint);
}

void DrawRoundedRectShadow(gfx::Canvas* canvas,
                           const SkRect& rect,
                           int corner_radius,
                           int shadow,
                           SkColor color) {
  SkPaint paint;
  paint.setFlags(SkPaint::kAntiAlias_Flag);
  paint.setStyle(SkPaint::kFill_Style);
  paint.setColor(color);
  SkMaskFilter* filter = SkBlurMaskFilter::Create(
      shadow / 2, SkBlurMaskFilter::kNormal_BlurStyle);
  paint.setMaskFilter(filter)->unref();
  SkRect inset_rect(rect);
  inset_rect.inset(SkIntToScalar(shadow / 2), SkIntToScalar(shadow / 2));
  canvas->sk_canvas()->drawRoundRect(
      inset_rect,
      SkIntToScalar(corner_radius), SkIntToScalar(corner_radius),
      paint);
  paint.setMaskFilter(NULL);
}

void DrawRectWithBorder(gfx::Canvas* canvas,
                        const gfx::Size& size,
                        const BorderDefinition* const border) {
  SkRect rect(gfx::RectToSkRect(gfx::Rect(size)));
  if (border->padding > 0) {
    SkPaint paint;
    paint.setColor(border->padding_color);
    canvas->sk_canvas()->drawRect(rect, paint);
    rect.inset(SkIntToScalar(border->padding), SkIntToScalar(border->padding));
  }
  if (border->shadow > 0) {
    DrawRoundedRectShadow(canvas, rect, border->corner_radius, border->shadow,
                          border->shadow_color);
    rect.inset(SkIntToScalar(border->shadow), SkIntToScalar(border->shadow));
    rect.offset(0, SkIntToScalar(-border->shadow / 3));
  }
  DrawRoundedRect(canvas, rect, border->corner_radius, border->top_color,
                  border->bottom_color);
}

// This Painter can be used to draw a background consistent cross all login
// screens. It draws a rect with padding, shadow and rounded corners.
class RoundedRectPainter : public views::Painter {
 public:
  explicit RoundedRectPainter(const BorderDefinition* const border)
      : border_(border) {
  }

  // Overridden from views::Painter:
  virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE {
    DrawRectWithBorder(canvas, size, border_);
  }

 private:
  const BorderDefinition* const border_;

  DISALLOW_COPY_AND_ASSIGN(RoundedRectPainter);
};

// This border can be used to draw shadow and rounded corners across all
// login screens.
class RoundedRectBorder : public views::Border {
 public:
  explicit RoundedRectBorder(const BorderDefinition* const border)
      : border_(border) {
  }

  virtual void Paint(const views::View& view, gfx::Canvas* canvas) const;
  virtual void GetInsets(gfx::Insets* insets) const;

 private:
  const BorderDefinition* const border_;

  DISALLOW_COPY_AND_ASSIGN(RoundedRectBorder);
};

void RoundedRectBorder::Paint(const views::View& view,
                              gfx::Canvas* canvas) const {
  // Don't paint anything. RoundedRectBorder is used to provide insets only.
}

void RoundedRectBorder::GetInsets(gfx::Insets* insets) const {
  DCHECK(insets);
  int shadow = border_->shadow;
  int inset = border_->corner_radius / 2 + border_->padding + shadow;
  insets->Set(inset - shadow / 3, inset, inset + shadow / 3, inset);
}

// Simple solid round background.
class RoundedBackground : public views::Background {
 public:
  RoundedBackground(int corner_radius,
                    int stroke_width,
                    const SkColor& background_color,
                    const SkColor& stroke_color)
      : corner_radius_(corner_radius),
        stroke_width_(stroke_width),
        stroke_color_(stroke_color) {
    SetNativeControlColor(background_color);
  }

  virtual void Paint(gfx::Canvas* canvas, views::View* view) const {
    SkRect rect;
    rect.iset(0, 0, view->width(), view->height());
    SkPath path;
    path.addRoundRect(rect,
                      SkIntToScalar(corner_radius_),
                      SkIntToScalar(corner_radius_));
    // Draw interior.
    SkPaint paint;
    paint.setStyle(SkPaint::kFill_Style);
    paint.setFlags(SkPaint::kAntiAlias_Flag);
    paint.setColor(get_color());
    canvas->DrawPath(path, paint);
    // Redraw boundary region with correspoinding color.
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(SkIntToScalar(stroke_width_));
    paint.setColor(stroke_color_);
    canvas->DrawPath(path, paint);
  }

 private:
  int corner_radius_;
  int stroke_width_;
  SkColor stroke_color_;

  DISALLOW_COPY_AND_ASSIGN(RoundedBackground);
};

}  // namespace

// static
const BorderDefinition BorderDefinition::kScreenBorder = {
  0,
  SK_ColorBLACK,
  kScreenShadow,
  kScreenShadowColor,
  login::kScreenCornerRadius,
  kScreenTopColor,
  kScreenBottomColor
};

const BorderDefinition BorderDefinition::kUserBorder = {
  0,
  SK_ColorBLACK,
  0,
  kScreenShadowColor,
  login::kUserCornerRadius,
  kScreenTopColor,
  kScreenBottomColor
};

views::Painter* CreateWizardPainter(const BorderDefinition* const border) {
  return new RoundedRectPainter(border);
}

views::Border* CreateWizardBorder(const BorderDefinition* const border) {
  return new RoundedRectBorder(border);
}

views::Background* CreateRoundedBackground(int corner_radius,
                                           int stroke_width,
                                           SkColor background_color,
                                           SkColor stroke_color) {
  return new RoundedBackground(
      corner_radius, stroke_width, background_color, stroke_color);
}

}  // namespace chromeos
<commit_msg>chromeos: Do not pass SkColor by const-reference as it's defined as POD(integer).<commit_after>// Copyright (c) 2012 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/browser/chromeos/login/rounded_rect_painter.h"

#include "base/logging.h"
#include "chrome/browser/chromeos/login/helper.h"
#include "third_party/skia/include/effects/SkBlurMaskFilter.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/border.h"
#include "ui/views/painter.h"

namespace chromeos {

namespace {

const SkColor kScreenTopColor = SkColorSetRGB(250, 251, 251);
const SkColor kScreenBottomColor = SkColorSetRGB(204, 209, 212);
const SkColor kScreenShadowColor = SkColorSetARGB(64, 34, 54, 115);
const int kScreenShadow = 10;

void DrawRoundedRect(gfx::Canvas* canvas,
                     const SkRect& rect,
                     int corner_radius,
                     SkColor top_color,
                     SkColor bottom_color) {
  SkPath path;
  path.addRoundRect(rect,
                    SkIntToScalar(corner_radius), SkIntToScalar(corner_radius));
  SkPaint paint;
  paint.setStyle(SkPaint::kFill_Style);
  paint.setFlags(SkPaint::kAntiAlias_Flag);
  if (top_color != bottom_color) {
    SkPoint p[2];
    p[0].set(SkIntToScalar(rect.left()), SkIntToScalar(rect.top()));
    p[1].set(SkIntToScalar(rect.left()), SkIntToScalar(rect.bottom()));
    SkColor colors[2] = { top_color, bottom_color };
    SkShader* s = SkGradientShader::CreateLinear(p, colors, NULL, 2,
        SkShader::kClamp_TileMode, NULL);
    paint.setShader(s);
    // Need to unref shader, otherwise never deleted.
    s->unref();
  } else {
    paint.setColor(top_color);
  }

  canvas->DrawPath(path, paint);
}

void DrawRoundedRectShadow(gfx::Canvas* canvas,
                           const SkRect& rect,
                           int corner_radius,
                           int shadow,
                           SkColor color) {
  SkPaint paint;
  paint.setFlags(SkPaint::kAntiAlias_Flag);
  paint.setStyle(SkPaint::kFill_Style);
  paint.setColor(color);
  SkMaskFilter* filter = SkBlurMaskFilter::Create(
      shadow / 2, SkBlurMaskFilter::kNormal_BlurStyle);
  paint.setMaskFilter(filter)->unref();
  SkRect inset_rect(rect);
  inset_rect.inset(SkIntToScalar(shadow / 2), SkIntToScalar(shadow / 2));
  canvas->sk_canvas()->drawRoundRect(
      inset_rect,
      SkIntToScalar(corner_radius), SkIntToScalar(corner_radius),
      paint);
  paint.setMaskFilter(NULL);
}

void DrawRectWithBorder(gfx::Canvas* canvas,
                        const gfx::Size& size,
                        const BorderDefinition* const border) {
  SkRect rect(gfx::RectToSkRect(gfx::Rect(size)));
  if (border->padding > 0) {
    SkPaint paint;
    paint.setColor(border->padding_color);
    canvas->sk_canvas()->drawRect(rect, paint);
    rect.inset(SkIntToScalar(border->padding), SkIntToScalar(border->padding));
  }
  if (border->shadow > 0) {
    DrawRoundedRectShadow(canvas, rect, border->corner_radius, border->shadow,
                          border->shadow_color);
    rect.inset(SkIntToScalar(border->shadow), SkIntToScalar(border->shadow));
    rect.offset(0, SkIntToScalar(-border->shadow / 3));
  }
  DrawRoundedRect(canvas, rect, border->corner_radius, border->top_color,
                  border->bottom_color);
}

// This Painter can be used to draw a background consistent cross all login
// screens. It draws a rect with padding, shadow and rounded corners.
class RoundedRectPainter : public views::Painter {
 public:
  explicit RoundedRectPainter(const BorderDefinition* const border)
      : border_(border) {
  }

  // Overridden from views::Painter:
  virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE {
    DrawRectWithBorder(canvas, size, border_);
  }

 private:
  const BorderDefinition* const border_;

  DISALLOW_COPY_AND_ASSIGN(RoundedRectPainter);
};

// This border can be used to draw shadow and rounded corners across all
// login screens.
class RoundedRectBorder : public views::Border {
 public:
  explicit RoundedRectBorder(const BorderDefinition* const border)
      : border_(border) {
  }

  virtual void Paint(const views::View& view, gfx::Canvas* canvas) const;
  virtual void GetInsets(gfx::Insets* insets) const;

 private:
  const BorderDefinition* const border_;

  DISALLOW_COPY_AND_ASSIGN(RoundedRectBorder);
};

void RoundedRectBorder::Paint(const views::View& view,
                              gfx::Canvas* canvas) const {
  // Don't paint anything. RoundedRectBorder is used to provide insets only.
}

void RoundedRectBorder::GetInsets(gfx::Insets* insets) const {
  DCHECK(insets);
  int shadow = border_->shadow;
  int inset = border_->corner_radius / 2 + border_->padding + shadow;
  insets->Set(inset - shadow / 3, inset, inset + shadow / 3, inset);
}

// Simple solid round background.
class RoundedBackground : public views::Background {
 public:
  RoundedBackground(int corner_radius,
                    int stroke_width,
                    SkColor background_color,
                    SkColor stroke_color)
      : corner_radius_(corner_radius),
        stroke_width_(stroke_width),
        stroke_color_(stroke_color) {
    SetNativeControlColor(background_color);
  }

  virtual void Paint(gfx::Canvas* canvas, views::View* view) const {
    SkRect rect;
    rect.iset(0, 0, view->width(), view->height());
    SkPath path;
    path.addRoundRect(rect,
                      SkIntToScalar(corner_radius_),
                      SkIntToScalar(corner_radius_));
    // Draw interior.
    SkPaint paint;
    paint.setStyle(SkPaint::kFill_Style);
    paint.setFlags(SkPaint::kAntiAlias_Flag);
    paint.setColor(get_color());
    canvas->DrawPath(path, paint);
    // Redraw boundary region with correspoinding color.
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(SkIntToScalar(stroke_width_));
    paint.setColor(stroke_color_);
    canvas->DrawPath(path, paint);
  }

 private:
  int corner_radius_;
  int stroke_width_;
  SkColor stroke_color_;

  DISALLOW_COPY_AND_ASSIGN(RoundedBackground);
};

}  // namespace

// static
const BorderDefinition BorderDefinition::kScreenBorder = {
  0,
  SK_ColorBLACK,
  kScreenShadow,
  kScreenShadowColor,
  login::kScreenCornerRadius,
  kScreenTopColor,
  kScreenBottomColor
};

const BorderDefinition BorderDefinition::kUserBorder = {
  0,
  SK_ColorBLACK,
  0,
  kScreenShadowColor,
  login::kUserCornerRadius,
  kScreenTopColor,
  kScreenBottomColor
};

views::Painter* CreateWizardPainter(const BorderDefinition* const border) {
  return new RoundedRectPainter(border);
}

views::Border* CreateWizardBorder(const BorderDefinition* const border) {
  return new RoundedRectBorder(border);
}

views::Background* CreateRoundedBackground(int corner_radius,
                                           int stroke_width,
                                           SkColor background_color,
                                           SkColor stroke_color) {
  return new RoundedBackground(
      corner_radius, stroke_width, background_color, stroke_color);
}

}  // namespace chromeos
<|endoftext|>


<commit_before>// Copyright (c) 2012 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/browser/history/web_history_service_factory.h"

#include "base/command_line.h"
#include "chrome/browser/content_settings/cookie_settings.h"
#include "chrome/browser/history/web_history_service.h"
#include "chrome/browser/signin/token_service_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/common/chrome_switches.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"

namespace {
// Returns true if the user is signed in and full history sync is enabled,
// and false otherwise.
bool IsHistorySyncEnabled(Profile* profile) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kHistoryDisableFullHistorySync)) {
    ProfileSyncService* sync =
        ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile);
    return sync &&
        sync->sync_initialized() &&
        sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES);
  }
  return false;
}

}  // namespace

// static
WebHistoryServiceFactory* WebHistoryServiceFactory::GetInstance() {
  return Singleton<WebHistoryServiceFactory>::get();
}

// static
history::WebHistoryService* WebHistoryServiceFactory::GetForProfile(
      Profile* profile) {
  if (IsHistorySyncEnabled(profile)) {
    return static_cast<history::WebHistoryService*>(
        GetInstance()->GetServiceForBrowserContext(profile, true));
  }
  return NULL;
}

BrowserContextKeyedService* WebHistoryServiceFactory::BuildServiceInstanceFor(
    content::BrowserContext* context) const {
  Profile* profile = static_cast<Profile*>(context);

  // Ensure that the service is not instantiated or used if the user is not
  // signed into sync, or if web history is not enabled.
  return IsHistorySyncEnabled(profile) ?
      new history::WebHistoryService(profile) : NULL;
}

WebHistoryServiceFactory::WebHistoryServiceFactory()
    : BrowserContextKeyedServiceFactory(
        "WebHistoryServiceFactory",
        BrowserContextDependencyManager::GetInstance()) {
  DependsOn(TokenServiceFactory::GetInstance());
  DependsOn(CookieSettings::Factory::GetInstance());
}

WebHistoryServiceFactory::~WebHistoryServiceFactory() {
}
<commit_msg>Cleanup: web history does not depend on TokenService, it depends on ProfileOAuth2TokenService.<commit_after>// Copyright (c) 2012 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/browser/history/web_history_service_factory.h"

#include "base/command_line.h"
#include "chrome/browser/content_settings/cookie_settings.h"
#include "chrome/browser/history/web_history_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/common/chrome_switches.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"

namespace {
// Returns true if the user is signed in and full history sync is enabled,
// and false otherwise.
bool IsHistorySyncEnabled(Profile* profile) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kHistoryDisableFullHistorySync)) {
    ProfileSyncService* sync =
        ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile);
    return sync &&
        sync->sync_initialized() &&
        sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES);
  }
  return false;
}

}  // namespace

// static
WebHistoryServiceFactory* WebHistoryServiceFactory::GetInstance() {
  return Singleton<WebHistoryServiceFactory>::get();
}

// static
history::WebHistoryService* WebHistoryServiceFactory::GetForProfile(
      Profile* profile) {
  if (IsHistorySyncEnabled(profile)) {
    return static_cast<history::WebHistoryService*>(
        GetInstance()->GetServiceForBrowserContext(profile, true));
  }
  return NULL;
}

BrowserContextKeyedService* WebHistoryServiceFactory::BuildServiceInstanceFor(
    content::BrowserContext* context) const {
  Profile* profile = static_cast<Profile*>(context);

  // Ensure that the service is not instantiated or used if the user is not
  // signed into sync, or if web history is not enabled.
  return IsHistorySyncEnabled(profile) ?
      new history::WebHistoryService(profile) : NULL;
}

WebHistoryServiceFactory::WebHistoryServiceFactory()
    : BrowserContextKeyedServiceFactory(
        "WebHistoryServiceFactory",
        BrowserContextDependencyManager::GetInstance()) {
  DependsOn(CookieSettings::Factory::GetInstance());
  DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
}

WebHistoryServiceFactory::~WebHistoryServiceFactory() {
}
<|endoftext|>


<commit_before>/*
 * File:   Class.cpp
 * Author: tjoppen
 *
 * Created on February 14, 2010, 4:20 PM
 */

#include "Class.h"
#include <sstream>
#include <stdexcept>
#include <iostream>
#include <boost/shared_ptr.hpp>

using namespace std;

Class::Class(FullName name, ClassType type) : name(name), type(type),
        base(NULL), isBasic(false), isDocument(false), hasBase(false) {
}

Class::Class(FullName name, ClassType type, FullName baseType) : name(name),
        type(type), base(NULL), isBasic(false), isDocument(false),
        hasBase(true), baseType(baseType) {
}

Class::~Class() {
}

void Class::addMember(string name, Member memberInfo) {
    if(members.find(name) != members.end())
        throw runtime_error("Member " + name + " defined more than once in " + this->name.second);

    cout << this->name.second << " got " << memberInfo.type.first << ":" << memberInfo.type.second << " " << name << ". Occurance: ";

    if(memberInfo.maxOccurs == UNBOUNDED) {
        cout << "at least " << memberInfo.minOccurs;
    } else if(memberInfo.minOccurs == memberInfo.maxOccurs) {
        cout << "exactly " << memberInfo.minOccurs;
    } else {
        cout << "between " << memberInfo.minOccurs << "-" << memberInfo.maxOccurs;
    }

    cout << endl;

    members[name] = memberInfo;
}

/**
 * Default implementation of generateAppender()
 */
string Class::generateAppender() const {
    ostringstream oss;

    for(std::map<std::string, Member>::const_iterator it = members.begin(); it != members.end(); it++) {
        string name = it->first;
        string setterName = it->first;
        string nodeName = name + "Node";

        if(it->second.isArray()) {
            setterName = "(*it)";
            oss << "for(" << it->second.getType() << "::const_iterator it = " << name << ".begin(); it != " << name << ".end(); it++) {" << endl;
        } else if(!it->second.isRequired()) {
            //insert a non-null check
            oss << "if(" << name << ") {" << endl;
        }

        oss << "DOMElement *" << nodeName << " = node->getOwnerDocument()->createElement(X(\"" << name << "\"));" << endl;
        oss << it->second.cl->generateNodeSetter(setterName, nodeName) << endl;
        oss << "node->appendChild(" << nodeName << ");" << endl;

        if(it->second.isArray() || !it->second.isRequired())
            oss << "}" << endl;

        oss << endl;
    }

    return oss.str();
}
//systemet?
string Class::generateNodeSetter(string memberName, string nodeName) const {
    return memberName + "->appendChildren(" + nodeName + ");";
}

string Class::generateParser() const {
    return "";
}

string Class::generateMemberSetter(string memberName, string nodeName) const {
    return memberName + "->parseNode(" + nodeName + ");";
}

string Class::getClassname() const {
    return name.second;
}

string Class::getClassType() const {
    if(isBasic)
        return getClassname();
    else
        return "boost::shared_ptr<" + name.second + ">";
}

string Class::getBaseClassname() const {
    return hasBase ? base->getClassname() : "james::XMLObject";
}

string Class::getBaseHeader() const {
    return hasBase ? base->getClassname() + ".h" : "XMLObject.h";
}

void Class::writeImplementation(ostream& os) const {
    //cout << "writeImplementation()" << endl;
    ClassName className = name.second;

    os << "#include <sstream>" << endl;
    os << "#include <xercesc/dom/DOMDocument.hpp>" << endl;
    os << "#include <xercesc/dom/DOMElement.hpp>" << endl;
    os << "#include \"XercesString.h\"" << endl;
    os << "#include \"" << className << ".h\"" << endl;

    //include headers of all non-basic member types that aren't us
    for(map<string, Member>::const_iterator it = members.begin(); it != members.end(); it++)
        if(!it->second.cl->isBasic && it->second.cl != this)
            os << "#include \"" << it->second.cl->name.second << ".h\"" << endl;

    os << "using namespace std;" << endl;
    os << "using namespace xercesc;" << endl;

    //constructor
    os << className << "::" << className << "() : " << getBaseClassname() << "() {";

    //give all basic optional members a default value of zero
    for(map<string, Member>::const_iterator it = members.begin(); it != members.end(); it++)
        if(!it->second.isArray() && !it->second.isRequired() && it->second.cl->isBasic)
            os << it->first << " = 0;" << endl;

    os << "}" << endl << endl;

    //method implementation
    if(isDocument) {
        os << "std::string " << className << "::getName() const {" << endl;
        os << "return \"" << className << "\";" << endl;
        os << "}" << endl;
    } else {
        os << "void " << className << "::appendChildren(xercesc::DOMNode *node) const {" << endl;

        //call base appender
        if(hasBase)
            os << base->name.second << "::appendChildren(node);" << endl;

        os << generateAppender() << endl;
        os << "}" << endl << endl;

        os << "void " << className << "::parseNode(xercesc::DOMNode *node) {" << endl;
        os << generateParser() << endl;
        os << "}" << endl << endl;
    }
}

void Class::writeHeader(ostream& os) const {
    ClassName className = name.second;

    os << "#ifndef _" << className << "_H" << endl;
    os << "#define _" << className << "_H" << endl;

    os << "#include <vector>" << endl;
    os << "#include <boost/shared_ptr.hpp>" << endl;
    os << "#include \"" << getBaseHeader() << "\"" << endl;

    if(isDocument)
        os << "#include \"XMLDocument.h\"" << endl;

    //non-basic member class prototypes
    for(map<string, Member>::const_iterator it = members.begin(); it != members.end(); it++)
        if(!it->second.cl->isBasic)
            os << "class " << it->second.cl->getClassname() << ";" << endl;

    os << "class " << className << " : public " << getBaseClassname();

    if(isDocument)
        os << ", public james::XMLDocument" << endl;

    os << " {" << endl;
    os << "public:" << endl;

    os << className << "();" << endl;

    //prototypes
    if(isDocument)
        os << "std::string getName() const;" << endl;
    else {
        os << "void appendChildren(xercesc::DOMNode *node) const;" << endl;
        os << "void parseNode(xercesc::DOMNode *node);" << endl;
    }

    //members
    for(map<string, Member>::const_iterator it = members.begin(); it != members.end(); it++) {
        os << it->second.getType() << " " << it->first << ";" << endl;
    }

    os << "};" << endl;

    os << "#endif //_" << className << "_H" << endl;
}

bool Class::Member::isArray() const {
    return maxOccurs > 1 || maxOccurs == UNBOUNDED;
}

bool Class::Member::isRequired() const {
    return minOccurs >= 1;
}

string Class::Member::getType() const {
    //vector if array, regular member otherwise
    if(isArray()) {
        return "std::vector<" + cl->getClassType() + " >";
    } else
        return cl->getClassType();
}
<commit_msg>Basic node parsing generated. Needs check for NULL shared_ptr and such.<commit_after>/*
 * File:   Class.cpp
 * Author: tjoppen
 *
 * Created on February 14, 2010, 4:20 PM
 */

#include "Class.h"
#include <sstream>
#include <stdexcept>
#include <iostream>
#include <boost/shared_ptr.hpp>

using namespace std;

Class::Class(FullName name, ClassType type) : name(name), type(type),
        base(NULL), isBasic(false), isDocument(false), hasBase(false) {
}

Class::Class(FullName name, ClassType type, FullName baseType) : name(name),
        type(type), base(NULL), isBasic(false), isDocument(false),
        hasBase(true), baseType(baseType) {
}

Class::~Class() {
}

void Class::addMember(string name, Member memberInfo) {
    if(members.find(name) != members.end())
        throw runtime_error("Member " + name + " defined more than once in " + this->name.second);

    cout << this->name.second << " got " << memberInfo.type.first << ":" << memberInfo.type.second << " " << name << ". Occurance: ";

    if(memberInfo.maxOccurs == UNBOUNDED) {
        cout << "at least " << memberInfo.minOccurs;
    } else if(memberInfo.minOccurs == memberInfo.maxOccurs) {
        cout << "exactly " << memberInfo.minOccurs;
    } else {
        cout << "between " << memberInfo.minOccurs << "-" << memberInfo.maxOccurs;
    }

    cout << endl;

    members[name] = memberInfo;
}

/**
 * Default implementation of generateAppender()
 */
string Class::generateAppender() const {
    ostringstream oss;

    for(std::map<std::string, Member>::const_iterator it = members.begin(); it != members.end(); it++) {
        string name = it->first;
        string setterName = it->first;
        string nodeName = name + "Node";

        if(it->second.isArray()) {
            setterName = "(*it)";
            oss << "for(" << it->second.getType() << "::const_iterator it = " << name << ".begin(); it != " << name << ".end(); it++) {" << endl;
        } else if(!it->second.isRequired()) {
            //insert a non-null check
            oss << "if(" << name << ") {" << endl;
        } else {
            //required member - check for its existance
        }

        oss << "DOMElement *" << nodeName << " = node->getOwnerDocument()->createElement(X(\"" << name << "\"));" << endl;
        oss << it->second.cl->generateNodeSetter(setterName, nodeName) << endl;
        oss << "node->appendChild(" << nodeName << ");" << endl;

        if(it->second.isArray() || !it->second.isRequired())
            oss << "}" << endl;

        oss << endl;
    }

    return oss.str();
}
//systemet?
string Class::generateNodeSetter(string memberName, string nodeName) const {
    return memberName + "->appendChildren(" + nodeName + ");";
}

string Class::generateParser() const {
    ostringstream oss;

    oss << "for(DOMNode *child = node->getFirstChild(); child; child = child->getNextSibling()) {" << endl;
    oss << "if(!child->getLocalName()) continue;" << endl;
    oss << "XercesString name(child->getLocalName());" << endl;

    //TODO: replace this with a map<pair<string, DOMNode::ElementType>, void(*)(DOMNode*)> thing?
    //in other words, lookin up parsing function pointers in a map should be faster then all these string comparisons
    for(std::map<std::string, Member>::const_iterator it = members.begin(); it != members.end(); it++) {
        oss << "if(name == \"" << it->first << "\" && child->getNodeType() == DOMNode::" << (it->second.isAttribute ? "ATTRIBUTE_NODE" : "ELEMENT_NODE") << ") {" << endl;

        string memberName = it->first;
        if(it->second.isArray()) {
            oss << it->second.cl->getClassType() << " temp;" << endl;
            memberName = "temp";
        }

        oss << it->second.cl->generateMemberSetter(memberName, "child");

        oss << "}" << endl;
    }

    oss << "}" << endl;

    return oss.str();
}

string Class::generateMemberSetter(string memberName, string nodeName) const {
    ostringstream oss;

    //TODO: add check & allocation for shared_ptr if non-basic

    oss << memberName << "->parseNode(" << nodeName << ");" << endl;

    return oss.str();
}

string Class::getClassname() const {
    return name.second;
}

string Class::getClassType() const {
    if(isBasic)
        return getClassname();
    else
        return "boost::shared_ptr<" + name.second + ">";
}

string Class::getBaseClassname() const {
    return hasBase ? base->getClassname() : "james::XMLObject";
}

string Class::getBaseHeader() const {
    return hasBase ? base->getClassname() + ".h" : "XMLObject.h";
}

void Class::writeImplementation(ostream& os) const {
    //cout << "writeImplementation()" << endl;
    ClassName className = name.second;

    os << "#include <sstream>" << endl;
    os << "#include <xercesc/dom/DOMDocument.hpp>" << endl;
    os << "#include <xercesc/dom/DOMElement.hpp>" << endl;
    os << "#include \"XercesString.h\"" << endl;
    os << "#include \"" << className << ".h\"" << endl;

    //include headers of all non-basic member types that aren't us
    for(map<string, Member>::const_iterator it = members.begin(); it != members.end(); it++)
        if(!it->second.cl->isBasic && it->second.cl != this)
            os << "#include \"" << it->second.cl->name.second << ".h\"" << endl;

    os << "using namespace std;" << endl;
    os << "using namespace xercesc;" << endl;

    //constructor
    os << className << "::" << className << "() : " << getBaseClassname() << "() {";

    //give all basic optional members a default value of zero
    for(map<string, Member>::const_iterator it = members.begin(); it != members.end(); it++)
        if(!it->second.isArray() && !it->second.isRequired() && it->second.cl->isBasic)
            os << it->first << " = 0;" << endl;

    os << "}" << endl << endl;

    //method implementation
    if(isDocument) {
        os << "std::string " << className << "::getName() const {" << endl;
        os << "return \"" << className << "\";" << endl;
        os << "}" << endl;
    } else {
        os << "void " << className << "::appendChildren(xercesc::DOMNode *node) const {" << endl;

        //call base appender
        if(hasBase)
            os << base->name.second << "::appendChildren(node);" << endl;

        os << generateAppender() << endl;
        os << "}" << endl << endl;

        os << "void " << className << "::parseNode(xercesc::DOMNode *node) {" << endl;
        os << generateParser() << endl;
        os << "}" << endl << endl;
    }
}

void Class::writeHeader(ostream& os) const {
    ClassName className = name.second;

    os << "#ifndef _" << className << "_H" << endl;
    os << "#define _" << className << "_H" << endl;

    os << "#include <vector>" << endl;
    os << "#include <boost/shared_ptr.hpp>" << endl;
    os << "#include \"" << getBaseHeader() << "\"" << endl;

    if(isDocument)
        os << "#include \"XMLDocument.h\"" << endl;

    //non-basic member class prototypes
    for(map<string, Member>::const_iterator it = members.begin(); it != members.end(); it++)
        if(!it->second.cl->isBasic)
            os << "class " << it->second.cl->getClassname() << ";" << endl;

    os << "class " << className << " : public " << getBaseClassname();

    if(isDocument)
        os << ", public james::XMLDocument" << endl;

    os << " {" << endl;
    os << "public:" << endl;

    os << className << "();" << endl;

    //prototypes
    if(isDocument)
        os << "std::string getName() const;" << endl;
    else {
        os << "void appendChildren(xercesc::DOMNode *node) const;" << endl;
        os << "void parseNode(xercesc::DOMNode *node);" << endl;
    }

    //members
    for(map<string, Member>::const_iterator it = members.begin(); it != members.end(); it++) {
        os << it->second.getType() << " " << it->first << ";" << endl;
    }

    os << "};" << endl;

    os << "#endif //_" << className << "_H" << endl;
}

bool Class::Member::isArray() const {
    return maxOccurs > 1 || maxOccurs == UNBOUNDED;
}

bool Class::Member::isRequired() const {
    return minOccurs >= 1;
}

string Class::Member::getType() const {
    //vector if array, regular member otherwise
    if(isArray()) {
        return "std::vector<" + cl->getClassType() + " >";
    } else
        return cl->getClassType();
}
<|endoftext|>


<commit_before>#include <cmath>
#include "Math/SVector.h"
#include "Math/SMatrix.h"

#include <iostream>
#include <vector>

using namespace ROOT::Math;

using std::cout;
using std::endl;

//#define TEST_STATIC_CHECK  // for testing compiler failures (static check)

#define XXX

int test1() {

  SVector<float,3> x(4,5,6);
  SVector<float,2> y(2.0,3.0);
  cout << "x: " << x << endl;
  cout << "y: " << y << endl;

  float yy1=2.; float yy2 = 3;
  SVector<float,2> y2(yy1,yy2);

  SMatrix<float,4,3> A;
  SMatrix<float,2,2> B;

  A.Place_in_row(y, 1, 1);
  A.Place_in_col(x + 2, 1, 0);
  A.Place_at(B , 2, 1);
  cout << "A: " << endl << A << endl;

#ifdef TEST_STATIC_CHECK
  // create a vector of size 2 from 3 arguments
  SVector<float, 2> v(1,2,3);
#endif

  // test STL interface

  //double p[2] = {1,2};
  double m[4] = {1,2,3,4};

  //SVector<float, 2> sp(p,2);
  SMatrix<float, 2,2> sm(m,4);

  //cout << "sp: " << endl << sp << endl;
  cout << "sm: " << endl << sm << endl;

  //std::vector<float> vp(sp.begin(), sp.end() );
  std::vector<float> vm(sm.begin(), sm.end() );

  //SVector<float, 2> sp2(vp.begin(),vp.end());
  //SVector<float, 2> sp2(vp.begin(),vp.size());
  SMatrix<float, 2,2> sm2(vm.begin(),vm.end());

  //if ( sp2 != sp) { cout << "Test STL interface for SVector failed" << endl; return -1; }
  if ( sm2 != sm) { cout << "Test STL interface for SMatrix failed" << endl; return -1; }

  return 0;

}

int test2() {
#ifdef XXX
  SMatrix<double,3> A;
  A(0,0) = A(1,0) = 1;
  A(0,1) = 3;
  A(1,1) = A(2,2) = 2;
  cout << "A: " << endl << A << endl;

  SVector<double,3> x = A.Row(0);
  cout << "x: " << x << endl;

  SVector<double,3> y = A.Col(1);
  cout << "y: " << y << endl;

  return 0;
#endif
}

int test3() {
#ifdef XXX
  SMatrix<double,3> A;
  A(0,0) = A(0,1) = A(1,0) = 1;
  A(1,1) = A(2,2) = 2;

  SMatrix<double,3> B = A; // save A in B
  cout << "A: " << endl << A << endl;

  double det = 0.;
  A.Sdet(det);
  cout << "Determinant: " << det << endl;
  // WARNING: A has changed!!
  cout << "A again: " << endl << A << endl;

  A.Sinvert();
  cout << "A^-1: " << endl << A << endl;

  // check if this is really the inverse:
  cout << "A^-1 * B: " << endl << A * B << endl;

  return 0;
#endif
}

int test4() {
#ifdef XXX
  SMatrix<double,3> A;
  A(0,0) = A(0,1) = A(1,0) = 1;
  A(1,1) = A(2,2) = 2;
  cout << " A: " << endl << A << endl;

  SVector<double,3> x(1,2,3);
  cout << "x: " << x << endl;

  // we add 1 to each component of x and A
  cout << " (x+1)^T * (A+1) * (x+1): " << Product(x+1,A+1) << endl;

  return 0;
#endif
}

int test5() {
#ifdef XXX
  SMatrix<float,4,3> A;
  A(0,0) = A(0,1) = A(1,1) = A(2,2) = 4.;
  A(2,3) = 1.;
  cout << "A: " << endl << A << endl;
  SVector<float,4> x(1,2,3,4);
  cout << " x: " << x << endl;
  SVector<float,3> a(1,2,3);
  cout << " a: " << a << endl;
  SVector<float,4> y = x + A * a;
  //    SVector<float,4> y = A * a;
  cout << " y: " << y << endl;

  SVector<float,3> b = (x+1) * (A+1);
  cout << " b: " << b << endl;

  return 0;
#endif
}

int test6() {
#ifdef XXX
  SMatrix<float,4,2> A;
  A(0,0) = A(0,1) = A(1,1) = A(2,0) = A(3,1) = 4.;
  cout << "A: " << endl << A << endl;

  SMatrix<float,2,3> S;
  S(0,0) = S(0,1) = S(1,1) = S(0,2) = 1.;
  cout << " S: " << endl << S << endl;

  SMatrix<float,4,3> C = A * S;
  cout << " C: " << endl << C << endl;

  return 0;
#endif
}

int test7() {
#ifdef XXX
  SVector<float,3>    xv(4,4,4);
  SVector<float,3>    yv(5,5,5);
  SVector<float,2>    zv(64,64);
  SMatrix<float,2,3>  x;
  x.Place_in_row(xv,0,0);
  x.Place_in_row(xv,1,0);
  SMatrix<float,2,3>  y;
  y.Place_in_row(yv,0,0);
  y.Place_in_row(yv,1,0);
  SMatrix<float,2,3>  z;
  z.Place_in_col(zv,0,0);
  z.Place_in_col(zv,0,1);
  z.Place_in_col(zv,0,2);

  // element wise multiplication
  cout << "x * y: " << endl << times(x, -y) << endl;

  x += z - y;
  cout << "x += z - y: " << endl << x << endl;

  // element wise square root
  cout << "sqrt(z): " << endl << sqrt(z) << endl;

  // element wise multiplication with constant
  cout << "2 * y: " << endl << 2 * y << endl;

  // a more complex expression
  cout << "fabs(-z + 3*x): " << endl << fabs(-z + 3*x) << endl;

  return 0;
#endif
}

int test8() {
#ifdef XXX
  SMatrix<float,2,3> A;
  SVector<float,3>    av1(5.,15.,5.);
  SVector<float,3>    av2(15.,5.,15.);
  A.Place_in_row(av1,0,0);
  A.Place_in_row(av2,1,0);

  cout << "A: " << endl << A << endl;

  SVector<float,3>    x(1,2,3);
  SVector<float,3>    y(4,5,6);

  cout << "dot(x,y): " << Dot(x,y) << endl;

  cout << "mag(x): " << Mag(x) << endl;

  cout << "cross(x,y): " << Cross(x,y) << endl;

  cout << "unit(x): " << Unit(x) << endl;

  SVector<float,3>    z(4,16,64);
  cout << "x + y: " << x+y << endl;

  cout << "x * y: " << x * -y << endl;
  x += z - y;
  cout << "x += z - y: " << x << endl;

  // element wise square root
  cout << "sqrt(z): " << sqrt(z) << endl;

  // element wise multiplication with constant
  cout << "2 * y: " << 2 * y << endl;

  // a more complex expression
  cout << "fabs(-z + 3*x): " << fabs(-z + 3*x) << endl;

  SVector<float,4> a;
  SVector<float,2> b(1,2);
  a.Place_at(b,2);
  cout << "a: " << a << endl;
#endif

  return 0;
}

#define TEST(N)                                                                 \
  itest = N;                                                                    \
  if (test##N() == 0) std::cout << " Test " << itest << "  OK " << std::endl;   \
  else  {std::cout << " Test " << itest << "  Failed " << std::endl;             \
  return -1;}

int main(void) {

  int itest;
  TEST(1);
  TEST(2);
  TEST(3);
  TEST(4);
  TEST(5);
  TEST(6);
  TEST(7);
  TEST(8);

  return 0;
}
<commit_msg>remove a warning in the test<commit_after>#include <cmath>
#include "Math/SVector.h"
#include "Math/SMatrix.h"

#include <iostream>
#include <vector>

using namespace ROOT::Math;

using std::cout;
using std::endl;

//#define TEST_STATIC_CHECK  // for testing compiler failures (static check)

#define XXX

int test1() {

  SVector<float,3> x(4,5,6);
  SVector<float,2> y(2.0,3.0);
  cout << "x: " << x << endl;
  cout << "y: " << y << endl;

//   float yy1=2.; float yy2 = 3;
//   SVector<float,2> y2(yy1,yy2);

  SMatrix<float,4,3> A;
  SMatrix<float,2,2> B;

  A.Place_in_row(y, 1, 1);
  A.Place_in_col(x + 2, 1, 0);
  A.Place_at(B , 2, 1);
  cout << "A: " << endl << A << endl;

#ifdef TEST_STATIC_CHECK
  // create a vector of size 2 from 3 arguments
  SVector<float, 2> v(1,2,3);
#endif

  // test STL interface

  //double p[2] = {1,2};
  double m[4] = {1,2,3,4};

  //SVector<float, 2> sp(p,2);
  SMatrix<float, 2,2> sm(m,4);

  //cout << "sp: " << endl << sp << endl;
  cout << "sm: " << endl << sm << endl;

  //std::vector<float> vp(sp.begin(), sp.end() );
  std::vector<float> vm(sm.begin(), sm.end() );

  //SVector<float, 2> sp2(vp.begin(),vp.end());
  //SVector<float, 2> sp2(vp.begin(),vp.size());
  SMatrix<float, 2,2> sm2(vm.begin(),vm.end());

  //if ( sp2 != sp) { cout << "Test STL interface for SVector failed" << endl; return -1; }
  if ( sm2 != sm) { cout << "Test STL interface for SMatrix failed" << endl; return -1; }

  return 0;

}

int test2() {
#ifdef XXX
  SMatrix<double,3> A;
  A(0,0) = A(1,0) = 1;
  A(0,1) = 3;
  A(1,1) = A(2,2) = 2;
  cout << "A: " << endl << A << endl;

  SVector<double,3> x = A.Row(0);
  cout << "x: " << x << endl;

  SVector<double,3> y = A.Col(1);
  cout << "y: " << y << endl;

  return 0;
#endif
}

int test3() {
#ifdef XXX
  SMatrix<double,3> A;
  A(0,0) = A(0,1) = A(1,0) = 1;
  A(1,1) = A(2,2) = 2;

  SMatrix<double,3> B = A; // save A in B
  cout << "A: " << endl << A << endl;

  double det = 0.;
  A.Sdet(det);
  cout << "Determinant: " << det << endl;
  // WARNING: A has changed!!
  cout << "A again: " << endl << A << endl;

  A.Sinvert();
  cout << "A^-1: " << endl << A << endl;

  // check if this is really the inverse:
  cout << "A^-1 * B: " << endl << A * B << endl;

  return 0;
#endif
}

int test4() {
#ifdef XXX
  SMatrix<double,3> A;
  A(0,0) = A(0,1) = A(1,0) = 1;
  A(1,1) = A(2,2) = 2;
  cout << " A: " << endl << A << endl;

  SVector<double,3> x(1,2,3);
  cout << "x: " << x << endl;

  // we add 1 to each component of x and A
  cout << " (x+1)^T * (A+1) * (x+1): " << Product(x+1,A+1) << endl;

  return 0;
#endif
}

int test5() {
#ifdef XXX
  SMatrix<float,4,3> A;
  A(0,0) = A(0,1) = A(1,1) = A(2,2) = 4.;
  A(2,3) = 1.;
  cout << "A: " << endl << A << endl;
  SVector<float,4> x(1,2,3,4);
  cout << " x: " << x << endl;
  SVector<float,3> a(1,2,3);
  cout << " a: " << a << endl;
  SVector<float,4> y = x + A * a;
  //    SVector<float,4> y = A * a;
  cout << " y: " << y << endl;

  SVector<float,3> b = (x+1) * (A+1);
  cout << " b: " << b << endl;

  return 0;
#endif
}

int test6() {
#ifdef XXX
  SMatrix<float,4,2> A;
  A(0,0) = A(0,1) = A(1,1) = A(2,0) = A(3,1) = 4.;
  cout << "A: " << endl << A << endl;

  SMatrix<float,2,3> S;
  S(0,0) = S(0,1) = S(1,1) = S(0,2) = 1.;
  cout << " S: " << endl << S << endl;

  SMatrix<float,4,3> C = A * S;
  cout << " C: " << endl << C << endl;

  return 0;
#endif
}

int test7() {
#ifdef XXX
  SVector<float,3>    xv(4,4,4);
  SVector<float,3>    yv(5,5,5);
  SVector<float,2>    zv(64,64);
  SMatrix<float,2,3>  x;
  x.Place_in_row(xv,0,0);
  x.Place_in_row(xv,1,0);
  SMatrix<float,2,3>  y;
  y.Place_in_row(yv,0,0);
  y.Place_in_row(yv,1,0);
  SMatrix<float,2,3>  z;
  z.Place_in_col(zv,0,0);
  z.Place_in_col(zv,0,1);
  z.Place_in_col(zv,0,2);

  // element wise multiplication
  cout << "x * y: " << endl << times(x, -y) << endl;

  x += z - y;
  cout << "x += z - y: " << endl << x << endl;

  // element wise square root
  cout << "sqrt(z): " << endl << sqrt(z) << endl;

  // element wise multiplication with constant
  cout << "2 * y: " << endl << 2 * y << endl;

  // a more complex expression
  cout << "fabs(-z + 3*x): " << endl << fabs(-z + 3*x) << endl;

  return 0;
#endif
}

int test8() {
#ifdef XXX
  SMatrix<float,2,3> A;
  SVector<float,3>    av1(5.,15.,5.);
  SVector<float,3>    av2(15.,5.,15.);
  A.Place_in_row(av1,0,0);
  A.Place_in_row(av2,1,0);

  cout << "A: " << endl << A << endl;

  SVector<float,3>    x(1,2,3);
  SVector<float,3>    y(4,5,6);

  cout << "dot(x,y): " << Dot(x,y) << endl;

  cout << "mag(x): " << Mag(x) << endl;

  cout << "cross(x,y): " << Cross(x,y) << endl;

  cout << "unit(x): " << Unit(x) << endl;

  SVector<float,3>    z(4,16,64);
  cout << "x + y: " << x+y << endl;

  cout << "x * y: " << x * -y << endl;
  x += z - y;
  cout << "x += z - y: " << x << endl;

  // element wise square root
  cout << "sqrt(z): " << sqrt(z) << endl;

  // element wise multiplication with constant
  cout << "2 * y: " << 2 * y << endl;

  // a more complex expression
  cout << "fabs(-z + 3*x): " << fabs(-z + 3*x) << endl;

  SVector<float,4> a;
  SVector<float,2> b(1,2);
  a.Place_at(b,2);
  cout << "a: " << a << endl;
#endif

  return 0;
}

#define TEST(N)                                                                 \
  itest = N;                                                                    \
  if (test##N() == 0) std::cout << " Test " << itest << "  OK " << std::endl;   \
  else  {std::cout << " Test " << itest << "  Failed " << std::endl;             \
  return -1;}

int main(void) {

  int itest;
  TEST(1);
  TEST(2);
  TEST(3);
  TEST(4);
  TEST(5);
  TEST(6);
  TEST(7);
  TEST(8);

  return 0;
}
<|endoftext|>


<commit_before>/**
 * @file DescriptorMatcher_.cpp
 * @brief mex interface for DescriptorMatcher
 * @author Kota Yamaguchi
 * @date 2012
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

#if CV_MINOR_VERSION >= 2
// Persistent objects

/// Last object id to allocate
int last_id = 0;
/// Object container
map<int,Ptr<DescriptorMatcher> > obj_;
#endif

/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
#if CV_MINOR_VERSION >= 2
	if (nrhs<1 || nlhs>1)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");

	// Determine argument format between constructor or (id,method,...)
	vector<MxArray> rhs(prhs,prhs+nrhs);
	int id = 0;
	string method;
	if (rhs[0].isChar() && nrhs==1) {
		// Constructor is called. Create a new object from argument
		string descriptorMatcherType(rhs[0].toString());
		obj_[++last_id] = DescriptorMatcher::create(descriptorMatcherType);
		plhs[0] = MxArray(last_id);
		return;
	}
	else if (rhs[0].isNumeric() && rhs[0].numel()==1 && nrhs>1) {
		id = rhs[0].toInt();
		method = rhs[1].toString();
	}
	else
        mexErrMsgIdAndTxt("mexopencv:error","Invalid arguments");

	// Big operation switch
	Ptr<DescriptorMatcher> obj = obj_[id];
    if (method == "delete") {
    	if (nrhs!=2 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	obj_.erase(id);
    }
    else if (method == "type") {
    	if (nrhs!=2)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	plhs[0] = MxArray(string(typeid(*obj).name()));
    }
    else if (method == "add") {
    	if (nrhs!=3 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	vector<Mat> descriptors(rhs[2].toVector<Mat>());
    	obj->add(descriptors);
    }
    else if (method == "getTrainDescriptors") {
    	if (nrhs!=2)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	plhs[0] = MxArray(obj->getTrainDescriptors());
    }
    else if (method == "clear") {
    	if (nrhs!=2 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	obj->clear();
    }
    else if (method == "empty") {
    	if (nrhs!=2 || nlhs!=1)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	plhs[0] = MxArray(obj->empty());
    }
    else if (method == "isMaskSupported") {
    	if (nrhs!=2)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	plhs[0] = MxArray(obj->isMaskSupported());
    }
    else if (method == "train") {
    	if (nrhs!=2 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	obj->train();
    }
    else if (method == "match") {
    	if (nrhs<3)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	Mat queryDescriptors(rhs[2].toMat());
        vector<DMatch> matches;
    	if (rhs[3].isNumeric()) { // First format
			Mat trainDescriptors(rhs[3].toMat());
			Mat mask;
			for (int i=4; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					mask = rhs[i+1].toMat(CV_8U);
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->match(queryDescriptors, trainDescriptors, matches, mask);
		}
		else { // Second format
			vector<Mat> masks;
			for (int i=3; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					masks = rhs[i+1].toVector<Mat>();
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->match(queryDescriptors, matches, masks);
    	}
    	plhs[0] = MxArray(matches);
    }
    else if (method == "knnMatch") {
    	if (nrhs<4)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	Mat queryDescriptors(rhs[2].toMat());
        vector<vector<DMatch> > matches;
        if (rhs[3].isNumeric()) { // First format
        	Mat trainDescriptors(rhs[3].toMat());
			int k = rhs[4].toInt();
			Mat mask;
			bool compactResult=false;
			for (int i=5; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					mask = rhs[i+1].toMat(CV_8U);
				else if (key=="CompactResult")
					compactResult = rhs[i+1].toBool();
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->knnMatch(queryDescriptors, trainDescriptors, matches, k, mask,
				compactResult);
		}
		else { // Second format
			int k = rhs[3].toInt();
			vector<Mat> masks;
			bool compactResult=false;
			for (int i=4; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					masks = rhs[i+1].toVector<Mat>();
				else if (key=="CompactResult")
					compactResult = rhs[i+1].toBool();
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->knnMatch(queryDescriptors, matches, k, masks, compactResult);
		}
    	plhs[0] = MxArray(matches);
    }
    else if (method == "radiusMatch") {
    	if (nrhs<4)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	Mat queryDescriptors(rhs[2].toMat());
        vector<vector<DMatch> > matches;
        if (rhs[3].isNumeric()) { // First format
        	Mat trainDescriptors(rhs[3].toMat());
			float maxDistance = rhs[4].toDouble();
			Mat mask;
			bool compactResult=false;
			for (int i=5; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					mask = rhs[i+1].toMat(CV_8U);
				else if (key=="CompactResult")
					compactResult = rhs[i+1].toBool();
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->radiusMatch(queryDescriptors, trainDescriptors, matches,
				maxDistance, mask, compactResult);
		}
		else { // Second format
			float maxDistance = rhs[3].toDouble();
			vector<Mat> masks;
			bool compactResult=false;
			for (int i=4; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					masks = rhs[i+1].toVector<Mat>();
				else if (key=="CompactResult")
					compactResult = rhs[i+1].toBool();
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->radiusMatch(queryDescriptors, matches, maxDistance, masks, compactResult);
		}
    	plhs[0] = MxArray(matches);
    }
    else if (method == "read") {
    	if (nrhs!=3 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	FileStorage fs(rhs[2].toString(),FileStorage::READ);
    	obj->read(fs.root());
    }
    else if (method == "write") {
    	if (nrhs!=3 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	FileStorage fs(rhs[2].toString(),FileStorage::WRITE);
    	obj->write(fs);
    }
    else
		mexErrMsgIdAndTxt("mexopencv:error","Unrecognized operation");
#else
	mexErrMsgIdAndTxt("mexopencv:error","DescriptorExtractor not supported in this version");
#endif
}
<commit_msg>Fixed a bug in DescriptorMatcher<commit_after>/**
 * @file DescriptorMatcher_.cpp
 * @brief mex interface for DescriptorMatcher
 * @author Kota Yamaguchi
 * @date 2012
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

#if CV_MINOR_VERSION >= 2
// Persistent objects

/// Last object id to allocate
int last_id = 0;
/// Object container
map<int,Ptr<DescriptorMatcher> > obj_;
#endif

/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
#if CV_MINOR_VERSION >= 2
	if (nrhs<1 || nlhs>1)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");

	// Determine argument format between constructor or (id,method,...)
	vector<MxArray> rhs(prhs,prhs+nrhs);
	int id = 0;
	string method;
	if (rhs[0].isChar() && nrhs==1) {
		// Constructor is called. Create a new object from argument
		string descriptorMatcherType(rhs[0].toString());
		obj_[++last_id] = DescriptorMatcher::create(descriptorMatcherType);
		plhs[0] = MxArray(last_id);
		return;
	}
	else if (rhs[0].isNumeric() && rhs[0].numel()==1 && nrhs>1) {
		id = rhs[0].toInt();
		method = rhs[1].toString();
	}
	else
        mexErrMsgIdAndTxt("mexopencv:error","Invalid arguments");

	// Big operation switch
	Ptr<DescriptorMatcher> obj = obj_[id];
    if (method == "delete") {
    	if (nrhs!=2 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	obj_.erase(id);
    }
    else if (method == "type") {
    	if (nrhs!=2)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	plhs[0] = MxArray(string(typeid(*obj).name()));
    }
    else if (method == "add") {
    	if (nrhs!=3 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	vector<Mat> descriptors(rhs[2].toVector<Mat>());
    	obj->add(descriptors);
    }
    else if (method == "getTrainDescriptors") {
    	if (nrhs!=2)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	plhs[0] = MxArray(obj->getTrainDescriptors());
    }
    else if (method == "clear") {
    	if (nrhs!=2 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	obj->clear();
    }
    else if (method == "empty") {
    	if (nrhs!=2 || nlhs!=1)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	plhs[0] = MxArray(obj->empty());
    }
    else if (method == "isMaskSupported") {
    	if (nrhs!=2)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	plhs[0] = MxArray(obj->isMaskSupported());
    }
    else if (method == "train") {
    	if (nrhs!=2 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	obj->train();
    }
    else if (method == "match") {
    	if (nrhs<3)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	Mat queryDescriptors(rhs[2].toMat(CV_32F));
        vector<DMatch> matches;
    	if (rhs[3].isNumeric()) { // First format
			Mat trainDescriptors(rhs[3].toMat(CV_32F));
			Mat mask;
			for (int i=4; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					mask = rhs[i+1].toMat(CV_8U);
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->match(queryDescriptors, trainDescriptors, matches, mask);
		}
		else { // Second format
			vector<Mat> masks;
			for (int i=3; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					masks = rhs[i+1].toVector<Mat>();
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->match(queryDescriptors, matches, masks);
    	}
    	plhs[0] = MxArray(matches);
    }
    else if (method == "knnMatch") {
    	if (nrhs<4)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	Mat queryDescriptors(rhs[2].toMat(CV_32F));
        vector<vector<DMatch> > matches;
        if (rhs[3].isNumeric()) { // First format
        	Mat trainDescriptors(rhs[3].toMat(CV_32F));
			int k = rhs[4].toInt();
			Mat mask;
			bool compactResult=false;
			for (int i=5; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					mask = rhs[i+1].toMat(CV_8U);
				else if (key=="CompactResult")
					compactResult = rhs[i+1].toBool();
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->knnMatch(queryDescriptors, trainDescriptors, matches, k, mask,
				compactResult);
		}
		else { // Second format
			int k = rhs[3].toInt();
			vector<Mat> masks;
			bool compactResult=false;
			for (int i=4; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					masks = rhs[i+1].toVector<Mat>();
				else if (key=="CompactResult")
					compactResult = rhs[i+1].toBool();
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->knnMatch(queryDescriptors, matches, k, masks, compactResult);
		}
    	plhs[0] = MxArray(matches);
    }
    else if (method == "radiusMatch") {
    	if (nrhs<4)
    		mexErrMsgIdAndTxt("mexopencv:error","Output not assigned");
    	Mat queryDescriptors(rhs[2].toMat(CV_32F));
        vector<vector<DMatch> > matches;
        if (rhs[3].isNumeric()) { // First format
        	Mat trainDescriptors(rhs[3].toMat(CV_32F));
			float maxDistance = rhs[4].toDouble();
			Mat mask;
			bool compactResult=false;
			for (int i=5; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					mask = rhs[i+1].toMat(CV_8U);
				else if (key=="CompactResult")
					compactResult = rhs[i+1].toBool();
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->radiusMatch(queryDescriptors, trainDescriptors, matches,
				maxDistance, mask, compactResult);
		}
		else { // Second format
			float maxDistance = rhs[3].toDouble();
			vector<Mat> masks;
			bool compactResult=false;
			for (int i=4; i<nrhs; i+=2) {
				string key(rhs[i].toString());
				if (key=="Mask")
					masks = rhs[i+1].toVector<Mat>();
				else if (key=="CompactResult")
					compactResult = rhs[i+1].toBool();
				else
					mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
			}
			obj->radiusMatch(queryDescriptors, matches, maxDistance, masks, compactResult);
		}
    	plhs[0] = MxArray(matches);
    }
    else if (method == "read") {
    	if (nrhs!=3 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	FileStorage fs(rhs[2].toString(),FileStorage::READ);
    	obj->read(fs.root());
    }
    else if (method == "write") {
    	if (nrhs!=3 || nlhs!=0)
    		mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
    	FileStorage fs(rhs[2].toString(),FileStorage::WRITE);
    	obj->write(fs);
    }
    else
		mexErrMsgIdAndTxt("mexopencv:error","Unrecognized operation");
#else
	mexErrMsgIdAndTxt("mexopencv:error","DescriptorExtractor not supported in this version");
#endif
}
<|endoftext|>


<commit_before>#include <tests/Base.hh>

#include <fstream>
#include <iostream>
#include <set>
#include <sstream>
#include <string>
#include <vector>

#include <cmath>

#include <aleph/geometry/CoverTree.hh>

using namespace aleph::geometry;

template <class T> struct SimpleMetric
{
  T operator()( T a, T b )
  {
    return std::abs( a - b );
  }
};

template <class T> void testSimple()
{
  ALEPH_TEST_BEGIN( "Simple" );

  CoverTree<T,
            SimpleMetric<T> > ct;

  ct.insert( 7 );
  ct.insert( 13 );
  ct.insert( 10 );
  ct.insert( 8 );
  ct.insert( 9 );
  ct.insert( 11 );
  ct.insert( 12 );

  ct.print( std::cerr );

  ALEPH_ASSERT_THROW( ct.checkLevelInvariant() );
  ALEPH_ASSERT_THROW( ct.checkCoveringInvariant() );
  ALEPH_ASSERT_THROW( ct.checkSeparatingInvariant() );

  ALEPH_TEST_END();
}

template <class T> void testSimplePermutations()
{
  ALEPH_TEST_BEGIN( "Simple (using permutations)" );

  std::vector<T> data = {7,8,9,10,11,12,13};

  do
  {
    CoverTree<T,
              SimpleMetric<T> > ct;

    // Debug output ----------------------------------------------------

    std::cerr << "Permutation: ";

    for( auto&& x : data )
      std::cerr << x << " ";

    std::cerr << "\n";

    // Check validity of tree ------------------------------------------

    for( auto&& x : data )
      ct.insert( x );

    ALEPH_ASSERT_THROW( ct.checkLevelInvariant() );
    ALEPH_ASSERT_THROW( ct.checkCoveringInvariant() );
    ALEPH_ASSERT_THROW( ct.checkSeparatingInvariant() );
  }
  while( std::next_permutation( data.begin(), data.end() ) );

  ALEPH_TEST_END();
}

template <class T> struct Point
{
  T x;
  T y;

  bool operator<( const Point& other ) const noexcept
  {
    if( x == other.x )
      return y < other.y;
    else
      return x < other.x;
  }
};

template <class T> std::ostream& operator<<( std::ostream& o, const Point<T>& p )
{
  o << p.x << " " << p.y;
  return o;
}

template <class T> struct EuclideanMetric
{
  T operator()( Point<T> a, Point<T> b )
  {
    return std::sqrt( std::pow( a.x - b.x, T(2) ) + std::pow( a.y - b.y, T(2) ) );
  }
};

template <class T> bool contains( const Point<T>& centre, const Point<T>& p, T r )
{
  EuclideanMetric<T> metric;
  return metric( centre, p ) <= r;
}

template <class T> T distance( const Point<T>& centre, const Point<T>& p )
{
  EuclideanMetric<T> metric;
  return metric( centre, p );
}

template <class T> void test2D()
{
  ALEPH_TEST_BEGIN( "2D" );

  using Point     = Point<T>;
  using Metric    = EuclideanMetric<T>;
  using CoverTree = CoverTree<Point, Metric>;

  CoverTree ct;

  std::ifstream in( CMAKE_SOURCE_DIR + std::string( "/tests/input/Cover_tree_simple.txt" ) );
  ALEPH_ASSERT_THROW( in );

  std::vector<Point> points;

  std::string line;
  while( std::getline( in, line ) )
  {
    std::stringstream converter( line );

    T x = T();
    T y = T();

    converter >> x
              >> y;

    ALEPH_ASSERT_THROW( not converter.fail() );

    points.push_back( {x,y} );
  }

  ALEPH_ASSERT_EQUAL( points.size(), 15 );

  for( auto&& p : points )
    ct.insert( p );

  ALEPH_ASSERT_THROW( ct.isValid() );

  auto&& nodesByLevel = ct.getNodesByLevel();

  // Determine radii, i.e. *level* of the original data set. Afterwards,
  // using the corresponding point as the centre, we can check how often
  // certain points are being covered.

  std::map<Point, unsigned > covered;
  std::multimap<Point, long> levels;
  std::multimap<Point, T   > distances;

  for( auto&& pair : nodesByLevel )
  {
    auto&& level  = pair.first;
    auto&& centre = pair.second;

    for( auto&& p : points )
    {
      // TODO: fix radius/level calculation; is this an implementation
      // detail of the tree?
      if( contains( centre, p, T( std::pow( T(2), level ) ) ) )
      {
        covered[p] += 1;
        levels.insert( std::make_pair( p, level ) );
        distances.insert( std::make_pair( p, distance( centre, p ) ) );
      }
    }
  }

  std::cerr << "# Cover counter\n";

  for( auto&& pair : covered )
    std::cerr << pair.first << ": " << pair.second << "\n";

  std::cerr << "# Levels counter\n";

  for( auto&& p : points )
  {
    std::cerr << p << ": ";

    auto range = levels.equal_range( p );
    for( auto it = range.first; it != range.second; ++it )
     std::cerr << it->second << " ";

    std::cerr << "\n";
  }

  std::cerr << "# Distances counter\n";

  for( auto&& p : points )
  {
    std::cerr << p << ": ";

    auto range = distances.equal_range( p );
    for( auto it = range.first; it != range.second; ++it )
     std::cerr << it->second << " ";

    std::cerr << "\n";
  }

  std::cerr << "# Basic cover distance density\n";

  for( auto&& p : points )
  {
    std::cerr << p << ": ";

    auto range      = distances.equal_range( p );
    double distance = 0.0;

    for( auto it = range.first; it != range.second; ++it )
      distance += it->second;

    distance /= static_cast<T>( std::distance( range.first, range.second ) );

    std::cerr << distance << "\n";
  }

  // DEBUG: output of cover radii --------------------------------------

  {
    std::ofstream out( "/tmp/C.txt" );

    for( auto&& pair : nodesByLevel )
    {
      auto&& level  = pair.first;
      auto&& centre = pair.second;
      auto r        = std::pow( T(2), level );

      out << centre << " " << r << "\n";
    }
  }

  // DEBUG: output of edges --------------------------------------------

  {
    std::set< std::pair<Point, Point> > edges;

    for( auto&& pair : nodesByLevel )
    {
      auto&& level  = pair.first;
      auto&& centre = pair.second;

      for( auto&& p : points )
      {
        // TODO: fix radius/level calculation; is this an implementation
        // detail of the tree?
        if( contains( centre, p, T( std::pow( T(2), level ) ) ) )
        {
          // Induce basic ordering of edges in order to make it easier
          // to print them later on.
          if( centre < p )
            edges.insert( std::make_pair( centre, p ) );
          else
            edges.insert( std::make_pair( p, centre ) );
        }
      }
    }

    std::ofstream out( "/tmp/E.txt" );

    for( auto&& edge : edges )
    {
      out << edge.first  << "\n"
          << edge.second << "\n\n";
    }
  }

  ALEPH_ASSERT_EQUAL( nodesByLevel.size(), points.size() );
  ALEPH_TEST_END();
}

int main( int, char** )
{
  testSimple<double>();
  testSimple<float> ();

  testSimplePermutations<double>();
  testSimplePermutations<float> ();

  test2D<double>();
  test2D<float> ();
}
<commit_msg>Added simple edge filtering criterion<commit_after>#include <tests/Base.hh>

#include <fstream>
#include <iostream>
#include <set>
#include <sstream>
#include <string>
#include <vector>

#include <cmath>

#include <aleph/geometry/CoverTree.hh>

using namespace aleph::geometry;

template <class T> struct SimpleMetric
{
  T operator()( T a, T b )
  {
    return std::abs( a - b );
  }
};

template <class T> void testSimple()
{
  ALEPH_TEST_BEGIN( "Simple" );

  CoverTree<T,
            SimpleMetric<T> > ct;

  ct.insert( 7 );
  ct.insert( 13 );
  ct.insert( 10 );
  ct.insert( 8 );
  ct.insert( 9 );
  ct.insert( 11 );
  ct.insert( 12 );

  ct.print( std::cerr );

  ALEPH_ASSERT_THROW( ct.checkLevelInvariant() );
  ALEPH_ASSERT_THROW( ct.checkCoveringInvariant() );
  ALEPH_ASSERT_THROW( ct.checkSeparatingInvariant() );

  ALEPH_TEST_END();
}

template <class T> void testSimplePermutations()
{
  ALEPH_TEST_BEGIN( "Simple (using permutations)" );

  std::vector<T> data = {7,8,9,10,11,12,13};

  do
  {
    CoverTree<T,
              SimpleMetric<T> > ct;

    // Debug output ----------------------------------------------------

    std::cerr << "Permutation: ";

    for( auto&& x : data )
      std::cerr << x << " ";

    std::cerr << "\n";

    // Check validity of tree ------------------------------------------

    for( auto&& x : data )
      ct.insert( x );

    ALEPH_ASSERT_THROW( ct.checkLevelInvariant() );
    ALEPH_ASSERT_THROW( ct.checkCoveringInvariant() );
    ALEPH_ASSERT_THROW( ct.checkSeparatingInvariant() );
  }
  while( std::next_permutation( data.begin(), data.end() ) );

  ALEPH_TEST_END();
}

template <class T> struct Point
{
  T x;
  T y;

  bool operator<( const Point& other ) const noexcept
  {
    if( x == other.x )
      return y < other.y;
    else
      return x < other.x;
  }
};

template <class T> std::ostream& operator<<( std::ostream& o, const Point<T>& p )
{
  o << p.x << " " << p.y;
  return o;
}

template <class T> struct EuclideanMetric
{
  T operator()( Point<T> a, Point<T> b )
  {
    return std::sqrt( std::pow( a.x - b.x, T(2) ) + std::pow( a.y - b.y, T(2) ) );
  }
};

template <class T> bool contains( const Point<T>& centre, const Point<T>& p, T r )
{
  EuclideanMetric<T> metric;
  return metric( centre, p ) <= r;
}

template <class T> T distance( const Point<T>& centre, const Point<T>& p )
{
  EuclideanMetric<T> metric;
  return metric( centre, p );
}

template <class T> void test2D()
{
  ALEPH_TEST_BEGIN( "2D" );

  using Point     = Point<T>;
  using Metric    = EuclideanMetric<T>;
  using CoverTree = CoverTree<Point, Metric>;

  CoverTree ct;

  std::ifstream in( CMAKE_SOURCE_DIR + std::string( "/tests/input/Cover_tree_simple.txt" ) );
  ALEPH_ASSERT_THROW( in );

  std::vector<Point> points;

  std::string line;
  while( std::getline( in, line ) )
  {
    std::stringstream converter( line );

    T x = T();
    T y = T();

    converter >> x
              >> y;

    ALEPH_ASSERT_THROW( not converter.fail() );

    points.push_back( {x,y} );
  }

  ALEPH_ASSERT_EQUAL( points.size(), 15 );

  for( auto&& p : points )
    ct.insert( p );

  ALEPH_ASSERT_THROW( ct.isValid() );

  auto&& nodesByLevel = ct.getNodesByLevel();

  // Determine radii, i.e. *level* of the original data set. Afterwards,
  // using the corresponding point as the centre, we can check how often
  // certain points are being covered.

  std::map<Point, unsigned > covered;
  std::multimap<Point, long> levels;
  std::multimap<Point, T   > distances;

  for( auto&& pair : nodesByLevel )
  {
    auto&& level  = pair.first;
    auto&& centre = pair.second;

    for( auto&& p : points )
    {
      // TODO: fix radius/level calculation; is this an implementation
      // detail of the tree?
      if( contains( centre, p, T( std::pow( T(2), level ) ) ) )
      {
        covered[p] += 1;
        levels.insert( std::make_pair( p, level ) );
        distances.insert( std::make_pair( p, distance( centre, p ) ) );
      }
    }
  }

  std::cerr << "# Cover counter\n";

  for( auto&& pair : covered )
    std::cerr << pair.first << ": " << pair.second << "\n";

  std::cerr << "# Levels counter\n";

  for( auto&& p : points )
  {
    std::cerr << p << ": ";

    auto range = levels.equal_range( p );
    for( auto it = range.first; it != range.second; ++it )
     std::cerr << it->second << " ";

    std::cerr << "\n";
  }

  std::cerr << "# Distances counter\n";

  for( auto&& p : points )
  {
    std::cerr << p << ": ";

    auto range = distances.equal_range( p );
    for( auto it = range.first; it != range.second; ++it )
     std::cerr << it->second << " ";

    std::cerr << "\n";
  }

  std::cerr << "# Basic cover distance density\n";

  for( auto&& p : points )
  {
    std::cerr << p << ": ";

    auto range      = distances.equal_range( p );
    double distance = 0.0;

    for( auto it = range.first; it != range.second; ++it )
      distance += it->second;

    distance /= static_cast<T>( std::distance( range.first, range.second ) );

    std::cerr << distance << "\n";
  }

  // DEBUG: output of cover radii --------------------------------------

  {
    std::ofstream out( "/tmp/C.txt" );

    for( auto&& pair : nodesByLevel )
    {
      auto&& level  = pair.first;
      auto&& centre = pair.second;
      auto r        = std::pow( T(2), level );

      out << centre << " " << r << "\n";
    }
  }

  // DEBUG: output of edges --------------------------------------------

  {
    std::set< std::pair<Point, Point> > edges;

    for( auto&& pair : nodesByLevel )
    {
      auto&& level  = pair.first;
      auto&& centre = pair.second;

      for( auto&& p : points )
      {
        // TODO: fix radius/level calculation; is this an implementation
        // detail of the tree?
        if( contains( centre, p, T( std::pow( T(2), level ) ) ) )
        {
          // Induce basic ordering of edges in order to make it easier
          // to print them later on.
          if( centre < p )
            edges.insert( std::make_pair( centre, p ) );
          else
            edges.insert( std::make_pair( p, centre ) );
        }
      }
    }

    std::ofstream out( "/tmp/E.txt" );

    for( auto&& edge : edges )
    {
      out << edge.first  << "\n"
          << edge.second << "\n\n";
    }

    std::cerr << "# Cover tree\n";

    ct.print( std::cerr );

    std::set< std::pair<Point, Point> > filteredEdges;

    auto&& nodesToLevel = ct.nodesToLevel();
    for( auto&& edge : edges )
    {
      auto&& source = edge.first;                 // source node
      auto&& upper  = nodesToLevel.at( source );  // source level
      auto&& target = edge.second;                // target node
      auto&& lower  = nodesToLevel.at( target );  // target level

      auto d       = distance( source, target );
      auto d_lower = std::pow( T(2), lower );
      auto d_upper = std::pow( T(2), upper );

      std::cerr << edge.first << " -- " << edge.second << ":\n";

      if( d <= d_lower && d <= d_upper )
        filteredEdges.insert( edge );
      else if( d <= d_lower && d > d_upper )
      {
        // Only one criterion holds
      }
      else if( d <= d_upper && d > d_lower )
      {
        // Ditto.
      }
      else
        throw std::runtime_error( "This should never happen" );
    }

    out.close();
    out.open( "/tmp/F.txt" );

    for( auto&& edge : filteredEdges )
    {
      out << edge.first  << "\n"
          << edge.second << "\n\n";
    }
  }

  ALEPH_ASSERT_EQUAL( nodesByLevel.size(), points.size() );
  ALEPH_TEST_END();
}

int main( int, char** )
{
  testSimple<double>();
  testSimple<float> ();

  testSimplePermutations<double>();
  testSimplePermutations<float> ();

  test2D<double>();
  test2D<float> ();
}
<|endoftext|>


<commit_before>#include "atcommandframe.h"
#include <QDebug>

/**
 * @brief ATCommandFrame's constructor
 * @param parent
 */
ATCommandFrame::ATCommandFrame(QObject *parent) :
    DigiMeshFrame(parent)
{
    setFrameType(DigiMeshFrame::ATCommandFrame);
    setFrameId(0x01);
}

/**
 * @brief Sets the AT Command
 * @param command
 */
void ATCommandFrame::setCommand(const ATCommand command) {
    int cmdMSB = (command>>8) & 0xFF;
    int cmdLSB = command & 0xFF;
    m_command.clear();
    m_command.append(cmdMSB);
    m_command.append(cmdLSB);
}

/**
 * @brief Sets the AT Command from the given QString
 * @param command
 */
void ATCommandFrame::setCommand(const QString &command) {
    m_command.clear();
    m_command.append(command.at(0));
    m_command.append(command.at(1));
}

/**
 * @brief Sets command's parameter
 * @param param
 */
void ATCommandFrame::setParameter(const QByteArray &param) {
    m_parameter.clear();
    m_parameter.append(param);
}

/**
 * @brief Returns the AT Command
 * @return the AT Command
 */
QByteArray ATCommandFrame::command() const {
    return m_command;
}

/**
 * @brief Returns the command's parameter
 * @return the command's parameter
 */
QByteArray ATCommandFrame::parameter() const {
    return m_parameter;
}

void ATCommandFrame::assemblePacket() {
    m_packet.clear();
    m_packet.append(frameType());
    m_packet.append(frameId());
    m_packet.append(command());
    m_packet.append(parameter());
    setLength(m_packet.size());
    createChecksum(m_packet);
    m_packet.append(checksum());
    m_packet.insert(0, startDelimiter());
    m_packet.insert(1, (length()>>8)&0xFF);
    m_packet.insert(2, length()&0xFF);
}

void ATCommandFrame::clear()
{
    DigiMeshFrame::clear();
    m_command.clear();
    m_parameter.clear();
}

/**
 * @brief Returns the given ATCommandFrame::ATCommand into QString
 * @param command the ATCommand to be converted into QString
 * @return the given ATCommand into QString
 */
QString ATCommandFrame::atCommandToString(const ATCommand command)
{
    QString at(atCommandToByteArray(command));
    return at;
}

/**
 * @brief Returns the given ATCommandFrame::ATCommand into QByteArray
 * @param command the ATCommand to be converted into QByteArray
 * @return the given ATCommand into QByteArray
 */
QByteArray ATCommandFrame::atCommandToByteArray(const ATCommand command)
{
    QByteArray at;
    at.append((command>>8)&0xFF);
    at.append(command&0xFF);
    return at;
}

/**
 * @brief Returns the ATCommandFrame::ATCommand corresponding to the given QByteArray
 * @param command
 * @return the ATCommandFrame::ATCommand corresponding to the given QByteArray.
 */
ATCommandFrame::ATCommand ATCommandFrame::atCommandFromByteArray(const QByteArray &command)
{
    ATCommandFrame::ATCommand at;
    at = (ATCommandFrame::ATCommand) ( ( (command.at(0)&0xFF)<<8) + command.at(1) );

    return at;
}
<commit_msg>Improved ATCommandFrame::clear<commit_after>#include "atcommandframe.h"
#include <QDebug>

/**
 * @brief ATCommandFrame's constructor
 * @param parent
 */
ATCommandFrame::ATCommandFrame(QObject *parent) :
    DigiMeshFrame(parent)
{
    setFrameType(DigiMeshFrame::ATCommandFrame);
    setFrameId(0x01);
}

/**
 * @brief Sets the AT Command
 * @param command
 */
void ATCommandFrame::setCommand(const ATCommand command) {
    int cmdMSB = (command>>8) & 0xFF;
    int cmdLSB = command & 0xFF;
    m_command.clear();
    m_command.append(cmdMSB);
    m_command.append(cmdLSB);
}

/**
 * @brief Sets the AT Command from the given QString
 * @param command
 */
void ATCommandFrame::setCommand(const QString &command) {
    m_command.clear();
    m_command.append(command.at(0));
    m_command.append(command.at(1));
}

/**
 * @brief Sets command's parameter
 * @param param
 */
void ATCommandFrame::setParameter(const QByteArray &param) {
    m_parameter.clear();
    m_parameter.append(param);
}

/**
 * @brief Returns the AT Command
 * @return the AT Command
 */
QByteArray ATCommandFrame::command() const {
    return m_command;
}

/**
 * @brief Returns the command's parameter
 * @return the command's parameter
 */
QByteArray ATCommandFrame::parameter() const {
    return m_parameter;
}

void ATCommandFrame::assemblePacket() {
    m_packet.clear();
    m_packet.append(frameType());
    m_packet.append(frameId());
    m_packet.append(command());
    m_packet.append(parameter());
    setLength(m_packet.size());
    createChecksum(m_packet);
    m_packet.append(checksum());
    m_packet.insert(0, startDelimiter());
    m_packet.insert(1, (length()>>8)&0xFF);
    m_packet.insert(2, length()&0xFF);
}

void ATCommandFrame::clear()
{
    DigiMeshFrame::clear();
    m_command.clear();
    m_parameter.clear();
    setFrameType(DigiMeshFrame::ATCommandFrame);
    setFrameId(0x01);
}

/**
 * @brief Returns the given ATCommandFrame::ATCommand into QString
 * @param command the ATCommand to be converted into QString
 * @return the given ATCommand into QString
 */
QString ATCommandFrame::atCommandToString(const ATCommand command)
{
    QString at(atCommandToByteArray(command));
    return at;
}

/**
 * @brief Returns the given ATCommandFrame::ATCommand into QByteArray
 * @param command the ATCommand to be converted into QByteArray
 * @return the given ATCommand into QByteArray
 */
QByteArray ATCommandFrame::atCommandToByteArray(const ATCommand command)
{
    QByteArray at;
    at.append((command>>8)&0xFF);
    at.append(command&0xFF);
    return at;
}

/**
 * @brief Returns the ATCommandFrame::ATCommand corresponding to the given QByteArray
 * @param command
 * @return the ATCommandFrame::ATCommand corresponding to the given QByteArray.
 */
ATCommandFrame::ATCommand ATCommandFrame::atCommandFromByteArray(const QByteArray &command)
{
    ATCommandFrame::ATCommand at;
    at = (ATCommandFrame::ATCommand) ( ( (command.at(0)&0xFF)<<8) + command.at(1) );

    return at;
}
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 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
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "libmesh/quadrature.h"

namespace libMesh
{

void QBase::init(const ElemType t,
                 unsigned int p)
{
  // check to see if we have already
  // done the work for this quadrature rule
  if (t == _type && p == _p_level)
    return;
  else
    {
      _type = t;
      _p_level = p;
    }

  switch(_dim)
    {
    case 0:
      this->init_0D(_type,_p_level);

      return;

    case 1:
      this->init_1D(_type,_p_level);

      return;

    case 2:
      this->init_2D(_type,_p_level);

      return;

    case 3:
      this->init_3D(_type,_p_level);

      return;

    default:
      libmesh_error();
    }
}

void QBase::init_0D(const ElemType,
                    unsigned int)
{
  _points.resize(1);
  _weights.resize(1);
  _points[0] = Point(0.);
  _weights[0] = 1.0;
}

void QBase::scale(std::pair<Real, Real> old_range,
		  std::pair<Real, Real> new_range)
{
  // Make sure we are in 1D
  libmesh_assert_equal_to (_dim, 1);

  // Make sure that we have sane ranges
  libmesh_assert_greater (new_range.second, new_range.first);
  libmesh_assert_greater (old_range.second, old_range.first);

  // Make sure there are some points
  libmesh_assert_greater (_points.size(), 0);

  // We're mapping from old_range -> new_range
  for (unsigned int i=0; i<_points.size(); i++)
    {
      _points[i](0) =
	(_points[i](0) - old_range.first) *
	(new_range.second - new_range.first) /
	(old_range.second - old_range.first) +
	new_range.first;
    }

  // Compute the scale factor and scale the weights
  const Real scfact = (new_range.second - new_range.first) /
                      (old_range.second - old_range.first);

  for (unsigned int i=0; i<_points.size(); i++)
    _weights[i] *= scfact;
}

void QBase::tensor_product_quad(const QBase& q1D)
{

  const unsigned int n_points = q1D.n_points();

  _points.resize(n_points * n_points);

  _weights.resize(n_points * n_points);

  unsigned int qp=0;

  for (unsigned int j=0; j<n_points; j++)
    for (unsigned int i=0; i<n_points; i++)
      {
	_points[qp](0) = q1D.qp(i)(0);
	_points[qp](1) = q1D.qp(j)(0);

	_weights[qp] = q1D.w(i)*q1D.w(j);

	qp++;
      }
}

void QBase::tensor_product_hex(const QBase& q1D)
{
  const unsigned int n_points = q1D.n_points();

  _points.resize(n_points * n_points * n_points);

  _weights.resize(n_points * n_points * n_points);

  unsigned int qp=0;

  for (unsigned int k=0; k<n_points; k++)
    for (unsigned int j=0; j<n_points; j++)
      for (unsigned int i=0; i<n_points; i++)
	{
	  _points[qp](0) = q1D.qp(i)(0);
	  _points[qp](1) = q1D.qp(j)(0);
	  _points[qp](2) = q1D.qp(k)(0);

	  _weights[qp] = q1D.w(i) * q1D.w(j) * q1D.w(k);

	  qp++;
	}
}

void QBase::tensor_product_prism(const QBase& q1D, const QBase& q2D)
{
  const unsigned int n_points1D = q1D.n_points();
  const unsigned int n_points2D = q2D.n_points();

  _points.resize  (n_points1D * n_points2D);
  _weights.resize (n_points1D * n_points2D);

  unsigned int qp=0;

  for (unsigned int j=0; j<n_points1D; j++)
    for (unsigned int i=0; i<n_points2D; i++)
      {
	_points[qp](0) = q2D.qp(i)(0);
	_points[qp](1) = q2D.qp(i)(1);
	_points[qp](2) = q1D.qp(j)(0);

	_weights[qp] = q2D.w(i) * q1D.w(j);

	qp++;
      }

}

std::ostream& operator << (std::ostream& os, const QBase& q)
{
  q.print_info(os);
  return os;
}

} // namespace libMesh
<commit_msg>Changes in quadrature.C for -Wshadow.<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 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
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "libmesh/quadrature.h"

namespace libMesh
{

void QBase::init(const ElemType t,
                 unsigned int p)
{
  // check to see if we have already
  // done the work for this quadrature rule
  if (t == _type && p == _p_level)
    return;
  else
    {
      _type = t;
      _p_level = p;
    }

  switch(_dim)
    {
    case 0:
      this->init_0D(_type,_p_level);

      return;

    case 1:
      this->init_1D(_type,_p_level);

      return;

    case 2:
      this->init_2D(_type,_p_level);

      return;

    case 3:
      this->init_3D(_type,_p_level);

      return;

    default:
      libmesh_error();
    }
}

void QBase::init_0D(const ElemType,
                    unsigned int)
{
  _points.resize(1);
  _weights.resize(1);
  _points[0] = Point(0.);
  _weights[0] = 1.0;
}

void QBase::scale(std::pair<Real, Real> old_range,
		  std::pair<Real, Real> new_range)
{
  // Make sure we are in 1D
  libmesh_assert_equal_to (_dim, 1);

  // Make sure that we have sane ranges
  libmesh_assert_greater (new_range.second, new_range.first);
  libmesh_assert_greater (old_range.second, old_range.first);

  // Make sure there are some points
  libmesh_assert_greater (_points.size(), 0);

  // We're mapping from old_range -> new_range
  for (unsigned int i=0; i<_points.size(); i++)
    {
      _points[i](0) =
	(_points[i](0) - old_range.first) *
	(new_range.second - new_range.first) /
	(old_range.second - old_range.first) +
	new_range.first;
    }

  // Compute the scale factor and scale the weights
  const Real scfact = (new_range.second - new_range.first) /
                      (old_range.second - old_range.first);

  for (unsigned int i=0; i<_points.size(); i++)
    _weights[i] *= scfact;
}

void QBase::tensor_product_quad(const QBase& q1D)
{

  const unsigned int np = q1D.n_points();

  _points.resize(np * np);

  _weights.resize(np * np);

  unsigned int q=0;

  for (unsigned int j=0; j<np; j++)
    for (unsigned int i=0; i<np; i++)
      {
	_points[q](0) = q1D.qp(i)(0);
	_points[q](1) = q1D.qp(j)(0);

	_weights[q] = q1D.w(i)*q1D.w(j);

	q++;
      }
}

void QBase::tensor_product_hex(const QBase& q1D)
{
  const unsigned int np = q1D.n_points();

  _points.resize(np * np * np);

  _weights.resize(np * np * np);

  unsigned int q=0;

  for (unsigned int k=0; k<np; k++)
    for (unsigned int j=0; j<np; j++)
      for (unsigned int i=0; i<np; i++)
	{
	  _points[q](0) = q1D.qp(i)(0);
	  _points[q](1) = q1D.qp(j)(0);
	  _points[q](2) = q1D.qp(k)(0);

	  _weights[q] = q1D.w(i) * q1D.w(j) * q1D.w(k);

	  q++;
	}
}

void QBase::tensor_product_prism(const QBase& q1D, const QBase& q2D)
{
  const unsigned int n_points1D = q1D.n_points();
  const unsigned int n_points2D = q2D.n_points();

  _points.resize  (n_points1D * n_points2D);
  _weights.resize (n_points1D * n_points2D);

  unsigned int q=0;

  for (unsigned int j=0; j<n_points1D; j++)
    for (unsigned int i=0; i<n_points2D; i++)
      {
	_points[q](0) = q2D.qp(i)(0);
	_points[q](1) = q2D.qp(i)(1);
	_points[q](2) = q1D.qp(j)(0);

	_weights[q] = q2D.w(i) * q1D.w(j);

	q++;
      }

}

std::ostream& operator << (std::ostream& os, const QBase& q)
{
  q.print_info(os);
  return os;
}

} // namespace libMesh
<|endoftext|>


<commit_before>/** @file Observer.cpp
 * This file includes the high gain observer implementations for the two tank system with the water level of tank 2
 * as measurement value.
 */
#include "Observer.h"

std::vector<double> HighGainObserver::compute(const double &dhT2,
                                              const double &dUa) {

    double dSgnT = sign(this->dOut[0] - this->dOut[1]);
    double dAbsT = fabs(this->dOut[0] - this->dOut[1]);
    double dError = this->dOut[1] - dhT2;

    this->dOut[0] += this->dSampleTime * (-(this->dAS1 / this->dAT * dSgnT * sqrt(2 * M_G * dAbsT)) +
                                           this->dK / this->dAT * dUa +
                                           this->dGain[0] * dError);
    this->dOut[1] += this->dSampleTime * (this->dAS1 / this->dAT * dSgnT * sqrt(2 * M_G * dAbsT) -
                                          this->dAS2 / this->dAT * sqrt(2 * M_G * this->dOut[1]) +
                                          this->dGain[1] * dError);

    if (this->dOut[0] <= 0) {
        this->dOut[0] = 0;
    }
    if (this->dOut[1] <= 0) {
        this->dOut[1] = 0
    }

    std::vector<double> dOut(std::begin(this->dOut), std::end(this->dOut));
    return dOut;
}
<commit_msg>Fix introduced error in cpp file<commit_after>/** @file Observer.cpp
 * This file includes the high gain observer implementations for the two tank system with the water level of tank 2
 * as measurement value.
 */
#include "Observer.h"

std::vector<double> HighGainObserver::compute(const double &dhT2,
                                              const double &dUa) {

    double dSgnT = sign(this->dOut[0] - this->dOut[1]);
    double dAbsT = fabs(this->dOut[0] - this->dOut[1]);
    double dError = this->dOut[1] - dhT2;

    this->dOut[0] += this->dSampleTime * (-(this->dAS1 / this->dAT * dSgnT * sqrt(2 * M_G * dAbsT)) +
                                           this->dK / this->dAT * dUa +
                                           this->dGain[0] * dError);
    this->dOut[1] += this->dSampleTime * (this->dAS1 / this->dAT * dSgnT * sqrt(2 * M_G * dAbsT) -
                                          this->dAS2 / this->dAT * sqrt(2 * M_G * this->dOut[1]) +
                                          this->dGain[1] * dError);

    if (this->dOut[0] <= 0) {
        this->dOut[0] = 0;
    }
    if (this->dOut[1] <= 0) {
        this->dOut[1] = 0;
    }

    std::vector<double> dOut(std::begin(this->dOut), std::end(this->dOut));
    return dOut;
}
<|endoftext|>