# Simplify vector vs. its norm

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 close merge delete

Sort by » oldest newest most voted

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.

more

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

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)

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);
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.

more

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

more

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.