Algorithm for functions permutating integers - algorithm

I want to write some functions as follows
y = f(x) and another function,
x = g(y) that acts as a reversible, where
y = f(g(y)) and where x and y are permutated integers.
For very simple example in the range of integers in 0 to 10 it would look like this:
0->1
1->2
2->3
...
9->10
10->0
but this is the simplest method by adding 1 and reversing by subtracting 1.
I want to have a more sofisticated algorithm that can do the following,
234927773->4299
34->33928830
850033->23234243423
but the reverse can be obtained by conversion
The solution could be obtained with a huge table storing pairs of unique integers but this will not be correct. This must be a function.

You could just XOR.
y = x XOR p
x = y XOR p
Though not my area of expertise, I think that cryptography should provide some valuable answers to your question.

If the domain of your permutation is a power of 2, you can use any block cipher: 'f' is encryption with a specific key, and 'g' is decryption with the same key. If your domain is not a power of 2, you can probably still use a block cipher: see this article.

You could use polynomial interpolation methods to interpolate a function one way, then do reverse interpolation to find the inverse function.
Here is some example code in MATLAB:
function [a] = Coef(x, y)
n = length(x);
a = y;
for j = 2:n
for i = n:-1:j
a(i) = (a(i) - a(i-1)) / (x(i) - x(i-j+1));
end
end
end
function [val] = Eval(x, a, t)
n = length(x);
val = a(n);
for i = n-1:-1:1
val = a(i) + val*(t-x(i));
end
end
It builds a Divided Difference table and evaluates a function based on Newtons Interpolation.
Then if your sets of points are x, and y (as vectors of the same length, where x(i) matches to y(i), your forward interpolation function at value n would be Eval(x, Coef(x, y), n) and the reverse interpolation function would be Eval(y, Coef(y, x), n).
Depending on your language, there are probably much cleaner ways to do this, but this gets down and dirty with the maths.
Here is an excerpt from the Text Book which is used in my Numerical Methods class: Google Book Link

Related

Julia JuMP array variable constraint

I am trying to model a non-linear problem involving vector rotation using JuMP in Julia. I need a constraint, which looks something like v[1:3] == rotate(v) If I write it like this, it does not work, since "Nonlinear expressions may contain only scalar expressions". How can I work around this?
I could say something like v[1] == rotate(v)[1] and same for v[2] and v[3], but then I would have to compute rotate(v) three times as often. I could also try to split the rotate function into three functions which compute one element each, but the actual constraint is a bit more complicated than a simple rotation, so this could prove to be tricky.
Are there any other ways to do this? Maybe to have something like an auxiliary variable which can be computed as a vector and then in the constraint only compare the elements of the two vectors (essentialy the first approach, but without computing the function three times)?
See here for a suggested work-around:
https://discourse.julialang.org/t/how-to-set-up-nlconstraints-from-multi-output-user-defined-function/42309/5?u=odow
using JuMP
using Ipopt
function myfun(x)
return sum(xi for xi in x), sum(xi^2 for xi in x)
end
function memoized()
cache = Dict{UInt, Any}()
fi = (i, x) -> begin
h = hash((x, typeof(x)))
if !haskey(cache, h)
cache[h] = myfun(x)
end
return cache[h][i]::Real
end
return (x...) -> fi(1, x), (x...) -> fi(2, x)
end
model = Model(Ipopt.Optimizer)
f1, f2 = memoized()
register(model, :f1, 3, f1; autodiff = true)
register(model, :f2, 3, f2; autodiff = true)
#variable(model, x[1:3] >= 0, start = 0.1)
#NLconstraint(model, f1(x...) <= 2)
#NLconstraint(model, f2(x...) <= 1)
#objective(model, Max, sum(x))
optimize!(model)

Checking that a matrix is positive semidefinite with a given rank (in Julia)

I am writing a function that checks if a matrix X is positive semidefinite with a given rank k. To do this, I compute the eigenvalues of X, and I check that exactly k of them are positive and the rest are 0. Here's what I have so far:
using LinearAlgebra
function ispossemdef(X::AbstractMatrix, k::Int, ϵ::Real = 1e-10)
n = size(X, 1) # dim of X
!issymmetric(X) && return false # short-circuit if X is asymmetric
k > n && error("k > n") # throw error if k > n
eigs = eigvals(X) # eigenvalues of X in ascending order
z = eigs[1:(n - k)] # the values that should be zero
p = eigs[(n - k + 1):end] # the values that should be positive
n_minus_k_zero_eigenvalues = norm(z) < ϵ
k_positive_eigenvalues = all(p .> ϵ)
return n_minus_k_zero_eigenvalues & k_positive_eigenvalues
end
Is there a better algorithm for doing this? Better might mean faster (avoids computing the eigenvalues), or more numerically stable (lets me get away with a stricter error tolerance).
For example, the isposdef function (which is the k = n special case of what I'm doing) works by attempting to compute the Cholesky factor of X, and reporting back with whether or not it could. Can I generalize this procedure to semidefinite matrices? If so, is it better than checking the eigenvalues?
It will not work on all matrices, but have you looked at
using LinearAlgebra # for julia 1+
help> isposdef
at the isposdef() function?

Optimizing computational cost on a task involving a multi-nested loop

I am just a beginner of programming, and sorry in advance for bothering you by a (presumably) basic question.
I would like to perform the following task:
(I apologize for inconvenience; I don't know how to input a TeX-y formula in Stack Overflow ). I am primarily considering an implementation on MATLAB or Scilab, but language does not matter so much.
The most naive approach to perform this, I think, is to form an n-nested for loop, that is (the case n=2 on MATLAB is shown for example),
n=2;
x=[x1,x2];
for u=0:1
y(1)=u;
if x(1)>0 then
y(1)=1;
end
for v=0:1
y(2)=v;
if x(2)>0 then
y(2)=1;
end
z=Function(y);
end
end
However, this implementation is too laborious for large n, and more importantly, it causes 2^n-2^k abundant evaluations of the function, where k is a number of negative elements in x. Also, naively forming a k-nested for loop with knowledge of which element in x is negative, e.g.
n=2;
x=[-1,2];
y=[1,1];
for u=0:1
y(1)=u;
z=Function(y);
end
doesn't seem to be a good way; if we want to perform the task for different x, we have to rewrite a code.
I would be grateful if you provide an idea to implement a code such that (a) evaluates the function only 2^k times (possible minimum number of evaluations) and (b) we don't have to rewrite a code even if we change x.
You can evaluate Function on y in Ax easily using recursion
function eval(Function, x, y, i, n) {
if(i == n) {
// break condition, evaluate Function
Function(y);
} else {
// always evaluate y(i) == 1
y(i) = 1;
eval(Function, x, y, i + 1, n);
// eval y(i) == 0 only if x(i) <= 0
if(x(i) <= 0) {
y(i) = 0;
eval(Function, x, y, i + 1, n);
}
}
}
Turning that into efficient Matlab code is another problem.
As you've stated the number of evaluations is 2^k. Let's sort x so that only the last k elements are non-positive. To evaluate Function index y using the reverse of the permutation of the sort of x: Function(y(perm)). Even better the same method allows us to build Ax directly using dec2bin:
// every column of the resulting matrix is a member of Ax: y_i = Ax(:,i)
function Ax = getAx(x)
n = length(x);
// find the k indices of non-positives in x
is = find(x <= 0);
k = length(is);
// construct Y (last k rows are all possible combinations of [0 1])
Y = [ones(n - k, 2 ^ k); (dec2bin(0:2^k-1)' - '0')];
// re-order the rows in Y to get Ax according to the permutation is (inverse is)
perm([setdiff(1:n, is) is]) = 1:n;
Ax = Y(perm, :);
end
Now rewrite Function to accept a matrix or iterate over the columns in Ax = getAx(x); to evaluate all Function(y).

How to solve this non 0-1 integer Knapsack_Problem in Ruby

Question:
Minimising x1+x2+...+xn
Known k1*x1+k2*x2+...kn*xn = T
k1,k2,...,kn and T are known integers and > 0
k1 > k2 > k3 > ... > kn
All the x are also integers and >= 0
Find all the x
I was trying to use Rglpk and Glpk. But I can't find an example with only one row of matrix. Is this Integer programming? And is it solvable? Many thanks.
Some Ruby codes I wrote:
ks = [33, 18, 15, 5, 3]
t = 999
problem = Rglpk::Problem.new
problem.name = "test"
problem.obj.dir = Rglpk::GLP_MIN
rows = problem.add_rows(1)
rows[0].name = "sum of x equals t"
rows[0].set_bounds(Rglpk::GLP_UP, t, t)
cols = problem.add_cols(ks.size)
ks.each_with_index do |k,index|
cols[index].name = "k: #{k}"
cols[index].set_bounds(Rglpk::GLP_LO, 0.0, 0.0)
end
problem.obj.coefs = Array.new(ks.size, 1)
problem.set_matrix(ks)
problem.simplex
minimum_x_sum = problem.obj.get
xs = []
cols.each do |col|
xs << col.get_prim
end
xs
Yes, it is an integer program, a rather famous one, the so-called "knapsack problem". You therefore can solve it with either of the packages you mention (provided the number of variables is not too great) but a much more efficient approach is to use dynamic programming (see the above link). The use of DP here is quite simple to implement. This is one Ruby implementation I found by Googling.
I should mention a few related tidbits. Firstly, your constraint is an equality constraint:
k1x1 + k2x2 +...+ knxn = T
but this is normally assumed to be an inequality by (DP) knapsack algorithms:
k1x1 + k2x2 +...+ knxn <= T
To deal with an equality constraint you can either modify the algorithm slightly, or add the term:
M*(T - x1 + x2 +...+ xn)
to the objective you are minimizing, where M is a very large number (106, perhaps), thereby forcing equality at the optimal solution. (When expanded, the coefficient for each xi becomes 1-M. The constant term MT can be disregarded.)
Two more details:
DP algorithms permit the variables in the objective to have coefficients other than 1 (and there is no gain in efficiency when all the coefficients equal 1); and
If the DP algorithm maximizes (rather than minimizes) the objective, you can simply negate the coefficients of the variables in the objective to obtain an optimal solution to the minimization problem.

Improving performance of interpolation (Barycentric formula)

I have been given an assignment in which I am supposed to write an algorithm which performs polynomial interpolation by the barycentric formula. The formulas states that:
p(x) = (SIGMA_(j=0 to n) w(j)*f(j)/(x - x(j)))/(SIGMA_(j=0 to n) w(j)/(x - x(j)))
I have written an algorithm which works just fine, and I get the polynomial output I desire. However, this requires the use of some quite long loops, and for a large grid number, lots of nastly loop operations will have to be done. Thus, I would appreciate it greatly if anyone has any hints as to how I may improve this, so that I will avoid all these loops.
In the algorithm, x and f stand for the given points we are supposed to interpolate. w stands for the barycentric weights, which have been calculated before running the algorithm. And grid is the linspace over which the interpolation should take place:
function p = barycentric_formula(x,f,w,grid)
%Assert x-vectors and f-vectors have same length.
if length(x) ~= length(f)
sprintf('Not equal amounts of x- and y-values. Function is terminated.')
return;
end
n = length(x);
m = length(grid);
p = zeros(1,m);
% Loops for finding polynomial values at grid points. All values are
% calculated by the barycentric formula.
for i = 1:m
var = 0;
sum1 = 0;
sum2 = 0;
for j = 1:n
if grid(i) == x(j)
p(i) = f(j);
var = 1;
else
sum1 = sum1 + (w(j)*f(j))/(grid(i) - x(j));
sum2 = sum2 + (w(j)/(grid(i) - x(j)));
end
end
if var == 0
p(i) = sum1/sum2;
end
end
This is a classical case for matlab 'vectorization'. I would say - just remove the loops. It is almost that simple. First, have a look at this code:
function p = bf2(x, f, w, grid)
m = length(grid);
p = zeros(1,m);
for i = 1:m
var = grid(i)==x;
if any(var)
p(i) = f(var);
else
sum1 = sum((w.*f)./(grid(i) - x));
sum2 = sum(w./(grid(i) - x));
p(i) = sum1/sum2;
end
end
end
I have removed the inner loop over j. All I did here was in fact removing the (j) indexing and changing the arithmetic operators from / to ./ and from * to .* - the same, but with a dot in front to signify that the operation is performed on element by element basis. This is called array operators in contrast to ordinary matrix operators. Also note that treating the special case where the grid points fall onto x is very similar to what you had in the original implementation, only using a vector var such that x(var)==grid(i).
Now, you can also remove the outermost loop. This is a bit more tricky and there are two major approaches how you can do that in MATLAB. I will do it the simpler way, which can be less efficient, but more clear to read - using repmat:
function p = bf3(x, f, w, grid)
% Find grid points that coincide with x.
% The below compares all grid values with all x values
% and returns a matrix of 0/1. 1 is in the (row,col)
% for which grid(row)==x(col)
var = bsxfun(#eq, grid', x);
% find the logical indexes of those x entries
varx = sum(var, 1)~=0;
% and of those grid entries
varp = sum(var, 2)~=0;
% Outer-most loop removal - use repmat to
% replicate the vectors into matrices.
% Thus, instead of having a loop over j
% you have matrices of values that would be
% referenced in the loop
ww = repmat(w, numel(grid), 1);
ff = repmat(f, numel(grid), 1);
xx = repmat(x, numel(grid), 1);
gg = repmat(grid', 1, numel(x));
% perform the calculations element-wise on the matrices
sum1 = sum((ww.*ff)./(gg - xx),2);
sum2 = sum(ww./(gg - xx),2);
p = sum1./sum2;
% fix the case where grid==x and return
p(varp) = f(varx);
end
The fully vectorized version can be implemented with bsxfun rather than repmat. This can potentially be a bit faster, since the matrices are not explicitly formed. However, the speed difference may not be large for small system sizes.
Also, the first solution with one loop is also not too bad performance-wise. I suggest you test those and see, what is better. Maybe it is not worth it to fully vectorize? The first code looks a bit more readable..

Resources