Maxima- symbolic variable substitution in more algorithmic way - algorithm

expJ:listarray(J);
(expJ) ["-(l[1]*l[3]*m[3]*('diff(r[3](t),t,1))^2*sin(r[3](t)-r[1](t))+(2*l[1]*l[2]*m[3]+l[1]*l[2]*m[2])*('diff(r[2](t),t,1))^2*sin(r[2](t)-r[1](t))-l[1]*m[1]*g*cos(r[1](t)))/2","-(l[2]*l[3]*m[3]*('diff(r[3](t),t,1))^2*sin(r[3](t)-r[2](t))+((-2*l[1]*l[2]*m[3])-l[1]*l[2]*m[2])*('diff(r[1](t),t,1))^2*sin(r[2](t)-r[1](t))-2*l[2]*m[2]*g*cos(r[2](t)))/2","(l[2]*l[3]*m[3]*('diff(r[2](t),t,1))^2*sin(r[3](t)-r[2](t))+l[1]*l[3]*m[3]*('diff(r[1](t),t,1))^2*sin(r[3](t)-r[1](t))+3*l[3]*m[3]*g*cos(r[3](t)))/2"]
for i:1 thru 3 do(
for k:1 thru 3 do(
J[i,1]:ssubst("m3","m[3]",J[i,1])
));
I wanna substitute numbers in front of m as they are 1,2,3 with algorithm, but when I put mi ,it recognizes this as different variable, so somehow I need to indicate ssubs("mi","m[i]",J[i,1]) as i is separate from m.
Any suggestions?

