Loading video...

Video Failed to Load

Go Home

Piplup crosshair | #VALORANT code: 0;s;1;P;c;4;o;1;d;1;z;6;a;0;f;0;m;1;0t;10;0l;10;0v;0;0g;1;0o;10;0a;0;0f;0;1t;6;1l;0;1v;3;1g;1;1o;0;1a;1;1s;0.053;1e;0.206

268,702 views • 1 year ago •via X (Twitter)

0 Comments

No comments available

Comments from the original post will appear here

Related Videos

Following many two-dimensional turbulence animations, it is time to share computer code! Implementation of a vorticity-streamfunction method with a pseudo-spectral discretization + third-order Runge-Kutta for time integration (our CFD class semester project). The MATLAB code: M = 256; % number of points N = M; Lx = 2*pi; Ly = 2*pi; nu = 5e-4; % kinematic viscosity Sc = 0.7; % Schmidt number beta = 0; % meridional gradient of Coriolis parameter ar = 0.02; %random number amplitude b = 1; % mean scalar gradient CFLmax = 0.8; tend = 200; % end time x=linspace(0,Lx,M+1); x(end)=[]; dx = Lx/M; kx=[0:M/2 -M/2+1:-1]*2*pi/Lx; y=linspace(0,Ly,N+1); y(end)=[]; ky=[0:N/2 -N/2+1:-1]*2*pi/Ly; dy = Ly/N; time = 0; index_kmax = ceil(M/3); kmax = kx(index_kmax); filter = ones(M,N); filter(index_kmax+1:2*index_kmax+3,index_kmax+1:2*index_kmax+3)=0; rng(64); [u, v, omega, psi, ddx, ddy, idel2, kk, k2]=deal(zeros(M,N)); for j=1:N ddx(:,j)=1i*kx; end for i=1:M ddy(i,:)=1i*ky; end for i=1:M for j=1:N idel2(i,j)=-kx(i)^2-ky(j)^2; end end idel2=1./idel2; idel2(1,1)=0; for i=1:M for j=1:N kk(i,j)=kx(i)^2+ky(j)^2; k2(i,j)=kx(i)^2+ky(j)^2; if kk(i,j) >= 6^2 && kk(i,j) <= 7^2 % forcing kk(i,j) = -kk(i,j); end if kk(i,j) <= 2^2 kk(i,j) = 8*kk(i,j); % large-scale dissipation end end end for i=1:M for j=1:N u(i,j) = cos(2*x(i))*sin(2*y(j))+ar*rand; v(i,j) = -sin(2*x(i))*cos(2*y(j))+ar*rand; end end uhat = fft2(u); vhat = fft2(v); omegahat = ddx.*vhat - ddy.*uhat; % make vorticity phi = rand(size(u)); phihat = fft2(phi); ncid = netcdf.create(' 'CLOBBER'); dimid_x = netcdf.defDim(ncid, 'x', M); dimid_y = netcdf.defDim(ncid, 'y', N); dimid_time = netcdf.defDim(ncid, 'time', netcdf.getConstant('NC_UNLIMITED')); varid_x = netcdf.defVar(ncid, 'x', 'NC_FLOAT', [dimid_x]); varid_y = netcdf.defVar(ncid, 'y', 'NC_FLOAT', [dimid_y]); varid_u = netcdf.defVar(ncid, 'u', 'NC_FLOAT', [dimid_x, dimid_y, dimid_time]); varid_v = netcdf.defVar(ncid, 'v', 'NC_FLOAT', [dimid_x, dimid_y, dimid_time]); varid_omega = netcdf.defVar(ncid, 'vorticity', 'NC_FLOAT', [dimid_x, dimid_y, dimid_time]); varid_phi = netcdf.defVar(ncid, 'scalar', 'NC_FLOAT', [dimid_x, dimid_y, dimid_time]); varid_dissipation = netcdf.defVar(ncid, 'dissipation', 'NC_FLOAT', [dimid_x, dimid_y, dimid_time]); varid_time = netcdf.defVar(ncid, 'time', 'NC_FLOAT', [dimid_time]); netcdf.endDef(ncid); netcdf.putVar(ncid, varid_time, 0, 1, time); netcdf.putVar(ncid, varid_x, 0, M, x); netcdf.putVar(ncid, varid_y, 0, N, y); netcdf.putVar(ncid, varid_phi, [0, 0, 0], [M, N, 1], phi); netcdf.putVar(ncid, varid_u, [0, 0, 0], [M, N, 1], u); netcdf.putVar(ncid, varid_v, [0, 0, 0], [M, N, 1], v); netcdf.putVar(ncid, varid_omega, [0, 0, 0], [M, N, 1], omega); netcdf.putVar(ncid, varid_dissipation, [0, 0, 0], [M, N, 1], 0*omega); dt = 0.5*min([dx dy]); nstep = 1; while time < tend psihat = -idel2.*omegahat; uhat = ddy.*psihat; vhat = -ddx.*psihat; u = real(ifft2(uhat)); v = real(ifft2(vhat)); omegadx = real(ifft2(ddx.*omegahat)); omegady = real(ifft2(ddy.*omegahat)); facto = exp(-nu*8/15*dt*kk); factp = exp(-nu/Sc*8/15*dt*k2); r0o = -fft2(u.*omegadx+v.*omegady)+beta*vhat; r0p = -fft2(u.*real(ifft2(ddx.*phihat))+v.*real(ifft2(ddy.*phihat)))+b*vhat; omegahat = facto.*(omegahat + dt*8/15*r0o); % update omega phihat = factp.*(phihat + dt*8/15*r0p); % update phi %%%% Substep 2 psihat = -idel2.*omegahat; uhat = ddy.*psihat; vhat = -ddx.*psihat; u = real(ifft2(uhat)); v = real(ifft2(vhat)); omegadx = real(ifft2(ddx.*omegahat)); omegady = real(ifft2(ddy.*omegahat)); r1o = -fft2(u.*omegadx+v.*omegady)+beta*vhat; r1p = -fft2(u.*real(ifft2(ddx.*phihat))+v.*real(ifft2(ddy.*phihat)))+b*vhat; omegahat = omegahat + dt*(-17/60*facto.*r0o + 5/12*r1o); phihat = phihat + dt*(-17/60*factp.*r0p + 5/12*r1p); facto = exp(-nu*(-17/60+5/12)*dt*kk); factp = exp(-nu/Sc*(-17/60+5/12)*dt*k2); omegahat = omegahat.*facto; phihat = phihat.*factp; %%%% Substep 3 psihat = -idel2.*omegahat; uhat = ddy.*psihat; vhat = -ddx.*psihat; % max(max(abs(real(ifft2(1i*ddx.*uhat+1i*ddy.*vhat))))) % divergence u = real(ifft2(uhat)); v = real(ifft2(vhat)); omegadx = real(ifft2(ddx.*omegahat)); omegady = real(ifft2(ddy.*omegahat)); r2o = -fft2(u.*omegadx+v.*omegady)+beta*vhat; r2p = -fft2(u.*real(ifft2(ddx.*phihat))+v.*real(ifft2(ddy.*phihat)))+b*vhat; omegahat = omegahat + dt*(-5/12*facto.*r1o + 3/4*r2o); phihat = phihat + dt*(-5/12*factp.*r1p + 3/4*r2p); facto = exp(-nu*(-5/12+3/4)*dt*kk); factp = exp(-nu/Sc*(-5/12+3/4)*dt*kk); omegahat = omegahat.*facto; phihat = phihat.*factp; phihat = filter.*phihat; omegahat = filter.*omegahat; time = time + dt; nstep = nstep + 1; CFL = max(max(abs(u)))/dx*dt+max(max(abs(v)))/dy*dt; if mod(nstep,20)==0 phi = real(ifft2(phihat)); omega = real(ifft2(omegahat)); dissipation = 2*nu*(real(ifft2(ddx.*uhat)).^2 + real(ifft2(ddy.*uhat)).^2 + real(ifft2(ddx.*vhat)).^2 + real(ifft2(ddy.*vhat)).^2); eta = (nu^3/mean(dissipation,'all'))^0.25; subplot(221); pcolor(x,y,omega'); title('Vorticity'); shading flat; axis equal tight; colorbar; drawnow subplot(222); pcolor(x,y,phi'); title('Scalar'); shading flat; axis equal tight; colorbar; drawnow subplot(223); pcolor(x,y,dissipation'); title('Dissipation'); shading flat; axis equal tight; colorbar; drawnow subplot(224); pcolor(x,y,u); title('u-velocity'); shading flat; axis equal tight; colorbar; drawnow fprintf(1,'step = %d time = %g dt = %g CFL = %g kmax*eta = %g %g\n', nstep, time, dt, CFL, eta.*kmax, eta.*kmax/sqrt(Sc)); [~, dim_time_len] = netcdf.inqDim(ncid,dimid_time); netcdf.putVar(ncid, varid_time, [dim_time_len], [1], time); netcdf.putVar(ncid, varid_phi, [0, 0, dim_time_len], [M, N, 1], phi); netcdf.putVar(ncid, varid_u, [0, 0, dim_time_len], [M, N, 1], u); netcdf.putVar(ncid, varid_v, [0, 0, dim_time_len], [M, N, 1], v); netcdf.putVar(ncid, varid_omega, [0, 0, dim_time_len], [M, N, 1], omega); netcdf.putVar(ncid, varid_dissipation, [0, 0, dim_time_len], [M, N, 1], dissipation); netcdf.sync(ncid); end dt = CFLmax/CFL*dt; %0.0005; end netcdf.close(ncid);

