How to change matrix values to values from another matrix - Wolfram - list

I have just started my journey with Wolfram Mathematica and I want to implement a simple genetic algorithm. The construction of the data is given and I have to start with such rows/columns.
Here is what I have:
chromosome := RandomSample[CharacterRange["A", "G"], 7]
chromosomeList = Table[chromosome, 7] // MatrixForm
This gives me a matrix, where every row represents a chromosome:
yPos = Flatten[Position[chromosomeList, #], 1] & /# {"A", "B", "C",
"D", "E", "F", "G"};
yPos = yPos[[All, 3 ;; 21 ;; 3]] // Transpose
Now every column represents a letter (From A to G) and every row it's index in every chromosome:
Here is a given efficiency matrix, where very row represents different letter (From A to G) and every column gives the value that should be applied on the particular position:
efficiencyMatrix = {
{34, 31, 20, 27, 24, 24, 18},
{14, 14, 22, 34, 26, 19, 22},
{22, 16, 21, 27, 35, 25, 30},
{17, 21, 24, 16, 31, 22, 20},
{17, 29, 22, 31, 18, 19, 26},
{26, 29, 37, 34, 37, 20, 21},
{30, 28, 37, 28, 29, 23, 19}}
What I want to do is to create a matrix with values that correspond to the letter and it's position. I have done it like that:
values = Transpose[{ efficiencyMatrix[[1, yPos[[1]]]],
efficiencyMatrix[[2, yPos[[2]]]],
efficiencyMatrix[[3, yPos[[3]]]],
efficiencyMatrix[[4, yPos[[4]]]],
efficiencyMatrix[[5, yPos[[5]]]],
efficiencyMatrix[[6, yPos[[6]]]],
efficiencyMatrix[[7, yPos[[7]]]]}]
How can I write it in more elegant way?

You can apply a list of functions to some variable using the function Through, which is helpful when applying Position multiple times. Because Position[patt][expr] == Position[expr, patt], we can do
Through[ (Position /# CharacterRange["A","C"])[{"B", "C", "A"}] ]
to get {3, 1, 2}.
Position can also operate on lists, so we can simplify finding ypos by doing
Transpose#Map[Last, Through[(Position /# characters)[chromosomeList]], {2}]
where characters is the relevant output of CharacterRange.
We can also simplify dealing with ranges of integers by mapping over the Range function, so in total we end up with
characters = CharacterRange["A","G"]
efficiencies = ...
chromosomes = ...
ypos = Transpose#Map[Last, Through[(Position /# characters)[chromosomes]], {2}];
efficiencies[[#, ypos[[#]]]]& /# Range[Length[characters]] //Transpose ]

Related

Lists and Indexing

Suppose I have a list of 17 objects, out of these 17 objects some have a certain property say P1. I separate them and say they are n in number where n < 17. Out of these n objects some have another property say P2. I separate them and say they are m in number where m < n. Out of these m objects some have another property say P3. I separate them and say they are k in number where k < m. I want to print these k objects only.
I was thinking of a long way that is I separate n, m and k objects all from 17 objects according to their respective property and then look for common index, the index that appear in all of three calculations.
Either I need to derive this common index or I do what I have written in the first paragraph that is to filter through and through according to the three properties.
Example:
list_1 = [17, 23, 15, 37, 43, 52, 57, 93, 55, 85, 11, 13, 7, 22, 24]
list_odd = [17, 23, 15, 37, 43, 57, 93, 55, 85, 11, 13, 7] #P1 is a number is odd
list_odd_div3 = [15, 57, 93] #P2 is a number divisible by 3
list_odd_div5 = [15, 55, 85] #P3 is a number divisible by 5
required_list = [15] #A number having P1, P2 and P3

Sorting lua lists

I have a list in lua that looks something like this:
list = {{1, 25, 31, 50, 5, 6}, {3, 22, 14, 82, 14, 1}, {2, 13, 40, 67, 92, 12},}
I want to be able to sort it by the first number in each set of braces, so it will become this:
list = {{1, 25, 31, 50, 5, 6}, {2, 13, 40, 67, 92, 12}, {3, 22, 14, 82, 14, 1}}
I have tried table.sort() but that doesn't seem to work.
Thanks for all the help!
table.sort(list, function(a, b) return a[1] < b[1] end)
The second argument to table.sort is a sorting function. So in this case we look into the first item in a and b and use that to compare.

Permuting on a schedule python

I'm trying to implement simplified DES for learning purposes in python, but I am having trouble figuring out how to do the permutations based on a "schedule." Essentially, I have a tuple with the appropriate permutations, and I need to bit shift to the correct location.
For example, using a key:
K = 00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001
Would move the 57st bit to the first bit spot, 49th bit to the second bit spot, etc...
K+ = 1111000 0110011 0010101 0101111 0101010 1011001 1001111 0001111
Current code:
def keyGen(key):
PC1table = (57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4)
keyBinary = bin(int(key, 16))[2:].zfill(64)
print keyBinary
permute(PC1table, keyBinary)
def permute(permutation, permuteInput):
elements = list(enumerate(permutation))
for bit in permuteInput:
***magic bitshifting goes here***
keyGen("133457799BBCDFF1")
The logic I thought would work was to enumerate the tuple of permutations, and for each bit of my old key, look in the enumeration to find the index corresponding the the bit, and bit shift the appropriate number of times, but I just can't figure out how to go about doing this. It may be that I am approaching the problem from the wrong angle, but any guidance would be greatly appreciated!
Ok, I ended up figuring a way to make this work, although this probably isn't the most efficient way...
prior to calling the function, turn the binary number into a list:
keyBinary = bin(int(key, 16))[2:].zfill(64)
keyBinary = [int(i) for i in keyBinary]
Kplus = permute(PC1table, keyBinary)
def permute(mapping, permuteInput):
permuteOutput = []
for i in range(len(mapping)):
permuteOutput.append(permuteInput[mapping[i % 56] - 1])
return permuteOutput
if anyone has a better way of tackling this, I'd love to see your solutions!

Automatically Deleting specific Elements in Mathematica Tables

I have a question which can be divided into two subquestions.
I have created a table the code of which is given below.
Problem 1.
xstep = 1;
xmaximum = 6;
numberofxnodes = 6;
numberofynodes = 3;
numberofzlayers = 3;
maximumgridnodes = numberofxnodes*numberofynodes
mnodes = numberofxnodes*numberofynodes*numberofzlayers;
orginaltable =
Table[{i,
node2 = i + xstep, node3 = node2 + xmaximum,
node4 = node3 - xstep,node5 = i + maximumgridnodes,
node6 = node5 + xstep,node7 = node6 + xmaximum,
node8 = node7 - xstep},
{i, 1, mnodes}]
If I run this I will get my original table. Basically I want to remove the sixth element and multiples of the sixth element from my original table. I am able to do this by using this code below.
modifiedtable = Drop[orginaltable, {6, mnodes, 6}]
Now I get the modified table where every sixth element and multiples of sixth element of my original table is removed. This solves my Problem 1.
Now my Problem 2:
** MAJOR EDITED VERSION**:(ALL THE CODES GIVEN ABOVE IS CORRECT)
Thanks a lot for the answers, but I wanted something else and I made a mistake
while explaining it initially so I'm making another try.
Below is my modified table: I want the elements in between
"/** and **/" deleted and remaining there.
{{1, 2, 8, 7, 19, 20, 26, 25}, {2, 3, 9, 8, 20, 21, 27, 26}, {3, 4,10, 9, 21, 22, 28, 27}, {4, 5, 11, 10, 22, 23, 29, 28}, {5, 6, 12, 11, 23, 24, 30, 29}, {7, 8, 14, 13, 25, 26, 32, 31}, {8, 9, 15, 14, 26, 27, 33, 32}, {9, 10, 16, 15, 27, 28, 34, 33}, {10, 11, 17, 16, 28, 29, 35, 34}, {11, 12, 18, 17, 29, 30, 36, 35}, /**{13, 14, 20, 19, 31, 32, 38, 37}, {14, 15, 21, 20, 32, 33, 39, 38}, {15, 16, 22, 21, 33, 34, 40, 39}, {16, 17, 23, 22, 34, 35, 41, 40}, {17, 18, 24, 23, 35, 36, 42, 41},**/ {19, 20, 26, 25, 37, 38, 44, 43}, {20, 21, 27, 26, 38, 39, 45, 44}, {21, 22, 28, 27, 39, 40, 46, 45}, {22, 23, 29, 28, 40, 41, 47, 46}, {23, 24, 30, 29, 41, 42, 48, 47}, {25, 26, 32, 31,43, 44, 50, 49}, {26, 27, 33, 32, 44, 45, 51, 50}, {27, 28, 34, 33, 45, 46, 52, 51}, {28, 29, 35, 34, 46, 47, 53, 52}, {29, 30, 36, 35, 47, 48, 54, 53}, /**{31, 32, 38, 37, 49, 50, 56, 55}, {32, 33, 39, 38,50, 51, 57, 56}, {33, 34, 40, 39, 51, 52, 58, 57}, {34, 35, 41, 40, 52, 53, 59, 58}, {35, 36, 42, 41, 53, 54, 60, 59},**/ {37, 38, 44, 43,55, 56, 62, 61}, {38, 39, 45, 44, 56, 57, 63, 62}, {39, 40, 46, 45, 57, 58, 64, 63}, {40, 41, 47, 46, 58, 59, 65, 64}, {41, 42, 48, 47,59, 60, 66, 65}, {43, 44, 50, 49, 61, 62, 68, 67}, {44, 45, 51, 50, 62, 63, 69, 68}, {45, 46, 52, 51, 63, 64, 70, 69}, {46, 47, 53, 52, 64, 65, 71, 70}, {47, 48, 54, 53, 65, 66, 72, 71}, /**{49, 50, 56, 55, 67, 68, 74, 73}, {50, 51, 57, 56, 68, 69, 75, 74},{51,52, 58, 57, 69, 70, 76, 75}, {52, 53, 59, 58, 70, 71, 77, 76}, {53, 54, 60, 59, 71, 72, 78, 77}}**/
Now, if you observe, I wanted the first ten elements
(1st to 10th element of modifiedtable) to be there in my final table
( DoubleModifiedTable ). the the next five (11th to 15th elements of modifiedtable) deleted.
Then the next ten elements ( 16th to 25th elements of modifiedtable)
to be present in my final table ( DoubleModifiedTable )
then the next five deleted (26th to 30th elements of modifiedtable) and so on for the whole table.
Let say we solve this problem and we name the final table DoubleModifiedTable.
I am basically interested in getting the DoubleModifiedTable. I decided to subdivide the problem as it easy to explain.
I want this to happen automatically through the table since as this is just an example table but in reality I have huge table. If I can understand how I can solve this problem for this table, then I can solve it for my large table too.
Perhaps simpler:
DoubleModifiedTable =
Module[{copy = modifiedtable},
copy[[Flatten[# + Range[5] & /# Range[10, Length[copy], 10]]]] = Sequence[];
copy]
EDIT
Even simpler:
DoubleModifiedTable =
Delete[modifiedtable,
Transpose[{Flatten[# + Range[5] & /# Range[10, Length[modifiedtable], 10]]}]]
EDIT 2
Per OP's request: one only has to change a single number (10 to 15) in any of my solutions to get the answer to a modified problem:
DoubleModifiedTable =
Delete[modifiedtable,
Transpose[{Flatten[# + Range[5] & /# Range[10, Length[modifiedtable], 15]]}]]
Another way is to do something like
DoubleModifiedTable = With[{n = 10, m = 5},
Flatten[{{modifiedtable[[;; m]]},
Partition[modifiedtable, n - m, n, {n - m + 1, 1}, {}]}, 2]]
Edit
The edited version of Problem 2 is actually slightly simpler to solve than the original version. You could for example do something like
DoubleModifiedTable =
With[{n = 10, m = 5}, Flatten[Partition[modifiedtable, n, n + m, 1, {}], 1]]
Edit 2
What my second version does is to split the original list modifiedtable into sublists using Partition and then to flatten these sublists to form the final list. If you look at the Documentation for Partition you can see that I'm using the 6th form of Partition which means that the length of the sublists is n and the offset (the distance be is n+m. The gap between the sublists is therefore n+m-n==m.
The next argument, 1, is actually equivalent to {1,1} which tells Mathematica that the first element of modifiedtable should appear at position 1 in the first sublist and the last element of modifiedtable should appear on or after position 1 of the last sublist.
The last argument, {} is to indicate that no padding should be used for sublists with length <=n.
In summary, if you want to delete the first 10 elements and keep the next 5 you want sublists of length n=5 with gap m=10. Since you want the first sublist to start with the (m+1)-th element of modifiedtable, you could replace the fourth argument in Partition with something of the form {k,1} for some value of k but it's probably easier to just drop the first m elements of modifiedtable beforehand, i.e.
DoubleModifiedTable =
With[{n = 5, m = 10},
Flatten[Partition[Drop[modifiedtable, m], n, n + m, 1, {}], 1]]
DoubleModifiedTable=
modifiedtable[[
Complement[
Range[Length[modifiedtable]],
Flatten#Table[10 i + j, {i, Floor[Length[modifiedtable]/10]}, {j, 5}]
]
]]
or, slightly shorter
DoubleModifiedTable=
#[[
Complement[
Range[Length[#]],
Flatten#Table[10 i + j, {i, Floor[Length[#]/10]}, {j, 5}]
]
]] & # modifiedtable

Setting up a Counter in a Table

I have two questions,
Q1.
The code is below:
orgtable = Table[{i, node2 = i + 1, node3 = node2 + 6, node4 = node3 - 1,
node5 = i + 18, node6 = node5 + 1, node7 = node6 + 6,
node8 = node7 - 1}, {i, 1, 36}
];
modtable = Drop[orgtable, {6, 36, 6}];
finaltable = With[{n = 5, m = 10},Flatten[Partition[modtable, n, n + m, 1, {}], 1]]
The first piece of code gives me an original table, the second one gives me a modified table, and the third yields the final table.
The output of the final table looks like this:
{{1, 2, 8, 7, 19, 20, 26, 25}, {2, 3, 9, 8, 20, 21, 27, 26},
{3, 4, 10, 9, 21, 22, 28, 27}, {4, 5, 11, 10, 22, 23, 29, 28},
{5, 6, 12,11, 23, 24, 30, 29}, {19, 20, 26, 25, 37, 38, 44,43},
{20, 21, 27,26, 38, 39, 45, 44}, {21, 22, 28, 27, 39, 40, 46, 45},
{22, 23, 29,28, 40,41, 47, 46}, {23, 24, 30, 29, 41, 42, 48, 47}}
But I want it to set up a counter to the final table so that my output should look like this(below):The counter will increase by 1 and in the below example it will start with 200;
{{200,1, 2, 8, 7, 19, 20, 26, 25}, {201,2, 3, 9, 8, 20, 21, 27, 26},
{202,3, 4,10, 9, 21,22, 28, 27}, {203,4, 5, 11, 10, 22, 23, 29, 28},
{204,5, 6, 12,11, 23, 24, 30, 29} and so on
As you can see from the desired output the count is present for each element and increases by one
Now question number two:
mycounter = 100;
tryone =
TableForm[
Flatten[
Table[{++mycounter, xcord, ycord,
(150*(Sin[((xcord - 90*2*3.14)/180]^2)*
(Sin[((ycord - 45)*2*3.14)/180]^2)
) + 20
}, {xcord, 0, 200, 5}, {ycord, 0, 200, 5}
], 1
]
]
In the above example, I have successfully implemented a counter which is starting from 100 and incrementing by 1 and it gives me an output
100 0 0 20.03
101 0 5 20.04 and so on..
But now I want to use the Transpose function on this, since I want to transpose the value presented but at the same time I don't want to transpose the "my counter".
mycounter = 100;
secondtry=
TableForm[
Flatten[
Transpose[
Table[{++mycounter, xcord, ycord,
(150*(Sin[((xcord - 90)*2*3.14)/180]^2)*
(Sin[((ycord - 45)*2*3.14)/180]^2)
) +20}, {xcord, 0, 200, 5}, {ycord, 0, 200, 5}
]
], 1
]
]
But as you can see the Transpose function transposes also the "mycounter" which I do not want. How do you prevent the transpose function from working on "mycounter" but work on the rest of it?
Any other idea of implementing a counter in the above code is also welcome.
Removed answer to first question as I probably didn't understand what you wanted.
As to the second question: I'm not sure whether I fully understand you here. If the counter belongs to the coordinate set the output should be left as it is, how awkward it may look. If the counter column is simply a line counter of the final output you could put in after you have done your flattening just like before.
But in this case, it seems the Transpose is fully superfluous. It suffices to switch the order of the indices of your table. If you do that you can leave your counter as it is:
mycounter = 100;
secondtry =
Flatten[
Table[{mycounter++, xcord,ycord,
(150*(Sin[((xcord - 90)*2*3.14)/180]^2)*
(Sin[((ycord - 45)*2*3.14)/180]^2)
) + 20},
{ycord,0, 200, 5}, {xcord, 0, 200, 5} (* order switched here *)
], 1
]
A few notes: I removed the TableForm from your assignment. This is generally only used for printing and not for data that gets assigned to a variable. If you want to do an assignment and want to see the result at the same time you could try something like
(myVar = Table[...{...},{...}] ) //TableForm
Also note that you don't have to multiply by 3.14/180 to convert degrees to radians. Mathematica has a built-in quantity named Degree for that (if you use the shortcut esc deg esc you will have a nice degree symbol instead). It looks like you are multiplying with 2 pi/180 for this conversion. If that was your intention, it was incorrect. The conversion is either 2 pi/360 or pi/180. ((xcord - 90)*2*3.14)/180 should then be written as (xcord - 90)Degree.
Question 1 :
Transpose[Prepend[Transpose[#], Range[Length[#]] + 200]] &#
{{1, 2, 8, 7, 19, 20, 26, 25}, {2, 3, 9, 8, 20, 21, 27, 26}, {3, 4,
10, 9, 21, 22, 28, 27}, {4, 5, 11, 10, 22, 23, 29, 28}, {5, 6, 12,
11, 23, 24, 30, 29}, {19, 20, 26, 25, 37, 38, 44, 43}, {20, 21, 27,
26, 38, 39, 45, 44}, {21, 22, 28, 27, 39, 40, 46, 45}, {22, 23,
29, 28, 40, 41, 47, 46}, {23, 24, 30, 29, 41, 42, 48, 47}}
Question2:
Function[mat,
Partition[
Transpose[Prepend[Transpose[#], Range[Length[#]] + 99]] &#
Flatten[mat, 1], Length[mat]]]#
Table[{xcord,
ycord, (150*(Sin[((xcord - 90)*2*3.14)/
180]^2)*(Sin[((ycord - 45)*2*3.14)/180]^2)
) + 20
}, {xcord, 0, 200, 50}, {ycord, 0, 200, 50}
]
Create the rest of the table without the counter, create a suitable n*1 matrix of the index using Range, and then use MapThread with the inner function Join to put the two together.
Your finaltable could also be produced from modtable using Table as follows:
finaltableAlt = Delete[#, Transpose#{Flatten#Table[i + j, {i, 5, (
Length[#] - 10), 15}, {j, 10}]}] & # modtable
Another possibility for numbering:
MapIndexed[Flatten#{#2[[1]] + 199, #1} &, finaltableAlt]