Arrays from nested for loops in maxima - arrays

Using MAxima I want to create 11 arrays in maxima. I am trying something like this:
for n:1 step 1 while n<=11 do( for j:1 while j<=21 do( if i<j then aa[n][i,j]:i+j+n));
This compiles fine but I can not use it how I would like. Say for example I want value 2,2 in the 5th array, I try the following but it does not work:
aa[5][2,2];
Any help is appreciated,
Ben

Your code fragment is missing any loop over i or other assignment to i.
You might consider using 'genmatrix' to construct a matrix, and then a loop over n to generate several matrices. E.g.:
foo : lambda ([i, j], if i < j then i + j + n else 0);
for n:1 thru 11 do aa[n] : genmatrix (foo, 21, 21);
Then I get
aa[5][2, 2];
=> 0
aa[5][2, 3];
=> 10
grind (aa[10]);
=> matrix([0,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],
[0,0,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],
[0,0,0,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],
[0,0,0,0,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],
[0,0,0,0,0,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],
[0,0,0,0,0,0,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],
[0,0,0,0,0,0,0,25,26,27,28,29,30,31,32,33,34,35,36,37,38],
[0,0,0,0,0,0,0,0,27,28,29,30,31,32,33,34,35,36,37,38,39],
[0,0,0,0,0,0,0,0,0,29,30,31,32,33,34,35,36,37,38,39,40],
[0,0,0,0,0,0,0,0,0,0,31,32,33,34,35,36,37,38,39,40,41],
[0,0,0,0,0,0,0,0,0,0,0,33,34,35,36,37,38,39,40,41,42],
[0,0,0,0,0,0,0,0,0,0,0,0,35,36,37,38,39,40,41,42,43],
[0,0,0,0,0,0,0,0,0,0,0,0,0,37,38,39,40,41,42,43,44],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,39,40,41,42,43,44,45],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,42,43,44,45,46],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,44,45,46,47],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,46,47,48],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,48,49],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,50],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])$

Related

Ruby arrays and how to print them

There was a one-liner in Ruby I saw on this site and lost track of:
if I need to print the results of some action with integers:
print {|e| e = e * e}
but how do I let Ruby know e is, say, 1 to 10?
use parenthesis around your range
(1..10).map {|ele| ele + 3} // 1 to 10 including the last number
(1...10).map {|ele| ele + 3 } // 1 to 9 excluding the last number
It's not really clear what you want to do, but here's an input
(1..10).to_a
This gives you an array of numbers from 1 to 10.

In MATLAB how can I write out a multidimensional array as a string that looks like a raw numpy array?

