I am currently working on a Mathematica project to calculate Riemann's sums and put them in a table. I am having trouble printing the row numbers (intervals). (The row numbers are also parameters to the secondary functions). I don't know of any way to just access the index of the iterator in a Mathematica Table, so I am trying to compute them using the function parameters.
Here is an example of what I'd like to print, for the integral of x^2 over the range {0, 1}, with 10 subdivisions.
tableRiemannSums[#^2 &, {0, 1}, 10]
I need to figure out what the index of each iteration is, based on the value of the current
subdivision k, the range of the integral {a, b}, and the number of subdivisions, n. Below is the main piece of code.
tableRiemannSums[fct_, {a_, b_}, n_] := Table[{'insert index here',
leftRiemannSum[fct, {a, b}, 'insert index here'],
rightRiemannSum[fct, {a, b}, 'insert index here']},
{k, a, b - (N[b - a]/n), N[b - a]/n}]
In the above equation, the line
{k, a, b - (N[b - a]/n), N[b - a]/n}]
means the range of the table is k as k goes from 'a' to 'b - ((b - a)/n)' in steps of size '(b - a)/n'.
In each of the places where my code says 'insert index here,' I need to put the same equation. Right now, I am using 'n * k + 1' to calculate the index, which is working for positive ranges, but breaks when I have a range like {a,b} = {-1, 1}.
I think this is a fairly straightforward algebra problem, but I have been racking my brain for hours and can't find a general equation.
(I apologize if this is a duplicate question - I tried searching through the Stack overflow archives, but had a hard time summarizing my question into a few key words.)
I finally figured out how to solve this. I was over thinking the range, rather than relying on the inner functions to control it. I rewrote the function as:
tableRiemannSums[fct_, {a_, b_}, n_] := Table[{k,
leftRiemannSum[fct, {a, b}, k],
rightRiemannSum[fct, {a, b}, k]},
{k, 1, n}}]
For reference, here are the left and right sums (for anyone interested!):
leftRiemannSum[fct_, {a_, b_}, n_] :=
N[b - a]/n* Apply[Plus, Map[fct, Range[a, b - N[b - a] / n, N[b - a]/n]]]
rightRiemannSum[fct_, {a_, b_}, n_] :=
N[b - a]/n* Apply[Plus, Map[fct, Range[a + (N[b - a]/n), b, N[b - a]/n]]]
What you may want to consider is creating a function to make each line of the table. One argument to this function would be the row number.
Execute this function using MapIndexed, which will provide you a way to traverse your range as required while providing an incrementing row number.
(Create a list with the range of values, then apply your MapIndexed function to this list.)
Related
Given:
A list of symbols of size M
The desired size of combination L
Symbols may occur any number of times in a combination
All permutations of any combination of the symbols must be taken into the account
Example: for a list of symbols (a, b, c), and L=4, all of the combinations (a, a, a, a), (a, b, a, c), (a, c, b, b) and so on are valid. For the lack of a better term, I called this "loose combinations".
The particular ordering of the combinations is not important. Being given the combination index N, the algorithm should return a unique combination from the set of possible combinations that satisfy the conditions. My guess is that the most natural order would be if we consider the combinations as numbers of radix M and length L, so that the normal number order would apply, but that is not strictly necessary to follow.
What is the algorithm to find the Nth combination?
I'm not sure how to find the answer myself, and have been searching if there was an answer for this particular set of conditions elsewhere, but did not find it. All the questions that I find are not interested in combinations with repeating elements like (a, a, b, b) and combinations with rearranged order, like (a, a, b, c) and (a, b, c, a) or (a, c, a, b) are treated as the same combination.
As you figured out already, you are essentially interested in enumerating the numbers of length up to L in base M.
So, a solution might look like this:
Define a bijection {0, …, M-1} -> Symbols, i.e. enumerate your symbols.
For any non-negative integer N < M^L, determine its base M representation.
Easily done by repeated modulo M and rounded down division by M.
Without loss of generality, this has length M by adding leading zeroes as needed.
Use your bijection to convert this list of digits 0 to M-1 to a loose combination of symbols.
So, let's go into detail on this part:
Easily done by repeated modulo M and rounded down division by M.
Pseudocode:
int a[L];
for int i from 0 to L-1 do
a[i] = N % M; // Should go from 0 to M-1
N = N / M; // Rounded down, of course
done
I am trying to write a rule that can return the sum of the product of each element from two lists (same length).
Here is what I have right now:
sum(0, _, []).
sum(Result, [H1|T1], [H2|T2]) :-
sum(Remaining,T1, T2),
Remaining is Result - (H1*H2).
It won't work when one of the list is not instantiated. What changes I need to make in order to make the following possible?
sum([1,2],X,3).
X = [3,0].
Thanks.
What you are calculating is commonly referred to as a dot product (also known as scalar product or inner product).
You write you are not allowed to use libraries. That surely refers to external libraries---not to the standard library that is part of SWI Prolog, right?
The following predicate list_list_dotProduct/3 roughly corresponds to the code you implemented. It uses finite domain constraints (#>=)/2 and (#=)/2 to allow for non-unidirectional integer arithmetic:
:- use_module(library(clpfd)).
list_list_dotProduct([],[],0).
list_list_dotProduct([X|Xs],[Y|Ys],Sum) :-
X #>= 0,
Y #>= 0,
Sum #= X*Y + Sum0,
list_list_dotProduct(Xs,Ys,Sum0).
Consider the following query:
?- list_list_dotProduct([1,2],Xs,3), label(Xs).
Xs = [1, 1] ;
Xs = [3, 0].
As an added bonus, here's an alternative implementation that is based on the predefined predicates same_length/2, ins/2, and scalar_product/4:
list_list_dotProduct(Xs,Ys,Prod) :-
same_length(Xs,Ys),
Xs ins 0..sup,
Ys ins 0..sup,
scalar_product(Xs,Ys,#=,Prod).
This is supposed to calculate the sum of two lists. The lists can be of different size.
sum([],[],[]).
sum(A,[],A).
sum([],B,B).
sum([A|Int1],[B|Int2],[C|Int3]) :-
(
C =:= A + B
;
((C =:= A), B = [])
;
((C =:= B), A = [])
),
sum(Int1,Int2,Int3).
It seems to work correctly, except when trying to find the sum of two lists. Then it gives the following error:
ERROR: =:=/2: Arguments are not sufficiently instantiated
I don't see why. There's a recursive and a basis step, what exactly is not yet instantiated and how do I fix it?
[1] While your disjunctions in the last clause are -- to some extent -- conceptually correct, Prolog considers these disjunctions in sequence. So it first considers C =:= A + B. But either A or B can be the empty list! This is what causes the error you reported, since the empty list is not allowed to occur in a numeric operation.
[2] You need to use C is A + b (assignment) i.o. C =:= A + B (numeric equivalence).
[3] If you say [A|Int1] and then A = [], then this means that [A|Int1] is not (only) a list of integers (as you claim it is) but (also) a list of lists! You probably intend to check whether the first or the second list is empty, not whether either contains the empty list.
Staying close to your original program, I would suggest to reorder and change things in the following way:
sumOf([], [], []):- !.
sumOf([], [B|Bs], [C|Cs]):- !,
C is B,
sumOf([], Bs, Cs).
sumOf([A|As], [], [C|Cs]):- !,
C is A,
sumOf(As, [], Cs).
sumOf([A|As], [B|Bs], [C|Cs]):-
C is A + B,
sumOf(As, Bs, Cs).
For example:
?- sumOf([1,2,3], [1,-90], X).
X = [2, -88, 3]
Notice my use of the cut (symbol !) in the above. This makes sure that the same answer is not given multiple times or -- more technically -- that no choicepoints are kept (and is called determinism).
You should read a tutorial or a book. Anyway, this is how you add two things to each other:
Result is A + B
This is how you could add all elements of one list:
sum([], 0). % because the sum of nothing is zero
sum([X|Xs], Sum) :-
sum(Xs, Sum0),
Sum is X + Sum0.
And this is how you could add the sums of a list of lists:
sums([], 0).
sums([L|Ls], Sums) :-
sums(Ls, Sums0),
sum(L, S),
Sums is Sums0 + S.
we have a problem in which we need to order/distribute the given set/s such that the numbers are not repeatable
here is an example ,say i have 4 sets
{A,A,A,A,A,A}
{B,B}
{C}
{D,D,D}
the resultant should be something like A,D,A,B,A,D,C,A,D,A,B,A
with no repeatable occurrence.
any thoughts,Algorithms..could be appreciated.
EDIT : sorry for not being clear, by occurrence I meant patterns like AA or BB or CC shouldn't
in the resultant it's OK to have ADAD
Thanks
Dee
A moment's consideration yielded this algorithm:
Let A be the symbol repeated the most times.
Let N be the number of occurrences of A.
Let Rest be the concatenation of the remaining symbols, in order.
Let Buckets be a list of length N, where each element Buckets[i] is an array containing a single A.
Iterate over Buckets: for each index i, pop an element from Rest and append it to Buckets[i]. When you reach the end of Buckets, start from the first index again. When you reach the end of Rest, you are done.
The answer is the concatenation of the contents of Buckets.
Your example:
Let A = 'A'.
Let N = 6.
Let Rest = [B, B, C, D, D, D].
Let Buckets = [[A], [A], [A], [A], [A], [A]].
After iterating, Buckets is [[A, B], [A, B], [A, C], [A, D], [A, D], [A, D]]. The output is ABABACADADAD.
Always pick the bucket with the most amount left.
My rusty Matlab skills did this:
generate a random distribution:
symbols = ceil(rand()*10)+1
maxn = ceil(rand()*20)
distribution= [floor(rand(1,symbols)*maxn);(1:symbols)]'
last = -1;
sequence=[]; #output vector
while sum(distribution(:,1))>0 ; #while something is left
distribution= sortrows(distribution); #sort the matrix
if last == distribution(end,2) #pick the one with the one with the second most elements
if a(end-1,1) ==0 #this means there are no fillers left
break
end
last = distribution(end-1,2);
distribution(end-1,1)--;
else #pick the one with the most elements
last = distribution(end,2);
distribution(end,1) --;
endif
sequence(end+1)=last;
end
sequence
rest = distribution'
Note: My symbols are numbers instead of letters.
Edit: Here is some (beautified) output from the script.
I'm fairly new to Prolog and I hope this question hasn't been asked and answered but if it has I apologize, I can't make sense of any of the other similar questions and answers.
My problem is that I have 3 towns, connected by roads. Most are one way, but there are two towns connected by a two way street. i.e.
facts:
road(a, b, 1).
road(b, a, 1).
road(b, c, 3).
where a, b and c are towns, and the numbers are the distances
I need to be able to go from town a to c without getting stuck between a and b
Up to here I can solve with the predicates: (where r is a list of towns on the route)
route(A, B, R, N) :-
road(A, B, N),
R1 = [B],
R = [A|R1],
!.
route(A, B, R, N) :-
road(A, C, N1),
route(C, B, R1, N2),
\+ member(A, R1),
R = [A | R1],
N is N1+N2.
however if I add a town d like so
facts:
road(b, d, 10)
I can't get Prolog to recognize this is a second possible route. I know that this is because I have used a cut, but without the cut it doesn't stop and ends in stack overflow.
Furthermore I will then need to be able to write a new predicate that returns true when R is given as the shortest route between a and c.
Sorry for the long description. I hope someone can help me!
This is a problem of graph traversal. I think your problem is that you've got a cyclic graph — you find the leg a-->b and the next leg you find is b-->a where it again finds the leg a-->b and ... well, you get the picture.
I would approach the problem like this, using a helper predicate with accumulators to build my route and compute total distance. Something like this:
% ===========================================================================
% route/4: find the route(s) from Origin to Destination and compute the total distance
%
% This predicate simply invoke the helper predicate with the
% accumulator(s) variables properly seeded.
% ===========================================================================
route(Origin,Destination,Route,Distance) :-
route(Origin,Destination,[],0,Route,Distance)
.
% ------------------------------------------------
% route/6: helper predicate that does all the work
% ------------------------------------------------
route(D,D,V,L,R,L) :- % special case: you're where you want to be.
reverse([D|V],R) % - reverse the visited list since it get built in reverse order
. % - and unify the length accumulator with the final value.
route(O,D,V,L,Route,Length) :- % direct connection
road(O,D,N) , % - a segment exists connecting origin and destination directly
L1 is L+N , % - increment the length accumulator
V1 = [O|V] , % - prepend the current origin to the visited accumulator
route(D,D,V1,L1,Route,Length) % - recurse down, indicating that we've arrived at our destination
. %
route(O,D,V,L,Route,Length) :- % indirect connection
road(O,X,N) , % - a segment exists from the current origin to some destination
X \= D , % - that destination is other than the desired destination
not member(X,V) , % - and we've not yet visited that destination
L1 is L+N , % - increment the length accumulator
V1 = [O|V] , % - prepend the current origin to the visited accumulator
route(X,D,V1,L1,Route,Length) % - recurse down using the current destination as the new origin.