I am suffering serious problems while trying to use nlopt library (http://ab-initio.mit.edu/wiki/index.php/NLopt_Tutorial) in windows forms application. I have created following namespace which runs perfectly in console application.
#include "math.h"
#include "nlopt.h"
namespace test
{
typedef struct {
double a, b;
} my_constraint_data;
double myfunc(unsigned n, const double *x, double *grad, void *my_func_data)
{
if (grad) {
grad[0] = 0.0;
grad[1] = 0.5 / sqrt(x[1]);
}
return sqrt(x[1]);
}
double myconstraint(unsigned n, const double *x, double *grad, void *data)
{
my_constraint_data *d = (my_constraint_data *) data;
double a = d->a, b = d->b;
if (grad) {
grad[0] = 3 * a * (a*x[0] + b) * (a*x[0] + b);
grad[1] = -1.0;
}
return ((a*x[0] + b) * (a*x[0] + b) * (a*x[0] + b) - x[1]);
}
int comp()
{
double lb[2] = { -HUGE_VAL, 0 }; /* lower bounds */
nlopt_opt opt;
opt = nlopt_create(NLOPT_LD_MMA, 2); /* algorithm and dimensionality */
nlopt_set_lower_bounds(opt, lb);
nlopt_set_min_objective(opt, myfunc, NULL);
my_constraint_data data[2] = { {2,0}, {-1,1} };
nlopt_add_inequality_constraint(opt, myconstraint, &data[0], 1e-8);
nlopt_add_inequality_constraint(opt, myconstraint, &data[1], 1e-8);
nlopt_set_xtol_rel(opt, 1e-4);
double x[2] = { 1.234, 5.678 }; /* some initial guess */
double minf; /* the minimum objective value, upon return */
int a=nlopt_optimize(opt, x, &minf) ;
return 1;
}
}
It optimizes simple nonlinear constrained minimization problem. The problem arises when I try to use this namespace in windows form application. I am constantly getting unhandled exception in myfunc which sees "x" as empty pointer for some reason and therefore causes error when trying to access its location. I believe that the problem is somehow caused by the fact that windows forms uses CLR but I dont know if it is solvable or not. I am using visual studio 2008 and the test programs are simple console project (which works fine) and windows forms project (that causes aforementioned errors).
My test code is based on tutorial for C from the provided link. I although tried C++ version which once again works fine in console application but gives debug assertion failed error in windows forms application.
So I guess my questions is : I have working windows forms application and I would like to use NLOpt. Is there a way to make this work ?
Related
Some background:
I wrote a single layer multi output perceptron class in C++. It uses the typical WX + b discriminant function and allows for user-defined activation functions. I have tested everything pretty throughly and it all seems to be working as I expect it to. I noticed a small logical error in my code, and when I attempted to fix it the network performed much worse than before. The error is as follows:
I evaluate the value at each output neuron using the following code:
output[i] =
activate_(std::inner_product(weights_[i].begin(), weights_[i].end(),
features.begin(), -1 * biases_[i]));
Here I treat the bias input as a fixed -1, but when I apply the learning rule to each bias, I treat the input as +1.
// Bias can be treated as a weight with a constant feature value of 1.
biases_[i] = weight_update(1, error, learning_rate_, biases_[i]);
So I attempted to fix my mistake by changing the call to weight_updated to be conistent with the output evaluation:
biases_[i] = weight_update(-1, error, learning_rate_, biases_[i]);
But doing so results in a 20% drop in accuracy!
I have been pulling my hair out for the past few days trying to find some other logical error in my code which might explain this strange behaviour, but have come up empty handed. Can anyone with more knowledge than I provide any insight into this? I have provided the entire class below for reference. Thank you in advance.
#ifndef SINGLE_LAYER_PERCEPTRON_H
#define SINGLE_LAYER_PERCEPTRON_H
#include <cassert>
#include <functional>
#include <numeric>
#include <vector>
#include "functional.h"
#include "random.h"
namespace qp {
namespace rf {
namespace {
template <typename Feature>
double weight_update(const Feature& feature, const double error,
const double learning_rate, const double current_weight) {
return current_weight + (learning_rate * error * feature);
}
template <typename T>
using Matrix = std::vector<std::vector<T>>;
} // namespace
template <typename Feature, typename Label, typename ActivationFn>
class SingleLayerPerceptron {
public:
// For testing only.
SingleLayerPerceptron(const Matrix<double>& weights,
const std::vector<double>& biases, double learning_rate)
: weights_(weights),
biases_(biases),
n_inputs_(weights.front().size()),
n_outputs_(biases.size()),
learning_rate_(learning_rate) {}
// Initialize the layer with random weights and biases in [-1, 1].
SingleLayerPerceptron(std::size_t n_inputs, std::size_t n_outputs,
double learning_rate)
: n_inputs_(n_inputs),
n_outputs_(n_outputs),
learning_rate_(learning_rate) {
weights_.resize(n_outputs_);
std::for_each(
weights_.begin(), weights_.end(), [this](std::vector<double>& wv) {
generate_back_n(wv, n_inputs_,
std::bind(random_real_range<double>, -1, 1));
});
generate_back_n(biases_, n_outputs_,
std::bind(random_real_range<double>, -1, 1));
}
std::vector<double> predict(const std::vector<Feature>& features) const {
std::vector<double> output(n_outputs_);
for (auto i = 0ul; i < n_outputs_; ++i) {
output[i] =
activate_(std::inner_product(weights_[i].begin(), weights_[i].end(),
features.begin(), -1 * biases_[i]));
}
return output;
}
void learn(const std::vector<Feature>& features,
const std::vector<double>& true_output) {
const auto actual_output = predict(features);
for (auto i = 0ul; i < n_outputs_; ++i) {
const auto error = true_output[i] - actual_output[i];
for (auto weight = 0ul; weight < n_inputs_; ++weight) {
weights_[i][weight] = weight_update(
features[weight], error, learning_rate_, weights_[i][weight]);
}
// Bias can be treated as a weight with a constant feature value of 1.
biases_[i] = weight_update(1, error, learning_rate_, biases_[i]);
}
}
private:
Matrix<double> weights_; // n_outputs x n_inputs
std::vector<double> biases_; // 1 x n_outputs
std::size_t n_inputs_;
std::size_t n_outputs_;
ActivationFn activate_;
double learning_rate_;
};
struct StepActivation {
double operator()(const double x) const { return x > 0 ? 1 : -1; }
};
} // namespace rf
} // namespace qp
#endif /* SINGLE_LAYER_PERCEPTRON_H */
I ended up figuring it out...
My fix was indeed correct and the loss of accuracy was just a consequence of having a lucky (or unlucky) dataset.
I am using the Qt Creator (Community) to learn how to code.
I have an assignment to calculate the roots of a function, and I tried using the code I found here in a Qt Widgets Project.
When I try to run the program, Qt didn't detect any errors.
However, my program crashes whenever I try to show the results using on_pushButton_clicked().
My lecturer suspects there should be an open loop somewhere but I don't see any.
Any help would be very much appreciated.
Code below:
double function1(double q)
{
double ab = ((q*q*q)+(9*q*q)-(15*q)+98)*(sin(q));
return ab;
}
void MainWindow::on_pushButton_clicked()
{
ui->label->setText(tr("%1").arg(func1()));
}
double MainWindow::func1()
{
std::setprecision(4);
double precision = 0.001;
double a = -10;
double b = -9;
double product = function1(a)*function1(b);
double absolute = fabs(a-b);
double e = 0;
if (product>0)
{
++a;
++b;
}
else
{
while (absolute >= precision)
{
e = (a + b) / 2;
double fa = function1(a);
double fe = function1(e);
if (fe == 0)
{
return e;
break;
}
if (fa*fe>0)
{
a = e;
}
else if (fa*fe<0)
{
b = e;
}
}
}
return e;
}
Try printing out the values of absolute and precision everytime this loop happens:
while (absolute >= precision)
.
That should help you figure it out.
If the program crashes when you click the button that "calls" on_pushButton_clicked, then it something wrong inside this slot.
Firstly, are all heap memory objects created previously with a new statement (in particular label)?
PS: you can remove the break instruction, function has already exited the while loop due to return in the line before.
I'm fairly new to programming in c++ and I've come across some code which gives me errors because the code was intended for a windows operating system, however I'm running a linux operating system. There's a file called TetrisBlock.h, which looks like:
#ifndef TETRIS_BLOCK_INCLUDED
#define TETRIS_BLOCK_INCLUDED
#include "Common.h"
class CTetrisBlock
{
public:
void Create();
void Draw();
void Destroy();
CTetrisBlock();
virtual ~CTetrisBlock();
int GetPosX();
int GetPosY();
void SetPosX(int x);
void SetPosY(int y);
private:
int m_iPosX, m_iPosY;
};
#endif
from my experience with java, this looks like an interface to me, waiting for a .cpp to implement it and fill in the abstract methods. The corresponding TetrisBlock.cpp file is as follows:
#include "TetrisBlock.h"
CTetrisBlock::CTetrisBlock()
{
int num_blocks_x = WINDOW_WIDTH / (BLOCK_SIZE + BLOCK_SPACING);
int num_blocks_y = WINDOW_HEIGHT / (BLOCK_SIZE + BLOCK_SPACING);
m_iPosX = num_blocks_x / 2;
m_iPosY = num_blocks_y - 1;
}
CTetrisBlock::~CTetrisBlock()
{
Destroy();
}
void CTetrisBlock::Create()
{
}
void CTetrisBlock::Draw()
{
tRect quad;
quad.m_iLeft = m_iPosX * (BLOCK_SIZE + BLOCK_SPACING) + BLOCK_SPACING;
quad.m_iRight = quad.m_iLeft + BLOCK_SIZE - BLOCK_SPACING;
quad.m_iTop = m_iPosY * (BLOCK_SIZE + BLOCK_SPACING) - BLOCK_SPACING;
quad.m_iBottom = quad.m_iTop - BLOCK_SIZE + BLOCK_SPACING;
glColor3d(1,1,1);
glBegin(GL_QUADS);
glVertex3f(quad.m_iLeft, quad.m_iBottom, 0);
glVertex3f(quad.m_iRight, quad.m_iBottom, 0);
glVertex3f(quad.m_iRight, quad.m_iTop, 0);
glVertex3f(quad.m_iLeft, quad.m_iTop, 0);
glEnd();
}
void CTetrisBlock::Destroy()
{
}
void CTetrisBlock::SetPosX(int x)
{
m_iPosX = x;
}
void CTetrisBlock::SetPosY(int y)
{
m_iPosY = y;
}
int CTetrisBlock::GetPosX()
{
return m_iPosX;
}
int CTetrisBlock::GetPosY()
{
return m_iPosY;
}
Note: The OpenGL library has already been imported within the common.h file
When I compile the file TetrisBlock.cpp, I get the error lines in the console:
undefined reference to 'CTetrisBlock::Create()'
undefined reference to 'CTetrisBlock::Draw()'
undefined reference to 'CTetrisBlock::Destroy()'
etc...
I'm guessing that the way I've filled in the abstract methods only works on windows, and that there's a different way to do it in linux. If this is true, then how would I fill in those abstract methods on linux. If I'm completely wrong, then can anyone explain why I'm receiving these errors. Also, are .h files always used the same way interfaces are used in java, or do they have a more general use?
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have recently read an enormous book on c++, but I have not tested what I have learned until now. Now, this "enormous book" of mine was actually made in 1995, so I obviously cannot trust everything that this book states. In other words, I know not whether the compiler, enormous book, or I did something wrong.
In order to test my knowledge of c++, I made a class (without pointer syntax due to fear of potential disaster) that I called MathContext. As a quick summary, this class of mine has eight (!) constructors in order to be user-friendly (if I can get this to work). It has three private fields (or attributes; I know not what one would prefer to call them in c++) called base, precision, and mode. The base field of type short stores the requested base (from two, inclusive, to thirty-six, inclusive), the precision field stores the requested decimal digit count (according to the base; I'll worry about that later), and the mode field is actually an instance of a nested enumeration called RoundingMode.
As you may see, this class is somewhat similar to the java.math.MathContext class except that I include the "java.math.RoundingMode" enumeration within the "java.math.MathContext" class.
Here is the complete syntax of all files that I have written in order to test this MathContext class:
MathContext.h:
#pragma once
class MathContext sealed
{
public:
enum RoundingMode
{
DOWN,
UP,
FLOOR,
CEILING,
HALF_DOWN,
HALF_UP,
HALF_EVEN
};
MathContext(void);
MathContext(unsigned short);
MathContext(unsigned int);
MathContext(RoundingMode);
MathContext(unsigned short, unsigned int);
MathContext(unsigned short, RoundingMode);
MathContext(unsigned int, RoundingMode);
MathContext(unsigned short, unsigned int, RoundingMode);
~MathContext(void);
unsigned short get_base(void);
void set_base(unsigned short);
unsigned int get_precision(void);
void set_precision(unsigned int);
RoundingMode get_rounding_mode(void);
void set_rounding_mode(RoundingMode);
bool operator==(MathContext);
bool operator!=(MathContext);
bool operator>(MathContext);
bool operator<(MathContext);
bool operator>=(MathContext);
bool operator<=(MathContext);
private:
unsigned short base;
unsigned int precision;
unsigned RoundingMode mode;
}
MathContext.cpp:
#include "stdafx.h"
#include "MathContext.h"
MathContext::MathContext(void)
{
base = 10;
precision = 15;
mode = RoundingMode::HALF_EVEN;
}
MathContext::MathContext(unsigned short base)
{
set_base(base);
precision = 15;
mode = RoundingMode::HALF_EVEN;
}
MathContext::MathContext(unsigned int precision)
{
base = 10;
set_precision(precision);
mode = RoundingMode::HALF_EVEN;
}
MathContext::MathContext(RoundingMode rounding_mode)
{
base = 10;
precision = 15;
mode = rounding_mode;
}
MathContext::MathContext(unsigned short base, unsigned int precision)
{
set_base(base);
set_precision(precision);
mode = RoundingMode::HALF_EVEN;
}
MathContext::MathContext(unsigned short base, RoundingMode rounding_mode)
{
set_base(base);
precision = 15;
mode = rounding_mode;
}
MathContext::MathContext(unsigned int precision, RoundingMode rounding_mode)
{
base = 10;
set_precision(precision);
mode = rounding_mode;
}
MathContext::MathContext(unsigned short base, unsigned int precision, RoundingMode rounding_mode)
{
set_base(base);
set_precision(precision);
mode = rounding_mode;
}
MathContext::~MathContext(void)
{
delete &base;
delete &precision;
delete &mode;
}
unsigned short MathContext::get_base(void)
{
return base;
}
void MathContext::set_base(unsigned short value)
{
base = value == 0 || value % 36 == 1 ? 2 : (value % 36 == 0 ? 36 : value % 36);
}
unsigned int MathContext::get_precision(void)
{
return precision;
}
void MathContext::set_precision(unsigned int value)
{
precision = value;
}
MathContext::RoundingMode MathContext::get_rounding_mode(void)
{
return mode;
}
void MathContext::set_rounding_mode(RoundingMode rounding_mode)
{
mode = rounding_mode;
}
bool MathContext::operator==(MathContext context)
{
return base == context.base && precision == context.precision && mode == context.mode;
}
bool MathContext::operator!=(MathContext context)
{
return base != context.base || precision != context.precision || mode != context.mode;
}
bool MathContext::operator>(MathContext context)
{
return precision == context.precision ? mode > context.mode : precision > context.precision;
}
bool MathContext::operator<(MathContext context)
{
return precision == context.precision ? mode < context.mode : precision < context.precision;
}
bool MathContext::operator>=(MathContext context)
{
return precision == context.precision ? mode >= context.mode : precision > context.precision;
}
bool MathContext::operator<=(MathContext context)
{
return precision == context.precision ? mode <= context.mode : precision < context.precision;
}
Graphics.cpp (the test class; please don't ask why I called it that):
#include "stdafx.h"
#include "MathContext.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
MathContext context[8];
context[0] = MathContext::MathContext();
context[1] = MathContext::MathContext((unsigned short) 46);
context[2] = MathContext::MathContext((unsigned int) 20);
context[3] = MathContext::MathContext(MathContext::RoundingMode::UP);
context[4] = MathContext::MathContext((unsigned short) 36, (unsigned int) 30);
context[5] = MathContext::MathContext((unsigned short) 36, MathContext::RoundingMode::HALF_DOWN);
context[6] = MathContext::MathContext((unsigned int) 25, MathContext::RoundingMode::HALF_EVEN);
context[7] = MathContext::MathContext((unsigned short) 26, (unsigned int) 29, MathContext::RoundingMode::HALF_EVEN);
int best = 0;
for(int i = 1; i < 8; i++)
{
if(context[best] < context[i])
{
best = i;
}
}
std::cout << "Context #" << best + 1 << " is the best!\n";
return 0;
}
I hoped that, Context #5 is the best! would show on the console (my Windows 8.1 Command Prompt), but I could not get anywhere near that point because after I compiled those three files and began to debug them, the command prompt actually did not terminate (I assume that some would call it a freeze), so I had to force its exit through the Windows 8.1 Task Manager. Now, that's what I call a problem!
Here are two essential details: My OS is Windows 8.1 (I hope that it won't throw anyone off), and I use the Microsoft Visual Studio Express 2012 for Windows Desktop Update 4. As miscellaneous information, I consider myself as an expert Java programmer (it may or may not help; perhaps someone could point out some relevant differences between Java and c++ so that this won't happen ever again), and the source code that I typed actually removed unnecessary whitespace; for example, instead of base = 10;, I typed base=10; Well, the compiler apparently thinks that my code is fine, but it apparently is not for some reason. Could anyone point out to me what is obsolete that I use, why the debugging apparently freezes the command prompt, and any essential differences between Java and c++ that I should take note of as I program in c++? I sincerely thank you!
You are calling the MathContext constructor-methods directly, change that to to the below
by dropping the first part of MathContext::MathContext to just MathContext
int main(int argc, _TCHAR* argv[])
{
MathContext context[8];
context[0] = MathContext();
context[1] = MathContext((unsigned short) 46);
context[2] = MathContext((unsigned int) 20);
context[3] = MathContext(MathContext::UP);
context[4] = MathContext((unsigned short) 36, (unsigned int) 30);
context[5] = MathContext((unsigned short) 36, MathContext::HALF_DOWN);
context[6] = MathContext((unsigned int) 25, MathContext::HALF_EVEN);
context[7] = MathContext((unsigned short) 26, (unsigned int) 29, MathContext::HALF_EVEN);
You are deleting memeory which is not allocated (newed) by you (remove that)
MathContext::~MathContext(void)
{
//delete &base;
//delete &precision;
//delete &mode;
}
In short, your program was hanging due to the weird memory errors you had -- direct invocation of a constructor will assume that memory for the object is already allocated + the deallocation of memory which you had not allocated.
I created a dll file from Mathlab .m files using Matlab coder. In matlab, the matlab code runs fine without any error and DLL creation was successful. MV2010 compiles and runs fine. However, when the software calls any function from this DLL in Visual studio, i get "unhandled exception" with memory location and "access violation reading location" with another memory location.
I thought the created dll is depending on another dll that is missing. So, I used dependency Walker to check the dependency. However, dependency walker did not show any missing dependency.
The Matlab functions takes 5 input variables ( four as a double and one as 1D-array of double) and return 4 double values. So I thought it might be the size of the array i am passing to the matlab-generated code is small. So, I re-sized the array. The original size was 750, while new size is 5000. Still getting the same unhandled exception.
Any idea how to debug this unhandled exception? anything else i need to check for?
/* Function Declarations */
extern void mat3(double ValueF, double DesiredValue, double io, double del, emxArray_real_T *a, double *status, double *slope_deg, double *fval, double *SVal);
and I am calling this method in MS2010 as shown below.
double lValueF = 166.6;
double lDesiredValue = 42.00;
double io = 1.0;
double del = 4.0;
emxArray_real_T *lInputRoi;
// a = emxCreate_real_T(height,width);
lInputRoi = emxCreate_real_T(size_y,size_x);
// Converting 2D image to ID array
if(!isHorz)
{
int lRow = 0;
int lCol = 0;
for (int row=roi.y+odd_y_offset;row< roi.y+size_y;row=row+2)
{
lCol = 0;
for (int col=roi.x;col< roi.x+size_x;col++)
{
lInputRoi->data[lRow *size_x + lCol] = (real_T)img.at<uchar>(row,col);
lCol++;
}
lRow++;
}
}
else
{
int lRow = 0;
int lCol = 0;
for (int col=roi.x+odd_x_offset;col< roi.x+size_x;col=col+2)
{
lRow = 0;
for (int row=roi.y;row< roi.y+size_y;row++)
{
lInputRoi->data[lCol *size_y + lRow] = (real_T)img.at<uchar>(row,col);
lRow++;
}
lCol++;
size_x = roi.height;
size_y = roi.width;
}
}
// initializing matlab generated function
mat3_initialize();
double lStatus = 0;
double lslope_deg = 0.0;
double lfreqval = 0.0;
double lsfrvalue = 0.0;
mat3(lValueF, lDesiredValue, io, del, lInputRoi, &lStatus, &lslope_deg, &lfreqval, &lsfrvalue);
note:
1) img -> is the input image data.
2) roi -> is an object of struct type that has two int variables (x and y)
3) MV2010 application is an application that used "MFC in a shared DLL"
4) I have seen a tutorial on how to integrate the Mathlab generated dll in Microsoft Visual studio. However, the tutorial does not get any error. http://www.mathworks.com/videos/integrate-code-into-visual-studio-77402.html
Thanks you for any help in advance.