I have 3 dynamical equations. Each has 3 components each making a total of 9 components. I want to run the code below for several initial conditions say for 100 times and thereafter take the average before plotting. What can I do please?
see how I made the code for the first 100 initial conditions.
num_iter = 100;
for k = 1:100
x= rand(9,1);
g= (0:5:60);
% g= 0.5;
% computing the trajectory
dt = 0.01;
tspan = 100000;
xinput = x;
X = zeros(9,tspan);
deltaDR=zeros(length(g));
deltaRA=zeros(length(g));
for j= 1:length(g)
X(:,1)=x;
for i = 1: tspan
xoutput = rk4angelstepb(#attractor,dt,xinput,a,b,c,sigma,beta,rho,g(j));
X(:,i) = xoutput;
xinput = xoutput;
end
end
My code ran but for only one set of initial conditions. Please how do I tave the average of the entire initial condition. Also how do I plot the graph.
Related
From what I have read, using FFTW.jl / AbstractFFTs.jl's fft(A) when A is a 2D array should perform fft in 2D, not column-wise. Any idea why I am seeing only column-wise diffusion when (I think) I'm adding scaled second spatial derivative to u(t,x), as if using explicit solver for time?
Thank you! I am quite new to this.
code and heatmap screenshot
using Random
using FFTW
using Plots
gr()
N = (100,100)
# initialize with gaussian noise
u = randn(Float16, (N[1], N[2])).*0.4.+0.4
# include square of high concentration to observe diffusion clearly
u[40:50,40:50] .= 3
N = size(x)
L = 100
k1 = fftfreq(51)
k2 = fftfreq(51)
lap_mat = -(k1.^2 + k2.^2)
function lap_fft(x)
lapF = rfft(x)
lap = irfft(lap_mat.*lapF, 100)
return lap
end
# ode stepper or Implicit-Explicit solver
for i in 1:100000
u+=lap_fft(u)*0.0001
end
# plot state
heatmap(u)
Just because you are performing a real FFT, doesn't mean that you can real inverse fft the result. rfft goes from R -> C. What you can however do is the following:
function lap_fft(x)
lapF = complex(zeros(100,100)); # only upper half filled
lapF[1:51,1:100] = rfft(x) .* lap_mat; # R -> C
return abs.(ifft(lapF)); # C -> R
end
Real FFT to complex frequency domain (only upper half filled because of data redundancy), multiply your filter in frequency domain, inverse FFT into complex image domain and obtain the magnitude abs.(), real part real.() etc.
But honestly, why the hassle with the real fft?
using Random
using FFTW
using Plots
gr()
N = (100,100)
# initialize with gaussian noise
u = randn(Float16, (N[1], N[2])).*0.4.+0.4;
# include square of high concentration to observe diffusion clearly
u[40:50,40:50] .= 3;
N = size(u);
L = 100;
k1 = fftfreq(100);
k2 = fftfreq(100);
tmp = -(k1.^2 + k2.^2);
lap_mat = sqrt.(tmp.*reshape(tmp,1,100));
function lap_fft(x)
return abs.(ifftshift(ifft(fftshift(ifftshift(fft(fftshift(x))).*lap_mat))));
end
# ode stepper or Implicit-Explicit solver
for i in 1:100000
u+=lap_fft(u)*0.001;
end
# plot state
heatmap(u)
Let f be a continuous real function defined on the interval [a,b]. I want to aproximate this function by a piecewise quadratic polynomial. I already created a matrix that summarizes these polynomials. Let's say that I'm considering a uniform partition of the interval into N pieces ( therefore N+1 points).
I have a matrix A of size N times 3, where the k row represents the quadratic polynomial associated with the k-interval of this partition in the natural form ( the row [a b c] represents the polynomial a+bx+cx^2). I already created a method to find this matrix (obviously it depends on the choice of my interpolation points inside of each interval but that it doesn't matter for this question).
I'm trying to plot the corresponding function but I'm having some problems. I used the same idea given in Similar question. This is what I wrote
x=zeros(N+1,1);
%this is the set of points defining the uniform partition
for i=1:N+1
x(i)=a+(i-1)*((b-a)/(N));
end
%this is the length of my linspace for plotting the functions
l=100
And now I plot the functions:
figure;
hold on;
%first the original function
u=linspace(a,b,l*N);
v=arrayfun( f , u);
plot(u,v,'b')
% this is for plotting the other functions
for k=1:N
x0=linspace(x(k),x(k+1));
y0=arrayfun(#(t) [1,t,t^2]*A(k,:)',x0);
plot(x0, y0, 'r');
end
The problem is that the for is plotting the same function f and I don't know why. I tried with multiple different functions. I'm pretty sure that my matrix A is correct.
Please write a minimal working example that can be run as standalone code or copy/pasted from people here to check where you might have a bug -- often in the process of reducing your code to its bare principles in this manner, you end up figuring out what is the problem yourself in the first place. But, in any case, I have written one myself and cannot replicate the problem.
figure;
hold on;
# arbitrary values for Minimal Working Example
N = 10;
x = [10:10:110]; # (N+1, 1)
A = randn( N, 3 ); # (3 , N)
a = 100; b = 200; l = 3;
f = #(t) t.^2 .* sin(t);
%first the original function
u = linspace(a,b,l*N);
v = arrayfun( f , u);
plot(u,v,'b')
for k = 1 : N
x0 = linspace( x(k), x(k+1) )
y0 = arrayfun( #(t) ([1, t, t.^2]) * (A(k, :).'), x0 )
x0, y0
plot(x0, y0, 'r');
endfor
hold off;
Output:
Are you doing something different?
The analysis with wavelets seems to be carried out as a discrete transform via matrix multiplication. So it is not surprising, I guess, that when plotting, for example, D4, the R package wmtsa returns the plot:
require(wmtsa)
filters <- wavDaubechies("d4")
plot(filters)
The question is how to go from this discretized plot to the plot in the Wikipedia entry:
Please note that I'm not interested in generating these curves precisely with wmtsa. Any other package will do - I don't have Matlab or Mathematica. But I wonder if the way to go is to start with translating this Mathematica chunk of code in this paper into R, rather than using built-in functions:
Wave1etTransform.m
c[k-1 := c[k] = Daubechies[4][[k+l]];
phi[l] = (l+Sqrt[3])/2 // N;
phi[2] = (l-Sqrt[3])/2 // N;
phi[xJ; xc=0 II x>=3] : = 0
phi[x-?NumberQ] := phi[x] =
N[Sqrt[2]] Sum[c[k] phi[2x-k],{k,0,3}];
In order to plot the wavelet and scaling function all you need are the four numbers shown in the first two plots. I'll focus on plotting the scaling function.
Integer shifts of the scaling function, 𝜑, form an orthonormal basis of the subspace V0 of the multiresolution analysis. We also have that V-1 ⊆ V0 and that 𝜑(x/2) ∈ V-1. Using this gives us the identity
𝜑(x/2) = ∑k ∈ ℤ hk𝜑(x-k)
Now we just need the values of hk. For the Daubechies wavelet these are the values show in the discrete plot you gave (and zero for every other value of k). For an exact value of the hk, first let 𝜇 = (1+sqrt(3))/2. Then we have that
h0 = 𝜇/4
h1 = (1+𝜇)/4
h2 = (2-𝜇)/4
h3 = (1-𝜇)/4
and hk = 0 otherwise.
Using these two things we are able to plot the function using what is known as the cascade algorithm. First notice that 𝜑(0) = 𝜑(0/2) = h0𝜑(0) + h1𝜑(0-1) + h2𝜑(0-2) + h3𝜑(0-3). The only way this equation can hold is if 𝜑(0) = 𝜑(-1) = 𝜑(-2) = 𝜑(-3) = 0. Extending this will show that for x ≦ 0 we have that 𝜑(x) = 0. Furthermore, a similar argument can show that 𝜑(x) = 0 for x ≥ 3.
Thus, we only need to worry about x = 1 and x = 2 to find non-zero values of 𝜑 for integer values of x. If we put x = 2 into the identity for 𝜑(x/2) we get that 𝜑(1) = h0𝜑(2) + h1𝜑(1). Putting x = 4 into the identity gives us that 𝜑(2) = h2𝜑(2) + h3𝜑(1).
We can rewrite the above two equations as a matrix multiplied by a vector equals a vector. In fact, it will be in the form v = Av (v is the same vector on both sides). This means that v is an eigenvector of the matrix A with eigenvalue 1. But v = (𝜑(1), 𝜑(2)) and so by finding this eigenvector using the standard methods we will be able to find the values of 𝜑(1) and 𝜑(2).
In fact, this gives us that 𝜑(1) = (1+sqrt(3))/2 and 𝜑(2) = (1-sqrt(3))/2 (this is where those values in the Mathematica code sample come from). Also note that we need to specifically chose the eigenvector of magnitude 2 for this algorithm to work so you must use those values for 𝜑(1) and 𝜑(2) even though you could rescale the eigenvector.
Now we can find the values of 𝜑(1/2), 𝜑(3/2), and 𝜑(5/2). For example, 𝜑(1/2) = h0𝜑(1) and 𝜑(3/2) = h1𝜑(2) + h2𝜑(1).
With these values, you can then find the values of 𝜑(1/4), 𝜑(3/4), and so on. Continuing this process will give you the value of 𝜑 for all dyadic rationals (rational numbers in the form k/2j.
The same process can be used to find the wavelet function. You only need to use the four different values shown in the first plot rather than the four shown in the second plot.
I recently implemented this Python. An R implementation will be fairly similar.
import numpy as np
import matplotlib.pyplot as plt
def cascade_algorithm(j: int):
mu = (1 + np.sqrt(3))/2
h_k = np.array([mu/4, (1+mu)/4, (2-mu)/4, (1-mu)/4])
# Array to store all the value of phi.
phi_vals = np.zeros((2, 3*2**j+1), dtype=np.float64)
for i in range(3*2**j+1):
phi_vals[0][i] = i/(2**j)
calced_vals = np.zeros((3*2**j+1), dtype=np.bool)
# Input values for 1 and 2.
phi_vals[1][1*2**j] = (1+np.sqrt(3))/2
phi_vals[1][2*2**j] = (1-np.sqrt(3))/2
# We now know the values for 0, 1, 2, and 3.
calced_vals[0] = True
calced_vals[1*2**j] = True
calced_vals[2*2**j] = True
calced_vals[3*2**j] = True
# Now calculate for all the dyadic rationals.
for k in range(1, j+1):
for l in range(1, 3*2**k):
x = l/(2**k)
if calced_vals[int(x*2**j)] != True:
calced_vals[int(x*2**j)] = True
two_x = 2*x
which_k = np.array([0, 1, 2, 3], dtype=np.int)
which_k = ((two_x - which_k > 0) & (two_x - which_k < 3))
phi = 0
for n, _ in enumerate(which_k):
if which_k[n] == True:
phi += h_k[n]*phi_vals[1][int((two_x-n)*2**j)]
phi_vals[1][int(x*2**j)] = 2*phi
return phi_vals
phi_vals = cascade_algorithm(10)
plt.plot(phi_vals[0], phi_vals[1])
plt.show()
If you just want to plot the graphs, then you can use the package "wavethresh" to plot for example the D4 with the following commands:
draw.default(filter.number=4, family="DaubExPhase", enhance=FALSE, main="D4 Mother", scaling.function = F) # mother wavelet
draw.default(filter.number=4, family="DaubExPhase", enhance=FALSE, main="D4 Father", scaling.function = T) # father wavelet
Notice that the mother wavelet and the father wavelets will be plotted depending on the variable "scaling.function". If true, then it plots the father wavelet (scaling), else it plots the mother wavelet.
If you want to generate it by yourself, without packages, I'd suggest you follow Daubechies-Lagarias algorithm, in this paper. It is not hard to implement.
I have such a problem on hand. Imagine there are 5 sliders with a range of values 0 to 100. In the beginning, they are all set to 50, so the average score is 50.
Goal 1. Maintain average at 50
Say, if I move the first slider to 70, in order to maintain the average at 50, I decrease the value of the other 4 sliders to 45, i.e. 50 - (20/4) = 45.
Goal 2. Maintain ratios between individual values
The above example was easy, because all 4 affected values where equal. However, if I decide to move the 5th slider to 50, I want all the other sliders to adjust so that the ratios between individual values (e.g. slider 1 / slider 2 is 70 / 45 -> 1,5555...) remain the same.
Here's the method I'm considering.
Step 1. Find the smallest value in the array of affected values (slider 1-4).
Step 2. Calculate ratios of each slider with the minimum-value-slider.
Step 3. This gives me a formula avg(ratio1*minV + ratio2*minV + ratio3*minV + *minV + newManualV) = 50
Step 4. Calculate minV and the remaining values using ratios.
So, in my example, it would be something like this:
newManualV = 50 (5th slider)
minV = 45 (any of the 2nd-4th sliders; let's say it's the 2nd)
ratio1 = 1.55556 (1st and minV)
ratio2 = 1 (3rd and minV)
ratio3 = 1 (3rd and minV)
(1.55556*minV + 1*minV + 1*minV + minV + 50) / 5 = 50
4.55556minV = 200
minV = 43.9
New (rounded) slider values are:
68 (43.9 * 1.55556)
44
44
44
50
Question. Is there a better way of doing this?
What is better? I think there is an easier way, as you do not need to explicitly calculate the ratio's. Just distribute the difference of the altered slider equally.
Denote the slide values with s1, ..., s5.
Suppose you change s1 with and amount d. Then, calculate s, the sum of the other sliders: s = s2+s3+s4+s5. Now, s2 -= (s2/s)*d.
The sum of s1 to s5 does not change (and so the average), and all other sliders are changed in proportion.
Five sliders equals 4 ratios to maintain. For example x_1/x_2. This is done only by multiplying all the slider by the same factor.
As soon as you set one value (for example slider #5) then all the others have to scale accordingly to maintain the ratios.
old_x_5 = x_5
x_5 = (new value)
scale = x_5/old_x_5
x_4 = x_4*scale
x_3 = x_3*scale
x_2 = x_2*scale
x_1 = x_1*scale
Now you have to re-scale everything in order to meet the average goal
average = (x_1+x_2+x_3+x_4+x_5)/5
if average>0
scale = 50/average
x_5 = x_5*scale
x_4 = x_4*scale
x_3 = x_3*scale
x_2 = x_2*scale
x_1 = x_1*scale
else
(now what?)
This changes the new x_5 to a value needed for the average goal instead of the user input. Also what happens if any of the sliders need to be over 100 to maintain the average.
I have been wracking my brain to come up with a solution to this problem.
I have a lookup table that returns height values for various points (x,z) on the grid. For instance I can calculate the height at A, B, C and D in Figure 1. However, I am looking for a way to interpolate the height at P (which has a known (x,z)). The lookup table only has values at the grid intervals, and P lies between these intervals. I am trying to calculate values s and t such that:
A'(s) = A + s(C-A)
B'(t) = B + t(P-B)
I would then use the these two equations to find the intersection point of B'(t) with A'(s) to find a point X on the line A-C. With this I can calculate the height at this point X and with that the height at point P.
My issue lies in calculating the values for s and t.
Any help would be greatly appreciated.
Try also bilinear interpolation or bicubic interpolation.
Depending on if you want to interpolate between ABC or ABCD the algorithm will change.
To interpolate between ABC (which I assume is what you want to do since you draw the diagonal) you will need to find the barycentric coordinates of P relative to ABC x and y positions then apply the barycentric coordinate to the height (z is assumed here) component of those triangles.
What about going this way: find u and v so that
P = B + u(A-B) + v(C-B)
If you write this out, you'll see that this is a 2x2 linear system with unknowns u and v, so I guess you know how to go on from there.
Oh, and once you have u and v you use the same exact formula as above for the height, only this time A,B,C,P will be the heights at these points.
Considering points value are available at four corners of a square of unit length, interpolated value at any point(x,y) inside the square is given by:
f(x,y) = [ (1-y)f(0,0) + yf(0,1) ](1-x) + [ (1-y)f(1,0)+y(f(1,1)) ]x
If square has length other than 1,say L then f(x,y) is given by:
f(x,y) = [ (L-y)f(0,0) + yf(0,L) ](L-x)/L^2 + [ (L-y)f(L,0)+y(f(L,L)) ]x/L^2
image
Here's an explicit example based on shape functions.
Consider the functions:
u1(x,z) = (x-x_b)/(x_c-x_b)
One has u1(x_b,z_b) = u1(x_a,z_a) = 0 (because x_a = x_b) and u1(x_c,z_c) = u1(x_d,z_d) = 1
u2(x,z) = 1 - u1(x,z)
Now we have u2(x_b,z_b) = u2(x_a,z_a) = 1 and u2(x_c,z_c) = u2(x_d,z_d) = 0
v1(x,z) = (z-z_b)/(z_a-z_b)
This function satisfies v1(x_a,z_a) = v1(x_d,z_d) = 1 and v1(x_b,z_b) = v1(x_c,z_c) = 0
v2(x,z) = 1 - v1(x,z)
We have v2(x_a,z_a) = v2(x_d,z_d) = 0 and v2(x_b,z_b) = v2(x_c,z_c) = 1
Now let's build new functions as follows:
S_D(x,z) = u1(x,z) * v1(x,z)
We get S_D(x_d, z_d) = 1 and S_D(x_a,z_a) = S_D(x_b,z_b) = S_D(x_c,z_c) = 0
S_C(x,z) = u1(x,z) * v2(x,z)
We get S_C(x_c, z_c) = 1 and S_C(x_a,z_a) = S_C(x_b,z_b) = S_C(x_d,z_d) = 0
S_A(x,z) = u2(x,z) * v1(x,z)
We get S_A(x_a, z_a) = 1 and S_A(x_b,z_b) = S_A(x_c,z_c) = S_A(x_d,z_d) = 0
S_B(x,z) = u2(x,z) * v2(x,z)
We get S_B(x_b, z_b) = 1 and S_B(x_a,z_a) = S_B(x_c,z_c) = S_B(x_d,z_d) = 0
Now define your interpolating function as
H(x,z) = h_a * S_A(x,z) + h_b * S_B(x,z) + h_c * S_C(x,z) + h_d * S_D(x,z),
where h_a is the heigh at point A, h_b is the height at point B, and so on.
You can easily verify that H is indeed an interpolating function:
H(x_a,z_a) = h_a, H(x_b,z_b) = h_b, H(x_c,z_c) = h_c and H(x_d,z_d) = h_d.
Now, in order to approximate the height at P, all you need to do is evaluate H at this point:
h_p = H(x_p, z_p)
The functions S are normally referred to as "shape functions". There's one such function for each node you want your interpolated value to depend on, and in this case they all satisfy Kronecker's delta property (they take the value one at one node and zero at all other nodes).
There are many ways to build shape functions for a given set of nodes. If I remember correctly, the construction of 2D shape functions by multiplication of 1D shape functions (as we've done in this case) is called "tensor product of functions" (easy in this case because the grid is rectangular). We have ended up with four functions (one per node), all of them linear combinations of {1, x, z, xz}.
If you want to use only three points for your interpolation, then you should be able to easily build three shape functions as linear combinations of {1, x, z} only, but you will loose a 25% of the height information provided by the grid and your interpolant will not be smooth inside the rectangle when h_b != h_d.