diff --git a/.DS_Store b/.DS_Store
index 6992d9a..39ebc78 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/README.md b/README.md
index 8393f4b..004f836 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
# Robust Stochastic Optimization Made Easy
@@ -13,7 +13,7 @@
![GitHub issues](https://img.shields.io/github/issues-raw/XiongPengNUS/rsome)
- Website: [RSOME for Python](https://xiongpengnus.github.io/rsome/)
-- PyPI: [RSOME 1.2.5](https://pypi.org/project/rsome/)
+- PyPI: [RSOME 1.2.6](https://pypi.org/project/rsome/)
RSOME (Robust Stochastic Optimization Made Easy) is an open-source Python package for generic modeling of optimization problems (subject to uncertainty). Models in RSOME are constructed by variables, constraints, and expressions that are formatted as N-dimensional arrays. These arrays are consistent with the NumPy library in terms of syntax and operations, including broadcasting, indexing, slicing, element-wise operations, and matrix calculation rules, among others. In short, RSOME provides a convenient platform to facilitate developments of robust optimization models and their applications.
diff --git a/rsome/cpt_solver.py b/rsome/cpt_solver.py
index 22571e9..760ca06 100644
--- a/rsome/cpt_solver.py
+++ b/rsome/cpt_solver.py
@@ -34,9 +34,7 @@ def solve(form, display=True, log=False, params={}):
try:
if xmat:
- warnings.warn('The SOCP solver ignores exponential cone constraints. ')
- # if lmi:
- # warnings.warn('The SOCP solver ignores semidefinite cone constraints. ')
+ warnings.warn('The conic solver ignores exponential cone constraints. ')
except AttributeError:
pass
@@ -52,14 +50,15 @@ def solve(form, display=True, log=False, params={}):
linear_ineq = form.linear[~is_eq]
linear_eq = form.linear[is_eq]
num_ineq = linear_ineq.shape[0]
- # num_eq = linear_eq.shape[0]
const_ineq = form.const[~is_eq]
const_eq = form.const[is_eq]
num_constr, num_var = form.linear.shape
- env = cp.Envr()
+ envconfig = cp.EnvrConfig()
+ envconfig.set('nobanner', '1')
+ env = cp.Envr(envconfig)
m = env.createModel()
m.setParam(cp.COPT.Param.Logging, log)
m.setParam(cp.COPT.Param.LogToConsole, False)
@@ -149,7 +148,14 @@ def solve(form, display=True, log=False, params={}):
else:
y = None
- solution = Solution('COPT', objval, x_sol, status, stime, y=y)
+ xx_sol = np.zeros(len(form.vtype))
+ xx_sol[idx_cont] = x_sol[:len(idx_cont)]
+ if idx_bin:
+ xx_sol[idx_bin] = x_sol[len(idx_cont): len(idx_cont)+len(idx_bin)]
+ if idx_int:
+ xx_sol[idx_int] = x_sol[len(idx_cont)+len(idx_bin):]
+
+ solution = Solution('COPT', objval, xx_sol, status, stime, y=y)
except cp.CoptError:
warnings.warn('Fail to find the optimal solution.')
# solution = None
diff --git a/rsome/gcp.py b/rsome/gcp.py
index b811a9e..feb6439 100644
--- a/rsome/gcp.py
+++ b/rsome/gcp.py
@@ -543,6 +543,7 @@ def to_socp(self, degree=4, cuts=(-30, 60)):
left_width = self.linear.shape[1]
qmat = self.qmat
+ lmi = self.lmi
linear = self.linear
const = self.const
@@ -570,4 +571,5 @@ def to_socp(self, degree=4, cuts=(-30, 60)):
qmat += [list(left_width + num_vars + np.array([2, 1, 0]) + q*3)
for q in range(3+degree)]
- return SOCProg(linear, const, sense, vtype, ub, lb, qmat, obj)
+ # return SOCProg(linear, const, sense, vtype, ub, lb, qmat, obj)
+ return GCProg(linear, const, sense, vtype, ub, lb, qmat, [], lmi, obj)
diff --git a/rsome/lp.py b/rsome/lp.py
index 0c40cc5..54a65a6 100644
--- a/rsome/lp.py
+++ b/rsome/lp.py
@@ -137,20 +137,20 @@ def concat(iters, axis=0):
"""
Join a sequence of arrays of affine expressions along an existing axis.
- Parameters
- ----------
- iters : array_like.
- A sequence of RSOME variables or affine expressions. The arrays must
- have the same shape, except in the dimension corresponding to `axis`
- (the first, by default).
+ Parameters
+ ----------
+ iters : array_like.
+ A sequence of RSOME variables or affine expressions. The arrays must
+ have the same shape, except in the dimension corresponding to `axis`
+ (the first, by default).
- axis : int, optional
- The axis along which the arrays will be joined. Default is 0.
+ axis : int, optional
+ The axis along which the arrays will be joined. Default is 0.
- Returns
- -------
- out : Affine
- The concatenated array of affine expressions.
+ Returns
+ -------
+ out : Affine
+ The concatenated array of affine expressions.
"""
linear_each = []
@@ -226,24 +226,24 @@ def rstack(*args):
"""
Stack a sequence of rows of affine expressions vertically (row wise).
- Parameters
- ----------
- arg : {list, Affine}.
- Each arg represents an array of affine expressions. If arg is a list
- of affine expressions, they will be concatenated horizontally (column
- wise) first.
+ Parameters
+ ----------
+ arg : {list, Affine}.
+ Each arg represents an array of affine expressions. If arg is a list
+ of affine expressions, they will be concatenated horizontally (column
+ wise) first.
- Returns
- -------
- out : Affine
- The vertically stacked array of affine expressions.
+ Returns
+ -------
+ out : Affine
+ The vertically stacked array of affine expressions.
- Notes
- -----
- The rstack function is different from the vstack function from the numpy
- package in 1) the arrays to be stacked together are presented as separate
- arguments, instead of elements in an array-like sequence; and 2) a list of
- arrays can be stacked horizontally first before being vertically stacked.
+ Notes
+ -----
+ The rstack function is different from the vstack function from the numpy
+ package in 1) the arrays to be stacked together are presented as separate
+ arguments, instead of elements in an array-like sequence; and 2) a list of
+ arrays can be stacked horizontally first before being vertically stacked.
"""
rows = []
@@ -260,24 +260,23 @@ def cstack(*args):
"""
Stack a sequence of rows of affine expressions horizontally (column wise).
- Parameters
- ----------
- arg : {list, Affine}.
- Each arg represents an array of affine expressions. If arg is a list
- of affine expressions, they will be concatenated vertically (row wise)
- first.
+ Parameters
+ ----------
+ arg : {list, Affine}.
+ Each arg represents an array of affine expressions. If arg is a list of
+ affine expressions, they will be concatenated vertically (row wise) first.
- Returns
- -------
- out : Affine
- The horizontally stacked array of affine expressions.
+ Returns
+ -------
+ out : Affine
+ The horizontally stacked array of affine expressions.
- Notes
- -----
- The cstack function is different from the hstack function from the numpy
- package in 1) the arrays to be stacked together are presented as separate
- arguments, instead of elements in an array-like sequence; and 2) a list of
- arrays can be stacked vertically first before being horizontally stacked.
+ Notes
+ -----
+ The cstack function is different from the hstack function from the numpy
+ package in 1) the arrays to be stacked together are presented as separate
+ arguments, instead of elements in an array-like sequence; and 2) a list of
+ arrays can be stacked vertically first before being horizontally stacked.
"""
cols = []
@@ -847,22 +846,72 @@ def get_ind(self):
return np.array(range(self.first, self.first + self.size))
def reshape(self, shape):
+ """
+ Returns an array containing the same variables with a new shape.
+
+ Parameters
+ ----------
+ shape : tuple
+ The new shape of the returned array.
+
+ Returns
+ -------
+ out : Affine
+ An array of the specified shape containing the given variables.
+ """
return self.to_affine().reshape(shape)
def flatten(self):
+ """
+ Returns a 1D array containing the same variables.
+
+ Returns
+ -------
+ out : Affine
+ A 1D array of the given variables.
+ """
return self.to_affine().flatten()
def diag(self, k=0, fill=False):
+ """
+ Return the diagonal elements of a 2-D array.
+
+ Refer to `rsome.math.diag` for full documentation.
+
+ See Also
+ --------
+ rsome.math.diag : equivalent function
+ """
return self.to_affine().diag(k, fill)
def tril(self, k=0):
+ """
+ Return the lower triangular elements of a 2-D array. The remaining
+ elements are filled with zeros.
+
+ Refer to `rsome.math.tril` for full documentation.
+
+ See Also
+ --------
+ rsome.math.tril : equivalent function
+ """
return self.to_affine().tril(k)
def triu(self, k=0):
+ """
+ Return the upper triangular elements of a 2-D array. The remaining
+ elements are filled with zeros.
+
+ Refer to `rsome.math.triu` for full documentation.
+
+ See Also
+ --------
+ rsome.math.triu : equivalent function
+ """
return self.to_affine().triu(k)
@@ -874,11 +923,11 @@ def norm(self, degree):
"""
Return the first, second, or infinity norm of a 1-D array.
- Refer to `rsome.norm` for full documentation.
+ Refer to `rsome.math.norm` for full documentation.
See Also
--------
- rso.norm : equivalent function
+ rsome.math.norm : equivalent function
"""
return self.to_affine().norm(degree)
@@ -887,11 +936,11 @@ def square(self):
"""
Return the element-wise square of an array.
- Refer to `rsome.square` for full documentation
+ Refer to `rsome.math.square` for full documentation
See Also
--------
- rso.square : equivalent function
+ rsome.lp.square : equivalent function
"""
return self.to_affine().square()
@@ -900,11 +949,11 @@ def sumsqr(self):
"""
Return the sum of squares of a 1-D array.
- Refer to `rsome.sumsqr` for full documentation.
+ Refer to `rsome.math.sumsqr` for full documentation.
See Also
--------
- rso.sumsqr : equivalent function
+ rsome.math.sumsqr : equivalent function
"""
return self.to_affine().sumsqr()
@@ -913,11 +962,11 @@ def quad(self, qmat):
"""
Return the quadratic expression var @ qmat @ var.
- Refer to `rsome.quad` for full documentation.
+ Refer to `rsome.math.quad` for full documentation.
See Also
--------
- rso.quad : equivalent function
+ rsome.math.quad : equivalent function
"""
return self.to_affine().quad(qmat)
@@ -926,11 +975,11 @@ def rsocone(self, y, z):
"""
Return the rotated second-order cone constraint.
- Refer to `rsome.rsocone` for full documentation.
+ Refer to `rsome.math.rsocone` for full documentation.
See Also
--------
- rso.rsocone : equivalent function
+ rsome.math.rsocone : equivalent function
"""
return self.to_affine().rsocone(y, z)
@@ -939,11 +988,11 @@ def expcone(self, x, z):
"""
Return the exponential cone constraint z*exp(x/z) <= var.
- Refer to `rsome.expcone` for full documentation.
+ Refer to `rsome.math.expcone` for full documentation.
See Also
--------
- rso.expcone : equivalent function
+ rsome.math.expcone : equivalent function
"""
return self.to_affine().expcone(x, z)
@@ -952,11 +1001,11 @@ def exp(self):
"""
Return the natural exponential function exp(var).
- Refer to `rsome.exp` for full documentation.
+ Refer to `rsome.math.exp` for full documentation.
See Also
--------
- rso.exp : equivalent function
+ rsome.math.exp : equivalent function
"""
return self.to_affine().exp()
@@ -966,11 +1015,11 @@ def pexp(self, scale):
Return the perspective natural exponential function
scale * exp(var/scale).
- Refer to `rsome.pexp` for full documentation.
+ Refer to `rsome.math.pexp` for full documentation.
See Also
--------
- rso.pexp : equivalent function
+ rsome.math.pexp : equivalent function
"""
return self.to_affine().pexp(scale)
@@ -979,11 +1028,11 @@ def log(self):
"""
Return the natural logarithm function log(var).
- Refer to `rsome.log` for full documentation.
+ Refer to `rsome.math.log` for full documentation.
See Also
--------
- rso.log : equivalent function
+ rsome.math.log : equivalent function
"""
return self.to_affine().log()
@@ -993,11 +1042,11 @@ def plog(self, scale):
Return the perspective of natural logarithm function
scale * log(var/scale).
- Refer to `rsome.plog` for full documentation.
+ Refer to `rsome.math.plog` for full documentation.
See Also
--------
- rso.plog : equivalent function
+ rsome.math.plog : equivalent function
"""
return self.to_affine().plog(scale)
@@ -1006,11 +1055,11 @@ def entropy(self):
"""
Return the natural exponential function -sum(var*log(var)).
- Refer to `rsome.entropy` for full documentation.
+ Refer to `rsome.math.entropy` for full documentation.
See Also
--------
- rso.entropy : equivalent function
+ rsome.math.entropy : equivalent function
"""
return self.to_affine().entropy()
@@ -1019,11 +1068,11 @@ def softplus(self):
"""
Return the softplus function log(1 + exp(var)).
- Refer to `rsome.softplus` for full documentation.
+ Refer to `rsome.math.softplus` for full documentation.
See Also
--------
- rso.softplus : equivalent function
+ rsome.math.softplus : equivalent function
"""
return self.to_affine().softplus()
@@ -1032,16 +1081,25 @@ def kldiv(self, q, r):
"""
Return the KL divergence constraints sum(var*log(var/q)) <= r.
- Refer to `rsome.kldiv` for full documentation.
+ Refer to `rsome.math.kldiv` for full documentation.
See Also
--------
- rso.kldiv : equivalent function
+ rsome.math.kldiv : equivalent function
"""
return self.to_affine().kldiv(q, r)
def trace(self):
+ """
+ Return the trace of a 2D array.
+
+ Refer to `rsome.lp.trace` for full documentation.
+
+ See Also
+ --------
+ rsome.lp.rsocone : equivalent function
+ """
return self.to_affine().trace()
@@ -1384,6 +1442,21 @@ def T(self):
return Affine(self.model, linear, const)
def reshape(self, shape):
+ """
+ Returns an array containing the same affine expressions with a
+ new shape.
+
+ Parameters
+ ----------
+ shape : tuple
+ The new shape of the returned array.
+
+ Returns
+ -------
+ out : Affine
+ An array of the specified shape containing the given affine
+ expressions.
+ """
if isinstance(self.const, np.ndarray):
new_const = self.const.reshape(shape)
@@ -1392,10 +1465,27 @@ def reshape(self, shape):
return Affine(self.model, self.linear, new_const)
def flatten(self):
+ """
+ Returns a 1D array containing the same affine expressions.
+
+ Returns
+ -------
+ out : Affine
+ A 1D array of the given affine expressions.
+ """
return self.reshape((self.size, ))
def diag(self, k=0, fill=False):
+ """
+ Return the diagonal elements of a 2-D array.
+
+ Refer to `rsome.math.diag` for full documentation.
+
+ See Also
+ --------
+ rsome.math.diag : equivalent function
+ """
if len(self.shape) != 2:
raise ValueError('The diag function can only be applied to 2D arrays.')
@@ -1424,6 +1514,16 @@ def diag(self, k=0, fill=False):
return self[idx_row, idx_col]
def tril(self, k=0):
+ """
+ Return the lower triangular elements of a 2-D array. The remaining
+ elements are filled with zeros.
+
+ Refer to `rsome.math.tril` for full documentation.
+
+ See Also
+ --------
+ rsome.math.tril : equivalent function
+ """
if len(self.shape) != 2:
raise ValueError('The tril function can only be applied to 2D arrays.')
@@ -1439,6 +1539,16 @@ def tril(self, k=0):
return affine
def triu(self, k=0):
+ """
+ Return the upper triangular elements of a 2-D array. The remaining
+ elements are filled with zeros.
+
+ Refer to `rsome.math.triu` for full documentation.
+
+ See Also
+ --------
+ rsome.math.triu : equivalent function
+ """
if len(self.shape) != 2:
raise ValueError('The tril function can only be applied to 2D arrays.')
@@ -1466,6 +1576,15 @@ def sum(self, axis=None):
return Affine(self.model, linear, const)
def trace(self):
+ """
+ Return the trace of a 2D array.
+
+ Refer to `rsome.math.trace` for full documentation.
+
+ See Also
+ --------
+ rsome.math.rsocone : equivalent function
+ """
if len(self.shape) != 2:
raise ValueError('The trace function only applies to two-dimensional arrays')
@@ -1487,11 +1606,11 @@ def norm(self, degree):
"""
Return the first, second, or infinity norm of a 1-D array.
- Refer to `rsome.norm` for full documentation
+ Refer to `rsome.math.norm` for full documentation
See Also
--------
- rso.norm : equivalent function
+ rsome.math.norm : equivalent function
"""
if len(self.shape) != 1:
@@ -1513,11 +1632,11 @@ def square(self):
"""
Return the element-wise square of an array.
- Refer to `rsome.square` for full documentation
+ Refer to `rsome.math.square` for full documentation
See Also
--------
- rso.square : equivalent function
+ rsome.math.square : equivalent function
"""
size = self.size
@@ -1529,11 +1648,11 @@ def sumsqr(self):
"""
Return the sum of squares of a 1-D array.
- Refer to `rsome.sumsqr` for full documentation.
+ Refer to `rsome.math.sumsqr` for full documentation.
See Also
--------
- rso.sumsqr : equivalent function
+ rsome.math.sumsqr : equivalent function
"""
shape = self.shape
@@ -1549,11 +1668,11 @@ def quad(self, qmat):
"""
Return the quadratic expression var @ qmat @ var.
- Refer to `rsome.quad` for full documentation.
+ Refer to `rsome.math.quad` for full documentation.
See Also
--------
- rso.quad : equivalent function
+ rsome.math.quad : equivalent function
"""
if len(self.shape) != 1:
@@ -1581,11 +1700,11 @@ def rsocone(self, y, z):
"""
Return the rotated second-order cone constraint.
- Refer to `rsome.rsocone` for full documentation.
+ Refer to `rsome.math.rsocone` for full documentation.
See Also
--------
- rso.rsocone : equivalent function
+ rsome.math.rsocone : equivalent function
"""
if self.size > 1:
@@ -1623,11 +1742,11 @@ def expcone(self, x, z):
"""
Return the exponential cone constraint z*exp(x/z) <= affine.
- Refer to `rsome.expcone` for full documentation.
+ Refer to `rsome.math.expcone` for full documentation.
See Also
--------
- rso.expcone : equivalent function
+ rsome.math.expcone : equivalent function
"""
if isinstance(x, (Vars, VarSub)):
@@ -1656,11 +1775,11 @@ def exp(self):
"""
Return the natural exponential function exp(affine).
- Refer to `rsome.exp` for full documentation.
+ Refer to `rsome.math.exp` for full documentation.
See Also
--------
- rso.exp : equivalent function
+ rsome.math.exp : equivalent function
"""
return Convex(self, np.zeros(self.shape), 'X', 1)
@@ -1670,11 +1789,11 @@ def pexp(self, scale):
Return the perspective natural exponential function
scale * exp(affine/scale).
- Refer to `rsome.pexp` for full documentation.
+ Refer to `rsome.math.pexp` for full documentation.
See Also
--------
- rso.pexp : equivalent function
+ rsome.math.pexp : equivalent function
"""
return PerspConvex(self, scale, np.zeros(self.shape), 'X', 1)
@@ -1683,11 +1802,11 @@ def log(self):
"""
Return the natural logarithm function log(affine).
- Refer to `rsome.log` for full documentation.
+ Refer to `rsome.math.log` for full documentation.
See Also
--------
- rso.log : equivalent function
+ rsome.math.log : equivalent function
"""
return Convex(self, np.zeros(self.shape), 'L', -1)
@@ -1697,11 +1816,11 @@ def plog(self, scale):
Return the perspective of natural logarithm function
scale * log(affine/scale).
- Refer to `rsome.plog` for full documentation.
+ Refer to `rsome.math.plog` for full documentation.
See Also
--------
- rso.plog : equivalent function
+ rsome.math.plog : equivalent function
"""
return PerspConvex(self, scale, np.zeros(self.shape), 'L', -1)
@@ -1710,11 +1829,11 @@ def entropy(self):
"""
Return the natural exponential function -sum(affine*log(affine)).
- Refer to `rsome.entropy` for full documentation.
+ Refer to `rsome.math.entropy` for full documentation.
See Also
--------
- rso.entropy : equivalent function
+ rsome.math.entropy : equivalent function
"""
if self.shape != ():
@@ -1727,11 +1846,11 @@ def softplus(self):
"""
Return the softplus function log(1 + exp(var)).
- Refer to `rsome.softplus` for full documentation.
+ Refer to `rsome.math.softplus` for full documentation.
See Also
--------
- rso.softplus : equivalent function
+ rsome.math.softplus : equivalent function
"""
return Convex(self, np.zeros(self.shape), 'F', 1)
@@ -1740,11 +1859,11 @@ def kldiv(self, q, r):
"""
Return the KL divergence constraints sum(affine*log(affine/q)) <= r.
- Refer to `rsome.kldiv` for full documentation.
+ Refer to `rsome.math.kldiv` for full documentation.
See Also
--------
- rso.kldiv : equivalent function
+ rsome.math.kldiv : equivalent function
"""
affine = self.to_affine().reshape((self.size, ))
@@ -3609,6 +3728,15 @@ def sum(self, axis=None):
return DecAffine(self.dro_model, expr, self.event_adapt, self.fixed)
def trace(self):
+ """
+ Return the trace of a 2D array.
+
+ Refer to `rsome.lp.trace` for full documentation.
+
+ See Also
+ --------
+ rsome.lp.rsocone : equivalent function
+ """
expr = super().trace()
@@ -4817,25 +4945,14 @@ def lp_export(self):
each_line = each_line[2:]
string += ' c{}: '.format(i+1) + each_line
- string += ' <= ' if self.sense[i] == 0 else ' == '
+ string += ' <= ' if self.sense[i] == 0 else ' = '
string += '{}\n'.format(self.const[i])
ub, lb = self.ub, self.lb
nvar = len(ub)
- ub_string = '\n'.join([' x{} <= {}'.format(i+1, ub[i])
- for i in range(nvar) if ub[i] < np.inf])
- lb_string = '\n'.join([' {} <= x{}'.format(lb[i], i+1)
- for i in range(nvar) if lb[i] > -np.inf])
- free_string = '\n'.join([' x{} free'.format(i+1)
- for i in range(nvar)
- if lb[i] == -np.inf and ub[i] == np.inf])
string += 'Bounds\n'
- if len(ub_string) > 0:
- string += ub_string + '\n'
- if len(lb_string) > 0:
- string += lb_string + '\n'
- if len(free_string) > 0:
- string += free_string + '\n'
+ for i in range(nvar):
+ string += '{} <= x{} <= {}\n'.format(lb[i], i+1, ub[i])
ind_int, = np.where(self.vtype == 'I')
int_string = '\n'.join(['x{}'.format(i+1) for i in ind_int])
diff --git a/rsome/math.py b/rsome/math.py
index 7f6c174..7436b9a 100644
--- a/rsome/math.py
+++ b/rsome/math.py
@@ -109,6 +109,7 @@ def quad(x, qmat):
x : an array of variables or affine expressions
Input array. The array must be 1-D.
qmat : a positive or negative semidefinite matrix.
+ A matrix representing the quadratic coefficients.
Returns
-------
@@ -432,10 +433,10 @@ def diag(affine, k=0, fill=False):
filled with zeros. Otherwise, return the diagonal elements as a
1-D array
- Returns
- -------
- out : Affine
- The diagonal elements of a given 2-D array.
+ Returns
+ -------
+ out : Affine
+ The diagonal elements of a given 2-D array.
"""
return affine.diag(k, fill)
@@ -446,20 +447,19 @@ def tril(affine, k=0):
Return the lower triangular elements of a 2-D array. The remaining
elements are filled with zeros.
- Parameters
- ----------
- affine : an array of variables or affine expressions.
- Input array. It must be a 2-D array.
+ Parameters
+ ----------
+ affine : an array of variables or affine expressions.
+ Input array. It must be a 2-D array.
- k : int, optional
- Diagonal above which to zero elements. `k = 0` (the
- default) is the main diagonal, `k < 0` is below it and
- `k > 0` is above.
+ k : int, optional
+ Diagonal above which to zero elements. `k = 0` (the default) is
+ the main diagonal, `k < 0` is below it and `k > 0` is above.
- Returns
- -------
- out : Affine
- The lower triangular elements of the given 2-D array.
+ Returns
+ -------
+ out : Affine
+ The lower triangular elements of the given 2-D array.
"""
return affine.tril(k)
@@ -481,7 +481,7 @@ def triu(affine, k):
Returns
-------
- out : Affine
+ out : Affine
The upper triangular elements of the given 2-D array.
"""
diff --git a/setup.cfg b/setup.cfg
index 802d98b..a469d4f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = rsome
-version = 1.2.5
+version = 1.2.6
description = Robust Stochastic Optimization Made Easy
long_description = file: README.rst
author = Peng Xiong