Interpolation of two variables on a 3D grid - python-2.7

I need to interpolate two variables written in the 3D grid on another 3D grid. I tried the inverse distance method, but I get only two values that do not represent the distribution on the original grid, assigned to each point of the new grid. Here is an example of my code:
text=text[pstart:pend]
x=[]
y=[]
z=[]
for line in text:
coords=line.split()
x.append(float(coords[2])) #coordinates of the new grid
y.append(float(coords[1]))
z.append(float(coords[0]))
Xg=np.asarray([x,y,z])
# Gather mean flow data
xd=[]
yd=[]
zd=[]
cd=[]
rhod=[]
with open(meanflowdata,'rb') as csvfile:
spamreader=csv.reader(csvfile, delimiter=',')
for row in spamreader:
if len(row)>2:
xd.append(float(row[0])) #coordinates and values of the source file
yd.append(float(row[1]))
zd.append(float(row[2]))
cd.append(float(row[3]))
rhod.append(float(row[4]))
Xd=np.asarray([xd,yd,zd])
Zd=np.asarray([cd,rhod])
leafsize = 20
print "# setting up KDtree"
invdisttree = Invdisttree( Xd.T, Zd.T, leafsize=leafsize, stat=1 )
print "# Performing interpolation"
interpol = invdisttree( Xg.T )
c=interpol.T[0]
rho=interpol.T[1]
As far as I could check, the problem lies when I call the invdisttree function, which does not work properly. Does someone have an idea or an alternative method to suggest for the interpolation?

Where do interpol.T[0], interpol.T[1] come from,
where did your Invdisttree come from ?
This
on SO has
invdisttree = Invdisttree( X, z ) -- data points, values
interpol = invdisttree( q, nnear=3, eps=0, p=1, weights=None, stat=0 )
In your case X could be 100 x 3, z 100 x 2,
query points q 10 x 3 ⟶ interpol 10 x 2.
(invdisttree is a function, which you call to do the interpolation:
interpol = invdisttree( q ...) . Is that confusing ?)

Related

Using For loop on nested list

I'm using a nested list to hold data in a Cartesian coordinate type system.
The data is a list of categories which could be 0,1,2,3,4,5,255 (just 7 categories).
The data is held in a list formatted thus:
stack = [[0,1,0,0],
[2,1,0,0],
[1,1,1,3]]
Each list represents a row and each element of a row represents a data point.
I'm keen to hang on to this format because I am using it to generate images and thus far it has been extremely easy to use.
However, I have run into problems running the following code:
for j in range(len(stack)):
stack[j].append(255)
stack[j].insert(0, 255)
This is intended to iterate through each row adding a single element 255 to the start and end of each row. Unfortunately it adds 12 instances of 255 to both the start and end!
This makes no sense to me. Presumably I am missing something very trivial but I can't see what it might be. As far as I can tell it is related to the loop: if I write stack[0].append(255) outside of the loop it behaves normally.
The code is obviously part of a much larger script. The script runs multiple For loops, a couple of which are range(12) but which should have closed by the time this loop is called.
So - am I missing something trivial or is it more nefarious than that?
Edit: full code
step_size = 12, the code above is the part that inserts "right and left borders"
def classify(target_file, output_file):
import numpy
import cifar10_eval # want to hijack functions from the evaluation script
target_folder = "Binaries/" # finds target file in "Binaries"
destination_folder = "Binaries/Maps/" # destination for output file
# open the meta file to retrieve x,y dimensions
file = open(target_folder + target_file + "_meta" + ".txt", "r")
new_x = int(file.readline())
new_y = int(file.readline())
orig_x = int(file.readline())
orig_y = int(file.readline())
segment_dimension = int(file.readline())
step_size = int(file.readline())
file.close()
# run cifar10_eval and create predictions vector (formatted as a list)
predictions = cifar10_eval.map_interface(new_x * new_y)
del predictions[(new_x * new_y):] # get rid of excess predictions (that are an artefact of the fixed batch size)
print("# of predictions: " + str(len(predictions)))
# check that we are mapping the whole picture! (evaluation functions don't necessarily use the full data set)
if len(predictions) != new_x * new_y:
print("Error: number of predictions from cifar10_eval does not match metadata for this file")
return
# copy predictions to a nested list to make extraction of x/y data easy
# also eliminates need to keep metadata - x/y dimensions are stored via the shape of the output vector
stack = []
for j in range(new_y):
stack.append([])
for i in range(new_x):
stack[j].append(predictions[j*new_x + i])
predictions = None # clear the variable to free up memory
# iterate through map list and explode each category to cover more pixels
# assigns a step_size x step_size area to each classification input to achieve correspondance with original image
new_stack = []
for j in range(len(stack)):
row = stack[j]
new_row = []
for i in range(len(row)):
for a in range(step_size):
new_row.append(row[i])
for b in range(step_size):
new_stack.append(new_row)
stack = new_stack
new_stack = None
new_row = None # clear the variables to free up memory
# add a border to the image to indicate that some information has been lost
# border also ensures that map has 1-1 correspondance with original image which makes processing easier
# calculate border dimensions
top_and_left_thickness = int((segment_dimension - step_size) / 2)
right_thickness = int(top_and_left_thickness + (orig_x - (top_and_left_thickness * 2 + step_size * new_x)))
bottom_thickness = int(top_and_left_thickness + (orig_y - (top_and_left_thickness * 2 + step_size * new_y)))
print(top_and_left_thickness)
print(right_thickness)
print(bottom_thickness)
print(len(stack[0]))
# add the right then left borders
for j in range(len(stack)):
for b in range(right_thickness):
stack[j].append(255)
for b in range(top_and_left_thickness):
stack[j].insert(0, 255)
print(stack[0])
print(len(stack[0]))
# add the top and bottom borders
row = []
for i in range(len(stack[0])):
row.append(255) # create a blank row
for b in range(top_and_left_thickness):
stack.insert(0, row) # append the blank row to the top x many times
for b in range(bottom_thickness):
stack.append(row) # append the blank row to the bottom of the map
# we have our final output
# repackage this as a numpy array and save for later use
output = numpy.asarray(stack,numpy.uint8)
numpy.save(destination_folder + output_file + ".npy", output)
print("Category mapping complete, map saved as numpy pickle: " + output_file + ".npy")

