How to generate a multidimensional array of indexed variables in Maxima? - maxima

I want to take a list of non-negative integers D=[d1,...,dm] and and generate a multidimensional array of indexed symbols A in the form of:
where 0<=i_j<=d_j. For example if D=[2,3] then A should be
[[a_[0,0],a_[0,1],a_[0,2]],
[a_[1,0],a_[1,1],a_[1,2]]]
For this case I could nest two for loops to generate the said array, however D does not necessarily have a length of 2 and I don't know how to nest an arbitrary number of for loops!
I would appreciate if you could help me know how I can generate A from D.
P.S. What I want to finally achieve is to create a multivariate polynomial as explained here.

Here's one way to do it. The essential part is that I called cartesian_product to construct the list of all combinations of indices, and then arrayapply to create the subscripted expressions.
(%i11) ii:setify(makelist(i, i, 0, n)), n=2;
(%o11) {0, 1, 2}
(%i12) apply (cartesian_product, makelist (ii, m)), m=3;
(%o12) {[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1],
[0, 1, 2], [0, 2, 0], [0, 2, 1], [0, 2, 2], [1, 0, 0],
[1, 0, 1], [1, 0, 2], [1, 1, 0], [1, 1, 1], [1, 1, 2],
[1, 2, 0], [1, 2, 1], [1, 2, 2], [2, 0, 0], [2, 0, 1],
[2, 0, 2], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 2, 0],
[2, 2, 1], [2, 2, 2]}
(%i13) map (lambda ([l], arrayapply (_a, l)), %);
(%o13) {_a , _a , _a , _a , _a ,
0, 0, 0 0, 0, 1 0, 0, 2 0, 1, 0 0, 1, 1
_a , _a , _a , _a , _a ,
0, 1, 2 0, 2, 0 0, 2, 1 0, 2, 2 1, 0, 0
_a , _a , _a , _a , _a ,
1, 0, 1 1, 0, 2 1, 1, 0 1, 1, 1 1, 1, 2
_a , _a , _a , _a , _a ,
1, 2, 0 1, 2, 1 1, 2, 2 2, 0, 0 2, 0, 1
_a , _a , _a , _a , _a ,
2, 0, 2 2, 1, 0 2, 1, 1 2, 1, 2 2, 2, 0
_a , _a }
2, 2, 1 2, 2, 2
(%i14) grind (%);
{_a[0,0,0],_a[0,0,1],_a[0,0,2],_a[0,1,0],_a[0,1,1],_a[0,1,2],
_a[0,2,0],_a[0,2,1],_a[0,2,2],_a[1,0,0],_a[1,0,1],_a[1,0,2],
_a[1,1,0],_a[1,1,1],_a[1,1,2],_a[1,2,0],_a[1,2,1],_a[1,2,2],
_a[2,0,0],_a[2,0,1],_a[2,0,2],_a[2,1,0],_a[2,1,1],_a[2,1,2],
_a[2,2,0],_a[2,2,1],_a[2,2,2]}$
(%o14) done
This is just working at the top-level interactive prompt; if you need to construct a function, I think you'll see how to do it.
EDIT: Here's a way to create the polynomial.
(%i16) S : {[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1],
[0, 1, 2], [0, 2, 0], [0, 2, 1], [0, 2, 2], [1, 0, 0],
[1, 0, 1], [1, 0, 2], [1, 1, 0], [1, 1, 1], [1, 1, 2],
[1, 2, 0], [1, 2, 1], [1, 2, 2], [2, 0, 0], [2, 0, 1],
[2, 0, 2], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 2, 0],
[2, 2, 1], [2, 2, 2]} $
(%i17) L : listify (S) $
(%i18) A : map (lambda ([l], arrayapply (_a, l)), L);
(%o18) [_a , _a , _a , _a , _a ,
0, 0, 0 0, 0, 1 0, 0, 2 0, 1, 0 0, 1, 1
_a , _a , _a , _a , _a ,
0, 1, 2 0, 2, 0 0, 2, 1 0, 2, 2 1, 0, 0
_a , _a , _a , _a , _a ,
1, 0, 1 1, 0, 2 1, 1, 0 1, 1, 1 1, 1, 2
_a , _a , _a , _a , _a ,
1, 2, 0 1, 2, 1 1, 2, 2 2, 0, 0 2, 0, 1
_a , _a , _a , _a , _a ,
2, 0, 2 2, 1, 0 2, 1, 1 2, 1, 2 2, 2, 0
_a , _a ]
2, 2, 1 2, 2, 2
(%i19) U : map (lambda ([l], product (u[i]^l[i], i, 1, length(l))), L);
2 2 2 2 2 2
(%o19) [1, u , u , u , u u , u u , u , u u , u u , u ,
3 3 2 2 3 2 3 2 2 3 2 3 1
2 2 2 2
u u , u u , u u , u u u , u u u , u u , u u u ,
1 3 1 3 1 2 1 2 3 1 2 3 1 2 1 2 3
2 2 2 2 2 2 2 2 2 2 2 2
u u u , u , u u , u u , u u , u u u , u u u , u u ,
1 2 3 1 1 3 1 3 1 2 1 2 3 1 2 3 1 2
2 2 2 2 2
u u u , u u u ]
1 2 3 1 2 3
(%i20) A.U;
2 2 2 2 2 2 2
(%o20) u u _a u + u u _a u + u _a u
1 2 2, 2, 2 3 1 2 2, 1, 2 3 1 2, 0, 2 3
2 2 2 2 2
+ u _a u u + _a u u + u _a u u
1 1, 2, 2 2 3 0, 2, 2 2 3 1 1, 1, 2 2 3
2 2 2
+ _a u u + u _a u + _a u
0, 1, 2 2 3 1 1, 0, 2 3 0, 0, 2 3
2 2 2 2
+ u u _a u + u u _a u + u _a u
1 2 2, 2, 1 3 1 2 2, 1, 1 3 1 2, 0, 1 3
2 2
+ u _a u u + _a u u + u _a u u
1 1, 2, 1 2 3 0, 2, 1 2 3 1 1, 1, 1 2 3
+ _a u u + u _a u + _a u
0, 1, 1 2 3 1 1, 0, 1 3 0, 0, 1 3
2 2 2 2
+ u u _a + u u _a + u _a
1 2 2, 2, 0 1 2 2, 1, 0 1 2, 0, 0
2 2
+ u _a u + _a u + u _a u
1 1, 2, 0 2 0, 2, 0 2 1 1, 1, 0 2
+ _a u + u _a + _a
0, 1, 0 2 1 1, 0, 0 0, 0, 0
Note that the ordering of terms within each product doesn't conform to what humans would consider the usual convention, e.g. [1]^2*u[2]^2*_a[2,2,2]*u[3]^2 is the first term. Maxima is ordering the terms according to the subscripts, therefore _a[2,2,2] comes after u[1] and before u[3]. In some contexts this coincides with what humans expect, but here it doesn't; in any event, Maxima is consistent in hope of making programmatic manipulation work better.
(%i21) grind (%);
u[1]^2*u[2]^2*_a[2,2,2]*u[3]^2+u[1]^2*u[2]*_a[2,1,2]*u[3]^2
+u[1]^2*_a[2,0,2]*u[3]^2
+u[1]*_a[1,2,2]*u[2]^2*u[3]^2
+_a[0,2,2]*u[2]^2*u[3]^2
+u[1]*_a[1,1,2]*u[2]*u[3]^2
+_a[0,1,2]*u[2]*u[3]^2
+u[1]*_a[1,0,2]*u[3]^2
+_a[0,0,2]*u[3]^2
+u[1]^2*u[2]^2*_a[2,2,1]*u[3]
+u[1]^2*u[2]*_a[2,1,1]*u[3]
+u[1]^2*_a[2,0,1]*u[3]
+u[1]*_a[1,2,1]*u[2]^2*u[3]
+_a[0,2,1]*u[2]^2*u[3]
+u[1]*_a[1,1,1]*u[2]*u[3]
+_a[0,1,1]*u[2]*u[3]
+u[1]*_a[1,0,1]*u[3]
+_a[0,0,1]*u[3]
+u[1]^2*u[2]^2*_a[2,2,0]
+u[1]^2*u[2]*_a[2,1,0]
+u[1]^2*_a[2,0,0]
+u[1]*_a[1,2,0]*u[2]^2
+_a[0,2,0]*u[2]^2
+u[1]*_a[1,1,0]*u[2]
+_a[0,1,0]*u[2]+u[1]*_a[1,0,0]
+_a[0,0,0]$
(%o21) done

