1

I'm currently working on a genetic algorithm, and want to convert my "population" into binary from decimal, so I can do crossovers more easily.

I have an array of 70x71 array of numbers (a population of 70; each population member has 71 variables).

Is there a way I can map BaseForm[] onto each element, whilst keeping the array format?

I tried doing this:

population=RandomReal[1,{70,71}];
binaryPopulation = {};
For[i = 1, i <= 70, i++,
  For[j = 1, j <= 71, j++,
    AppendTo[binaryPopulation, BaseForm[population[[i, j]], 2]]
    ];
  ];

But this generates one large array (ie. not separated into 70 different members, it's just one long array).

Any help would be much appreciated!

Thanks

Rohit Namjoshi
  • 10,212
  • 6
  • 16
  • 67

2 Answers2

3

A minimal working example does not require a 70x71 array.

(population = RandomReal[1, {2, 3}]) // MatrixForm

enter image description here

(binaryPopulation = Map[{#, BaseForm[#, 2]} &, population, {2}]) // MatrixForm

enter image description here

However, BaseForm is a display form used for printing. Perhaps you want something like

(binaryPopulation = 
   Map[{#, FromDigits[RealDigits[#, 2]]} &, population, {2}]) // 
  MatrixForm

enter image description here

Or

(binaryPopulation = 
   Map[{#, {Numerator[
        r = FromDigits[RealDigits[#, 2]]], -Log10[Denominator[r]]}} &, 
    population, {2}]) // MatrixForm

enter image description here

Bob Hanlon
  • 157,611
  • 7
  • 77
  • 198
  • Isn't this answer the same as my comment to the OP? – Rohit Namjoshi Apr 04 '22 at 14:10
  • 2
    Mechanically yes; however, I am suggesting that BaseForm may not be want is desired. – Bob Hanlon Apr 04 '22 at 14:13
  • Good point Bob, newbies frequently apply MatrixForm, TableForm, ... to an expression and are surprised when subsequent evaluations fail to work as expected. – Rohit Namjoshi Apr 04 '22 at 14:18
  • OTOH, I can't imagine wanting FromDigits[RealDigits[#, 2]] since it changes the numeric value. That is, I'd rather have my numbers be the number they represent. Also FromDigits[RealDigits[0.8455762478601447`, 2]] has an extra bit than RealDigits[0.8455762478601447`, 2]. That darned base 10, I guess. – Michael E2 Apr 04 '22 at 14:32
1

The direct way to translate array construction via a nested for loop is to use Table; see Why should I avoid the For loop in Mathematica?

binaryPopulation = Table[BaseForm[population[[i, j]], 2], {i, 70}, {j, 71}];

Map as in @RohitNamjoshi's comment and @BobHanlon's answer is the preferred functional-programming approach.

Another alternative is

binaryPopulation = Function[, BaseForm[#, 2], Listable][population];
Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • To get a binary rational number, as in Bob Hanlon's answer, you could use Function[, BaseForm[SetPrecision[#, Infinity], 2], Listable], since SetPrecision[real, Infinity] converts a floating-point real to its binary fraction. – Michael E2 Apr 04 '22 at 19:45