Solving SDP problem with cvx - difference between MATLAB and R solution - r

I solved the following Linear Matrix Inequality (LMI) problem using cvx in Matlab:
Lhs = [19.467593196, 1.82394007, 0.1625838, 0.01685267, 0.002495194;
1.823940068, 1.78664305, 0.9845668, 0.32951706, 0.010431878;
0.162583843, 0.98456679, 1.2333818, 0.92276329, 0.132643463;
0.016852668, 0.32951706, 0.9227633, 1.55698000, 0.848190932;
0.002495194, 0.01043188, 0.1326435, 0.84819093, 0.638889503];
S = [0.001, -0.001, 0, 0, 0;
-0.001, 0.001, 0, 0, 0;
0, 0, 0, 0, 0;
0, 0, 0, 0.001 -0.001;
0, 0, 0, -0.001, 0.001];
cvx_begin sdp
variable t;
minimize t;
Lhs+t*S >= 0;
cvx_end
The result makes sense.
I need to solve the same problem in R. As far as I understood, it can't be expressed as a LMI with CVXR. Thus, I exploited the dual formulation to write the problem as
cvx_begin sdp
variable X(5,5) symmetric;
maximize -trace(Lhs*X);
trace(S*X) == 1;
X >= 0;
cvx_end
As expected, the result in Matlab is the same as in the primal formulation.
However, if I solve the dual problem in R:
Lhs = matrix(c(19.467593196, 1.82394007, 0.1625838, 0.01685267, 0.002495194,
1.823940068, 1.78664305, 0.9845668, 0.32951706, 0.010431878,
0.162583843, 0.98456679, 1.2333818, 0.92276329, 0.132643463,
0.016852668, 0.32951706, 0.9227633, 1.55698000, 0.848190932,
0.002495194, 0.01043188, 0.1326435, 0.84819093, 0.638889503), ncol = 5, byrow = T)
S = matrix(c(0.001, -0.001, 0, 0, 0,
-0.001, 0.001, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0.001, -0.001,
0, 0, 0, -0.001, 0.001), ncol = 5, byrow = T)
X = Variable(k, k, PSD = T)
constr = list(matrix_trace(S%*%X) == 1,
X >= 0)
prob = Problem(Maximize(-matrix_trace(Lhs%*%X)), constr)
the result is totally wrong. Where is the mistake?

Related

ICC unused argument

I need to calculate the 95% CI of iCC.
I'm using this code:
icc(mydata[,c(1,2)], model = "twoway",type = "agreement", unit = "average")
I obtain this error message.
Error in icc(mydata[, c(1, 1)], model = "twoway", type = "agreement", :
unused arguments (model = "twoway", type = "agreement", unit = "average")
My data:
mydata= data.frame(A=c(0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 3), B=c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 2))
How can I fix it?
Thank you!
You might have competing packages loaded that both use icc(). The psych package and the irr package both have this as a function name. If both are loaded, the psych package is likely masking the irr command. Those are not valid arguments for psych::icc() but they are for irr::icc()
Try:
irr:: icc(mydata[,c(1,2)], model = "twoway",type = "agreement", unit = "average")

What does this error mean "order(vertex_attr(g, measure), decreasing = TRUE) : argument 1 is not a vector" in R?

I am trying to calculate robustness, a graph theory measure using R (braingraph package).
Robustness = robustness(my_networkgraph, type = c("vertex"), measure = ("btwn.cent"))
I get the following error, when I use the above robustness function:
Error in order(vertex_attr(g, measure), decreasing = TRUE) : argument 1 is not a vector
Any idea, what I am doing wrong here?
My network, which is a matrix has been converted to igraph object and robustness was calculated.
My network as a matrix:
mynetwork <- matrix(c(0, 1, 0, 1, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 1, 1, 0, 1, 1,
0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0), nrow = 8)
This matrix was converted as igraph using the following code:
my_networkgraph <-graph_from_adjacency_matrix(mynetwork, mode = c("undirected"),weighted = NULL, diag = TRUE, add.colnames = NULL, add.rownames = NA)
Please help me to understand the above error
Thanks
Priya
There was a bug in the above function. To run the robustness code, you will need to supply a vertex attribute to your network: V(network)$degree <- degree(network) V(network)$btwn.cent <- centr_betw(network)$res

Planned Contrasts on glmmTMB

Apologies if this is a repeat question. Many have posted looking looking for a way to do post-hoc analyses on the conditional model (fixed factors) in glmmTMB. I want to do plannned contrasts between certain groups, not test every pairwise comparison (e.g. Tukey).
The code below worked well on nlme:lme for a lmm. However, it returns an error on the code below.
Error in modelparm.default(model, ...) :
dimensions of coefficients and covariance matrix don't match
Is there a way to do planned contrasts on a glmmTMB?
#filtdens is a dataframe and TRT,DATE,BURN,VEG are factors
filtdens <- merged %>% filter(!BLOCK %in% c("JB2","JB4","JB5") & MEAS =="DENS" &
group == "TOT" & BURN == "N" & VEG == "C")
filtdens$TD <- interaction(filtdens$TRT, filtdens$DATE)
mod2 <- glmmTMB(count~(TD)+(1|BLOCK),
data=filtdens,
zi=~1,
family=nbinom1(link = "log"))
k1 <- matrix(c(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1), byrow = T, ncol = 12)
summary(glht(mod2, linfct=k1),test=adjusted("bonferroni"))
A reproducible example would be helpful, but: this vignette in the development version offers code that ought to enable multcomp::linfct, i.e.:
glht_glmmTMB <- function (model, ..., component="cond") {
glht(model, ...,
coef. = function(x) fixef(x)[[component]],
vcov. = function(x) vcov(x)[[component]],
df = NULL)
}
modelparm.glmmTMB <- function (model,
coef. = function(x) fixef(x)[[component]],
vcov. = function(x) vcov(x)[[component]],
df = NULL, component="cond", ...) {
multcomp:::modelparm.default(model, coef. = coef., vcov. = vcov.,
df = df, ...)
}
Test (this example is with Tukey, but I don't see why it shouldn't work more generally ...)
library(glmmTMB)
data("cbpp",package="lme4")
cbpp_b1 <- glmmTMB(incidence/size~period+(1|herd),
weights=size,family=binomial,
data=cbpp)
g1 <- glht(cbpp_b1, linfct = mcp(period = "Tukey"))
summary(g1)
This works with the current CRAN version, but the current development version of glmmTMB offers more options (e.g. emmeans(); see the above-linked vignette). You'll need to install via devtools::install_github("glmmTMB/glmmTMB/glmmTMB") (you'll need compilation tools installed as well).

