Maxima: Simplify expressions containing minimum - maxima

I am trying to use Maxima to simplify mathematical expressions involving min(a, b). Say I have defined
z = min(x1, x2) and d = abs(x1 - x2), then the identities x1 * x2 = z*(z+d) and x1 + x2 = 2*z + d follow.
For example, take the following expression:
(2*z^3+(−3*x2−3*x1)*z^2+6*x1*x2*z)/6
If I manually apply the above identities, I can simplify it to
z^3 / 3 + (z^2 * d) / 2
In Maxima, naively trying
subst(min(x1, x2), v, ((6*v*x1−3*v^2)*x2−3*v^2*x1+2*v^3)/6), ratsimp
Produces a long expression.
How can I make Maxima find the occurrences of x1 * x2 and x1 + x2 buried deep inside the expression? I have tried various forms of tellsimp, let and letsimp, for example:
let(x1*x2, z * (z+d))
or
let(K * x1*x2, K * z * (z + d), K, integer)
or
matchdeclare(R, true)
let(R * x1*x2 * z, R * z * (z+d))
How can I make Maxima produce the nice short expression that I can manually arrive at? I need to work with much larger expressions.

May be this is helpful,
load("lrats");
lratsubst([x1*x2=z*(z+d),x1+x2=2*z+d],
(2*z^3+(−3*x2−3*x1)*z^2+6*x1*x2*z)/6)
(2*z^3+3*d*z^2)/6
Also if you want to test your identities, you could do
z(x1,x2):=min(x1,x2)$
d(x1,x2):=abs(x1-x2)$
Now put numerical values say, z(2,3)*(z(2,3)+d(2,3))=6. Apparently these don't help in simplifying your expression.

Related

Function return tuple and the result is assigned to new variables

I've just started learning F# very recently. I have a function which counts the coefficients of the linear equation: y = ax + b, based on coordinates of two points P1(x1, y1), P2(x1, y2). The function looks like this:
module LinearFit
let generate(x1 : double, y1 : double, x2 : double, y2 : double) =
let w = x1 * 1.0 - x2 * 1.0
let wa = y1 * 1.0 - y2 * 1.0
let wb = x1 * y2 - x2 * y1
printfn "w: %g" w
printfn "wa: %g" wa
printfn "wb: %g" wb
let a = wa/w
let b = wb/w
printfn "a: %g" a
printfn "b: %g" b
printfn "%g %g" a b
(a, b)
I'm trying to somehow return founded coefficients as a tuple result and then assign the result to the new variables so later I can use the result to do some other operations. The trivial thing, for now, would be just displayed a result like:
The generated function is y = 2.5x - 6.5
So far I was trying to do sth like this
open System
let main() =
printf "Linear fit"
(a: double, b: double) <- LinearFit.generate(5.0, 6.0, 7.0, 11.0)
printfn "The generated functi..."
main()
Console.ReadKey() |> ignore
This is only a concept as I'm not even able to compile the project as im getting errors:
"Unexpected symbol ',' in expression"
"Unexpected symbol ')' in binding."
I tried to find some similar approach to C#...
For now what I want to achieve is just to assing the result of generate function to some variables. In C# it would look just like
public (double a, double b) Generate(some params here)
{
// some logic here
return (a, b);
}
(var a, var b) = Generate(...);
Any ideas?
You're making several syntactic mistakes.
First, the arrow-left operator <- is destructive update. It takes a mutable variable on the right and an expression on the left, and pushes the value of the expression into the variable. For example:
let mutable x = 5
x <- 42
In your example, neither a nor b are mutable variables that exist by the time you're trying to use the <- operator. Plus, the operator expects a single mutable variable, not a pattern.
Second, the way to declare new variables in F# is with let. It is roughly equivalent to var in C#, except you can declare multiple variables at once by putting them in a pattern. For example:
let x = 42
let pair = (1, 5)
let a, b = pair
Here, on the last line, I'm declaring two variables a and b by destructuring the pair.
In your example, you're trying to introduce the two new variables a and b without a let keyword. This is not allowed.
So, putting all of the above together, this is the right way to do what you're trying to do:
let main() =
printf "Linear fit"
let a, b = LinearFit.generate(5.0, 6.0, 7.0, 11.0)
printfn "The generated functi..."
P.S. Your question betrays a misunderstanding of some pretty basic principles of F# syntax. Because of this, I would recommend that you read through tutorials, examples, and other articles on F# to familiarize yourself with the syntax before attempting to venture farther.

