Click here to Skip to main content
15,889,462 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to implement NLOPT in a class in my program. The errors are :
Warning	7	warning C4717: 'NonlinearOpt::nlopt_add_inequality_constraint' : recursive on all control paths, function will cause runtime stack overflow	d:\program\robotsimu190902_salah\robotsimu\nonlinearopt.cpp	142
Warning	6	warning C4717: 'NonlinearOpt::nlopt_create' : recursive on all control paths, function will cause runtime stack overflow	d:\program\robotsimu190902_salah\robotsimu\nonlinearopt.cpp	149
Warning	10	warning C4717: 'NonlinearOpt::nlopt_optimize' : recursive on all control paths, function will cause runtime stack overflow	d:\program\robotsimu190902_salah\robotsimu\nonlinearopt.cpp	169
Warning	9	warning C4717: 'NonlinearOpt::nlopt_set_lower_bounds' : recursive on all control paths, function will cause runtime stack overflow	d:\program\robotsimu190902_salah\robotsimu\nonlinearopt.cpp	156
Warning	5	warning C4717: 'NonlinearOpt::nlopt_set_min_objective' : recursive on all control paths, function will cause runtime stack overflow	d:\program\robotsimu190902_salah\robotsimu\nonlinearopt.cpp	177
Warning	8	warning C4717: 'NonlinearOpt::nlopt_set_xtol_rel' : recursive on all control paths, function will cause runtime stack overflow	d:\program\robotsimu190902_salah\robotsimu\nonlinearopt.cpp	161


What I have tried:

Here is the code I mad :
<nonlinearopt.h>
#ifndef __NONLINEAROPT_H__
#define __NONLINEAROPT__
#pragma once

#include "stdafx.h"

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#include <iostream>

#include "nlopt.h"

#pragma comment(lib, "libnlopt-0.lib")

class NonlinearOpt
{
private:

public:
	double ankle_angle;		//ankle angle from GA
	double knee_angle;		//knee angle from GA
	double pelvis_angle;	//pelvis angle from GA

	double k1;
	double k2;
	double k3;
	
	double max_ankle;		//maximum ankle angle
	double max_knee;		//maximum knee angle
	double max_pelvis;		//maximum pelvis angle

	double min_ankle;		//minimum ankle angle
	double min_knee;		//minimum knee angle
	double min_pelvis;		//minimum pelvis angle

	double new_ankle_angle;
	double new_knee_angle;
	double new_pelvis_angle;

public:
	NonlinearOpt(void){

		//constant value
		k1 = 1.0;
		k2 = 1.0;
		k3 = 1.0;

	};

	~NonlinearOpt(void){

	};

	public:

/************************** Nonlinear Equations ********************************/

	//joint function (f)
	double myfunction(unsigned int n, const double *theta, double *grad);

	//constraint function (c) for solution 1
	double myconstraint1(unsigned int n, const double *x, double *grad);	//c1
	double myconstraint2(unsigned n, const double *x, double *grad);		//c2	
double myconstraint6(unsigned n, const double *x, double *grad);		//c6
	
	int main();

/****************** NLOPT Functions ****************************/
	//add inequality constraints
	nlopt_result nlopt_add_inequality_constraint(nlopt_opt opt, nlopt_func fc, void* fc_data, double tol);

	//add equality constraints
	nlopt_result nlopt_add_equality_constraint(nlopt_opt opt, nlopt_func h, void* h_data, double tol);

	//create the dimension of algorithm
	nlopt_opt nlopt_create(nlopt_algorithm algorithm, unsigned n);

	//add the lower bounds for minimalization
	nlopt_result nlopt_set_lower_bounds(nlopt_opt opt, const double* lb);

	//add the variable's tolarance
	nlopt_result nlopt_set_xtol_rel(nlopt_opt opt, double tol);

	//for minimal optimization
	nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *opt_f);
	nlopt_result nlopt_set_min_objective(nlopt_opt opt, nlopt_func f, void* f_data);

	//destroy optimization
	void nlopt_destroy(nlopt_opt opt);
};

#endif


<nonlinearopt.cpp>
#include "stdafx.h"
#include "NonlinearOpt.h"

typedef UINT( __stdcall * ThreadFunc )( PVOID );


