Inserting complex functions in a python code - python

I have been trying to insert $e^ix$ as matrix element.
The main aim is to find the eigenvalue of a matrix which has many complex functions as elements. Can anyone help me how to insert it? My failed attempt is below:
for i in range(0,size):
H[i,i]=-2*(cmath.exp((i+1)*aj))
H[i,i+1]=1.0
H[i,i-1]=1.0
'a' is defined earlier in the program. The error flagged shows that aj is not defined. Using cmath I thought a complex number can be expontiated as (x+yj). Unfortunately, I couldn't figure out the right way to use it. Any help would be appreciated

Define a small float array:
In [214]: H = np.eye(3)
In [215]: H
Out[215]:
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
Create a complex number:
In [216]: 1+3j
Out[216]: (1+3j)
In [217]: np.exp(1+3j)
Out[217]: (-2.6910786138197937+0.383603953541131j)
Trying to assign it to H:
In [218]: H[1,1]=np.exp(1+3j)
<ipython-input-218-6c0b228d2833>:1: ComplexWarning: Casting complex values to real discards the imaginary part
H[1,1]=np.exp(1+3j)
In [219]: H
Out[219]:
array([[ 1. , 0. , 0. ],
[ 0. , -2.69107861, 0. ],
[ 0. , 0. , 1. ]])
Now make an complex dtype array:
In [221]: H = np.eye(3).astype( complex)
In [222]: H[1,1]=np.exp(1+3j)
In [223]: H
Out[223]:
array([[ 1. +0.j , 0. +0.j ,
0. +0.j ],
[ 0. +0.j , -2.69107861+0.38360395j,
0. +0.j ],
[ 0. +0.j , 0. +0.j ,
1. +0.j ]])
edit
For an array of values:
In [225]: a = np.array([1,2,3])
In [226]: np.exp(a+1j*a)
Out[226]:
array([ 1.46869394+2.28735529j, -3.07493232+6.7188497j ,
-19.88453084+2.83447113j])
In [228]: H[:,0]=np.exp(a+1j*a)
In [229]: H
Out[229]:
array([[ 1.46869394+2.28735529j, 0. +0.j ,
0. +0.j ],
[ -3.07493232+6.7188497j , -2.69107861+0.38360395j,
0. +0.j ],
[-19.88453084+2.83447113j, 0. +0.j ,
1. +0.j ]])

Related

how to put Multiple Matrices Together into a Single Matrix?

I need to put multiple matrices together into a single matrix, like so:
I have the values for the matrix, but I can't get it to appear like how it does in the image- instead, my values end up stacked on top of each other in an array. How can I go about getting my matrices to look like the image above?
My code:
import numpy as np
w_estimate = [0.656540, 7.192304, 2.749036]
F = [np.identity(3) * -w_estimate[1:4], -np.identity(3)], [np.identity(3)*0, np.identity(3)*0]
It's supposed to look like:
F = [[np.identity(3) * -w_estimate[1:4], -np.identity(3)]
[np.identity(3) * 0, np.identity(3) * 0]]
but instead it looks like:
[[np.identity(3) * -w_estimate[1:4]],
[-np.identity(3)],
[np.identity(3) * 0],
[np.identity(3) * 0]]
Help is very much appreciated.
The first correction to your code pertains to -w_estimate[1:4].
Since w_estimate is a plain pythonic list, you can not apply
minus operator to it.
You can however apply minus operator to a Numpy array.
Another correction is to avoid -0 in the result.
To get an array with diagonal elements filled from some other array,
and all other zeroes, you can use np.diagonal_fill, which fills
in-place diagonal elements of some (earlier) created array
(using np.zeros).
So to construct 2 "upper" blocks of your result, you can write:
a1 = np.zeros((3,3))
a2 = a1.copy()
np.fill_diagonal(a1, -np.array(w_estimate)[1:4])
np.fill_diagonal(a2, -1)
Note that -np.array(w_estimate)[1:4] returns last 2 elements of
w_estimate them, i.e. [7.192304, 2.749036]. Since the target array
is "3 by 3", the source sequence is repeated (in this case, for the
last diagonal element only).
If your intention is different, change -np.array(w_estimate)[1:4]
accordingly.
And to construct the whole intended array, run:
F = np.vstack((np.hstack((a1, a2)), np.zeros((3,6))))
The result is:
array([[-7.192304, 0. , 0. , -1. , 0. , 0. ],
[ 0. , -2.749036, 0. , 0. , -1. , 0. ],
[ 0. , 0. , -7.192304, 0. , 0. , -1. ],
[ 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. ]])
You shoud definitely take a look at numpy.block method.
>>> A = np.eye(2) * 2
>>> B = np.eye(3) * 3
>>> np.block([
... [A, np.zeros((2, 3))],
... [np.ones((3, 2)), B ]
... ])
array([[2., 0., 0., 0., 0.],
[0., 2., 0., 0., 0.],
[1., 1., 3., 0., 0.],
[1., 1., 0., 3., 0.],
[1., 1., 0., 0., 3.]])