OK, here is a way to substitute v(k) for v[k]. I believe that's OK since Matlab recognizes parentheses for array subscripts.
%o5 is the input (as strings) which you gave above. I've parsed the strings in %o7 and extracted the list of subscripted variables (via sublist and subvarp) in %o10. From there I created a list v(k) = v[k] in %o14 and then substituted those back into the parsed expressions in %o15.
I hope that this is going in the direction that will be helpful to you. You might still need to modify this approach to get what you want, but in any event, I will repeat my very strong advice against string processing. If there is still something more to do, it is almost certainly better to achieve it by working with expressions than with strings.
(%o5) [-(l[1]*l[3]*m[3]*('diff(r[3](t),t,1))^2*sin(r[3](t)-r[1](t))+(2*l[1]*l[\
2]*m[3]+l[1]*l[2]*m[2])*('diff(r[2](t),t,1))^2*sin(r[2](t)-r[1](t))-l[1]*m[1]*\
g*cos(r[1](t)))/2, -(l[2]*l[3]*m[3]*('diff(r[3](t),t,1))^2*sin(r[3](t)-r[2](t)\
)+((-2*l[1]*l[2]*m[3])-l[1]*l[2]*m[2])*('diff(r[1](t),t,1))^2*sin(r[2](t)-r[1]\
(t))-2*l[2]*m[2]*g*cos(r[2](t)))/2, (l[2]*l[3]*m[3]*('diff(r[2](t),t,1))^2*sin\
(r[3](t)-r[2](t))+l[1]*l[3]*m[3]*('diff(r[1](t),t,1))^2*sin(r[3](t)-r[1](t))+3\
*l[3]*m[3]*g*cos(r[3](t)))/2]
(%i6) linel:65;
(%o6) 65
(%i7) map (parse_string, %o5);
d 2
(%o7) [((- l l m (-- (r (t))) sin(r (t) - r (t)))
1 3 3 dt 3 3 1
d 2
- (2 l l m + l l m ) (-- (r (t))) sin(r (t) - r (t))
1 2 3 1 2 2 dt 2 2 1
d 2
+ l m g cos(r (t)))/2, ((- l l m (-- (r (t)))
1 1 1 2 3 3 dt 3
d 2
sin(r (t) - r (t))) - ((- 2 l l m ) - l l m ) (-- (r (t)))
3 2 1 2 3 1 2 2 dt 1
sin(r (t) - r (t)) + 2 l m g cos(r (t)))/2,
2 1 2 2 2
d 2
(l l m (-- (r (t))) sin(r (t) - r (t))
2 3 3 dt 2 3 2
d 2
+ l l m (-- (r (t))) sin(r (t) - r (t))
1 3 3 dt 1 3 1
+ 3 l m g cos(r (t)))/2]
3 3 3
(%i8) grind (%);
[((-l[1]*l[3]*m[3]*('diff(r[3](t),t,1))^2*sin(r[3](t)-r[1](t)))
-(2*l[1]*l[2]*m[3]+l[1]*l[2]*m[2])
*('diff(r[2](t),t,1))^2*sin(r[2](t)-r[1](t))
+l[1]*m[1]*g*cos(r[1](t)))
/2,
((-l[2]*l[3]*m[3]*('diff(r[3](t),t,1))^2*sin(r[3](t)-r[2](t)))
-((-2*l[1]*l[2]*m[3])-l[1]*l[2]*m[2])
*('diff(r[1](t),t,1))^2*sin(r[2](t)-r[1](t))
+2*l[2]*m[2]*g*cos(r[2](t)))
/2,
(l[2]*l[3]*m[3]*('diff(r[2](t),t,1))^2*sin(r[3](t)-r[2](t))
+l[1]*l[3]*m[3]*('diff(r[1](t),t,1))^2*sin(r[3](t)-r[1](t))
+3*l[3]*m[3]*g*cos(r[3](t)))
/2]$
(%o8) done
(%i9) listofvars (%o7);
(%o9) [l , m , g, t, l , m , m , l ]
1 1 2 2 3 3
(%i10) sublist (%, subvarp);
(%o10) [l , m , l , m , m , l ]
1 1 2 2 3 3
(%i11) map (op, %o10);
(%o11) [l, m, l, m, m, l]
(%i12) map (args, %o10);
(%o12) [[1], [1], [2], [2], [3], [3]]
(%i13) map (lambda ([v], apply (op(v), args(v))), %o10);
(%o13) [l(1), m(1), l(2), m(2), m(3), l(3)]
(%i14) map (lambda ([v1, v2], v1=v2), %o10, %o13);
(%o14) [l = l(1), m = m(1), l = l(2), m = m(2), m = m(3),
1 1 2 2 3
l = l(3)]
3
(%i15) subst (%, %o7);
d 2
(%o15) [((- l(1) l(3) m(3) (-- (r (t))) sin(r (t) - r (t)))
dt 3 3 1
d 2
- (2 l(1) l(2) m(3) + l(1) l(2) m(2)) (-- (r (t)))
dt 2
sin(r (t) - r (t)) + l(1) m(1) g cos(r (t)))/2,
2 1 1
d 2
((- l(2) l(3) m(3) (-- (r (t))) sin(r (t) - r (t)))
dt 3 3 2
d 2
- ((- 2 l(1) l(2) m(3)) - l(1) l(2) m(2)) (-- (r (t)))
dt 1
sin(r (t) - r (t)) + 2 l(2) m(2) g cos(r (t)))/2,
2 1 2
d 2
(l(2) l(3) m(3) (-- (r (t))) sin(r (t) - r (t))
dt 2 3 2
d 2
+ l(1) l(3) m(3) (-- (r (t))) sin(r (t) - r (t))
dt 1 3 1
+ 3 l(3) m(3) g cos(r (t)))/2]
3
(%i16) grind (%);
[((-l(1)*l(3)*m(3)*('diff(r[3](t),t,1))^2*sin(r[3](t)-r[1](t)))
-(2*l(1)*l(2)*m(3)+l(1)*l(2)*m(2))
*('diff(r[2](t),t,1))^2*sin(r[2](t)-r[1](t))
+l(1)*m(1)*g*cos(r[1](t)))
/2,
((-l(2)*l(3)*m(3)*('diff(r[3](t),t,1))^2*sin(r[3](t)-r[2](t)))
-((-2*l(1)*l(2)*m(3))-l(1)*l(2)*m(2))
*('diff(r[1](t),t,1))^2*sin(r[2](t)-r[1](t))
+2*l(2)*m(2)*g*cos(r[2](t)))
/2,
(l(2)*l(3)*m(3)*('diff(r[2](t),t,1))^2*sin(r[3](t)-r[2](t))
+l(1)*l(3)*m(3)*('diff(r[1](t),t,1))^2*sin(r[3](t)-r[1](t))
+3*l(3)*m(3)*g*cos(r[3](t)))
/2]$
(%o16) done
(%i17) listofvars (%o15);
(%o17) [g, t]

Related

Average over the columns of the matrix in Julia

I have a big matrix with float entries of the form
[ a b c d
e f g h
i j k l
m n o p ]
some of the values are outliers, so I wanted to average each of the entries with values with its recent k entries in the corresponding column and preserve the shape. In other words to have something like this for k = 3:
[ a b c d
(e + a)/2 (f + b)/2 (g + c)/2 (h + d)/2
(e + a + i)/3 (f + b + j)/3 (g + c + k)/3 (h + d + l)/3
(e + i + m)/3 (f + j + n)/3 (g + k + o)/3 (h + l + p)/3 ]
etc.
You can do this with RollingFunctions and mapslices:
julia> a = reshape(1:16, 4, 4)
4×4 reshape(::UnitRange{Int64}, 4, 4) with eltype Int64:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
julia> using RollingFunctions
julia> mapslices(x -> runmean(x, 3), a, dims = 1)
4×4 Matrix{Float64}:
1.0 5.0 9.0 13.0
1.5 5.5 9.5 13.5
2.0 6.0 10.0 14.0
3.0 7.0 11.0 15.0
I didn't know about RollingFunctions, but a regular loop is 4X faster. I'm not sure if it's some kind of type instability caused by mapslices?.
function runmean(a,W)
A = similar(a)
for j in axes(A,2), i in axes(A,1)
l = max(1, i-W+1)
A[i,j] = mean(a[k,j] for k=l:i)
end
A
end
Testing yields:
using RollingFunctions
#btime mapslices(x -> runmean(x, 3), A, dims = 1) setup=(A = rand(0.0:9,1000,1000))
#btime runmean(A,3) setup=(A = rand(0.0:9,1000,1000))
15.326 ms (10498 allocations: 23.45 MiB)
4.410 ms (2 allocations: 7.63 MiB)

What sort of time complexity would be required to solve the RSA Factoring Challenge?

Although the challenge ended a long time ago, I'm kinda bored so I decided to try to factorise some of the numbers.
I initially had an O(n) algorithm, but then, I decided to research big O notation.
Apparently (I could be wrong), O(n) algorithms and O(2n) algorithms basically have the same running time. So do O(n) and O(4n) algorithms. In fact, O(n) and O(cn) algorithms (where c is an integer) essentially have the same running time.
So now, I have an O(8n) algorithm, but it isn't quick enough for 77-bit numbers.
What sort of time complexity would be required to factorise the first few RSA numbers (in under 5-ish minutes)?
My O(8n) algorithm:
import math
num = int(input())
sq = math.sqrt(num)
if num % 2 == 0:
print(2, int(num / 2))
elif sq % 1 == sq:
print(int(sq), int(sq))
else:
sq = round(sq)
a = 3
b = sq + (1 - (sq % 2))
c = ((b + 1) / 2)
d = ((b + 1) / 2)
c -= (1 - (c % 2))
d += (1 - (d % 2))
e = ((c + 1) / 2)
f = ((c + 1) / 2)
e -= (1 - (e % 2))
f += (1 - (f % 2))
g = ((d + 1) / 2) + d
h = ((d + 1) / 2) + d
g -= (1 - (g % 2))
h += (1 - (h % 2))
while a <= sq and num % a != 0 and b > 2 and num % b != 0 and c <= sq and num % c != 0 and d > 2 and num % d != 0 and e <= sq and num % e != 0 and f > 2 and num % f != 0 and g <= sq and num % g != 0 and h > 2 and num % h != 0:
a += 2
b -= 2
c += 2
d -= 2
e += 2
f -= 2
g += 2
h -= 2
if num % a == 0:
print(a, int(num / a))
elif num % b == 0:
print(b, int(num / b))
elif num % c == 0:
print(c, int(num / c))
elif num % d == 0:
print(d, int(num / d))
elif num % e == 0:
print(e, int(num / e))
elif num % f == 0:
print(f, int(num / f))
elif num % g == 0:
print(g, int(num / g))
elif num % h == 0:
print(h, int(num / h))
Your algorithm is poorly-implemented trial division. Throw it away.
Here is my basic prime-number library, using the Sieve of Eratosthenes to enumerate prime numbers, the Miller-Rabin algorithm to recognize primes, and wheel factorization followed by Pollard's rho algorithm to factor composites, which I leave to you to translate to Python:
function primes(n)
i, p, ps, m := 0, 3, [2], n // 2
sieve := makeArray(0..m-1, True)
while i < m
if sieve[i]
ps := p :: ps # insert at head of list
for j from (p*p-3)/2 to m step p
sieve[i] := False
i, p := i+1, p+2
return reverse(ps)
function isPrime(n, k=5)
if n < 2 then return False
for p in [2,3,5,7,11,13,17,19,23,29]
if n % p == 0 then return n == p
s, d = 0, n-1
while d % 2 == 0
s, d = s+1, d/2
for i from 0 to k
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1 then next i
for r from 1 to s
x = (x * x) % n
if x == 1 then return False
if x == n-1 then next i
return False
return True
function factors(n, limit=10000)
wheel := [1,2,2,4,2,4,2,4,6,2,6]
w, f, fs := 0, 2, []
while f*f <= n and f < limit
while n % f == 0
fs, n := f :: fs, n / f
f, w := f + wheel[w], w+1
if w = 11 then w = 3
if n == 1 return fs
h, t, g, c := 1, 1, 1, 1
while not isPrime(n)
repeat
h := (h*h+c) % n # the hare runs
h := (h*h+c) % n # twice as fast
t := (t*t+c) % n # as the tortoise
g := gcd(t-h, n)
while g == 1
if isPrime(g)
while n % g == 0
fs, n := g :: fs, n / g
h, t, g, c := 1, 1, 1, c+1
return sort(n :: fs)
function powerMod(b, e, m)
x := 1
while e > 0
if e%2 == 1
x, e := (x*b)%m, e-1
else b, e := (b*b)%m, e//2
return x
function gcd(a, b)
if b == 0 then return a
return gcd(b, a % b)
Properly implemented, that algorithm should factor your 79-bit number nearly instantly.
To factor larger numbers, you will have to work harder. Look up "elliptic curve factorization" and "self-initializing quadratic sieve" to find factoring algorithms that you can implement yourself.

Can anyone explain how this division algorithm works?

I saw this in an algorithm textbook. I am confused about the middle recursive function. If you can explain it with an example, such as 4/2, that would be great!
function divide(x, y)
Input: Two n-bit integers x and y, where y ≥ 1
Output: The quotient and remainder of x divided by y
if x = 0: return (q, r) = (0, 0)
(q, r) = divide(floor(x/2), y)
q = 2 · q, r = 2 · r
if x is odd: r = r + 1
if r ≥ y: r = r − y, q = q + 1
return (q, r)
You're seeing how many times it's divisible by 2. This is essentially performing bit shifts and operating on the binary digits. A more interesting case would be 13/3 (13 is 1101 in binary).
divide(13, 3) // initial binary value - 1101
divide(6, 3) // shift right - 110
divide(3, 3) // shift right - 11
divide(1, 3) // shift right - 1 (this is the most significant bit)
divide(0, 3) // shift right - 0 (no more significant bits)
return(0, 0) // roll it back up
return(0, 1) // since x is odd (1)
return(1, 0) // r = r * 2 = 2; x is odd (3) so r = 3 and the r > y condition is true
return(2, 0) // q = 2 * 1; r = 2 * 1 - so r >= y and q = 2 + 1
return(4, 1) // q = 2 * 2; x is odd to r = 0 + 1

Prefix-function computation in Knuth-Morris-Pratt Algorithm

So for the following sub string
1 2 3 4 5 6 7 8 9 10 11
a b c d a b c d a b x
Which is the prefix function? Me and one of my friends computed it and we have different results, mine is:
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 2
and his:
a b c d a b c d a b x
0 0 0 0 1 2 3 4 1 2 0
If I am wrong, why is that?
The prefix table should be:
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 0
so both versions given are not right.
For the last entry of your table
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 2
^
|
this one
to be correct, the suffix of length 2 of a b c d a b c d a b x which is b x would also have to be its length 2 prefix, which is a b instead.
In case of entries different from zero in the prefix table corresponding prefixes and suffixes have been marked in the table below:
a 0
a b 0
a b c 0
a b c d 0
a b c d a 1
-
=
a b c d a b 2
---
===
a b c d a b c 3
-----
=====
a b c d a b c d 4
-------
=======
a b c d a b c d a 5
---------
=========
a b c d a b c d a b 6
-----------
===========
a b c d a b c d a b x 0
My KMP function in java:
public int[] KMP(String val) {
int i = 0;
int j = -1;
int[] result = new int[val.length() + 1];
result[0] = -1;
while (i < val.length()) {
while (j >= 0 && val.charAt(j) != val.charAt(i)) {
j = result[j];
}
j++;
i++;
result[i] = j;
}
return result;
}
Result for prefix arrays:
[-1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 0]
Neither of your answers are correct. The prefix function or partial match table would be the following:
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 0
Your answer was correct upto index 10. But in the last index you have done something wrong. The reason why value of index 11 of partial match table would 0 is because there are no proper prefix which matches any proper suffix of the string upto index 11. Because all proper suffixes at this position will end with x and no proper prefix at this position will end with x.
If you have problem understanding what actually prefix function or partial index table means you can take a look into this document. It has a very good explanation. Hope it helps.
both of your answers are wrong. correct one will be
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 0

Some linear constraints seem to be ignored in function NMinimize with Mathematica 8

I'm trying to minimize a non-linear function of four variables with some linear constraints. Mathematica 8 is unable to find a good solution giving complex values of the function at some point in the iteration. This implies that one or some contraints are not being enabled in the process. Is this a bug or limitation of the optimization function ?
Function to minimize is
ff[lxw_, lwz_, c_, d_] := - J1 (lxw + lwz) - 2 J2 c +
T (-Log[2] - 1/2 (1 - lxw) Log[(1 - lxw)/4] -
1/2 (1 + lxw) Log[(1 + lxw)/4] -
1/2 (1 - lwz) Log[(1 - lwz)/4] -
1/2 (1 + lwz) Log[(1 + lwz)/4] + 1/2 (1 - d) Log[(1 - d)/16] +
1/8 (1 + 2 c + d - 2 lwz - 2 lxw) Log[
1/16 (1 + 2 c + d - 2 lwz - 2 lxw)])
where
T = 10;
J1 = 1;
J2 = -0.2;
are constant parameters. Then I try
NMinimize[{ff[lxw, lwz, c, d],
2 c + d - 2 lwz - 2 lxw >= -0.999 &&
-0.999 <= lxw <= 0.999 &&
-0.999 <= lwz <= 0.999 &&
-0.999 <= c <= 0.999 &&
d <= 0.9999}, {lxw, lwz, c, d}]
with the result
NMinimize::nrnum: "The function value 5.87777[VeryThinSpace]-4.87764\ I\n
is not a real number at {c,d,lwz,lxw} = {-0.718817,-1.28595,0.69171,-0.932461}.
I would appreciate if someone can give a hint at what is happening here.
Try this:
Clear[ff];
ff[lxw_, lwz_, c_, d_] /; 2 c + d - 2 lwz - 2 lxw >= -0.999 :=
< your function def >
This will cause the cause the function to be unevaluated in case NMinimize takes an excursion out of bounds. Sorry i cant test this from here.. If that doesn't do try asking on mathematica.stackexchange.com
Aside, why use <=.999 instead of simply < 1 ?
It just might help if you fix that too ( use integer 1, not 1. )
The warning is appearing because at the values given in the warning the last term in ff is complex, due to taking the log of a negative number, i.e.
{c, d, lwz, lxw} = {
-0.7188174745559741`,
-1.2859482844800894`,
0.6917100913968041`,
-0.9324611085040573`};
Log[1/16 (1 + 2 c + d - 2 lwz - 2 lxw)]
-2.5558 + 3.14159 i
1/16 (1 + 2 c + d - 2 lwz - 2 lxw)
-0.0776301
In Mathematica 9 a result is produced in addition to the warning :-
{-4.90045, {c -> 0.94425, d -> -0.315633, lwz -> 0.900231, lxw -> -0.191476}}
I.e.
{c, d, lwz, lxw} = {
0.9442497691706085`,
-0.31563295950647885`,
0.900230825707721`,
-0.1914760216875171`};
ff[lxw, lwz, c, d]
-4.90045

Resources