Is it possible to alias multiple names in a numpy record array? - numpy

Suppose I construct a numpy record array like this
num_rows = <whatever>
data = np.zeros(
(num_rows,),
dtype={
'names':['apple', 'banana'],
'formats': ['f8', 'f8']
}
Now I can access data either by name or index.
For example, the following are the same:
data['banana'][0]
and
data[0]['banana']
etc.
Is there a way to alias different names?
For example, can I set things up so that there's another name manzana such that
data['manzana']
is the same thing as
data['apple']
?

['offsets' and 'titles' are 2 mechanisms for giving different names to fields]
There is an offset parameter that can function in this way. Usually it is used to split another field into several pieces (e.g. an int into bytes). But it also works with identical fields. In effect it defines several fields with overlapping data.
In [743]: dt=np.dtype({'names':['apple','manzana','banana','guineo'],
'formats':['f8','f8','f8','f8'],
'offsets':[0,0,8,8]})
In [745]: np.zeros((3,),dtype=dt)
Out[745]:
array([(0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0)],
dtype={'names':['apple','manzana','banana','guineo'],
'formats':['<f8','<f8','<f8','<f8'],
'offsets':[0,0,8,8], 'itemsize':16})
In [746]: A=np.zeros((3,),dtype=dt)
In [747]: A['banana']=[1,2,3]
In [748]: A
Out[748]:
array([(0.0, 0.0, 1.0, 1.0),
(0.0, 0.0, 2.0, 2.0),
(0.0, 0.0, 3.0, 3.0)],
dtype={'names':['apple','manzana','banana','guineo'], 'formats':['<f8','<f8','<f8','<f8'], 'offsets':[0,0,8,8], 'itemsize':16})
In [749]: A['guineo']
Out[749]: array([ 1., 2., 3.])
In [750]: A['manzana']=[.1,.2,.3]
In [751]: A['apple']
Out[751]: array([ 0.1, 0.2, 0.3])
In [752]: A
Out[752]:
array([(0.1, 0.1, 1.0, 1.0),
(0.2, 0.2, 2.0, 2.0),
(0.3, 0.3, 3.0, 3.0)],
dtype={'names':['apple','manzana','banana','guineo'], 'formats':['<f8','<f8','<f8','<f8'], 'offsets':[0,0,8,8], 'itemsize':16})
There's another dtype parameter, titles that is better suited to your needs, and easier to understand:
http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html
In [792]: dt1=np.dtype({'names':['apple','banana'],'formats':['f8','f8'], 'titles':['manzana', 'guineo'], 'offsets':[0,8]})
In [793]: A1=np.zeros((3,),dtype=dt1)
In [794]: A1
Out[794]:
array([(0.0, 0.0), (0.0, 0.0), (0.0, 0.0)],
dtype=[(('manzana', 'apple'), '<f8'), (('guineo', 'banana'), '<f8')])
In [795]: A1['apple']=[1,2,3]
In [796]: A1['guineo']=[.1,.2,.3]
In [797]: A1
Out[797]:
array([(1.0, 0.1), (2.0, 0.2), (3.0, 0.3)],
dtype=[(('manzana', 'apple'), '<f8'), (('guineo', 'banana'), '<f8')])
In [798]: A1['banana']
Out[798]: array([ 0.1, 0.2, 0.3])

I have put the answer of #hpaulj into a simple method and share it here in case someone wants to use it.
def add_alias(arr, original, alias):
"""
Adds an alias to the field with the name original to the array arr.
Only one alias per field is allowed.
"""
if arr.dtype.names is None:
raise TypeError("arr must be a structured array. Use add_name instead.")
descr = arr.dtype.descr
try:
index = arr.dtype.names.index(original)
except ValueError:
raise ValueError("arr does not have a field named '" + str(original)
+ "'")
if type(descr[index][0]) is tuple:
raise ValueError("The field " + str(original) +
" already has an alias.")
descr[index] = ((alias, descr[index][0]), descr[index][1])
arr.dtype = np.dtype(descr)
return arr
def add_name(arr, name):
"""
Adds a name to the data of an unstructured array.
"""
if arr.dtype.names is not None:
raise TypeError("arr must not be a structured array. "
+ "Use add_alias instead.")
arr.dtype = np.dtype([(name, arr.dtype.name)])
return arr

Related

Julia Jump : Getting all feasible solutions to mip

I would like to have instead of only the vector of optimal solution to a mip , all the feasible (suboptimal) vectors.
I found some old questions here, but I am not sure how they work.
First of all, is there any new library tool/way to do that automatically ?
I tried this but, it did nothing:
if termination_status(m) == MOI.FEASIBLE_POINT
println(x)
end
optimize!(m);
If not, what's the easiest way?
I thought of scanning the optimal solution till I find the first non -zero decision variable, then constraint this variable to be zero and solving the model again.
for i in 1:active_variables
if value.(z[i])==1
#constraint(m, x[i] == 0)
break
end
end
optimize!(m);
But I see this problem with this method** :
Ιf I constraint x[i] to be zero, in the next step I will want maybe to drop again this constraint? This comes down to whether there can exist two(or more) different solutions in which x[i]==1
JuMP supports returning multiple solutions.
Documentation: https://jump.dev/JuMP.jl/stable/manual/solutions/#Multiple-solutions
The workflow is something like:
using JuMP
model = Model()
#variable(model, x[1:10] >= 0)
# ... other constraints ...
optimize!(model)
if termination_status(model) != OPTIMAL
error("The model was not solved correctly.")
end
an_optimal_solution = value.(x; result = 1)
optimal_objective = objective_value(model; result = 1)
for i in 2:result_count(model)
#assert has_values(model; result = i)
println("Solution $(i) = ", value.(x; result = i))
obj = objective_value(model; result = i)
println("Objective $(i) = ", obj)
if isapprox(obj, optimal_objective; atol = 1e-8)
print("Solution $(i) is also optimal!")
end
end
But you need a solver that supports returning multiple solutions, and to configure the right solver-specific options.
See this blog post: https://jump.dev/tutorials/2021/11/02/tutorial-multi-jdf/
The following is an example of all-solution finder for a boolean problem. Such problems are easier to handle since the solution space is easily enumerated (even though it can still grow exponentially big).
First, let's get the packages and define the sample problem:
using Random, JuMP, HiGHS, MathOptInterface
function example_knapsack()
profit = [5, 3, 2, 7, 4]
weight = [2, 8, 4, 2, 5]
capacity = 10
minprofit = 10
model = Model(HiGHS.Optimizer)
set_silent(model)
#variable(model, x[1:5], Bin)
#objective(model, FEASIBILITY_SENSE, 0)
#constraint(model, weight' * x <= capacity)
#constraint(model, profit' * x >= minprofit)
return model
end
(it is a knapsack problem from the JuMP docs).
Next, we use recursion to explore the tree of all possible solutions. The tree does not go down branches with no solution (so the running time is not always exponential):
function findallsol(model, x)
perm = shuffle(1:length(x))
res = Vector{Float64}[]
_findallsol!(res, model, x, perm, 0)
return res
end
function _findallsol!(res, model, x, perm, depth)
n = length(x)
depth > n && return
optimize!(model)
if termination_status(model) == MathOptInterface.OPTIMAL
if depth == n
push!(res, value.(x))
return
else
idx = perm[depth+1]
v = value(x[idx])
newcon = #constraint(model, x[idx] == v)
_findallsol!(res, model, x, perm, depth + 1)
delete(model, newcon)
newcon = #constraint(model, x[idx] == 1 - v)
_findallsol!(res, model, x, perm, depth + 1)
delete(model, newcon)
end
end
return
end
Now we can:
julia> m = example_knapsack()
A JuMP Model
Maximization problem with:
Variables: 5
...
Names registered in the model: x
julia> res = findallsol(m, m.obj_dict[:x])
5-element Vector{Vector{Float64}}:
[1.0, 0.0, 0.0, 1.0, 1.0]
[0.0, 0.0, 0.0, 1.0, 1.0]
[1.0, 0.0, 1.0, 1.0, 0.0]
[1.0, 0.0, 0.0, 1.0, 0.0]
[0.0, 1.0, 0.0, 1.0, 0.0]
And we get a vector with all the solutions.
If the problem in question is a boolean problem, this method might be used, as is. In case it has non-boolean variables, the recursion will have to split the feasible space in some even fashion. For example, choosing a variable and cutting its domain in half, and recursing to each half with a smaller domain on this variable (to ensure termination).
P.S. This is not the optimal method. This problem has been well studied. Possible terms to search for are 'model counting' (especially in the boolean domain).
(UPDATE: Changed objective to use FEASIBLE)

Scipy curve_fit error, no optimal parameters

I am trying to use the scipy.optimize.curve_fit but I encounter an error - RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 800.
I have data points for the morse potential function and I am trying to extract the three parameters D, alpha and r_eq
from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt
z_top = np.array([-2.0, -1.9733333333333334, -1.9466666666666668, -1.92, -1.8933333333333333, -1.8666666666666667, -1.84, -1.8133333333333332, -1.7866666666666666, -1.76, -1.7333333333333334, -1.7066666666666666, -1.68, -1.6533333333333333, -1.6266666666666667, -1.6, -1.5733333333333333, -1.5466666666666666, -1.52, -1.4933333333333332, -1.4666666666666668, -1.44, -1.4133333333333333, -1.3866666666666667, -1.3599999999999999, -1.3333333333333333, -1.3066666666666666, -1.2799999999999998, -1.2533333333333334, -1.2266666666666666, -1.2, -1.1733333333333333, -1.1466666666666665, -1.12, -1.0933333333333333, -1.0666666666666667, -1.04, -1.0133333333333332, -0.9866666666666666, -0.96, -0.9333333333333333, -0.9066666666666665, -0.8799999999999999, -0.8533333333333333, -0.8266666666666667, -0.7999999999999998, -0.7733333333333332, -0.7466666666666666, -0.72, -0.6933333333333334, -0.6666666666666665, -0.6399999999999999, -0.6133333333333333, -0.5866666666666667, -0.5599999999999998, -0.5333333333333332, -0.5066666666666666, -0.48, -0.45333333333333314, -0.4266666666666665, -0.3999999999999999, -0.3733333333333333, -0.34666666666666646, -0.31999999999999984, -0.2933333333333332, -0.2666666666666666, -0.24, -0.21333333333333315, -0.18666666666666654, -0.15999999999999992, -0.1333333333333333, -0.10666666666666647, -0.07999999999999985, -0.05333333333333323, -0.026666666666666616, 0.0, 0.02666666666666684, 0.05333333333333368, 0.08000000000000007, 0.10666666666666691, 0.1333333333333333, 0.16000000000000014, 0.18666666666666698, 0.21333333333333337, 0.2400000000000002, 0.2666666666666666, 0.29333333333333345, 0.3200000000000003, 0.3466666666666667, 0.3733333333333335, 0.40000000000000036, 0.42666666666666675, 0.4533333333333336, 0.48, 0.5066666666666668, 0.5333333333333337, 0.56, 0.5866666666666669, 0.6133333333333333, 0.6400000000000001, 0.666666666666667, 0.6933333333333334, 0.7200000000000002, 0.746666666666667, 0.7733333333333334, 0.8000000000000003, 0.8266666666666667, 0.8533333333333335, 0.8800000000000003, 0.9066666666666667, 0.9333333333333336, 0.9600000000000004, 0.9866666666666668, 1.0133333333333336, 1.04, 1.0666666666666669, 1.0933333333333337, 1.12, 1.146666666666667, 1.1733333333333333, 1.2000000000000002, 1.226666666666667, 1.2533333333333334, 1.2800000000000002, 1.306666666666667, 1.3333333333333335, 1.3600000000000003, 1.3866666666666667, 1.4133333333333336, 1.4400000000000004, 1.4666666666666668, 1.4933333333333336, 1.52, 1.5466666666666669, 1.5733333333333337, 1.6, 1.626666666666667, 1.6533333333333338, 1.6800000000000002, 1.706666666666667, 1.7333333333333334, 1.7600000000000002, 1.786666666666667, 1.8133333333333335, 1.8400000000000003, 1.8666666666666667, 1.8933333333333335, 1.9200000000000004, 1.9466666666666668, 1.9733333333333336, 2.0, 2.0266666666666673, 2.0533333333333337, 2.08, 2.1066666666666674, 2.1333333333333337, 2.16, 2.1866666666666665, 2.213333333333334, 2.24, 2.2666666666666666, 2.293333333333334, 2.3200000000000003, 2.3466666666666667, 2.373333333333334, 2.4000000000000004, 2.4266666666666667, 2.453333333333334, 2.4800000000000004, 2.506666666666667, 2.533333333333333, 2.5600000000000005, 2.586666666666667, 2.6133333333333333, 2.6400000000000006, 2.666666666666667, 2.6933333333333334, 2.7200000000000006, 2.746666666666667, 2.7733333333333334, 2.8000000000000007, 2.826666666666667, 2.8533333333333335, 2.88, 2.906666666666667, 2.9333333333333336, 2.96, 2.9866666666666672, 3.0133333333333336, 3.04, 3.0666666666666673, 3.0933333333333337, 3.12, 3.1466666666666674, 3.173333333333334, 3.2, 3.2266666666666666, 3.253333333333334, 3.2800000000000002, 3.3066666666666666, 3.333333333333334, 3.3600000000000003, 3.3866666666666667, 3.413333333333334, 3.4400000000000004, 3.466666666666667, 3.493333333333334, 3.5200000000000005, 3.546666666666667, 3.5733333333333333, 3.6000000000000005, 3.626666666666667, 3.6533333333333333, 3.6800000000000006, 3.706666666666667, 3.7333333333333334, 3.7600000000000007, 3.786666666666667, 3.8133333333333335, 3.8400000000000007, 3.866666666666667, 3.8933333333333335, 3.920000000000001, 3.946666666666667, 3.9733333333333336, 4.0, 4.026666666666667, 4.053333333333334, 4.08, 4.106666666666667, 4.133333333333334, 4.16, 4.186666666666667, 4.213333333333334, 4.24, 4.2666666666666675, 4.293333333333334, 4.32, 4.346666666666667, 4.373333333333334, 4.4, 4.426666666666667, 4.453333333333334, 4.48, 4.506666666666667, 4.533333333333334, 4.5600000000000005, 4.586666666666667, 4.613333333333334, 4.640000000000001, 4.666666666666667, 4.693333333333333, 4.720000000000001, 4.746666666666667, 4.773333333333333, 4.800000000000001, 4.826666666666667, 4.8533333333333335, 4.880000000000001, 4.906666666666667, 4.933333333333334, 4.960000000000001, 4.986666666666667, 5.013333333333334, 5.04, 5.066666666666667, 5.093333333333334, 5.12, 5.146666666666667, 5.173333333333334, 5.2, 5.2266666666666675, 5.253333333333334, 5.28, 5.3066666666666675, 5.333333333333334, 5.36, 5.386666666666667, 5.413333333333334, 5.44, 5.466666666666667, 5.493333333333334, 5.5200000000000005, 5.546666666666667, 5.573333333333334, 5.6000000000000005, 5.626666666666667, 5.653333333333334, 5.680000000000001, 5.706666666666667, 5.733333333333333, 5.760000000000001, 5.786666666666667, 5.8133333333333335, 5.840000000000001, 5.866666666666667, 5.8933333333333335, 5.920000000000001, 5.946666666666667, 5.973333333333334])
p_top = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 52.872576794481944, 60.36328831067402, 68.58181676019626, 77.54010551102007, 87.24546077586182, 97.71380116903708, 108.97588971792945, 121.1230000000001, 134.28859358309765, 148.68731887019467, 164.5633871885017, 182.18666227169558, 201.83818349095438, 223.81267643614873, 248.42818042617202, 276.03506399135284, 307.0337209116861, 341.87896590372986, 381.1192679598341, 425.3893723626624, 475.5021283556349, 532.4158997232969, 597.4090000000003, 672.0410742621983, 758.533379251738, 859.7165530846363, 979.6593316087284, 1124.0206760913093, 1301.1409742106393, 1519.6640526904762, 1788.227505227972, 2115.468518070886, 2510.024265626171, 2980.5319397027483, 3535.6285264165717, 4183.950889387946, 4934.135917372832, 5794.82045, 4934.420403031789, 4184.487017193709, 3536.3779199568417, 2981.450849155281, 2511.0636810971228, 2116.574298226707, 1789.340587092605, 1520.720465547997, 1302.0718287570105, 1124.752573196128, 980.1205102605351, 859.8428649405212, 758.281365651945, 671.394251505908, 596.3759999999991, 531.0259774866203, 473.7897372355332, 423.3784182587137, 378.7905732211398, 339.2052390738119, 304.05693724550565, 272.8094869362206, 244.93161029019166, 220.00582429999793, 197.7284586919518, 177.8007936067852, 159.92938926933715, 143.86679302868998, 129.3920578431436, 116.3009999999999, 104.39987683440208, 93.51271797907324, 83.48433620575351, 74.20490406269317, 65.59711336145308, 57.63198789171022, 50.29487274165398, 43.58296879663324, 37.48630089022281, 31.9864346061135, 27.059460686269396, 22.676772829659317, 18.800931214057726, 15.390398961980129, 12.405999999999976, 9.808750398065335, 7.556975821856745, 5.609771290609389, 3.930241859207573, 2.4840486871436225, 1.2405555333284073, 0.17249876364223482, -0.7431963631258247, -1.527178008314559, -2.1976614885762182, -2.7685586963324997, -3.2507065483663036, -3.654521247585481, -3.989819778712002, -4.264, -4.483339654609878, -4.653107428963594, -4.778317791591804, -4.863979954625947, -4.914753159149808, -4.934618850520453, -4.92747858548951, -4.8971925826874845, -4.846723689404206, -4.778134576732593, -4.693446251582014, -4.5947146119860145, -4.483931113002393, -4.363044061334697, -4.234, -4.0985235604644705, -3.9574567255996067, -3.811418823406809, -3.661031677747074, -3.507335845802052, -3.3521869245809506, -3.197532929895521, -3.045306521322895, -2.897111875210079, -2.7542247897630006, -2.6179055748822746, -2.4892499037088855, -2.3679261099625046, -2.2528674758007727, -2.142999999999998, -2.03745860943027, -1.936218329497232, -1.8394781167611673, -1.747441997712195, -1.6600861278953287, -1.5769440991709724, -1.4974984903385995, -1.4212457390197035, -1.3480060418851023, -1.277923339237923, -1.2111555085799302, -1.1478331446399963, -1.0878510870420735, -1.030982650405997, -0.9769999999999986, -0.9257060180247605, -0.8770268056960342, -0.8309191877527421, -0.7873394579322428, -0.7462046341344566, -0.707355543280765, -0.6706241363212588, -0.6358440114180867, -0.6028906779941965, -0.5716816224666781, -0.542135986875562, -0.514173025332713, -0.4877142855378665, -0.4626824379381182, -0.43899999999999995, -0.4165943842589561, -0.3954130579480966, -0.37540839142719296, -0.35653259042310337, -0.3387377083468086, -0.3219756460666744, -0.3061981561026408, -0.2913568256017715, -0.27740309673209135, -0.26428826973514485, -0.25196348850713185, -0.24038028798051297, -0.22949466726113874, -0.21926484416543945, -0.20964892669615007, -0.20060488653428893, -0.19209054169683576, -0.18406358448408644, -0.17648157320150093, -0.16930192351620832, -0.1624822410268282, -0.15599398273189863, -0.1498278946257743, -0.143976027663664, -0.1384303016449746, -0.13318251846105061, -0.1282243553559818, -0.12354735885956175, -0.11914296564285694, -0.115, -0.11110306063818942, -0.10743823387446969, -0.10399057427215586, -0.10074506770538746, -0.09768595719983417, -0.09478686404733155, -0.09203198506265693, -0.08941054762959841, -0.0869117305275437, -0.08452465786411881, -0.08223840650397521, -0.08004200111956421, -0.07792441608596867, -0.07587457925344288, -0.07388137031451006, -0.0719336220194075, -0.07002011928032632, -0.06812960289914699, -0.06625080975713306, -0.06437774354263374, -0.062514670658265, -0.06066699908536895, -0.058840093159610946, -0.05703927761570363, -0.055269833348506214, -0.053537002547862714, -0.05184598638412147, -0.05020194624570422, -0.048609299571983254, -0.0470683062510954, -0.04557769671809728, -0.04413616149903207, -0.04274235499024258, -0.04139489568258407, -0.04009236691353722, -0.03883331623326931, -0.037616257023266514, -0.03643968154837971, -0.03530235422607354, -0.03420331195177105, -0.03314152488588915, -0.032107966203906546, -0.031098116639678777, -0.03011436052645273, -0.029159083111374974, -0.02823466944709844, -0.027343502994046268, -0.026487055881413483, -0.025664282278113962, -0.024873704934188466, -0.024113846492361448, -0.023383229629240988, -0.022680377059935815, -0.022003811622373776, -0.02135205612181401, -0.020723633222147094, -0.020117107909086978, -0.01953141316798061, -0.01896567156149227, -0.018419007242562745, -0.017890544187225972, -0.017379406521364806, -0.016884718251067944, -0.016405603478766607, -0.015941186322196526, -0.015490596420519654, -0.01505321655270402, -0.014628780797528938, -0.014217049100448345, -0.01381778138256858, -0.01343073756640109, -0.013055677585210439, -0.012692361374500867, -0.012340548869974452])
def leps(z, D, alpha, r_eq):
return (D*(np.exp(-2*alpha*(z - r_eq)) - 2*np.exp(-alpha*(z - r_eq))))
popt, pcov = curve_fit(leps, z_top, p_top)
print(popt)
plt.figure(figsize=(20,10))
plt.plot(z_top,p_top,label='data')
plt.plot(z_top, leps(z_top, *popt), 'r-',label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
plt.ylim(-8,1)
EDIT:
the fit is very poor, even after providing starting parameters. How do you determine the optimal parameters for a good fit?

How to choose the mesh for phonon calculation with PyIron

I would like to calculate phonon density of states and band structure with pyiron, using the phononpy package.
I created a job, following the tutorial:
phono = pr.create_job(pr.job_type.PhonopyJob,"pDOS")
I can run this job, but it takes a lot of time because the mesh is too dense. Is there a way of choosing the mesh I would like to work with ?
Also, I would like to calculate phonon band structure for a given path, is it possible with pyiron ?
You can specify the input in:
phono.input
Here you can set the mesh as:
phono.input["dos_mesh"]
Best,
Jan
To address the comment regarding the band structure - you can use the phonopy API directly:
bands = []
q_start = np.array([0.5, 0.5, 0.0])
q_end = np.array([0.0, 0.0, 0.0])
band = []
for i in range(51):
band.append(q_start + (q_end - q_start) / 50 * i)
bands.append(band)
q_start = np.array([0.0, 0.0, 0.0])
q_end = np.array([0.5, 0.0, 0.0])
band = []
for i in range(51):
band.append(q_start + (q_end - q_start) / 50 * i)
bands.append(band)
phon.phonopy.set_band_structure(bands)
phon.phonopy.plot_band_structure().show()

Inconsistent results in Tensorflow incremental assignment with scatter_update

I am using Tensorflow's scatter_update to set the values of an array in a simple test. I would expect the following code to set all values in the array to 1.0.
pt = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
numOne = tf.constant(1)
xi = tf.Variable(0)
out = tf.Variable(pt)
tf.global_variables_initializer().run()
xi_ = xi + numOne
out_ = tf.scatter_update(out, [xi], [tf.cast(numOne, tf.float32)])
step = tf.group(
xi.assign(xi_),
out.assign(out_)
)
for i in range(15): step.run()
print(out.eval())
Instead I get inconsistent results like:
[ 1. 1. 1. 0. 1. 1. 1. 1. 1. 1. 1. 0. 1. 1. 1. 1.]
Is there some type of locking mechanism that I am missing?
Ops inside tf.group are executed in random order. If you want specific order, you could use tf.control_dependencies or split into two .run calls, ie
step1 = xi.assign(xi_)
step2 = out.assign(out_)
for i in range(15):
print(out.eval())
sess.run(step1)
sess.run(step2)
Also, using control_dependencies it would be something like:
xi_ = xi + numOne
with tf.control_dependencies[xi_]:
out_ = tf.scatter_update(out, [xi], [tf.cast(numOne, tf.float32)])
with tf.control_dependencies[out_]:
step = tf.group(
xi.assign(xi_),
out.assign(out_)
)
for i in range(15): step.run()
print(out.eval())

how to perform coordinates affine transformation using python? part 2

I have same problem as described here:
how to perform coordinates affine transformation using python?
I was trying to use method described but some reason I will get error messages.
Changes I made to code was to replace primary system and secondary system points. I created secondary coordinate points by using different origo. In real case for which I am studying this topic will have some errors when measuring the coordinates.
primary_system1 = (40.0, 1160.0, 0.0)
primary_system2 = (40.0, 40.0, 0.0)
primary_system3 = (260.0, 40.0, 0.0)
primary_system4 = (260.0, 1160.0, 0.0)
secondary_system1 = (610.0, 560.0, 0.0)
secondary_system2 = (610.0,-560.0, 0.0)
secondary_system3 = (390.0, -560.0, 0.0)
secondary_system4 = (390.0, 560.0, 0.0)
Error I get from when executing is following.
*Traceback (most recent call last):
File "affine_try.py", line 57, in <module>
secondary_system3, secondary_system4 )
File "affine_try.py", line 22, in solve_affine
A2 = y * x.I
File "/usr/lib/python2.7/dist-packages/numpy/matrixlib/defmatrix.py", line 850, in getI
return asmatrix(func(self))
File "/usr/lib/python2.7/dist-packages/numpy/linalg/linalg.py", line 445, in inv
return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))
File "/usr/lib/python2.7/dist-packages/numpy/linalg/linalg.py", line 328, in solve
raise LinAlgError, 'Singular matrix'
numpy.linalg.linalg.LinAlgError: Singular matrix*
What might be the problem ?
The problem is that your matrix is singular, meaning it's not invertible. Since you're trying to take the inverse of it, that's a problem. The thread that you linked to is a basic solution to your problem, but it's not really the best solution. Rather than just inverting the matrix, what you actually want to do is solve a least-squares minimization problem to find the optimal affine transform matrix for your possibly noisy data. Here's how you would do that:
import numpy as np
primary = np.array([[40., 1160., 0.],
[40., 40., 0.],
[260., 40., 0.],
[260., 1160., 0.]])
secondary = np.array([[610., 560., 0.],
[610., -560., 0.],
[390., -560., 0.],
[390., 560., 0.]])
# Pad the data with ones, so that our transformation can do translations too
n = primary.shape[0]
pad = lambda x: np.hstack([x, np.ones((x.shape[0], 1))])
unpad = lambda x: x[:,:-1]
X = pad(primary)
Y = pad(secondary)
# Solve the least squares problem X * A = Y
# to find our transformation matrix A
A, res, rank, s = np.linalg.lstsq(X, Y)
transform = lambda x: unpad(np.dot(pad(x), A))
print "Target:"
print secondary
print "Result:"
print transform(primary)
print "Max error:", np.abs(secondary - transform(primary)).max()
The reason that your original matrix was singular is that your third coordinate is always zero, so there's no way to tell what the transform on that coordinate should be (zero times anything gives zero, so any value would work).
Printing the value of A tells you the transformation that least-squares has found:
A[np.abs(A) < 1e-10] = 0 # set really small values to zero
print A
results in
[[ -1. 0. 0. 0.]
[ 0. 1. 0. 0.]
[ 0. 0. 0. 0.]
[ 650. -600. 0. 1.]]
which is equivalent to x2 = -x1 + 650, y2 = y1 - 600, z2 = 0 where x1, y1, z1 are the coordinates in your original system and x2, y2, z2 are the coordinates in your new system. As you can see, least-squares just set all the terms related to the third dimension to zero, since your system is really two-dimensional.