Functional increment

I am working on a simple function that should, given x, return a tuple (y, z) such that y <= abs(5) + z * 10 = x, where z the smallest possible value.
In C, I would loop over z++ and y++, until their sum matches x.
Currently, I am trying to solve this problem functionally. Please consider the following example:
let foo x =
let rec aux (y, z, q) =
match (y + z * 10) with
q -> (y, z)
|_ -> aux(y + 1, z + 1, q) //How to correctly set the increments?
aux(0, 0, x)
This approach always returns (0, 0), no matter what. I referred to this question, while thinking a solution. I am aware that mutable variables should be avoided, and that is what I do. Unfortunately, I am afraid I missed the point, somewhere, thus I am approaching the problem from the wrong side.
You're introducing a new q binding for the result of the expression evaluated in your first case match rather than comparing against it. What you want is something like this:
match (y + z * 10) with
| r when r = q -> (y, z)
| _ -> aux(y + 1, z + 1, q)
In F# you are generally either within a value expression or a pattern matching expression. When you do this:
match (y + z * 10) with
q -> (y, z)
You're effectively saying: "Calculate y + z * 10 and then always assign the result to a new variable q, ignore this new variable and return (y, z)". This is because q is written in a pattern matching expression as it's just after with.
This is also why you're getting a warning on the next line saying "This rule will never by matched". This is a very common misunderstanding when people are learning F#.
You're not really making use of pattern matching at all when you do this. So I would recommend using an if expression instead:
if y + z * 10 = q
then (y, z)
else aux (y + 1, z + 1, q)
This is actually equivalent to using the ternary operators ? and : in C because it's an expression, not a statement, but it reads more clearly.

How do achieve the below function composition in point free style?