Computational Fluid Dynamics group

226,726 views • 3 years ago

[Graph Convolutional Network] by hand ✍️ Graph Convolutional Networks (GCNs), introduced by Thomas Kipf and Max Welling in 2017, have emerged as a powerful tool in the analysis and interpretation of data structured as graphs. This exercise demonstrates how GCN works in a simple application: binary classification. -- Goal -- Predict if a node in a graph is X. -- Architecture -- 🟪 Graph Convolutional Network (GCN) 1. GCN1(4,3) 2. GCN2(3,3) 🟦 Fully Connected Network (FCN) 1. Linear1(3,5) 2. ReLU 3. Linear2(5,1) 4. Sigmoid Simplications: • Adjacent matrices are not normalized. • ReLU is applied to messages directly. -- Walkthrough -- [1] Given ↳ A graph with five nodes A, B, C, D, E [2] 🟩 Adjacency Matrix: Neighbors ↳ Add 1 for each edge to neighbors ↳ Repeat in both directions (e.g., A->C, C->A) ↳ Repeat for both GCN layers [3] 🟩 Adjacency Matrix: Self ↳ Add 1's for each self loop ↳ Equivalent to adding the identity matrix ↳ Repeat for both GCN layers [4] 🟪 GCN1: Messages ↳ Multiply the node embeddings 🟨 with weights and biases ↳ Apply ReLU (negatives → 0) ↳ The result is one message per node [5] 🟪 GCN1: Pooling ↳ Multiply the messages with the adjacent matrix ↳ The purpose is the pool messages from each node's neighbors as well as from the node itself. ↳ The result is a new feature per node [6] 🟪 GCN1: Visualize ↳ For node 1, visualize how messages are pooled to obtain a new feature for better understanding ↳ [3,0,1] + [1,0,0] = [4,0,1] [7] 🟪 GCN2: Messages ↳ Multiply the node features with weights and biases ↳ Apply ReLU (negatives → 0) ↳ The result is one message per node [8] 🟪 GCN2: Pooling ↳ Multiply the messages with the adjacent matrix ↳ The result is a new feature per node [9] 🟪 GCN2: Visualize ↳ For node 3, visualize how messages are pooled to obtain a new feature for better understanding ↳ [1,2,4] + [1,3,5] + [0,0,1] = [2,5,10] [10] 🟦 FCN: Linear 1 + ReLU ↳ Multiply node features with weights and biases ↳ Apply ReLU (negatives → 0) ↳ The result is a new feature per node ↳ Unlike in GCN layers, no messages from other nodes are included. [11] 🟦 FCN: Linear 2 ↳ Multiply node features with weights and biases [12] 🟦 FCN: Sigmoid ↳ Apply the Sigmoid activation function ↳ The purpose is to obtain a probability value for each node ↳ One way to calculate Sigmoid by hand ✍️ is to use the approximation below: • >= 3 → 1 • 0 → 0.5 • <= -3 → 0 -- Outputs -- A: 0 (Very unlikely) B: 1 (Very likely) C: 1 (Very likely) D: 1 (Very likely) E: 0.5 (Neutral)