//solution 1
//f= k2(x2-a2)^2 + k3(x3-a3)^2 
double NonlinearOpt::myfunction(unsigned int n, const double *theta, double *grad) {
	if (grad) {
		grad[0] = 2*k1*(theta[0]-ankle_angle);
		grad[1] = 2*k2*(theta[1]-knee_angle);
		grad[2] = 2*k3*(theta[2]-pelvis_angle);
	}

	return (k1*(theta[0]-ankle_angle)*(theta[0]-ankle_angle) + k2*(theta[1]-knee_angle)*(theta[1]-knee_angle) + k3*(theta[2]-pelvis_angle)*(theta[2]-pelvis_angle));
}

//wrapper function of myfunction
double MyFunction( unsigned n, const double *theta, double *grad, void *pdata )
{
   NonlinearOpt * pnlo = (NonlinearOpt *)pdata;
   return pnlo->myfunction( n, theta, grad );
}

//nlopt constraints h(x)<=0 
//c1 = theta1_min - theta1
double NonlinearOpt::myconstraint1(unsigned n, const double *theta, double *grad){
	//++count;
	if (grad) {
		grad[0] = -1;		//grad[0] = d(c1)/dtheta1
		grad[1] = 0;		//grad[1] = d(c1)/dtheta2
		grad[2] = 0;		//grad[2] = d(c1)/dtheta3
	}
	return (min_ankle - theta[0]);
}

//wrapper function of myconstraint1
double MyConstraint1( unsigned n, const double *theta, double *grad, void *pdata )
{
   NonlinearOpt * pnlo = (NonlinearOpt *)pdata;
   return pnlo->myconstraint1( n, theta, grad );
}

//c2 = theta1 - theta1_max
double NonlinearOpt::myconstraint2(unsigned n, const double *theta, double *grad){
	//++count;
	if (grad) {
		grad[0] = 1;		//grad[0] = d(c2)/dtheta1
		grad[1] = 0;		//grad[1] = d(c2)/dtheta2
		grad[2] = 0;		//grad[2] = d(c2)/dtheta3
	}
	return (theta[0] - max_ankle);
}

//wrapper function of myconstraint2
double MyConstraint2( unsigned n, const double *theta, double *grad, void *pdata )
{
   NonlinearOpt * pnlo = (NonlinearOpt *)pdata;
   return pnlo->myconstraint2( n, theta, grad );
}



nlopt_result NonlinearOpt::nlopt_add_inequality_constraint(nlopt_opt opt, nlopt_func fc, void *fc_data, double tol){
	opt = opt;
	fc = fc;
	fc_data = fc_data;
	tol = tol;

	return nlopt_add_inequality_constraint(opt, fc, fc_data, tol);
}

nlopt_opt NonlinearOpt::nlopt_create(nlopt_algorithm algorithm, unsigned int n){
	algorithm = algorithm;
	n=n;

	return nlopt_create(algorithm, n);
}

nlopt_result NonlinearOpt::nlopt_set_lower_bounds(nlopt_opt opt, const double *lb){
	opt = opt;
	lb = lb;

	return nlopt_set_lower_bounds(opt, lb);
}

nlopt_result NonlinearOpt::nlopt_set_xtol_rel(nlopt_opt opt, double tol){

	return nlopt_set_xtol_rel(opt, tol);
}

nlopt_result NonlinearOpt::nlopt_optimize(nlopt_opt opt, double *x, double *opt_f){
	opt = opt;
	x = x;
	opt_f = opt_f;

	return nlopt_optimize(opt, x, opt_f);
}

nlopt_result NonlinearOpt::nlopt_set_min_objective(nlopt_opt opt, nlopt_func f, void *f_data){
	opt = opt;
	f = f;
	f_data = f_data;

	return nlopt_set_min_objective(opt, f, f_data);
}

void NonlinearOpt::nlopt_destroy(nlopt_opt opt){
	opt = opt;
}

int NonlinearOpt::main() {

	nlopt_opt opt;
	
	double lb[2] = { -HUGE_VAL, 0 }; // lower bounds 
	double theta[3] = {0, 0, 1};  // `*`some` `initial` `guess`*`
	double minf; // `*`the` `minimum` `objective` `value,` `upon` `return`*`

	opt = nlopt_create(NLOPT_LD_MMA, 3); // algorithm and dimensionality 
	nlopt_set_lower_bounds(opt, lb);
	nlopt_set_min_objective(opt,MyFunction, NULL);

	nlopt_add_inequality_constraint(opt, MyConstraint1, NULL, 1e-8);
	nlopt_add_inequality_constraint(opt, MyConstraint2, NULL, 1e-8);

	nlopt_set_xtol_rel(opt, 1e-4);

	if (nlopt_optimize(opt, theta, &minf) < 0) {
		printf("nlopt failed!\n");
	}
	else {
		//printf("found minimum after %d evaluation\n", &CNonlinearOptimization::count);
		printf("found minimum at f(%0.10g,%0.10g,%0.10g) = %0.10g\n", theta[0], theta[1], theta[2], minf);
		new_ankle_angle  = theta[0];
		new_knee_angle   = theta[1];
		new_pelvis_angle = theta[2];
	}
	nlopt_destroy(opt);
	system("pause");
	
	return 0;
}


