I try to loop trough a matrix but cant find a easy and elegant way instead of writing many (>10) equations... Can anyone help me please?
My Matrix looks like this:
and I want to calculate the following:
(0 * 0 * 4/24) + (0 * 1 * 6/24) + (0 * 2 * 3/24) + (1 * 0 * 3/24) + (1 * 1 * 4/24) + (1 * 2 * 4/24)
instead of using
__
btw: my code for the matrix
vals<- c(4/24, 6/24, 3/24, 3/24, 4/24, 4/24)
x <- c(0,1)
y <- c(0,1,2)
df <- matrix(vals, byrow = TRUE, nrow = 2, ncol = 3,
dimnames = list(x,y))
instead of calculation each step manually, I think there should be a for-loop method, but cant figure it out..
A possible solution:
c(x %*% df %*% y)
#> [1] 0.5
Another possible solution, based on outer:
sum(outer(x, y, Vectorize(\(x,y) x*y*df[x+1,y+1])))
#> [1] 0.5
x <- c(0, 1)
y <- c(0, 1, 2)
vals<- c(4/24, 6/24, 3/24, 3/24, 4/24, 4/24)
mat <- matrix(vals, byrow = TRUE, nrow = 2, ncol = 3,
dimnames = list(x,y)) ## not a data frame; don't call it "df"
There is even a better way than a for loop:
sum(tcrossprod(x, y) * mat)
#[1] 0.5
sum((x %o% y) * df)
Explanation:
x %o% y gets the outer product of vectors x and y which is:
#> [,1] [,2] [,3]
#> [1,] 0 0 0
#> [2,] 0 1 2
Since that has the same dimensions as df, you can multiply the corresponding elements and get the sum: sum((x %o% y) * df)
If you are new to R (as I am), here is the loop approach.
result = 0
for (i in 1:length(x)) {
for (j in 1:length(y)) {
result = result + x[i] * y[j] * df[i, j]
}
}
result
Related
#generating 100 uniformly distributed numbers
u1 <- runif(100,0,1)
u2 <- runif(100,0,1)
x1 <- function(x, y) {
return(sqrt(-2 * log(x) * cos(2 * pi * y)))
}
x2 <- function(x, y) {
return(sqrt(-2 * log(x) * sin(2 * pi * y)))
}
#applying x1
x1_vals <- mapply(x1, u1, u2)
#applying x2
x2_vals <- mapply(x2, u1, u2)
Hi I want to write a box muller function, this is part of my attempt above, I'm trying to avoid using loops as much as possible(for loops especially)
However, I keep getting NA values for my x1/x2 functions. I can't figure out whats wrong.
Here is the Box-Muller formula corrected.
x1 <- function(x, y) sqrt(-2 * log(x)) * cos(2 * pi * y)
x2 <- function(x, y) sqrt(-2 * log(x)) * sin(2 * pi * y)
u1 <- runif(1000,0,1)
u2 <- runif(1000,0,1)
# applying x1
x1_vals <- x1(u1, u2)
all(is.finite(x1_vals))
#> [1] TRUE
# applying x2
x2_vals <- x2(u1, u2)
all(is.finite(x2_vals))
#> [1] TRUE
old_par <- par(mfrow = c(1, 2))
hist(x1_vals, freq = FALSE)
curve(dnorm, from = -4, to = 4, add = TRUE)
hist(x2_vals, freq = FALSE)
curve(dnorm, from = -4, to = 4, add = TRUE)
par(old_par)
Created on 2022-09-28 with reprex v2.0.2
Those functions are already vectorized. Don't need to wrap mapply around them. Just give the two vectors to x1 and x2
x1(u1,u2)
[1] NaN NaN NaN NaN 0.3088330
[6] NaN 0.7866889 NaN NaN 1.7102801
[11] 2.1886770 NaN 1.5473627 1.0644378 0.8499208
snipped remaining 100 values
Vectorization is a feature of the R language. If the expressions in the function body can all take vectors and return vectors of equal length then no loop wrapper is needed.
You are getting NA's because the domain of the arguments to sin and cos are causing both positive and negative values to be given to sqrt.
I need to find exact and numerical solutions to a function but my code in R shows Error in optim(start_val[i, ], g) :
function cannot be evaluated at initial parameters
that is my code:
g <- function(x) (3*x[1]+2*x[2]+4*x[3]-4)^2 + (4*x[1]+2*x[2]+4*x[3]-2)^2 + (1*x[1]+1*x[2]+4*x[3]-4)^2
start_val <- expand.grid(c(-10,0,10),c(-10,0,10),c(-10,0,10))
optim_on_a_multiple_grid <- function(start_val, fun, ...) {
opt_result <- sapply(1:nrow(start_val),
function(i) {
res <- optim(start_val[i,], g)
c(res[[1]], res[[2]], res[[4]])
})
rownames(opt_result) <-
c(paste("x_", 1:ncol(start_val),
"_start_val", sep = ""),
paste("x_", 1:ncol(start_val),
"_sol", sep = ""),
paste(c(deparse(substitute(
fun
)), "_min"), collapse = ""),
"convergence")
opt_result
}
round(optim_on_a_multiple_grid(expand.grid(c(-10, 0, 10), c(-10, 0, 10)), g), 3)
Please, point me at my mistakes and explain how to fix them, I am stuck on it for quite a while now
I do not know why you have alot of objects while your aim is to optimize:
Do
# Define g
g <- function(x){
a <- (3 * x[1] + 2 * x[2] + 4 * x[3] - 4)^2
b <- (4 * x[1] + 2 * x[2] + 4*x[3] - 2)^2
d <- (x[1] + x[2] + 4*x[3] - 4)^2
a +b +d
}
optim(par=c(0,0,1), fn=g)
$par
[1] -1.9998762 3.9996836 0.5000453
$value
[1] 8.468819e-09
$counts
function gradient
160 NA
$convergence
[1] 0
$message
NULL
If you need your code:
The problem lies at the very end of it:
You should have:
round(optim_on_a_multiple_grid(start_val, g), 3)
I am starting to learn R and trying to multiply a 5X3 matrix with a 3X1 column vector in R; However while creating a new variable to perform the operation, R throws the error "non-conformable arrays". Can someone please point out my mistake in the code below -
*#5X3 Matrix*
X <- matrix(c(1,25.5,1.23,1,40.8,1.89,1,30.2,1.55,1,4.3,1.18,1,10.7,1.68),nrow=5,ncol=3,byrow=TRUE)
*3X1 Column vector*
b1 <- matrix(c(23,0.1,-8), nrow = 3, ncol = 1, byrow = TRUE)
v1 <- X * b1
v1
Appreciate your help :)
You need the matrix-multiplication operator %*%:
X <- matrix(c(1,25.5,1.23,1,40.8,1.89,1,30.2,1.55,1,4.3,1.18,1,10.7,1.68),nrow=5,ncol=3,byrow=TRUE)
b1 <- matrix(c(23,0.1,-8), nrow = 3, ncol = 1, byrow = TRUE)
v1 <- X %*% b1
v1
#> [,1]
#> [1,] 15.71
#> [2,] 11.96
#> [3,] 13.62
#> [4,] 13.99
#> [5,] 10.63
Normally one would use the first alternative below but the others are possible too. The first four alternatives below give a column vector as the result while the others give a plain vector without dimensions. The first three work even if b1 has more than one column. The remainder assume b1 has one column but could be generalized.
X %*% b1
crossprod(t(X), b1)
library(einsum)
einsum("ij,jk -> ik", X, b1)
out <- matrix(0, nrow(X), ncol(b1))
for(i in 1:nrow(X)) {
for(k in 1:ncol(X)) out[i] <- out[i] + X[i, k] * b1[k, 1]
}
out
colSums(t(X) * c(b1))
apply(X, 1, crossprod, b1)
sapply(1:nrow(X), function(i) sum(X[i, ] * b1))
rowSums(mapply(`*`, as.data.frame(X), b1))
rowSums(sapply(1:ncol(X), function(j) X[, j] * b1[j]))
X[, 1] * b1[1, 1] + X[, 2] * b1[2, 1] + X[, 3] * b1[3, 1]
Note
The input shown in the question is:
X <- matrix(c(1,25.5,1.23,1,40.8,1.89,1,30.2,1.55,1,4.3,1.18,1,10.7,1.68),nrow=5,ncol=3,byrow=TRUE)
b1 <- matrix(c(23,0.1,-8), nrow = 3, ncol = 1, byrow = TRUE)
I have to write a vectorized R function f that takes a vector x= (x_1, . . . , x_m) and a natural number n, and returns the value f_n(x) given by:
Example:
> x = seq(-1, 3, by = 0.4)
> f(x,6) # here n=6
[1] 0.000000e+00 0.000000e+00 0.000000e+00
[4] 2.666667e-06 6.480000e-04 8.333333e-03
[7] 4.430667e-02 1.410800e-01 3.050933e-01
[10] 4.755467e-01 5.500000e-01
This is what I got:
f = function(x, n){
s = 0
for(j in 0:x)
s = s + (-1)^j*choose(n, j)*(x-j)^(n-1)
s/factorial(n-1)
}
x = seq(-1, 3, by = 0.4)
f(x,6)
Warning in 0:x: numerical expression has 11 elements: only the first used
[1] -8.333333e-03 -6.480000e-04 -2.666667e-06 2.666667e-06 6.480000e-04
[6] 8.333333e-03 4.481867e-02 1.574640e-01 4.294693e-01 9.901147e-01
[11] 2.025000e+00
Clearly it is not what it should be in the example. What did I do wrong here? TIA
EDIT: Maybe using outer and apply might help with x?
This is a slightly different way of doing this solely based on base R:
x = seq(-1, 3, by = 0.4)
n <- 6
fn <- function(x, n) {
x[x <= 0] <- 0
sapply(x, function(x) {
Reduce(function(a, b) {
a + (-1) ^ b * (factorial(n)/(factorial(b) * factorial(n-b))) * (x - b) ^ (n-1)
}, seq(0, x), init = 0) * (1/factorial(n-1))
})
}
fn(x, 6)
[1] 0.000000e+00 0.000000e+00 0.000000e+00 2.666667e-06 6.480000e-04 8.333333e-03 4.430667e-02
[8] 1.410800e-01 3.050933e-01 4.755467e-01 5.500000e-01
Try this code. It can be modified to become tidier but maybe it can solve your problem in its current form. I used both base R and purr functions for iteration instead of for loop but maybe for loop alone can do the job.
library(tidyverse)
n <- 6
x <- seq(-1, 3, by = 0.4)
x[x<= 0] <- 0
seq_fun <- function(x) seq(0, x)
d <- sapply(x, seq_fun)
fun <- function(r, t) {
sum((-1) ^ r *choose(n, r)*(r-t)^(n-1)) / factorial(n - 1)
}
as_vector(map2(d, x, fun))
I'm trying to write a for-loop of a dataset. Just to make it simple, I'll write an example:
Two variables, X and Y.
X = 3, 6, 9
Y = 4, 8, 12
I want to make a loop that does this:
(Xi - Yi)^2, so first (3-4)^2, then
(6-8)^2 and so on.
Then, after that is done, multiply by this:
((1/2)/(n*(n-1))).
In this example, it would be:
(3-4)^2 + (6-8)^2 + (9-12)^2 = 1 + 4 + 9 = 14
1/2 / (3*(3-1)) = 0.5 / 6 = 0.0833.
0.0833 * 14 = 1.166.
result <- 0
sum <- rep(NA, n)
for (i in (1:n)) {
for(j in (1:n)) {
sum <- ((gathered$X[i] - gathered$X[j])^2)
}
}
Usually in R you can avoid for loops most of the times. For your case you can do
sum((X - Y)^2) * (1/2)/(length(X) * (length(X) - 1))
#[1] 1.166666667
However, as far as for loop is concerned you should be using a single loop since you want to access X[i] and Y[i] together.
sum <- 0
n <- 3
for (i in (1:n)) {
sum <- sum + (X[i] - Y[i])^2
}
sum * (1/2)/(n*(n-1))
#[1] 1.1667
data
X = c(3, 6, 9)
Y = c(4, 8, 12)
How about this, i think outer is fit to your problem.
CASE 1 ( X-Y )
sum(diag(outer(X,Y,function(X,Y)(X-Y)^2))) *
(1/2)/(length(X) * (length(X) - 1))
1.166667
CASE 2 ( all X and Y calculation )
sum(outer(X,Y,function(X,Y)(X-Y)^2)) *
(1/2)/(length(X) * (length(X) - 1))
15.5