Related

How to predict Total Hours needed with List as Input?

I am struggling with the problem I am facing:
I have a dataset of different products (Cars) that have certain Work Orders open at a given time. I know from historical data how much time this work in TOTAL has caused.
Now I want to predict it for another Car (e.g. Car 3).
Which type of algorithm, regression shall I use for this?
My idea was to transform this row based dataset into column based with binary values e.g. Brake: 0/1, Screen 0/1.. But then I will have lots of Inputs as the number of possible Inputs is 100-200..
Here's a quick idea using multi-factor regression for 30 jobs, each of which is some random accumulation of 6 tasks with a "true cost" for each task. We can regress against the task selections in each job to estimate the cost coefficients that best explain the total job costs.
First done w/ no "noise" in the system (tasks are exact), then with some random noise.
A "more thorough" job would include examining the R-squared value and plotting the residuals to ensure linearity.
In [1]: from sklearn import linear_model
In [2]: import numpy as np
In [3]: jobs = np.random.binomial(1, 0.6, (30, 6))
In [4]: true_costs = np.array([10, 20, 5, 53, 31, 42])
In [5]: jobs
Out[5]:
array([[0, 1, 1, 1, 1, 0],
[1, 0, 0, 1, 0, 1],
[1, 1, 0, 1, 0, 0],
[1, 0, 1, 1, 1, 1],
[1, 1, 0, 0, 1, 1],
[0, 1, 0, 0, 1, 0],
[1, 0, 0, 1, 1, 0],
[1, 1, 1, 1, 0, 1],
[1, 0, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 0],
[0, 0, 1, 0, 1, 1],
[1, 0, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1],
[1, 0, 1, 1, 1, 1],
[0, 1, 1, 0, 1, 0],
[1, 0, 1, 0, 1, 0],
[1, 1, 1, 1, 1, 1],
[1, 0, 1, 0, 0, 1],
[0, 1, 0, 1, 1, 0],
[1, 1, 1, 0, 1, 0],
[1, 1, 1, 1, 1, 0],
[1, 0, 1, 0, 0, 1],
[0, 0, 0, 1, 1, 1],
[1, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 1],
[1, 0, 1, 1, 1, 1],
[0, 0, 1, 1, 0, 0],
[1, 1, 0, 0, 1, 1],
[1, 1, 1, 1, 0, 0]])
In [6]: tot_job_costs = jobs # true_costs
In [7]: reg = linear_model.LinearRegression()
In [8]: reg.fit(jobs, tot_job_costs)
Out[8]: LinearRegression()
In [9]: reg.coef_
Out[9]: array([10., 20., 5., 53., 31., 42.])
In [10]: np.random.normal?
In [11]: noise = np.random.normal(0, scale=5, size=30)
In [12]: noisy_costs = tot_job_costs + noise
In [13]: noisy_costs
Out[13]:
array([113.94632664, 103.82109478, 78.73776288, 145.12778089,
104.92931235, 48.14676751, 94.1052639 , 134.64827785,
109.58893129, 67.48897806, 75.70934522, 143.46588308,
143.12160502, 147.71249157, 53.93020167, 44.22848841,
159.64772255, 52.49447057, 102.70555991, 69.08774251,
125.10685342, 45.79436364, 129.81354375, 160.92510393,
108.59837665, 149.1673096 , 135.12600871, 60.55375843,
107.7925208 , 88.16833899])
In [14]: reg.fit(jobs, noisy_costs)
Out[14]: LinearRegression()
In [15]: reg.coef_
Out[15]:
array([12.09045186, 19.0013987 , 3.44981506, 55.21114084, 33.82282467,
40.48642199])
In [16]:

