local variable T conflicts with a static parameter warining - class

I'm getting warning that I don't understand.
I first run the following code:
type PDF{T <: Real}
š›‘::Vector{Float64} # K
Ī¼s::Matrix{T} # D x K
Ī£s::Vector{Matrix{T}} # K{D x D}
end
type Q{T <: Real}
w::Union{Float64, Vector{Float64}}
Ī¼pair::Union{Vector{T}, Matrix{T}}
Ī£pair::Union{Matrix{T}, Tuple{Matrix{T}, Matrix{T}} } # K{D x D}
end
type Smod{T <: Real}
H::Matrix{T} # D x D
Ī£s::Vector{Matrix{T}} # K{D x D}
qs::Vector{Q{T}}
end
type Scale{T <: Real}
Ī¼::Vector{T} # D
Ī£::Matrix{T} # D x D
end
type Parameters{T <: Real}
scale::Scale{T}
w::Vector{Float64}
maxNumCompsBeforeCompression::Integer
numComponentsAbsorbed::Integer
end
type KDE{T}
pdf::PDF{T}
smod::Smod{T}
params::Parameters{T}
end
And when after this I run the following snippet in IJulia
function initializeKDE{T <: Real}(x::Vector{T})
d = size(x,1)
T = typeof(x)
š›‘ = ones(Float64, 1)
Ī¼s = Array(T, d,1)
Ī¼s[:,1] = x
Ī£s = Array(Matrix{T}, 0)
pdf = PDF(š›‘, Ī¼s, Ī£s)
H = zeros(T, d,d)
qs = Array(Q{T}, 0)
smod = Smod(H, Ī£s, qs)
scale = Scale(x, H)
w = [0.0, 1.0]
maxNumCompsBeforeCompression = min(10, (0.5d^2 + d))
numComponentsAbsorbed = 0
params = Params(scale, w, maxNumCompsBeforeCompression, numComponentsAbsorbed)
kde = KDE(pdf, smod, params)
return kde::KDE
end
I get the following warning:
WARNING: local variable T conflicts with a static parameter in initializeKDE at In[4]:3.
where In[4]:3 corresponds to the 3rd line of the 2nd snippet.
Can anyone explain in human english what this warning is saying?

This is saying that you are trying to use T in two different ways: once as a "static parameter" and once as a local variable.
Firstly, you are using T as the parameter with which you are parametrising the function initializeKDE:
function initializeKDE{T <: Real}(x::Vector{T})
But then you are trying to redefine a new T in that third line:
T = typeof(x)
What are you trying to do here? If you are trying to define T to be the type of the elements that the vector x contains, then you should just delete this line and everything should just work -- T will automatically take the element type (eltype) of the vector that you pass to the initializeKDE function.

Related

MiniZinc: build a connectivity matrix

