cmfrec 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +21 -16
- data/lib/cmfrec/data.rb +12 -7
- data/lib/cmfrec/ffi.rb +8 -7
- data/lib/cmfrec/recommender.rb +254 -192
- data/lib/cmfrec/version.rb +1 -1
- data/lib/cmfrec.rb +7 -7
- data/vendor/arm64-darwin/COPYRIGHTS +57 -0
- data/vendor/arm64-darwin/LICENSE +23 -0
- data/vendor/arm64-darwin/libcmfrec.dylib +0 -0
- data/vendor/x86_64-darwin/COPYRIGHTS +57 -0
- data/vendor/x86_64-darwin/LICENSE +23 -0
- data/vendor/x86_64-darwin/libcmfrec.dylib +0 -0
- data/vendor/x86_64-linux/COPYRIGHTS +57 -0
- data/vendor/x86_64-linux/LICENSE +23 -0
- data/vendor/x86_64-linux/libcmfrec.so +0 -0
- metadata +14 -9
- data/vendor/LICENSE.txt +0 -74
- data/vendor/libcmfrec.arm64.dylib +0 -0
- data/vendor/libcmfrec.dylib +0 -0
- data/vendor/libcmfrec.so +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6dbbc801e415a4f505ffc436be23ccf066d144da072669e782b88c02e14b0f8
|
4
|
+
data.tar.gz: 3851230f0a4dc4be9fbc24fe81681de0758bdbb583803780f8e07b10741f4bd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 103c09a7c0e13fca3cb81dc68c667e776fc965a485cf358e0fc8f350a97474b54bdfc0910f4472051020dbe34b8c097908c1024d5fc036ad77d0444372885109
|
7
|
+
data.tar.gz: b107b36333f714106d981168f24fda48a2a211f288a2dbe01f570adb607b7d6a5215c18df4c67d159bb367d652f3d10faeb4dbc66688eaf117c5b7a1432ee951
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## 0.2.0 (2022-06-14)
|
2
|
+
|
3
|
+
- Updated cmfrec to 3.4.2
|
4
|
+
- Fixed missing item ids with `load_movielens`
|
5
|
+
- Dropped support for Ruby < 2.7
|
6
|
+
|
7
|
+
## 0.1.7 (2022-03-22)
|
8
|
+
|
9
|
+
- Improved ARM detection
|
10
|
+
- Fixed error with `load_movielens`
|
11
|
+
- Fixed duplicates in `item_info` with `load_movielens`
|
12
|
+
|
13
|
+
## 0.1.6 (2021-08-12)
|
14
|
+
|
15
|
+
- Added `user_ids` and `item_ids` methods
|
16
|
+
- Added `user_id` argument to `user_factors`
|
17
|
+
- Added `item_id` argument to `item_factors`
|
18
|
+
- Added `user_id` argument to `user_bias`
|
19
|
+
- Added `item_id` argument to `item_bias`
|
20
|
+
- Added `item_ids` argument to `new_user_recs`
|
21
|
+
- Fixed order for `user_recs`
|
22
|
+
|
1
23
|
## 0.1.5 (2021-08-10)
|
2
24
|
|
3
25
|
- Fixed issue with `user_recs` and `new_user_recs` returning rated items
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# cmfrec
|
1
|
+
# cmfrec Ruby
|
2
2
|
|
3
3
|
:fire: Recommendations for Ruby, powered by [cmfrec](https://github.com/david-cortes/cmfrec)
|
4
4
|
|
@@ -6,14 +6,14 @@
|
|
6
6
|
- Works with explicit and implicit feedback
|
7
7
|
- Uses high-performance matrix factorization
|
8
8
|
|
9
|
-
[![Build Status](https://github.com/ankane/cmfrec/workflows/build/badge.svg?branch=master)](https://github.com/ankane/cmfrec/actions)
|
9
|
+
[![Build Status](https://github.com/ankane/cmfrec-ruby/workflows/build/badge.svg?branch=master)](https://github.com/ankane/cmfrec-ruby/actions)
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
13
13
|
Add this line to your application’s Gemfile:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
gem
|
16
|
+
gem "cmfrec"
|
17
17
|
```
|
18
18
|
|
19
19
|
For Windows, also follow [these instructions](#windows-installation).
|
@@ -58,8 +58,8 @@ Get recommendations for a new user
|
|
58
58
|
|
59
59
|
```ruby
|
60
60
|
recommender.new_user_recs([
|
61
|
-
{item_id: 1,
|
62
|
-
{item_id: 2,
|
61
|
+
{item_id: 1, rating: 5},
|
62
|
+
{item_id: 2, rating: 3}
|
63
63
|
])
|
64
64
|
```
|
65
65
|
|
@@ -112,7 +112,7 @@ recommender.new_user_recs([], user_info: {cats: 0, dogs: 2})
|
|
112
112
|
Add this line to your application’s Gemfile:
|
113
113
|
|
114
114
|
```ruby
|
115
|
-
gem
|
115
|
+
gem "ngt"
|
116
116
|
```
|
117
117
|
|
118
118
|
Get similar users
|
@@ -150,11 +150,7 @@ recommender.predict(ratings.last(20000))
|
|
150
150
|
[Ahoy](https://github.com/ankane/ahoy) is a great source for implicit feedback
|
151
151
|
|
152
152
|
```ruby
|
153
|
-
views = Ahoy::Event.
|
154
|
-
where(name: "Viewed post").
|
155
|
-
group(:user_id).
|
156
|
-
group("properties->>'post_id'"). # postgres syntax
|
157
|
-
count
|
153
|
+
views = Ahoy::Event.where(name: "Viewed post").group(:user_id).group_prop(:post_id).count
|
158
154
|
|
159
155
|
data =
|
160
156
|
views.map do |(user_id, post_id), count|
|
@@ -230,8 +226,17 @@ bin = File.binread("recommender.bin")
|
|
230
226
|
recommender = Marshal.load(bin)
|
231
227
|
```
|
232
228
|
|
229
|
+
Alternatively, you can store only the factors and use a library like [Neighbor](https://github.com/ankane/neighbor). See the [examples](https://github.com/ankane/neighbor/tree/master/examples) for Disco, which has a similar API. For explicit feedback, you should [disable the bias](#explicit-feedback) with this approach.
|
230
|
+
|
233
231
|
## Reference
|
234
232
|
|
233
|
+
Get ids
|
234
|
+
|
235
|
+
```ruby
|
236
|
+
recommender.user_ids
|
237
|
+
recommender.item_ids
|
238
|
+
```
|
239
|
+
|
235
240
|
Get the global mean
|
236
241
|
|
237
242
|
```ruby
|
@@ -262,22 +267,22 @@ Cmfrec.ffi_lib = "path/to/cmfrec.dll"
|
|
262
267
|
|
263
268
|
## History
|
264
269
|
|
265
|
-
View the [changelog](https://github.com/ankane/cmfrec/blob/master/CHANGELOG.md)
|
270
|
+
View the [changelog](https://github.com/ankane/cmfrec-ruby/blob/master/CHANGELOG.md)
|
266
271
|
|
267
272
|
## Contributing
|
268
273
|
|
269
274
|
Everyone is encouraged to help improve this project. Here are a few ways you can help:
|
270
275
|
|
271
|
-
- [Report bugs](https://github.com/ankane/cmfrec/issues)
|
272
|
-
- Fix bugs and [submit pull requests](https://github.com/ankane/cmfrec/pulls)
|
276
|
+
- [Report bugs](https://github.com/ankane/cmfrec-ruby/issues)
|
277
|
+
- Fix bugs and [submit pull requests](https://github.com/ankane/cmfrec-ruby/pulls)
|
273
278
|
- Write, clarify, or fix documentation
|
274
279
|
- Suggest or add new features
|
275
280
|
|
276
281
|
To get started with development:
|
277
282
|
|
278
283
|
```sh
|
279
|
-
git clone https://github.com/ankane/cmfrec.git
|
280
|
-
cd cmfrec
|
284
|
+
git clone https://github.com/ankane/cmfrec-ruby.git
|
285
|
+
cd cmfrec-ruby
|
281
286
|
bundle install
|
282
287
|
bundle exec rake vendor:all
|
283
288
|
bundle exec rake test
|
data/lib/cmfrec/data.rb
CHANGED
@@ -3,11 +3,11 @@ module Cmfrec
|
|
3
3
|
def load_movielens
|
4
4
|
require "csv"
|
5
5
|
|
6
|
-
data_path = download_file("ml-100k/u.data", "
|
6
|
+
data_path = download_file("ml-100k/u.data", "https://files.grouplens.org/datasets/movielens/ml-100k/u.data",
|
7
7
|
file_hash: "06416e597f82b7342361e41163890c81036900f418ad91315590814211dca490")
|
8
|
-
user_path = download_file("ml-100k/u.user", "
|
8
|
+
user_path = download_file("ml-100k/u.user", "https://files.grouplens.org/datasets/movielens/ml-100k/u.user",
|
9
9
|
file_hash: "f120e114da2e8cf314fd28f99417c94ae9ddf1cb6db8ce0e4b5995d40e90e62c")
|
10
|
-
item_path = download_file("ml-100k/u.item", "
|
10
|
+
item_path = download_file("ml-100k/u.item", "https://files.grouplens.org/datasets/movielens/ml-100k/u.item",
|
11
11
|
file_hash: "553841ebc7de3a0fd0d6b62a204ea30c1e651aacfb2814c7a6584ac52f2c5701")
|
12
12
|
|
13
13
|
# convert u.item to utf-8
|
@@ -24,9 +24,15 @@ module Cmfrec
|
|
24
24
|
|
25
25
|
item_info = []
|
26
26
|
movies = {}
|
27
|
+
movie_names = {}
|
27
28
|
genres = %w(unknown action adventure animation childrens comedy crime documentary drama fantasy filmnoir horror musical mystery romance scifi thriller war western)
|
28
29
|
CSV.parse(movies_str, col_sep: "|", converters: [:numeric]) do |row|
|
29
30
|
movies[row[0]] = row[1]
|
31
|
+
|
32
|
+
# filter duplicates
|
33
|
+
next if movie_names[row[1]]
|
34
|
+
movie_names[row[1]] = true
|
35
|
+
|
30
36
|
item = {item_id: row[1], year: row[2] ? Date.parse(row[2]).year : 1970}
|
31
37
|
genres.each_with_index do |genre, i|
|
32
38
|
item[:"genre_#{genre}"] = row[i + 5]
|
@@ -49,7 +55,10 @@ module Cmfrec
|
|
49
55
|
private
|
50
56
|
|
51
57
|
def download_file(fname, origin, file_hash:)
|
58
|
+
require "digest"
|
52
59
|
require "fileutils"
|
60
|
+
require "net/http"
|
61
|
+
require "tmpdir"
|
53
62
|
|
54
63
|
# TODO handle this better
|
55
64
|
raise "No HOME" unless ENV["HOME"]
|
@@ -58,10 +67,6 @@ module Cmfrec
|
|
58
67
|
|
59
68
|
return dest if File.exist?(dest)
|
60
69
|
|
61
|
-
require "digest"
|
62
|
-
require "net/http"
|
63
|
-
require "tmpdir"
|
64
|
-
|
65
70
|
temp_path = "#{Dir.tmpdir}/cmfrec-#{Time.now.to_f}" # TODO better name
|
66
71
|
|
67
72
|
digest = Digest::SHA2.new
|
data/lib/cmfrec/ffi.rb
CHANGED
@@ -17,12 +17,13 @@ module Cmfrec
|
|
17
17
|
typealias "int_t", "int"
|
18
18
|
typealias "real_t", "double"
|
19
19
|
|
20
|
-
extern "int_t fit_collective_explicit_als(real_t *restrict biasA, real_t *restrict biasB, real_t *restrict A, real_t *restrict B, real_t *restrict C, real_t *restrict D, real_t *restrict Ai, real_t *restrict Bi, bool add_implicit_features, bool reset_values, int_t seed, real_t *restrict glob_mean, real_t *restrict U_colmeans, real_t *restrict I_colmeans, int_t m, int_t n, int_t k, int_t ixA[], int_t ixB[], real_t *restrict X, size_t nnz, real_t *restrict Xfull, real_t *restrict weight, bool user_bias, bool item_bias, bool center, real_t lam, real_t *restrict lam_unique, real_t l1_lam, real_t *restrict l1_lam_unique, bool scale_lam, bool scale_lam_sideinfo, real_t *restrict U, int_t m_u, int_t p, real_t *restrict II, int_t n_i, int_t q, int_t U_row[], int_t U_col[], real_t *restrict U_sp, size_t nnz_U, int_t I_row[], int_t I_col[], real_t *restrict I_sp, size_t nnz_I, bool NA_as_zero_X, bool NA_as_zero_U, bool NA_as_zero_I, int_t k_main, int_t k_user, int_t k_item, real_t w_main, real_t w_user, real_t w_item, real_t w_implicit, int_t niter,
|
21
|
-
extern "int_t fit_collective_implicit_als(real_t *restrict A, real_t *restrict B, real_t *restrict C, real_t *restrict D, bool reset_values, int_t seed, real_t *restrict U_colmeans, real_t *restrict I_colmeans, int_t m, int_t n, int_t k, int_t ixA[], int_t ixB[], real_t *restrict X, size_t nnz, real_t lam, real_t *restrict lam_unique, real_t l1_lam, real_t *restrict l1_lam_unique, real_t *restrict U, int_t m_u, int_t p, real_t *restrict II, int_t n_i, int_t q, int_t U_row[], int_t U_col[], real_t *restrict U_sp, size_t nnz_U, int_t I_row[], int_t I_col[], real_t *restrict I_sp, size_t nnz_I, bool NA_as_zero_U, bool NA_as_zero_I, int_t k_main, int_t k_user, int_t k_item, real_t w_main, real_t w_user, real_t w_item, real_t *restrict w_main_multiplier, real_t alpha, bool adjust_weight, bool apply_log_transf, int_t niter,
|
22
|
-
extern "int_t
|
23
|
-
extern "int_t
|
24
|
-
extern "int_t
|
25
|
-
extern "int_t
|
26
|
-
extern "int_t
|
20
|
+
extern "int_t fit_collective_explicit_als(real_t *restrict biasA, real_t *restrict biasB, real_t *restrict A, real_t *restrict B, real_t *restrict C, real_t *restrict D, real_t *restrict Ai, real_t *restrict Bi, bool add_implicit_features, bool reset_values, int_t seed, real_t *restrict glob_mean, real_t *restrict U_colmeans, real_t *restrict I_colmeans, int_t m, int_t n, int_t k, int_t ixA[], int_t ixB[], real_t *restrict X, size_t nnz, real_t *restrict Xfull, real_t *restrict weight, bool user_bias, bool item_bias, bool center, real_t lam, real_t *restrict lam_unique, real_t l1_lam, real_t *restrict l1_lam_unique, bool scale_lam, bool scale_lam_sideinfo, bool scale_bias_const, real_t *scaling_biasA, real_t *scaling_biasB, real_t *restrict U, int_t m_u, int_t p, real_t *restrict II, int_t n_i, int_t q, int_t U_row[], int_t U_col[], real_t *restrict U_sp, size_t nnz_U, int_t I_row[], int_t I_col[], real_t *restrict I_sp, size_t nnz_I, bool NA_as_zero_X, bool NA_as_zero_U, bool NA_as_zero_I, int_t k_main, int_t k_user, int_t k_item, real_t w_main, real_t w_user, real_t w_item, real_t w_implicit, int_t niter, int nthreads, bool verbose, bool handle_interrupt, bool use_cg, int_t max_cg_steps, bool precondition_cg, bool finalize_chol, bool nonneg, int_t max_cd_steps, bool nonneg_C, bool nonneg_D, bool precompute_for_predictions, bool include_all_X, real_t *restrict B_plus_bias, real_t *restrict precomputedBtB, real_t *restrict precomputedTransBtBinvBt, real_t *restrict precomputedBtXbias, real_t *restrict precomputedBeTBeChol, real_t *restrict precomputedBiTBi, real_t *restrict precomputedTransCtCinvCt, real_t *restrict precomputedCtCw, real_t *precomputedCtUbias)"
|
21
|
+
extern "int_t fit_collective_implicit_als(real_t *restrict A, real_t *restrict B, real_t *restrict C, real_t *restrict D, bool reset_values, int_t seed, real_t *restrict U_colmeans, real_t *restrict I_colmeans, int_t m, int_t n, int_t k, int_t ixA[], int_t ixB[], real_t *restrict X, size_t nnz, real_t lam, real_t *restrict lam_unique, real_t l1_lam, real_t *restrict l1_lam_unique, real_t *restrict U, int_t m_u, int_t p, real_t *restrict II, int_t n_i, int_t q, int_t U_row[], int_t U_col[], real_t *restrict U_sp, size_t nnz_U, int_t I_row[], int_t I_col[], real_t *restrict I_sp, size_t nnz_I, bool NA_as_zero_U, bool NA_as_zero_I, int_t k_main, int_t k_user, int_t k_item, real_t w_main, real_t w_user, real_t w_item, real_t *restrict w_main_multiplier, real_t alpha, bool adjust_weight, bool apply_log_transf, int_t niter, int nthreads, bool verbose, bool handle_interrupt, bool use_cg, int_t max_cg_steps, bool precondition_cg, bool finalize_chol, bool nonneg, int_t max_cd_steps, bool nonneg_C, bool nonneg_D, bool precompute_for_predictions, real_t *restrict precomputedBtB, real_t *restrict precomputedBeTBe, real_t *restrict precomputedBeTBeChol, real_t *precomputedCtUbias)"
|
22
|
+
extern "int_t predict_X_old_collective_explicit(int_t row[], int_t col[], real_t *restrict predicted, size_t n_predict, real_t *restrict A, real_t *restrict biasA, real_t *restrict B, real_t *restrict biasB, real_t glob_mean, int_t k, int_t k_user, int_t k_item, int_t k_main, int_t m, int_t n_max, int nthreads)"
|
23
|
+
extern "int_t predict_X_old_collective_implicit(int_t row[], int_t col[], real_t *restrict predicted, size_t n_predict, real_t *restrict A, real_t *restrict B, int_t k, int_t k_user, int_t k_item, int_t k_main, int_t m, int_t n, int nthreads)"
|
24
|
+
extern "int_t topN_old_collective_explicit(real_t *a_vec, real_t a_bias, real_t *A, real_t *biasA, int_t row_index, real_t *B, real_t *biasB, real_t glob_mean, int_t k, int_t k_user, int_t k_item, int_t k_main, int_t *include_ix, int_t n_include, int_t *exclude_ix, int_t n_exclude, int_t *outp_ix, real_t *outp_score, int_t n_top, int_t n, int_t n_max, bool include_all_X, int nthreads)"
|
25
|
+
extern "int_t topN_old_collective_implicit(real_t *a_vec, real_t *A, int_t row_index, real_t *B, int_t k, int_t k_user, int_t k_item, int_t k_main, int_t *include_ix, int_t n_include, int_t *exclude_ix, int_t n_exclude, int_t *outp_ix, real_t *outp_score, int_t n_top, int_t n, int nthreads)"
|
26
|
+
extern "int_t topN_new_collective_explicit(bool user_bias, real_t *u_vec, int_t p, real_t *u_vec_sp, int_t u_vec_X_col[], size_t nnz_u_vec, real_t *u_bin_vec, int_t pbin, bool NA_as_zero_U, bool NA_as_zero_X, bool nonneg, real_t *C, real_t *Cb, real_t glob_mean, real_t *biasB, real_t *U_colmeans, real_t *Xa, int_t X_col[], size_t nnz, real_t *Xa_dense, int_t n, real_t *weight, real_t *B, real_t *Bi, bool add_implicit_features, int_t k, int_t k_user, int_t k_item, int_t k_main, real_t lam, real_t *lam_unique, real_t l1_lam, real_t *l1_lam_unique, bool scale_lam, bool scale_lam_sideinfo, bool scale_bias_const, real_t scaling_biasA, real_t w_main, real_t w_user, real_t w_implicit, int_t n_max, bool include_all_X, real_t *BtB, real_t *TransBtBinvBt, real_t *BtXbias, real_t *BeTBeChol, real_t *BiTBi, real_t *CtCw, real_t *TransCtCinvCt, real_t *CtUbias, real_t *B_plus_bias, int_t *include_ix, int_t n_include, int_t *exclude_ix, int_t n_exclude, int_t *outp_ix, real_t *outp_score, int_t n_top, int nthreads)"
|
27
|
+
extern "int_t topN_new_collective_implicit(int_t n, real_t *u_vec, int_t p, real_t *u_vec_sp, int_t u_vec_X_col[], size_t nnz_u_vec, bool NA_as_zero_U, bool nonneg, real_t *U_colmeans, real_t *B, real_t *C, real_t *Xa, int_t X_col[], size_t nnz, int_t k, int_t k_user, int_t k_item, int_t k_main, real_t lam, real_t l1_lam, real_t alpha, real_t w_main, real_t w_user, real_t w_main_multiplier, bool apply_log_transf, real_t *BeTBe, real_t *BtB, real_t *BeTBeChol, real_t *CtUbias, int_t *include_ix, int_t n_include, int_t *exclude_ix, int_t n_exclude, int_t *outp_ix, real_t *outp_score, int_t n_top, int nthreads)"
|
27
28
|
end
|
28
29
|
end
|
data/lib/cmfrec/recommender.rb
CHANGED
@@ -67,23 +67,10 @@ module Cmfrec
|
|
67
67
|
user = @user_map[user_id]
|
68
68
|
|
69
69
|
if user
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
data = item_ids.map { |v| {user_id: user_id, item_id: v} }
|
76
|
-
scores = predict(data)
|
77
|
-
|
78
|
-
item_ids.zip(scores).map do |item_id, score|
|
79
|
-
{item_id: item_id, score: score}
|
80
|
-
end
|
81
|
-
else
|
82
|
-
a_vec = @a[user * @k * Fiddle::SIZEOF_DOUBLE, @k * Fiddle::SIZEOF_DOUBLE]
|
83
|
-
a_bias = @bias_a ? @bias_a[user * Fiddle::SIZEOF_DOUBLE, Fiddle::SIZEOF_DOUBLE].unpack1("d") : 0
|
84
|
-
# @rated[user] will be nil for recommenders saved before 0.1.5
|
85
|
-
top_n(a_vec: a_vec, a_bias: a_bias, count: count, rated: (@rated[user] || {}).keys)
|
86
|
-
end
|
70
|
+
a_vec = @a[user * @k * Fiddle::SIZEOF_DOUBLE, @k * Fiddle::SIZEOF_DOUBLE]
|
71
|
+
a_bias = @bias_a ? @bias_a[user * Fiddle::SIZEOF_DOUBLE, Fiddle::SIZEOF_DOUBLE].unpack1("d") : 0
|
72
|
+
# @rated[user] will be nil for recommenders saved before 0.1.5
|
73
|
+
top_n(a_vec: a_vec, a_bias: a_bias, count: count, rated: (@rated[user] || {}).keys, item_ids: item_ids, row_index: user)
|
87
74
|
else
|
88
75
|
# no items if user is unknown
|
89
76
|
# TODO maybe most popular items
|
@@ -91,28 +78,164 @@ module Cmfrec
|
|
91
78
|
end
|
92
79
|
end
|
93
80
|
|
94
|
-
|
95
|
-
def new_user_recs(data, count: 5, user_info: nil)
|
81
|
+
def new_user_recs(data, count: 5, user_info: nil, item_ids: nil)
|
96
82
|
check_fit
|
97
83
|
|
98
|
-
|
99
|
-
|
84
|
+
data = to_dataset(data)
|
85
|
+
user_info = to_dataset(user_info) if user_info
|
86
|
+
|
87
|
+
# remove unknown items
|
88
|
+
data, unknown_data = data.partition { |d| @item_map[d[:item_id]] }
|
89
|
+
|
90
|
+
if unknown_data.any?
|
91
|
+
# TODO warn for unknown items?
|
92
|
+
# warn "[cmfrec] Unknown items: #{unknown_data.map { |d| d[:item_id] }.join(", ")}"
|
93
|
+
end
|
94
|
+
|
95
|
+
rated_ids = data.map { |d| @item_map[d[:item_id]] }
|
96
|
+
|
97
|
+
nnz = data.size
|
98
|
+
|
99
|
+
u_vec_sp = []
|
100
|
+
u_vec_x_col = []
|
101
|
+
if user_info
|
102
|
+
user_info.each do |k, v|
|
103
|
+
next if k == :user_id
|
104
|
+
|
105
|
+
uc = @user_info_map[k]
|
106
|
+
raise "Bad key: #{k}" unless uc
|
107
|
+
|
108
|
+
u_vec_x_col << uc
|
109
|
+
u_vec_sp << v
|
110
|
+
end
|
111
|
+
end
|
112
|
+
p_ = @user_info_map.size
|
113
|
+
nnz_u_vec = u_vec_sp.size
|
114
|
+
u_vec_x_col = int_ptr(u_vec_x_col)
|
115
|
+
u_vec_sp = real_ptr(u_vec_sp)
|
116
|
+
|
117
|
+
u_vec = nil
|
118
|
+
u_bin_vec = nil
|
119
|
+
pbin = 0
|
120
|
+
|
121
|
+
weight = nil
|
122
|
+
lam_unique = nil
|
123
|
+
l1_lam_unique = nil
|
124
|
+
n_max = @n
|
125
|
+
|
126
|
+
if data.any?
|
127
|
+
if @implicit
|
128
|
+
ratings = data.map { |d| d[:value] || 1 }
|
129
|
+
else
|
130
|
+
ratings = data.map { |d| d[:rating] }
|
131
|
+
check_ratings(ratings)
|
132
|
+
end
|
133
|
+
xa = real_ptr(ratings)
|
134
|
+
x_col = int_ptr(rated_ids)
|
135
|
+
else
|
136
|
+
xa = nil
|
137
|
+
x_col = nil
|
138
|
+
end
|
139
|
+
xa_dense = nil
|
140
|
+
|
141
|
+
rated = rated_ids.uniq
|
142
|
+
|
143
|
+
prep = prepare_top_n(count: count, rated: rated, item_ids: item_ids)
|
144
|
+
return [] if prep.empty?
|
145
|
+
include_ix, n_include, exclude_ix, n_exclude, outp_ix, outp_score, count = prep
|
146
|
+
|
147
|
+
if @implicit
|
148
|
+
args = [
|
149
|
+
@n,
|
150
|
+
u_vec, p_,
|
151
|
+
u_vec_sp, u_vec_x_col, nnz_u_vec,
|
152
|
+
@na_as_zero_user,
|
153
|
+
@nonneg,
|
154
|
+
@u_colmeans,
|
155
|
+
@b, @c,
|
156
|
+
xa, x_col, nnz,
|
157
|
+
@k, @k_user, @k_item, @k_main,
|
158
|
+
@lambda_, @l1_lambda, @alpha, @w_main, @w_user,
|
159
|
+
@w_main_multiplier,
|
160
|
+
@apply_log_transf,
|
161
|
+
nil, #BeTBe,
|
162
|
+
nil, #BtB,
|
163
|
+
nil, #BeTBeChol,
|
164
|
+
nil, #CtUbias,
|
165
|
+
include_ix, n_include,
|
166
|
+
exclude_ix, n_exclude,
|
167
|
+
outp_ix, outp_score,
|
168
|
+
count, @nthreads
|
169
|
+
]
|
170
|
+
check_status FFI.topN_new_collective_implicit(*fiddle_args(args))
|
171
|
+
else
|
172
|
+
cb = nil
|
173
|
+
scaling_bias_a = 0
|
174
|
+
|
175
|
+
args = [
|
176
|
+
@user_bias,
|
177
|
+
u_vec, p_,
|
178
|
+
u_vec_sp, u_vec_x_col, nnz_u_vec,
|
179
|
+
u_bin_vec, pbin,
|
180
|
+
@na_as_zero_user, @na_as_zero,
|
181
|
+
@nonneg,
|
182
|
+
@c, cb,
|
183
|
+
@global_mean, @bias_b,
|
184
|
+
@u_colmeans,
|
185
|
+
xa, x_col, nnz,
|
186
|
+
xa_dense, @n,
|
187
|
+
weight,
|
188
|
+
@b,
|
189
|
+
@bi, @add_implicit_features,
|
190
|
+
@k, @k_user, @k_item, @k_main,
|
191
|
+
@lambda_, lam_unique,
|
192
|
+
@l1_lambda, l1_lam_unique,
|
193
|
+
@scale_lam, @scale_lam_sideinfo,
|
194
|
+
@scale_bias_const, scaling_bias_a,
|
195
|
+
@w_main, @w_user, @w_implicit,
|
196
|
+
n_max, @include_all_x,
|
197
|
+
nil, #BtB,
|
198
|
+
nil, #TransBtBinvBt,
|
199
|
+
nil, #BtXbias,
|
200
|
+
nil, #BeTBeChol,
|
201
|
+
nil, #BiTBi,
|
202
|
+
nil, #CtCw,
|
203
|
+
nil, #TransCtCinvCt,
|
204
|
+
nil, #CtUbias,
|
205
|
+
nil, #B_plus_bias,
|
206
|
+
include_ix, n_include,
|
207
|
+
exclude_ix, n_exclude,
|
208
|
+
outp_ix, outp_score,
|
209
|
+
count, @nthreads
|
210
|
+
]
|
211
|
+
check_status FFI.topN_new_collective_explicit(*fiddle_args(args))
|
212
|
+
end
|
213
|
+
|
214
|
+
top_n_output(outp_ix, outp_score)
|
215
|
+
end
|
216
|
+
|
217
|
+
def user_ids
|
218
|
+
@user_map.keys
|
219
|
+
end
|
220
|
+
|
221
|
+
def item_ids
|
222
|
+
@item_map.keys
|
100
223
|
end
|
101
224
|
|
102
|
-
def user_factors
|
103
|
-
read_factors(@a, [@m, @m_u].max, @k_user + @k + @k_main)
|
225
|
+
def user_factors(user_id = nil)
|
226
|
+
read_factors(@a, [@m, @m_u].max, @k_user + @k + @k_main, user_id, @user_map)
|
104
227
|
end
|
105
228
|
|
106
|
-
def item_factors
|
107
|
-
read_factors(@b, [@n, @n_i].max, @k_item + @k + @k_main)
|
229
|
+
def item_factors(item_id = nil)
|
230
|
+
read_factors(@b, [@n, @n_i].max, @k_item + @k + @k_main, item_id, @item_map)
|
108
231
|
end
|
109
232
|
|
110
|
-
def user_bias
|
111
|
-
read_bias(@bias_a) if @bias_a
|
233
|
+
def user_bias(user_id = nil)
|
234
|
+
read_bias(@bias_a, user_id, @user_map) if @bias_a
|
112
235
|
end
|
113
236
|
|
114
|
-
def item_bias
|
115
|
-
read_bias(@bias_b) if @bias_b
|
237
|
+
def item_bias(item_id = nil)
|
238
|
+
read_bias(@bias_b, item_id, @item_map) if @bias_b
|
116
239
|
end
|
117
240
|
|
118
241
|
def similar_items(item_id, count: 5)
|
@@ -216,7 +339,6 @@ module Cmfrec
|
|
216
339
|
x_full = nil
|
217
340
|
weight = nil
|
218
341
|
lam_unique = nil
|
219
|
-
l1_lambda = 0
|
220
342
|
l1_lam_unique = nil
|
221
343
|
|
222
344
|
uu = nil
|
@@ -253,7 +375,7 @@ module Cmfrec
|
|
253
375
|
@m, @n, @k,
|
254
376
|
x_row, x_col, x, nnz,
|
255
377
|
@lambda_, lam_unique,
|
256
|
-
l1_lambda, l1_lam_unique,
|
378
|
+
@l1_lambda, l1_lam_unique,
|
257
379
|
uu, @m_u, p_,
|
258
380
|
ii, @n_i, q,
|
259
381
|
u_row, u_col, u_sp, nnz_u,
|
@@ -263,12 +385,13 @@ module Cmfrec
|
|
263
385
|
@w_main, @w_user, @w_item, real_ptr([@w_main_multiplier]),
|
264
386
|
@alpha, @adjust_weight, @apply_log_transf,
|
265
387
|
@niter, @nthreads, @verbose, @handle_interrupt,
|
266
|
-
@use_cg, @max_cg_steps, @finalize_chol,
|
388
|
+
@use_cg, @max_cg_steps, @precondition_cg, @finalize_chol,
|
267
389
|
@nonneg, @max_cd_steps, @nonneg_c, @nonneg_d,
|
268
390
|
@precompute_for_predictions,
|
269
391
|
nil, #precomputedBtB,
|
270
392
|
nil, #precomputedBeTBe,
|
271
|
-
nil
|
393
|
+
nil, #precomputedBeTBeChol
|
394
|
+
nil #precomputedCtUbias
|
272
395
|
]
|
273
396
|
check_status FFI.fit_collective_implicit_als(*fiddle_args(args))
|
274
397
|
|
@@ -287,9 +410,9 @@ module Cmfrec
|
|
287
410
|
|
288
411
|
glob_mean = Fiddle::Pointer.malloc(Fiddle::SIZEOF_DOUBLE)
|
289
412
|
|
290
|
-
|
291
|
-
|
292
|
-
|
413
|
+
# TODO add
|
414
|
+
scaling_bias_a = nil
|
415
|
+
scaling_bias_b = nil
|
293
416
|
|
294
417
|
args = [
|
295
418
|
@bias_a, @bias_b,
|
@@ -304,10 +427,11 @@ module Cmfrec
|
|
304
427
|
x_row, x_col, x, nnz,
|
305
428
|
x_full,
|
306
429
|
weight,
|
307
|
-
@user_bias, @item_bias, center,
|
430
|
+
@user_bias, @item_bias, @center,
|
308
431
|
@lambda_, lam_unique,
|
309
|
-
l1_lambda, l1_lam_unique,
|
310
|
-
scale_lam, scale_lam_sideinfo,
|
432
|
+
@l1_lambda, l1_lam_unique,
|
433
|
+
@scale_lam, @scale_lam_sideinfo,
|
434
|
+
@scale_bias_const, scaling_bias_a, scaling_bias_b,
|
311
435
|
uu, @m_u, p_,
|
312
436
|
ii, @n_i, q,
|
313
437
|
u_row, u_col, u_sp, nnz_u,
|
@@ -316,7 +440,7 @@ module Cmfrec
|
|
316
440
|
@k_main, @k_user, @k_item,
|
317
441
|
@w_main, @w_user, @w_item, @w_implicit,
|
318
442
|
@niter, @nthreads, @verbose, @handle_interrupt,
|
319
|
-
@use_cg, @max_cg_steps, @finalize_chol,
|
443
|
+
@use_cg, @max_cg_steps, @precondition_cg, @finalize_chol,
|
320
444
|
@nonneg, @max_cd_steps, @nonneg_c, @nonneg_d,
|
321
445
|
@precompute_for_predictions,
|
322
446
|
@include_all_x,
|
@@ -327,7 +451,8 @@ module Cmfrec
|
|
327
451
|
nil, #precomputedBeTBeChol,
|
328
452
|
nil, #precomputedBiTBi,
|
329
453
|
nil, #precomputedTransCtCinvCt,
|
330
|
-
nil
|
454
|
+
nil, #precomputedCtCw
|
455
|
+
nil, #precomputedCtUbias
|
331
456
|
]
|
332
457
|
check_status FFI.fit_collective_explicit_als(*fiddle_args(args))
|
333
458
|
|
@@ -342,21 +467,20 @@ module Cmfrec
|
|
342
467
|
end
|
343
468
|
|
344
469
|
def set_params(
|
345
|
-
k: 40, lambda_:
|
346
|
-
item_bias: true, add_implicit_features: false,
|
470
|
+
k: 40, lambda_: 10.0, method: "als", use_cg: true,
|
471
|
+
user_bias: true, item_bias: true, center: true, add_implicit_features: false,
|
472
|
+
scale_lam: false, scale_lam_sideinfo: false, scale_bias_const: false,
|
347
473
|
k_user: 0, k_item: 0, k_main: 0,
|
348
474
|
w_main: 1.0, w_user: 1.0, w_item: 1.0, w_implicit: 0.5,
|
475
|
+
l1_lambda: 0.0, center_u: true, center_i: true,
|
349
476
|
maxiter: 800, niter: 10, parallelize: "separate", corr_pairs: 4,
|
350
|
-
max_cg_steps: 3, finalize_chol: true,
|
477
|
+
max_cg_steps: 3, precondition_cg: false, finalize_chol: true,
|
351
478
|
na_as_zero: false, na_as_zero_user: false, na_as_zero_item: false,
|
352
479
|
nonneg: false, nonneg_c: false, nonneg_d: false, max_cd_steps: 100,
|
353
480
|
precompute_for_predictions: true, include_all_x: true,
|
354
|
-
use_float:
|
355
|
-
|
356
|
-
handle_interrupt: true, produce_dicts: false,
|
357
|
-
copy_data: true, nthreads: -1
|
481
|
+
use_float: true, random_state: 1, verbose: true, print_every: 10,
|
482
|
+
handle_interrupt: true, produce_dicts: false, nthreads: -1
|
358
483
|
)
|
359
|
-
|
360
484
|
@k = k
|
361
485
|
@k_user = k_user
|
362
486
|
@k_item = k_item
|
@@ -392,9 +516,17 @@ module Cmfrec
|
|
392
516
|
@random_state = random_state.to_i
|
393
517
|
@produce_dicts = !!produce_dicts
|
394
518
|
@handle_interrupt = !!handle_interrupt
|
395
|
-
@copy_data = !!copy_data
|
396
519
|
nthreads = Etc.nprocessors if nthreads < 0
|
397
520
|
@nthreads = nthreads
|
521
|
+
|
522
|
+
@center = center
|
523
|
+
@scale_lam = scale_lam
|
524
|
+
@scale_lam_sideinfo = scale_lam_sideinfo
|
525
|
+
@scale_bias_const = scale_bias_const
|
526
|
+
@l1_lambda = l1_lambda
|
527
|
+
@precondition_cg = precondition_cg
|
528
|
+
|
529
|
+
# TODO center_u, center_i
|
398
530
|
end
|
399
531
|
|
400
532
|
def update_maps(train_set)
|
@@ -443,26 +575,47 @@ module Cmfrec
|
|
443
575
|
end
|
444
576
|
end
|
445
577
|
|
446
|
-
def read_factors(ptr, d1, d2)
|
447
|
-
arr = []
|
448
|
-
offset = 0
|
578
|
+
def read_factors(ptr, d1, d2, id, map)
|
449
579
|
width = d2 * Fiddle::SIZEOF_DOUBLE
|
450
|
-
|
451
|
-
|
452
|
-
|
580
|
+
if id
|
581
|
+
i = map[id]
|
582
|
+
ptr[i * width, width].unpack("d*") if i
|
583
|
+
else
|
584
|
+
arr = []
|
585
|
+
offset = 0
|
586
|
+
d1.times do |i|
|
587
|
+
arr << ptr[offset, width].unpack("d*")
|
588
|
+
offset += width
|
589
|
+
end
|
590
|
+
arr
|
453
591
|
end
|
454
|
-
arr
|
455
592
|
end
|
456
593
|
|
457
|
-
def read_bias(ptr)
|
458
|
-
|
594
|
+
def read_bias(ptr, id, map)
|
595
|
+
if id
|
596
|
+
i = map[id]
|
597
|
+
ptr[i * Fiddle::SIZEOF_DOUBLE, Fiddle::SIZEOF_DOUBLE].unpack1("d") if i
|
598
|
+
else
|
599
|
+
real_array(ptr)
|
600
|
+
end
|
459
601
|
end
|
460
602
|
|
461
|
-
def
|
462
|
-
|
463
|
-
|
603
|
+
def prepare_top_n(count: nil, rated: nil, item_ids: nil)
|
604
|
+
if item_ids
|
605
|
+
# remove missing ids
|
606
|
+
item_ids = item_ids.map { |v| @item_map[v] }.compact
|
607
|
+
return [] if item_ids.empty?
|
608
|
+
|
609
|
+
include_ix = int_ptr(item_ids)
|
610
|
+
n_include = item_ids.size
|
464
611
|
|
465
|
-
|
612
|
+
count = n_include if n_include < count
|
613
|
+
else
|
614
|
+
include_ix = nil
|
615
|
+
n_include = 0
|
616
|
+
end
|
617
|
+
|
618
|
+
if rated && !item_ids
|
466
619
|
# assumes rated is unique and all items are known
|
467
620
|
# calling code is responsible for this
|
468
621
|
exclude_ix = int_ptr(rated)
|
@@ -478,145 +631,54 @@ module Cmfrec
|
|
478
631
|
outp_ix = Fiddle::Pointer.malloc(count * Fiddle::SIZEOF_INT)
|
479
632
|
outp_score = Fiddle::Pointer.malloc(count * Fiddle::SIZEOF_DOUBLE)
|
480
633
|
|
481
|
-
|
482
|
-
a_vec, @k_user,
|
483
|
-
@b, @k_item,
|
484
|
-
@bias_b, @global_mean, a_bias,
|
485
|
-
@k, @k_main,
|
486
|
-
include_ix, n_include,
|
487
|
-
exclude_ix, n_exclude,
|
488
|
-
outp_ix, outp_score,
|
489
|
-
count, @n,
|
490
|
-
@nthreads
|
491
|
-
)
|
492
|
-
|
493
|
-
imap = @item_map.map(&:reverse).to_h
|
494
|
-
item_ids = int_array(outp_ix).map { |v| imap[v] }
|
495
|
-
scores = real_array(outp_score)
|
496
|
-
|
497
|
-
item_ids.zip(scores).map do |item_id, score|
|
498
|
-
{item_id: item_id, score: score}
|
499
|
-
end
|
634
|
+
[include_ix, n_include, exclude_ix, n_exclude, outp_ix, outp_score, count]
|
500
635
|
end
|
501
636
|
|
502
|
-
def
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
# remove unknown items
|
507
|
-
data, unknown_data = data.partition { |d| @item_map[d[:item_id]] }
|
508
|
-
|
509
|
-
if unknown_data.any?
|
510
|
-
# TODO warn for unknown items?
|
511
|
-
# warn "[cmfrec] Unknown items: #{unknown_data.map { |d| d[:item_id] }.join(", ")}"
|
512
|
-
end
|
513
|
-
|
514
|
-
item_ids = data.map { |d| @item_map[d[:item_id]] }
|
515
|
-
|
516
|
-
nnz = data.size
|
517
|
-
a_vec = Fiddle::Pointer.malloc((@k_user + @k + @k_main) * Fiddle::SIZEOF_DOUBLE)
|
518
|
-
bias_a = Fiddle::Pointer.malloc(Fiddle::SIZEOF_DOUBLE)
|
519
|
-
|
520
|
-
u_vec_sp = []
|
521
|
-
u_vec_x_col = []
|
522
|
-
if user_info
|
523
|
-
user_info.each do |k, v|
|
524
|
-
next if k == :user_id
|
525
|
-
|
526
|
-
uc = @user_info_map[k]
|
527
|
-
raise "Bad key: #{k}" unless uc
|
528
|
-
|
529
|
-
u_vec_x_col << uc
|
530
|
-
u_vec_sp << v
|
531
|
-
end
|
532
|
-
end
|
533
|
-
p_ = @user_info_map.size
|
534
|
-
nnz_u_vec = u_vec_sp.size
|
535
|
-
u_vec_x_col = int_ptr(u_vec_x_col)
|
536
|
-
u_vec_sp = real_ptr(u_vec_sp)
|
537
|
-
|
538
|
-
u_vec = nil
|
539
|
-
u_bin_vec = nil
|
540
|
-
pbin = 0
|
541
|
-
|
542
|
-
weight = nil
|
543
|
-
lam_unique = nil
|
544
|
-
l1_lambda = 0
|
545
|
-
l1_lam_unique = nil
|
546
|
-
n_max = @n
|
547
|
-
|
548
|
-
if data.any?
|
549
|
-
if @implicit
|
550
|
-
ratings = data.map { |d| d[:value] || 1 }
|
551
|
-
else
|
552
|
-
ratings = data.map { |d| d[:rating] }
|
553
|
-
check_ratings(ratings)
|
554
|
-
end
|
555
|
-
xa = real_ptr(ratings)
|
556
|
-
x_col = int_ptr(item_ids)
|
557
|
-
else
|
558
|
-
xa = nil
|
559
|
-
x_col = nil
|
560
|
-
end
|
561
|
-
xa_dense = nil
|
637
|
+
def top_n(a_vec:, a_bias:, count:, rated: nil, item_ids: nil, row_index:)
|
638
|
+
prep = prepare_top_n(count: count, rated: rated, item_ids: item_ids)
|
639
|
+
return [] if prep.empty?
|
640
|
+
include_ix, n_include, exclude_ix, n_exclude, outp_ix, outp_score, count = prep
|
562
641
|
|
563
642
|
if @implicit
|
564
|
-
|
643
|
+
check_status FFI.topN_old_collective_implicit(
|
565
644
|
a_vec,
|
566
|
-
|
567
|
-
|
568
|
-
@na_as_zero_user,
|
569
|
-
@nonneg,
|
570
|
-
@u_colmeans,
|
571
|
-
@b, @n, @c,
|
572
|
-
xa, x_col, nnz,
|
645
|
+
@a, row_index,
|
646
|
+
@b,
|
573
647
|
@k, @k_user, @k_item, @k_main,
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
nil #BeTBeChol
|
580
|
-
]
|
581
|
-
check_status FFI.factors_collective_implicit_single(*fiddle_args(args))
|
648
|
+
include_ix, n_include,
|
649
|
+
exclude_ix, n_exclude,
|
650
|
+
outp_ix, outp_score,
|
651
|
+
count, @n, @nthreads
|
652
|
+
)
|
582
653
|
else
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
u_bin_vec, pbin,
|
593
|
-
@na_as_zero_user, @na_as_zero,
|
594
|
-
@nonneg,
|
595
|
-
@c, cb,
|
596
|
-
@global_mean, @bias_b, @u_colmeans,
|
597
|
-
xa, x_col, nnz, xa_dense,
|
598
|
-
@n, weight, @b, @bi,
|
599
|
-
@add_implicit_features,
|
654
|
+
# TODO add param
|
655
|
+
n_max = @n
|
656
|
+
|
657
|
+
check_status FFI.topN_old_collective_explicit(
|
658
|
+
a_vec, a_bias,
|
659
|
+
@a, @bias_a, row_index,
|
660
|
+
@b,
|
661
|
+
@bias_b,
|
662
|
+
@global_mean,
|
600
663
|
@k, @k_user, @k_item, @k_main,
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
@
|
605
|
-
|
606
|
-
@include_all_x,
|
607
|
-
nil, #BtB,
|
608
|
-
nil, #TransBtBinvBt,
|
609
|
-
nil, #BtXbias,
|
610
|
-
nil, #BeTBeChol,
|
611
|
-
nil, #BiTBi,
|
612
|
-
nil, #CtCw,
|
613
|
-
nil, #TransCtCinvCt,
|
614
|
-
nil #B_plus_bias
|
615
|
-
]
|
616
|
-
check_status FFI.factors_collective_explicit_single(*fiddle_args(args))
|
664
|
+
include_ix, n_include,
|
665
|
+
exclude_ix, n_exclude,
|
666
|
+
outp_ix, outp_score,
|
667
|
+
count, @n, n_max, @include_all_x ? 1 : 0, @nthreads
|
668
|
+
)
|
617
669
|
end
|
618
670
|
|
619
|
-
|
671
|
+
top_n_output(outp_ix, outp_score)
|
672
|
+
end
|
673
|
+
|
674
|
+
def top_n_output(outp_ix, outp_score)
|
675
|
+
imap = @item_map.map(&:reverse).to_h
|
676
|
+
item_ids = int_array(outp_ix).map { |v| imap[v] }
|
677
|
+
scores = real_array(outp_score)
|
678
|
+
|
679
|
+
item_ids.zip(scores).map do |item_id, score|
|
680
|
+
{item_id: item_id, score: score}
|
681
|
+
end
|
620
682
|
end
|
621
683
|
|
622
684
|
# convert boolean to int
|
data/lib/cmfrec/version.rb
CHANGED
data/lib/cmfrec.rb
CHANGED
@@ -15,19 +15,19 @@ module Cmfrec
|
|
15
15
|
class << self
|
16
16
|
attr_accessor :ffi_lib
|
17
17
|
end
|
18
|
-
|
18
|
+
lib_path =
|
19
19
|
if Gem.win_platform?
|
20
|
-
"cmfrec.dll"
|
20
|
+
"x64-mingw/cmfrec.dll"
|
21
21
|
elsif RbConfig::CONFIG["host_os"] =~ /darwin/i
|
22
|
-
if RbConfig::CONFIG["host_cpu"] =~ /arm/i
|
23
|
-
"libcmfrec.
|
22
|
+
if RbConfig::CONFIG["host_cpu"] =~ /arm|aarch64/i
|
23
|
+
"arm64-darwin/libcmfrec.dylib"
|
24
24
|
else
|
25
|
-
"libcmfrec.dylib"
|
25
|
+
"x86_64-darwin/libcmfrec.dylib"
|
26
26
|
end
|
27
27
|
else
|
28
|
-
"libcmfrec.so"
|
28
|
+
"x86_64-linux/libcmfrec.so"
|
29
29
|
end
|
30
|
-
vendor_lib = File.expand_path("../vendor/#{
|
30
|
+
vendor_lib = File.expand_path("../vendor/#{lib_path}", __dir__)
|
31
31
|
self.ffi_lib = [vendor_lib]
|
32
32
|
|
33
33
|
# friendlier error message
|
@@ -0,0 +1,57 @@
|
|
1
|
+
For the included LFBGS library (files "lbfgs.h", "lbfgs.c", "arithmetic_ansi.h"):
|
2
|
+
|
3
|
+
The MIT License
|
4
|
+
|
5
|
+
Copyright (c) 1990 Jorge Nocedal
|
6
|
+
Copyright (c) 2007-2010 Naoaki Okazaki
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
9
|
+
copy of this software and associated documentation files (the "Software"),
|
10
|
+
to deal in the Software without restriction, including without limitation
|
11
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
12
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
13
|
+
Software is furnished to do so, subject to the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be included in
|
16
|
+
all copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
THE SOFTWARE.
|
25
|
+
|
26
|
+
For the included ziggurat tables (file "ziggurat.h"):
|
27
|
+
|
28
|
+
Copyright (c) 2005-2022, NumPy Developers.
|
29
|
+
All rights reserved.
|
30
|
+
|
31
|
+
Redistribution and use in source and binary forms, with or without
|
32
|
+
modification, are permitted provided that the following conditions are
|
33
|
+
met:
|
34
|
+
|
35
|
+
* Redistributions of source code must retain the above copyright
|
36
|
+
notice, this list of conditions and the following disclaimer.
|
37
|
+
|
38
|
+
* Redistributions in binary form must reproduce the above
|
39
|
+
copyright notice, this list of conditions and the following
|
40
|
+
disclaimer in the documentation and/or other materials provided
|
41
|
+
with the distribution.
|
42
|
+
|
43
|
+
* Neither the name of the NumPy Developers nor the names of any
|
44
|
+
contributors may be used to endorse or promote products derived
|
45
|
+
from this software without specific prior written permission.
|
46
|
+
|
47
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
48
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
49
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
50
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
51
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
52
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
53
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
54
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
55
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
56
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
57
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020-2022 David Cortes
|
4
|
+
|
5
|
+
All rights reserved.
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
of this software and associated documentation files (the "Software"), to
|
9
|
+
deal in the Software without restriction, including without limitation the
|
10
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
11
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
12
|
+
furnished to do so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
15
|
+
all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
23
|
+
IN THE SOFTWARE.
|
Binary file
|
@@ -0,0 +1,57 @@
|
|
1
|
+
For the included LFBGS library (files "lbfgs.h", "lbfgs.c", "arithmetic_ansi.h"):
|
2
|
+
|
3
|
+
The MIT License
|
4
|
+
|
5
|
+
Copyright (c) 1990 Jorge Nocedal
|
6
|
+
Copyright (c) 2007-2010 Naoaki Okazaki
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
9
|
+
copy of this software and associated documentation files (the "Software"),
|
10
|
+
to deal in the Software without restriction, including without limitation
|
11
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
12
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
13
|
+
Software is furnished to do so, subject to the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be included in
|
16
|
+
all copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
THE SOFTWARE.
|
25
|
+
|
26
|
+
For the included ziggurat tables (file "ziggurat.h"):
|
27
|
+
|
28
|
+
Copyright (c) 2005-2022, NumPy Developers.
|
29
|
+
All rights reserved.
|
30
|
+
|
31
|
+
Redistribution and use in source and binary forms, with or without
|
32
|
+
modification, are permitted provided that the following conditions are
|
33
|
+
met:
|
34
|
+
|
35
|
+
* Redistributions of source code must retain the above copyright
|
36
|
+
notice, this list of conditions and the following disclaimer.
|
37
|
+
|
38
|
+
* Redistributions in binary form must reproduce the above
|
39
|
+
copyright notice, this list of conditions and the following
|
40
|
+
disclaimer in the documentation and/or other materials provided
|
41
|
+
with the distribution.
|
42
|
+
|
43
|
+
* Neither the name of the NumPy Developers nor the names of any
|
44
|
+
contributors may be used to endorse or promote products derived
|
45
|
+
from this software without specific prior written permission.
|
46
|
+
|
47
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
48
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
49
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
50
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
51
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
52
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
53
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
54
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
55
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
56
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
57
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020-2022 David Cortes
|
4
|
+
|
5
|
+
All rights reserved.
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
of this software and associated documentation files (the "Software"), to
|
9
|
+
deal in the Software without restriction, including without limitation the
|
10
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
11
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
12
|
+
furnished to do so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
15
|
+
all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
23
|
+
IN THE SOFTWARE.
|
Binary file
|
@@ -0,0 +1,57 @@
|
|
1
|
+
For the included LFBGS library (files "lbfgs.h", "lbfgs.c", "arithmetic_ansi.h"):
|
2
|
+
|
3
|
+
The MIT License
|
4
|
+
|
5
|
+
Copyright (c) 1990 Jorge Nocedal
|
6
|
+
Copyright (c) 2007-2010 Naoaki Okazaki
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
9
|
+
copy of this software and associated documentation files (the "Software"),
|
10
|
+
to deal in the Software without restriction, including without limitation
|
11
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
12
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
13
|
+
Software is furnished to do so, subject to the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be included in
|
16
|
+
all copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
THE SOFTWARE.
|
25
|
+
|
26
|
+
For the included ziggurat tables (file "ziggurat.h"):
|
27
|
+
|
28
|
+
Copyright (c) 2005-2022, NumPy Developers.
|
29
|
+
All rights reserved.
|
30
|
+
|
31
|
+
Redistribution and use in source and binary forms, with or without
|
32
|
+
modification, are permitted provided that the following conditions are
|
33
|
+
met:
|
34
|
+
|
35
|
+
* Redistributions of source code must retain the above copyright
|
36
|
+
notice, this list of conditions and the following disclaimer.
|
37
|
+
|
38
|
+
* Redistributions in binary form must reproduce the above
|
39
|
+
copyright notice, this list of conditions and the following
|
40
|
+
disclaimer in the documentation and/or other materials provided
|
41
|
+
with the distribution.
|
42
|
+
|
43
|
+
* Neither the name of the NumPy Developers nor the names of any
|
44
|
+
contributors may be used to endorse or promote products derived
|
45
|
+
from this software without specific prior written permission.
|
46
|
+
|
47
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
48
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
49
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
50
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
51
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
52
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
53
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
54
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
55
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
56
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
57
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020-2022 David Cortes
|
4
|
+
|
5
|
+
All rights reserved.
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
of this software and associated documentation files (the "Software"), to
|
9
|
+
deal in the Software without restriction, including without limitation the
|
10
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
11
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
12
|
+
furnished to do so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
15
|
+
all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
23
|
+
IN THE SOFTWARE.
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cmfrec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: andrew@ankane.org
|
@@ -24,11 +24,16 @@ files:
|
|
24
24
|
- lib/cmfrec/ffi.rb
|
25
25
|
- lib/cmfrec/recommender.rb
|
26
26
|
- lib/cmfrec/version.rb
|
27
|
-
- vendor/
|
28
|
-
- vendor/
|
29
|
-
- vendor/libcmfrec.dylib
|
30
|
-
- vendor/
|
31
|
-
|
27
|
+
- vendor/arm64-darwin/COPYRIGHTS
|
28
|
+
- vendor/arm64-darwin/LICENSE
|
29
|
+
- vendor/arm64-darwin/libcmfrec.dylib
|
30
|
+
- vendor/x86_64-darwin/COPYRIGHTS
|
31
|
+
- vendor/x86_64-darwin/LICENSE
|
32
|
+
- vendor/x86_64-darwin/libcmfrec.dylib
|
33
|
+
- vendor/x86_64-linux/COPYRIGHTS
|
34
|
+
- vendor/x86_64-linux/LICENSE
|
35
|
+
- vendor/x86_64-linux/libcmfrec.so
|
36
|
+
homepage: https://github.com/ankane/cmfrec-ruby
|
32
37
|
licenses:
|
33
38
|
- MIT
|
34
39
|
metadata: {}
|
@@ -40,14 +45,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
45
|
requirements:
|
41
46
|
- - ">="
|
42
47
|
- !ruby/object:Gem::Version
|
43
|
-
version: '2.
|
48
|
+
version: '2.7'
|
44
49
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
50
|
requirements:
|
46
51
|
- - ">="
|
47
52
|
- !ruby/object:Gem::Version
|
48
53
|
version: '0'
|
49
54
|
requirements: []
|
50
|
-
rubygems_version: 3.
|
55
|
+
rubygems_version: 3.3.7
|
51
56
|
signing_key:
|
52
57
|
specification_version: 4
|
53
58
|
summary: Recommendations for Ruby using collective matrix factorization
|
data/vendor/LICENSE.txt
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
MIT License
|
2
|
-
|
3
|
-
Copyright (c) 2020 David Cortes
|
4
|
-
|
5
|
-
All rights reserved.
|
6
|
-
|
7
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
-
of this software and associated documentation files (the "Software"), to
|
9
|
-
deal in the Software without restriction, including without limitation the
|
10
|
-
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
11
|
-
sell copies of the Software, and to permit persons to whom the Software is
|
12
|
-
furnished to do so, subject to the following conditions:
|
13
|
-
|
14
|
-
The above copyright notice and this permission notice shall be included in
|
15
|
-
all copies or substantial portions of the Software.
|
16
|
-
|
17
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
23
|
-
IN THE SOFTWARE.
|
24
|
-
|
25
|
-
---
|
26
|
-
|
27
|
-
ANSI C implementation of vector operations.
|
28
|
-
|
29
|
-
Copyright (c) 2007-2010 Naoaki Okazaki
|
30
|
-
All rights reserved.
|
31
|
-
|
32
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
33
|
-
of this software and associated documentation files (the "Software"), to deal
|
34
|
-
in the Software without restriction, including without limitation the rights
|
35
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
36
|
-
copies of the Software, and to permit persons to whom the Software is
|
37
|
-
furnished to do so, subject to the following conditions:
|
38
|
-
|
39
|
-
The above copyright notice and this permission notice shall be included in
|
40
|
-
all copies or substantial portions of the Software.
|
41
|
-
|
42
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
43
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
44
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
45
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
46
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
47
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
48
|
-
THE SOFTWARE.
|
49
|
-
|
50
|
-
---
|
51
|
-
|
52
|
-
C library of Limited memory BFGS (L-BFGS).
|
53
|
-
|
54
|
-
Copyright (c) 1990, Jorge Nocedal
|
55
|
-
Copyright (c) 2007-2010 Naoaki Okazaki
|
56
|
-
All rights reserved.
|
57
|
-
|
58
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
59
|
-
of this software and associated documentation files (the "Software"), to deal
|
60
|
-
in the Software without restriction, including without limitation the rights
|
61
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
62
|
-
copies of the Software, and to permit persons to whom the Software is
|
63
|
-
furnished to do so, subject to the following conditions:
|
64
|
-
|
65
|
-
The above copyright notice and this permission notice shall be included in
|
66
|
-
all copies or substantial portions of the Software.
|
67
|
-
|
68
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
69
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
70
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
71
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
72
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
73
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
74
|
-
THE SOFTWARE.
|
Binary file
|
data/vendor/libcmfrec.dylib
DELETED
Binary file
|
data/vendor/libcmfrec.so
DELETED
Binary file
|