Find the sum of the difference of maximum and minimum element of all subarrays

sample input: 3 1 4 2
output: 1) Subarrays of size 1 : (3),(1),(4),(2) , sum = 0 + 0 + 0 + 0 = 0.
2) Subarrays of size 2: [3, 1], [1, 4], [4, 2], sum = 2 + 3 + 2 = 7.
3) Subarrays of size 3:- [3, 1, 4], [1, 4, 2], sum = 3 + 3 = 6.
4) Subarrays of size 4:- [3, 1, 4, 2], sum = 3
Total sum = 16
Here the problem can solve in many ways, hope this might help you to get your ideas.
arr = [3, 1, 4, 2]
lists = []
res = 0
for i in range(len(arr) + 1):
for j in range(i):
if len(arr[j: i]) > 1:
res += np.max(arr[j:i]) - np.min(arr[j:i])
lists.append(arr[j:i])
print(res)

Can I use cvxpy to split integer-2D-array to two arrays?

I have a problem that I wonder if I can solve using cvxpy:
The problem:
I have a two dimensional integers array and I want to split it to two array in a way that each row of the source array is either in the 1st or 2nd array.
The requirement from these arrays us that for each column, the sum of integers in array #1 will be as close as possible to twice the sum of integers in array #2.
Example:
Consider the input array:
[
[1, 2, 3, 4],
[4, 6, 2, 5],
[3, 9, 1, 2],
[8, 1, 0, 9],
[8, 4, 0, 5],
[9, 8, 0, 4]
]
The sums of its columns is [33, 30, 6, 29] so ideally we are looking for 2 arrays that the sums of their columns will be:
Array #1: [22, 20, 4, 19]
Array #2: [11, 10, 2, 10]
Off course this is not always possible but I looking for the best solution for this problem.
A possible solution for this specific example might be:
Array #1:
[
[1, 2, 3, 4],
[4, 6, 2, 5],
[8, 4, 0, 5],
[9, 8, 0, 4]
]
With column sums: [22, 20, 5, 18]
Array #2:
[
[3, 9, 1, 2],
[8, 1, 0, 9],
]
With column sums: [11, 10, 1, 11]
Any suggestions?
You can use a boolean vector variable to select rows. The only thing left to decide is how much to penalize errors. In this case I just used the norm of the difference vector.
import cvxpy as cp
import numpy as np
data = np.array([
[1, 2, 3, 4],
[4, 6, 2, 5],
[3, 9, 1, 2],
[8, 1, 0, 9],
[8, 4, 0, 5],
[9, 8, 0, 4]
])
x = cp.Variable(data.shape[0], boolean=True)
prob = cp.Problem(cp.Minimize(cp.norm((x - 2 * (1 - x)) * data)))
prob.solve()
A = np.round(x.value) # data
B = np.round(1 - x.value) # data
A and B are the sum of rows.
(array([21., 20., 4., 19.]), array([12., 10., 2., 10.]))