In MiniZinc, I have an array of boolean representing an oriented connection between nodes of a graph:
array[Variants,Variants] of bool : VariantIsDirectlyUpwardOf;
VariantIsDirectlyUpwardOf[v1,v2] = true if there is an oriented arc "v1 -> v2".
now I want to build
array[Variants,Variants] of bool VariantIsUpwardOf;
where VariantIsUpwardOf[v1,v2] = true if there is an oriented path "v1 -> ... -> v2" where "..." is a sequence of nodes defining an oriented path of any length going from v1 to v2.
My first try was to define a transitive kind of constraint
array[Variants,Variants] of var bool : VariantIsUpwardOf;
constraint forall (v1 in Variants, v2 in Variants)(VariantIsDirectlyUpwardOf[v1,v2]->VariantIsUpwardOf[v1,v2]);
constraint forall (v1 in Variants, v2 in Variants, v3 in Variants)( VariantIsUpwardOf[v1,v2] /\ VariantIsUpwardOf[v2,v3] -> VariantIsUpwardOf[v1,v3]);
but I think this is incorrect because if all values of VariantIsUpwardOf[v1,v2] were true, then my constraints would be satisfied and the result would be incorrect.
Following the comment (thanks Axel), I made a second unsuccessful test using predicate dpath, here is my very basic test calling dpath::
include "path.mzn";
enum MyNodes={N1,N2};
array [int] of MyNodes: EdgeFrom=[N1];
array [int] of MyNodes: EdgeTo= [N2];
array [MyNodes] of bool: NodesInSubGraph = [true, true];
array [int] of bool: EdgesInSubGraph = [true];
var bool : MyTest = dpath(EdgeFrom,EdgeTo,N1,N2,NodesInSubGraph,EdgesInSubGraph);
output [show(MyTest)];
it produces the following error:
Running MiniTest.mzn
221msec
fzn_dpath_enum_reif:3.3-52
in call 'abort'
MiniZinc: evaluation error: Abort: Reified dpath constraint is not supported
Process finished with non-zero exit code 1.
Finished in 221msec.
The following MiniZinc model demonstrates the usage of the dpath() predicate to find a directed path in a graph.
I took the directed graph from Wikipedia as example:
The model:
include "globals.mzn";
int: Nodes = 4;
bool: T = true; % abbreviate typing
bool: F = false;
set of int: Variants = 1..Nodes;
% VariantIsDirectlyUpwardOf[v1,v2] = true if there is an oriented arc "v1 -> v2".
% Example from https://en.wikipedia.org/wiki/Directed_graph
array[Variants,Variants] of bool : VariantIsDirectlyUpwardOf =
[| F, T, T, F,
| F, F, F, F,
| F, T, F, T,
| F, F, T, F |];
% count the number of Edges as 2D array sum
int: NoOfEdges = sum(VariantIsDirectlyUpwardOf);
set of int: Edges = 1..NoOfEdges;
% for dpath(), the graph has to be represented as two
% 'from' 'to' arrays of Nodes
% cf. https://www.minizinc.org/doc-2.6.4/en/lib-globals-graph.html
array[Edges] of Variants: fromNodes =
[row | row in Variants, col in Variants
where VariantIsDirectlyUpwardOf[row, col]];
array[Edges] of Variants: toNodes =
[col | row in Variants, col in Variants
where VariantIsDirectlyUpwardOf[row, col]];
% arbitrary choice of Nodes to be connected by a directed path
Variants: sourceNode = 4;
Variants: destNode = 2;
% decision variables as result of the path search
array[Variants] of var bool: nodesInPath;
array[Edges] of var bool: edgesInPath;
constraint dpath(fromNodes, toNodes, sourceNode, destNode, nodesInPath, edgesInPath);
% determine next node after nd in path
function int: successor(int: nd) =
min([s | s in Variants, e in Edges where
fix(nodesInPath[s]) /\ fix(edgesInPath[e]) /\
(fromNodes[e] = nd) /\ (toNodes[e] = s)]);
function string: showPath(int: nd) =
if nd = destNode then "\(nd)" else "\(nd)->" ++ showPath(successor(nd)) endif;
output [showPath(sourceNode)];
Resulting output:
4->3->2

Callback in Bender's decomposition

I am learning Bender's decomposition method and I want to use that in a small instance. I started from "bendersatsp.py" example in CPLEX. When I run this example with my problem, I got the following error. Could you please let me know what the problem is and how I can fix it? In the following you can see the modifications in lazy constraints function. I have two decision variables in master problem "z_{ik}" and "u_{k}" that would incorporate as constant in the workerLp.
class BendersLazyConsCallback(LazyConstraintCallback):
def __call__(self):
print("shoma")
v = self.v
u = self.u
z = self.z
print ("u:", u)
print ("z:", z)
workerLP = self.workerLP
boxty = len(u)
#scenarios=self.scenarios2
ite=len(z)
print ("ite:", ite)
print ("boxty:", boxty)
# Get the current x solution
sol1 = []
sol2 = []
sol3 = []
print("okkkk")
for k in range(1, boxty+1):
sol1.append([])
sol1[k-1]= [self.get_values(u[k-1])];
print ("sol1:", sol1[k-1])
for i in range(1, ite+1):
sol2.append([])
sol2[i-1]= self.get_values(z[i-1]);
print ("sol2:", sol2[i-1])
for i in range(1, ite+1):
sol3.append([])
sol3[i-1]= self.get_values(v[i-1]);
#print ("sol3:", sol3[i-1])
# Benders' cut separation
if workerLP.separate(sol3,sol1,sol2,v,u,z):
self.add(cut = workerLP.cutLhs, sense = "G", rhs = workerLP.cutRhs)
CPLEX Error 1006: Error during callback.
benders(sys.argv[1][0], datafile)
cpx.solve()
_proc.mipopt(self._env._e, self._lp)
check_status(env, status)
raise callback_exception
TypeError: unsupported operand type(s) for +: 'int' and 'list'

Julia macro for transforming `f(dim1,dim2,..) = value` into `f(value,dim1,dim2,..)`

