Diagnosing Infeasible Constraints in a Quadratic Portfolio Optimization
Summary
This question concerns a quadratic program for portfolio weights that fails with an error reporting inconsistent constraints. The setup uses an identity objective matrix, zero linear term, return data for 15 assets, a fully invested constraint, and individual lower-bound constraints. The accepted answer identifies matrix orientation as the key issue: `solve.QP` expects constraint vectors as columns of `Amat`, but the supplied matrix and transposition arguments do not match that convention.
The answer reconstructs the constraint matrix in the expected orientation and calls the solver with the corresponding right-hand side vector. It reports a feasible solution with the weights summing to one and most constraints inactive. This is a specific debugging example rather than a general treatment of quadratic programming; the displayed matrix is lengthy, and the post does not explain how to systematically detect infeasibility or assess whether the portfolio constraints reflect sound investment assumptions.
Key ideas
- The quadratic programming solver expects constraint vectors as columns of its constraint matrix.
- The orientation of the constraint matrix and matching lower-bound vector can cause a false infeasibility error.
- A feasible solution is reported after supplying the matrices in the expected orientation.
- The example uses a full-investment constraint alongside asset-level constraints.
Tags
Full text
# solve.QP error: constraints are inconsistent, no solution!
# solve.QP error: constraints are inconsistent, no solution!
I am trying to solve a constrained optimization with the following statement and struggling with the error `constraints are inconsistent, no solution!`:
```
solve.QP(2 * Dmat, dvec, t(Amat), t(bvec1), NumRec+1, factorized = FALSE)
```
```
Numrec = 15
```
The matrices are:
Dmat (15 x 15):
```
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
```
Dvec (1 x 15):
`0 0 0 0 0 0 0 0 0 0 0 0 0 0`
t(bvec1) (1 x 29):
```
-0.02269294 0.07120749 -0.01830448 0.04465172 0.03508689 -0.0003176476 0.01089419 0.06466093 0.01265293 -0.02748855 0.04753743 -0.000408749 0.03108376 -0.07378021 -0.0608137 1 0 0 0 0 0 0 0 0 0 0 0 0 0
```
Amat (29 x 15):
```
1 -0.013959391 -0.0035813073 -0.038078917 0.0124926605 -0.002016983 -0.0032304378 0.010058027 -0.044171141 -0.055580295 -0.014411096 0.0008017905 -0.0259418441 -0.056603718 1
1 0.039691156 0.0084864014 0.003370366 -0.0071331985 0.0109135 0.0119733703 0.033320528 0.050453417 0.042508974 0.120962364 0.0304405599 0.0254747337 -0.015625 1
1 -0.018320518 -0.0082170279 -0.041101627 -0.0405825243 -0.007596961 -0.0168135124 -0.072646369 -0.04816928 -0.054911181 -0.013992648 -0.0690593677 -0.0417795628 -0.060634921 1
1 0.023857612 0.0102814833 -0.022410771 0.0321797207 0.00926668 0.0098625048 0.007793745 0.035395618 0.069127505 -0.023812435 0.099373698 0.0200329719 -0.059479554 1
1 0.027538287 0.0027665152 0.021366548 -0.0386274706 0.007584871 0.0025087178 -0.012889173 0.018929178 -0.00188323 0.177651822 0.0200025578 -0.0006931377 -0.100970176 1
1 -0.008198327 -0.0080796139 -0.046851101 -0.0356924339 -0.003565769 -0.0007149969 -0.055243071 0.003743297 0.024797798 -0.016424302 0.0053369741 -0.0254334798 -0.137490008 1
1 -0.029003723 0.0218536311 0.006401417 0.0177664978 0.029423419 0.0274572852 -0.000212609 -0.01125694 -0.035858295 -0.106466659 0.0685185556 0.0028469275 -0.087117655 1
1 0.056454484 -0.0083600756 0.060199864 0.062344141 -0.018539939 -0.0138404948 0.042109741 0.050848635 0.060107311 0.148315661 -0.0367417665 0.0007096996 0.05939086 1
1 -0.020639955 0.007254171 -0.025283824 0.0031298905 0.005116135 0.00070617 -0.013673429 0.010169485 0.012437785 -0.075256576 0.0112749786 -0.0108746811 -0.065644511 1
1 0.009719501 -0.0064233966 0.04528461 0.0325663423 -0.007047768 -0.0112905263 0.072625654 -0.014212324 -0.023044997 -0.029705202 -0.05847469 0.0446940488 0.109230718 1
1 0.013009273 -0.0031344795 0.002944269 -0.0030217185 -0.003943257 -0.0141849947 -0.036458314 0.01668669 0.014569422 0.191659016 -0.0030234065 -0.0134980557 -0.021729035 1
1 -0.025966713 -0.0122825984 -0.049695933 -0.0284144719 -0.009501188 -0.0174660634 -0.038238237 -0.015362466 0.007607479 -0.178381014 -0.0562294296 -0.0579777379 -0.002362902 1
1 0.022505569 -0.0005968763 0.024492498 0.0003899396 0.009592326 0.005618495 -0.065570398 0.00020002 -0.008313497 -0.115752189 0.0577051531 0.0046775481 -0.141639027 1
1 -0.061496334 -0.0006967948 -0.066551798 -0.0783863364 -0.001979454 -0.0127312603 -0.093562043 -0.055996229 -0.051924721 -0.074326112 -0.0629114051 -0.0529281781 0.002759327 1
1 -0.030095602 -0.0013945513 -0.039224758 -0.0485957557 0.0079334 0.0062157713 -0.019660851 -0.035308241 -0.038437264 -0.004180496 0.0203971636 -0.023803414 -0.059988993 1
0 1 1 1 1 1 1 1 1 1 1 1 1 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
```
dput:
```
structure(list(`rep(1, NumRec)` = c(1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
AAA = c(-0.01395939086, 0.03969115573, -0.01832051828, 0.02385761182,
0.02753828692, -0.008198326702, -0.02900372285, 0.0564544844,
-0.02063995502, 0.009719501422, 0.01300927292, -0.02596671346,
0.02250556865, -0.06149633449, -0.03009560186, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0), BBB = c(-0.003581307309,
0.008486401418, -0.008217027854, 0.01028148333, 0.002766515194,
-0.008079613914, 0.02185363111, -0.00836007558, 0.007254171017,
-0.006423396594, -0.003134479504, -0.01228259838, -0.0005968762613,
-0.0006967947511, -0.001394551264, 1, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0), CCC = c(-0.03807891663, 0.003370365648,
-0.04110162737, -0.02241077072, 0.02136654796, -0.04685110148,
0.006401417174, 0.0601998637, -0.02528382367, 0.04528461001,
0.002944269252, -0.0496959331, 0.02449249779, -0.06655179841,
-0.03922475773, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
DDD = c(0.01249266055, -0.007133198518, -0.04058252427,
0.0321797207, -0.03862747059, -0.03569243393, 0.01776649784,
0.06234414095, 0.003129890515, 0.03256634229, -0.003021718545,
-0.0284144719, 0.0003899395518, -0.07838633642, -0.04859575573,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0), EEE = c(-0.002016982573,
0.0109135004, -0.007596961216, 0.009266680097, 0.007584870562,
-0.003565768621, 0.02942341948, -0.01853993892, 0.00511613538,
-0.007047767931, -0.003943256942, -0.009501187648, 0.009592326139,
-0.001979453682, 0.007933399759, 1, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0), FFF = c(-0.003230437846, 0.01197337033,
-0.01681351243, 0.009862504792, 0.002508717834, -0.0007149968783,
0.02745728517, -0.01384049479, 0.0007061699999, -0.0112905263,
-0.01418499471, -0.01746606335, 0.00561849498, -0.0127312603,
0.00621577135, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0),
GGG = c(0.01005802688, 0.0333205279, -0.07264636903, 0.007793744848,
-0.01288917311, -0.05524307062, -0.0002126089775, 0.04210974054,
-0.01367342857, 0.07262565394, -0.03645831404, -0.03823823747,
-0.0655703983, -0.09356204263, -0.01966085081, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0, 0, 0), HHH = c(-0.0441711414, 0.05045341659,
-0.0481692803, 0.03539561813, 0.01892917758, 0.003743296955,
-0.01125694037, 0.0508486352, 0.01016948508, -0.01421232436,
0.01668668992, -0.01536246647, 0.000200020008, -0.05599622878,
-0.03530824069, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0),
III = c(-0.05558029461, 0.04250897372, -0.05491118109, 0.0691275052,
-0.00188323017, 0.02479779807, -0.03585829451, 0.06010731054,
0.012437785, -0.02304499723, 0.01456942181, 0.007607479402,
-0.008313496988, -0.0519247211, -0.03843726358, 1, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), JJJ = c(-0.01441109618,
0.1209623639, -0.0139926476, -0.02381243479, 0.1776518216,
-0.01642430239, -0.1064666594, 0.1483156613, -0.07525657639,
-0.02970520154, 0.1916590155, -0.1783810145, -0.1157521888,
-0.07432611224, -0.004180495711, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0), KKK = c(0.0008017905292, 0.03044055993,
-0.06905936771, 0.09937369796, 0.02000255779, 0.00533697406,
0.06851855556, -0.03674176649, 0.0112749786, -0.05847469004,
-0.003023406514, -0.05622942957, 0.05770515309, -0.06291140506,
0.02039716359, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0),
LLL = c(-0.02594184408, 0.02547473367, -0.04177956282, 0.02003297195,
-0.000693137724, -0.02543347977, 0.002846927504, 0.0007096995505,
-0.01087468111, 0.04469404876, -0.01349805567, -0.05797773789,
0.004677548121, -0.05292817807, -0.02380341403, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0), MMM = c(-0.05660371796,
-0.015625, -0.06063492063, -0.0594795539, -0.1009701761,
-0.137490008, -0.08711765524, 0.05939085993, -0.06564451051,
0.1092307179, -0.02172903475, -0.002362901701, -0.1416390269,
0.002759326559, -0.05998899285, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1), `rep(1, NumRec)` = c(1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0)), row.names = c(NA, -29L), class = "data.frame")
```
Thanks in advance!
## Answer by AK88 (score 1)
https://quant.stackexchange.com/a/50048
Check this out:
```
library(quadprog)
Dmat <- matrix(0,15,15)
diag(Dmat) <- 1
dvec <- matrix(0,1,15)
bvec <- c(-0.02269294, 0.07120749, -0.01830448, 0.04465172, 0.03508689,
-0.0003176476, 0.01089419, 0.06466093, 0.01265293, -0.02748855,
0.04753743, -0.000408749, 0.03108376, -0.07378021, -0.0608137,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
```
Then I read your `Amat` with Excel and got this:
```
dat <- read.table(file = "clipboard", sep = "\t", header = FALSE) ## copy the data
Amat <- as.matrix(dat)
Amat <- t(Amat)
> dput(Amat)
structure(c(1, -0.013959391, -0.003581307, -0.038078917, 0.012492661,
-0.002016983, -0.003230438, 0.010058027, -0.044171141, -0.055580295,
-0.014411096, 0.000801791, -0.025941844, -0.056603718, 1, 1,
0.039691156, 0.008486401, 0.003370366, -0.007133199, 0.0109135,
0.01197337, 0.033320528, 0.050453417, 0.042508974, 0.120962364,
0.03044056, 0.025474734, -0.015625, 1, 1, -0.018320518, -0.008217028,
-0.041101627, -0.040582524, -0.007596961, -0.016813512, -0.072646369,
-0.04816928, -0.054911181, -0.013992648, -0.069059368, -0.041779563,
-0.060634921, 1, 1, 0.023857612, 0.010281483, -0.022410771, 0.032179721,
0.00926668, 0.009862505, 0.007793745, 0.035395618, 0.069127505,
-0.023812435, 0.099373698, 0.020032972, -0.059479554, 1, 1, 0.027538287,
0.002766515, 0.021366548, -0.038627471, 0.007584871, 0.002508718,
-0.012889173, 0.018929178, -0.00188323, 0.177651822, 0.020002558,
-0.000693138, -0.100970176, 1, 1, -0.008198327, -0.008079614,
-0.046851101, -0.035692434, -0.003565769, -0.000714997, -0.055243071,
0.003743297, 0.024797798, -0.016424302, 0.005336974, -0.02543348,
-0.137490008, 1, 1, -0.029003723, 0.021853631, 0.006401417, 0.017766498,
0.029423419, 0.027457285, -0.000212609, -0.01125694, -0.035858295,
-0.106466659, 0.068518556, 0.002846928, -0.087117655, 1, 1, 0.056454484,
-0.008360076, 0.060199864, 0.062344141, -0.018539939, -0.013840495,
0.042109741, 0.050848635, 0.060107311, 0.148315661, -0.036741767,
0.0007097, 0.05939086, 1, 1, -0.020639955, 0.007254171, -0.025283824,
0.003129891, 0.005116135, 0.00070617, -0.013673429, 0.010169485,
0.012437785, -0.075256576, 0.011274979, -0.010874681, -0.065644511,
1, 1, 0.009719501, -0.006423397, 0.04528461, 0.032566342, -0.007047768,
-0.011290526, 0.072625654, -0.014212324, -0.023044997, -0.029705202,
-0.05847469, 0.044694049, 0.109230718, 1, 1, 0.013009273, -0.00313448,
0.002944269, -0.003021719, -0.003943257, -0.014184995, -0.036458314,
0.01668669, 0.014569422, 0.191659016, -0.003023407, -0.013498056,
-0.021729035, 1, 1, -0.025966713, -0.012282598, -0.049695933,
-0.028414472, -0.009501188, -0.017466063, -0.038238237, -0.015362466,
0.007607479, -0.178381014, -0.05622943, -0.057977738, -0.002362902,
1, 1, 0.022505569, -0.000596876, 0.024492498, 0.00038994, 0.009592326,
0.005618495, -0.065570398, 0.00020002, -0.008313497, -0.115752189,
0.057705153, 0.004677548, -0.141639027, 1, 1, -0.061496334, -0.000696795,
-0.066551798, -0.078386336, -0.001979454, -0.01273126, -0.093562043,
-0.055996229, -0.051924721, -0.074326112, -0.062911405, -0.052928178,
0.002759327, 1, 1, -0.030095602, -0.001394551, -0.039224758,
-0.048595756, 0.0079334, 0.006215771, -0.019660851, -0.035308241,
-0.038437264, -0.004180496, 0.020397164, -0.023803414, -0.059988993,
1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0), .Dim = c(15L, 29L), .Dimnames = list(c("V1", "V2", "V3",
"V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13",
"V14", "V15"), NULL))
```
And finally:
```
solve.QP(Dmat,dvec,Amat,bvec)
```
Gives the following output:
```
> solve.QP(Dmat,dvec,Amat,bvec)
$`solution`
[1] 0.02304078 0.07780795 0.07727566 0.07785373 0.07729839 0.07751042 0.07741886 0.07577862 0.07729402 0.07709786
[11] 0.07462239 0.07861898 0.07739718 0.07402593 0.02304078
$value
[1] 0.0390028
$unconstrained.solution
[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
$iterations
[1] 3 0
$Lagrangian
[1] 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
[11] 0.00000000 0.00000000 0.02304078 0.00000000 0.00000000 0.07728941 0.00000000 0.00000000 0.00000000 0.00000000
[21] 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
$iact
[1] 16 13
```Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.