opt-rb 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d603d7ad934458c4f00463082749bf1a7677e57d94503478e84cad8bc2978603
4
- data.tar.gz: 204192ddce062448155f5022a8a08548e30401d98082e36995730a12d65403cd
3
+ metadata.gz: 62fefec1218ff8c8b7d9674f3cb2d88aaf527a0a82438299fb33c5b8e4d42583
4
+ data.tar.gz: 5e6f8347697f8e43c0b39df41d8745d57318d9a9947be636b8aa6355fb416f53
5
5
  SHA512:
6
- metadata.gz: 6fff64916a1c84fabdc93b2c9185a382bb88e02312f79fdd1586810827f4d0c69802d560398e724836804b745196b10e3962f6b31cb3f9f0818486428a786e7a
7
- data.tar.gz: 2844557f339635d291ed81b19ac98159d374e694c6811c8c81cf7bd6cda83704f02557da79d4bcbebe0c4827d09204a084d45c8ecd29b820c23e20a35dc1f8e2
6
+ metadata.gz: 78d1ebff8e8ce021f1aa2089e7b1f08b8ff790ebb1558f43c2230f09f326ece636a696eea4423ad67dfe374a6b7eaf201f09f4f6aa21fa64021716ef2b4c3c7c
7
+ data.tar.gz: e263aa310c69f7bf617e50d5b002e3db6814728bdbf84648d069ba9265140e0c434a6638484fe7c0e9aee820f69f73fc0f2917ba5650a1f9aeb8c1fd3b0b344c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 0.3.1 (2026-07-09)
2
+
3
+ - Added support for QP with SCS
4
+ - Fixed error with QP and HiGHS Ruby 0.3
5
+
6
+ ## 0.3.0 (2026-04-07)
7
+
8
+ - Dropped support for Ruby < 3.3
9
+
1
10
  ## 0.2.1 (2025-04-26)
2
11
 
3
12
  - Added support for OSQP Ruby 0.4