plot graph of results within in interval in R

n=50
p=0.32
P=matrix( c(p, 1-p, 0, 0, 0, 0,
p, 0, 1-p, 0, 0, 0,
p, 0, 0, 1-p, 0, 0,
0, p, 0, 0, 1-p, 0,
0, 0, p, 0, 0, 1-p,
0, 0, 0, p, 0, 1-p),
ncol=6, nrow=6, byrow = T)
X=2
for(j in 1:n)
{Y=runif(1)
k=P[X[j],]
k=cumsum(k)
if(Y<=k[1])
{X[j+1]=1}
else if (Y<=k[2])
{X[j+1]=2}
else if (Y<=k[3])
{X[j+1]=3}
else if (Y<=k[4])
{X[j+1]=4}
else if (Y<=k[5])
{X[j+1]=5}
else {X[j+1]=6}}
mean(X)
x=c(1,2,3,4,5,6)
y=c(0.1,0.15,0.22,0.29,0.38,0.45)
approx(x,y,xout=mean(X))
I used the code above to get a mean(y) by linear interpolation with a fixed p.
But now, how to change the code in order to plot a graph of mean(y) against p[0:1]???
I kept getting only one mean(y),help me please.
p.s.I need only approx$y, that's where I'm stuck :(
I think it would be better to change your code into function() and use it with sapply(p.vector, ...).
the function
func <- function(p) {
P = matrix( c(p, 1-p, 0, 0, 0, 0,
p, 0, 1-p, 0, 0, 0,
p, 0, 0, 1-p, 0, 0,
0, p, 0, 0, 1-p, 0,
0, 0, p, 0, 0, 1-p,
0, 0, 0, p, 0, 1-p),
ncol=6, nrow=6, byrow = T)
X = 2
for(j in 1:n)
{Y=runif(1)
k=P[X[j],]
k=cumsum(k)
if(Y<=k[1])
{X[j+1]=1}
else if (Y<=k[2])
{X[j+1]=2}
else if (Y<=k[3])
{X[j+1]=3}
else if (Y<=k[4])
{X[j+1]=4}
else if (Y<=k[5])
{X[j+1]=5}
else {X[j+1]=6}}
return(approx(x, y, xout = mean(X))$y)
}
use the function with p[0:1]
p.vec <- seq(0, 1, 0.01) # preparation of p[0:1] as a vector
n = 50 # defining other paramaters
x = c(1, 2, 3, 4, 5, 6)
y = c(0.1, 0.15, 0.22, 0.29, 0.38, 0.45)
y.vec <- sapply(p.vec, func) # calculation of the y about p[0:1]
plot(p.vec, y.vec, type="o") # for example

R Matrix::expm(x), x is complex

I am trying to compute the matrix exponential of a matrix M, such that M = 1i*(pi/2)*Spin_Sx, where Spin_Sx is a matrix with real values. I get the following error:
Matrix::expm(M)
Error in expm(Matrix(x)) :
error in evaluating the argument 'x' in selecting a method for function'expm': Error in all0(object[lower.tri(object)]) :
Argument must be numeric-like atomic vector
Spin_Sx <- structure(c(0, 1.22474487139159, 0, 0, 0, 0, 0, 1.22474487139159,
0, 1.58113883008419, 0, 0, 0, 0, 0, 1.58113883008419, 0, 1.73205080756888,
0, 0, 0, 0, 0, 1.73205080756888, 0, 1.73205080756888, 0, 0, 0,
0, 0, 1.73205080756888, 0, 1.58113883008419, 0, 0, 0, 0, 0, 1.58113883008419,
0, 1.22474487139159, 0, 0, 0, 0, 0, 1.22474487139159, 0), .Dim = c(7L,
7L))
I figured out a solution with a little help from my friend. Since, Spin_Sx is a symmetric matrix (real or complex), it can be diagonalized as: Spin_Sx = UDU', where U is a unitary matrix, D is a diagonal matrix, and UU' = I. Therefore, exp(Spin_Sx) = U exp(D) U'. As D is a diagonal matrix, the exp(D) is simply the element exponential of the diagonal elements of D.
> A <- 1i*(pi/2)*Spin_Sx
> eig_Values <- eigen(A)$values
> Diagonal_A <- diag(exp(eig_Values))
> eig_Vector <- eigen(A)$vector
> expm_A <- eig_Vector %*% Diagonal_A %*% t(Conj(eig_Vector))

Resources