Mathematica: Compile NSolve, NMinimize and other numerical functions - compilation

Is there a way to compile those functions using Compile[]? it seems that Mathematica always fails in that.
I have purely numerical functions inside NSolve and NMinimize, and it still doesn't work.
A tiny example is:
tempfunc = Compile[{}, NSolve[x^2 - 5 x + 6 == 0, x]]
tempfunc[]
This would give an error...
Any idea how to compile those functions and make them much faster?

It seems this is not possible. Evaluate:
Compile`CompilerFunctions[] // Sort
This will give list of "compilable" functions. On Mathematica 10.3 it will give:
{Abs, AddTo, And, Append, AppendTo, Apply, ArcCos, ArcCosh, ArcCot, ArcCoth,
ArcCsc, ArcCsch, ArcSec, ArcSech, ArcSin, ArcSinh, ArcTan, ArcTanh, Arg,
Array, ArrayDepth, Internal`Bag, Internal`BagPart, BitAnd, BitNot, BitOr,
BitXor, Block, BlockRandom, Boole, Break, Cases, Catch, Ceiling, Chop,
Internal`CompileError, System`Private`CompileSymbol, Complement,
ComposeList, CompoundExpression, Conjugate, ConjugateTranspose, Continue,
Cos, Cosh, Cot, Coth, Count, Csc, Csch, Decrement, Delete, DeleteCases,
Dimensions, Divide, DivideBy, Do, Dot, Drop, Equal, Erf, Erfc, EvenQ, Exp,
Fibonacci, First, FixedPoint, FixedPointList, Flatten,
NDSolve`FEM`FlattenAll, Floor, Fold, FoldList, For, FractionalPart, FreeQ,
Gamma, Compile`GetElement, Goto, Greater, GreaterEqual, Gudermannian,
Haversine, If, Im, Implies, Increment, Indexed, Inequality, Compile`InnerDo,
Insert, IntegerDigits, IntegerPart, Intersection, InverseGudermannian,
InverseHaversine, Compile`IteratorCount, Join, Label, Last, Length, Less,
LessEqual, List, Log, Log10, Log2, LogGamma, LogisticSigmoid, LucasL, Map,
MapAll, MapAt, MapIndexed, MapThread, NDSolve`FEM`MapThreadDot, MatrixQ,
Max, MemberQ, Min, Minus, Mod, Compile`Mod1, Module, Most, N, Negative,
Nest, NestList, NonNegative, Not, OddQ, Or, OrderedQ, Out, Outer, Part,
Partition, Piecewise, Plus, Position, Positive, Power, PreDecrement,
PreIncrement, Prepend, PrependTo, Product, Quotient, Random, RandomChoice,
RandomComplex, RandomInteger, RandomReal, RandomSample, RandomVariate,
Range, Re, Internal`ReciprocalSqrt, ReplacePart, Rest, Return, Reverse,
RotateLeft, RotateRight, Round, RuleCondition, SameQ, Scan, Sec, Sech,
SeedRandom, Select, Set, SetDelayed, Compile`SetIterate, Sign, Sin, Sinc,
Sinh, Sort, Sqrt, Internal`Square, Internal`StuffBag, Subtract,
SubtractFrom, Sum, Switch, Table, Take, Tan, Tanh, TensorRank, Throw, Times,
TimesBy, Tr, Transpose, Unequal, Union, Unitize, UnitStep, UnsameQ, VectorQ,
Which, While, With, Xor}
I tried
cnm = Compile[{{a, _Real}},
Block[{v, r},
{v, r} = NMinimize[2 x^2 + x - a, x];
{v, x /. r}
]
]
and result is evaluation of non compiled Mathematica code:
In[35]:= cnm[2]
During evaluation of In[35]:= CompiledFunction::cfse: Compiled expression {-2.125,{x->-0.25}} should be a machine-size real number. >>
During evaluation of In[35]:= CompiledFunction::cfex: Could not complete external evaluation at instruction 1; proceeding with uncompiled evaluation. >>
Out[35]= {-2.125, -0.25}

Related

How can I verify if a coordinate is in a list

