Turing machines for equation with modulo - turing-machines

I'm required to create a touring machine for
Z =(Xi + Ki)mod 2
but I'm completely lost in terms of creating a touring machine for a modulo of 2. X and K are binary inputs where i is the length of the string. The input is given as such where:
XYK
the Y just acts as a separator for binary strings X and K which could vary in length. The problem I'm having now is regarding the modulo part of the equation. How do i begin with mod 2 and what I'm supposed to look out for?

Based on this I think what you are asking for is Z such that Z_i = X_i + Y_i (mod 2):
(X0 X1 X2 ... Xi
+ K0 K1 K2 ... Ki)
% 2 2 2 ... 2
= Z0 Z1 Z2 ... Zi
Given this and an input tape like BXX...XY...KK...KBB... where B is blank, XX...X is an i-digit binary number, Y is a separator and KK...K is another i-digit binary number, the problem is easy:
Write a new separator V to the first non-blank cell after the input. Make sure you can distinguish it from X, Y, K. Return to the beginning of the tape.
Move right until you find a 0 or 1 belonging to X (if you find Y, skip below). Enter state X1 if 1 and X0 of 0. Write W on the tape and move right to the first 0 or 1 after Y. If you found Y before a 0 or 1, then copy V to the front of the tape, then write blanks over everything else and halt-accept.
If in state X0 and you see a 0, or if you're in X1 and you see a 1, enter state Z0. Otherwise, enter state Z1.
Write a W to the tape and move right to the first blank cell after V.
Write 0 if in Z0, or 1 if in Z1.
Move back to the beginning of the tape and repeat the process until you find Y first in step 2.
Example: 0011 + 1010
B0011Y1010BBBBB...
^
B0011Y1010VBBBB...
^ move to the end of input, write V separator, reset head
B0011Y1010VBBBB...
^ move right to first 0
BW011Y1010VBBBB...
^ enter X0, write W, move right to first 1 after Y
BW011YW010VBBBB...
^ enter Z1, write W, move right to first blank after V
BW011YW010V1BBB...
^ write 1, return to beginning, repeat
BWW11YWW10V10BB...
^ find 0, X0, find 0, Z0, write 0, return to start, repeat
BWWW1YWWW0V100B...
^ find 1, X1, find 1, Z0, write 0, return to start, repeat
BWWWWYWWWWV1001...
^ find 1, X1, find 0, Z1, write 1, return to start, repeat
B1001BBBBBBBBBB...
^ find Y, copy from after V to beginning, erase rest, halt.

Related

Floating and interval arithmetic in Isabelle

I'm using the Approximation.thy from the Descision_Procs file for interval arithmetic in Isabelle. The file gives you a tactic for proving inequalities over the reals, such as:
theorem "3 ≤ x ∧ x ≤ 6 ⟹ sin ( pi / x) > 0.4" by (approximation 10)
Now, I'm interested in trying out the core function of the implementation which appears to be the approx function. This is described in section 4.5.2 of Proving Real-Valued Inequalities by Computation in Isabelle/HOL. Here are some of the statements that I do:
value "Float 3 (-1)"
value "approx 1 (Num (Float 3 (-2))) [Some (Float 1 0,Float 4 0)]"
value "approx 1 (Add (Num (Float 3 (-2))) (Num (Float 4 (-8)))) [Some (Float 1 0,Float 4 0)]"
value "approx 1 (Add (Var 1) (Num (Float 4 (-8)))) [Some (Float 1 0,Float 4 0)]"
First, I would ask if you know a more convinient way to write floats (instead of Float a b, maybe there is a function of the kind real_to_float r). Then, you see that the function computes, given some precision (which I understand as the number of correct decimals), the upper and lower bounds for the operations given as a second parameter.
Now, the main question is the following:
What is the purpose of the last parameter? I guess they are confidence intervals for the variables in the second parameter?
The text claims that this function also implements interval arithmetic. Can you show an example where I can see how this functions performs interval addition for instance? ([a,b]+[c,d]=[a+c,b+d])
None of these things are meant to be used directly; that's why the Approximation method offers a convenience layer above them.
There is a function like real_to_float. Its name is float_of, but it does not have any code equations, so you cannot really use it. One could prove a code equation for it, but that would be a bit tedious.
As for your other questions: Yes, the last parameter is a list where the i-th element is an interval in which the value of the i-th variable is known to lie.
And yes, approx performs interval arithmetic; in fact, that is at the very core of what it does. It operates entirely on intervals. The example you mentioned can be observed e.g. when doing x + y where x is in [1;2] and y is in [-1;2]:
value "approx 10 (Add (Var 0) (Var 1))
[Some (Float 1 0, Float 1 1), Some (Float (-1) 0, Float 1 1)]"
which returns the interval [0;4]:
"Some (Float 0 0, Float 2 1)"
:: "(float × float) option"
or, more directly:
lemma "(x :: real) ∈ {1..2} ⟹ y ∈ {-1..2} ⟹ x + y ∈ {0..4}"
by (approximation 10)