I am trying to write a Julia macro that transforms this:
[par1!( par2(d1,d2)+par3(d1,d2) ,d1,d2,dfix3) for d1 in DIM1, d2 in DIM2]
(not very inspiring) into something much more readable, like this:
#meq par1!(d1 in DIM1, d2 in DIM2, dfix3) = par2(d1,d2)+par3(d1,d2)
where par1!() is a function to set some multi-dimensional data and par2() is a getData()-type of function.
I am trying to implement it using a macro, but as I am on my first experience with julia marcro, I'm not sure how to "assemble" the final expression from the various pieces..
Here is what I done so far:
macro meq(eq)
# dump(eq)
lhs_par = eq.args[1].args[1]
rhs = eq.args[2]
lhs_dims = eq.args[1].args[2:end]
loop_counters = [d.args[2] for d in lhs_dims if typeof(d) == Expr]
loop_sets = [d.args[3] for d in lhs_dims if typeof(d) == Expr]
loop_wholeElements = [d for d in lhs_dims if typeof(d) == Expr]
lhs_dims_placeholders = []
for d in lhs_dims
if typeof(d) == Expr
push!(lhs_dims_placeholders,d.args[2])
else
push!(lhs_dims_placeholders,d)
end
end
outExp = quote
[$(lhs_par)($(rhs),$(lhs_dims_placeholders ...)) for $(loop_wholeElements ...) ]
end
#show(outExp)
return outExp
end
However the above macro doesn't compile and returns a syntax error (ā€œinvalid iteration specificationā€) due to the for $(loop_wholeElements) partā€¦ indeed I donā€™t know how to treat the expressions in lhs_dims_placeholders and loop_wholeElements in order to ā€œassembleā€ the expanded expressionā€¦
EDIT:
The example posted, with d1, d2 and dfix3, is only a specific case, but the macro should be able to handle whichever dimensions are looped for..
I think the macro up there does that, but I don't know how to build the final expression.. :-(
Instead of manually doing those hard-coded args matching stuff, we could use MacroTools.jl as a handy tool for template matching:
julia> using MacroTools
julia> macro meq(ex)
#capture(ex, f_(d1_ in dim1_, d2_ in dim2_, dfix3_) = body__)
ret = :([$f($(body[]), $d1, $d2, $dfix3) for $d1 in $dim1, $d2 in $dim2])
end
#meq (macro with 1 method)
julia> prettify(#macroexpand #meq par1!(d1 in DIM1, d2 in DIM2, dfix3) = par2(d1,d2)+par3(d1,d2))
:([(Main.par1!)((Main.par2)(lobster, redpanda) + (Main.par3)(lobster, redpanda), lobster, redpanda, Main.dfix3) for lobster = Main.DIM1, redpanda = Main.DIM2])
UPDATE:
The desired final expression is a comprehension, it seems that for some reason Julia couldn't figure out for expr(where $expr #=> XXX in XXX) is a comprehension. The workaround is directly using its lowered form:
julia> using MacroTools
julia> par1(a, b, c, d) = a + b + c + d
par1 (generic function with 1 method)
julia> par2(a, b) = a + b
par2 (generic function with 1 method)
julia> macro meq(ex)
#capture(ex, par_(dims__) = rhs_)
loopElements = []
dimsPlaceholders = []
for d in dims
#capture(d, di_ in DIMi_) || (push!(dimsPlaceholders, d); continue)
# push!(loopElements, x)
push!(loopElements, :($di = $DIMi))
push!(dimsPlaceholders, di)
end
ret = Expr(:comprehension, :($par($(rhs),$(dimsPlaceholders...))), loopElements...)
end
#meq (macro with 1 method)
julia> prettify(#macroexpand #meq par1!(d1 in DIM1, d2 in DIM2, dfix3) = par2(d1,d2)+par3(d1,d2))
:($(Expr(:comprehension, :((Main.par1!)(begin
(Main.par2)(bee, wildebeest) + (Main.par3)(bee, wildebeest)
end, bee, wildebeest, Main.dfix3)), :(bee = Main.DIM1), :(wildebeest = Main.DIM2))))
julia> #meq par1(m in 1:2, n in 4:5, 3) = par2(m,n) + par2(m,n)
2Ɨ2 Array{Int64,2}:
18 21
21 24
Note that, the variable scope of d1,d2 in generated expression will be wrong if we use push!(loopElements, x) rather than push!(loopElements, :($di = $DIMi)). Let's wait for someone knowledgeable to give a thorough explanation.
If you do not want to rely on an external package for this, the solution I provided on the Julia discourse should also work
return :([$(Expr(:generator,:($(Expr(:call,lhs_par,rhs,lhs_dims_placeholders...))),loop_wholeElements...))])
The key is to use the :generator constructor to make the loop expression
Also, rhs can be replaced with rhs.args[n] in order to eliminate the quote block and insert the expression directly.
This then produces the exact expression:
:([(par1!(par2(d1, d2) + par3(d1, d2), d1, d2, dfix3) for d1 in DIM1, d2 in DIM2)])
EDIT:
Alright, so I went ahead and tested this:
return Expr(:comprehension,Expr(:generator,Expr(:call,lhs_par,rhs.args[2],lhs_dims_placeholders...),loop_wholeElements...))
end
Then computing the result like this
meq(:(par1!(d1 = 1:2, d2 = 1:2, 3) = par2(d1,d2)+par3(d1,d2))) |> eval

Imprecise Assigned value

In a simple program I want to build a matrix by defining a function. The problem is that a variable declared and initialized in the program has the exact assinged value of zero (zero_test)and some components of the matrix(D(4,1), D(1,4) etc.) which are assigned to 0., are not exactly zero. The latter have a value of order E-308 or E-291etc. I wonder why is there a difference.
Due to some articles I read, like this, the other components(D(1,1), D(1,2) etc.) are imprecise because of the transformation to the binary format.
System info: IA-32, Intel Visual Fortran 11.1.048 integrated with Microsoft Visual Studio 2008
The code:
program test
implicit none
real(8),parameter :: LAMBDA=75.e9,MU=50.e9
integer,parameter :: ndi=3,ntens=4
real(8) :: D(ntens,ntens),zero_test=0.
D = clcElasticStiffnessMatrix(LAMBDA,MU,ndi,ntens)
contains
function clcElasticStiffnessMatrix(LAMBDA,MU,ndi,ntens)
implicit none
integer :: ndi,ntens,i,j
real(8) :: clcElasticStiffnessMatrix(ntens,ntens),LAMBDA,MU
do i=1,ndi
do j=i,ndi
if(i .eq. j) then
clcElasticStiffnessMatrix(i,j) = 2.*MU + LAMBDA
else
clcElasticStiffnessMatrix(i,j) = LAMBDA
clcElasticStiffnessMatrix(j,i) = clcElasticStiffnessMatrix(i,j)
end if
end do
end do
do i=ndi+1,ntens
do j=i,ntens
if(i .eq. j) then
clcElasticStiffnessMatrix(i,j) = MU
else
clcElasticStiffnessMatrix(i,j) = 0.
clcElasticStiffnessMatrix(j,i) = clcElasticStiffnessMatrix(i,j)
end if
end do
end do
end function
end program
Matrix D in break mode:
D:
174999994368.000 74999996416.0000 74999996416.0000 2.641443384627243E-308
74999996416.0000 174999994368.000 74999996416.0000 2.640433316727162E-308
74999996416.0000 74999996416.0000 174999994368.000 -1.051992669438322E-291
2.640110775815455E-308 0.000000000000000E+000 6.151018477594351E-318 49999998976.0000
The problem is that you are assigning real(4) values to real(8) variables when you write
LAMBDA=75.e9,MU=50.e9
or
clcElasticStiffnessMatrix(i,j) = 0.
Try with d instead e and specify always:
LAMBDA=75.d9,MU=50.d9
clcElasticStiffnessMatrix(i,j) = 0.d0

Input argument "b" is undefined

i am new in matlab and search everything. I am writing a the function. i could not able to understand why this error is comning :"Input argument "b" is undefined." . shall i intialise b =0 ? whereas it is the parameter coming from input console. my code:
function f = evenorodd( b )
%UNTITLED2 Summary of this function goes here
%zohaib
% Detailed explanation goes here
%f = b;%2;
f = [0 0];
f = rem(b,2);
if f == 0
disp(b+ 'is even')
else
disp(b+ 'is odd')
end
console:
??? Input argument "b" is undefined.
Error in ==> evenorodd at 6
f = rem(b,2);
From what I see, this is what you are trying to do:
function f = evenorodd( b )
f = rem(b,2);
if f == 0
fprintf('%i is even\n', b)
else
fprintf('%i is odd\n', b)
end
=======================
>> evenorodd(2);
2 is even
No need to initialize f as [0,0].
In MATLAB, you cant concatenate a number and string with + operator. Use fprintf.
The above function evenorodd takes one argument (integer) and returns 0 or 1.