3

I have two arrays, field_in_k_space_REAL and field_in_k_space_IMAGINARY, that contain, respectively, the real and imaginary parts of an array of complex numbers, field_in_k_space_TOTAL, which I would like to create. Why does the following assignment not work, producing the error

AttributeError: attribute 'real' of 'numpy.generic' objects is not writable


field_in_k_space_TOTAL = zeros(n, complex)
for i in range(n):
    field_in_k_space_TOTAL[i].real = field_in_k_space_REAL[i]
    field_in_k_space_TOTAL[i].imag = field_in_k_space_IMAGINARY[i]
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
johnhenry
  • 1,293
  • 5
  • 21
  • 43
  • 1
    The error message seems pretty clear; what is confusing you? Have you read e.g. http://stackoverflow.com/q/2598734/3001761 – jonrsharpe Mar 16 '15 at 11:36

4 Answers4

4

The suggestion by @Ffisegydd (and by @jonsharpe in a comment) are good ones. See if that works for you.

Here, I'll just point out that the real and imag attributes of the array are writeable, and the vectorized assignment works, so you can simplify your code to

field_in_k_space_TOTAL = zeros(n, complex)

field_in_k_space_TOTAL.real = field_in_k_space_REAL
field_in_k_space_TOTAL.imag = field_in_k_space_IMAGINARY
Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
2

You cannot assign the specific real and imaginary parts of a numpy element. You'd have to create an intermediate value and then assign it to field_total, for example:

for i in range(n):
    x = field_in_k_space_REAL[i] + field_in_k_space_IMAGINARY[i]
    field_in_k_space_TOTAL[i] = x

This will be slow and cumbersome though. Instead, why don't you just add the two arrays together and make use of vectorisation? I can promise you, it'll be much quicker.

import numpy as np

# Note: dropping the long names.

field_real = np.array([0, 10, 20, 30])
field_imag = np.array([0j, 1j, 2j, 3j])

field_total = field_real + field_imag

print(field_total)
# [  0.+0.j  10.+1.j  20.+2.j  30.+3.j]

In the case where field_imag is an array of real numbers that you want to convert to imaginary (as in your original example) then the following code will work (thanks to jonrsharpe for the comment).

field_real = np.array([0, 10, 20, 30])
field_imag = np.array([0, 1, 2, 3])

field_total = field_real + (field_imag * 1j)
Ffisegydd
  • 51,807
  • 15
  • 147
  • 125
1

You simply do

field_in_k_space_TOTAL = field_in_k_space_REAL + 1j*field_in_k_space_IMAGINARY

It is hard to do anything simpler. :)

Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260
0

Provided that your data types are compatible, you can do:

field_in_k_space_TOTAL = np.hstack((field_in_k_space_REAL[:,None], field_in_k_space_IMAGINARY[:,None])).ravel().view(np.complex)
Stefan
  • 4,380
  • 2
  • 30
  • 33