def model_sde_1mut(z, t, R, R_div, c, c_0, c_1, delta, I, k_x, k_s, N, H, rw, a, mu, K): ##wt, mutant populations, and substrate given as one length 4*R array due to odeint constraints z[z < 0] = 0 ind = (R - 1) * R_div + 1 b = z[0:ind] bm = z[ind:2 * ind] s = z[2 * ind:] ##compact support heaviside function height CC = (3.5 * 10**8) dbdt = M_A(c, c_0, c_1, R_div) * grad(grad(b)) - delta * X_A( c, c_0, c_1, I) * grad(b * (k_x / (s + k_x)**2) * grad(s)) + b * rw * ( (s / (k_s + s)) - b - bm) - b * mu + np.random.normal( np.zeros(len(b)), abs(b * abs( ((2 * b * (1 - b - bm)) / K))**.5)) dbmdt = M_A(c, c_0, c_1, R_div) * grad(grad(bm)) - delta * X_A( c, c_0, c_1, I) * grad(bm * (k_x / (s + k_x)**2) * grad(s)) + bm * rw * a * ( (s / (k_s + s)) - b - bm) + b * mu - bm * mu + np.random.normal( np.zeros(len(bm)), abs(b * abs(((2 * bm * (1 - b - bm)) / K))**.5)) dsdt = N * grad(grad(s)) - H * (s / (s + k_s)) * (rw * b + a * rw * bm) dzdt = [dbdt, dbmdt, dsdt] return np.concatenate(dzdt)
def curl(Bx, By, Bz, dx, dy, dz): ''' Take numerical curl in 3D regular cartesian coords ''' dBx, dBy, dBz = grad(Bx), grad(By), grad(Bz) Rx = dBz[1] / dy - dBy[2] / dz Ry = dBx[2] / dz - dBz[0] / dx Rz = dBy[0] / dx - dBx[1] / dy return Rx, Ry, Rz
def JxB_force(path, I, B): ''' Given a wire path, a current I and magnetic field B, calculates the JxB force at each point ''' dl = grad(path, axis=0) #centered differences return I * np.cross(dl, B)
def inductance(path1, path2, rwire=0.001, norm=None): ''' Given two wire paths, calculates the mutual inductance in SI units taken from: Advanced Electromagnetics. 2016;5(1) DOI 10.7716/aem.v5i1.331 ''' dl1 = grad(path1, axis=0) #centered differences dl2 = grad(path2, axis=0) #centered differences L = 0 for i in range(0, len(path1)): for j in range(0, len(path2)): dd = sqrt(((path1[i] - path2[j])**2).sum()) if dd > rwire / 2.: L += np.dot(dl1[i], dl2[j]) / dd if norm is None: return mu0 * L / (4 * pi) else: return mu0 * L / (4 * pi) / norm
def _calc_objectives(self, a, b, x, y): # Compute transport plan. M = (self.w_[:, None] + self.h_[None, :] - self.C_) / self.eps log_P = jx.log(a)[:, None] + jx.log(b)[None, :] + M self.P_ = jx.exp(log_P) # Compute dual objective. self.dual_obj_ = ( - inner_prod(a, self.margdiv.conj_ent(-self.w_)) - inner_prod(b, self.margdiv.conj_ent(-self.h_)) - self.eps * jx.sum(self.P_) + self.eps * jx.sum(a[:, None] * b[None, :]) ) # Compute primal objective. kl = ForwardKL(1.0) self.primal_obj_ = ( inner_prod(self.C_, self.P_) + self.margdiv(self.P_.sum(axis=1), a) + self.margdiv(self.P_.sum(axis=0), b) + self.eps * kl(self.P_, a[:, None] * b[None, :]) ) # These gradients still need to be validated # Compute gradient with respect to mass vector a self.grad_a_ = self.w_ # Compute gradient with respect to mass vector b self.grad_b_ = self.h_ # Compute gradient with respect to position vector x # Will grad work because logsumexp was imported from scipy? phi_x = lambda x0: -softmin(self.C - self.h_[None, :], b[None, :], eps, axis=1) self.grad_x_ = jx.grad(phi_x)(x) # Compute gradient with respect to position vector y phi_y = lambda y0: -softmin(self.C - self.w_[:, None], a[:, None], eps, axis=0) self.grad_y_ = jx.grad(phi_y)(y)
def biot_savart(p, I, path, delta=.01): '''Given a point, a current and its path, calculates the magnetic field at that point This function uses normalized units: e.g. positions are normalized by a radial length scale r~(r'/L0) current is normalized to a characteristic value I~(I'/I0) Bfield is normalized to B~(B'/B0) ''' dl = grad(path, axis=0) #centered differences r = path - p rmag = linalg.norm(r, axis=1) rmag[rmag <= delta] = 1e6 B = sum(np.cross(r, dl) / (rmag**3.)[:, newaxis]) B *= I / 2. return B
def genForce(self, B_field, phi, i): Bx_field = B_field[0] By_field = B_field[1] Bz_field = B_field[2] current_path = os.getcwd() if "forcefielddata" not in os.listdir(current_path): os.mkdir("forcefielddata") os.chdir("forcefielddata") file = open("forcefielddata" + str(i) + ".txt", "w+") forcex = np.zeros((int(2 * self.xlim / self.resolution), int(2 * self.ylim / self.resolution), int(2 * self.zlim / self.resolution))) forcey = np.zeros((int(2 * self.xlim / self.resolution), int(2 * self.ylim / self.resolution), int(2 * self.zlim / self.resolution))) forcez = np.zeros((int(2 * self.xlim / self.resolution), int(2 * self.ylim / self.resolution), int(2 * self.zlim / self.resolution))) M = self.magnetization * np.array([np.cos(phi), np.sin(phi), 0]) for i in range(int(2 * self.xlim / self.resolution)): for j in range(int(2 * self.ylim / self.resolution)): for k in range(int(2 * self.zlim / self.resolution)): force = np.grad( np.dot( M, np.array([ Bx_field[i][j][k], By_field[i][j][k], Bz_field[i][j][k] ]))) forcex[i][j][k] = force[0] forcey[i][j][k] = force[1] forcez[i][j][k] = force[2] file.write("(" + str(i * self.resolution - self.xlim) + "," + str(j * self.resolution - self.ylim) + "," + str(k * self.resolution - self.zlim) + ") " + "(" + str(force[0]) + "," + str(force[1]) + "," + str(force[2]) + ")\r\n") os.chdir(current_path)
def get_R(r): '''Solve for curvature in 3d (assume x(s), y(s), z(s)). endpoints and penultimate points will give incorrect values due to boundary effects ''' xp = grad(r[0]) xpp= grad(xp) yp = grad(r[1]) ypp= grad(yp) zp = grad(r[2]) zpp= grad(zp) numer = ( (zpp*yp - ypp*zp)**2. + (xpp*zp - zpp*xp)**2. + (ypp*xp - xpp*yp)**2. )**.5 denom = (xp**2. + yp**2. + zp**2.)**1.5 kappa = numer/denom return 1./kappa
def get_normal(r): ''' Solve for normal unit vector of 3D curve, r=(x,y,z) ''' xp = grad(r[0]) yp = grad(r[1]) zp = grad(r[2]) v = (xp**2 + yp**2 + zp**2)**.5 tx = xp / v ty = yp / v tz = zp / v nx = grad(tx) ny = grad(ty) nz = grad(tz) norm = (nx**2 + ny**2 + nz**2)**.5 N = array([nx, ny, nz]) / norm return N.T
def divergence(Bx, By, Bz, dx, dy, dz): dBx, dBy, dBz = grad(Bx), grad(By), grad(Bz) ret = dBx[0] / dx + dBy[1] / dy + dBz[2] / dz return ret
def parz(f,dR,dZ): return grad(f,dR,dZ,edge_order = 2)[0]
def parr(f,dR,dZ): return grad(f,dR,dZ,edge_order = 2)[1]
def model_sde_5mut(z, t, R, R_div, c, c_0, c_1, delta, I, k_x, k_s, N, H, f, mu): ##wt, mutant populations, and substrate given as one length 4*R array due to odeint constraints ind = R * R_div b = z[0:ind] bm = z[ind:2 * ind] bm2 = z[2 * ind:3 * ind] bm3 = z[3 * ind:4 * ind] bm4 = z[5 * ind:6 * ind] bm5 = z[6 * ind:7 * ind] s = z[7 * ind:] ##compact support heaviside function height CC = (3.5 * 10**8) dbdt = M_A(c, c_0, c_1, R_div) * grad(grad(b)) - delta * X_A( c, c_0, c_1, I) * grad(b * (k_x / (s + k_x)**2) * grad(s)) + cell_growth( b, rw * (s / (k_s + s)), rw * (b + bm + bm2 + bm3 + bm4 + bm5), CC) - cell_mut(b, mu, CC) dbmdt = M_A(c, c_0, c_1, R_div) * grad(grad(bm)) - delta * X_A( c, c_0, c_1, I) * grad(bm * (k_x / (s + k_x)**2) * grad(s)) + cell_growth( bm, rw * a * (s / (k_s + s)), rw * a * (b + bm + bm2 + bm3 + bm4 + bm5), CC) + cell_mut(b, mu, CC) - cell_mut( bm, mu, CC) dbm2dt = M_A(c, c_0, c_1, R_div) * grad(grad(bm2)) - delta * X_A( c, c_0, c_1, I) * grad( bm2 * (k_x / (s + k_x)**2) * grad(s)) + cell_growth( bm2, rw * a * a * (s / (k_s + s)), rw * a * a * (b + bm + bm2 + bm3 + bm4 + bm5), CC) + cell_mut(bm, mu, CC) - cell_mut(bm2, mu, CC) dbm3dt = M_A(c, c_0, c_1, R_div) * grad(grad(bm3)) - delta * X_A( c, c_0, c_1, I) * grad(bm3 * (k_x / (s + k_x)**2) * grad(s)) + cell_growth( bm3, rw * a * a * a * (s / (k_s + s)), rw * a * a * a * (b + bm + bm2 + bm3 + bm4 + bm5), CC) + cell_mut(bm2, mu, CC) - cell_mut(bm3, mu, CC) dbm4dt = M_A(c, c_0, c_1, R_div) * grad(grad(bm4)) - delta * X_A( c, c_0, c_1, I) * grad(bm4 * (k_x / (s + k_x)**2) * grad(s)) + cell_growth( bm4, rw * a * a * a * a * (s / (k_s + s)), (b + bm + bm2 + bm3 + bm4 + bm5) * a * a * a * a * rw, CC) + cell_mut( bm3, mu, CC) - cell_mut(bm4, mu, CC) dbm5dt = M_A(c, c_0, c_1, R_div) * grad(grad(bm5)) - delta * X_A( c, c_0, c_1, I) * grad(bm5 * (k_x / (s + k_x)**2) * grad(s)) + cell_growth( bm5, rw * a * a * a * a * a * (s / (k_s + s)), (b + bm + bm2 + bm3 + bm4 + bm5) * rw * a * a * a * a * a, CC) + cell_mut( bm4, mu, CC) - cell_mut(bm5, mu, CC) dsdt = N * grad(grad(s)) - H * (s / (s + k_s)) * ( rw * b + rw * a * bm + rw * a * a * bm2 ) + rw * a * a * a * bm3 + rw * a * a * a * a * f * bm4 + rw * a * a * a * a * a * bm5 dzdt = [dbdt, dbmdt, dbm2dt, dbm3dt, dbm4dt, dbm5dt, dsdt] return np.concatenate(dzdt)
def simple_fisher(u, t, D, r, dt): ##classic 1D fisher equation with diffusion constant D, growth rate r, population density u ### population density u is scaled by carrying capacity dudt = D * grad(grad(u, dt), dt) + r * u * (1 - u) return dudt