change scaling for the schrodinger equation - python
I need to change the scaling for my plot on the Schrodinger equation, y axis to show a difference between the theoretical calculation and ours which is about a 0.01 percent difference. so on the plot I am getting the scale is not small enough to show a difference. Here is the code from my project.
# -*- coding: utf-8 -*-
"""
Created on Sat Nov 05 12:25:14 2016
#author: produce
"""
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
#
c = .5 / 500 # c = delta x
x = np.arange(0, .5, c) # creates array of argument values from 0 to 1/2 in increments
# of delta x = c
psi = np.zeros(len(x)) # creates array of zeros which will be replaced by y values
k = 20 # starting energy for calculator of E
ans = 0 # The value of k, when we have y as between 0.004 and 0
ansPsi = 0
diff = 0.001
increment = 0.0001
done = False
while 1:
# print k
psi[0] = 1
psi[1] = 1
for i in range(0, len(x) - 2):
psi[i + 2] = psi[i + 1] + (psi[i + 1] - psi[i]) - 2 * k * c * c * psi[i]
# plt.plot(x,psi)
# print(x,psi)
# print (psi[i+2]--->)
if (float(psi[i + 2]) < 0.004 and float(psi[i + 2]) > 0):
ans = k
ansPsi = psi[i + 2]
# print ("NOW ENTERING INNER LOOP")
while 1: # would be an infinite loop, but have a break statement
# k = k - 0.00001
k = k + increment
for i in range(0, len(x) - 2):
psi[i + 2] = psi[i + 1] + (psi[i + 1] - psi[i]) - 2 * k * c * c * psi[i]
plt.plot(x, psi, 'r') #red solid line
if (psi[i + 2] > ansPsi or psi[i + 2] < 0):
done = True
break
else:
ansPsi = psi[i + 2]
ans = k
# print (k, psi[i+2])
if done:
break
k = k - diff
print("Value of k:", ans, "Value of Y:", ansPsi) # prints our answer for energy and psi[1/2]
k1 = 10 # 1st Higher Energy Value
k2 = 7 # 2nd Higher Energy Value
k3 = 3 # 1st Lower Energy Value
k4 = 1 # 2nd Lower Energy Value
kt = np.pi * np.pi * .5 # theoretical value
psi1 = np.zeros(len(x))
psi1[0] = 1
psi1[1] = 1
for i in range(0, len(x) - 2):
psi1[i + 2] = psi1[i + 1] + (psi1[i + 1] - psi1[i]) - 2 * k1 * c * c * psi1[i]
# psi2 = np.zeros(len(x))
# psi2[0] = 1
# psi2[1] = 1
# for i in range (0,len(x)-2):
# psi2[i+2] = psi2[i+1] + (psi2[i+1] - psi2[i]) - 2*k2*c*c*psi2[i]
# plt.plot(x,psi2,'k')
# psi3 = np.zeros(len(x))
# psi3[0] = 1
# psi3[1] = 1
# for i in range (0,len(x)-2):
# psi3[i+2] = psi3[i+1] + (psi3[i+1] - psi3[i]) - 2*k3*c*c*psi3[i]
# plt.plot(x,psi3,'p')
psi4 = np.zeros(len(x))
psi4[0] = 1
psi4[1] = 1
for i in range(0, len(x) - 2):
psi4[i + 2] = psi4[i + 1] + (psi4[i + 1] - psi4[i]) - 2 * k4 * c * c * psi4[i]
plt.plot(x, psi, 'r-', label='Corrected Energy')
psiT = np.zeros(len(x))
psiT[0] = 1
psiT[1] = 1
for i in range(0, len(x) - 2):
psiT[i + 2] = psiT[i + 1] + (psiT[i + 1] - psiT[i]) - 2 * kt * c * c * psiT[i]
plt.plot(x, psiT, 'b-', label='Theoretical Energy')
plt.ylabel("Value of Psi")
plt.xlabel("X value from 0 to 0.5")
plt.title("Schrodingers equation for varying inital energy")
plt.legend(loc=3)
plt.yscale()
plt.show()
The code you shared fails since plt.yscale() needs an argument. I simply commented that line out.
Because your theoretical energy curve and your corrected energy curve differ by so little, it is not possible to scale the y-axis and still see both curves over the full range of x (ie - from 0 to 0.5). Instead, maybe you should plot the difference of the two curves?
plt.plot(x, psiT-psi)
plt.title("Size of Correction for Varying Initial Energy")
plt.ylabel(r"$\Delta$E")
plt.xlabel("X value from 0 to 0.5")
plt.show()
Also, it might be nice to tack some units on the x and y labels. :)
Related
Compute Fourier Series for a discrete set of points
I'm trying to compute the continuous function hidden behind the points, but it shows a graph that looks like it actually coutns the points in-between as zeros. Here's the plot that shows up (100 vectors, red dots - data set, blue plot - my Fourier series): Here's the python code: import matplotlib.pyplot as plt import numpy as np import math step = (np.pi * 2) / 5 start = -np.pi xDiscrete = [start, start + step, start + 2 * step, start + 3 * step, start + 4 * step, np.pi] yDiscrete = [2.88, 2.98, 3.24, 3.42, 3.57, 3.79] ak = [] bk = [] a0 = 0 precisionSize = 0.001 n = 100 avgError = 0 def getAN(k): sum = 0 for ind in range(1, len(yDiscrete)): sum += yDiscrete[ind] * math.cos(k * xDiscrete[ind]) an = (2.0 / n) * sum print('a' + str(k) + ' = ' + str(an)) return an def getBN(k): sum = 0 for ind in range(1, len(yDiscrete)): sum += yDiscrete[ind] * math.sin(k * xDiscrete[ind]) bn = (2.0 / n) * sum print('b' + str(k) + ' = ' + str(bn)) return bn def getA0(): sum = 0 for ind in range(1, len(yDiscrete)): sum += yDiscrete[ind] a0 = (2.0 / n) * sum print('a0 = ' + str(a0)) return a0 def getFourierOneSum(x, i): return ak[i - 1] * math.cos(i * x) + bk[i - 1] * math.sin(i * x) def getFourierAtPoint(x): sum = a0 / 2 for i in range(1, n + 1): sum += getFourierOneSum(x, i) return sum for i in range(1, n + 1): ak.append(getAN(i)) bk.append(getBN(i)) a0 = getA0() x2 = np.arange(-np.pi, np.pi, precisionSize) y2 = [] for coor in x2: y2.append(getFourierAtPoint(coor)) plt.plot(xDiscrete, yDiscrete, 'ro', alpha=0.6) plt.plot(x2, y2) plt.grid() plt.title('Approximation') plt.show() I've checked where is the problem, and I'm pretty sure it's with the coefficients (functions getAN, getBN, getA0), but I'm not sure how to fix it.
How to increase FPS in ursina python
I want to create survival games with infinite block terrain(like Minecraft). So i using ursina python game engine, you can see it here So i using perlin noise to create the terrain with build-in ursina block model. I test for first 25 block and it work pretty good with above 100 FPS, so i start increase to 250 block and more because I want a infinite terrain. But i ran to some problem, when i increase to 100 block or more, my FPS start to decrease below 30 FPS (With i create just one layer). Here is my code: #-------------------------------Noise.py(I got on the github)------------------------- # Copyright (c) 2008, Casey Duncan (casey dot duncan at gmail dot com) # see LICENSE.txt for details """Perlin noise -- pure python implementation""" __version__ = '$Id: perlin.py 521 2008-12-15 03:03:52Z casey.duncan $' from math import floor, fmod, sqrt from random import randint # 3D Gradient vectors _GRAD3 = ((1,1,0),(-1,1,0),(1,-1,0),(-1,-1,0), (1,0,1),(-1,0,1),(1,0,-1),(-1,0,-1), (0,1,1),(0,-1,1),(0,1,-1),(0,-1,-1), (1,1,0),(0,-1,1),(-1,1,0),(0,-1,-1), ) # 4D Gradient vectors _GRAD4 = ((0,1,1,1), (0,1,1,-1), (0,1,-1,1), (0,1,-1,-1), (0,-1,1,1), (0,-1,1,-1), (0,-1,-1,1), (0,-1,-1,-1), (1,0,1,1), (1,0,1,-1), (1,0,-1,1), (1,0,-1,-1), (-1,0,1,1), (-1,0,1,-1), (-1,0,-1,1), (-1,0,-1,-1), (1,1,0,1), (1,1,0,-1), (1,-1,0,1), (1,-1,0,-1), (-1,1,0,1), (-1,1,0,-1), (-1,-1,0,1), (-1,-1,0,-1), (1,1,1,0), (1,1,-1,0), (1,-1,1,0), (1,-1,-1,0), (-1,1,1,0), (-1,1,-1,0), (-1,-1,1,0), (-1,-1,-1,0)) # A lookup table to traverse the simplex around a given point in 4D. # Details can be found where this table is used, in the 4D noise method. _SIMPLEX = ( (0,1,2,3),(0,1,3,2),(0,0,0,0),(0,2,3,1),(0,0,0,0),(0,0,0,0),(0,0,0,0),(1,2,3,0), (0,2,1,3),(0,0,0,0),(0,3,1,2),(0,3,2,1),(0,0,0,0),(0,0,0,0),(0,0,0,0),(1,3,2,0), (0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0), (1,2,0,3),(0,0,0,0),(1,3,0,2),(0,0,0,0),(0,0,0,0),(0,0,0,0),(2,3,0,1),(2,3,1,0), (1,0,2,3),(1,0,3,2),(0,0,0,0),(0,0,0,0),(0,0,0,0),(2,0,3,1),(0,0,0,0),(2,1,3,0), (0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0), (2,0,1,3),(0,0,0,0),(0,0,0,0),(0,0,0,0),(3,0,1,2),(3,0,2,1),(0,0,0,0),(3,1,2,0), (2,1,0,3),(0,0,0,0),(0,0,0,0),(0,0,0,0),(3,1,0,2),(0,0,0,0),(3,2,0,1),(3,2,1,0)) # Simplex skew constants _F2 = 0.5 * (sqrt(3.0) - 1.0) _G2 = (3.0 - sqrt(3.0)) / 6.0 _F3 = 1.0 / 3.0 _G3 = 1.0 / 6.0 class BaseNoise: """Noise abstract base class""" permutation = (151,160,137,91,90,15, 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, 190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, 88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166, 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, 102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,169,200,196, 135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123, 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, 223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,167,43,172,9, 129,22,39,253,9,98,108,110,79,113,224,232,178,185,112,104,218,246,97,228, 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, 49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254, 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180) period = len(permutation) # Double permutation array so we don't need to wrap permutation = permutation * 2 randint_function = randint def __init__(self, period=None, permutation_table=None, randint_function=None): """Initialize the noise generator. With no arguments, the default period and permutation table are used (256). The default permutation table generates the exact same noise pattern each time. An integer period can be specified, to generate a random permutation table with period elements. The period determines the (integer) interval that the noise repeats, which is useful for creating tiled textures. period should be a power-of-two, though this is not enforced. Note that the speed of the noise algorithm is indpendent of the period size, though larger periods mean a larger table, which consume more memory. A permutation table consisting of an iterable sequence of whole numbers can be specified directly. This should have a power-of-two length. Typical permutation tables are a sequnce of unique integers in the range [0,period) in random order, though other arrangements could prove useful, they will not be "pure" simplex noise. The largest element in the sequence must be no larger than period-1. period and permutation_table may not be specified together. A substitute for the method random.randint(a, b) can be chosen. The method must take two integer parameters a and b and return an integer N such that a <= N <= b. """ if randint_function is not None: # do this before calling randomize() if not hasattr(randint_function, '__call__'): raise TypeError( 'randint_function has to be a function') self.randint_function = randint_function if period is None: period = self.period # enforce actually calling randomize() if period is not None and permutation_table is not None: raise ValueError( 'Can specify either period or permutation_table, not both') if period is not None: self.randomize(period) elif permutation_table is not None: self.permutation = tuple(permutation_table) * 2 self.period = len(permutation_table) def randomize(self, period=None): """Randomize the permutation table used by the noise functions. This makes them generate a different noise pattern for the same inputs. """ if period is not None: self.period = period perm = list(range(self.period)) perm_right = self.period - 1 for i in list(perm): j = self.randint_function(0, perm_right) perm[i], perm[j] = perm[j], perm[i] self.permutation = tuple(perm) * 2 class SimplexNoise(BaseNoise): """Perlin simplex noise generator Adapted from Stefan Gustavson's Java implementation described here: http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf To summarize: "In 2001, Ken Perlin presented 'simplex noise', a replacement for his classic noise algorithm. Classic 'Perlin noise' won him an academy award and has become an ubiquitous procedural primitive for computer graphics over the years, but in hindsight it has quite a few limitations. Ken Perlin himself designed simplex noise specifically to overcome those limitations, and he spent a lot of good thinking on it. Therefore, it is a better idea than his original algorithm. A few of the more prominent advantages are: * Simplex noise has a lower computational complexity and requires fewer multiplications. * Simplex noise scales to higher dimensions (4D, 5D and up) with much less computational cost, the complexity is O(N) for N dimensions instead of the O(2^N) of classic Noise. * Simplex noise has no noticeable directional artifacts. Simplex noise has a well-defined and continuous gradient everywhere that can be computed quite cheaply. * Simplex noise is easy to implement in hardware." """ def noise2(self, x, y): """2D Perlin simplex noise. Return a floating point value from -1 to 1 for the given x, y coordinate. The same value is always returned for a given x, y pair unless the permutation table changes (see randomize above). """ # Skew input space to determine which simplex (triangle) we are in s = (x + y) * _F2 i = floor(x + s) j = floor(y + s) t = (i + j) * _G2 x0 = x - (i - t) # "Unskewed" distances from cell origin y0 = y - (j - t) if x0 > y0: i1 = 1; j1 = 0 # Lower triangle, XY order: (0,0)->(1,0)->(1,1) else: i1 = 0; j1 = 1 # Upper triangle, YX order: (0,0)->(0,1)->(1,1) x1 = x0 - i1 + _G2 # Offsets for middle corner in (x,y) unskewed coords y1 = y0 - j1 + _G2 x2 = x0 + _G2 * 2.0 - 1.0 # Offsets for last corner in (x,y) unskewed coords y2 = y0 + _G2 * 2.0 - 1.0 # Determine hashed gradient indices of the three simplex corners perm = self.permutation ii = int(i) % self.period jj = int(j) % self.period gi0 = perm[ii + perm[jj]] % 12 gi1 = perm[ii + i1 + perm[jj + j1]] % 12 gi2 = perm[ii + 1 + perm[jj + 1]] % 12 # Calculate the contribution from the three corners tt = 0.5 - x0**2 - y0**2 if tt > 0: g = _GRAD3[gi0] noise = tt**4 * (g[0] * x0 + g[1] * y0) else: noise = 0.0 tt = 0.5 - x1**2 - y1**2 if tt > 0: g = _GRAD3[gi1] noise += tt**4 * (g[0] * x1 + g[1] * y1) tt = 0.5 - x2**2 - y2**2 if tt > 0: g = _GRAD3[gi2] noise += tt**4 * (g[0] * x2 + g[1] * y2) return noise * 70.0 # scale noise to [-1, 1] def noise3(self, x, y, z): """3D Perlin simplex noise. Return a floating point value from -1 to 1 for the given x, y, z coordinate. The same value is always returned for a given x, y, z pair unless the permutation table changes (see randomize above). """ # Skew the input space to determine which simplex cell we're in s = (x + y + z) * _F3 i = floor(x + s) j = floor(y + s) k = floor(z + s) t = (i + j + k) * _G3 x0 = x - (i - t) # "Unskewed" distances from cell origin y0 = y - (j - t) z0 = z - (k - t) # For the 3D case, the simplex shape is a slightly irregular tetrahedron. # Determine which simplex we are in. if x0 >= y0: if y0 >= z0: i1 = 1; j1 = 0; k1 = 0 i2 = 1; j2 = 1; k2 = 0 elif x0 >= z0: i1 = 1; j1 = 0; k1 = 0 i2 = 1; j2 = 0; k2 = 1 else: i1 = 0; j1 = 0; k1 = 1 i2 = 1; j2 = 0; k2 = 1 else: # x0 < y0 if y0 < z0: i1 = 0; j1 = 0; k1 = 1 i2 = 0; j2 = 1; k2 = 1 elif x0 < z0: i1 = 0; j1 = 1; k1 = 0 i2 = 0; j2 = 1; k2 = 1 else: i1 = 0; j1 = 1; k1 = 0 i2 = 1; j2 = 1; k2 = 0 # Offsets for remaining corners x1 = x0 - i1 + _G3 y1 = y0 - j1 + _G3 z1 = z0 - k1 + _G3 x2 = x0 - i2 + 2.0 * _G3 y2 = y0 - j2 + 2.0 * _G3 z2 = z0 - k2 + 2.0 * _G3 x3 = x0 - 1.0 + 3.0 * _G3 y3 = y0 - 1.0 + 3.0 * _G3 z3 = z0 - 1.0 + 3.0 * _G3 # Calculate the hashed gradient indices of the four simplex corners perm = self.permutation ii = int(i) % self.period jj = int(j) % self.period kk = int(k) % self.period gi0 = perm[ii + perm[jj + perm[kk]]] % 12 gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]] % 12 gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]] % 12 gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] % 12 # Calculate the contribution from the four corners noise = 0.0 tt = 0.6 - x0**2 - y0**2 - z0**2 if tt > 0: g = _GRAD3[gi0] noise = tt**4 * (g[0] * x0 + g[1] * y0 + g[2] * z0) else: noise = 0.0 tt = 0.6 - x1**2 - y1**2 - z1**2 if tt > 0: g = _GRAD3[gi1] noise += tt**4 * (g[0] * x1 + g[1] * y1 + g[2] * z1) tt = 0.6 - x2**2 - y2**2 - z2**2 if tt > 0: g = _GRAD3[gi2] noise += tt**4 * (g[0] * x2 + g[1] * y2 + g[2] * z2) tt = 0.6 - x3**2 - y3**2 - z3**2 if tt > 0: g = _GRAD3[gi3] noise += tt**4 * (g[0] * x3 + g[1] * y3 + g[2] * z3) return noise * 32.0 def lerp(t, a, b): return a + t * (b - a) def grad3(hash, x, y, z): g = _GRAD3[hash % 16] return x*g[0] + y*g[1] + z*g[2] class TileableNoise(BaseNoise): """Tileable implemention of Perlin "improved" noise. This is based on the reference implementation published here: http://mrl.nyu.edu/~perlin/noise/ """ def noise3(self, x, y, z, repeat, base=0.0): """Tileable 3D noise. repeat specifies the integer interval in each dimension when the noise pattern repeats. base allows a different texture to be generated for the same repeat interval. """ i = int(fmod(floor(x), repeat)) j = int(fmod(floor(y), repeat)) k = int(fmod(floor(z), repeat)) ii = (i + 1) % repeat jj = (j + 1) % repeat kk = (k + 1) % repeat if base: i += base; j += base; k += base ii += base; jj += base; kk += base x -= floor(x); y -= floor(y); z -= floor(z) fx = x**3 * (x * (x * 6 - 15) + 10) fy = y**3 * (y * (y * 6 - 15) + 10) fz = z**3 * (z * (z * 6 - 15) + 10) perm = self.permutation A = perm[i] AA = perm[A + j] AB = perm[A + jj] B = perm[ii] BA = perm[B + j] BB = perm[B + jj] return lerp(fz, lerp(fy, lerp(fx, grad3(perm[AA + k], x, y, z), grad3(perm[BA + k], x - 1, y, z)), lerp(fx, grad3(perm[AB + k], x, y - 1, z), grad3(perm[BB + k], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3(perm[AA + kk], x, y, z - 1), grad3(perm[BA + kk], x - 1, y, z - 1)), lerp(fx, grad3(perm[AB + kk], x, y - 1, z - 1), grad3(perm[BB + kk], x - 1, y - 1, z - 1)))) #--------------------------Math.py(For InverseLefp)-------------------------------- def Clamp(t: float, minimum: float, maximum: float): """Float result between a min and max values.""" value = t if t < minimum: value = minimum elif t > maximum: value = maximum return value def InverseLefp(a: float, b: float, value: float): if a != b: return Clamp((value - a) / (b - a), 0, 1) return 0 #-----------------------------Game.py(Main code)---------------------- from ursina import * from ursina.prefabs import * from ursina.prefabs.first_person_controller import * from Math import InverseLefp import Noise app = Ursina() #The maximum height of the terrain maxHeight = 10 #Control the width and height of the map mapWidth = 10 mapHeight = 10 #A class that create a block class Voxel(Button): def __init__(self, position=(0,0,0)): super().__init__( parent = scene, position = position, model = 'cube', origin_y = .5, texture = 'white_cube', color = color.color(0, 0, random.uniform(.9, 1.0)), highlight_color = color.lime, ) #Detect user key input def input(self, key): if self.hovered: if key == 'right mouse down': #Place block if user right click voxel = Voxel(position=self.position + mouse.normal) if key == 'left mouse down': #Break block if user left click destroy(self) if key == 'escape': #Exit the game if user press the esc key app.userExit() #Return perlin noise value between 0 and 1 with x, y position with scale = noiseScale def GeneratedNoiseMap(y: int, x: int, noiseScale: float): #Check if the noise scale was invalid or not if noiseScale <= 0: noiseScale = 0.001 sampleX = x / noiseScale sampleY = y / noiseScale #The Noise.SimplexNoise().noise2 will return the value between -1 and 1 perlinValue = Noise.SimplexNoise().noise2(sampleX, sampleY) #The InverseLefp will make the value scale to between 0 and 1 perlinValue = InverseLefp(-1, 1, perlinValue) return perlinValue for z in range(mapHeight): for x in range(mapWidth): #Calculating the height of the block and round it to integer height = round(GeneratedNoiseMap(z, x, 20) * maxHeight) #Place the block and make it always below the player block = Voxel(position=(x, height - maxHeight - 1, z)) #Set the collider of the block block.collider = 'mesh' #Character movement player = FirstPersonController() #Run the game app.run() All file in same folder. It was working fine but the FPS is very low, so can anyone help?
I'm not able to test this code at the moment but this should serve as a starting point: level_parent = Entity(model=Mesh(vertices=[], uvs=[])) for z in range(mapHeight): for x in range(mapWidth): height = round(GeneratedNoiseMap(z, x, 20) * maxHeight) block = Voxel(position=(x, height - maxHeight - 1, z)) level_parent.model.vertices.extend(block.model.vertices) level_parent.collider = 'mesh' # call this only once after all vertices are set up For texturing, you might have to add the block.uvs from each block to level_parent.model.uvs as well. Alternatively, call level_parent.model.project_uvs() after setting up the vertices.
On my version of ursina engine (5.0.0) only this code: ` level_parent = Entity(model=Mesh(vertices=[], uvs=[])) for z in range(mapHeight): for x in range(mapWidth): height = round(GeneratedNoiseMap(z, x, 20) * maxHeight) block = Voxel(position=(x, height - maxHeight - 1, z)) #level_parent.model.vertices.extend(block.model.vertices) level_parent.combine().vertices.extend(block.combine().vertices) level_parent.collider = 'mesh' ` is working.
Value Error, Shapes do Not Align Python
Yeah, so this is my code in multiclass logistic regression, but when I run it it gives the error of Value Error, Shapes not aligned or whatever. import numpy import matplotlib.pyplot as plt import math as mt #normalized and feature scaled Just loading the data set def load(): data = numpy.loadtxt(open("housing.data.txt", "rb"), dtype="float") m, n = data.shape first_col = numpy.ones((m, 1)) #create new array using new parameters data = numpy.hstack((first_col, data)) #divide each X with the max in the column #subtract the mean of X to each element for l in range(1, n): max = 0.0 sum = 0.0 for j in range(0, m): if max < data[j, l]: max = data[j, l] sum += data[j, l] avg = sum / m for j in range(0, m): data[j, l] -= avg data[j, l] /= max return data def logistic(z): z = z[0,0] z = z * -1 return (1.0 / (1.0 + mt.exp(z))) def hyp(theta, x): x = numpy.mat(x) theta = numpy.mat(theta) return logistic(theta * x.T) #cost and derivative functions: TO REWRITE #regularize using "-1000/m (hyp(theta, data[x, :-1]))" def derv(theta, data, j): sum = 0.0 last = data.shape[1] - 1 m = data.shape[0] for x in range(0, m): sum += (hyp(theta, data[x, :-1]) - numpy.mat(data[x, last])) + numpy.mat(data[x, j]) return (sum[0,0] / m) #regularize using " + 1000/2m(hyp(theta, data[x, :-1]))" def cost(theta, data): sum = 0.0 last = data.shape[1] - 1 m = data.shape[0] for x in range(0, m): y = data[x, last] sum += y * mt.log(hyp(theta, data[x, :-1])) + (1 - y) * mt.log(1 - hyp(theta, data[x, :-1])) return -1 * (sum / m) data = load() data1 = data[:, [10]] data2 = data[:, [13]] d12 = numpy.hstack((data1, data2)) data3 = data[:, [14]] pdata = numpy.hstack((d12, data3)) print(pdata) alpha = 0.01 theta = [10,10,10,10] ntheta = [0,0,0,0] delta = 50 x = 0 for l in range(0, 1000): old_cost = cost(theta, pdata) for y in range(0, data.shape[1] - 1): ntheta[y] = theta[y] - alpha * derv(theta, data1, y) for k in range(0, data.shape[1] - 1): theta[k] = ntheta[k] new_cost = cost(theta, data1) delta = new_cost - old_cost print("Cost: " + str(new_cost)) print("Delta: " + str(delta)) for r in range(0, data.shape[1]): if hyp(theta, data1[r, :-1]) >= 0.5: print("Predicted: 1 Actual: " + str(data1[r, data1.shape[1] - 1])) else: print("Predicted: 0 Actual: " + str(data1[r, data1.shape[1] - 1])) plt.scatter(data1[:, 1], data1[:, 2]) x1 = (-1 * theta[0]) / theta[1] x2 = (-1 * theta[0]) / theta[1] x = range(-2, 2) y = [((-1 * theta[0]) - (theta[1] * z) ) for z in x] plt.plot(x, y) plt.show() I'm guessing it cant be plotted like this or idk
Replacing multiprocessing pool.map with mpi4py
I'm a beginner in using MPI, and I'm still going through the documentation. However, there's very little to work on when it comes to mpi4py. I have written a code that currently uses the multiprocessing module to run on many cores, but I need replace this with mpi4py so that I can use more than one node to run my code. My code is below, when using the multiprocessing module, and also without. With multiprocessing, import numpy as np import multiprocessing start_time = time.time() E = 0.1 M = 5 n = 1000 G = 1 c = 1 stretch = [10, 1] #Point-Distribution Generator Function def CDF_inv(x, e, m): A = 1/(1 + np.log(m/e)) if x == 1: return m elif 0 <= x <= A: return e * x / A elif A < x < 1: return e * np.exp((x / A) - 1) #Elliptical point distribution Generator Function def get_coor_ellip(dist=CDF_inv, params=[E, M], stretch=stretch): R = dist(random.random(), *params) theta = random.random() * 2 * np.pi return (R * np.cos(theta) * stretch[0], R * np.sin(theta) * stretch[1]) def get_dist_sq(x_array, y_array): return x_array**2 + y_array**2 #Function to obtain alpha def get_alpha(args): zeta_list_part, M_list_part, X, Y = args alpha_x = 0 alpha_y = 0 for key in range(len(M_list_part)): z_m_z_x = X - zeta_list_part[key][0] z_m_z_y = Y - zeta_list_part[key][1] dist_z_m_z = get_dist_sq(z_m_z_x, z_m_z_y) alpha_x += M_list_part[key] * z_m_z_x / dist_z_m_z alpha_y += M_list_part[key] * z_m_z_y / dist_z_m_z return (alpha_x, alpha_y) #The part of the process containing the loop that needs to be parallelised, where I use pool.map() if __name__ == '__main__': # n processes, scale accordingly num_processes = 10 pool = multiprocessing.Pool(processes=num_processes) random_sample = [CDF_inv(x, E, M) for x in [random.random() for e in range(n)]] zeta_list = [get_coor_ellip() for e in range(n)] x1, y1 = zip(*zeta_list) zeta_list = np.column_stack((np.array(x1), np.array(y1))) x = np.linspace(-3, 3, 100) y = np.linspace(-3, 3, 100) X, Y = np.meshgrid(x, y) print len(x)*len(y)*n,'calculations to be carried out.' M_list = np.array([.001 for i in range(n)]) # split zeta_list, M_list, X, and Y zeta_list_split = np.array_split(zeta_list, num_processes, axis=0) M_list_split = np.array_split(M_list, num_processes) X_list = [X for e in range(num_processes)] Y_list = [Y for e in range(num_processes)] alpha_list = pool.map( get_alpha, zip(zeta_list_split, M_list_split, X_list, Y_list)) alpha_x = 0 alpha_y = 0 for e in alpha_list: alpha_x += e[0] * 4 * G / (c**2) alpha_y += e[1] * 4 * G / (c**2) print("%f seconds" % (time.time() - start_time)) Without multiprocessing, import numpy as np E = 0.1 M = 5 G = 1 c = 1 M_list = [.1 for i in range(n)] #Point-Distribution Generator Function def CDF_inv(x, e, m): A = 1/(1 + np.log(m/e)) if x == 1: return m elif 0 <= x <= A: return e * x / A elif A < x < 1: return e * np.exp((x / A) - 1) n = 1000 random_sample = [CDF_inv(x, E, M) for x in [random.random() for e in range(n)]] stretch = [5, 2] #Elliptical point distribution Generator Function def get_coor_ellip(dist=CDF_inv, params=[E, M], stretch=stretch): R = dist(random.random(), *params) theta = random.random() * 2 * np.pi return (R * np.cos(theta) * stretch[0], R * np.sin(theta) * stretch[1]) #zeta_list is the list of coordinates of a distribution of points zeta_list = [get_coor_ellip() for e in range(n)] x1, y1 = zip(*zeta_list) zeta_list = np.column_stack((np.array(x1), np.array(y1))) #Creation of a X-Y Grid x = np.linspace(-3, 3, 100) y = np.linspace(-3, 3, 100) X, Y = np.meshgrid(x, y) def get_dist_sq(x_array, y_array): return x_array**2 + y_array**2 #Calculation of alpha, containing the loop that needs to be parallelised. alpha_x = 0 alpha_y = 0 for key in range(len(M_list)): z_m_z_x = X - zeta_list[key][0] z_m_z_y = Y - zeta_list[key][1] dist_z_m_z = get_dist_sq(z_m_z_x, z_m_z_y) alpha_x += M_list[key] * z_m_z_x / dist_z_m_z alpha_y += M_list[key] * z_m_z_y / dist_z_m_z alpha_x *= 4 * G / (c**2) alpha_y *= 4 * G / (c**2) Basically what my code does is, it first generates a list of points that follow a certain distribution. Then I apply an equation to obtain the quantity 'alpha' using different relations between the distances of the points. The part that requires parallelisation is the single for loop involved in the calculation of alpha. What I want to do is to use mpi4py instead of multiprocessing to do this, and I am not sure how to get this going.
Transforming the multiprocessing.map version to MPI can be done using scatter / gather. In your case it is useful, that you already prepare the input list into one chunk for each rank. The main difference is, that all code gets executed by all ranks in the first place, so you must make everything that should be done only by the maste rank 0 conidtional. if __name__ == '__main__': comm = MPI.COMM_WORLD if comm.rank == 0: random_sample = [CDF_inv(x, E, M) for x in [random.random() for e in range(n)]] zeta_list = [get_coor_ellip() for e in range(n)] x1, y1 = zip(*zeta_list) zeta_list = np.column_stack((np.array(x1), np.array(y1))) x = np.linspace(-3, 3, 100) y = np.linspace(-3, 3, 100) X, Y = np.meshgrid(x, y) print len(x)*len(y)*n,'calculations to be carried out.' M_list = np.array([.001 for i in range(n)]) # split zeta_list, M_list, X, and Y zeta_list_split = np.array_split(zeta_list, comm.size, axis=0) M_list_split = np.array_split(M_list, comm.size) X_list = [X for e in range(comm.size)] Y_list = [Y for e in range(comm.size)] work_list = list(zip(zeta_list_split, M_list_split, X_list, Y_list)) else: work_list = None my_work = comm.scatter(work_list) my_alpha = get_alpha(my_work) alpha_list = comm.gather(my_alpha) if comm.rank == 0: alpha_x = 0 alpha_y = 0 for e in alpha_list: alpha_x += e[0] * 4 * G / (c**2) alpha_y += e[1] * 4 * G / (c**2) This works fine as long as each processor gets a similar amount of work. If communication becomes an issue, you might want to split up the data generation among processors instead of doing it all on the master rank 0. Note: Some things about the code are bogus, e.g. alpha_[xy] ends up as np.ndarray. The serial version runs into an error.
For people who are still interested in similar subjects, I highly recommend having a look at the MPIPoolExecutor() class here and the documentation is here.
Generalized Distance Transform in Python
I'm currently trying to implement the GDT described by Felzenszwalb and Huttenlocher (http://www.cs.cornell.edu/~dph/papers/dt.pdf) inside of Python for an image processing algorithm. However I used the algorithm described in the paper they published a few years back but got faulty results. I found a C# implementation here: https://dsp.stackexchange.com/questions/227/fastest-available-algorithm-for-distance-transform/29727?noredirect=1#comment55866_29727 And converted it to Python (which is pretty much the same I had before). This is my code: def of_column(dataInput): output = zeros(dataInput.shape) n = len(dataInput) k = 0 v = zeros((n,)) z = zeros((n + 1,)) v[0] = 0 z[0] = -inf z[1] = +inf s = 0 for q in range(1, n): while True: s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k])) if s <= z[k]: k -= 1 else: break k += 1 v[k] = q z[k] = s z[k + 1] = +inf k = 0 for q in range(n): while z[k + 1] < q: k += 1 output[q] = ((q - v[k]) * (q - v[k]) + dataInput[v[k]]) return output I still can't find my error. When giving the algorithm a binary (boolean) numpy array it just returns the array itself not the Distance Transform. Why is this not working in Python?
I got it working after hours and hours. The answer given in the link above implementing the code in C# suggests putting up the "white" areas to a very large number. My dataInput array was a boolean array (0, 1). I replaced all 1s with 2^32 and it works just fine. The higher the number the more blurry it gets. The lower the more similar to the source it gets.
I would like to add the function for 2D that works with the 1D function described previously: ############################################################################### # distance transform of 1d function using squared distance ############################################################################### def dt_1d(dataInput, n): output = np.zeros(dataInput.shape) k = 0 v = np.zeros((n,)) z = np.zeros((n + 1,)) v[0] = 0 z[0] = -np.inf z[1] = +np.inf for q in range(1, n): s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k])) while s <= z[k]: k -= 1 s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k])) k += 1 v[k] = q z[k] = s z[k + 1] = +np.inf k = 0 for q in range(n): while z[k + 1] < q: k += 1 value = ((q - v[k]) * (q - v[k]) + dataInput[v[k]]) if value > 255: value = 255 if value < 0: value = 0 output[q] = value print output return output ############################################################################### # distance transform of 2d function using squared distance ############################################################################### def dt_2d(dataInput): height, width = dataInput.shape f = np.zeros(max(height, width)) # transform along columns for x in range(width): f = dataInput[:,x] dataInput[:,x] = dt_1d(f, height) # transform along rows for y in range(height): f = dataInput[y,:] dataInput[y,:] = dt_1d(f, width) return dataInput I hope it helps.