Tom Yeh

46,779 views • 2 years ago

MLP in PyTorch by hand ✍️ ~ 7 steps walkthrough below Goal: fill in every blank in the PyTorch code to build a multi-layer perceptron. 1. Given Let us start with a code template on the left and the network it is supposed to build on the right. Every blank in the code can be worked out from the picture. 2. Linear layer We count: 3 features in, 4 features out. So the weight matrix is 4 by 3. There is an extra column for the biases, which means bias = T. 3. ReLU Let us apply the activation. ReLU crosses out the negatives, so -1 becomes 0. 4. Linear layer The input size is 4, because that is what the previous layer put out. The output size is 2. A 2 by 4 weight matrix, and this time no extra column, so bias = F. 5. ReLU We cross out the negatives again. 6. Linear layer Two features in, five out. A 5 by 2 weight matrix, with a bias column, so bias = T. 7. Sigmoid Let us finish. Sigmoid squashes the raw scores (3, 0, -2, 5, -5) into probabilities between 0 and 1. You have just implemented a three-layer deep neural network by hand. ✍️ == Story == Three years ago I gave this exercise to my students, to connect the code to the math. They found it odd. Every other AI course they were taking lived inside a Jupyter notebook, and here I was handing out paper. Three years later, my colleagues are the ones rushing to move their materials to paper. The exercise has not changed. Paper still asks the one thing a notebook lets you skip: do you actually understand what the code is doing? If you can tell me why the weight matrix is 4 by 3, and why bias is F on the second layer, you understand nn.Linear better than someone who has been copy-pasting it for a year. 💾 Save this post! #AIbyHand #PyTorch #DeepLearning

