How can I limit the digits of data matrix to 2 digits?
data = reshape([tuple(c[i], c2[i]) for i in eachindex(c, c2)], 9, 9)
#9×9 Matrix{Tuple{Real, Real}}:
hl = Highlighter((d,i,j)->d[i,j][1]*d[i,j][2] < 0, crayon"red")
pretty_table(data ; header = names, row_names= names , highlighters=hl)
There are a couple of ways to do this:
You can use the round function:
data = round(data, 2)
You can use string formatting:
data = ["{0:.2f}".format(x) for x in data]
You can round the numbers when creating the data variable:
round2(n) = round(n; digits = 2)
data = reshape([tuple(round2(c[i]), round2(c2[i])) for i in eachindex(c, c2)], 9, 9)
Or if you want to maintain precision in the data array, but limit to 2 digits just for the printing, you can use the formatters keyword argument of PrettyTables:
pretty_table(data; header = titles, row_names = titles, formatters = (v, i, j) -> round.(v; digits = 2))
You can use an anonymous function as a formatter, like this:
formatter = (v, i, j) -> round(v, digits=2);
hl = Highlighter((d,i,j)->di,j*d[i,j][2] < 0, crayon"red")
pretty_table(data; header=names, row_names=names , highlighters=hl, formatters=formatter)
I encourage you to read the documentations for further options.
I understand you have a matrix of tuples such as:
julia> mx = [tuple(rand(2)...) for i in 1:3, j=1:2]
3×2 Matrix{Tuple{Float64, Float64}}:
(0.617653, 0.0742714) (0.0824311, 0.0344668)
(0.327074, 0.235599) (0.912262, 0.0250492)
(0.116079, 0.387601) (0.804606, 0.81485)
This can be rounded as:
julia> (x->round.(x;digits=2)).(mx)
3×2 Matrix{Tuple{Float64, Float64}}:
(0.62, 0.07) (0.08, 0.03)
(0.33, 0.24) (0.91, 0.03)
(0.12, 0.39) (0.8, 0.81)
Related
I am stuck in a problem. I want to update my cartesian index.
I have a matrix (x) 200x6 that is binary. 1 if assigned, 0 otherwise. I want to find the cartesian index of when x is 1 in the first 3 columns and in the last 3 elements.
I have the following code:
index_right = findall( x -> x == 1, sol.x_assignment[:,1:3])
index_left = findall( x -> x == 1, sol.x_assignment[:,4:6])
index_left
However index_right is correct, index_left is wrong as it returns index between 1,2,3 instead of 4,5,6
CartesianIndex(2, 1)
CartesianIndex(3, 1)
CartesianIndex(10, 2)
CartesianIndex(11, 1)
Expected output:
CartesianIndex(2, 4)
CartesianIndex(3, 4)
CartesianIndex(10, 5)
CartesianIndex(11, 4)
How can I update index_left to add +3 in the second index for all?
One solution could be
index_left = findall( x -> x == 1, sol.x_assignment[:,4:6])
index_left = map(x -> x + CartesianIndex(0, 3), index_left)
I think you can also use ==(1) in place of x -> x + 1, looks a bit nicer :)
index_left = findall(==(1), sol.x_assignment[:,4:6])
and the inplace version of map should work too
map!(x -> x + CartesianIndex(0, 3), index_left, index_left).
An alternative could be first finding all the indices with 1 and then filtering afterwards, so smth like
full_index = findall(==(1), sol.x_assignment)
and then
left_index = filter(x -> x[2] <= 3, full_index)
right_index = filter(x -> x[2] > 3, full_index)
Assuming your x is:
using Random;Random.seed!(0);
x = rand(Bool, (5,6))
The first set can be found as:
findall(isone, #view x[:, 1:3])
For the second set you need to shift the results hence you want:
findall(isone, #view x[:, 4:6]) .+ Ref( CartesianIndex(0,3))
If you are searching for different value eg. 2 use ==(2) rather than a lambda as this is faster.
Similarly #view allows to avoid unnecessary allocations.
I want to code this constraint.
d and a in the below code are the subsets of set S with the size of N. For example: (N=5, T=3, S=6), d=[1,2,2,3,1] (the elements of d are the first three digits of S and the size of d is N) and a=[6,4,5,6,4] (the elements of a are the three last digits of set S and the size of a is N).
In the constraint, s should start with d and end with a.
It should be like s[j=1]=1:6, s[j=2]=2:4, s[j=3]=2:5, s[j=4]=3:6, s[j=5]1:4.
I do not know how to deal with this set that depends on the other sets. Can you please help me to code my constraint correctly? The below code is not working correctly.
N = 5
T=3
S=6
Cap=15
Q=rand(1:5,N)
d=[1,2,2,3,1]
a=[6,4,5,6,4]
#variable(model, x[j=1:N,t=1:T,s=1:S], Bin)
#constraint(model, [j= 1:N,t = 1:T, s = d[j]:a[j]], sum(x[j,t,s] * Q[j] for j=1:N) <= Cap)
N, T, S = 5, 3, 6
Q = rand(1:5,N)
d = [1, 2, 2, 3, 1]
a = [6, 4, 5, 6, 4]
using JuMP
model = Model()
#variable(model, x[1:N, 1:T, 1:S], Bin)
#constraint(
model,
[t = 1:T, s = 1:S],
sum(x[j, t, s] * Q[j] for j in 1:N if d[j] <= s < a[j]) <= 15,
)
p.s. There's no need to post multiple comments and questions:
Coding arrays in constraint JuMP
You should also consider posting on the Julia discourse instead: https://discourse.julialang.org/c/domain/opt/13. It's easier to have a conversation there.
I have a user-defined structure:
using Parameters
#with_kw struct TypeSingle
id::Int
x::Union{Int32, Missing} = missing
flag::Bool = true
end
#with_kw struct TypeAll
A = TypeSingle(id=01,x=0.1,flag=false)
B = TypeSingle(id=02)
# this continues on until
Z = TypeSingle(id=26,x=1.3)
end
I have some questions regarding operations that I would like to perform with TypeAll:
I'd like to refer to each entry, A.id, B.id etc.. in the composite TypeAll in a loop that runs from the lowest id to the highest.
Is there a way to extract the size of this type? i.e. how many A,B,...Z are there in total?
Would this be better suited to a vector of TypeA? In my actual code TypeAll isn't only composed of TypeA, but also includes TypeB, TypeC etc..
As long as your TypeAll is not going to be mutable, it looks a lot like a named tuple (NamedTuple) so why not use one instead of a TypeAll? e.g.
julia> t = (A = (01, 0.1, false), B = (02, missing, true), C = (26, 1.3, true))
(A = (1, 0.1, false), B = (2, missing, true), C = (26, 1.3, true))
julia> t[1]
(1, 0.1, false)
julia> length(t)
3
julia> sort(collect(t), lt = (x, y) -> x[1] < y[1])
3-element Vector{Tuple{Int64, Any, Bool}}:
(1, 0.1, 0)
(2, missing, 1)
(26, 1.3, 1)
If you want to have TypeAll mutable, I would use a vector of TypeSingle, instead of a named tuple.
Mathematical background
Continued fractions are a way to represent numbers (rational or not), with a basic recursion formula to calculate it. Given a number r, we define r[0]=r and have:
for n in range(0..N):
a[n] = floor(r[n])
if r[n] == [an]: break
r[n+1] = 1 / (r[n]-a[n])
where a is the final representation. We can also define a series of convergents by
h[-2,-1] = [0, 1]
k[-2, -1] = [1, 0]
h[n] = a[n]*h[n-1]+h[n-2]
k[n] = a[n]*k[n-1]+k[n-2]
where h[n]/k[n] converge to r.
Pell's equation is a problem of the form x^2-D*y^2=1 where all numbers are integers and D is not a perfect square in our case. A solution for a given D that minimizes x is given by continued fractions. Basically, for the above equation, it is guaranteed that this (fundamental) solution is x=h[n] and y=k[n] for the lowest n found which solves the equation in the continued fraction expansion of sqrt(D).
Problem
I am failing to get this simple algorithm work for D=61. I first noticed it did not solve Pell's equation for 100 coefficients, so I compared it against Wolfram Alpha's convergents and continued fraction representation and noticed the 20th elements fail - the representation is 3 compared to 4 that I get, yielding different convergents - h[20]=335159612 on Wolfram compared to 425680601 for me.
I tested the code below, two languages (though to be fair, Python is C under the hood I guess), on two systems and get the same result - a diff on loop 20. I'll note that the convergents are still accurate and converge! Why am I getting different results compared to Wolfram Alpha, and is it possible to fix it?
For testing, here's a Python program to solve Pell's equation for D=61, printing first 20 convergents and the continued fraction representation cf (and some extra unneeded fluff):
from math import floor, sqrt # Can use mpmath here as well.
def continued_fraction(D, count=100, thresh=1E-12, verbose=False):
cf = []
h = (0, 1)
k = (1, 0)
r = start = sqrt(D)
initial_count = count
x = (1+thresh+start)*start
y = start
while abs(x/y - start) > thresh and count:
i = int(floor(r))
cf.append(i)
f = r - i
x, y = i*h[-1] + h[-2], i*k[-1] + k[-2]
if verbose is True or verbose == initial_count-count:
print(f'{x}\u00B2-{D}x{y}\u00B2 = {x**2-D*y**2}')
if x**2 - D*y**2 == 1:
print(f'{x}\u00B2-{D}x{y}\u00B2 = {x**2-D*y**2}')
print(cf)
return
count -= 1
r = 1/f
h = (h[1], x)
k = (k[1], y)
print(cf)
raise OverflowError(f"Converged on {x} {y} with count {count} and diff {abs(start-x/y)}!")
continued_fraction(61, count=20, verbose=True, thresh=-1) # We don't want to stop on account of thresh in this example
A c program doing the same:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int main() {
long D = 61;
double start = sqrt(D);
long h[] = {0, 1};
long k[] = {1, 0};
int count = 20;
float thresh = 1E-12;
double r = start;
long x = (1+thresh+start)*start;
long y = start;
while(abs(x/(double)y-start) > -1 && count) {
long i = floor(r);
double f = r - i;
x = i * h[1] + h[0];
y = i * k[1] + k[0];
printf("%ld\u00B2-%ldx%ld\u00B2 = %lf\n", x, D, y, x*x-D*y*y);
r = 1/f;
--count;
h[0] = h[1];
h[1] = x;
k[0] = k[1];
k[1] = y;
}
return 0;
}
mpmath, python's multi-precision library can be used. Just be careful that all the important numbers are in mp format.
In the code below, x, y and i are standard multi-precision integers. r and f are multi-precision real numbers. Note that the initial count is set higher than 20.
from mpmath import mp, mpf
mp.dps = 50 # precision in number of decimal digits
def continued_fraction(D, count=22, thresh=mpf(1E-12), verbose=False):
cf = []
h = (0, 1)
k = (1, 0)
r = start = mp.sqrt(D)
initial_count = count
x = 0 # some dummy starting values, they will be overwritten early in the while loop
y = 1
while abs(x/y - start) > thresh and count > 0:
i = int(mp.floor(r))
cf.append(i)
x, y = i*h[-1] + h[-2], i*k[-1] + k[-2]
if verbose or initial_count == count:
print(f'{x}\u00B2-{D}x{y}\u00B2 = {x**2-D*y**2}')
if x**2 - D*y**2 == 1:
print(f'{x}\u00B2-{D}x{y}\u00B2 = {x**2-D*y**2}')
print(cf)
return
count -= 1
f = r - i
r = 1/f
h = (h[1], x)
k = (k[1], y)
print(cf)
raise OverflowError(f"Converged on {x} {y} with count {count} and diff {abs(start-x/y)}!")
continued_fraction(61, count=22, verbose=True, thresh=mpf(1e-100))
Output is similar to wolfram's:
...
335159612²-61x42912791² = 3
1431159437²-61x183241189² = -12
1766319049²-61x226153980² = 1
[7, 1, 4, 3, 1, 2, 2, 1, 3, 4, 1, 14, 1, 4, 3, 1, 2, 2, 1, 3, 4, 1]
I would like to make a predicat reverse(N,Result) in Prolog.
For example:
reverse(12345,Result).
Result = 54321.
I have to use tail-recursion. I can use *, +, - and divmod/4 and that's all.I can't use list.
I can reverse a number < 100 but I don't find how to finish my code, I can't complete my code to reverse integers bigger than 100 correctly.
reverse(N,N):-
N <10,
N>0.
reverse(N,Result):-
N > 9,
iter(N,0,Result).
iter(N,Ac,Result):-
N < 100, !,
divmod(N,10,Q,R),
R1 is R*10,
Result is Q + R1.
Can I have some help please ?
Thanks you in advance.
I suggest the use of CLP(FD), since it offers declarative reasoning over integer arithmetic and a lot of Prolog systems provide it. Concerning the digit-reversal, I recommend you take a look at entry A004086 in The On-Line Encyclopedia of Integer Sequences. In the paragraph headed FORMULA, you'll find, among others, the following formulae:
a(n) = d(n,0) with d(n,r) = if n=0 then r else d(floor(n/10),r*10+(n mod 10))
These can be translated into a predicates by adding an additional argument for the reversed number. First let's give it a nice declarative name, say digits_reversed/2. Then the relation can be expressed using #>/2, #=/2, (/)/2, +/2, mod/2 and tail-recursion:
:- use_module(library(clpfd)).
digits_reversed(N,X) :-
digits_reversed_(N,X,0).
digits_reversed_(0,R,R).
digits_reversed_(N,X,R) :-
N #> 0,
N0 #= N/10,
R1 #= R*10 + (N mod 10),
digits_reversed_(N0,X,R1).
Note that digits_reversed/2 correspond to a(n) and digits_reversed_/3 corresponds to d(n,r) in the above formulae. Now let's query the predicate with the example from your post:
?- digits_reversed(12345,R).
R = 54321 ;
false.
The predicate can also be used in the other direction, that is ask What number has been reversed to obtain 54321? However, since leading zeros of numbers are omitted one reversed number has infinitely many original numbers:
?- digits_reversed(N,54321).
N = 12345 ;
N = 123450 ;
N = 1234500 ;
N = 12345000 ;
N = 123450000 ;
N = 1234500000 ;
N = 12345000000 ;
N = 123450000000 ;
.
.
.
Even the most general query yields solutions but you'll get residual goals as an answer for numbers with more than one digit:
?- digits_reversed(N,R).
N = R, R = 0 ; % <- zero
N = R,
R in 1..9 ; % <- other one-digit numbers
N in 10..99, % <- numbers with two digits
N mod 10#=_G3123,
N/10#=_G3135,
_G3123 in 0..9,
_G3123*10#=_G3159,
_G3159 in 0..90,
_G3159+_G3135#=R,
_G3135 in 1..9,
R in 1..99 ;
N in 100..999, % <- numbers with three digits
N mod 10#=_G4782,
N/10#=_G4794,
_G4782 in 0..9,
_G4782*10#=_G4818,
_G4818 in 0..90,
_G4818+_G4845#=_G4842,
_G4845 in 0..9,
_G4794 mod 10#=_G4845,
_G4794 in 10..99,
_G4794/10#=_G4890,
_G4890 in 1..9,
_G4916+_G4890#=R,
_G4916 in 0..990,
_G4842*10#=_G4916,
_G4842 in 0..99,
R in 1..999 ;
.
.
.
To get actual numbers with the query above, you have to restrict the range of N and label it after the predicate has posted the arithmetic constraints:
?- N in 10..20, digits_reversed(N,R), label([N]).
N = 10,
R = 1 ;
N = R, R = 11 ;
N = 12,
R = 21 ;
N = 13,
R = 31 ;
N = 14,
R = 41 ;
N = 15,
R = 51 ;
N = 16,
R = 61 ;
N = 17,
R = 71 ;
N = 18,
R = 81 ;
N = 19,
R = 91 ;
N = 20,
R = 2 ;
false.
If for some reason you don't want a constraints based solution, or if you using a Prolog system not supporting constraints, an alternative solution is:
reverse_digits(N, M) :-
( integer(N) ->
reverse_digits(N, 0, M)
; integer(M),
reverse_digits(M, 0, N)
).
reverse_digits(0, M, M) :- !.
reverse_digits(N, M0, M) :-
N > 0,
R is N div 10,
M1 is M0 * 10 + N mod 10,
reverse_digits(R, M1, M).
This solution can be used with either argument bound to an integer and leaves no spurious choice-points:
?- reverse_digits(12345, M).
M = 54321.
?- reverse_digits(N, 12345).
N = 54321.
?- reverse_digits(12345, 54321).
true.
But note that this solution, unlike the constraints based solution, cannot be used as a generator of pairs of integers that satisfy the relation:
?- reverse_digits(N, M).
false.
reverseNumber(N,R):-reverse_acc(N,0,R).
reverse_acc(0,Acc,Acc).
reverse_acc(N,Acc,R):- C is N mod 10, N1 is N div 10,
Acc1 is Acc * 10 + C,
reverse_acc(N1, Acc1,R).