How can I reshape this NumPy array correctly?

I'm needing to combine the rows in this array:
array([[0. , 1. , 0.44768612],
[0.34177215, 1. , 0. ]])
So that the output is:
array([[0., 0.34177215], [1., 1.], [0.44768612, 0.])
But for some reason, I can't figure it out with the reshape function. Any help would be appreciated.
If x is your array, x.T will transpose it:
array([[0. , 1. , 0.44768612],
[0.34177215, 1. , 0. ]])
becomes
array([[0. , 0.34177215],
[1. , 1. ],
[0.44768612, 0. ]])
if array is A, just do A.T...

Change values of a tensorflow tensor based on condition

I'm trying to recreate a numpy code snippet I wrote in tensorflow, but I'm struggling to find the correct/best tensorflow operations.
Consider the following numpy solution:
import numpy as np
# Initialize a random numpy array:
my_dummy = np.random.random((6, 2, 2, 10))
print(my_dummy)
> [[[[0.6715164 0.58915908 0.36607568 0.73404715 0.69455375 0.52177771
0.91810873 0.85010461 0.37485212 0.35634401]
[0.55885052 0.13041019 0.89774818 0.3363019 0.66634638 0.32054576
0.46174629 0.59975141 0.02283781 0.02997967]]
....
]]]]
# Create random floats, based on channel 0 of my dummy:
random_floats = np.random.random(my_dummy.shape[0])
print(random_floats)
> [0.89351759 0.76734892 0.36810602 0.08513434 0.65511941 0.61297472]
# Create a mask with ones and a shape based on my_dummy:
my_mask = np.ones((my_dummy.shape[0], 1, 1, my_dummy.shape[-1]))
print(my_mask)
> [[[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]
[[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]
[[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]
[[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]
[[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]
[[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]]
# Initialize a rate parameter:
my_rate = 0.5
# Based on my_rate, change the array accordingly:
my_mask[my_rate > random_floats] = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
print(my_mask)
[[[[1. 0. 1. 0. 1. 0. 1. 0. 1. 0.]]]
[[[1. 0. 1. 0. 1. 0. 1. 0. 1. 0.]]]
[[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]
[[[1. 0. 1. 0. 1. 0. 1. 0. 1. 0.]]]
[[[1. 0. 1. 0. 1. 0. 1. 0. 1. 0.]]]
[[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]]
# Multiply my_dummy with the new mask:
np.multiply(my_dummy, my_mask)
array([[[[0.6715164 , 0.58915908, 0.36607568, 0.73404715, 0.69455375,
0.52177771, 0.91810873, 0.85010461, 0.37485212, 0.35634401],
[0.55885052, 0.13041019, 0.89774818, 0.3363019 , 0.66634638,
0.32054576, 0.46174629, 0.59975141, 0.02283781, 0.02997967]],
[[0.22358676, 0.74959561, 0.11109368, 0.56021714, 0.2767754 ,
0.55156506, 0.15488703, 0.25738564, 0.18588607, 0.57593545],
[0.15804289, 0.87858207, 0.12890992, 0.78828551, 0.52467083,
0.45117698, 0.2605117 , 0.46659721, 0.855278 , 0.29630581]]],
[[[0.381445 , 0. , 0.48308211, 0. , 0.5136352 ,
0. , 0.84428703, 0. , 0.20532641, 0. ],
[0.696645 , 0. , 0.84184568, 0. , 0.01369105,
0. , 0.27683334, 0. , 0.59356542, 0. ]],
[[0.5281193 , 0. , 0.82336821, 0. , 0.63435181,
0. , 0.12824084, 0. , 0.35045286, 0. ],
[0.02205884, 0. , 0.22927706, 0. , 0.45538199,
0. , 0.81220918, 0. , 0.46427429, 0. ]]],
.....
]]]])
In tensorflow, I did this (warning, many imports, I tried a lot of things and no longer sure whether all of them are necessary, just want to ensure you can reproduce immediately):
from keras.engine.base_layer import InputSpec
from tensorflow.python.util import deprecation
from tensorflow.python.framework import ops
from tensorflow.python.eager import context
from tensorflow.python.framework import tensor_shape
from tensorflow.python.framework import tensor_util
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import random_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.platform import tf_logging as logging
import numbers
import numpy as np
import tensorflow as tf
from tensorflow.python.framework import ops
from tensorflow.python.ops import random_ops
from tensorflow.python.ops import math_ops
from keras import backend as K
# Create my_dummy and convert to tensor object:
my_dummy = np.random.random((6, 2, 2, 4))
my_dummy = ops.convert_to_tensor(my_dummy)
my_dummy.get_shape()
> TensorShape([Dimension(6), Dimension(2), Dimension(2), Dimension(4)])
# Create random floats, like before and inspect tensor with Keras (instead of running a tf session):
random_floats = random_ops.random_uniform([my_dummy.get_shape().as_list()[0]], dtype=my_dummy.dtype)
K.eval(random_floats)
> array([0.74018297, 0.76996447, 0.52047441, 0.28215968, 0.91457724,
0.64637448])
# Like before, create a mask with ones, like before shape (almost completely) based on my_dummy:
my_mask = tf.ones([my_dummy.get_shape()[0], 1, 1, my_dummy.get_shape()[-1]], dtype=x.dtype)
K.eval(my_mask)
> array([[[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]],
[[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]],
[[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]],
[[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]],
[[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]],
[[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]]])
Unfortunately, this where I'm stuck. I did not find a way to alter the entries in the my_mask Tensor object, based on a rate value. One thing I tried was tf.where:
tf.where(rate > random_floats, my_mask, tf.constant([1, 0, 1, 0, 1, 0, 1, 0, 1, 0], dtype = my_dummy.dtype))
but get the error:
ValueError: Shapes must be equal rank, but are 4 and 1 for 'Select_1' (op: 'Select') with input shapes: [6], [6,1,1,10], [10].
Thankful for any advice/help :)
It is basically more or less the same in tensorflow. Showing with smaller shaped data for convenience:
import tensorflow as tf
value_to_assign = tf.constant([[1., 0., 1., 0., 1.]])
rate = tf.constant(.5)
dummy = tf.random_normal(shape=(4, 1, 1, 5))
# random_floats = tf.random_normal(shape=(tf.shape(dummy)[0], ))
random_floats = tf.constant([0.4, 0.6, .7, .2]) # <--using const values to illustrate
init_val = tf.ones((tf.shape(dummy)[0], 1, 1, tf.shape(dummy)[-1]))
mask = tf.Variable(init_val,
trainable=False)
indices = tf.where(tf.equal(True, rate > random_floats))
tiled = tf.tile(value_to_assign,
multiples=[tf.shape(indices)[0], 1])[:, tf.newaxis, tf.newaxis, :]
mask = tf.scatter_nd_update(mask,
indices=indices,
updates=tiled)
res = mask * dummy
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print('MASK')
print(sess.run(mask))
print('DUMMY')
print(sess.run(dummy))
print('RESULT')
print(sess.run(res))
MASK
[[[[1. 0. 1. 0. 1.]]]
[[[1. 1. 1. 1. 1.]]]
[[[1. 1. 1. 1. 1.]]]
[[[1. 0. 1. 0. 1.]]]]
DUMMY
[[[[-1.2031308 -1.6657363 -1.5552464 0.8540495 0.37618718]]]
[[[-0.4468031 0.46417323 -0.3764856 1.1906835 -1.4670093 ]]]
[[[ 1.2066191 -1.4767337 -0.9487017 -0.49180242 -0.33098853]]]
[[[-0.1621628 0.61168176 0.10006899 0.7585997 -0.23903783]]]]
RESULT
[[[[ 1.7753109 0. -0.5451439 -0. -0.53782284]]]
[[[ 0.08024058 -1.8178499 1.183356 1.0895957 -0.9272436 ]]]
[[[-0.5266396 -2.0316153 -1.0043124 -1.1657876 0.6106227 ]]]
[[[-0.46503183 0. 0.01983969 -0. 0.58563703]]]]

python convert 2d array to 1d array [duplicate]

This question already has answers here:
How do you get the magnitude of a vector in Numpy?
(8 answers)
Closed 4 years ago.
I am new to python and need to do the following thing:
I've given an 1d array of vectors (so pretty much 2d).
My task is to create an 1d array that contains the length of each vector.
array([[0. , 0. ],
[1. , 0. ],
[1. , 1. ],
[1. , 0.75],
[0.75, 1. ],
[0.5 , 1. ]
...
should be converted to
array([0,
1,
1.4142,
...
I could easily do this in theory but I am not familiar with the inbuild commands of python and I am very happy if someone could tell me some inbuild commands of python that can do this.
Using norm from np.linalg.norm:
import numpy as np
a = np.array([[0., 0.],
[1., 0.],
[1., 1.],
[1., 0.75],
[0.75, 1.],
[0.5, 1.]])
print(np.linalg.norm(a, axis=1))
Output
[0. 1. 1.41421356 1.25 1.25 1.11803399]
With NumPy you can use vectorised operations:
A = np.array([[0. , 0. ],
[1. , 0. ],
[1. , 1. ],
[1. , 0.75],
[0.75, 1. ],
[0.5 , 1. ]])
res = np.sqrt(np.square(A).sum(1))
array([ 0. , 1. , 1.41421356, 1.25 , 1.25 ,
1.11803399])
Alternatively, if you prefer a less functional solution:
res = (A**2).sum(1)**0.5
You can use the list comprehension. In Python 2,
print [(x[0]*x[0]+x[1]*x[1])**0.5 for x in arr]
where arr is your input
you can iterate over your array to find the vector length:
array=[[0,0],[0,1],[1,0],[1,1]]
empty=[]
for (x,y) in array:
empty.append((x**2+y**2)**0.5)
print(empty)
You can achieve it with hypotenuse np.hypot
np.hypot(array[:, 0], array[:, 1])
You can try this:
import math
b = []
for el in arr:
b.append(math.sqrt(el[0]**2 + el[1]**2))
print b
or you can do it even shorter:
b = [math.sqrt(el[0]**2 + el[1]**2) for el in arr]
where arr is the your array.
Here is and one more example with lambda:
b = map(lambda el: (el[0]**2 + el[1]**2)**0.5, arr)

How to extract the BSpline basis from scipy.interpolate.BSpline

In this question I asked the community about how scipy.interpolate.splev calculates a spline basis.. My goal was to compute a spline faster then splev by pre-calculating a bspline basis and generate a curve by doing a basis to control point dot product.
Since then a new scipy.interpolate.BSpline interpolator was added to scipy. It comes with a basis_element function, which I presume could be used to return the basis used to calculate a spline.
So for example using the code from here with the inputs below:
import numpy as np
# Control points
cv = np.array([[ 50., 25., 0.],
[ 59., 12., 0.],
[ 50., 10., 0.],
[ 57., 2., 0.],
[ 40., 4., 0.],
[ 40., 14., 0.]])
kv = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3] # knot vector
n = 10 # 10 samples (keeping it simple)
degree = 3 # Curve degree
I can compute the following bspline basis:
[[ 1. 0. 0. 0. 0. 0. ]
[ 0.2962963 0.56481481 0.13271605 0.00617284 0. 0. ]
[ 0.03703704 0.51851852 0.39506173 0.04938272 0. 0. ]
[ 0. 0.25 0.58333333 0.16666667 0. 0. ]
[ 0. 0.07407407 0.54938272 0.36728395 0.00925926 0. ]
[ 0. 0.00925926 0.36728395 0.54938272 0.07407407 0. ]
[ 0. 0. 0.16666667 0.58333333 0.25 0. ]
[ 0. 0. 0.04938272 0.39506173 0.51851852 0.03703704]
[ 0. 0. 0.00617284 0.13271605 0.56481481 0.2962963 ]
[ 0. 0. 0. 0. 0. 1. ]]
Using np.dot with basis and control points returns 10 samples on curve:
[[ 50. 25. 0. ]
[ 55.12654321 15.52469136 0. ]
[ 55.01234568 11.19753086 0. ]
[ 53.41666667 9.16666667 0. ]
[ 53.14506173 7.15432099 0. ]
[ 53.1882716 5.17901235 0. ]
[ 51.58333333 3.83333333 0. ]
[ 47.20987654 3.87654321 0. ]
[ 42.31790123 6.7345679 0. ]
[ 40. 14. 0. ]]
Question : is it possible to extract the basis as described above out of scipy.interpolate.BSpline?
Obviously I must be using it wrong, because when I try I get something like this:
from scipy.interpolate import BSpline
b = BSpline.basis_element(kv)
print b(np.linspace(kv[0],kv[-1],n)) # i'm not sure what these values represent
[ 0. 0.00256299 0.04495618 0.16555213 0.28691315 0.28691315
0.16555213 0.04495618 0.00256299 0. ]
BSpline.basis_element takes as its arguments the internal knots.
In your example, you padded the knots, and that did not do what you thought it would:
In [3]: t = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3]
In [4]: b = BSpline.basis_element(t)
In [5]: b.k
Out[5]: 8
So it's an 8th order spline.
If you wanted a quadratic spline, you would do
In [7]: b1 = BSpline.basis_element([0, 1, 2, 3])
In [8]: b1.k
Out[8]: 2
In [9]: b1.t
Out[9]: array([-1., -1., 0., 1., 2., 3., 4., 4.])
Confused? The method is quite simple: https://github.com/scipy/scipy/blob/v0.19.1/scipy/interpolate/_bsplines.py#L243-L302
The callable returned by BSpline.basis_element is really a b-spline function. The result of calling it with an array argument is then equivalent to directly running the example code in the BSpline docstring in a loop for each element of your array, https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.BSpline.html
EDIT: if you're after a variant of Cox-de Boor algorithm of calculating all non-zero splines at a given point, then you can look at a _bspl.evaluate_all_bsplines function, https://github.com/scipy/scipy/blob/v0.19.1/scipy/interpolate/_bspl.pyx#L161
(which itself is just a wrapper over a C routine which does all the heavy lifting; note that it's hard to beat that latter one performance wise.)
However, it's not a public function, so it's not guaranteed to be available in future versions. If you have a good use for it, and a suggestion for a user-facing API, bring the discussion over to the scipy bug tracker.

Categories