Related
I am trying to integrate a function on a 2d polygon described by its vertices as follow
import numpy as np
import quadpy
def f(x):
return x[0]
poly = np.array([[0.0, 0.0], [1.0, 0.0], [0, 1], [1,1]])
scheme = quadpy.t2.get_good_scheme(10)
val = scheme.integrate(f, poly)
But I get
QuadpyError: Wrong domain shape.
I really appreciate any kind of help
quad.t2 is for triangles, three points are expected. Your polygon is a square, you have to use quad.c2.
import quadpy
scheme = quadpy.c2.get_good_scheme(7)
val = scheme.integrate(
lambda x : x[0],
[ [[0.0, 0.0], [1.0, 0.0]], [[0.0, 1.0], [1.0, 1.0]] ]
)
val
This gives 0.5, which is easy to get mathematically.
See the link for the way to specify the quadrilateral.
I have a set of coordinates which I would like to manipulate and get desired results. I need to find the horizontal projection of some vector with respect to a reference vector ie, if v1(x1,y1,z1) represent the reference unit vector and v2(x2,y2,z2) be some random vector, I want to find the projection of v2 perpendicular to the direction of v1.
The figurative representation of the required is given as,
https://drive.google.com/file/d/1i3RQm--nLc1dIdZGMpt7oc5KLahOJySk/view?usp=sharing
The vectorial representation is required as
https://drive.google.com/file/d/12QLIoIJ0wckLa8sIgJ8ynMaD33PWrgxQ/view?usp=sharing
The code that I have written is as follows,
catalog=ascii.read("catalog.txt",'r',format='fixed_width_no_header', fast_reader=False, delimiter="\s",names=x,col_starts=y,col_ends=z)
x=[]
y=[]
z=[]
for i in range(0,len(catalog['PSRJ'])):
catalog['DECJD'][i] = catalog['DECJD'][i]+90
x.append(sin(catalog['DECJD'][i])*cos(catalog['RAJD'][i]))
y.append(sin(catalog['DECJD'][i])*sin(catalog['RAJD'][i]))
z.append(cos(catalog['DECJD'][i]))
coord=[]
for i in range(0,len(catalog['PSRJ'])):
coord.append([x[i],y[i],z[i]])
def norm(k):
p=[0.0,0.0,0.0]
p[0]=k[0]/(k[0]**2+k[1]**2+k[2]**2)**0.5
p[1]=k[1]/(k[0]**2+k[1]**2+k[2]**2)**0.5
p[2]=k[2]/(k[0]**2+k[1]**2+k[2]**2)**0.5
return([p[0],p[1],p[2]])
direc = norm(coord[]) #insert key for required coordinate
pix=[]
print(direc)
for i in range(0,len(catalog['PSRJ'])):
if a-5<=catalog['RAJD'][i]<=a+5 and b-5<=catalog['DECJD'][i]<=b+5:
pix.append(coord[i])
if pix[-1]==f:
p=len(pix)
print('p',pix)
val=pix
count=count+1
for i in range(0,count):
for j in range(0,3):
if not(i==p-1):
k=np.dot(direc,pix[i])
val[i][j]=direc[j]*k
val[i][j]=pix[i][j]-val[i][j]
else:
val[i][j]=0.0
print(val)
coord is list containing position vectors,
eg:[[x1,y1,z1],[x2,y2,z2]...]
f is the reference coordinate,
eg:[a,b,c]
OUTPUTS:
[0.049780917594520344, 0.9791671435583665, -0.19685925230782697]
p= 1
[[0.049780917594520344, 0.9791671435583665, -0.19685925230782697]]
[[0.0, 0.0, 0.0]]
[-0.813400538291293, 0.4058994949023155, 0.41668353020665466]
p= 2
[[0.683288067396023, -0.16836586544306054, -0.7104719222515533], [-0.813400538291293, 0.4058994949023155, 0.41668353020665466]]
[[-0.0, -0.0, -0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
[0.15331177729205145, -0.40555298841701465, 0.9011227843804535]
p= 2
[[0.08556174481590322, 0.8925106169941267, -0.4428362974924498], [0.15331177729205145, -0.40555298841701465, 0.9011227843804535]]
[[-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.0, 0.0]]
[0.4561283699625753, 0.08868628538946206, 0.8854838524214335]
p= 3
[[0.016015167632180395, 0.07982154161648915, -0.9966805084377242], [-0.39320614327231507, 0.918593873485819, -0.03967649792044076], [0.4561283699625753, 0.08868628538946206, 0.8854838524214335]]
[[-0.0, -0.0, -0.0], [-0.0, 0.0, -0.0], [0.0, 0.0, 0.0]]
The end result I am getting is null vectors, I don't know if it is my calculation causing the issue, Any insight into the problem would be helpful.
Using these two library functions:
SimpleITK.Euler3DTransform
scipy.spatial.transform.Rotation.from_euler
to create a simple rotation matrix from Euler Angles:
import numpy as np
import SimpleITK as sitk
from scipy.spatial.transform import Rotation
from math import pi
euler_angles = [pi / 10, pi / 18, pi / 36]
sitk_matrix = sitk.Euler3DTransform((0, 0, 0), *euler_angles).GetMatrix()
sitk_matrix = np.array(sitk_matrix).reshape((3,3))
print(np.array_str(sitk_matrix, precision=3, suppress_small=True))
order = 'XYZ' # Different results for any order in ['XYZ','XZY','YZX','YXZ','ZXY','ZYX','xyz','xzy','yzx','yxz','zxy','zyx']
scipy_matrix = Rotation.from_euler(order, euler_angles).as_matrix()
print(np.array_str(scipy_matrix, precision=3, suppress_small=True))
I get two different results:
[[ 0.976 -0.083 0.2 ]
[ 0.139 0.947 -0.288]
[-0.165 0.309 0.937]]
[[ 0.981 -0.086 0.174]
[ 0.136 0.943 -0.304]
[-0.138 0.322 0.937]]
Why? How can I compute the same matrix as SimpleITK using scipy?
The issue is that the itk.Euler3DTransform class by default applies the rotation matrix multiplications in Z # X # Y order and the Rotation.from_euler function in Z # Y # X order.
Note that this is independent of the order you specified. The order you specify refers to the order of the angles, not the order of the matrix multiplications.
If you are using the itk.Euler3DTransform directly as you showed in your example, you can actually change the default behavior for itk to perform the matrix multiplication in Z # Y # X order.
I never worked with sitk but in theory and based on the documentation, something like this should work:
euler_transform = sitk.Euler3DTransform((0, 0, 0), *euler_angles)
euler_transform.SetComputeZYX(True)
sitk_matrix = euler_transform.GetMatrix()
Alternatively, I wrote a function which is similar to Rotation.from_euler but has the option to specify the rotation order as well:
def build_rotation_3d(radians: NDArray,
radians_oder: str = 'XYZ',
rotation_order: str = 'ZYX',
dims: List[str] = ['X', 'Y', 'Z']) -> NDArray:
x_rad, y_rad, z_rad = radians[(np.searchsorted(dims, list(radians_oder)))]
x_cos, y_cos, z_cos = np.cos([x_rad, y_rad, z_rad], dtype=np.float64)
x_sin, y_sin, z_sin = np.sin([x_rad, y_rad, z_rad], dtype=np.float64)
x_rot = np.asarray([
[1.0, 0.0, 0.0, 0.0],
[0.0, x_cos, -x_sin, 0.0],
[0.0, x_sin, x_cos, 0.0],
[0.0, 0.0, 0.0, 1.0],
])
y_rot = np.asarray([
[y_cos, 0.0, y_sin, 0.0],
[0.0, 1.0, 0.0, 0.0],
[-y_sin, 0.0, y_cos, 0.0],
[0.0, 0.0, 0.0, 1.0],
])
z_rot = np.asarray([
[z_cos, -z_sin, 0.0, 0.0],
[z_sin, z_cos, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0],
])
rotations = np.asarray([x_rot, y_rot, z_rot])[(np.searchsorted(dims, list(rotation_order)))]
return rotations[0] # rotations[1] # rotations[2]
What is your 'order' string. When I ran your code with order='xyz', I get the same results for SimpleITK and scipy's Rotation.
I am working with a list of points [(1,2),(3,4),(5,6),(7,8)]. I want to find the euclidean distance from each point to every other point in the list.
I then need a new list created to represent each point in the original list, and in the new list I will add the distances relating to that point only.
So far I have:
for i in mat_ary1:
points_dist_i = []
for j in i:
row = []
x2 = [u[0] for u in i]
y2 = [u[1] for u in i]
# Calculate the distance from point j to all others
for a in x2:
dist_x_1 = pow((a - j[0]),2)
for b in y2:
dist_y_1 = pow((b - j[1]),2)
dist_xy_1 = float('{0:.2f}'.format((math.sqrt(dist_x_1 + dist_y_1))))
for item in j:
if item not in row:
row.append(dist_xy_1)
else:
continue
points_dist_i.append(row)
Each i in mat_ary1 represents a list of points. With the loops I am using I appear to repeating the same calculations.
My input seems to be duplicating the rows:
[[6.32, 6.32], [6.32, 6.32], [0.0, 0.0], [0.0, 0.0]]
[[11.4, 11.4], [11.4, 11.4], [0.0, 0.0], [0.0, 0.0]]
[[16.49, 16.49], [16.49, 16.49], [0.0, 0.0], [0.0, 0.0]]
[[14.32, 14.32], [14.32, 14.32], [0.0, 0.0], [0.0, 0.0]]
[[13.0, 13.0], [13.0, 13.0], [0.0, 0.0], [0.0, 0.0]]
[[11.66, 11.66], [11.66, 11.66], [0.0, 0.0], [0.0, 0.0]]
You can use the following nested list comprehension
>>> import math
>>> [[math.hypot(point[0]-x, point[1]-y) for x,y in points] for point in points]
[[0.0, 2.8284271247461903, 5.656854249492381, 8.48528137423857],
[2.8284271247461903, 0.0, 2.8284271247461903, 5.656854249492381],
[5.656854249492381, 2.8284271247461903, 0.0, 2.8284271247461903],
[8.48528137423857, 5.656854249492381, 2.8284271247461903, 0.0]]
This essentially makes a matrix with the distance from one point to any other point, where the row and column indexes are the "from" and "to" points, in which case the matrix will also be symmetric about the diagonal, and the diagonal will be all zeros.
Scikit-learn has a function for this exact problem, and it will probably be the fastest implementation if your array is large.
>>>>from sklearn.metrics.pairwise import pairwise_distances
>>>>pairwise_distances(mat_ary1)
array([[ 0. , 2.82842712, 5.65685425, 8.48528137],
[ 2.82842712, 0. , 2.82842712, 5.65685425],
[ 5.65685425, 2.82842712, 0. , 2.82842712],
[ 8.48528137, 5.65685425, 2.82842712, 0. ]])
I am doing an optimization problem and writing a gigantic list. I would like to insert comments inside the list like below
my_rhs = [1.0, 1.0, 0.0, 0.0, 0.0,\ #comment1
-1.0, -1.0, -1.0,\ #comment2
0.0, 0.0, 0.0]
but when I do this Python gives an error. How can I comment in the places shown? I tried defining each line as a new list and using + to append but that doesn't seem to work either. Like below
my_rhs = [1.0, 1.0, 0.0, 0.0, 0.0]+\ #comment1
[-1.0, -1.0, -1.0]+\ #comment2
[0.0, 0.0, 0.0]
How can I comment in the shown locations without Python giving an error?
You simply need to remove the backslash characters:
my_rhs = [1.0, 1.0, 0.0, 0.0, 0.0, # comment1
-1.0, -1.0, -1.0, # comment2
0.0, 0.0, 0.0]
Below is a demonstration:
>>> my_rhs = [1.0, 1.0, 0.0, 0.0, 0.0, # comment1
... -1.0, -1.0, -1.0, # comment2
... 0.0, 0.0, 0.0]
>>> my_rhs
[1.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0]
>>>
The \ character tells Python that the following line is part of the current line. So, it interprets this:
my_rhs = [1.0, 1.0, 0.0, 0.0, 0.0,\ #comment1
-1.0, -1.0, -1.0,\ #comment2
0.0, 0.0, 0.0]
As being equivalent to this:
my_rhs = [1.0, 1.0, 0.0, 0.0, 0.0, #comment1 -1.0, -1.0, -1.0, #comment2 0.0, 0.0, 0.0]
It is noteworthy that PEP 8, the official style-guide for Python code, has a section on wrapping long lines:
The preferred way of wrapping long lines is by using Python's implied
line continuation inside parentheses, brackets and braces. Long lines
can be broken over multiple lines by wrapping expressions in
parentheses. These should be used in preference to using a backslash
for line continuation.
This excerpt from Explicit Line Joining is also relevant:
A line ending in a backslash cannot carry a comment. A backslash does
not continue a comment. A backslash does not continue a token except
for string literals (i.e., tokens other than string literals cannot be
split across physical lines using a backslash). A backslash is illegal
elsewhere on a line outside a string literal.