string to complex matrix representation in python - python

I have the following example string:
s ="1 1+i\n1-i 0"
Now I have to turn this string into a complex matrix. I am aware of the np.matrix() function but it is not designed for a complex matrix. Maybe some of you can provide me some ideas of how I can go forward. I also tried to split at \n but then I have two arrays which contain exactly one element (1 1+i & 1-i 0 ). The result should be:
np.array([[1, complex(1,1)], [complex(1, -1), 0]])
Thanks in advance!

Your question has two parts.
First, we want to convert the string into a list of complex numbers (as strings), and then convert this list into the actual complex numbers.
s = "1 1+i\n1-i 0"
import re
complex_strings = re.split("\n|\s+", s.replace('i', 'j'))
complex_numbers = [complex(x) for x in complex_strings]
m = np.array(complex_numbers).reshape(2, 2)
[[1.+0.j 1.+1.j]
[1.-1.j 0.+0.j]]

Related

python string slicing with alternating strides

Is there an elegant way to perform python slicing with more than one stride?
For example, given an input string, create string which contains the characters in positions: 1,4,6,9,11,14,16,19 and so forth
Input example:
s = "abcdefhijklmnopqrstuvwxyz"
Output:
out = "behkmpruwz"
Here is a regex solution which might meet your requirements:
s = "abcdefhijklmnopqrstuvwxyz"
output = re.sub(r'.(.)..(.)', '\\1\\2', s)
print(s)
print(output)
This prints:
abcdefhijklmnopqrstuvwxyz
behkmpruwz
The pattern matches five characters at a time, capturing the second and fifth characters in capture groups \1 and \2. Then, it just replaces those five characters with the two single captured characters.
This happens to work perfectly for your input string, because it is exactly a multiple of 5 in length. Note that my pattern won't do any replacements to any characters 1 to 4 which exceed a multiple length of 5.
If you do not want to use external libraries, then one general solution is to calculate the correct index yourself and join the corresponding characters.
start1 = 0
start2 = 1
stride1 = 5
stride2 = 3
result = ''.join([s[i + j] for i in range(start1, len(s), stride1)
for j in range(start2, stride1, stride2)])
If you do not mind using libraries such as numpy, then you can make the input into N-d arrays (in this case, a 2-D matrix) and apply advanced slicing on multiple axes.
import numpy as np
start1 = 0
start2 = 1
stride1 = 5
stride2 = 3
s_mat = np.array([*s]).reshape(stride1, -1) # Reshape the input into a 5 by 5 matrix
result_mat = s_mat[start1:, start2::stride2].flatten() # Apply slicing and flatten the result into a 1-D array
result = ''.join(result_mat) # Merge the output array into a string
I tried to simplify the loops like this. Not sure if its the perfect fit.
stride_1_seq = s[1::3]
stride_2_seq = s[4::5]
extracted_str = "".join(map(lambda x,y: x+y, stride_1_seq, stride_2_seq))
This should work, if the intervals are configured well.

Tick tack toe: Python numbers displaying differently in different contexts for no reason

I'm not sure exactly how to describe this problem, so apologies if the title was insufficient.
I'm trying to make a piece of code that will put all possible tick-tack-toe boards (0 is blank, 1 is X, 2 is O) into a 2d array (list of lists). I've successfully found a way to do this:
import math
boxes = []
for m in range (0, 19683):
boxes.append([m%3, int(math.floor((m%9)/3))])
print(boxes)
And it works. But instead of typing out the next seven list items, I thought it would be easier to iterate over them like so:
boxes = []
for m in range (0, 19683):
boxes.append([])
for s in range (0,9):
boxes[m].append(int(math.floor((m%(3**(m+1)))/(3**m))))
print(boxes)
and it just gave me a big array of zeros! I have no idea why changing it to iteration would do this; I tried with both ** and pow(). DOes anyone know what the problem is?
Looking at your code, I think in your second example you could have meant:
boxes[m].append(int(math.floor((m%(3**(s+1)))/(3**s))))
Also, you can utilise itertools.product() to achieve the same kind of outcome:
boxes = list(product([0, 1, 2], repeat=9))
Let's look at that inner expression:
math.floor(m%(3**(m+1)))/(3**m)
The numerator is simply m: you take it modulus 3^(m+1), which will be larger than m. The next step is then m / (3**m) -- taken as an integer, this is 0.
In short, your algebra is off.
I recommend that you use itertools.product to get the output you want.

