First time here? Check out the FAQ!

Ask Your Question
1

How do I "tidy up" error terms in a matrix?

asked 12 years ago

GaryMak gravatar image

Hi - I have some calculation results in the form of a complex Gram matrix which are all supposed to be integers (or "obvious" algebraic numbers which I know about). However inevitably in the course of creating them as inner products, some "error" terms arise which are of a size of the order of 10^-16 (real and/or complex). Is there an easy way to "clean up" my matrix with some sort of threshold, so that things which differ from a user-specified list of algebraic numbers by less than a tiny amount like 10^-15, are assumed to be the relevant algebraic number? At the moment I'm having to do it by a bunch of hideous if-statement contortions but I'm sure there's a better way! Many thanks in advance for any help.

Preview: (hide)

Comments

I've wondered similar things myself. It would be nice to have something like `fnormal` in Maple. Can you apply `round` in some way using a `map` command to help. For example, `round(1+10.^(-16),5)` gives `1.0`.

calc314 gravatar imagecalc314 ( 12 years ago )

thanks - as an example for future reference, I used John's suggestion below in the following form: mat.apply_map( lambda x: (d*abs(x)^2).round()/d ); where I knew that the largest denominator for the abs values was d (one has to be a little more careful with complex entries)

GaryMak gravatar imageGaryMak ( 12 years ago )

2 Answers

Sort by » oldest newest most voted
2

answered 12 years ago

Volker Braun gravatar image

Matrices over ComplexField don't implement round(), unfortunately. But the following variant of John's answer works:

sage: mat = matrix(3, 3, [2+1e-15+i*1e-15]*9)
sage: mat.change_ring(CDF).round()
[2.0 2.0 2.0]
[2.0 2.0 2.0]
[2.0 2.0 2.0]
Preview: (hide)
link

Comments

I applied 'real()' and then 'round()' in my answer.

John Palmieri gravatar imageJohn Palmieri ( 12 years ago )

Agreed. I just wanted to point out that matrices over some rings have already a round() method.

Volker Braun gravatar imageVolker Braun ( 12 years ago )

thanks Volker - that's helpful.

GaryMak gravatar imageGaryMak ( 12 years ago )
2

answered 12 years ago

This will clean things up if the entries are integers. If the entries differ by small amounts from known algebraic numbers, that's more complicated.

sage: mat = matrix(3, 3, [2+1e-15+i*1e-15]*9)
sage: mat
[2.00000000000000 + 1.00000000000000e-15*I 2.00000000000000 + 1.00000000000000e-15*I 2.00000000000000 + 1.00000000000000e-15*I]
[2.00000000000000 + 1.00000000000000e-15*I 2.00000000000000 + 1.00000000000000e-15*I 2.00000000000000 + 1.00000000000000e-15*I]
[2.00000000000000 + 1.00000000000000e-15*I 2.00000000000000 + 1.00000000000000e-15*I 2.00000000000000 + 1.00000000000000e-15*I]
sage: mat.apply_map(lambda x: x.real().round())
[2 2 2]
[2 2 2]
[2 2 2]
sage: mat_Z = mat.apply_map(lambda x: x.real().round())
sage: mat_Z.base_ring()
Integer Ring
Preview: (hide)
link

Comments

thanks John - that's certainly a thousand times neater than the mess I had before! The algebraic number thing is almost too good to be true, but maybe someone out there knows a way ... (obviously the list would have to be "restricted" in the sense that the abs vals of the entries would have to be separated by more than twice the error term or something, etc etc)

GaryMak gravatar imageGaryMak ( 12 years ago )

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 12 years ago

Seen: 679 times

Last updated: Nov 13 '12