(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 f to something like f[v_]:=#/Sqrt[#.#]&[Dt[v,t]] gets closer, but Dot is neither distributive over Plus nor commutative, as Mathematica includes the possibility of the arguments to Dot being rectangular matrices, which would indeed produce different results.
  • Using Simplify and 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, making VectorQ[v] evaluate to False.
  • Using patterns to indicate vectors: While using expressions like {u__} is an intriguing possibility, when taking the derivative, Mathematica ends up producing the nonsensical expression Derivative[1,0][Pattern][u,__] as a part of the result.
  • Adding the distributive-over-Plus and commutative properties to the dot product: While the latter is easy enough to do via the Orderless attribute, I have no idea how to do the former, given the aforementioned problems with VectorQ. (For the record, I'm talking about a.(b+c)==a.b+a.c.)
  • Defining a substitute for the Dot function with those properties: While the substitute function itself does not have to be defined, defining its properties would likely require reverse-engineering of the Dot function, and especially how it interacts with the Dt function, 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 Dt function: 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?



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.