I'm generating random coordinates and adding on my list, but first I need verify if that coordinate already exists. I'm trying to use member but when I was debugging I saw that isn't working:
My code is basically this:
% L is a list and Q is a count that define the number of coordinate
% X and Y are the coordinate members
% check if the coordniate already exists
% if exists, R is 0 and if not, R is 1
createCoordinates(L,Q) :-
random(1,10,X),
random(1,10,Y),
convertNumber(X,Z),
checkCoordinate([Z,Y],L,R),
(R is 0 -> print('member'), createCoordinates(L,Q); print('not member'),createCoordinates(L,Q-1).
checkCoordinate(C,L,R) :-
(member(C,L) -> R is 0; R is 1).
% transforms the number N in a letter L
convertNumber(N,L) :-
N is 1, L = 'A';
N is 2, L = 'B';
...
N is 10, L = 'J'.
%call createCoordinates
createCoordinates(L,20).
When I was debugging this was the output:
In this picture I'm in the firts interation and L is empty, so R should be 1 but always is 0, the coordinate always is part of the list.
I have the impression that the member clause is adding the coordinate at my list and does'nt make sense
First off, I would recommend breaking your problem down into smaller pieces. You should have a procedure for making a random coordinate:
random_coordinate([X,Y]) :-
random(1, 10, XN), convertNumber(XN, X),
random(1, 10, Y).
Second, your checkCoordinate/3 is converting Prolog's success/failure into an integer, which is just busy work for Prolog and not really improving life for you. memberchk/2 is completely sufficient to your task (member/2 would work too but is more powerful than necessary). The real problem here is not that member/2 didn't work, it's that you are trying to build up this list parameter on the way out, but you need it to exist on the way in to examine it.
We usually solve this kind of problem in Prolog by adding a third parameter and prepending values to the list on the way through. The base case then equates that list with the outbound list and we protect the whole thing with a lower-arity procedure. In other words, we do this:
random_coordinates(N, Coordinates) :- random_coordinates(N, [], Coordinates).
random_coordinates(0, Result, Result).
random_coordinates(N, CoordinatesSoFar, FinalResult) :- ...
Now that we have two things, memberchk/2 should work the way we need it to:
random_coordinates(N, CoordinatesSoFar, FinalResult) :-
N > 0, succ(N0, N), % count down, will need for recursive call
random_coordinate(Coord),
(memberchk(Coord, CoordinatesSoFar) ->
random_coordinates(N, CoordinatesSoFar, FinalResult)
;
random_coordinates(N0, [Coord|CoordinatesSoFar], FinalResult)
).
And this seems to do what we want:
?- random_coordinates(10, L), write(L), nl.
[[G,7],[G,3],[H,9],[H,8],[A,4],[G,1],[I,9],[H,6],[E,5],[G,8]]
?- random_coordinates(10, L), write(L), nl.
[[F,1],[I,8],[H,4],[I,1],[D,3],[I,6],[E,9],[D,1],[C,5],[F,8]]
Finally, I note you continue to use this syntax: N is 1, .... I caution you that this looks like an error to me because there is no distinction between this and N = 1, and your predicate could be stated somewhat tiresomely just with this:
convertNumber(1, 'A').
convertNumber(2, 'B').
...
My inclination would be to do it computationally with char_code/2 but this construction is actually probably better.
Another hint that you are doing something wrong is that the parameter L to createCoordinates/2 gets passed along in all cases and is not examined in any of them. In Prolog, we often have variables that appear to just be passed around meaninglessly, but they usually change positions or are used multiple times, as in random_coordinates(0, Result, Result); while nothing appears to be happening there, what's actually happening is plumbing: the built-up parameter becomes the result value. Nothing interesting is happening to the variable directly there, but it is being plumbed around. But nothing is happening at all to L in your code, except it is supposedly being checked for a new coordinate. But you're never actually appending anything to it, so there's no reason to expect that anything would wind up in L.
Edit Notice that #lambda.xy.x solves the problem in their answer by prepending the new coordinate in the head of the clause and examining the list only after the recursive call in the body, obviating the need for the second list parameter.
Edit 2 Also take a look at #lambda.xy.x's other solution as it has better time complexity as N approaches 100.
Since i had already written it, here is an alternative solution: The building block is gen_coord_notin/2 which guarantees a fresh solution C with regard to an exclusion list Excl.
gen_coord_notin(C, Excl) :-
random(1,10,X),
random(1,10,Y),
( memberchk(X-Y, Excl) ->
gen_coord_notin(C, Excl)
;
C = X-Y
).
The trick is that we only unify C with the new result, if it is fresh.
Then we only have to fold the generations into N iterations:
gen_coords([], 0).
gen_coords([X|Xs], N) :-
N > 0,
M is N - 1,
gen_coords(Xs, M),
gen_coord_notin(X, Xs).
Remark 1: since coordinates are always 2-tuples, a list representation invites unwanted errors (e.g. writing [X|Y] instead of [X,Y]). Traditionally, an infix operator like - is used to seperate tuples, but it's not any different than using coord(X,Y).
Remark 2: this predicate is inherently non-logical (i.e. calling gen_coords(X, 20) twice will result in different substitutions for X). You might use the meta-level predicates var/1, nonvar/1, ground/1, integer, etc. to guard against non-sensical calls like gen_coord(1-2, [1-1]).
Remark 3: it is also important that the conditional does not have multiple solutions (compare member(X,[A,B]) and memberchk(X,[A,B])). In general, this can be achieved by calling once/1 but there is a specialized predicate memberchk/2 which I used here.
I just realized that the performance of my other solutions is very bad for N close to 100. The reason is that with diminishing possible coordinates, the generate and test approach will take longer and longer. There's an alternative solution which generates all coordinates and picks N random ones:
all_pairs(Ls) :-
findall(X-Y, (between(1,10,X), between(1,10,Y)), Ls).
remove_index(X,[X|Xs],Xs,0).
remove_index(I,[X|Xs],[X|Rest],N) :-
N > 0,
M is N - 1,
remove_index(I,Xs,Rest,M).
n_from_pool(_Pool, [], 0).
n_from_pool(Pool, [C|Cs], N) :-
N > 0,
M is N - 1,
length(Pool, L),
random(0,L,R),
remove_index(C,Pool,NPool,R),
n_from_pool(NPool, Cs, M).
gen_coords2(Xs, N) :-
all_pairs(Pool),
n_from_pool(Pool, Xs, N).
Now the query
?- gen_coords2(Xs, 100).
Xs = [4-6, 5-6, 5-8, 9-6, 3-1, 1-3, 9-4, 6-1, ... - ...|...] ;
false.
succeeds as expected. The error message
?- gen_coords2(Xs, 101).
ERROR: random/1: Domain error: not_less_than_one' expected, found0'
when we try to generate more distinct elements than possible is not nice, but better than non-termination.

Not able to reach base case in fibonacci sequence

I'm quite new to Prolog, and this way of thinking is kind of messing with my mind. I'm currently using SWI-Prolog to run and debug my code. I have implemented a tail recursive algorithm to solve the N'th fibonnaci-number. I have tried debugging step by step, and I cannot explain why my implementation is skipping the base case. Where am I thinking wrong?
fib(0, A,_, A). %Base case, when we reach N = 0, return.
%Tail recursion. Use N as counter, iterate until base value (N=0) is reached.
fib(N, A, B, F) :-
Nnew is N - 1,
Sum is (A + B),
fib(Nnew, B, Sum, F).
fib(N, F) :-
fib(N, 0, 1, F). %set start values for when fib(N,F). is called
My implementation is working great (and fast) if I want to calculate the nth fib number. For example, if I run ?- fib(5,F)., I get F = 5 back. Great. If I want to check ?- fib(5,5). I get True back, which is correct. Great.
But, if I input a false statement, for example: ?- fib(5,4). then the program is looping forever. What happens is that N passes 0, ignores the base case(?), and continues on to be decremented. Why is the base case skipped? In my eyes, fib(0,A,_,A). is satisfied. Where am I wrong?
You should add the condition N>0 to the second clause of your predicate fib/3, otherwise the predicate fib/3 will continue trying with the negative numbers if the base-case fails. Lets see the case when you consult ?- fib(0,1):
This case will unified the second clause fib(0,0,1,1), where Nnew will be instantiated to the value -1. From here Nnew will be infinitely decremented, and the base-case will never be unified.
Any other false case, like ?- fib(5,4) will try to decrement N until the base case is unified, and that won't happen unless after 5 iteration, the sum of the fibonacci numbers are equal to 4. So, there's is no point on try with more attempts.

Prompt does not come back

I try to do some exercise - to represent numbers in "s representation" which means '0' is zero, s(0) is 1, s(s(0)) is 2 and so on.
I tried to write predicate for adding "s numbers":
the predicate s2int convert "s number" to int.
s2int(0, 0).
s2int(s(X), Y) :-
s2int(X, Y1),
Y is 1 + Y1.
add(X, Y, Z) :-
s2int(X, SX),
s2int(Y, SY),
s2int(Z, SZ),
SZ is SX + SY.
When I query add it writes the correct answer but the prompt does not come back.
What's the problem?
Your definition of add/3 works fine, and also terminates, if all three arguments are given. If you leave one of them as a variable, one of the goals s2int(XYZ, SXYZ) has then two uninstantiated variables as arguments. It describes thus an infinitely large set, whose complete enumeration takes infinitely long.
Not sure what you are after, but probably you want to define add/3 for successor arithmetics. You can do this, without resorting to the 0,1,2 integers! Try it! Otherwise search of successor-arithmetics.

Best way to do an iteration scheme

I hope this hasn't been asked before, if so I apologize.
EDIT: For clarity, the following notation will be used: boldface uppercase for matrices, boldface lowercase for vectors, and italics for scalars.
Suppose x0 is a vector, A and B are matrix functions, and f is a vector function.
I'm looking for the best way to do the following iteration scheme in Mathematica:
A0 = A(x0), B0=B(x0), f0 = f(x0)
x1 = Inverse(A0)(B0.x0 + f0)
A1 = A(x1), B1=B(x1), f1 = f(x1)
x2 = Inverse(A1)(B1.x1 + f1)
...
I know that a for-loop can do the trick, but I'm not quite familiar with Mathematica, and I'm concerned that this is the most efficient way to do it. This is a justified concern as I would like to define a function u(N):=xNand use it in further calculations.
I guess my questions are:
What's the most efficient way to program the scheme?
Is RecurrenceTable a way to go?
EDIT
It was a bit more complicated than I tought. I'm providing more details in order to obtain a more thorough response.
Before doing the recurrence, I'm having problems understanding how to program the functions A, B and f.
Matrices A and B are functions of the time step dt = 1/T and the space step dx = 1/M, where T and M are the number of points in the {0 < x < 1, 0 < t} region. This is also true for vector the function f.
The dependance of A, B and f on x is rather tricky:
A and B are upper and lower triangular matrices (like a tridiagonal matrix; I suppose we can call them multidiagonal), with defined constant values on their diagonals.
Given a point 0 < xs < 1, I need to determine it's representative xn in the mesh (the closest), and then substitute the nth row of A and B with the function v( x) (transposed, of course), and the nth row of f with the function w( x).
Summarizing, A = A(dt, dx, xs, x). The same is true for B and f.
Then I need do the loop mentioned above, to define u( x) = step[T].
Hope I've explained myself.
I'm not sure if it's the best method, but I'd just use plain old memoization. You can represent an individual step as
xstep[x_] := Inverse[A[x]](B[x].x + f[x])
and then
u[0] = x0
u[n_] := u[n] = xstep[u[n-1]]
If you know how many values you need in advance, and it's advantageous to precompute them all for some reason (e.g. you want to open a file, use its contents to calculate xN, and then free the memory), you could use NestList. Instead of the previous two lines, you'd do
xlist = NestList[xstep, x0, 10];
u[n_] := xlist[[n]]
This will break if n > 10, of course (obviously, change 10 to suit your actual requirements).
Of course, it may be worth looking at your specific functions to see if you can make some algebraic simplifications.
I would probably write a function that accepts A0, B0, x0, and f0, and then returns A1, B1, x1, and f1 - say
step[A0_?MatrixQ, B0_?MatrixQ, x0_?VectorQ, f0_?VectorQ] := Module[...]
I would then Nest that function. It's hard to be more precise without more precise information.
Also, if your procedure is numerical, then you certainly don't want to compute Inverse[A0], as this is not a numerically stable operation. Rather, you should write
A0.x1 == B0.x0+f0
and then use a numerically stable solver to find x1. Of course, Mathematica's LinearSolve provides such an algorithm.

Problem performing a substitution in a multiple derivative

I have a basic problem in Mathematica which has puzzled me for a while. I want to take the m'th derivative of x*Exp[t*x], then evaluate this at x=0. But the following does not work correct. Please share your thoughts.
D[x*Exp[t*x], {x, m}] /. x -> 0
Also what does the error mean
General::ivar: 0 is not a valid variable.
Edit: my previous example (D[Exp[t*x], {x, m}] /. x -> 0) was trivial. So I made it harder. :)
My question is: how to force it to do the derivative evaluation first, then do substitution.
As pointed out by others, (in general) Mathematica does not know how to take the derivative an arbitrary number of times, even if you specify that number is a positive integer.
This means that the D[expr,{x,m}] command remains unevaluated and then when you set x->0, it's now trying to take the derivative with respect to a constant, which yields the error message.
In general, what you want is the m'th derivative of the function evaluated at zero.
This can be written as
Derivative[m][Function[x,x Exp[t x]]][0]
or
Derivative[m][# Exp[t #]&][0]
You then get the table of coefficients
In[2]:= Table[%, {m, 1, 10}]
Out[2]= {1, 2 t, 3 t^2, 4 t^3, 5 t^4, 6 t^5, 7 t^6, 8 t^7, 9 t^8, 10 t^9}
But a little more thought shows that you really just want the m'th term in the series, so SeriesCoefficient does what you want:
In[3]:= SeriesCoefficient[x*Exp[t*x], {x, 0, m}]
Out[3]= Piecewise[{{t^(-1 + m)/(-1 + m)!, m >= 1}}, 0]
The final output is the general form of the m'th derivative. The PieceWise is not really necessary, since the expression actually holds for all non-negative integers.
Thanks to your update, it's clear what's happening here. Mathematica doesn't actually calculate the derivative; you then replace x with 0, and it ends up looking at this:
D[Exp[t*0],{0,m}]
which obviously is going to run into problems, since 0 isn't a variable.
I'll assume that you want the mth partial derivative of that function w.r.t. x. The t variable suggests that it might be a second independent variable.
It's easy enough to do without Mathematica: D[Exp[t*x], {x, m}] = t^m Exp[t*x]
And if you evaluate the limit as x approaches zero, you get t^m, since lim(Exp[t*x]) = 1. Right?
Update: Let's try it for x*exp(t*x)
the mth partial derivative w.r.t. x is easily had from Wolfram Alpha:
t^(m-1)*exp(t*x)(t*x + m)
So if x = 0 you get m*t^(m-1).
Q.E.D.
Let's see what is happening with a little more detail:
When you write:
D[Sin[x], {x, 1}]
you get an expression in with x in it
Cos[x]
That is because the x in the {x,1} part matches the x in the Sin[x] part, and so Mma understands that you want to make the derivative for that symbol.
But this x, does NOT act as a Block variable for that statement, isolating its meaning from any other x you have in your program, so it enables the chain rule. For example:
In[85]:= z=x^2;
D[Sin[z],{x,1}]
Out[86]= 2 x Cos[x^2]
See? That's perfect! But there is a price.
The price is that the symbols inside the derivative get evaluated as the derivative is taken, and that is spoiling your code.
Of course there are a lot of tricks to get around this. Some have already been mentioned. From my point of view, one clear way to undertand what is happening is:
f[x_] := x*Exp[t*x];
g[y_, m_] := D[f[x], {x, m}] /. x -> y;
{g[p, 2], g[0, 1]}
Out:
{2 E^(p t) t + E^(p t) p t^2, 1}
HTH!

Resources