CVXR:as.vector(数据)中的错误:没有将此 S4 class 强制转换为向量的方法

CVXR: Error in as.vector(data): no method for coercing this S4 class to a vector

我正在尝试尽量减少 R 的以下问题:

\min \sum_{t=1}^T \| y_t - \delta \|_2

其中 y_t 对于 t = 1,...,T 和 \delta 是向量
这是我试过的:

deltaHat <- Variable(p)

objective <- sum(col.norm(y - matrix(deltaHat, ncol=obs, 
                                     nrow=p, byrow=FALSE)))
problem <- Problem(Minimize(objective))
result <- solve(problem)
delta <-  matrix(result$getValue(deltaHat), ncol = 1)

这是我在编译 objective 时收到的错误消息:

Error in as.vector(data) : 
  no method for coercing this S4 class to a vector

据我所知,这里的 betaHat 不是数值,这就是出现错误的原因。 那么,如何编写具有相同列的矩阵呢? 如果 y 有 2 列

,我尝试将其作为多个约束
delta_1 <- Variable(p)
delta_2 <- Variable(p)
objective <- norm(y[,1]-delta_1, type="2") + norm(y[,2]-delta_2, type="2")
constraints <- list( delta_1 == delta_2)
problem <- Problem(Minimize(objective), constraints)
result <- solve(problem)

这可行,但我如何为 T 列重复该操作?是否可以在循环中创建多个变量?然后求和?

您在顶部的代码摘录使用了 col.norm,这是我不知道的功能。因此,我将使用一个可重现的示例来进行第二个示例,其中 delta 有 5 列。

library(CVXR)
set.seed(123)
n  <- 10
p  <- 5
delta  <- Variable(n, p)  # n by p matrix
A <- matrix(rnorm(n * p), nrow = n)
col_diffs <- lapply(X = seq_len(p), FUN = function(j) delta[, j] - A[, j])
col_diff_norms <- lapply(X = col_diffs, FUN = cvxr_norm, p = 2)
objective  <- Reduce(f = sum, x = col_diff_norms)
constraints <- lapply(2:p, function(j) delta[, j] == delta[, 1])
problem <- Problem(Minimize(objective), constraints)
## Specify solver to avoid automatic use of commercial solvers I have
system.time(result <- solve(problem, solver = "ECOS", verbose = TRUE))
result$value
result$getValue(delta)
## Always post session info to help others
sessionInfo()

结果如下。

ECOS 2.0.7 - (C) embotech GmbH, Zurich Switzerland, 2012-15. Web: www.embotech.com/ECOS

It     pcost       dcost      gap   pres   dres    k/t    mu     step   sigma     IR    |   BT
 0  +0.000e+00  -0.000e+00  +6e+01  5e-01  3e-04  1e+00  1e+01    ---    ---    1  1  - |  -  - 
 1  +4.960e+00  +5.047e+00  +1e+01  1e-01  5e-05  3e-01  2e+00  0.8458  1e-02   2  2  2 |  0  0
 2  +1.242e+01  +1.246e+01  +8e-01  9e-03  4e-06  6e-02  1e-01  0.9369  3e-02   2  2  2 |  0  0
 3  +1.284e+01  +1.284e+01  +3e-02  4e-04  2e-07  3e-03  6e-03  0.9580  4e-04   2  2  2 |  0  0
 4  +1.286e+01  +1.286e+01  +2e-03  2e-05  9e-09  2e-04  4e-04  0.9410  1e-03   2  2  2 |  0  0
 5  +1.286e+01  +1.286e+01  +2e-04  2e-06  1e-09  2e-05  4e-05  0.8911  2e-03   2  1  1 |  0  0
 6  +1.286e+01  +1.286e+01  +5e-05  5e-07  2e-10  4e-06  9e-06  0.7863  1e-02   2  1  1 |  0  0
 7  +1.286e+01  +1.286e+01  +3e-06  3e-08  1e-11  5e-07  5e-07  0.9890  5e-02   2  1  1 |  0  0
 8  +1.286e+01  +1.286e+01  +2e-07  2e-09  2e-12  3e-08  3e-08  0.9387  7e-04   2  1  1 |  0  0
 9  +1.286e+01  +1.286e+01  +1e-08  1e-10  8e-13  2e-09  2e-09  0.9890  6e-02   2  1  1 |  0  0

