天道酬勤,学无止境

由于 scipy SLSQP 中不受约束的数学域错误最小化(Math domain error due to disrespected constraint in scipy SLSQP minimize)

问题

考虑一个简单的问题:

max log(x)
subject to x >= 1e-4

scipy.optimize.minimize解决问题:

import numpy as np
from scipy.optimize import minimize
from math import log

def func(x):
    return log(x[0])

def func_deriv(x):
    return np.array([1 / x[0]])

cons = ({'type': 'ineq',
         'fun' : lambda x: x[0] - 1e-4,
         'jac' : lambda x: np.array([1])})
minimize(func, [1.0], jac=func_deriv, constraints=cons, method='SLSQP')

该脚本遇到ValueError是因为log(x)的计算结果为负x 。 即使不满足约束,函数值似乎也会被评估。

我知道在minimize()中使用bounds可以避免这个问题,但这只是我原来问题的简化。 在我的原始问题中,约束x >= 1e-4不能轻易表示为x边界,而是g(x) >= C ,因此bounds无济于事。

回答1

如果我们只关心x > ε的函数值,就可以定义一个扩展域的安全函数。

log功能为例。 可以用另一个三次函数扩展log ,同时使桥点 ε 平滑:

safe_log(x) = log(x) if x > ε else a * (x - b)**3

要计算ab ,我们必须满足:

log(ε) = a * (ε - b)**3
1 / ε = 3 * a * (ε - b)**2

因此,safe_log 函数:

eps = 1e-3

def safe_log(x):
    if x > eps:
        return log(x)
    logeps = log(eps)
    a = 1 / (3 * eps * (3 * logeps * eps)**2)
    b = eps * (1 - 3 * logeps)
    return a * (x - b)**3