Disk structuring element in opencv

I know a disk structuring element can be created in MATLAB as following:
se=strel('disk',4);
0 0 1 1 1 0 0
0 1 1 1 1 1 0
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
0 1 1 1 1 1 0
0 0 1 1 1 0 0
Is there any function or method or any other way of creating the structuring element same as above in opencv. I know we can manually create it using loops but I just want to know if some function exist for that.
The closest one (not the exact same) you can get in OpenCV is by calling getStructuringElement():
int sz = 4;
cv::Mat se = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2*sz-1, 2*sz-1));
, which gives the matrix with values
[0, 0, 0, 1, 0, 0, 0;
0, 1, 1, 1, 1, 1, 0;
1, 1, 1, 1, 1, 1, 1;
1, 1, 1, 1, 1, 1, 1;
1, 1, 1, 1, 1, 1, 1;
0, 1, 1, 1, 1, 1, 0;
0, 0, 0, 1, 0, 0, 0]
def estructurant(radius):
kernel = np.zeros((2*radius+1, 2*radius+1) ,np.uint8)
y,x = np.ogrid[-radius:radius+1, -radius:radius+1]
mask = x**2 + y**2 <= radius**2
kernel[mask] = 1
kernel[0,radius-1:kernel.shape[1]-radius+1] = 1
kernel[kernel.shape[0]-1,radius-1:kernel.shape[1]-radius+1]= 1
kernel[radius-1:kernel.shape[0]-radius+1,0] = 1
kernel[radius-1:kernel.shape[0]-radius+1,kernel.shape[1]-1] = 1
return kernel
try this
You could also use skimage.morphology.disk, which produces a symmetric result (unlike cv2.getStructuringElement):
>>> disk(4)
array([[0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0]], dtype=uint8)

Find a value in common in two two-dimensionals arrays Ruby

I have two arrays, and each is two dimensional, I want to take the value of array 1 in position i and try to find the same value in array 2. If they have the same value, the values of array 2 in x position is concatenated in array 1 in position i.
example
Array 1
[[1,2,3,4,5,6],[3,5,7,2,12,5],[a,f,3,d,4,g]]
Array 2
[[b,e,w,1,4,6] , [1,0,8,5,8,9]]
So the new array 1 will be
[[1,2,3,4,5,6,1,0,8,5,8,9],[3,5,7,2,12,5],[a,f,3,d,4,g]]
Any thought.....
Your description of the task isn't correct. You can't
take the value of the array 1 in position i
because array 1 contain arrays itself, so you can take value in position i, j. And search for same values in array 2 in each i on position j. And if this is what you want, here is sample code:
arr_1 = [[1, 2, 3, 4, 5, 6], [3, 5, 7, 2, 12, 5], ['a', 'f', 3, 'd', 4, 'g']]
arr_2 = [['b', 'e', 'w', 1, 4, 6], [1, 0, 8, 5, 8, 9]]
search_i = 0
search_j = 0
search_val = arr_1[search_i][search_j]
arr_2.each_with_index do |val_i, i|
val_i.each_with_index do |val_j, j|
if j == search_j && arr_2[i][j] == search_val
arr_1[search_i].concat(arr_2[i])
end
end
end
p arr_1 # [[1, 2, 3, 4, 5, 6, 1, 0, 8, 5, 8, 9], [3, 5, 7, 2, 12, 5], ["a", "f", 3, "d", 4, "g"]]

Resources