Is there in R a function allowing to fast calculate powers modulo n ? For example, suppose I want to calculate :
(10 378)^8743 (mod 10403)
I know it's possible to use successives powers of 2 by writing :
8743 = 8192 + 512 + 32 + 4 + 2 + 1
But is something already implemented ?
I believe the modpower function in the numbers package is what you want.
Related
I have the following algorithm:
def func(n):
if n <= 1:
return 1
x = 0
for i in range(n ** 2):
if i % 4 == 0:
x += i
return x + func(n//3) + func(n//3) + func(n//3)
The complexity analysis is:
$ T(n) = n^2 + 3*T(\frac {n}{3}) + 1 $
I know that the complexity is $ O(n^2) $, but my question is how is it possible that without the recursive calls and with them the complexity is the same? Is there any intuitive explanation for this?
An algorithm complexity is the time/space of the most expensive operation. If other operations are less expensive comparing to it, they do not affect the algorithm complexity.
E.g. If an algorithm runs in T(n) = n^2 + log(n) -> O(n)=n^2 since log(n) will not affect n^2 since it's too much lower than it as the variable n increases.
Even if T(n) = n^2 + 3n^2 = 4n^2 -> O(n)=n^2 because the scalar 4 will not take the complexity to another quantitive level, as the dependency of the variable n (the most important and expensive part) is equal.
So, I was just playing around with manually calculating the value of e in R and I noticed something that was a bit disturbing to me.
The value of e using R's exp() command...
exp(1)
#[1] 2.718282
Now, I'll try to manually calculate it using x = 10000
x <- 10000
y <- (1 + (1 / x)) ^ x
y
#[1] 2.718146
Not quite but we'll try to get closer using x = 100000
x <- 100000
y <- (1 + (1 / x)) ^ x
y
#[1] 2.718268
Warmer but still a bit off...
x <- 1000000
y <- (1 + (1 / x)) ^ x
y
#[1] 2.71828
Now, let's try it with a huge one
x <- 5000000000000000
y <- (1 + (1 / x)) ^ x
y
#[1] 3.035035
Well, that's not right. What's going on here? Am I overflowing the data type and need to use a certain package instead? If so, are there no warnings when you overflow a data type?
You've got a problem with machine precision. As soon as (1 / x) < 2.22e-16, 1 + (1 / x) is just 1. Mathematical limit breaks down in finite-precision numerical computations. Your final x in the question is already 5e+15, very close to this brink. Try x <- x * 10, and your y would be 1.
This is neither "overflow" nor "underflow" as there is no difficulty in representing a number as small as 1e-308. It is the problem of the loss of significant digits during floating-point arithmetic. When you do 1 + (1 / x), the bigger x is, the fewer significant digits in the (1 / x) part can be preserved when you add it to 1, and eventually you lose that (1 / x) term altogether.
## valid 16 significant digits
1 + 1.23e-01 = 1.123000000000000|
1 + 1.23e-02 = 1.012300000000000|
... ...
1 + 1.23e-15 = 1.000000000000001|
1 + 1.23e-16 = 1.000000000000000|
Any numerical analysis book would tell you the following.
Avoid adding a large number and a small number. In floating-point addition a + b = a * (1 + b / a), if b / a < 2.22e-16, there us a + b = a. This implies that when adding up a number of positive numbers, it is more stable to accumulate them from the smallest to the largest.
Avoid subtracting one number from another of the same magnitude, or you may get cancellation error. The web page has a classic example of using the quadratic formula.
You are also advised to have a read on Approximation to constant "pi" does not get any better after 50 iterations, a question asked a few days after your question. Using a series to approximate an irrational number is numerically stable as you won't get the absurd behavior seen in your question. But the finite number of valid significant digits imposes a different problem: numerical convergence, that is, you can only approximate the target value up to a certain number of significant digits. MichaelChirico's answer using Taylor series would converge after 19 terms, since 1 / factorial(19) is already numerically 0 when added to 1.
Multiplication / division between floating-point numbers don't cause problem on significant digits; they may cause "overflow" or "underflow". However, given the wide range of representable floating-point values (1e-308 ~ 1e+307), "overflow" and "underflow" should be rare. The real difficulty is with addition / subtraction where significant digits can be easily lost. See Can I stably invert a Vandermonde matrix with many small values in R? for an example on matrix computations. It is not impossible to get higher precision, but the work is probably more involved. For example, OP of the matrix example eventually used the GMP (GNU Multiple Precision Arithmetic Library) and associated R packages to proceed: How to put Rmpfr values into a function in R?
You might also try the Taylor series approximation to exp(1), namely
e^x = \sum_{k = 0}{\infty} x^k / k!
Thus we can approximate e = e^1 by truncating this sum; in R:
sprintf('%.20f', exp(1))
# [1] "2.71828182845904509080"
sprintf('%.20f', sum(1/factorial(0:10)))
# [1] "2.71828180114638451315"
sprintf('%.20f', sum(1/factorial(0:100)))
# [1] "2.71828182845904509080"
This question already has answers here:
Algorithm for solving systems of linear inequalities
(5 answers)
Closed 8 years ago.
Consider the following equations:
X > Y
X + Y > 7
Y <= 10
X >= 0
Y >= 0
I want to find out if there exists a solution that fulfills all of them (natural numbers).
I don't care about the exact solution, I just want to know if there is a solution at all
I have read about Microsoft Solver Foundation or other linear programming libraries, but I'm not sure if they can solve problems like this.
Especially I'm not sure if the can solve equations with variables on each side, like
X > Y, or X + Y > Z
most examples are of the form:
X * 10 + Y * 30 > constant
I need it to be able to solve systems with maximum of 4-8 variables, all in range of 0-100
Another important constraint I have, the library needs to be fast. I need to be able to solve systems of like 7 equations in like 0,00001 seconds
Interesting question. Feels a lot like the integer-knapsack problem.
First of all, whether variables are on each side is irrelevant, since an equation like
X + Y > Z
can be rewritten to
X + Y - Z > 0
So let's assume that all constraints are of the format
(const1 * var1) + ... + (const8 * var8) > const
To support less variables, just use the value 0 for one of the constants.
The way to visualize this is to see the case of 2 variables as determining the convex hull of the 'lines' corresponding to the constraints. So each constraint can be drawn as a 2D line, and only values on one side of the line are allowed.
To visualize this for 3 variables, it's the same as whether the convex hull of 'planes' determined by the constraint have any grid points ('natural numbers') in them.
The trouble in this case is the fact that the solution should have only natural numbers: this makes normal linear algebra impossible, since a grid is imposed. I would not know of any library supporting such restrictions.
But it would not be too difficult to write a solution yourself: the idea is to find a solution by trying every number by pruning aggressively.
So in your example: test all X in the range 0 to 100. Now go to the next variable, and determine the valid range for the free variable based on the constraints. Worked out for x == 8: then the range for y would be:
0 .. 7 because of constraint x > y
0 .. 100 because of constraint x + y > 7 (since x is already 8)
0 .. 9 because of constraint y < 10
...and we repeat this for all constraints. The final constraint for y is then 0 .. 7, because that is the most tight constraint. Now repeat this process for the left-over unbound variables, and you're done if you find at least one solution.
I expect this code to be about 100 lines with dynamic programming; computation time very much depends on the input and vary wildly.
For example, a set of equations which would take a long time:
A + B + C + D + E + F + G + H > 400.5
A + B + C + D + E + F + G + H < 400.6
As a human we can deduce that since we're requiring natural numbers, there is no solution to these equations. However, this solution is not prunable using the method described above, all combinations of A .. G will have to be tested before it will be concluded that there is no fitting H. Therefore it will look at about all possibilities. Not really pleasant, but unavoidable.
I am very new to R, trying to use it to visualize things. To make the story short, I'm exploring a conjecture I have on the economic theory of public goods. (I'm in my mid 50s, so bear with me.)
As far as R is concerned, I need to create a matrix with two vectors, one with E(W)/max(W), and the 2nd vector with stdev(W)/E(W). The trick is that the sample space of W, my r.v., keeps expanding by 1. To make this clearer, here's the probability distribution of W, the first 4 iterations:
W p
0 2/3
1 1/3
W p
0 3/6
1 2/6
2 1/6
W p
0 4/10
1 3/10
2 2/10
3 1/10
W p
0 5/15
1 4/15
2 3/15
3 2/15
4 1/15
...
I need to iterate this 20 times or so. Of course, I could do this manually, by copying, pasting, and then manually adjusting simple code, but it'd be too bulky and ugly looking, and I'm a bit concerned about --- you know --- elegance.
With good help from this community, I learned how to program R to generate the denominator of the probabilities:
R code iteration
I thought (foolishly) I could take it from there, but after a few hours scratching my bald head, I'm still stuck without knowing how to get what I want. It's about my not understanding well how to program less simple procedures that iterate. :/
I'll appreciate any help, especially clues setting me on the right track.
Thanks in advance!
You're just diving out by the sum; and sum of 1 to k is k*(k+1)/2. So...
R>k <- 3
R>k:1 / (k^2 + k)*2
I assume you mean that you want a matrix of 20 or so rows with each row being the values of your two requested quantities given that the distribution has max(W) = N values.
t(vapply(seq_len(20) + 1, function(N) {
W <- seq(N, 1) / (N * (N + 1) / 2) # create your distribution w/ 20 values
E <- function(pdf) sum((seq_along(pdf) - 1) * pdf)
c(E(W) / max(W), sqrt(E((W - E(W))^2)) / E(W))
}, numeric(2)))
I am not able to figure out. space complexity of one of my program.
its coming out as follows but i am not sure if it is O(n ^3), or O(n^4)
1*n + 2*(n-1) + 3*(n-2) + ..+ (n-1) *(2) + n *1
as I understand 1+ 2 + 3 + ....+ n = n*(n-1)/2
and here we have two of them , so i was wondering if it will be O(n^4)
It is O(n3).
I have computed the first five elements of this sequence:
n=1 -> 1
n=2 -> 4
n=3 -> 10
n=4 -> 20
n=5 -> 35
The On-Line Encyclopedia of Integer Sequences® (OEIS®)
says that these are the Tetrahedral (or triangular pyramidal) numbers: a(n) = C(n+2,3) = n*(n+1)*(n+2)/6.
Of course, this is not a proof. You should check by induction whether your sum does satisfies this relation.