Tom Yeh

13,318 views • 1 month ago

[Discrete Fourier Transform] by Hand ✍️ In signal processing, the Discrete Fourier Transform (DFT) is no doubt the most important method. But the math involved is extremely complex, literally, involving a summation over a complex number term e^(-iwt). I developed this exercise to demonstrate that underneath such complexity, DFT is just a series of matrix multiplications you can calculate by hand. ✍️ Once you see that, it should not surprise you that a deep neural network, which is also a series of matrix multiplications, with activation functions in-between, can learn to perform DFT to process and analyze signals so effectively. How does DFT work? [1] Given ↳ Signals A, B, and C in the 🟧 frequency domain: ◦ A = cos(w) + 2cos(2w) ◦ B = cos(w) + cos(3w) + cos(4w) ◦ C = -cos(2w) + cos(3w) ◦ Each signal is a weighed sum of four cosine waves at frequencies 1w, 2w, 3w, and 4w. ◦ We will apply Inverse DFT to convert the signals to time domain representations, and then demonstrate DFT can convert back to their original frequency domain representations. ↳ Signal X in the 🟩 time domain. X is sampled at 10 time points 1t, 2t, …, 10t: ◦ X = [-2.5, -1.8, 3, -0.7, -1.0, -0.7, 3, -1.8, -2.5, 5] ◦ Suppose X is also a weighted sum of the same four cosine waves, but we don’t already know their weights. We will apply DFT to discover them. [2] 🟧 Frequency Matrix (F) ↳ Write the coefficients of A, B, C as a matrix F. Each signal is a row. Each frequency is a column. ↳ A → [1, 2, 0, 0] ↳ B → [1, 0, 1, 1] ↳ C → [0, 1-, 1, 0] [3] Cosine → Discrete ↳ Sample from the continuous cosine waves at discrete time points 1t, 2t, 3t, to 10t. [4] Cosine Matrix (W) ↳ Write the samples as a matrix, Each frequency is a row. Each time point is a column. [5] Inverse DFT: 🟧 Frequency → 🟩 Time ↳ Multiply the frequency matrix F and the cosine matrix W. ↳ The meaning of this multiplication is to linearly combine the four cosine waves (rows in W) into time-domain signals (rows in T) using the weights specified in F. ↳ The result is matrix T, which are signals A, B, C converted to the time domain. Each signal is a row. Each time point is a column. [6] Transpose ↳ Transpose T, converting each signal’s time domain representation from a row to a column. [7] DFT: 🟩 Time → 🟧 Frequency ↳ Multiply the cosine matrix W with the transpose of matrix T. ↳ The purpose of this multiplication is to take a dot-product between each time-domain signal (columns in the transpose of T) and each cosine wave (rows in W), which has the effect of projecting the signal onto a cosine wave to determine how much they are correlated. Zero means not correlated at all. ↳ The result is an intermediate version of the “recovered” frequency matrix where each column corresponds to a signal and each row corresponds to a frequency. ↳ Compared to the original frequency matrix F, this intermediate matrix has non-zero weights in the correct places, but scaled up by a factor of 5 (n/2, n=10). For example, signal A, originally [1,2,0,0], is recovered at [5,10,0,0]. [8] Scale ↳ Multiply each value by 2/n = 1/5 to scale down the intermediate matrix to match the magnitude of the original frequency matrix F. [9] Transpose ↳ Transpose the recovered frequency matrix back to the same orientation of the original frequency matrix F. ↳ Like magic 🪄, the result is identical to the original F, which means DFT successfully recovered the frequency components of signals A, B, C. [10] Apply DFT to X: 🟩 Time → 🟧 Frequency ↳ Now that we have some confidence in DFT’s ability to recover frequency components, we apply DFT to X’s time-domain representation by multiplying W with X. ↳ The result is the an intermediate matrix. [11] Scale ↳ Similarly, we scale down by a factor of 5 to obtain the recovered frequency components of X (a column). [12] Transpose ↳ Similarly, we transpose the recovered column to row to match the orientation of the frequency matrix. ↳ Using the coefficients [0,0,3,2], we can write the equation of X as 3cos(3w) + 2cos(4w). Notes: I hope this by hand exercise helps you understand the essence of DFT. But there is more technical details, such as: • Sine: The complete DFT math also includes sine waves that follow a similar calculation process. • Phase: Here, we assume all the cosine waves are aligned at the origin, namely, phase is 0. If a phase p is added, for example, cos(w+p), we will need to calculate the sine component and use their ratio to figure out what p is. • Magnitude: If phase is not zero, the magnitude will need to be calculated by combining both cosine and sine terms.

Tom Yeh

116,622 views • 2 years ago