libmf 0.4.0 → 0.5.0

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: b264767ceb43c4a0407896e2bcf2373a47296e1e0580c65ec2ef08471589f661
4
- data.tar.gz: addfb47cc44989620f847eac0392aef7431e596af08095ddd56ed227c4b99274
3
+ metadata.gz: d82762549216fa7e42bc21e9450aaa7f9a423350915f8d1c6ed158cea7b4520d
4
+ data.tar.gz: 820677028926afecac55c270d74e572b70ce19e22c2d16710fa2c514f77e7154
5
5
  SHA512:
6
- metadata.gz: b22bcab875b5c2e8b7432c137f90b3ea37a8c16c3e64aa0fb4c15f824f8345a3105ca981a4ea1ea091396dcd0ce10320eab52f56e6ede75601ea2192e5bc61ac
7
- data.tar.gz: 2e946522f35f77a46ab3880d74da38a0efdcaf432eabc1945d35af344d5cafb2c7712a3e0660352f8cf84fbd44af5c9c4e1cc6110ef5b908cd66c3393e124a99
6
+ metadata.gz: 1278c9ad499069cd1287bda40878ad9e61c2e8d039bea27c439fcc5b1bcb32bcd5136b9ffde6bb967ba39ea49fbd97d832f765a3b6d5b90a8bd51a81d26843b1
7
+ data.tar.gz: fac4621e932e5eb07b4652ed0f7336275833a63e37814e853aa407e2f344076dec201cbff49b1a0271a115a715e2fd43ac0bdb25abdbd262ddfa5bcb14774ad8
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.5.0 (2026-04-17)
2
+
3
+ - Added checks for invalid data
4
+ - Fixed memory leak in shared library
5
+ - Dropped support for reading data directly from files
6
+ - Dropped support for Ruby < 3.3
7
+
1
8
  ## 0.4.0 (2024-10-22)
2
9
 
3
10
  - Dropped support for Ruby < 3.1
data/LICENSE.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  BSD 3-Clause License
2
2
 
3
3
  Copyright (c) 2014-2015 The LIBMF Project.
4
- Copyright (c) 2019-2024 Andrew Kane.
4
+ Copyright (c) 2019-2026 Andrew Kane.
5
5
  All rights reserved.
6
6
 
7
7
  Redistribution and use in source and binary forms, with or without
data/README.md CHANGED
@@ -191,23 +191,6 @@ model.fit(train_set, eval_set: valid_set)
191
191
  puts model.rmse(valid_set)
