# Problem with conjugate_transpose of a symbolic matrix

dAbar=diagAbar.subs(t=0);dAbar
[ 3.18953143618644*I*sech(x3) - 3.00000000000000 - 2.68953143618644*I
0                                                                    0]
[                                                                   0
-3.18953143618644*I*sech(x3) - 3.00000000000000 + 2.68953143618644*I
0]

[                                                                   0
0                                                                   -4]

TdiagAbar=dAbar.conjugate_transpose() + dAbar

Traceback (click to the left of this block for traceback)
...
AttributeError:
'sage.rings.complex_interval.ComplexIntervalFieldElement' object has no
attribute 'sech'


I hope their is an easy answer. Thanks, nonlinear

edit retag close merge delete

Could you please add how x3 and diagAbar were constructed so that we can reproduce your problem ?

( 2013-05-12 00:00:32 -0500 )edit

A simpler example illustrating the error: sage: x3 = CIF(3) sage: B = matrix(CIF,[[3*I*sech(x3), 0], [0, 0]])

( 2013-05-12 02:17:39 -0500 )edit

Sort by » oldest newest most voted
var('t,x3')
p1= -3+2.5*tanh(2.*t)+(3.19*sech(x3)-2.69)*I
p2= -3+2.5*tanh(2.*t)-(3.19*sech(x3)-2.69)*I
p3=-4
diagAbar= diagonal_matrix(Ta.[p1,p2,p3])
dAbar=diagAbar.subs(t=0);dAbar


Playing around with dAbar I found that:

TdiagAbar=dAbar.conjugate()


works, but

TdiagAbar=dAbar.transpose()


and

TdiagAbar=dAbar.conjugate()+dAbar


do not work. Sorry, I didn't follow much of what link said. I do a lot of symbolic math with symbolic variables such as with t and x3 above. I know MATLAB well and Mathematica somewhat. I would prefer to support Sage. Thanks for your help.

nonlinear

more

Hi, could you ploease provide the definition of Ta ?

( 2013-05-12 22:07:59 -0500 )edit

Just after defining dAbar, type:

sage: dAbar = dAbar.dense_matrix()


And it will work.

Now, here are some explanations that may help you to understand what happened, tha may help in further cases (look to the Traceback). You defined your matrix in a sparse way: you only defined the diagonal assuming that the other values are zero. Hence, instead of storing all entries of the matrix, Sage only stores the interesting entries in a dictionary, hence the name sparse matrix.

But, at some point (during the .transpose() operation), probably to maintain the sparse structure, Sage checks whether some entries are zero. For this, it needs to be sure, hence it uses the safe complex interval arithmetic (where a complex number is approximated by a pair of floating point real intervals containing it).

Unfortunately, as explained in my previous answer, elements of the Complex Interval Field (named CIF) do not have a .sech() method, and you got an error. If you transform your matrix into a dense one (where zeros are explicitely written everywhere), this test is not done and the error does not appear.

By the way, there is another workaround in your case. Before doing any computation, redefine the sech() function (as explained in my previous answer), so that it will work for Complex Interval Field elements. Before any computation, just type:

sage: sech = lambda x: 2*exp(-x)/(1+exp(-2*x))


And, since the .exp() method is defined for elements of CIF, then you will not encounter the problem.

more

Sorry, Ta was a typo and should not be there. I used

dAbar = dAbar.dense_matrix()

and all is good. Thanks so much tmonteil.

nonlinear

more

You shoud give us more informations about how x3 and diagAbar were constructed.

If i assume, as @slelievre suggests, that x3 is an element of CIF (Complex Interval Field with 53 bits of precision), then you can see that no method .sech() is implemented for it:

sage: a = CIF(3+I)
sage: a.sech()
AttributeError: 'sage.rings.complex_interval.ComplexIntervalFieldElement' object
has no attribute 'sech'


You might be confused by the fact that

sage: sech(CIF(3+I))
sech(3+1*I)


gives you an answer. It is just that the function sech() does not find the method .sech() for CIF(3+I), then it answers by a symbolic expression sech(3+1*I), as you can see by typing:

sage: sech(CIF(3+I)).parent()
Symbolic Ring


This does not solves anything, since, if you try to get the value of this symbolic expression by converting it to an element of CIF, at some point Sage will have to evaluate CIF(3+I).sech() which is not implemented:

sage: CIF(sech(CIF(3+I)))
AttributeError: 'sage.rings.complex_interval.ComplexIntervalFieldElement' object
has no attribute 'sech'


As you can check, CIF seems the only field where sech is not implemented:

for field in [RR,RDF,RIF,CC,CDF,CIF,SR]:
print str(field) + ' - ' +  str(sech(field(1)).parent())
try:
print str(field(1).sech()) + ' - ' + str(field(1).sech().parent())
except Exception as e:
print e
print ''


But nothing is lost, as you can do it yourself, since elements of CIF have an exp() method and $sech(x) = \frac{2e^{-x}}{1 + e^{-2x}}$.

Just define:

sage: sech = lambda x: 2*exp(-x)/(1+exp(-2*x))


But be careful, when you write

sage: I * sech(a)
0.0837533280462231? + 0.0540446576423634?*I


the coercion system will do the multiplication in the Symbolic Ring since I is an element of the Symbolic Ring.

sage: (I * sech(a)).parent()
Symbolic Ring


Hence, you should just do:

sage: CIF(I) * sech(a)
0.0837533280462231? + 0.0540446576423634?*I


And now you will be safe, with respect to the fact that our sech function did not try to minimize the dimaeters of the intervals defining the output, as much as could have done a direct .sech() method defined for elements of CIF.

more