The Goal
(Forgive me for length of this, it's mostly background and detail.)
I'm contributing to a TOML encoder/decoder for MATLAB and I'm working with numerical arrays right now. I want to input (and then be able to write out) the numerical array in the same format. This format is the nested square-bracket format that is used by numpy.array. For example, to make multi-dimensional arrays in numpy:
The following is in python, just to be clear. It is a useful example though my work is in MATLAB.
2D arrays
>> x = np.array([1,2])
>> x
array([1, 2])
>> x = np.array([[1],[2]])
>> x
array([[1],
[2]])
3D array
>> x = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
>> x
array([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
4D array
>> x = np.array([[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]])
>> x
array([[[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]]],
[[[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16]]]])
The input is a logical construction of the dimensions by nested brackets. Turns out this works pretty well with the TOML array structure. I can already successfully parse and decode any size/any dimension numeric array with this format from TOML to MATLAB numerical array data type.
Now, I want to encode that MATLAB numerical array back into this char/string structure to write back out to TOML (or whatever string).
So I have the following 4D array in MATLAB (same 4D array as with numpy):
>> x = permute(reshape([1:16],2,2,2,2),[2,1,3,4])
x(:,:,1,1) =
1 2
3 4
x(:,:,2,1) =
5 6
7 8
x(:,:,1,2) =
9 10
11 12
x(:,:,2,2) =
13 14
15 16
And I want to turn that into a string that has the same format as the 4D numpy input (with some function named bracketarray or something):
>> str = bracketarray(x)
str =
'[[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]]'
I can then write out the string to a file.
EDIT: I should add, that the function numpy.array2string() basically does exactly what I want, though it adds some other whitespace characters. But I can't use that as part of the solution, though it is basically the functionality I'm looking for.
The Problem
Here's my problem. I have successfully solved this problem for up to 3 dimensions using the following function, but I cannot for the life of me figure out how to extend it to N-dimensions. I feel like it's an issue of the right kind of counting for each dimension, making sure to not skip any and to nest the brackets correctly.
Current bracketarray.m that works up to 3D
function out = bracketarray(in, internal)
in_size = size(in);
in_dims = ndims(in);
% if array has only 2 dimensions, create the string
if in_dims == 2
storage = cell(in_size(1), 1);
for jj = 1:in_size(1)
storage{jj} = strcat('[', strjoin(split(num2str(in(jj, :)))', ','), ']');
end
if exist('internal', 'var') || in_size(1) > 1 || (in_size(1) == 1 && in_dims >= 3)
out = {strcat('[', strjoin(storage, ','), ']')};
else
out = storage;
end
return
% if array has more than 2 dimensions, recursively send planes of 2 dimensions for encoding
else
out = cell(in_size(end), 1);
for ii = 1:in_size(end) %<--- this doesn't track dimensions or counts of them
out(ii) = bracketarray(in(:,:,ii), 'internal'); %<--- this is limited to 3 dimensions atm. and out(indexing) need help
end
end
% bracket the final bit together
if in_size(1) > 1 || (in_size(1) == 1 && in_dims >= 3)
out = {strcat('[', strjoin(out, ','), ']')};
end
end
Help me Obi-wan Kenobis, y'all are my only hope!
EDIT 2: Added test suite below and modified current code a bit.
Test Suite
Here is a test suite to use to see if the output is what it should be. Basically just copy and paste it into the MATLAB command window. For my current posted code, they all return true except the ones more than 3D. My current code outputs as a cell. If your solution output differently (like a string), then you'll have to remove the curly brackets from the test suite.
isequal(bracketarray(ones(1,1)), {'[1]'})
isequal(bracketarray(ones(2,1)), {'[[1],[1]]'})
isequal(bracketarray(ones(1,2)), {'[1,1]'})
isequal(bracketarray(ones(2,2)), {'[[1,1],[1,1]]'})
isequal(bracketarray(ones(3,2)), {'[[1,1],[1,1],[1,1]]'})
isequal(bracketarray(ones(2,3)), {'[[1,1,1],[1,1,1]]'})
isequal(bracketarray(ones(1,1,2)), {'[[[1]],[[1]]]'})
isequal(bracketarray(ones(2,1,2)), {'[[[1],[1]],[[1],[1]]]'})
isequal(bracketarray(ones(1,2,2)), {'[[[1,1]],[[1,1]]]'})
isequal(bracketarray(ones(2,2,2)), {'[[[1,1],[1,1]],[[1,1],[1,1]]]'})
isequal(bracketarray(ones(1,1,1,2)), {'[[[[1]]],[[[1]]]]'})
isequal(bracketarray(ones(2,1,1,2)), {'[[[[1],[1]]],[[[1],[1]]]]'})
isequal(bracketarray(ones(1,2,1,2)), {'[[[[1,1]]],[[[1,1]]]]'})
isequal(bracketarray(ones(1,1,2,2)), {'[[[[1]],[[1]]],[[[1]],[[1]]]]'})
isequal(bracketarray(ones(2,1,2,2)), {'[[[[1],[1]],[[1],[1]]],[[[1],[1]],[[1],[1]]]]'})
isequal(bracketarray(ones(1,2,2,2)), {'[[[[1,1]],[[1,1]]],[[[1,1]],[[1,1]]]]'})
isequal(bracketarray(ones(2,2,2,2)), {'[[[[1,1],[1,1]],[[1,1],[1,1]]],[[[1,1],[1,1]],[[1,1],[1,1]]]]'})
isequal(bracketarray(permute(reshape([1:16],2,2,2,2),[2,1,3,4])), {'[[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]]'})
isequal(bracketarray(ones(1,1,1,1,2)), {'[[[[[1]]]],[[[[1]]]]]'})
I think it would be easier to just loop and use join. Your test cases pass.
function out = bracketarray_matlabbit(in)
out = permute(in, [2 1 3:ndims(in)]);
out = string(out);
dimsToCat = ndims(out);
if iscolumn(out)
dimsToCat = dimsToCat-1;
end
for i = 1:dimsToCat
out = "[" + join(out, ",", i) + "]";
end
end
This also seems to be faster than the route you were pursing:
>> x = permute(reshape([1:16],2,2,2,2),[2,1,3,4]);
>> tic; for i = 1:1e4; bracketarray_matlabbit(x); end; toc
Elapsed time is 0.187955 seconds.
>> tic; for i = 1:1e4; bracketarray_cris_luengo(x); end; toc
Elapsed time is 5.859952 seconds.
The recursive function is almost complete. What is missing is a way to index the last dimension. There are several ways to do this, the neatest, I find, is as follows:
n = ndims(x);
index = cell(n-1, 1);
index(:) = {':'};
y = x(index{:}, ii);
It's a little tricky at first, but this is what happens: index is a set of n-1 strings ':'. index{:} is a comma-separated list of these strings. When we index x(index{:},ii) we actually do x(:,:,:,ii) (if n is 4).
The completed recursive function is:
function out = bracketarray(in)
n = ndims(in);
if n == 2
% Fill in your n==2 code here
else
% if array has more than 2 dimensions, recursively send planes of 2 dimensions for encoding
index = cell(n-1, 1);
index(:) = {':'};
storage = cell(size(in, n), 1);
for ii = 1:size(in, n)
storage(ii) = bracketarray(in(index{:}, ii)); % last dimension automatically removed
end
end
out = { strcat('[', strjoin(storage, ','), ']') };
Note that I have preallocated the storage cell array, to prevent it from being resized in every loop iteration. You should do the same in your 2D case code. Preallocating is important in MATLAB for performance reasons, and the MATLAB Editor should warm you about this too.

Gnuplot: Nested “plot” iteration (“plot for”) with dependent loop indices

I have recently attempted to concisely draw several graphs in a plot using gnuplot and the plot for ... syntax. In this case, I needed nested loops because I wanted to pass something like the following index combinations (simplified here) to the plot expression:
i = 0, j = 0
i = 1, j = 0
i = 1, j = 1
i = 2, j = 0
i = 2, j = 1
i = 2, j = 2
and so on.
So i loops from 0 to some upper limit N and for each iteration of i, j loops from 0 to i (so i <= j). I tried doing this with the following:
# f(i, j, x) = ...
N = 5
plot for [i=0:N] for [j=0:i] f(i, j, x) title sprintf('j = %d', j)
but this only gives five iterations with j = 0 every time (as shown by the title). So it seems that gnuplot only evaluates the for expressions once, fixing i = 0 at the beginning and not re-evaluating to keep up with changing i values. Something like this has already been hinted at in this answer (“in the plot for ... structure the second index cannot depend on the first one.”).
Is there a simple way to do what I want in gnuplot (i.e. use the combinations of indices given above with some kind of loop)? There is the do for { ... } structure since gnuplot 4.6, but that requires individual statements in its body, so it can’t be used to assemble a single plot statement. I suppose one could use multiplot to get around this, but I’d like to avoid multiplot if possible because it makes things more complicated than seems necessary.
I took your problem personally. For your specific problem you can use a mathematical trick. Remap your indices (i,j) to a single index k, such that
(0,0) -> (0)
(1,0) -> (1)
(1,1) -> (2)
(2,0) -> (3)
...
It can be shown that the relation between i and j and k is
k = i*(i+1)/2 + j
which can be inverted with a bit of algebra
i(k)=floor((sqrt(1+8.*k)-1.)/2.)
j(k)=k-i(k)*(i(k)+1)/2
Now, you can use a single index k in your loop
N = 5
kmax = N*(N+1)/2 + N
plot for [k=0:kmax] f(i(k), j(k), x) title sprintf('j = %d', j(k))

Accessing elements in matlab, get pixels of color image (array) from indices stored in another array

A and B are mask indices (row and column respectively) and C is an image and I want to note the color values stored in C for which the indices are stored in A and B. If A and B would be something like [1, 2, 3] and [20, 30, 40] so I would like to find C(1, 20, :), C(2, 30, :) and C(3, 40, :).
If I do D = C(A, B, :), I get an array of size 3x3x3 in this case, however I want an array of size 3x1x3. I know I am messing with the indexing, is there a simple way to do this without writing a loop?
Simply stating, is there a way to do the following without a loop:
for i = 1:10
D(i, :) = C(A(i), B(i), :)
end
You need to convert subindices to linear indices. You can use sub2ind for that:
r = C(sub2ind([size(C,1) size(C,2) 1],A,B,1*ones(1,length(A))));
g = C(sub2ind([size(C,1) size(C,2) 2],A,B,2*ones(1,length(A))));
b = C(sub2ind([size(C,1) size(C,2) 3],A,B,3*ones(1,length(A))));
The n x 1 x 3 result you want would be simply cat(3, r.',g.',b.').
Why not something like
C = C(A,B(i),:);
You could use a for statement to get the value of i or set it some other way.
It sounds like everything is working as it should. In your example you've indexed 9 elements of C using A and B. Then D is a 3x3x3 array with the dimensions corresponding to [row x col x color_mask(RGB)]. Why would the second dimension be reduced to 1 unless B only contained one value (signifying you only want to take elements from one column)? Of course A and B must not contain values higher than the number of rows and columns in C.
A = [1 2 3];
B = [20];
D = C(A,B,:);
size(D)
>> 3 1 3
EDIT: Ok, I see what you mean now. You want to specify N number of points using A(Nx1) and B(Nx1). Not NxN number of points which is what you are currently getting.

How to do C++ style(indexed) nested loops in python?

What is the equivalent of the following in python?
for (i=0; i<n; i++)
for (j=i+1; j<n; j++)
//do stuff with A[i], A[j]
Or in some sense, the following. It should also remove the element from A at the completion of each round of the loop.
for a in A:
for a' in A/{a}: #i.e. rest of the elements of A
#do something with a,a'
#remove a from A
Is there a pythonic way of doing this without using enumerate()?
Edits:
Sorry for the bad description.
In the first example, I mean to use i & j only as indices. Their values do not matter. Its just a rough c++ equivalent of the latter.
The outer loop is executed n times. The inner loop is executed (n-1), (n-2)...0 times for each iteration of the outer loop.
Maybe this might help (pseudocode):
function next_iteration(list):
head = first element
tail = remaining elements #list
each element in tail interacts with head one by one
next_iteration(tail)
PS: All code samples above are pseudocodes. I'm trying to express something that is still a bit vague in my mind.
I intepret what you're asking as
How can I iterate over all pairs of distinct elements of a container?
Answer:
>>> x = {1,2,3}
>>> import itertools
>>> for a, b in itertools.permutations(x, 2):
... print a, b
...
1 2
1 3
2 1
2 3
3 1
3 2
EDIT: If you don't want both (a,b) and (b,a), just use itertools.combinations instead.
Since your two questions are different, here is solution for your second problem:
for i in xrange(len(A)):
for j in xrange(len(A)):
if i != j:
do_stuff(A[i], A[j])
or using itertools (I think using the included batteries is very pythonic!):
import itertools
for a, b in itertools.permutations(A, 2):
do_stuff(a, b)
This applies do_stuff to all combinations of 2 different elements from A. I you want to store the result just use:
[do_stuff(a, b) for a, b in itertools.permutations(A, 2)]
How about:
for i in range(0,n):
for j in range (i+1,n):
# do stuff
for i in range(0,n):
for j in range(i+1,n):
# do stuff
Still can't leave comments.. but basically what the other two posts said - but get in the habit of using xrange instead of range.
for i in xrange(0,n):
for j in xrange(i+1,n):
# do stuff
You could make the inner loop directly over a slice. Not saying this is any better, but it is another approach.
for i in range(0,len(x)):
a = x[i]
for b in x[i+1:]:
print a, b
Another way to approach this is - if n is an sequence that provides the iterable interface, then in Python you can simplify your code by iterating over the object directly:
for i in n:
for some_var in n[n.index(i):]: # rest of items
# do something
I hope I understood your loop correctly, because as others have stated - they don't do the same thing.
For the first one of your questions, as already mentioned in other answers:
for i in xrange(n):
for j in xrange(i+1, n):
# do stuff with A[i] and A[j]
For the second one:
for i, a in enumerate(A):
for b in A[i+1:]:
# do stuff with a and b
Your psuedocode almost has it:
function next_iteration(list):
head = first element
tail = remaining elements #list
each element in tail interacts with head one by one
next_iteration(tail)
Python code:
def next_iteration(lst):
head, tail = lst[0], lst[1:]
for item in tail:
print(head, item)
if tail:
next_iteration(tail)
Which, when tried with next_iteration([1, 2, 3]), prints:
1 2
1 3
2 3
You can use xrange to generate values for i and j respectively as show below:
for i in xrange(0, n):
for j in xrange(i + 1, n):
# do stuff
In the first for-loop, enumerate() walks through the array and makes the index,value of each element available to the second for-loop. In the second loop, range() makes j = i+1 --> len(a) available. At this point you'd have exactly what you need which is i & j to do your operation.
>>> a = [1,2,3,4]
>>> array_len = len(a)
>>> for i,v in enumerate(a):
... for j in range(i+1, array_len):
... print a[i], a[j]
...
1 2
1 3
1 4
2 3
2 4
3 4
>>>

Resources