192
192
  ```
193
193
 
194
- ## Performance
195
-
196
- For performance, read data directly from files
197
-
198
- ```ruby
199
- model.fit("train.txt", eval_set: "validate.txt")
200
- model.cv("train.txt")
201
- ```
202
-
203
- Data should be in the format `row_index column_index value`:
204
-
205
- ```txt
206
- 0 0 5.0
207
- 0 2 3.5
208
- 1 1 4.0
209
- ```
210
-
211
194
  ## Numo
212
195
 
213
196
  Get latent factors as Numo arrays
data/lib/libmf/ffi.rb CHANGED
@@ -53,7 +53,6 @@ module Libmf
53
53
  end
54
54
 
55
55
  attach_function :mf_get_default_param, [], Parameter.by_value
56
- attach_function :mf_read_problem, [:string], Problem.by_value
57
56
  attach_function :mf_save_model, [Model.by_ref, :string], :int
58
57
  attach_function :mf_load_model, [:string], Model.auto_ptr
59
58
  attach_function :mf_destroy_model, [:pointer], :void
data/lib/libmf/model.rb CHANGED
@@ -10,9 +10,22 @@ module Libmf
10
10
  @model =
11
11
  if eval_set
12
12
  eval_set = create_problem(eval_set)
13
+ param = self.param
14
+
15
+ # LIBMF does not handle these cases
16
+ if param[:fun] == 12
17
+ if eval_set[:m] > train_set[:m]
18
+ raise ArgumentError, "Eval set cannot have extra rows for one_class_l2 loss"
19
+ end
20
+
21
+ if eval_set[:n] > train_set[:n]
22
+ raise ArgumentError, "Eval set cannot have extra columns for one_class_l2 loss"
23
+ end
24
+ end
25
+
13
26
  FFI.mf_train_with_validation(train_set, eval_set, param)
14
27
  else
15
- FFI.mf_train(train_set, param)
28
+ FFI.mf_train(train_set, self.param)
16
29
  end
17
30
  raise Error, "fit failed" if @model.null?
18
31
 
@@ -160,8 +173,7 @@ module Libmf
160
173
 
161
174
  def create_problem(data)
162
175
  if data.is_a?(String)
163
- # need to expand path so it's absolute
164
- return FFI.mf_read_problem(File.expand_path(data))
176
+ raise Error, "Reading data directly from files is no longer supported"
165
177
  end
166
178
 
167
179
  if data.is_a?(Matrix)
@@ -175,7 +187,23 @@ module Libmf
175
187
  # and write directly to C string
176
188
  buffer = String.new
177
189
  pack_format = "iif"
190
+ int_max = 2**31 - 1
191
+ umax = -1
192
+ vmax = -1
178
193
  data.each do |row|
194
+ u = row[0]
195
+ if u < 0 || u >= int_max
196
+ raise ArgumentError, "Invalid row index"
197
+ end
198
+
199
+ v = row[1]
200
+ if v < 0 || v >= int_max
201
+ raise ArgumentError, "Invalid column index"
202
+ end
203
+
204
+ umax = u if u > umax
205
+ vmax = v if v > vmax
206
+
179
207
  row.pack(pack_format, buffer: buffer)
180
208
  end
181
209
 
@@ -186,12 +214,9 @@ module Libmf
186
214
  # FFI will throw an error above if too long
187
215
  raise Error, "Bad buffer size" if r.size != buffer.bytesize
188
216
 
189
- m = data.max_by { |r| r[0] }[0] + 1
190
- n = data.max_by { |r| r[1] }[1] + 1
191
-
192
217
  prob = FFI::Problem.new
193
- prob[:m] = m
194
- prob[:n] = n
218
+ prob[:m] = umax + 1
219
+ prob[:n] = vmax + 1
195
220
  prob[:nnz] = data.size
196
221
  prob[:r] = r
197
222
  prob
data/lib/libmf/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Libmf
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
Binary file
Binary file
data/vendor/libmf.dylib CHANGED
Binary file
data/vendor/libmf.so CHANGED
Binary file
data/vendor/mf.dll CHANGED
Binary file
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libmf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-10-23 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: ffi
@@ -24,7 +23,6 @@ dependencies:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
25
  version: '0'
27
- description:
28
26
  email: andrew@ankane.org
29
27
  executables: []
30
28
  extensions: []
@@ -50,7 +48,6 @@ homepage: https://github.com/ankane/libmf-ruby
50
48
  licenses:
51
49
  - BSD-3-Clause
52
50
  metadata: {}
53
- post_install_message:
54
51
  rdoc_options: []
55
52
  require_paths:
56
53
  - lib
@@ -58,15 +55,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
58
55
  requirements:
59
56
  - - ">="
60
57
  - !ruby/object:Gem::Version
61
- version: '3.1'
58
+ version: '3.3'
62
59
  required_rubygems_version: !ruby/object:Gem::Requirement
63
60
  requirements:
64
61
  - - ">="
65
62
  - !ruby/object:Gem::Version
66
63
  version: '0'
67
64
  requirements: []
68
- rubygems_version: 3.5.16
69
- signing_key:
65
+ rubygems_version: 4.0.6
70
66
  specification_version: 4
71
67
  summary: Large-scale sparse matrix factorization for Ruby
72
68
  test_files: []