Skip to main content

Stack Exchange Network

Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
Asked
Modified 2 days ago
Viewed 319 times
6
$\begingroup$

I study the behavior of spatial curves and it is very convenient to write curvature and torsion as pure functions (PF).
It is often necessary to obtain their combinations, integrals and differentiates as pure functions also.
For example, we have curvature as crv = Log[1+#]& or smth like this.
Fortunately crv' directly produce PF.
But further there are difficulties. For sphere there is an equation for torsion:

trs = crv'/(crv Sqrt[crv^2 - 1])

But we don’t get PF if we just put crv. In this post it is proposed to enter mergeF as

mergeF[expr_] := Function @@ (Hold[expr] /. Function[body_] :> body)

so mergeF[crv'/(crv Sqrt[crv^2 - 1])] produce needed result: 1/(Log[1 + #1] Sqrt[-1 + Log[1 + #1]^2] (1 + #1)) &

In other cases it is necessary to obtain an integral from crv also as PF.
I found only a naive way to do it, and same I found here:

intCrv = Evaluate[Integrate[crv[s], {s, 0, #}]] &

But it looks unnatural, and also gives an answer with conditions that I don’t need.
And if we try to integrate a combination of PF, everything is confused at all.

The question arises whether there is a universal natural way (not list of tricks for possible special cases) to operate with PF to get PF?

Clarification
Let $f_1, f_2, \dots$ - some simple enough scalar functions as pure functions in Mathematica.
We know that:

  • f' is a PF
  • Derivative[-1][f] is a PF (thanks to @xzczd)
  • If expr is a combination of PF then mergeF[expr] is PF

But I can’t figure out how to get PF universally as result from smth like this (and more complicated expressions):

$$\int \left(f_1 \cdot \left( \int f_2 \cdot f'_3 \right)\right)$$

$\endgroup$
7
  • 1
    $\begingroup$ Derivative[-1][crv] or Integrate[crv@#, #] // Evaluate // Function? $\endgroup$
    xzczd
    –  xzczd
    2025-10-15 08:13:26 +00:00
    Commented Oct 15 at 8:13
  • 2
    $\begingroup$ trs*crv // mergeF // Derivative[-1]? $\endgroup$
    xzczd
    –  xzczd
    2025-10-15 08:20:45 +00:00
    Commented Oct 15 at 8:20
  • 1
    $\begingroup$ It seems that full answer should contain a recursion of mergeF to resolve all expressions, but apparently this is difficult $\endgroup$
    lesobrod
    –  lesobrod
    2025-10-15 08:24:48 +00:00
    Commented Oct 15 at 8:24
  • 1
    $\begingroup$ Can you add an example on which the above approach doesn't work well? $\endgroup$
    xzczd
    –  xzczd
    2025-10-15 08:35:37 +00:00
    Commented Oct 15 at 8:35
  • 1
    $\begingroup$ People here generally like users to examples as copyable Mathematica code as well as images or TeX, so they can copy-paste it. It makes it convenient for them and more likely you will get someone to help you. You may find the meta Q&A, How to copy code from Mathematica so it looks good on this site, helpful $\endgroup$
    Michael E2
    –  Michael E2
    2025-10-15 14:56:08 +00:00
    Commented Oct 15 at 14:56

3 Answers 3

3
$\begingroup$

You seem to need a depth-first evaluation. I've done this before with a special head, but I don't know where the old code is, so I threw this together:

ClearAll[mergeF`myF];
mergeF`myF /: h_[a___, f_mergeF`myF, b___] := 
  Block[{mergeF`myF = Function}, mergeF[h[a, f, b]]];
ClearAll[mergeF];
mergeF[expr_Function] := expr; (* Function has bubbled to the top *)
mergeF[expr_] /; mergeF`myF === Function := (* myF has evaluated *)
  Function @@ (Hold[expr] /. Function[body_] :> body);
mergeF[expr_] /; ! FreeQ[expr, Function] := 
  mergeF[expr /. Function -> mergeF`myF];
mergeF[expr_] := expr &; (* no Function; give error msg instead? *)

{f1, f2, f3} = {3 + # &, #^7 &, Log[1 + #] &};
Derivative[-1][f1*Derivative[-1][f2 *f3]] // mergeF
(*
1/604800#1 (171360 + 141120 #1 - 18480 #1^2 + 13860 #1^3 - 
     9828 #1^4 + 7350 #1^5 - 5760 #1^6 + 4680 #1^7 - 3910 #1^8 - 
     1701 #1^9) + 
  1/240 Log[1 + #1] (-68 - 90 #1 - 15 #1^2 + 10 #1^9 + 3 #1^10) &
*)
$\endgroup$
2
  • $\begingroup$ I think it should be f2 *f3'? :) $\endgroup$
    xzczd
    –  xzczd
    2025-10-15 15:03:21 +00:00
    Commented Oct 15 at 15:03
  • $\begingroup$ Aha, looks like what I meant, thank you! I should study this $\endgroup$
    lesobrod
    –  lesobrod
    2025-10-15 15:04:49 +00:00
    Commented Oct 15 at 15:04
2
$\begingroup$

Here's my solution (just an update for Kuba's answer):

Clear@mergeF; 
mergeF[expr_] := 
 Function @@ {expr //. {Derivative[i_][h_] :> Derivative[i][mergeF@h],
      Function[body_] :> body}};
int = Derivative[-1];

{f1, f2, f3} = {3 + # &, #^7 &, Log[1 + #] &};
  
int[f1 int[f2 f3']] // mergeF
(* -(1/2) Log[1 + #1] (5 + 6 #1 + #1^2) + 1/
  5040#1 (12600 + 8820 #1 - 840 #1^2 + 630 #1^3 - 420 #1^4 + 
     294 #1^5 - 216 #1^6 + 165 #1^7 + 80 #1^8) & *)
$\endgroup$
2
  • $\begingroup$ Hmm that's cool! May be better with Module with int encapsulated? $\endgroup$
    lesobrod
    –  lesobrod
    2025-10-15 15:07:36 +00:00
    Commented Oct 15 at 15:07
  • $\begingroup$ @lesobrod I think it's better to keep int global so one can do something like f1 // int. $\endgroup$
    xzczd
    –  xzczd
    2025-10-15 15:09:33 +00:00
    Commented Oct 15 at 15:09
0
$\begingroup$
mergeF[expr_] := Module[{result},
  result = expr /. Function[a_] -> Function[a][#];
  result = Evaluate[result] &;
  result
  ]
crv = Log[1 + #] &
expr = crv'/(crv Sqrt[crv^2 - 1])
expr // mergeF
Derivative[-1][result] result // mergeF

Result: $$\frac{1}{(\text{$\#$1}+1) \log (\text{$\#$1}+1) \sqrt{\log ^2(\text{$\#$1}+1)-1}}\&$$ $$\frac{\tan ^{-1}\left(\sqrt{\log ^2(\text{$\#$1}+1)-1}\right)}{(\text{$\#$1}+1) \log (\text{$\#$1}+1) \sqrt{\log ^2(\text{$\#$1}+1)-1}}\&$$

Explanation

In simplifying these expressions we implicitly assume these functions have the same argument. To see what I mean, let's say you have the functions $f(x)=x^2$ and $g(y)=1/y$. If you take the product $f\cdot g$, you can either interpret it as a new function with two variables, $f(x)g(y)=x^2/y$, or you can assume point wise multiplication, $f(x)g(x)=x$. Since we assume the latter, we are well justified to simply evaluate every function at some variable, and then re-interpret the result as a function. The cleanest way to do this is by evaluating at $\#$.

Note: This version also works with functions like Function[x, x^2]. If you only want to work with pure functions of the form #^2&, Kuba's answer also works.

$\endgroup$

Your Answer

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.