Constrained quadratic minimization in Mathematica with matrices

I'm attempting to solve the familiar mean-variance optimization problem using matrices in Mathematica, with a few added constraints on the solution vector "w". (The mean-variance optimization problem is basically choosing how to allocate a given budget over a number of assets according to their means and covariances in order to minimize the risk of the portfolio for a chosen level of mean return.)
My question: I'm not sure which function to use to perform the minimization of the objective function, which is quadratic:
obj = 0.5*w'* Sig * w
where w is the Nx1 vector of weights for each of the N assets and Sig is the NxN covariance matrix
From what I've been able to find (I'm fairly new to Mathematica), it seems that FindMinimum, NMinimize, etc. are meant to deal only with scalar inputs, while LinearProgramming is meant for an objective function that's linear (not quadratic) in the weight vector w. I could very well be wrong here--any help in steering me toward the correct function would be much appreciated!
If it helps, I've attached my sample code--I'm not sure how, but if there's a place to upload the sample .csv data, I can do that as well if someone could point me to it.
Thank you very much for any help you can provide.
-Dan
CODE
(* Goal: find an Nx1 vector of weights w that minimizes total \
portfolio risk w'*Sig*w (where Sig is the covariance matrix) subject to:
-The portfolio expected return is equal to the desired level d: w'*M \
= d, where M is the Nx1 vector of means
-There are exactly two assets chosen from each of the refining, \
construction, hitech, and utility sectors, and exactly one asset \
chosen from the "other" sector
^ The above two constraints are represented together as w'*R = k, \
where R is the matrix [M SEC] and k is the vector [d 2 2 2 2 1]
-Each weight in w takes an integer value of either 0 or 1, \
representing buying or not buying that physical asset (ex. a plant) -- \
this constraint is achieved as a combination of an integer constraint \
and a boundary constraint
**Note that for the T=41 days of observations in the data, not every \
asset generates a value for every day; by leaving the days when the \
asset is "off" as blanks, this shouldn't affect the mean or \
covariance matrices.
*)
Clear["Global`*"]
(* (1) Import the data for today *)
X = Import["X:\\testassets.csv", "Data"];
Dimensions[X];
(* (2) Create required vectors and matrices *)
P = Take[X, {2, 42}, {4}];
Dimensions[P]; (* Should be N assets x 1) *)
r = Take[X, {2, 42}, {10, 50}];
Dimensions[r]; (* Should be N x T *)
Sig = Covariance[
r]; (* When there's more time, add block diagonal restriction here \
*)
Dimensions[Sig]; (* Should be N x N *)
M = Mean[r\[Transpose]];
Dimensions[M]; (* Should be N x 1 *)
SEC = Take[X, {2, 42}, {5, 9}];
Dimensions[SEC]; (* Should be N x 5 *)
(* (3) Set up constrained optimization *)
d = 200; (* desired level of return *)
b = 60000;(* budget constraint *)
R = Join[M, POS];
Dimensions[R]; (* Should be N x 6 *)
k = {d, 2, 2, 2, 2, 1};
obj = w*Sig*w\[Transpose];
constr = w*R;
budgetcap = w*P;
lb = ConstantArray[0, 41];
ub = ConstantArray[1, 41];
FindMinimum[{obj, constr = k, budgetcap <= b, Element[w, Integers],
lb <= w <= ub}, w]

Impossible deduced upper bounds in AMPL

I'm intending to conduct an optimization where I want to maximize the amount of flow in a system subjected to some time constraints and some "these routes must be fulfilled" constraints. The first time constraint states that each vehicle must not exceed a 24 hour workload (expressed in minutes). The second time constraint is a subtour elimination constraint which also states that the starttime at the "visiting" node cannot be activated before the vehicle has had time to travel etc. Constraint3 describes that the road between K1 and N1 must be used no more than 9 times, using whichever vehicle k. The last constraint states that all the vehicles from the specific nodes must return at the end of the day.
maximize maxamount: sum{i in V, j in V, k in K} x[i,j,k];
subject to TimeConstraint {k in K}:
sum{i in V, j in V} traveltime[i,j]*x[i,j,k] <= 1440;
subject to StartTime{i in V,j in V, k in K}:
starttime[i] + servicetime[i] +traveltime[i,j] - 1300 * (1 - x[i,j,k]) <= starttime[j];
subject to Constraint3:
sum{k in K} x["K1","N1",k] <= 9;
subject to EndNode{k in K}:
sum{i in V}x[i,"K1",k] - sum{j in V} x["K1",j,k]= 0;
Constraint3 and EndNode has several more constraints of the same type (just with other "predefined locations", such as for instance the road between K1 and N2 cannot exceed 4 visits and so on).
My problem is that I get the error Impossible deduced bounds x[K1,K1,1] has lower bound = 0 and upper bound = -76 which I've understood stems from conflicting constraints. My question is however: how? Using almost exclusively binary variables, I cannot see why the code above is not working. Have I misunderstood what I'm actually doing in my model?
I've noticed that the compiler only complains when i=j, so I checked my .dat file and noticed that the traveltime between i and j, when i=j were very big (so the program would not choose those routes). However, editing that .dat file to no longer exceed TimeConstraints limit automatically still gives me the same error (albeitly lesser, now the upper bound is -1 instead of -76).
I hope someone could shed some light into this
Thanks in advance
Cenderze
the traveltime between i and j, when i=j were very big (so the program would not choose those routes)
If traveltime[i,j] = M (very big) then StartTime for i=j reads
servicetime[i] + M - 1300 * (1 - x[i,j,k]) <= 0 <=>
1300 * x[i,j,k] <= 1300 - servicetime[i] - M
Therefore, whenever M > 1300 - servicetime[i], the problem is infeasible.
I would suggest defining the X variables for all pairs (i,j) with i<>j, or (if the problem is symmetric) with i < j.
Follow up from the comment
The following snippet works well when plugged in the AMPL Online Editor:
param n := 10;
set N:= 1..n;
set V := {i in N, j in N: i <> j};
display V;
Output:
set V :=
(1,2) (2,3) (3,4) (4,5) (5,6) (6,7) (7,8) (8,9) (9,10)
(1,3) (2,4) (3,5) (4,6) (5,7) (6,8) (7,9) (8,10) (10,1)
(1,4) (2,5) (3,6) (4,7) (5,8) (6,9) (7,10) (9,1) (10,2)
(1,5) (2,6) (3,7) (4,8) (5,9) (6,10) (8,1) (9,2) (10,3)
(1,6) (2,7) (3,8) (4,9) (5,10) (7,1) (8,2) (9,3) (10,4)
(1,7) (2,8) (3,9) (4,10) (6,1) (7,2) (8,3) (9,4) (10,5)
(1,8) (2,9) (3,10) (5,1) (6,2) (7,3) (8,4) (9,5) (10,6)
(1,9) (2,10) (4,1) (5,2) (6,3) (7,4) (8,5) (9,6) (10,7)
(1,10) (3,1) (4,2) (5,3) (6,4) (7,5) (8,6) (9,7) (10,8)
(2,1) (3,2) (4,3) (5,4) (6,5) (7,6) (8,7) (9,8) (10,9);
== 1 ==========================
Change your snippet to
set N = {'K1', 'K2','K3','K4'};
set V := {i in N, j in N: i != j};
display V
and give it a go. I get:
set V :=
(K1,K2) (K1,K4) (K2,K3) (K3,K1) (K3,K4) (K4,K2)
(K1,K3) (K2,K1) (K2,K4) (K3,K2) (K4,K1) (K4,K3);
== 1 ==========================
I hope this helps!

Accumulating Curried Function (SML)

I have a set of problems that I've been working through and can't seem to understand what the last one is asking. Here is the first problem, and my solution to it:
a) Often we are interested in computing ∑i=m..n f(i), the sum of function values f(i) for i = m through n. Define sigma f m n which computes ∑i=m..n f(i). This is different from defining sigma (f, m, n).
fun sigma f m n = if (m=n) then f(m) else (f(m) + sigma f (m+1) n);
The second problem, and my solution:
b) In the computation of sigma above, the index i goes from current
i to next value i+1. We may want to compute the sum of f(i) where i
goes from current i to the next, say i+2, not i+1. If we send this
information as an argument, we can compute more generalized
summation. Define ‘sum f next m n’ to compute such summation, where
‘next’ is a function to compute the next index value from the
current index value. To get ‘sigma’ in (a), you send the successor
function as ‘next’.
fun sum f next m n = if (m>=n) then f(m) else (f(m) + sum f (next) (next(m)) n);
And the third problem, with my attempt:
c) Generalizing sum in (b), we can compute not only summation but also
product and other forms of accumulation. If we want to compute sum in
(b), we send addition as an argument; if we want to compute the
product of function values, we send multiplication as an argument for
the same parameter. We also have to send the identity of the
operator. Define ‘accum h v f next m n’ to compute such accumulation,
where h is a two-variable function to do accumulation, and v is the
base value for accumulation. If we send the multiplication function
for h, 1 for v, and the successor function as ‘next’, this ‘accum’
computes ∏i=m..n f(i). Create examples whose ‘h’ is not addition or
multiplication, too.
fun accum h v f next m n = if (m>=n) then f(m) else (h (f(m)) (accum (h) (v) (f) (next) (next(m)) n));
In problem C, I'm unsure of what i'm suppose to do with my "v" argument. Right now the function will take any interval of numbers m - n and apply any kind of operation to them. For example, I could call my function
accum mult (4?) double next3 1 5;
where double is a doubling function and next3 adds 3 to a given value. Any ideas on how i'm suppoes to utilize the v value?
This set of problems is designed to lead to implementation of accumulation function. It takes
h - combines previous value and current value to produce next value
v - starting value for h
f - function to be applied to values from [m, n) interval before passing them to h function
next - computes next value in sequence
m and n - boundaries
Here is how I'd define accum:
fun accum h v f next m n = if m >= n then v else accum h (h (f m) v) f next (next m) n
Examples that were described in C will look like this:
fun sum x y = x + y;
fun mult x y = x * y;
fun id x = x;
accum sum 0 id next 1 10; (* sum [1, 10) staring 0 *)
accum mult 1 id next 1 10; (* prod [1, 10) starting 1 *)
For example, you can calculate sum of numbers from 1 to 10 and plus 5 if you pass 5 as v in first example.
The instructions will make more sense if you consider the possibility of an empty interval.
The "sum" of a single value n is n. The sum of no values is zero.
The "product" of a single value n is n. The product of no values is one.
A list of a single value n is [n] (n::nil). A list of no values is nil.
Currently, you're assuming that m ≤ n, and treating m = n as a special case that returns f m. Another approach is to treat m > n as the special case, returning v. Then, when m = n, your function will automatically return h v (f m), which is the same as (f m) (provided that v was selected properly for this h).
To be honest, though, I think the v-less approach is fine when the function's arguments specify an interval of the form [m,n], since there's no logical reason that such a function would support an empty interval. (I mean, [m,m−1] isn't so much "the empty interval" as it is "obvious error".) The v-ful approach is chiefly useful when the function's arguments specify a list or set of elements in some way that really could conceivably be empty, e.g. as an 'a list.

How to optimize this computation

I'm writing a model-checker which relies on the computation of a coefficient which is used intensively by the algorithms which is the following:
![alt text][1]
where q is double, t a double too and k an int. e stands for exponential function. This coefficient is used in steps in which q and t don't change while k always starts from 0 until the sum of all previous coefficients (of that step) reaches 1.
My first implementation was a literal one:
let rec fact k =
match k with
0 | 1 -> 1
| n -> n * (fact (k - 1))
let coeff q t k = exp(-. q *. t) *. ((q *. t) ** (float k)) /. float (fact k)
Of course this didn't last so much since computing the whole factorial was just unfeasible when k went over a small threshold (15-20): obviously results started to go crazy. So I rearranged the whole thing by doing incremental divisions:
let rec div_by_fact v d =
match d with
1. | 0. -> v
| d -> div_by_fact (v /. d) (d -. 1.)
let coeff q t k = div_by_fact (exp(-. q *. t) *. ((q *. t) ** (float k))) (float k)
This version works quite well when q and t are enough 'normal' but when things gets strange, eg q = 50.0 and t = 100.0 and I start to calculate it from k = 0 to 100 what I get is a series of 0s followed by NaNs from a certain number until the end.
Of course this is caused by operations with numbers that start to get too near to 0 or similar problems.
Do you have any idea in how I can optimize the formula to be able to give enough accurate results over a wide spread of inputs?
Everything should be already 64 bit (since I'm using OCaml which uses doubles by default). Maybe there is a way to use 128 bit doubles too but I don't know how.
I'm using OCaml but you can provide ideas in whatever language you want: C, C++, Java, etc. I quite used all of them.
qt^k/k! = e^[log[qt^k/k!]]
log[qt^k/k!] = log[qt^k] - log[k!] // log[k!] ~ klnk - k by stirling
~ k ln(qt) - (k lnk - k)
~ k ln(qt/k) - k
for small values of k, Stirling approximation is not accurate.
however, since you appear to be doing finite known range, you can compute log[k!]and put it in array, avoiding any errors whatsoever.
of course there are multiple variations you can do further.
This is not an answer (I believe), but pehaps just a clarification .If I misunderstood something, I'll delete it after your comment.
As I understand, you are trying to calculate n, such as the following sum is equal to 1.
As you may see it approaches to 1 asymptotically, it'll never be EQUAL to 1.
Please correct me if I misunderstood your question.

Resources