(Oddly enough, the title for another question that ended up dealing with an unrelated problem could have worked better here, but I didn't want to plagiarize.)
Given a symbolic vector function U[t] with independent variable t in an arbitrary number of dimensions, let f[U[t]]:=Normalize[U'[t]]. Then, one can succinctly define the unit tangent, normal, and binormal vectors as {T[t],N[t],B[t]}=NestList[f,U[t],3][[2;;]]. (Note that in this case, N does not refer to the built-in numerical approximation function; it's just an unfortunate coincidence in notation.) Although there's no reason why NestList has to stop at three layers, I have been having problems with going beyond such due to the size and complexity of the output, which I know can be greatly simplified. Here are the methods I have come up with so far, and the problems I have encountered with each of them:
- Using the given definition: This leads to instances of
Norm'[_], which prevents much of the simplification. - Adjusting the given definition: Changing the definition of
fto something likef[v_]:=#/Sqrt[#.#]&[Dt[v,t]]gets closer, butDotis neither distributive overPlusnor commutative, as Mathematica includes the possibility of the arguments toDotbeing rectangular matrices, which would indeed produce different results. - Using
Simplifyand the like: This takes a rather long time, given that the input expression is a 16-level fraction with square roots. - Using assumptions to indicate vectors:
Assuming[VectorQ[v],_]fails because lone variables that aren't explicitly lists are treated as scalars, makingVectorQ[v]evaluate toFalse. - Using patterns to indicate vectors: While using expressions like
{u__}is an intriguing possibility, when taking the derivative, Mathematica ends up producing the nonsensical expressionDerivative[1,0][Pattern][u,__]as a part of the result. - Adding the distributive-over-
Plusand commutative properties to the dot product: While the latter is easy enough to do via theOrderlessattribute, I have no idea how to do the former, given the aforementioned problems withVectorQ. (For the record, I'm talking abouta.(b+c)==a.b+a.c.) - Defining a substitute for the
Dotfunction with those properties: While the substitute function itself does not have to be defined, defining its properties would likely require reverse-engineering of theDotfunction, and especially how it interacts with theDtfunction, which might or might not be against the terms of the license, depending on whether the reverse-engineering or it being common mathematical knowledge takes precedence within the context of the license. - Defining a substitute for the
Dtfunction: This runs into the problem with attributes. - Doing everything manually: While I am better able to find repeating sub-patterns within the expressions myself than I am programming Mathematica to do it, the computer is far faster than me, and I'm sure I'll make a sign error or something somewhere.
Is there any way to fix any of these?
FIRST UPDATE: I ended up using a substitute Dot function and defining its attributes (aside from Orderless) through assignments (e.g. dot[a_,b_+c_]:=dot[a,b]+dot[a,c]). However, factoring expressions out over Times had been an issue, as incorrectly factoring out undotted instances of Derivative[_][U][t] would lead to the nonsensical result of a dot product between a scalar and a vector, or even between two scalars. Nevertheless, I found a possible way around this by adding a function i that encloses undotted instances of Derivative[_][U][t] as a sort of indicator, and serves as an identity function otherwise; it would finally disappear using the assignment of dot[i[a_],i[b_]]:=dot[a,b]. (In other words, one could use MatchQ[i] or FreeQ[i] on an expression as a substitute for the [non-functioning] VectorQ[expr].)
But now I've run into another issue that, on its face, seems bizarre. Consider the expression dot[2*i[U''[t]]*dot[U'[t],U'[t]],-2*i[U'[t]]*dot[U'[t],U''[t]]], an actual subexpression encountered for the unit normal vector. The assignment dot[a_,b_*c_?FreeQ[i]]:=c*dot[a,b] fails to do anything, due to MatchQ[-2*i[U'[t]]*dot[U'[t],U''[t]],b_*c_?FreeQ[i]] returning False (even if the test ?MemberQ[i] is added onto b_ in addition to or instead of the test on c_, and/or the positions of b_ and c_ are swapped with each other), despite the fact that all of the following return True:
MatchQ[-2*i[U'[t]]*dot[U'[t],U''[t]],b_*c_]MatchQ[-2*i[U'[t]]*dot[U'[t],U''[t]],b_*c_Integer]MatchQ[-2*i[U'[t]]*dot[U'[t],U''[t]],b_*c_?IntegerQ]
Now what is going on here?
SECOND UPDATE: Immediately after posting the previous update, I found that setting the assignment dot[a_,b_*c_/;FreeQ[c,i]]:=c*dot[a,b] actually does work in solving the second issue (and the whole problem in general), but this only makes that issue even more strange: what would allow FreeQ[dot[U'[t],U''[t]],i] and MatchQ[dot[U'[t],U''[t]],c_/;FreeQ[c,i]] to evaluate to True, yet force MatchQ[dot[U'[t],U''[t]],c_?FreeQ[i]], a supposedly identical expression, to evaluate to False?