Ask Your Question
0

Simplify vector vs. its norm

asked 2018-08-25 22:40:11 +0100

Harald gravatar image

In the following I compute the matrix mrot which shall rotate the vector v to the unit vector pointing into the x-direction. This does indeed work, except that the last printout for verification, view(u*mrot), looks complicated, despite the fact that it should just be (1, 0, 0). How would I let sage reduce the enormous formulas for the vector components?

v1 = var('v1');
v2 = var('v2');
v3 = var('v3');
e1 = vector([1,0,0]);
v = vector([v1, v2, v3]);
u = v/v.norm();
#u = v;
view(["u=", u], sep=" ");
z=u.cross_product(e1);
#z=e1.cross_product(u);
view(["z=", z]);
c=u.dot_product(e1);
view(["c=",c]);
mat=Matrix( [[0, -z[3-1], z[2-1]], [z[3-1], 0, -z[1-1]], [-z[2-1], z[1-1], 0]] );
#view([mat, mat*mat]);
mrot=-(matrix.identity(3) + mat + (1/(1+c)) * mat*mat);
view(u*mrot);
edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
1

answered 2018-08-26 21:20:56 +0100

nbruin gravatar image

You need to do {{{ asume(v1,'real'); asume(v2,'real'); asume(v3,'real'); }}} because some of the simplifications you need are not valid for complex numbers. You can just call "simplify_full" on the vector itself. It will apply to the entries.

It looks like you need to let mrot act on the left, though: mrotu; or u(mrot.T), and even then it looks like you get the vector (-1,0,0); so there may be a sign error somewhere or sage takes an unexpected branch cut somewhere.

edit flag offensive delete link more

Comments

The minus sign in front of the definition of mrot is wrong in my original post, but given that originally I got a spaghetti plate full of formula, (-1, 0, 0) is great and easily fixed by removing the minus :-)

Harald gravatar imageHarald ( 2018-08-27 07:37:16 +0100 )edit

Formatting note: note that

mrot*u or u*(mrot.T)

will render as

mrotu or u(mrot.T)

while

`mrot*u` or `u*(mrot.T)`

will render as

mrot*u or u*(mrot.T)

slelievre gravatar imageslelievre ( 2018-09-20 03:50:55 +0100 )edit
0

answered 2018-08-26 16:37:09 +0100

tmonteil gravatar image

updated 2018-08-26 16:39:35 +0100

You can apply the full_simplify() method to every entry of the vector as follows:

sage: vector(e.full_simplify() for e in u*mrot)
(-(v1^2 - v2^2 - v3^2)/(v1^2 + v2^2 + v3^2), -2*v1*v2/(v1^2 + v2^2 + v3^2), -2*v1*v3/(v1^2 + v2^2 + v3^2))

It does not seem to look equal to (1,0,0)` however :/

edit flag offensive delete link more

Comments

Well, this is because full_simplify() is not what is needed. I am working on a solution and it starts with not using v.norm(), but explicitly defining T=v1^2 +v2^2 + v3^2 and using its sqrt(). This makes the result half understandable, but I need to find out more to get this solved.

Harald gravatar imageHarald ( 2018-08-26 18:48:16 +0100 )edit
0

answered 2018-08-26 19:58:04 +0100

Harald gravatar image

Here is how it works. In fact it is only slightly different from the above, but the two things that helped were canonicalize_radical() and mapping the simplify to the final vector.

v1 = var('v1');
v2 = var('v2');
v3 = var('v3');
e1 = vector([1,0,0]);
v = vector([v1, v2, v3]);
T=(v1^2 + v2^2 + v3^2);

u = v/sqrt(T); 
z=u.cross_product(e1);
c=u.dot_product(e1);

mat=Matrix( [[0, -z[3-1], z[2-1]], [z[3-1], 0, -z[1-1]], [-z[2-1], z[1-1], 0]] );
mrot=(matrix.identity(3) + mat + (1/(1+c)) * mat*mat);
mrot = mrot*sqrt(T);
mrot = mrot.apply_map(lambda e: e.canonicalize_radical());
view(["mrot*sqrt(T)", mrot])

e = mrot/sqrt(T)*u;
e = e.apply_map(lambda e: e.full_simplify())
e

Multiplying sqrt(T) into mrot and taking it out again when multiplying with u is only for better readability.

edit flag offensive delete link more

Your Answer

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

Add Answer

Question Tools

1 follower

Stats

Asked: 2018-08-25 22:40:11 +0100

Seen: 792 times

Last updated: Aug 26 '18