data/README.md CHANGED
@@ -24,9 +24,7 @@ Solver | LP | QP | MIP | License
24
24
  [GLPK](https://github.com/ankane/glpk-ruby) | ✓ | | ✓ | GPL-3.0-or-later
25
25
  [HiGHS](https://github.com/ankane/highs-ruby) | ✓ | ✓ | ✓ | MIT
26
26
  [OSQP](https://github.com/ankane/osqp-ruby) | ✓ | ✓ | | Apache-2.0
27
- [SCS](https://github.com/ankane/scs-ruby) | ✓ | * | | MIT
28
-
29
- \* supports, but not implemented yet
27
+ [SCS](https://github.com/ankane/scs-ruby) | ✓ | | | MIT
30
28
 
31
29
  ## Getting Started
32
30
 
data/lib/opt/problem.rb CHANGED
@@ -27,9 +27,9 @@ module Opt
27
27
 
28
28
  vars = self.vars
29
29
  raise Error, "No variables" if vars.empty?
30
- has_semi_continuous_var = vars.any? { |v| v.is_a?(SemiContinuous) }
31
- has_semi_integer_var = vars.any? { |v| v.is_a?(SemiInteger) }
32
- has_integer_var = vars.any? { |v| v.is_a?(Integer) }
30
+ has_semi_continuous_var = vars.any?(SemiContinuous)
31
+ has_semi_integer_var = vars.any?(SemiInteger)
32
+ has_integer_var = vars.any?(Integer)
33
33
  type = has_semi_continuous_var || has_semi_integer_var || has_integer_var ? :mip : :lp
34
34
  quadratic = @indexed_objective.any? { |k, _| k.is_a?(Array) }
35
35
 
@@ -26,14 +26,17 @@ module Opt
26
26
  q_index = []
27
27
  q_value = []
28
28
 
29
+ before_0_3 = Highs::VERSION.to_f < 0.3
29
30
  vars.each_with_index do |v2, j|
30
31
  q_start << q_index.size
31
32
  vars.each_with_index do |v1, i|
32
- v = indexed_objective[[v1, v2]]
33
- if v != 0
34
- q_index << i
35
- # multiply values by 2 since minimizes 1/2
36
- q_value << (v1.equal?(v2) ? v * 2 : v)
33
+ if i <= j || before_0_3
34
+ v = indexed_objective[[v1, v2]]
35
+ if v != 0
36
+ q_index << i
37
+ # multiply values by 2 since minimizes 1/2
38
+ q_value << (v1.equal?(v2) ? v * 2 : v)
39
+ end
37
40
  end
38
41
  end
39
42
  end
@@ -13,7 +13,7 @@ module Opt
13
13
 
14
14
  # add variable constraints
15
15
  vars.each_with_index do |v, i|
16
- row = [0] * vars.size
16
+ row = Array.new(vars.size, 0.0)
17
17
  row[i] = 1
18
18
  a << row
19
19
  row_lower << col_lower[i]
@@ -22,11 +22,9 @@ module Opt
22
22
 
23
23
  p = OSQP::Matrix.new(a.first.size, a.first.size)
24
24
  if type == :qp
25
- vars.map.with_index do |v1, i|
26
- vars.map.with_index do |v2, j|
27
- if i > j
28
- 0
29
- else
25
+ vars.each_with_index do |v1, i|
26
+ vars.each_with_index do |v2, j|
27
+ if i <= j
30
28
  v = indexed_objective[[v1, v2]]
31
29
  v = (v1.equal?(v2) ? v * 2 : v)
32
30
  v *= -1 if sense == :maximize
@@ -1,7 +1,7 @@
1
1
  module Opt
2
2
  module Solvers
3
3
  class ScsSolver < AbstractSolver
4
- def solve(sense:, col_lower:, col_upper:, obj:, row_lower:, row_upper:, constraints_by_var:, vars:, offset:, verbose:, time_limit:, **)
4
+ def solve(sense:, col_lower:, col_upper:, obj:, row_lower:, row_upper:, constraints_by_var:, vars:, offset:, verbose:, time_limit:, type:, indexed_objective:, **)
5
5
  obj = obj.map { |v| -v } if sense == :maximize
6
6
 
7
7
  a = []
@@ -41,6 +41,24 @@ module Opt
41
41
 
42
42
  data = {a: a, b: b, c: obj}
43
43
  cone = {z: z, l: l}
44
+
45
+ if type == :qp
46
+ p = SCS::Matrix.new(a.first.size, a.first.size)
47
+ vars.each_with_index do |v1, i|
48
+ vars.each_with_index do |v2, j|
49
+ if i <= j
50
+ v = indexed_objective[[v1, v2]]
51
+ v = (v1.equal?(v2) ? v * 2 : v)
52
+ v *= -1 if sense == :maximize
53
+ # p must be positive semidefinite
54
+ raise Error, "Non-convex problem" if v < 0
55
+ p[i, j] = v
56
+ end
57
+ end
58
+ end
59
+ data[:p] = p
60
+ end
61
+
44
62
  solver = SCS::Solver.new
45
63
  res = solver.solve(data, cone, verbose: verbose, time_limit_secs: time_limit)
46
64
  objective = res[:pobj]
@@ -69,7 +87,7 @@ module Opt
69
87
  end
70
88
 
71
89
  def self.supported_types
72
- [:lp]
90
+ [:lp, :qp]
73
91
  end
74
92
  end
75
93
  end
data/lib/opt/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Opt
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opt-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
@@ -49,14 +49,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
49
49
  requirements:
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: '3.1'
52
+ version: '3.3'
53
53
  required_rubygems_version: !ruby/object:Gem::Requirement
54
54
  requirements:
55
55
  - - ">="
56
56
  - !ruby/object:Gem::Version
57
57
  version: '0'
58
58
  requirements: []
59
- rubygems_version: 3.6.7
59
+ rubygems_version: 4.0.14
60
60
  specification_version: 4
61
61
  summary: Convex optimization for Ruby
62
62
  test_files: []