它看起来像这样:

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Scipy 最小化约束函数(Scipy minimize constrained function)
    问题 我正在解决以下优化问题: 使用此 Python 代码: from scipy.optimize import minimize import math def f(x): return math.log(x[0]**2 + 1) + x[1]**4 + x[0]*x[2] x0 = [0, 0, 0] cons=({'type': 'ineq', 'fun': lambda x: x[0]**3 - x[1]**2 - 1}, {'type': 'ineq', 'fun': lambda x: x[0]}, {'type': 'ineq', 'fun': lambda x: x[2]}) res = minimize(f, x0, constraints=cons) print res 我收到一个错误 消息:'不等式约束不兼容' 什么会导致此错误? 回答1 问题似乎与您最初的猜测有关。 如果我将您的起始值更改为 x0 = [1.0, 1.0, 1.0] 然后你的代码会执行得很好(至少在我的机器上) Python 3.5.1 (v3.5.1:37a07cee5969, 2015 年 12 月 6 日,01:54:25) [MSC v.1900 64 位 (AMD64)] 在 win32 上 message: 'Optimization terminated
  • Scipy.optimize:如何限制参数值(Scipy.optimize: how to restrict argument values)
    问题 我正在尝试使用scipy.optimize函数来查找带有多个参数的复杂函数的全局最小值。 scipy.optimize.minimize似乎最能完成所有工作,即“ Nelder-Mead”方法。 但是,它倾向于去到参数域之外的区域(为只能为正数的参数赋负值),因此在这种情况下会返回错误。 有没有办法在scipy.optimize.minimize函数本身内限制参数的范围? 或者也许在其他scipy.optimize函数之内? 我发现以下建议: 当参数超出允许范围时,返回一个巨大的数字(与要拟合的数据相去甚远)。 这将(希望地)对这种参数选择造成curve_fit , curve_fit将以其他一些可允许的最佳参数集为基础。 在先前的答案中给出,但是在我的情况下,该过程将需要大量的计算时间。 回答1 Nelder-Mead解算器不支持约束优化,但是还有其他几个可以。 TNC和L-BFGS-B都仅支持绑定约束(例如x[0] >= 0 ),这对于您的情况应该是合适的。 COBYLA和SLSQP更加灵活,支持范围,基于等式和基于不等式的约束的任意组合。 您可以通过查看独立函数的文档找到有关求解器的更多详细信息,例如scipy.optimize.fmin_slsqp for method='SLSQP' 。 您可以在这里看到我以前的答案,以获取使用SLSQP进行约束优化的示例。 回答2
  • 使用 PCA 时出现数学域错误(math domain error while using PCA)
    问题 我正在使用 python 的 scikit-learn 包来实现 PCA。我正在学习数学 domain error : C:\Users\Akshenndra\Anaconda2\lib\site-packages\sklearn\decomposition\pca.pyc in _assess_dimension_(spectrum, rank, n_samples, n_features) 78 for j in range(i + 1, len(spectrum)): 79 pa += log((spectrum[i] - spectrum[j]) * ---> 80 (1. / spectrum_[j] - 1. / spectrum_[i])) + log(n_samples) 81 82 ll = pu + pl + pv + pp - pa / 2. - rank * log(n_samples) / 2. ValueError: math domain error 我已经知道当我们取负数的对数时会导致数学域错误,但我在这里不明白对数中怎么会有负数? 因为此代码适用于其他数据集。 也许这与 sci-kitlearn 网站上写的内容有关-“此实现使用奇异值分解的 scipy.linalg 实现。它仅适用于密集数组,不能扩展到大维数据。”(有大0 值的数量) 回答1
  • 带有线性约束的Scipy.optimize.minimize SLSQP失败(Scipy.optimize.minimize SLSQP with linear constraints fails)
    问题 考虑以下(凸)优化问题: minimize 0.5 * y.T * y s.t. A*x - b == y 其中优化(向量)变量是x和y而A , b分别是适当尺寸的矩阵和向量。 下面的代码使用Scipy的SLSQP方法轻松找到解决方案: import numpy as np from scipy.optimize import minimize # problem dimensions: n = 10 # arbitrary integer set by user m = 2 * n # generate parameters A, b: np.random.seed(123) # for reproducibility of results A = np.random.randn(m,n) b = np.random.randn(m) # objective function: def obj(z): vy = z[n:] return 0.5 * vy.dot(vy) # constraint function: def cons(z): vx = z[:n] vy = z[n:] return A.dot(vx) - b - vy # constraints input for SLSQP: cons = ({'type': 'eq','fun': cons}) #
  • 使用优化模块的 Scipy 错误。 将数组转换为 Fortran 失败(Scipy error using optimization module. Failure converting array to fortran)
    问题 尝试使用 scipy 的优化模块来查找使用 slsqp 的函数的最小值,但我遇到了一些问题。 调用该函数的实际代码如下所示: def minimizeWebEnergyLost(x, parameters): """values = [theta, velocity]""" firstTerm = lambda values: (x * values[1]**2 / 2.0) sqrtTerm = lambda values: np.sqrt((parameters.gravity**2 * x**2) / (4 * values[1]**4 * np.cos(values[0])**4) + 1) secondTerm = lambda values: (values[1]**4 * np.cos(values[0])**2) / parameters.gravity arcsinhTerm = lambda values: np.arcsinh((parameters.gravity * x) / (2 * values[1]**2 * np.cos(values[0])**2)) costFunction = lambda values: firstTerm(values)*sqrtTerm(values)+secondTerm(values)*arcsinhTerm
  • Python Scipy Optimization.minimize 使用 SLSQP 显示最大化结果(Python Scipy Optimization.minimize using SLSQP showing maximized results)
    问题 我正在学习使用scipy.optimize.minimize优化多变量约束非线性问题,但收到了奇怪的结果。 我的问题: minimize objfun objfun x*y constraints 0<=x<=5, 0<=y<=5, x+y==5 我的代码: from scipy import optimize def func(x): return x[0]*x[1] bnds=((0,100),(0,5)) cons=({'type':'eq','fun':lambda x:x[0]+x[1]-5}) x0=[0,0] res= optimize.minimize(func,x0,method='SLSQP',bounds=bnds,constraints=cons) 收到的结果: status: 0 success: True njev: 2 nfev: 8 fun: 6.2499999999999991 x: array([ 2.5, 2.5]) message: 'Optimization terminated successfully.' jac: array([ 2.5, 2.5, 0. ]) nit: 2 我期待乐趣为 0 或显着接近 0 并且 x 或 y 为 0 回答1 我认为您遇到了边缘情况。 如果您尝试不对称的猜测,则会收敛到正确的解决方案。 只需将x0
  • Python约束的非线性优化(Python constrained non-linear optimization)
    问题 python中受约束的非线性优化的推荐软件包是什么? 我要解决的特定问题是这样的: 我有一个未知的X (NX1),我M (NX1) u矢量和M (N×N个) s矩阵。 max [5th percentile of (ui_T*X), i in 1 to M] st 0<=X<=1 and [95th percentile of (X_T*si*X), i in 1 to M]<= constant 当我开始讨论问题时,我对u和s估计只有一点,因此我可以使用cvxpy解决上述问题。 我意识到,我没有对u和s进行一次估计,而是拥有值的整个分布,因此我想更改目标函数,以便可以使用整个分布。 上面的问题描述是我试图以有意义的方式包括该信息。 cvxpy不能用来解决这个问题,我已经尝试过scipy.optimize.anneal ,但是我似乎无法为未知值设置界限。 我也看过pulp但它不允许非线性约束。 回答1 scipy具有用于约束非线性优化的引人注目的软件包。 您可以通过阅读optimize文档来开始使用,但这是SLSQP的示例: minimize(func, [-1.0,1.0], args=(-1.0,), jac=func_deriv, constraints=cons, method='SLSQP', options={'disp': True}) 回答2
  • Scipy fmin_slsqp错误“将_slsqp.slsqp的第8个参数'g'转换为C / Fortran数组失败”(Scipy fmin_slsqp error “failed in converting 8th argument `g' of _slsqp.slsqp to C/Fortran array”)
    问题 我已经看过这个问题或在其他地方问过一个变体,例如 使用优化模块的Scipy错误。 无法将数组转换为fortran http://numpy-discussion.10968.n7.nabble.com/minimize-Algorithmen-Problem-with-boundarys-td37709.html 但是,它们并没有真正带有简单的可破解示例代码。 也没有任何真正的答案(可能是由于缺少问题的简单演示)。 问题是,当尝试使用scipy.optimise fmin_slsqp方法拟合函数时,您会得到此相当不透明的错误 “未能将_slsqp.slsqp的第8个参数'g'转换为C / Fortran数组” 在下面的代码中,我使用Minimumsq方法将线性函数拟合到随机相关数据。 从.docs文件中,我看不出使用fmin_slsqp进行相同语法不应执行相同操作的理由,但事实并非如此。 有人知道为什么吗? import numpy as nm from scipy.optimize import leastsq, fmin_slsqp import matplotlib.pyplot as plt # residuals of linear function def res(params,x,y_real): y_fit = params[0] +x*params[1]
  • Math domain error due to disrespected constraint in scipy SLSQP minimize
    Consider a simple problem: max log(x) subject to x >= 1e-4 To solve the problem with scipy.optimize.minimize: import numpy as np from scipy.optimize import minimize from math import log def func(x): return log(x[0]) def func_deriv(x): return np.array([1 / x[0]]) cons = ({'type': 'ineq', 'fun' : lambda x: x[0] - 1e-4, 'jac' : lambda x: np.array([1])}) minimize(func, [1.0], jac=func_deriv, constraints=cons, method='SLSQP') The script encounters ValueError because log(x) is evaluated with negative x. It seems that the function value is evaluated even if the constraint is not satisfied. I
  • Scipy.optimize.minimize method='SLSQP' 忽略约束(Scipy.optimize.minimize method='SLSQP' ignores constraint)
    问题 我正在使用 SciPy 进行优化,而 SLSQP 方法似乎忽略了我的约束。 具体来说,我希望 x[3] 和 x[4] 在 [0-1] 范围内 我收到消息:'不等式约束不兼容' 下面是执行结果和示例代码(使用了一个虚拟函数): status: 4 success: False njev: 2 nfev: 24 fun: 0.11923608071680103 x: array([-10993.4278558 , -19570.77080806, -23495.15914299, -26531.4862831 , 4679.97660534]) message: 'Inequality constraints incompatible' jac: array([ 12548372.4766904 , 12967696.88362279, 39928956.72239509, -9224613.99092537, 3954696.30747453, 0. ]) nit: 2 这是我的代码: from random import random from scipy.optimize import minimize def func(x): """ dummy function to optimize """ print 'x'+str(x) return random() my
  • 人工智能与机器学习---线性规划和非线性规划求解
    一、线性规划 1、线性规划的概念 线性规划(Linear Programming 简记 LP)是了运筹学中数学规划的一个重要分支。自从 1947 年 G. B. Dantzig 提出 求解线性规划的单纯形法以来,线性规划在理论上趋向成熟,在实用中由于计算机能处理成千上万个约束条件和决策变量的线性规划问题之后,线性规划现代管理中经常采用的基本方法之一。 在解决实际问题时,需要把问题归结成一个线性规划数学模型,关键及难点在于选适当的决策变量建立恰当的模型,这直接影响到问题的求解。 线性规划问题的目标函数及约束条件均为线性函数;约束条件记为 s.t.(即 subject to)。目标函数可以是求最大值,也可以是求最小值,约束条件的不等号可以 是小于号也可以是大于号。 一般线性规划问题的(数学)标准型为 2、单纯形法 一般线性规划问题中当线性方程组的变量数大于方程个数,这时会有不定数量的解,而单纯形法是求解线性规划问题的通用方法。 具体步骤是,从线性方程组找出一个个的单纯形,每一个单纯形可以求得一组解,然后再判断该解使目标函数值是增大还是变小了,决定下一步选择的单纯形。通过优化迭代,直到目标函数实现最大或最小值。 换而言之,单纯形法就是秉承“保证每一次迭代比前一次更优”的基本思想:先找出一个基本可行解,对它进行鉴别,看是否是最优解;若不是,则按照一定法则转换到另一改进后更优的基本可行解
  • 如何在有约束的scipy中使用最小化函数(How do I use a minimization function in scipy with constraints)
    问题 我需要有关python(scipy)中优化函数的一些帮助,问题是优化f(x) ,其中x=[a,b,c...n] 。 约束条件是a,b等的值应介于0和1之间,并且sum(x)==1 。 scipy.optimise.minimize函数似乎最好,因为它不需要差异。 如何传递参数? 使用置换创建ndarray太长。 我现在的代码如下: import itertools as iter all=iter.permutations([0.0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1.0],6) if sum==1 all_legal=[] for i in all: if np.sum(i)==1: #print np.sum(i) all_legal.append(i) print len(all_legal) lmax=0 sharpeMax=0 for i in all_legal: if sharpeMax<getSharpe(i): sharpeMax=getSharpe(i) lmax=i 回答1 您可以按照文档中的说明使用COBYLA或SLSQP进行约束优化。 from scipy.optimize import minimize start_pos = np.ones(6)*(1/6.) #or whatever #Says one minus the
  • math.log 函数中的 python 数学域错误(python math domain errors in math.log function)
    问题 我必须使用 Python math.log(x)函数和来自 (0, ..., 1) 的x值。 有时 x 可能太接近于零,Python 给我一个错误: ValueError:数学域错误 我怎么知道math.log函数的定义域是什么? 回答1 只要您的输入在半开区间 (0, 1] (不包括 0) 内,您就可以。您不能太接近零: >>> math.log(sys.float_info.min) -708.3964185322641 因此,只需检查零(可能是下溢的结果)就足够了,或者捕获异常并处理它。 编辑:这也适用于非正规最小浮点数: >>> math.log(sys.float_info.min * sys.float_info.epsilon) -744.4400719213812 回答2 您正在检查支持的精度,请改用 Decimal 类。 >>> from math import log >>> from decimal import Decimal >>> d = Decimal('1E-1024') >>> log(d) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: math domain error >>> d.ln() Decimal('-2357
  • ValueError:数学域错误(ValueError: math domain error)
    问题 我只是从“使用Python进行工程中的数值方法”中测试一个示例。 from numpy import zeros, array from math import sin, log from newtonRaphson2 import * def f(x): f = zeros(len(x)) f[0] = sin(x[0]) + x[1]**2 + log(x[2]) - 7.0 f[1] = 3.0*x[0] + 2.0**x[1] - x[2]**3 + 1.0 f[2] = x[0] + x[1] + x[2] -5.0 return f x = array([1.0, 1.0, 1.0]) print newtonRaphson2(f,x) 当我运行它时,它显示以下错误: File "example NR2method.py", line 8, in f f[0] = sin(x[0]) + x[1]**2 + log(x[2]) - 7.0 ValueError: math domain error 我将其范围缩小到日志,因为当我删除日志并添加其他功能时,它可以工作。 我认为这是由于对底座的某种干扰,我不知道怎么做。 有人可以提出解决方案吗? 回答1 您的代码正在log小于或等于零的数字。 从数学上来说这是未定义的,因此Python的log函数会引发异常。
  • scipy.optimize 与非线性约束(scipy.optimize with non linear constraints)
    问题 我有非线性约束的非线性函数,我想优化它。 我不知道如何使用 scipy.optimize 定义非线性约束。 到目前为止,我的代码如下所示: from math import cos, atan import numpy as np from scipy.optimize import minimize import sympy as sy def f(x): return 0.1*x*y def ineq_constraint(x): x**2 + y**2 - (5+2.2*sy.cos(10*sy.atan(x/y)))**2 return x,y con = {'type': 'ineq', 'fun': ineq_constraint} minimize(f,x0,method='SLSQP',constraints=con) 回答1 代码有一些小问题; 这是修改后的版本(解释如下): from math import cos, atan import numpy as np from scipy.optimize import minimize def f(x): return 0.1 * x[0] * x[1] def ineq_constraint(x): return x[0]**2 + x[1]**2 - (5. + 2.2 * cos(10 * atan
  • 为什么无符号整数在PostgreSQL中不可用?(Why unsigned integer is not available in PostgreSQL?)
    问题 我碰到了这篇文章(MySQL中tinyint,smallint,mediumint,bigint和int有什么区别?),并且意识到PostgreSQL不支持无符号整数。 谁能帮忙解释为什么会这样吗? 大多数时候,我在MySQL中使用无符号整数作为自动递增的主键。 在这样的设计中,当我将数据库从MySQL移植到PostgreSQL时,如何克服这个问题? 谢谢。 回答1 已经回答了为什么postgresql缺少无符号类型的问题。 但是,我建议对无符号类型使用域。 http://www.postgresql.org/docs/9.4/static/sql-createdomain.html CREATE DOMAIN name [ AS ] data_type [ COLLATE collation ] [ DEFAULT expression ] [ constraint [ ... ] ] where constraint is: [ CONSTRAINT constraint_name ] { NOT NULL | NULL | CHECK (expression) } 域就像一种类型,但有附加的约束。 作为一个具体的例子,您可以使用 CREATE DOMAIN uint2 AS int4 CHECK(VALUE >= 0 AND VALUE < 65536)
  • 具有跨约束共享值的复杂 scipy 优化(Complex scipy optimization with shared values across constraints)
    问题 我正在尝试使用 Python 和 scipy.optimize 库实现结构优化代码。 目标是最小化结构的重量,对于各种材料应力和破坏条件有 5 个不等式约束。 我的计划是使用 COBYLA 或 SLSQP 方法。 我过去使用 scipy 做过一些优化代码,但它们都是设计变量的相当简单的函数(很像官方 scipy 文档中的教程)。 我似乎无法解决这个问题的是,所有约束函数都有些相互依赖。 我创建了一个包含一堆无关数据(材料属性、载荷、常量几何参数、辅助函数...)的类,这些数据将作为额外参数传递给目标函数和约束函数。 我的问题围绕着何时调用辅助函数来计算用于评估约束的几个参数。 当 scipy.optimize 将外部参数传递给目标和约束函数时,它是对象的单个实例吗? 还是为每个函数制作 n 个副本? 优化模块是否在评估目标函数之前评估约束? 优化模块是并行评估约束还是从 0 到 n 按顺序通过它们? 我是否可以调用 helperclass.updateSharedValues() 一次(例如,在第一个约束函数或目标函数中)并让所有其他约束函数都可以访问新值? 还是我需要在每个约束函数中调用它? 这是一些伪代码来帮助解释我在做什么: """ inside the main script that calls scipy.optimize """ cons =({'type':
  • 使用math.acos函数的Python数学域错误(Python math domain error using math.acos function [closed])
    问题 关门了。 这个问题需要细节或明确性。 它当前不接受答案。 想要改善这个问题吗? 添加详细信息,并通过编辑此帖子来澄清问题。 5年前关闭。 改善这个问题 我正在使用math.acos()函数: math.acos(1.0000000000000002) 这将引发数学域错误。 有人可以说出原因吗? 我正在获取此值之前计算过的值,在这里此值会产生错误,但是如果我最后删除2,则不会抛出错误。 我没有得到这个原因。 回答1 您正在尝试执行acos数量不存在的acos 。 Acos - Arccosine , which is the inverse of cosine function. acos的输入值的范围是-1 <= x <= 1 。 因此,尝试执行math.acos(1.0000000000000002)您会收到错误消息。 如果您尝试使用更大的数字,则将不断遇到相同的错误math.acos(2) -导致math.acos(2) ValueError: math domain error 回答2 反余弦仅定义在-1和1之间(包括-1和1)。 1.0000000000000002的反余弦除了“不存在”或“未定义”外,没有数学或语义含义。 当然,因为确实存在1的反余弦,所以acos(1)不会引发任何错误。
  • Scipy的“优化曲线拟合极限”(Scipy's Optimize Curve Fit Limits)
    问题 有什么方法可以为Scipy的“优化曲线拟合”提供限制吗? 我的例子: def optimized_formula(x, m_1, m_2, y_1, y_2, ratio_2): return (log(x[0]) * m_1 + m_2)*((1 - x[1]/max_age)*(1-ratio_2)) + ((log(x[1]) * y_1 + y_2)*(x[1]/max_age)*ratio_2) popt, pcov = optimize.curve_fit(optimized_formula, usage_and_age, prices) x [0]是age,max_age是常数。 考虑到这一点,当x [0]接近最大值时,x [1] / max_age接近1。 是否可以提供一个约束/限制,从而x [1] / max_age> 0.3和x [1] / max_age <0.7以及其他约束,例如m_1 <0,m_2> 0,依此类推。 回答1 如另一个答案中所建议,您可以将lmfit用于此类问题。 因此,我还添加了一个有关如何使用它的示例,以防有人对此主题感兴趣。 假设您有一个数据集,如下所示: xdata = np.array([177.,180.,183.,187.,189.,190.,196.,197.,201.,202.,203.,204.,206.,218
  • 对于不可行的 NLP,Scipy.optimize 成功终止(Scipy.optimize terminates successfully for infeasible NLP)
    问题 尝试使用 scipy.optimize SLSQP 解决 NLP。 这个问题显然是不可行的,但 scipy.optimize 中的最小化函数似乎不同意。 minimize X^2 + Y^2 subject to X + Y = 11 X, Y >= 6 编码: from scipy.optimize import minimize def obj(varx): return varx[1]**2 + varx[0]**2 def constr1(varx): constr1 = -varx[0]-varx[1]+11 return constr1 bnds = [(6,float('Inf')),(6,float('Inf'))] ops = ({'maxiter':100000, 'disp':'bool'}) cons = ({'type':'eq', 'fun':constr1}) res = minimize(obj, x0=[7,7], method='SLSQP', constraints = cons, bounds = bnds, options = ops) print res.x print res.success 输出: Optimization terminated successfully. (Exit mode 0) Current