In Julia:
In [1]: M1 = [1 3 4;
45 64 33;
456 3 454;]
Out [1]: 3x3 Array{Int64,2}:
1 3 4
45 64 33
456 3 454
In [2]: M1 * inv(M1)
Out [2]: 3x3 Array{Float64,2}:
1.0 6.93889e-18 -8.67362e-19
0.0 1.0 -2.08167e-17
-1.42109e-14 -8.88178e-16 1.0
M1 * inv(M1) is supposed to get the Identity matrix by definition. What's wrong?
I tried the same thing in Matlab:
>> M1 = [1 3 4;
45 64 33;
456 3 454;]
M1 =
1 3 4
45 64 33
456 3 454
>> inv(M1)
ans =
-0.280088987764182 0.013057987135465 0.001518595540939
0.052057842046719 0.013251438796731 -0.001421869710306
0.280978865406007 -0.013203075881414 0.000686753397495
>> M1 * inv(M1)
ans =
1.000000000000000 0.000000000000000 -0.000000000000000
0 1.000000000000000 -0.000000000000000
-0.000000000000014 -0.000000000000001 1.000000000000000
>>
Matlab returns the right result here. I guess Julia will not make a mistake here. So what's wrong with my calculation / notation?
Edit
The problem is caused by number of digits in floating point result. I should have asked, how to set result digits precision in Julia?
Julia and Matlab actually give the same result
(for instance, the bottom-left element is -1.4e-14 in both cases):
it is not exactly the identity matrix because floating point arithmetic is not exact.
You can explicitly round the result before displaying it.
M1 = [
1 3 4;
45 64 33;
456 3 454
]
round( M1 * inv(M1), 6 )
# 3x3 Array{Float64,2}:
# 1.0 0.0 -0.0
# 0.0 1.0 -0.0
# 0.0 -0.0 1.0
If you want an exact result, you can also use rationals.
M1 = [
1//1 3 4;
45 64 33;
456 3 454
]
M1 * inv(M1)
# 3x3 Array{Rational{Int64},2}:
# 1//1 0//1 0//1
# 0//1 1//1 0//1
# 0//1 0//1 1//1
Related
I've got a dataframe with latitude and longitude, which looks like this:
x y set
61 -112
63 -113
61 -113
62 -111 point
61 -111
64 -120
I want to find the three closest points to the point that is marked as point in column set. Then, for these three closest points, I want to amend the column set to say closest. Like this:
x y set
61 -112 closest
65 -113
62 -113 closest
62 -111 point
62 -111 closest
64 -120
How can I do this?
dists <- geosphere::distHaversine(dat[dat$set=="point",c("y","x")], dat[,c("y","x")])
dists
# [1] 123339.4 151513.9 153862.4 0.0 111319.5 505814.4
dat$set[dat$set != "point" & rank(dists) < 5] <- "closest"
dat
# x y set
# 1 61 -112 closest
# 2 63 -113 closest
# 3 61 -113
# 4 62 -111 point
# 5 61 -111 closest
# 6 64 -120
The reason we use < 5 is that the own-distance (point to point) will be the closest (0), so we need ranks 2-4. This assumes there is one "point"; if there are more, you'll likely want outer (to produce a matrix of distances) and look at each row before populating $set.
I'm inferring latitude and longitude from the sp tag, so chose the Haversine distance calculation since it's fast, and the appearance of coarse coordinates does not suggest the requirement for sub-millimeter accuracy (i.e., Vincenty Ellipsoid formula). There are other distance calculations if needed.
Here is first another approach with geosphere (make a distance matrix with distm) and then I show how you can use the terra::nearby method (which works for both long/lat and planar coordinates).
m <- matrix(c(61, -112, 63, -113, 61, -113, 62, -111, 61, -111, 64, -120), ncol=2, byrow=TRUE)
# note that the order should be long/lat !!!
m <- m[, 2:1]
d <- geosphere::distm(m)
diag(d) <- NA
i <- order(d[4,])[1:3]
i
#[1] 5 1 2
m[i,]
# [,1] [,2]
#[1,] -111 61
#[2,] -112 61
#[3,] -113 63
Now with terra. The below gets the nearest 3 neighbors for all points.
library(terra)
v <- vect(m, crs="+proj=lonlat")
nearby(v, k=3)
# id k1 k2 k3
#1 1 3 5 4
#2 2 4 3 1
#3 3 1 5 4
#4 4 5 1 2
#5 5 1 3 4
#6 6 2 3 4
With terra version 1.3.15 (currently the development version) you can also do
nearby(v[4,], v, k=4)
# id k1 k2 k3 k4
#[1,] 1 4 5 1 2
Taking k=4 neighbors as the first one is the point itself.
To get the development version, do
install.packages('terra', repos='https://rspatial.r-universe.dev')
I have a number of weighted graphs stored in *.ncol files. For the sake of the question lets say I have 2 files,
ncol_1.ncol
21 53 1.0
5 52 1.0
32 52 1.0
119 119 0.5
119 85 0.5
87 0 1.0
36 116 1.0
85 87 1.0
116 5 1.0
4 52 1.0
115 4 1.0
53 115 1.0
52 36 0.3333333333333333
52 21 0.3333333333333333
52 119 0.3333333333333333
ncol_2.ncol
21 115 1.0
119 85 1.0
87 0 1.0
85 87 1.0
4 48 0.3333333333333333
4 20 0.6666666666666666
115 4 1.0
55 119 1.0
48 4 1.0
20 4 0.25
20 20 0.25
20 21 0.25
20 55 0.25
0 20 1.0
I would like to read these into a list of graphs, that is I would like to have a list where my_graphs[1] would give me the graph from ncol_1.ncol
(I've crossed over from Python so my go to data structure is a list, I am open to a better R solution if one exists)
My attempt in R,
library(igraph)
f_list <- list.files(pattern = "\\.ncol$")
set.seed(123)
my_graphs <- list(length(f_list)
g_count = 1
for (f in f_list){
print(f)
my_graphs[g_count] <- read.graph(f, format = "ncol", directed = T)
g_count = g_count + 1
}
This is what I get as output,
[1] "r_test_1_0_100.ncol"
[1] "r_test_1_0_125.ncol"
Warning messages:
1: In my_graphs[g_count] <- read.graph(f, format = "ncol", directed = T) :
number of items to replace is not a multiple of replacement length
2: In my_graphs[g_count] <- read.graph(f, format = "ncol", directed = T) :
number of items to replace is not a multiple of replacement length
> my_graphs[1]
[[1]]
[1] 13
So what am I doing wrong here? Is the list initialization wrong? is this something that just cant be done? am I expecting Pythonic behaviour where none exists?
For list, you should use
my_graphs[[g_count]] <- read.graph(f, format = "ncol", directed = T)
or
my_graphs[g_count] <- list(read.graph(f, format = "ncol", directed = T))
I have the following variable Q
a = c(1,2,3,4)
b = c(45,4,3,2)
c = c(34,23,12,45)
Q = cbind(a,b,c)
I also have another variable r
r = c(10,20,30)
I would like to multiply each column of Q by each respective value in r (for example, the first column of Q multiplied by first value in r, the second column of Q multiplied by second value in rand so on).
Specifically for this example, the output I am looking for is:
10 900 1020
20 80 690
30 60 360
40 40 1350
I am new to R and looking for the most optimal way to do this.
Try this:
Q %*% diag(r)
giving:
[,1] [,2] [,3]
[1,] 10 900 1020
[2,] 20 80 690
[3,] 30 60 360
[4,] 40 40 1350
or any of these:
t(t(Q) * r)
Q * r[col(Q)]
sweep(Q, 2, r, "*")
Q * rep(r, each = nrow(Q))
mapply("*", as.data.frame(Q), r)
See this answer for the same question except using division:
How to divide each row of a matrix by elements of a vector in R
you will just need to do double transpose:
t(r*t(Q))
a b c
[1,] 10 900 1020
[2,] 20 80 690
[3,] 30 60 360
[4,] 40 40 1350
I am trying to do something pretty simple with R but I am not sure I am doing it well. I have a dataset containing three columns V1,V4,V5 and I want to do a regression to get the coefficients Ci,j of the following polynomial of two variables:
sum[i=0->3] sum[j=0->i] Ci,j . (V4_k)^i . (V5_k)^(3-j)
So I tried using the function polym:
lm(V1 ~ polym(V4, V5, degree=3, raw = TRUE), data)
which gives me the following coefficients
[1] 1.048122e+04 -2.050453e+02 1.407736e+00 -3.309312e-03 -3.748650e+01 8.983050e-01 -4.308559e-03 1.834724e-01 -6.868446e-04 4.030224e-04
Now, if I understand well how we must build a formula, I assumed that the following would give the same:
lm(v1 ~ V4 + V5 + I(V4 * V5) + I(V4^2 * V5) + I(V4^3 * V5) + I(V4^2 * V5^2) + I(V4^2*V5^3) + I(V4^3 * V5^2) + I(V4^3 * V5^3), data)
But I get different coefficients:
[1] 3.130403e+03 -1.652007e+01 -1.592879e+02 3.984177e+00 -2.419069e-02 3.919910e-05 1.008657e-04 4.271893e-07 -5.305623e-07 -2.289836e-09
Could you please tell me what I am doing wrong, and what is the correct way to achieve this regression with R?
The polym(V4, V5) call is not giving you what you think it is. (It doesn't matter if you use poly or polym for this example)
Let's look at an example:
v1 <- 1:10; v2 <- 1:10
poly(v1, v2, degree=3, raw=TRUE)
1.0 2.0 3.0 0.1 1.1 2.1 0.2 1.2 0.3
[1,] 1 1 1 1 1 1 1 1 1
[2,] 2 4 8 2 4 8 4 8 8
[3,] 3 9 27 3 9 27 9 27 27
[4,] 4 16 64 4 16 64 16 64 64
[5,] 5 25 125 5 25 125 25 125 125
[6,] 6 36 216 6 36 216 36 216 216
[7,] 7 49 343 7 49 343 49 343 343
[8,] 8 64 512 8 64 512 64 512 512
[9,] 9 81 729 9 81 729 81 729 729
[10,] 10 100 1000 10 100 1000 100 1000 1000
The column label is telling you the degree of the first and second vectors that you gave as arguments. The first three are from V2^0, the seconds three are linear in V2, and so on.
This is correct, but your second example has 4th degree terms in it. If you are actually looking for the 4th degree terms, just change degree to be 4 in the method call.
If you need some more help with polynomial regression, this article, on R-Bloggers should be helpful. It shows how to create models with both I() and poly although I think they were just univariate.
With the sample data
dd<-data.frame(x1=rnorm(50),
x2=rnorm(50))
dd<-transform(dd, z = 2*x1-.5*x1*x2 + 3*x2^2+x1^2 + rnorm(50))
we see that
lm(z~polym(x1,x2,degree=3, raw=T), dd)
lm(z~x1+I(x1^2)+I(x1^3)+I(x2)+I(x1*x2) +
I(x1^2*x2)+I(x2^2) + I(x1*x2^2) + I(x2^3), dd)
are the same.
Note that in your expansion, you have terms like
I(V4^3 * V5) + I(V4^2 * V5^2)
which are both 4th degree terms (the sum of the exponents is 4) so they should not appear in a third degree polynomial. So it depends on what you want. Normally, for a third degree polynomial, you have
sum[i=0->3] sum[j=0->3-i] Ci,j . (V4_k)^i . (V5_k)^j
so i+j<=3 always. It's unclear to me exactly what type of regression you want.
I am solving an example problem, RSA algorithm
I have been given two prime numbers 7 and 11. Let's say p=7 and q=11
I have to calculate the decryption key, d, for some encryption key, e.
Firstly I calculated n=p*q which implies that n=77.
Suppose that e=13,
to calculate d I used the formula d*e = 1 mod fi,
where fi=(p-1)(q-1), and so fi=60
The final equation becomes 13*d = 1 mod fi
According to some solved example
d is calculated to be 37, how is this result obtained?
Any help would be appreciated.
i think this is what you are looking for
Verifying the answer is easy, finding it in the first place, a little more work.
Verification:
13 * 37 = 481
481 = 8 * 60 + 1
Hence if you divide 13 * 37 by 60 you have remainder 1.
Alternate answers:
Any integer of the form (37 + 60 k) where k is any integer is also a solution. (97, -23, etc.)
To find the solution you can proceed as follows:
Solve:
13 d = 1 + 60 k
mod 13:
0 = 1 + 8k (mod 13)
8k = -1 (mod 13)
Add 13's until a multiple of 8 is found:
8k = 12 or 25 or 38 or 51 or 64 .... aha a multiple of 8!
k = 64 / 8 = 8
Substitute k = 8 back into 13 d = 1 + 60 k
13 d = 1 + 8 * 60 = 481
481 /13 = 37
and that is the answer.
Use the extended Euclidean algorithm to compute integers x and y such that
13*x+60*y=1
Then x is the answer you're looking for, mod 60.