Related
I'm wondering if there is any easier way to prevent accessing array beyond range than using if() statement.
I have switch case code for arduino like this with many cases:
switch(a){
case 3:
case 27:
for (int i = 0; i < 8; i++){
leds[ledMapArray[x][i]] = CRGB(0,255,0);
leds[ledMapArray[i][y]] = CRGB(0,255,0);
if ((x + i < 8) && (y + i < 8)) leds[ledMapArray[x + i][y + i]] = CRGB(0,255,0);
if ((x - i >= 0) && (y - i >= 0)) leds[ledMapArray[x - i][y - i]] = CRGB(0,255,0);
if ((x + i < 8) && (y - i >= 0)) leds[ledMapArray[x + i][y - i]] = CRGB(0,255,0);
if ((x - i >= 0) && (y + i < 8)) leds[ledMapArray[x - i][y + i]] = CRGB(0,255,0);
}
break;
case 4:
case 28:
if (x + 1 < 8) leds[ledMapArray[x + 1][y]] = CRGB(0,255,0);
if (x - 1 >= 0) leds[ledMapArray[x - 1][y]] = CRGB(0,255,0);
if (y - 1 >= 0) leds[ledMapArray[x][y - 1]] = CRGB(0,255,0);
if (y + 1 < 8) leds[ledMapArray[x][y + 1]] = CRGB(0,255,0);
if ((x + 1 < 8) && (y + 1 < 8)) leds[ledMapArray[x + 1][y + 1]] = CRGB(0,255,0);
if ((x - 1 >= 0) && (y - 1 >= 0)) leds[ledMapArray[x - 1][y - 1]] = CRGB(0,255,0);
if ((x + 1 < 8) && (y - 1 >= 0)) leds[ledMapArray[x + 1][y - 1]] = CRGB(0,255,0);
if ((x - 1 >= 0) && (y + 1 < 8)) leds[ledMapArray[x - 1][y + 1]] = CRGB(0,255,0);
break;
...
ledMapArray is 8x8 array where x and y value may be <7,0>. Here are some definitions:
// CRGB is structure from FastLed library
CRGB leds[NUM_LEDS]; // from FastLed library to control LED strip
// Array to show how LED strip looks like, values in array represents leds
const short ledMapArray[8][8] = {{0, 1, 2, 3, 4, 5, 6, 7},
{15, 14, 13, 12, 11, 10, 9, 8},
{16, 17, 18, 19, 20, 21, 22, 23},
{31, 30, 29, 28, 27, 26, 25, 24},
{32, 33, 34, 35, 36, 37, 38, 39},
{47, 46, 45, 44, 43, 42, 41, 40},
{48, 49, 50, 51, 52, 53, 54, 55},
{63, 62, 61, 60, 59, 58, 57, 56}};
The point of this switch case is to light up specific LEDs from LED strip. I want to show allowed moves for chess pieces on smart chessboard.
Is there any better way to do this?
The Answer was written when the question used the tag c, not c++ and edited later. The FastLED library is clearly implemented in C++.
You could wrap the array access in a function that implements the checks.
The following function assumes that the array leds and ledMapArray are file scope variables. Otherwise the function would need more arguments. In C++, the function will also work if the function and the variables are members of the same class.
Instead of a hard-coded number 8, the check should better be implemented based on the number of elements in the array. (Something like sizeof(array)/sizeof(array[0]). I would need to see the definition of leds and ledMapArray.)
Note that the function implements a bounds check for ledMapArray only, not for leds.
void setLed(int x, int y, some_type crgb)
{
if((x >= 0) && (x < 8) && (y >= 0) && (y < 8))
{
leds[ledMapArray[x][y]] = crgb;
}
}
The function could also be replaced with a macro which would work for local array variables as well as for global variables.
#define setLed(x, y, crgb) do { \
if((x >= 0) && (x < 8) && (y >= 0) && (y < 8)) { \
leds[ledMapArray[x][y]] = crgb; \
} \
} while(0)
switch(x){
case 3:
case 27:
for (int i = 0; i < 8; i++){
setLed(x, i, CRGB(0,255,0));
setLed(i, y, CRGB(0,255,0));
setLed(x + i, y + i, CRGB(0,255,0));
setLed(x - i, y - i, CRGB(0,255,0));
setLed(x + i, y - i, CRGB(0,255,0));
setLed(x - i, y + i, CRGB(0,255,0));
}
break;
case 4:
case 28:
setLed(x + 1, y, CRGB(0,255,0));
/* etc ... */
Instead of repeatedly using anonymous objects with the same constructor CRGB(0,255,0), you could use a named object.
CRGB greenColor(0,255,0);
setLed(x, i, greenColor);
setLed(i, y, greenColor);
/* etc ... */
Or use pre-defined color objects from the library.
setLed(x, i, CRGB::Green);
setLed(i, y, CRGB::Green);
/* etc ... */
Question: How can I make these oscillate as such that the first digits or expression is + the next is - the one after is + and so on and so forth for the lists provided below (without using a specially made function for oscillation if one even exists).
I'm currently getting output as shown below:
x + x^3/6 + x^5/120 + x^7/5040 + x^9/362880
1. {1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69,
73, 77, 81, 85, 89}
Expected output:
x - x^3/6 + x^5/120 - x^7/5040 + x^9/362880
2. {1, -5, 9, -13, 17, -21, 25, -29, 33, -37, 41, -45, 49, -53, 57, -61, 65, -69, 73, -77, 81, -85, 89}
Sum[x^j/Factorial[j], {j, 1, 9, 2}];
myOsc = Table[i, {i, 1, 89, 4}];
A small improvement that does not require the extra s variable:
MapIndexed[(-1)^(1 + #2[[1]])*#1 &, x + x^3/6 + x^5/120 + x^7/5040 + x^9/362880]
x - x^3/6 + x^5/120 - x^7/5040 + x^9/362880
Sum[If[OddQ[(j - 1)/2], -x^j, x^j]/Factorial[j], {j, 1, 9, 2}]
x - x^3/6 + x^5/120 - x^7/5040 + x^9/362880
myOsc = Table[If[OddQ[(i - 1)/4], -i, i], {i, 1, 89, 4}]
{1, -5, 9, -13, 17, -21, 25, -29, 33, -37, 41, -45, 49, -53, 57, -61, 65, -69, 73, -77, 81, -85, 89}
s = -1; Map[(s *= -1) # &, x + x^3/6 + x^5/120 + x^7/5040 + x^9/362880]
x - x^3/6 + x^5/120 - x^7/5040 + x^9/362880
note of caution mathematica will put your expression in canonical order for you first. So for example if you key it in like this:
s = -1; Map[(s *= -1) # &,x^3/6 + x + x^5/120 + x^7/5040 + x^9/362880]
you get the same result
x - x^3/6 + x^5/120 - x^7/5040 + x^9/362880
I am getting a runtime SIGBUS with the call stack showing as below:
--- called from signal handler with signal 10 (SIGBUS) ---
001279b8 allocate__t24__default_alloc_template2b0i0Ui (20, 20, 2fa3c0, 32, 0, 0
) + a4
00117380 __nw__Q2t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc
_template2b0i0_3RepUiUi (10, 10, 838e00, 0, 0, 0) + 14
001173c0 create__Q2t12basic_string3ZcZt18string_char_traits1ZcZt24__default_all
oc_template2b0i0_3RepUi (9, 9, 838e00, 9, 0, 0) + 24
00117784 replace__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_allo
c_template2b0i0UiUiPCcUi (fbf7f758, 0, ffffffff, fcbf40c2, 9, 80808080) + 114
0012b988 assign__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc
_template2b0i0PCcUi (fbf7f758, fcbf40c2, 9, ffffffff, ffffffff, 20) + 24
0012a35c assign__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc
_template2b0i0PCc (fbf7f758, fcbf40c2, 90, b0, 1ff0, 0) + 24
00127170 __t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_templ
ate2b0i0PCc (fbf7f758, fcbf40c2, fcbf40b8, 1c00, 9, 7c) + 28
What could be the cause?
Stack overflow? or no more space on heap?
I have a piece of code like this:
#include<LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void leftShift(bool toShift[28], int noOfShifts, bool destination[28]) {
for (int i = 0; i < 28; i++) {
destination[(i - noOfShifts + 28) % 28] = toShift[i];
}
}
void divideBinary(bool binary[], size_t sizeOfBinary, bool LB[], bool RB[]) {
size_t half = sizeOfBinary / 2;
// LB - first half
size_t i = 0;
for (; i < half; i++) {
LB[i] = binary[i];
}
// RB - second half
for (; i < half * 2; i++) {
RB[i - half] = binary[i];
}
}
void createSubkeys(bool binaryKey[8 * 8], bool subkeys[16][48]) {
Serial.println("just entered subkeys"); Serial.flush();
int pc_1[56] = {
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
};
bool keyPermutation[56];
// according to pc_1 create from 64-bit key 56-bit keyPermutation
for (int i = 0; i < 56; i++) {
keyPermutation[i] = binaryKey[pc_1[i] - 1];
}
// C and D will be saved here: [C/D] [index] [28 bools]
bool CD[2][16 + 1][56 / 2];
Serial.println("CD ready"); Serial.flush();
// divide keyPermutation into halves to C0 a D0 - each consists of 28 bits
divideBinary(keyPermutation, 56, CD[0][0], CD[1][0]);
// from C0, D0 and shifts make C1, D1 -> C16, D16
int shifts[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
for (int i = 1; i < 17; i++) {
leftShift(CD[0][i - 1], shifts[i - 1], CD[0][i]);
leftShift(CD[1][i - 1], shifts[i - 1], CD[1][i]);
}
// each subKey out of 16 is made from one out of 16 CD with the use of pc_2
int pc_2[48] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 48; j++) {
// find out which part of CD we should look at - that means C, or D? for C CorD is 0, for D 1
int where = pc_2[j] - 1;
bool CorD = 0;
if (where >= 56 / 2) {
CorD = 1;
where -= 56 / 2; // subtract 28, to start indexing from 0 again in case of D
}
subkeys[i][j] = CD[CorD][i + 1][where];
}
}
// Serial.println("subkeys ready");
}
void setup() {
// put your setup code here, to run once:
Serial.begin( 9600 );
lcd.begin(16, 2);
Serial.println("ready"); Serial.flush();
bool binaryKey[8 * 8];
bool subkeys[16][48];
createSubkeys(binaryKey, subkeys);
}
void loop() {
// put your main code here, to run repeatedly:
lcd.setCursor(0,0);
lcd.print("haf");
}
It is not really important what it does, it is just so you can roughly see its complexity.
Why won't this work on Arduino, even if it were to be much slower? Instead, when I run it, my Arduino UNO really behaves weirdly. In Serial it just repeats a sequence of characters "jready" in a loop. Forever. It never prints anything else and it never reaches the loop() function.
My Arduino and its Serial both work perfectly fine for smaller programs.
EDIT: If I attempt to locate the problem by commenting out blocks of code, it seems to occur here:
// from C0, D0 and shifts make C1, D1 -> C16, D16
int shifts[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
for (int i = 1; i < 17; i++) {
leftShift(CD[0][i - 1], shifts[i - 1], CD[0][i]);
leftShift(CD[1][i - 1], shifts[i - 1], CD[1][i]);
}
But if I make my setup() function more complex, it happens earlier, on this line:
divideBinary(keyPermutation, 56, CD[0][0], CD[1][0]);
You are passing variables to methods without correctly specifying whether they should return that value which you modify inside that method. Look at:
void leftShift(bool toShift[28], int noOfShifts, bool destination[28])
You modify destination in there but destination is boolean array copied to the method but when the method finishes that modified value is not returned to the caller. Change your declarations.
Here:
bool CD[2][16 + 1][56 / 2];
You have a third dimension to the array but never use it. The third dimension has 28 elements but you only ever use the second dimension. If you are trying to do pointer operations then you will have to change leftShift
Also consider the above points I made with divideBinary.
Assuming that I have the following matrix/array:
array([[0, 0, 1, 1, 1],
[0, 0, 1, 0, 1],
[1, 1, 0, 1, 1],
[1, 0, 1, 0, 0],
[1, 1, 1, 0, 0]])
and I want to apply the following permutation:
1 -> 5
2 -> 4
the result should be in the end:
array([[1, 1, 1, 0, 0],
[1, 0, 1, 0, 0],
[1, 1, 0, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 1, 1, 1]])
Now, an incredibly naive (and memory costly) way of doing so might be:
a2 = deepcopy(a1)
a2[0,:] = a1[4,:]
a2[4,:] = a1[0,:]
a = deepcopy(a2)
a2[:,0] = a[:,4]
a2[:,4] = a[:,0]
a3 = deepcopy(a2)
a2[1,:] = a3[3,:]
a2[3,:] = a3[1,:]
a = deepcopy(a2)
a2[:,1] = a[:,3]
a2[:,3] = a[:,1]
But, I would like to know if there is something more efficient that does this. numpy.shuffle and numpy.permutation seem to permute only the rows of the matrix (not the columns at the same time). That doesn't work for me because the matrices are adjacency matrices (representing graphs), and I need to do the permutations which will give me a graph which is isomorphic with the original graph. Furthermore, I need to do an arbitrary number of permutations (more than one).
Thanks!
You can perform the swap in a one-liner using integer array indexing:
a = np.array([[0, 0, 1, 1, 1],
[0, 0, 1, 0, 1],
[1, 1, 0, 1, 1],
[1, 0, 1, 0, 0],
[1, 1, 1, 0, 0]])
b = a.copy()
# map 0 -> 4 and 1 -> 3 (N.B. Python indexing starts at 0 rather than 1)
a[[4, 3, 0, 1]] = a[[0, 1, 4, 3]]
print(repr(a))
# array([[1, 1, 1, 0, 0],
# [1, 0, 1, 0, 0],
# [1, 1, 0, 1, 1],
# [0, 0, 1, 0, 1],
# [0, 0, 1, 1, 1]])
Note that array indexing always returns a copy rather than a view - there's no way to swap arbitrary rows/columns of an array without generating a copy.
In this particular case you could avoid the copy by using slice indexing, which returns a view rather than a copy:
b = b[::-1] # invert the row order
print(repr(b))
# array([[1, 1, 1, 0, 0],
# [1, 0, 1, 0, 0],
# [1, 1, 0, 1, 1],
# [0, 0, 1, 0, 1],
# [0, 0, 1, 1, 1]])
Update:
You can use the same indexing approach to swap columns.
c = np.arange(25).reshape(5, 5)
print(repr(c))
# array([[ 0, 1, 2, 3, 4],
# [ 5, 6, 7, 8, 9],
# [10, 11, 12, 13, 14],
# [15, 16, 17, 18, 19],
# [20, 21, 22, 23, 24]])
c[[0, 4], :] = c[[4, 0], :] # swap row 0 with row 4...
c[:, [0, 4]] = c[:, [4, 0]] # ...and column 0 with column 4
print(repr(c))
# array([[24, 21, 22, 23, 20],
# [ 9, 6, 7, 8, 5],
# [14, 11, 12, 13, 10],
# [19, 16, 17, 18, 15],
# [ 4, 1, 2, 3, 0]])
I've used a different example array in this case - your version will yield an identical output after performing the row/column swaps which makes it difficult to understand what's going on.
I found a solution to do what I want (though it is expensive):
a2 = deepcopy(a1)
first = randint(0, 5, 10)
second = randint(0, 5, 10)
for i in range(len(first)):
a = deepcopy(a2)
a2[first[i],:] = a[second[i],:]
a2[second[i],:] = a[first[i],:]
for i in range(len(first)):
a = deepcopy(a2)
a2[:,first[i]] = a[:,second[i]]
a2[:,second[i]] = a[:,first[i]]
Basically, I am doing 10 random switches. However, I need to copy the matrix many times. Anyway, a2 now represents a graph which is isomorphic with a1.