How to use values computed with NDSolve in Mathematica? - wolfram-mathematica

I'm trying to solve one differential equation and use 2 computed values (at specific points) as boundary conditions for a new differential equation. An example:
sys1 = {p''[x] + p'[x] + p[x] == 0,p'[0] == 0,p'[1] ==0};
sol1 = NDsolve[sys1,p[x],{x,0,1}];
Now I want do define sys2 with boundary conditions taken from the solution sol1. I mean it should look like this:
sys2 = {3y''[x] + 7y'[x] - 6y[x] == 0,y[0.3] == p[0.3],y'[1] == p'[1]}
And then we can solve sys2 using NDSolve. I didn't find any clues to how to extract these values from the solution.
Your help would be greatly appreciated.

You can do:
sol1 = NDSolve[sys1,p,{x,0,1}];
pfun=First[p/.sol1];
pfun[0.3]
pfun'[1]
There is an example in the documentation of InterpolatingFunction for achieving this (http://reference.wolfram.com/language/ref/InterpolatingFunction.html).

Related

Homework: Implementing Karp-Rabin; For the hash values modulo q, explain why it is a bad idea to use q as a power of 2?

I have a two-fold homework problem, Implement Karp-Rabin and run it on a test file and the second part:
For the hash values modulo q, explain why it is a bad idea to use q as a power of 2. Can you construct a terrible example e.g. for q=64
and n=15?
This is my implementation of the algorithm:
def karp_rabin(text, pattern):
# setup
alphabet = 'ACGT'
d = len(alphabet)
n = len(pattern)
d_n = d**n
q = 2**32-1
m = {char:i for i,char in enumerate(alphabet)}
positions = []
def kr_hash(s):
return sum(d**(n-i-1) * m[s[i]] for i in range(n))
def update_hash():
return d*text_hash + m[text[i+n-1]] - d_n * m[text[i-1]]
pattern_hash = kr_hash(pattern)
for i in range(0, len(text) - n + 1):
text_hash = update_hash() if i else kr_hash(text[i:n])
if pattern_hash % q == text_hash % q and pattern == text[i:i+n]:
positions.append(i)
return ' '.join(map(str, positions))
...The second part of the question is referring to this part of the code/algo:
pattern_hash = kr_hash(pattern)
for i in range(0, len(text) - n + 1):
text_hash = update_hash() if i else kr_hash(text[i:n])
# the modulo q used to check if the hashes are congruent
if pattern_hash % q == text_hash % q and pattern == text[i:i+n]:
positions.append(i)
I don't understand why it would be a bad idea to use q as a power of 2. I've tried running the algorithm on the test file provided(which is the genome of ecoli) and there's no discernible difference.
I tried looking at the formula for how the hash is derived (I'm not good at math) trying to find some common factors that would be really bad for powers of two but found nothing. I feel like if q is a power of 2 it should cause a lot of clashes for the hashes so you'd need to compare strings a lot more but I didn't find anything along those lines either.
I'd really appreciate help on this since I'm stumped. If someone wants to point out what I can do better in the first part (code efficiency, readability, correctness etc.) I'd also be thrilled to hear your input on that.
There is a problem if q divides some power of d, because then only a few characters contribute to the hash. For example in your code d=4, if you take q=64 only the last three characters determine the hash (d**3 = 64).
I don't really see a problem if q is a power of 2 but gcd(d,q) = 1.
Your implementation looks a bit strange because instead of
if pattern_hash % q == text_hash % q and pattern == text[i:i+n]:
you could also use
if pattern_hash == text_hash and pattern == text[i:i+n]:
which would be better because you get fewer collisions.
The Thue–Morse sequence has among its properties that its polynomial hash quickly becomes zero when a power of 2 is the hash module, for whatever polynomial base (d). So if you will try to search a short Thue-Morse sequence in a longer one, you will have a great lot of hash collisions.
For example, your code, slightly adapted:
def karp_rabin(text, pattern):
# setup
alphabet = '01'
d = 15
n = len(pattern)
d_n = d**n
q = 32
m = {char:i for i,char in enumerate(alphabet)}
positions = []
def kr_hash(s):
return sum(d**(n-i-1) * m[s[i]] for i in range(n))
def update_hash():
return d*text_hash + m[text[i+n-1]] - d_n * m[text[i-1]]
pattern_hash = kr_hash(pattern)
for i in range(0, len(text) - n + 1):
text_hash = update_hash() if i else kr_hash(text[i:n])
if pattern_hash % q == text_hash % q : #and pattern == text[i:i+n]:
positions.append(i)
return ' '.join(map(str, positions))
print(karp_rabin('0110100110010110100101100110100110010110011010010110100110010110', '0110100110010110'))
outputs a lot of positions, although only three of then are proper matches.
Note that I have dropped the and pattern == text[i:i+n] check. Obviously if you restore it, the result will be correct, but also it is obvious that the algorithm will do much more work checking this additional condition than for other q. In fact, because there are so many collisions, the whole idea of algorithm becomes not working: you could almost as effectively wrote a simple algorithm that checks every position for a match.
Also note that your implementation is quite strange. The whole idea of polynomial hashing is to take the modulo operation each time you compute the hash. Otherwise your pattern_hash and text_hash are very big numbers. In other languages this might mean arithmetic overflow, but in Python this will invoke big integer arithmetic, which is slow and once again loses the whole idea of the algorithm.

matlab code nested loop performance improvement

I would be very interested to receive suggestions on how to improve performance of the following nested for loop:
I = (U > q); % matrix of indicator variables, I(i,j) is 1 if U(i,j) > q
for i = 2:K
for j = 1:(i-1)
mTau(i,j) = sum(I(:,i) .* I(:,j));
mTau(j,i) = mTau(i,j);
end
end
The code evaluates if for pairs of variables both variables are below a certain threshold, thereby filling a matrix. I appreciate your help!
You can use matrix multiplication:
I = double(U>q);
mTau = I.'*I;
This will have none-zero values on diagonal so you can set them to zero by
mTau = mTau - diag(diag(mTau));
One approach with bsxfun -
out = squeeze(sum(bsxfun(#and,I,permute(I,[1 3 2])),1));
out(1:size(out,1)+1:end)=0;

Mathematica Order of an Equation

Is there a way to obtain the order of an ODE in mathematica.
For example, if i have y''+5y i want mathematica return 2 (beacuse it's a 2nd order equation). So, is it possible what i'm asking?
here is a way to extract the value automatically:
ode = y'' + y' + y == 0 ;
Max[Cases[ ode , Derivative[n_][y] :> n , Infinity]]
2
note this just finds the largest derivative in the expression, it doesn't verify if the expression is actually an ode..

Plotting the solution to an equation with Mathematica

I have a function f(x,t) and I'd like to plot the function of the solution x(t) of f(x(t),t)=0 using Mathematica. How can I do it?
Mathematica is often quite different to other programming languages I can use. Normally, I would try something looking like:
Create arrays X, T
For t in T do
solve (numerically) f(x,t)=0, append the solution to X
Plot X
However, I don't know really well how to use loops in Mathematica yet, and the same for arrays, so I'm having serious problems doing this.
Is there some rapid, direct way of solving this problem with Mathematica? If not, could somebody please help me out with this?
Also, does anybody have a better title for the question?
Edit: Following the suggestion of #LutzL, I would try something like the following:
Table[FindRoot[f[x,t]==0,{x,x_0}],{t,start,stop,step}]
Would this work correctly?
I still have a problem, because my function f(x,t) is highly nonlinear, and thus i would like to input a good starting point for every t. Specifically, I know the solution for t=0 and I would like to use for time step t_{n+1} the solution for t_n. Is there a way to do this?
Edit 2: I solved the problem the following way:
tmax = 10; nsteps = 100*tmax;
thrust = {v/2 - g}; angle = {Pi/2};
For[i = 1, i <= nsteps, i++,
sol = {thr, \[Theta]} /.
FindRoot[{eq1[i*tmax/nsteps],
eq2[i*tmax/nsteps]}, {{thr, Last[thrust]}, {\[Theta],
Last[angle]}}]; AppendTo[thrust, sol[[1]]];
AppendTo[angle, sol[[2]]]];
ListPlot[Table[{i*tmax/nsteps, thrust[[i + 1]]}, {i, 0, nsteps}]]
ListPlot[Table[{i*tmax/nsteps, angle[[i + 1]]/Pi}, {i, 0, nsteps}]]
where eq1 and eq2 are my equations and thrust and angle are the solutions
A way to do it would be to create a list and then to plot it.
You have x(0) and you want x(t) for t>0. You can use the expression Szabolcs provides:
root(t_NumericQ, x0_):= Module[{z}, z = z /. FindRoot[f[z, t] == 0, {z, x0}]]
And then you compute and plot a list.
list[tin_, tend_, tstep_, x0_] := Module[{z = x0, t = tin}, lis = {};
While[t < tend, z = root[t, z]; lis = Append[lis, {t, z}]; t = t + tstep; ];
ListPlot[lis]]
Or you can change the last line for a x=Interpolation[lis] and x[t] will be an interpolation function for the solution x(t)
Moreover you can test whether other solutions for x(t) are possible replacing root[t,z] for RandomReal[{x_1,x_2}] where x_1and x_2 are in the range of the x space you want to explore.

Matlab Multiple Regression

I have this set of variables:
N = 250;
% independent variables[0..10]
x_1 = rand(N,1) * 10;
x_2 = rand(N,1) * 10;
y = ones(N,1); % regresssion variable
y((x_1 + x_2 + rand(N,1) * 2) <= 11) = 2;
I want to make two-var regression in matlab, but do not know how to do this, can somebody helps me? The result of linear or polynomial regression must be line between this two classes, stored in y.
One or more 'independent' variables, it's the same. Just as an example few ways to solve:
>>> X= [x_1 x_2];
>>> X\ y
ans =
0.10867
0.11984
>>> pinv(X)* y
ans =
0.10867
0.11984
See more of \ and pinv.
Matlab do have many other ways to solve least squares. You may like to elaborate more on your specific case, in order to find the most suitable one. Anyway, above documentation is a good starting point for you.
Edit:
Some general information on least squares worthwhile to read are wiki and mathworks

Resources