Center point coordinates

I have a certain function which takes inputs as milling parameters and then generates a surface .
Within this function I have a for loop which stores the co-ordinates of the center point of my tool.
I wanted to know how can i store the X and Y coordinates of my center point CP
in an array so that i can use these values for further manipulations?
for further manipulation i need to access each value of X-Coordinate of my CP variable using a for loop , multiply the value of X coordinate with some factor and then make this as my new CP x-coordinates for the next iteration of loop.
How do i do this?
def Milling(xdim, ydim, resolution, feed, infeed, radius ):
"""
Die Funktion gibt eine Punktwolke zurück (x1 y1 z1)
xdim, ydim: gemessenes Feld [mm] \n
resolution: Messpunktauflösung [1/mm] \n
feed: Bahnabstand [mm] \n
infeed: vertikale Zustellung [mm] \n
"""
tstart = time.time()
surface = np.zeros((xdim*resolution+1, ydim*resolution+1)) #inititalisation of the array
i = 0 # Run index for the milling paths
phi = np.arccos(1-infeed/radius) # angle between ball cutter center point and extreme trimming edge on the path
print("np.zeros(): ", (time.time()-tstart)*1000)
for i in range(0,int((xdim+radius)//feed)): #Here is a post-checked-loop, a milling operation is always executed
cp = [feed*i,-infeed+radius] # Center point location of the spherical cutter
if radius*np.sin(phi) > i*feed:
x0 = 0 # Milling path has a wide range of x0 to x1.
else:
x0 = cp[0]-radius*np.sin(phi) #if X0 is outside surface set it 0 , i.e at staarting point of workpiece
if cp[0]+radius*np.sin(phi) > xdim:
x1 = xdim #if x1 exeeds XDIM set it as last point of workpeice
else:
x1 = cp[0]+radius*np.sin(phi)
for x in range(int(np.round(x0*resolution)),int(np.round(x1*resolution))): # Ball Mill# represents the discretized points on between X0 &x1..remember res is 1/res**
phi_ = np.arcsin((cp[0]-x/resolution)/radius)
z = cp[1] - radius * np.cos(phi_) #this y should be actually a temperory value along Z...
if surface[x,0] > z:
surface[x,0] = z
So I just wanted to know how can i store and print out the values of my variable cp?
You can use a list to store values in. As an example, you can initiate an empty list storage = [] and then append values to it, using storage.append(value).
storage = []
for i in range(10):
cp = [2*i, -i/2]
storage.append(cp)
# do other things with cp
You can also use the last stored value to calculate the next one, e.g.,
storage = [[1,1]]
for i in range(10):
cp = storage[-1]
cp = [cp[0]+i, -cp[1]/2.]
storage.append(cp)
You may then print the complete list print(storage), or only some value of interest out of it print(storage[3]). You can also let your function return the list,
def func():
storage = []
#....
return storage

Deleting duplicate x values and their corresponding y values

I am working with a list of points in python 2.7 and running some interpolations on the data. My list has over 5000 points and I have some repeating "x" values within my list. These repeating "x" values have different corresponding "y" values. I want to get rid of these repeating points so that my interpolation function will work, because if there are repeating "x" values with different "y" values it runs an error because it does not satisfy the criteria of a function. Here is a simple example of what I am trying to do:
Input:
x = [1,1,3,4,5]
y = [10,20,30,40,50]
Output:
xy = [(1,10),(3,30),(4,40),(5,50)]
The interpolation function I am using is InterpolatedUnivariateSpline(x, y)
have a variable where you store the previous X value, if it is the same as the current value then skip the current value.
For example (pseudo code, you do the python),
int previousX = -1
foreach X
{
if(x == previousX)
{/*skip*/}
else
{
InterpolatedUnivariateSpline(x, y)
previousX = x /*store the x value that will be "previous" in next iteration
}
}
i am assuming you are already iterating so you dont need the actualy python code.
A bit late but if anyone is interested, here's a solution with numpy and pandas:
import pandas as pd
import numpy as np
x = [1,1,3,4,5]
y = [10,20,30,40,50]
#convert list into numpy arrays:
array_x, array_y = np.array(x), np.array(y)
# sort x and y by x value
order = np.argsort(array_x)
xsort, ysort = array_x[order], array_y[order]
#create a dataframe and add 2 columns for your x and y data:
df = pd.DataFrame()
df['xsort'] = xsort
df['ysort'] = ysort
#create new dataframe (mean) with no duplicate x values and corresponding mean values in all other cols:
mean = df.groupby('xsort').mean()
df_x = mean.index
df_y = mean['ysort']
# poly1d to create a polynomial line from coefficient inputs:
trend = np.polyfit(df_x, df_y, 14)
trendpoly = np.poly1d(trend)
# plot polyfit line:
plt.plot(df_x, trendpoly(df_x), linestyle=':', dashes=(6, 5), linewidth='0.8',
color=colour, zorder=9, figure=[name of figure])
Also, if you just use argsort() on the values in order of x, the interpolation should work even without the having to delete the duplicate x values. Trying on my own dataset:
polyfit on its own
sorting data in order of x first, then polyfit
sorting data, delete duplicates, then polyfit
... I get the same result twice

Python - Number with a variable part

I have a number given in this form 623746xyz3 and i have to code a Python script that prints on screen all numbers that can be created with the combination of all values (from 0 to 9 ) that x,y,z can assume.
Can someone help me?
If those xyz are always next to each other, you can just loop from 0 to 999 and replace that part of the string accordingly.
s = "623746xyz3"
for xyz in range(1000):
sxyz = s.replace('xyz', str(xyz))
print int(sxyz)
In case the x, y, and z can be more 'spread out', you will need three nested loops:
for x in range(10):
sx = s.replace('x', str(x))
for y in range(10):
sxy = sx.replace('y', str(y))
for z in range(10):
sxyz = sxy.replace('z', str(z))
print int(sxyz)
(And in case you do not know the 'variables' a priori, you will first need to find the non-digit characters and use a recursive approach to replace them.)
My first idea:
for x in range(0, 10)
for y in range(0. 10)
for z in range (0, 10)
print 6*1000000000+2*100000000+3*10000000+7*1000000+4*100000+6*10000+x*1000+y*100+z*10+3

Prolog If Then Else fail with member predicate

Hello guys I am working on a prolog game and I need to write a piece of code that will:
Take a number (ArmyNo) from the user.
Take an X coordinate
Take an Y coordinate.
Then I have a list that is named TempBoard and it looks like this:
([
(1,1,-,-),(1,2,-,-),(1,3,-,-),(1,4,-,-),
(2,1,-,-),(2,2,-,-),(2,3,-,-),(2,4,-,-),
(3,1,-,-),(3,2,-,-),(3,3,-,-),(3,4,-,-),
(4,1,-,-),(4,2,-,-),(4,3,-,-),(4,4,-,-)
]).
before I add this (X,Y,w,ArmyNO) to the list I first want to check it if it is already there.
I attempted to do that by using this code but it does not seem to work properly:
%#######Got the number####
repeat,
%Get Cordinates X & Y.
writelist( [TempBoard,'select coordinates for the horizontal axis 1 to 4 to place your soldier Mr. Human',nl]),
read(X),
writelist(['select coordinates for the vertical axis 1 to 4 to place your soldier Mr. Human',nl]),
read(Y),
%Check if they are in the list.
(
member( (X,Y,w,ArmyNo),TempBoard ) ->
( replace((X,Y,w,ArmyNo),TempBoard,NewBoard) ) ;
(
writelist(['selected positions are not available in the table Mr.Human',nl]) , fail
)
).
%%
(X, Y, w, ArmyNo)
cannot be unified with any member of your example list because w doesn't unify with -. You may have meant W.