Let d1 and d2 be matrices over the integers Z. How can I compute the group quotient ker d1 / im d2 in Sage?
So far I've been able to compute a basis for the kernel and image as follows:
M24 = MatrixSpace(IntegerRing(),2,4)
d1 = M24([-1,1, 1,-1, -1,1, 1,-1])
kerd1 = d1.right_kernel().basis()
M43 = MatrixSpace(IntegerRing(),4,3)
d2 = M43([1,1,-1, 1,-1,-1, 1,-1,1, 1,1,1])
imd2 = d2.column_space().basis()
which gives output:
kerd1 = [
(1, 0, 0, -1),
(0, 1, 0, 1),
(0, 0, 1, 1)
]
imd2 = [
(1, 1, 1, 1),
(0, 2, 0, -2),
(0, 0, 2, 2)
]
I tried to compute the quotient like this:
Z4.<a,b,c,d> = AbelianGroup(4, [0,0,0,0])
G = Z4.subgroup([a/d, b*d, c*d])
H = Z4.subgroup([a*b*c*d, b^2/d^2, c^2*d^2])
G.quotient(H)
But I got a NotImplementedError.
I found two ways to do this:
d1 = matrix(ZZ,4,2, [-1,1, 1,-1, -1,1, 1,-1]).transpose()
d2 = matrix(ZZ,4,3, [1,1,-1, 1,-1,-1, 1,-1,1, 1,1,1])
(d1.right_kernel() / (d2.column_space())).invariants()
# OUTPUT: (2, 2)
ChainComplex([d2, d1]).homology()[1]
# OUTPUT: C2 x C2
Related
I have made a matrix with values 1 and 0, and I want to check if there is one or more rows identical to (0, 0, 0, 0, 0, 0, 0, 0, 0, 0).
How can I do this?
Here's my code so far for making the matrix:
moeda <- c(0, 1)
n <- 100
casosTotais <- 0
casosFav <- 0
caras <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ## the vector to compare with
matriz <- matrix(nrow = n, ncol = 10)
i <- 1
lin <- 1
col <- 1
while(i <= n * 10){
matriz[lin, col] <- sample(moeda,1)
if(col==10){
lin <- lin + 1
col <- col - 10
}
i <- i + 1
col <- col + 1
}
matriz
I will first assume a general caras with zeros and ones:
## a vector of TRUE/FALSE; TRUE means a row of `matriz` is identical to `caras`
comp <- colSums(abs(t(matriz) - caras)) == 0
Then if caras is a simply a vector of zeros:
## a vector of TRUE/FALSE; TRUE means a row of `matriz` only contains zeros
comp <- rowSums(matriz) == 0
If you want to summarize the comparison:
To know which rows of matriz are identical to caras, do which(comp).
To know if any row of matriz is identical to caras, do any(comp).
To know how many rows of matriz is identical to caras, do sum(comp).
Note: You can generate this random matrix using:
## an n x 10 random matrix of zeros and ones
matriz <- matrix(rbinom(n * 10, size = 1, prob = 0.5), ncol = 10)
I am trying to estimate a state-space model to obtain the potential output (y_p) from data on output (y) and the unemployment rate (u) using R. The model is already programmed in EViews and I simply want to reproduce its results. The model is described by the following eqations (with time indizes):
signal equations:
(i) y_t = y_p_t + eps_y_t
(ii) u_t = beta_0 + beta_1(y_t-y_p_t) + eps_u_t
state equations:
(iii) y_p_t = y_p_(t-1) + g_(t-1)
(iv) g_t = g_(t-1) + eps_g_t
I have tried different packages. But there are different problems: Either there are no intercepts allowed (dlm package) or there is no smoother function (FKF package). So I do have two questions, either of them answered would solve my problem. The first (Questions 1a and 1b) relates to the specification of an appropriate state-space model in the dlm-package; the second (Question 2) relates to a smoothing function that could be used with the FKF package.
Question 1a. In the dlm-package no intercepts are allowed. So I put beta_0 and the output gap (gap_t = y_t-y_p_t) into the state vector using the JGG-matrix to reference to the y_t-data and tried to estimate beta_1 subsequently via maximum likelihood. However, I didn't obtain reasonable results.
# States: x(1) y_pot, x(2) growth, x(3) y_gap, x(4) beta_0
# Signal: y(1) y, y(2) u
beta_1 <- -0.2
beta_0 <- 0.03
# Measurement
FF <- matrix(c(1, 0, 0, 0,
0, beta_1, 0, 1), 2, 4)
# Transition
GG <- matrix(c(1, 0, -1, 0,
1, 1, -1, 0,
0, 0, 1, 0,
0, 0, 0, beta_0), 4, 4)
JGG <- matrix(c(0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 0), 4, 4)
# Covariance Transition
W <- diag(1e-2, 4)
# Covariance Measurement
V <- matrix(c(1e-2, 0,
0, 1e-2), 2, 2)
m0 <- c(11.4, 0.04, 0, 0.03)
C0 <- diag(1, 4) # 1e-7
C0[3,3] <- 0.1
C0[4,4] <- 0.1
# Now bring them into the dlm-object
myMod <- dlm(FF = FF,
GG = GG,
JGG = JGG,
X = dataMLE,
W = W,
V = V,
m0 = m0,
C0 = C0)
buildFun <- function(theta) {
V(myMod)[1,1] <- lambda_ss*exp(theta[1])
V(myMod)[2,2] <- exp(theta[2])
W(myMod)[2,2] <- exp(theta[1])
FF(myMod)[2,3] <- theta[3]
return(myMod)
}
myMod.mle <- dlmMLE(y = dataMLE, parm = c(-10, -10, -.2),
build = buildFun,
lower = c(rep(-1e6, 3)),
upper = c(rep(1e6, 3)),
control = list(trace = 1, REPORT = 5, maxit = 1000))
Question 1b. I've also tried to use the state vector x(1) y_pot, x(2) growth, x(3) beta_1, x(4) beta_0, and to use JFF to get the y_t-data for the output-gap-calculation... but this approach was not sucessfull either.
Question 1: Do you know of a way in which this rather simple model could be implemented within the dlm-package? The problems are the incercepts on the one hand and on the other the interaction of the beta_1-estimation with the ouput-gap, which consists itself of one state-variable and one external signal.
A more promising approach seemed to be to use the FKF-package. However, no smoother function is provided within this package.
Question 2: Is there a way to obtain the smoothed output instead of the Kalman-filtered output usind the FKF-package?
I deepely appreciate any help on this problem!
Thank you a lot!
Samuel
How can I assign a value into a matrix based in a vector condition index. A working example is:
# Input:
r <- c(2, 1, 3)
m <- matrix(rep(0, 9), nrow = 3)
# Desired output
result <- matrix(c(0, 1, 0,
1, 0, 0,
0, 1, 0), nrow = 3)
result.
# I try with this notation but it does not work:
sapply(1:3, function(x)m[x, r[x]] <- 1)
We use row/column indexing to assign
m[cbind(seq_len(nrow(m)), r)] <- 1
Or using replace
replace(m, cbind(seq_len(nrow(m)), r), 1)
I have the following code:
beta <- c(1, 2, 3)
X1 <- matrix(c(1, 1, 1, 1,
0, 1, 0, 1,
0, 0, 1, 1),
nrow = 4,
ncol = 3)
Z1 <- matrix(c(1, 1, 1, 1,
0, 1, 0, 1),
nrow = 4,
ncol = 2)
Z2 <- matrix(c(1, 1, 1, 1,
0, 1, 0, 1),
nrow = 4,
ncol = 2)
library(MASS)
S1 <- mvrnorm(70, mu = c(0,0), Sigma = matrix(c(10, 3, 3, 2), ncol = 2))
S2 <- mvrnorm(40, mu = c(0,0), Sigma = matrix(c(10, 4, 4, 2), ncol = 2))
z <- list()
y <- list()
for(j in 1:dim(S1)[1]){
for(i in 1:dim(S2)[1]){
z[[i]] <- X1 %*% beta+Z1 %*% S1[j,]+Z2 %*% S2[i,]+matrix(rnorm(4, mean = 0 , sd = 0.27), nrow = 4)
Z <- unname(do.call(rbind, z))
}
y[[j]] <- Z
Y <- unname(do.call(rbind, y))
}
X1 is a 4x3, Z1 and Z2 are 4x2 matrices. So everytime X1 %*% beta+X2 %*% S1[j,]+X2 %*% S2[i,]+matrix(rnorm(4, mean = 0 , sd = sigma), nrow = 4) is called it outputs a 4x1 matrix. So far I store all these values in the inner and outer loop in two lists and then call rbind() to transform them into a matrix. Is there a way to directly store them in matrices?
You can avoid using lists if you rely on the apply functions and on vector recycling. I broke down your equation into its parts. (I hope I interpreted it accurately!)
Mb <- as.vector(X1 %*% beta)
M1 <- apply(S1,1,function(x) Z1 %*% x )
M2 <- apply(S2,1,function(x) Z2 %*% x ) + Mb
Mout <- apply(M1,2,function(x) M2 + as.vector(x))
as.vector(Mout) + rnorm(length(Mout), mean = 0 , sd = 0.27)
because the random numbers are added after the matrix multiplication (ie are not involved in any calculation), you can just put them in on the end.
Also note that you can't add a smaller matrix to a larger one, but if you make it a vector first then R will recycle it as necessary. So when Mb (a vector of length 4) is added to a matrix with 4 rows and n columns, it is recycled n times.
I am using solveLP in the linprog R package to solve a simple linear programming problem:
minimize -x1-x2
subject to 2*x1+x2+x3 =12
x1+2*x2 +x4 = 9
x1,x2,x3,x4 >=0
which has dual equivalent:
maximize 12*y1+9*y2
subject to 2*y1+y2 <= -1
y1+2*y2 <= -1
y1,y2 <=0
If I state the problem in the primal form I get the right results (5,2,0,0). But when stating the problem in the dual form, the first two constraints simply get ignored. I get the result (0,0) which clearly violates (2*y1+y2 <= -1 and y1+2*y2 <= -1), is there an extra setting or parameter I am missing ? Please have a look at the code underneath and let me know what you think:
require(linprog)
objVec <- c(-1,-1,0,0)
rhsConstr <- c(12, 9,0,0,0,0)
Amat <- rbind( c( 2, 1, 1, 0 ),
c( 1, 2, 0, 1 ),
c( 1, 0, 0, 0 ),
c( 0, 1, 0, 0 ),
c( 0, 0, 1, 0 ),
c( 0, 0, 0, 1 ))
res <- solveLP( objVec, rhsConstr, Amat, maximum=FALSE, const.dir = c("==","==",">=",">=",">=",">=") , lpSolve=TRUE)
res$solution
# dual problem - this is where the problem is
objVec <- c(12,9)
rhsConstr <- c(-1.0,-1.0,0,0)
Amat <- rbind( c( 2, 1),
c( 1, 2),
c( 1, 0),
c( 0, 1))
res <- solveLP( objVec, rhsConstr, Amat, maximum=TRUE, const.dir = rep("<=",length(rhsConstr)))
res$solution
In positive space the dual problem does give the right answer (1/3,1/3):
objVec <- c(12,9);
rhsConstr <- c(1,1,0,0);
Amat <- rbind( c( 2, 1), c( 1, 2), c( 1, 0), c( 0, 1));
res <- solveLP( objVec, rhsConstr, Amat, maximum=FALSE, const.dir = rep(">=",length(rhsConstr)) , lpSolve=TRUE);
res$solution;
As with many linear programming libraries,
there are implicit non-negative constraints, y>=0:
there are no feasible solutions
(but I would expect res$status to indicate this).
solveLP does not seem to allow negative solutions:
you can either transform the problem to have only non-negative values
(replace y1 with u1-v1, y2 with u2-v2)
or use another package, that allows negative values.
library(Rglpk)
objVec <- c(12,9)
rhsConstr <- c(-1.0,-1.0,0,0)
Amat <- rbind( c( 2, 1),
c( 1, 2),
c( 1, 0),
c( 0, 1))
Rglpk_solve_LP(
objVec, Amat, rep("<=",4), rhsConstr,
bounds = list( lower = list( ind=c(1L,2L), val=c(-Inf,-Inf) ),
upper = list( ind=c(1L,2L), val=c( Inf, Inf) ) ),
max=TRUE
)