Thread: Asking slice_array for elements

  1. #1
    Caution: Wet Floor
    Join Date
    May 2006
    Posts
    55

    Asking slice_array for elements

    `cake' represents a 5-by-5 matrix. How would you do a row-wise addition on `cake'? I tried slicing `cake' and adding the slices, but things like state = cake[l1] + ... + cake[l5];
    are illegal, and now I'm stuck.

    Code:
     
      1 0 0 0 0 }
      0 1 0 0 0 }
      1 0 0 0 0 } `cake'
      0 0 0 1 0 }
     +0 0 0 0 1 }
    -------------
       2 1 0 1 1 `state'
    Code:
    void cycle(int balls) {
    
      valarray<int> state(0, 5);   // State of the machine
      valarray<int> cake(0, 25);  // A "cake" with five layers (slices)
    
      state[0] = balls;
    
      // FORTRAN-style indexing is used: elements are read top to bottom,
      // and left to right.
    
      slice_array<int> l1 = cake[slice(0, 5, 1)];
      slice_array<int> l2 = cake[slice(5, 5, 1)];
      slice_array<int> l3 = cake[slice(10, 5, 1)];
      slice_array<int> l4 = cake[slice(15, 5, 1)];
      slice_array<int> l5 = cake[slice(20, 5, 1)];
    
      for(int i = 0; i < 5; i++) {
    
        state[i] = cake[0+i] + cake[5+i] + cake[10+i] + cake[15+i] + cake[20+i];
    
      }
    }
    Also, how would you make this function more compact?

    Thanks!

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> I tried slicing `cake' and adding the slices
    I see where you created slices l1 through l5 - but not where you've tried to add them.

    Since slice_array<> doesn't have a nice sum() method, this would be my first attempt:
    Code:
    for (int i = 0; i < 5; ++i) 
        state[i] = valarray<int>(cake[slice(i * 5, 5, 1)]).sum();
    gg

  3. #3
    Caution: Wet Floor
    Join Date
    May 2006
    Posts
    55
    Thanks, Codeplug. The function works now, but it's very sloppy, and the goal is efficiency (which is why numeric containers were used in the first place). Would inlining or recursion be reasonable here?

    Code:
    // 5**5 values
    
    void cycle(int balls) {
    
      // Return the next cyclic arrangement of b
    
      valarray<int> state(0, 5); // State of the machine
      valarray<int> cake(0, balls*5); // A "cake" with five layers (slices)
    
      for(int b = 0; b < balls; b++) cake[5*b] = 1;
    
      // FORTRAN-style indexing is used: elements are read top to bottom,
      // and left to right.
    
      enum Odometer { L2 = 5, L3 = 25, L4 = 125, L5 = 625, LD = 3125};
      for(;;) {
        static int ct = 0;
    
        ct++;
    
        for(int k = 0; k < balls; k++){
          state[k] = valarray<int>(cake[slice(k, 5, 5)]).sum();
          cout << state[k] << " ";
        }
        cout << '\n';
    
        cake[slice(0, 5, 1)] = valarray<int>(cake[slice(0, 5, 1)]).cshift(-1);
    
        if(ct % L2 == 0)
          cake[slice(5, 5, 1)] = valarray<int>(cake[slice(5, 5, 1)]).cshift(-1);
        if(ct % L3 == 0)
          cake[slice(10, 5, 1)] = valarray<int>(cake[slice(10, 5, 1)]).cshift(-1);
        if(ct % L4 == 0)
          cake[slice(15, 5, 1)] = valarray<int>(cake[slice(15, 5, 1)]).cshift(-1);
        if(ct % L5 == 0)
          cake[slice(20, 5, 1)] = valarray<int>(cake[slice(20, 5, 1)]).cshift(-1);
    
        if(ct % LD == 0) break;
      }
    }

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Don't use valarrays. They aren't implemented efficiently, because you have to cast all the intermediate types to valarray, which kills the efficiency is was intended to provide.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

Popular pages Recent additions subscribe to a feed