Ask Your Question
0

Simplify vector vs. its norm

asked 6 years ago

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);
Preview: (hide)

3 Answers

Sort by » oldest newest most voted
1

answered 6 years ago

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.

Preview: (hide)
link

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 ( 6 years ago )

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 ( 6 years ago )
0

answered 6 years ago

tmonteil gravatar image

updated 6 years ago

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 :/

Preview: (hide)
link

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 ( 6 years ago )
0

answered 6 years ago

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.

Preview: (hide)
link

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: 6 years ago

Seen: 869 times

Last updated: Aug 26 '18