首页 > 解决方案 > 转换 CppAD::ADcpp翻倍

问题描述

我将 CppAD 与 Ipopt 一起使用。在某些地方,我必须将 AD 格式转换为其基本格式,即双倍。我使用了 CppAD::Value(AD var) 它以双格式输出。

但考虑到第 27 行,代码在编译期间是可以的。它在运行时显示以下错误。错误是:

cppad-20160000.1 error from a known source:
Value: argument is a variable (not a parameter)
Error detected by false result for
    Parameter(x)
at line 89 in the file 
    /usr/include/cppad/local/value.hpp

我附上了我正在运行以进行验证的代码。请帮忙。请在运行代码之前安装 Ipopt。

值的类型仍然是 CppAD::AD 。但是 Value() 不起作用。

#include <cppad/ipopt/solve.hpp>
#include <iostream>
namespace {
     using CppAD::AD;

     class FG_eval {
     public:
          typedef CPPAD_TESTVECTOR( AD<double> ) ADvector;
          void operator()(ADvector& fg, const ADvector& x)
          {     assert( fg.size() == 3 );
               assert( x.size()  == 4 );

               // Fortran style indexing
               AD<double> x1 = x[0];
               AD<double> x2 = x[1];
               AD<double> x3 = x[2];
               AD<double> x4 = x[3];
               // f(x)
               fg[0] = x1 * x4 * (x1 + x2 + x3) + x3;
               // g_1 (x)
               fg[1] = x1 * x2 * x3 * x4;
               // g_2 (x)
               fg[2] = x1 * x1 + x2 * x2 + x3 * x3 + x4 * x4;
              // help on this line
               std::cout << CppAD::Value(x1) << std::endl;
               //
               return;
          }
     };
}

bool get_started()
{     bool ok = true;
     size_t i;
     typedef CPPAD_TESTVECTOR( double ) Dvector;

     // number of independent variables (domain dimension for f and g)
     size_t nx = 4;
     // number of constraints (range dimension for g)
     size_t ng = 2;
     // initial value of the independent variables
     Dvector xi(nx);
     xi[0] = 1.0;
     xi[1] = 5.0;
     xi[2] = 5.0;
     xi[3] = 1.0;
     // lower and upper limits for x
     Dvector xl(nx), xu(nx);
     for(i = 0; i < nx; i++)
     {     xl[i] = 1.0;
          xu[i] = 5.0;
     }
     // lower and upper limits for g
     Dvector gl(ng), gu(ng);
     gl[0] = 25.0;     gu[0] = 1.0e19;
     gl[1] = 40.0;     gu[1] = 40.0;

     // object that computes objective and constraints
     FG_eval fg_eval;

     // options
     std::string options;
     // turn off any printing
     options += "Integer print_level  0\n";
     options += "String  sb           yes\n";
     // maximum number of iterations
     options += "Integer max_iter     10\n";
     // approximate accuracy in first order necessary conditions;
     // see Mathematical Programming, Volume 106, Number 1,
     // Pages 25-57, Equation (6)
     options += "Numeric tol          1e-6\n";
     // derivative testing
     options += "String  derivative_test            second-order\n";
     // maximum amount of random pertubation; e.g.,
     // when evaluation finite diff
     options += "Numeric point_perturbation_radius  0.\n";

     // place to return solution
     CppAD::ipopt::solve_result<Dvector> solution;

     // solve the problem
     CppAD::ipopt::solve<Dvector, FG_eval>(
          options, xi, xl, xu, gl, gu, fg_eval, solution
     );
     //
     // Check some of the solution values
     //
     ok &= solution.status == CppAD::ipopt::solve_result<Dvector>::success;
     //
     double check_x[]  = { 1.000000, 4.743000, 3.82115, 1.379408 };
     double check_zl[] = { 1.087871, 0.,       0.,      0.       };
     double check_zu[] = { 0.,       0.,       0.,      0.       };
     double rel_tol    = 1e-6;  // relative tolerance
     double abs_tol    = 1e-6;  // absolute tolerance
     for(i = 0; i < nx; i++)
     {     ok &= CppAD::NearEqual(
               check_x[i],  solution.x[i],   rel_tol, abs_tol
          );
          ok &= CppAD::NearEqual(
               check_zl[i], solution.zl[i], rel_tol, abs_tol
          );
          ok &= CppAD::NearEqual(
               check_zu[i], solution.zu[i], rel_tol, abs_tol
          );
     }

     return ok;
}

int main()
{
    get_started();
    return 0;
}

cmakelists.txt

cmake_minimum_required(VERSION 3.5)
project(jnk)

add_compile_options(-std=c++11)
add_executable(${PROJECT_NAME} testCppAD.cpp)

target_link_libraries(${PROJECT_NAME}
   ipopt z uv
 )

标签: c++

解决方案


我找到了答案。在使用 CppAD::Value() 之前,我们必须使用内置函数 CppAD::Var2Par()。将工作。


推荐阅读