OPTIMAL (within feastol=1.3e-10, reltol=9.3e-10, abstol=1.2e-08).
Runtime: 0.000648 seconds.

> result$value
[1] 12.85991
> result$getValue(delta)
             [,1]        [,2]        [,3]        [,4]        [,5]
 [1,]  0.05115646  0.05115646  0.05115646  0.05115646  0.05115646
 [2,] -0.15827438 -0.15827438 -0.15827438 -0.15827438 -0.15827438
 [3,]  0.49632013  0.49632013  0.49632013  0.49632013  0.49632013
 [4,]  0.57015571  0.57015571  0.57015571  0.57015571  0.57015571
 [5,]  0.34898918  0.34898918  0.34898918  0.34898918  0.34898918
 [6,]  0.61539678  0.61539678  0.61539678  0.61539678  0.61539678
 [7,]  0.43976476  0.43976476  0.43976476  0.43976476  0.43976476
 [8,] -0.64837389 -0.64837389 -0.64837389 -0.64837389 -0.64837389
 [9,] -0.18336475 -0.18336475 -0.18336475 -0.18336475 -0.18336475
[10,] -0.20182226 -0.20182226 -0.20182226 -0.20182226 -0.20182226
> ## Always post session info to help others
> sessionInfo()
R version 3.6.3 (2020-02-29)
Platform: x86_64-apple-darwin19.3.0 (64-bit)
Running under: macOS Catalina 10.15.4

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
[1] CVXR_1.0-1     rmarkdown_2.1  knitr_1.28     pkgdown_1.5.1  devtools_2.3.0
[6] usethis_1.6.0 

loaded via a namespace (and not attached):
 [1] gmp_0.5-13.6      Rcpp_1.0.4.6      compiler_3.6.3    prettyunits_1.1.1
 [5] remotes_2.1.1     tools_3.6.3       bit_1.1-15.2      testthat_2.3.2   
 [9] digest_0.6.25     pkgbuild_1.0.6    pkgload_1.0.2     memoise_1.1.0    
[13] evaluate_0.14     lattice_0.20-41   rlang_0.4.5       Matrix_1.2-18    
[17] gurobi_9.0-1      cli_2.0.2         Rglpk_0.6-4       xfun_0.13        
[21] ECOSolveR_0.5.3   Rmpfr_0.8-1       withr_2.1.2       desc_1.2.0       
[25] fs_1.4.1          rprojroot_1.3-2   bit64_0.9-7       grid_3.6.3       
[29] glue_1.4.0        R6_2.4.1          processx_3.4.2    fansi_0.4.1      
[33] sessioninfo_1.1.1 callr_3.4.3       magrittr_1.5      rcbc_0.1.0.9001  
[37] backports_1.1.6   ps_1.3.2          ellipsis_0.3.0    htmltools_0.4.0  
[41] MASS_7.3-51.5     assertthat_0.2.1  Rcplex_0.3-3      Rmosek_9.1.0     
[45] slam_0.1-47       crayon_1.3.4 

我找到了解决问题的方法:

delta <- Variable(p)
objective <- norm(y[,1]-delta, type = "2")
for (s in 2:obs){
  objective <- objective + norm(y[,s]-delta, type = "2")
}
problem <- Problem(Minimize(objective))
result <- solve(problem)
delta_one <-  matrix(result$getValue(delta), ncol = 1)

这是解决问题所花费的时间:

system.time(result <- solve(problem))

user  system elapsed 
1.61    0.00    1.69