When I was debugging my program, the error refers to the wrapper function of constraints (MyConstraint1, MyConstraint2, etc.). Do you know how to solve this problem ? specially for my wrapper function to call NLOPT. If you know so well about NLOPT, please let me know. Thank you
Posted
Updated 3-Sep-19 5:12am
Comments
[no name] 3-Sep-19 11:00am    
You copied this code, made changes to it, and now (if ever) it doesn't work?
Member 13922009 4-Sep-19 7:24am    
yes, do you know how to solve this ?

1 solution

The problem is your wrapper class's methods have the same name as the library's functions. It appears you are not using the c++ version of the library so you need to revise the function calls so they look like this :
C++
nlopt_result NonlinearOpt::nlopt_add_inequality_constraint( nlopt_opt opt, nlopt_func fc, void *fc_data, double tol )
{
    return ::nlopt_add_inequality_constraint( opt, fc, fc_data, tol );
}
The assignments of variables to themselves do nothing so they are not necessary. The double colons (::) in this case are scope resolution operators. They tell the compiler to use the functions in the global namespace. Without those, the compiler will use the version in the current namespace which results in the recursion warnings that were flagged. This needs to be done for each of the cases where a recursion warning was noted.

There is a C++ interface available for that library. You should consider using it. One of the things it does is it removes nlopt_ prefix from those functions which are not necessary in wrapper class methods since you know what object you are referencing. You might not need some of the methods of your wrapper class since it is doing essentially the same thing. That is, unless you are supposed to write your own wrapper class. In that case, one thing you should do is remove the nlopt_ prefixes from your methods. :)
 
Share this answer
 
Comments
Member 13922009 4-Sep-19 7:22am    
I tried your advice, but I got same errors :
Warning 1 warning C4717: 'NonlinearOpt::nlopt_add_inequality_constraint' : recursive on all control paths, function will cause runtime stack overflow d:\program\robotsimu190902\robotsimu\nonlinearopt.cpp 137
Warning 4 warning C4717: 'NonlinearOpt::nlopt_create' : recursive on all control paths, function will cause runtime stack overflow d:\program\robotsimu190902\robotsimu\nonlinearopt.cpp 146
Warning 2 warning C4717: 'NonlinearOpt::nlopt_optimize' : recursive on all control paths, function will cause runtime stack overflow d:\program\robotsimu190902\robotsimu\nonlinearopt.cpp 161
Warning 5 warning C4717: 'NonlinearOpt::nlopt_set_lower_bounds' : recursive on all control paths, function will cause runtime stack overflow d:\program\robotsimu190902\robotsimu\nonlinearopt.cpp 151
Warning 3 warning C4717: 'NonlinearOpt::nlopt_set_min_objective' : recursive on all control paths, function will cause runtime stack overflow d:\program\robotsimu190902\robotsimu\nonlinearopt.cpp 166
Warning 6 warning C4717: 'NonlinearOpt::nlopt_set_xtol_rel' : recursive on all control paths, function will cause runtime stack overflow d:\program\robotsimu190902\robotsimu\nonlinearopt.cpp 156

same messages. It will be works in single program, but when I implement in one class in my program that has several cpp and header files, this error always occur
Rick York 4-Sep-19 10:38am    
Edit your question and place the updated code in there so we can see you did.

You have the same errors offset by a few lines. It appears that you did not do what I suggested or those errors would be gone. Which part of what I suggested did you try?
Member 13922009 4-Sep-19 12:28pm    
I remove the nlopt_ prefixes
Rick York 4-Sep-19 16:06pm    
You removed the prefixes from what? They were in several places. You have to be very, VERY specific in your descriptions.

I am not even going to try to guess what the problem is until you update the original question with your current code.
Member 13922009 9-Sep-19 9:23am    
Thank you, I just solved that warning. I change nlopt to Win32 from 64x platform using cmake. I did it because because win32 platform is used in my program. I follow your advice on my objective function "myfunction" and "myconstraint". Thank you for helping me. :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900