Matlab repr function

In Matlab, one can evaluate an arbitrary string as code using the eval function. E.g.
s = '{1, 2, ''hello''}' % char
c = eval(s) % cell
Is there any way to do the inverse operation; getting the literal string representation of an arbitrary variable? That is, recover s from c?
Something like
s = repr(c)
Such a repr function is built into Python, but I've not come across anything like it in Matlab, nor do I see a clear way of how to implement it myself.
The closest thing I know of is something like disp(c) which prints out a representation of c, but in a "readable" format as opposed to a literal code format.
The closest there is in Matlab is mat2str, which works for numeric, character or logical 2D arrays (including vectors). (It doesn't work for ND arrays, cell arrays, struct arrays, or tables).
Examples:
>> a = [1 2; 3 4]; ar = mat2str(a), isequal(eval(ar), a)
ar =
'[1 2;3 4]'
ans =
logical
1
>> a = ['abc'; 'def']; ar = mat2str(a), isequal(eval(ar), a)
ar =
'['abc';'def']'
ans =
logical
1
In this related question and answers you can see:
A function I wrote for obtaining a string representation of 2D cell arrays with arbitrarily nested cell, numeric, char or logical arrays.
How to do what you want in Octave for arbitrary data types.
OK, I see your pain.
My advice would still be to provide a function of the sort of toString leveraging on fprintf, sprint, and friends, but I understand that it may be tedious if you do not know the type of the data and also requires several subcases.
For a quick fix you can use evalc with the disp function you mentioned.
Something like this should work:
function out = repr(x)
out = evalc('disp(x)');
end
Or succinctly
repr = #(x) evalc('disp(x)');
Depending on exactly why you want to do this, your use case may be resolved with matlab.io.saveVariablesToScript
Here is the doc for it.
Hope that helps!

2D python list of numpy arrays to 2D numpy array

Which is the most performant way
to convert something like that
problem = [ [np.array([1,2,3]), np.array([4,5])],
[np.array([6,7,8]), np.array([9,10])]]
into
desired = np.array([[1,2,3,4,5],
[6,7,8,9,10]])
Unfortunately, the final number of columns and rows (and length of subarrays) is not known in advance, as the subarrays are read from a binary file, record by record.
How about this:
problem = [[np.array([1,2,3]), np.array([4,5])],
[np.array([6,7,8]), np.array([9,10])]]
print np.array([np.concatenate(x) for x in problem])
I think this:
print np.array([np.hstack(i) for i in problem])
Using your example, this runs in 0.00022s, wherease concatenate takes 0.00038s
You can also use apply_along_axis although this runs in 0.00024s:
print np.apply_along_axis(np.hstack, 1, problem)

Regarding an instance of simulating the functionality of 2D arrays in Python

arr = [
"xxyyyxxxx",
"xxxeeexxx",
"xwwwxxxxx",
]
I've seen code similar to this used to simulate 2 dimensional arrays in python by parsing the contents using for in row and for in col. Using this method what would be the easiest way to identify a specific "index" (or rather the location of a character within a certain string). If you don't have to modify the array and having to type out the entire array isn't an issue would there still be a better way to simulate a 2 dimensional array?
Strings are immutable sequences that can be indexed just like lists. So here,
arr[0][2]
Would take the string with index 0, and from that the character with index 2 -- "y". So that works.
Better ways to do it depends on what you need to do exactly. Real 2D arrays are available in Numpy.
to get the position of a specific character you could do a 2D loop like so
for i in range(len(arr)):
for j in range(len(arr[i])):
if arr[i][j]=="e":
print str(i), ", ", str(j)

Categories

Resources