The below is in an F# code snippet where I am trying to remove reliance on the input parameters and perform some sort of function composition:
let h x1 x2 = (*) (exp x1) (sin x2) // how to reduce to point free style
I have tried:
let h1 = (*) exp sin
let h2 = exp * sin
let h3 = ((*) << exp) << sin
Compiler not happy with the first two and the last doesn't yield the desired result.
I am in fact trying to solve the more general problem of function composition (using whatever tools F# has available) summarised as follows:
f1: float -> float
f2: float -> float
f3: float -> float -> float
How to construct h = f3(f1(x),f2(y)) represented mathematically.

Currying and multiple integrals

I am interested in learning an elegant way to use currying in a functional programming language to numerically evaluate multiple integrals. My language of choice is F#.
If I want to integrate f(x,y,z)=8xyz on the region [0,1]x[0,1]x[0,1] I start by writing down a triple integral of the differential form 8xyz dx dy dz. In some sense, this is a function of three ordered arguments: a (float -> float -> float -> float).
I take the first integral and the problem reduces to the double integral of 4xy dx dy on [0,1]x[0,1]. Conceptually, we have curried the function to become a (float -> float -> float).
After the second integral I am left to take the integral of 2x dx, a (float -> float), on the unit interval.
After three integrals I am left with the result, the number 1.0.
Ignoring optimizations of the numeric integration, how could I succinctly execute this? I would like to write something like:
let diffForm = (fun x y z -> 8 * x * y * z)
let result =
diffForm
|> Integrate 0.0 1.0
|> Integrate 0.0 1.0
|> Integrate 0.0 1.0
Is this doable, if perhaps impractical? I like the idea of how closely this would capture what is going on mathematically.
I like the idea of how closely this would capture what is going on mathematically.
I'm afraid your premise is false: The pipe operator threads a value through a chain of functions and is closely related to function composition. Integrating over an n-dimensional domain however is analogous to n nested loops, i.e. in your case something like
for x in x_grid_nodes do
for y in y_grid_nodes do
for z in z_grid_nodes do
integral <- integral + ... // details depend on integration scheme
You cannot easily map that to a chain of three independet calls to some Integrate function and thus the composition integrate x1 x2 >> integrate y1 y2 >> integrate z1 z2 is actually not what you do when you integrate f. That is why Tomas' solution—if I understood it correctly (and I am not sure about that...)—essentially evaluates your function on an implicitly defined 3D grid and passes that to the integration function. I suspect that is as close as you can get to your original question.
You did not ask for it, but if you do want to evaluate a n-dimensional integral in practice, look into Monte Carlo integration, which avoids another problem commonly known as the "curse of dimensionality", i.e. that fact that the number of required sample points grows exponentially with n with classic integration schemes.
Update
You can implement iterated integration, but not with a single integrate function, because the type of the function to be integrated is different for each step of the integration (i.e. each step turns an n-ary function to an (n - 1)-ary one):
let f = fun x y z -> 8.0 * x * y * z
// numerically integrate f on [x1, x2]
let trapRule f x1 x2 = (x2 - x1) * (f x1 + f x2) / 2.0
// uniform step size for simplicity
let h = 0.1
// integrate an unary function f on a given discrete grid
let integrate grid f =
let mutable integral = 0.0
for x1, x2 in Seq.zip grid (Seq.skip 1 grid) do
integral <- integral + trapRule f x1 x2
integral
// integrate a 3-ary function f with respect to its last argument
let integrate3 lower upper f =
let grid = seq { lower .. h .. upper }
fun x y -> integrate grid (f x y)
// integrate a 2-ary function f with respect to its last argument
let integrate2 lower upper f =
let grid = seq { lower .. h .. upper }
fun x -> integrate grid (f x)
// integrate an unary function f on [lower, upper]
let integrate1 lower upper f =
integrate (seq { lower .. h .. upper }) f
With your example function f
f |> integrate3 0.0 1.0 |> integrate2 0.0 1.0 |> integrate1 0.0 1.0
yields 1.0.
I'm not entirely sure how you would implement this in a normal way, so this might not fully solve the problem, but here are some ideas.
To do the numerical integration, you'll (I think?) need to call the original function diffForm at various points as specified by the Integrate calls in the pipeline - but you actually need to call it at a product of the ranges - so if I wanted to call it only at the borders, I would still need to call it 2x2x2 times to cover all possible combinations (diffForm 0 0 0, diffForm 0 0 1, diffForm 0 1 0 etc.) and then do some calcualtion on the 8 results you get.
The following sample (at least) shows how to write similar code that calls the specified function with all combinations of the argument values that you specify.
The idea is to use continuations which can be called multiple times (and so when we get a function, we can call it repeatedly at multiple different points).
// Our original function
let diffForm x y z = 8.0 * x * y * z
// At the first step, we just pass the function to a continuation 'k' (once)
let diffFormK k = k diffForm
// This function takes a function that returns function via a continuation
// (like diffFormK) and it fixes the first argument of the function
// to 'lo' and 'hi' and calls its own continuation with both options
let range lo hi func k =
// When called for the first time, 'f' will be your 'diffForm'
// and here we call it twice with 'lo' and 'hi' and pass the
// two results (float -> float -> float) to the next in the pipeline
func (fun f -> k (f lo))
func (fun f -> k (f hi))
// At the end, we end up with a function that takes a continuation
// and it calls the continuation with all combinations of results
// (This is where you need to do something tricky to aggregate the results :-))
let integrate result =
result (printfn "%f")
// Now, we pass our function to 'range' for every argument and
// then pass the result to 'integrate' which just prints all results
let result =
diffFormK
|> range 0.0 1.0
|> range 0.0 1.0
|> range 0.0 1.0
|> integrate
This might be pretty confusing (because continuations take a lot of time to get used to), but perhaps you (or someone else here?) can find a way to turn this first attempt into a real numerical integration :-)

Unification by transformation

I am writing a unification algorithm in F# for use with AST transformations using "Term Rewriting and All That" (WoldCat) by Franz Baader and Tobias Nipkow. For section 4.6 Unification by transformation, it was too much math theory with the examples, and not as clear as I would have liked.
Can someone give or point out simpler examples that make use of transformations:
Delete, Decompose, Orient, Eliminate.
Delete: t = t is pointless and can be removed from the set of equations.
1 =? 1 -> nil
Orient: We want all equations in the form of x =? t, so flip any equations in the form of t =? x.
2 =? x1 -> x1 =? 2
Eliminate: Given x =? t, change all other equations to replace all instances of x with t.
x1 + x2 = 7, x2 = 5 -> x1 + 5 = 7, x2 = 5
Decompose: We need to take any functions and eliminate them to get equations in the form of x =? t. Note that this process technically only removes one function at a time.
x1 + 5 = 7 -> x1 = 2
2 * (x1 + x2) = 14 -> x1 + x2 = 7
Hopefully this helps.

Resources