void write_solution(uchar our_index[16], global uchar *solution) {
uchar8 solution_data = 0;
solution_data.s0 = (our_index[0] & 0xF) + ((our_index[1] & 0xF) << 4);
solution_data.s1 = (our_index[2] & 0xF) + ((our_index[3] & 0xF) << 4);
solution_data.s2 = (our_index[4] & 0xF) + ((our_index[5] & 0xF) << 4);
solution_data.s3 = (our_index[6] & 0xF) + ((our_index[7] & 0xF) << 4);
solution_data.s4 = (our_index[8] & 0xF) + ((our_index[9] & 0xF) << 4);
solution_data.s5 = (our_index[10] & 0xF) + ((our_index[11] & 0xF) << 4);
solution_data.s6 = (our_index[12] & 0xF) + ((our_index[13] & 0xF) << 4);
solution_data.s7 = (our_index[14] & 0xF) + ((our_index[15] & 0xF) << 4);
vstore8(solution_data, 0, solution);
}
As can be seen in the code, it would be really lovely if I could just write it like this instead:
void write_solution(uchar our_index[16], global uchar *solution) {
uchar8 solution_data = 0;
for(int i = 0; i < 8; i++) {
solution_data[i] = (our_index[i * 2] & 0xF) + ((our_index[i * 2 + 1] & 0xF) << 4);
}
vstore8(solution_data, 0, solution);
}
But of course, OpenCL doesn't allow the indexed notation described in the above code to be used with vector types.
Is there anything I can do to solve this issue?
Vector operations are component-wise, and you can take advantage of the .even and .odd vector addressing modes. Does this work for you?
void write_solution(uchar16 our_index, global uchar *solution) {
uchar8 solution_data = 0;
solution_data = (our_index.even & 0xF) + ((our_index.odd & 0xF) << 4);
vstore8(solution_data, 0, solution);
}
Related
I am trying to work on an Arduino project and for some reason, I cannot get it to store the data on the Adafruit Metro M4 controller or data logger shield (saving so that when reconnected, the data entered would still be there).
I have an SD card for the TFT LCD, I would appreciate any help, not sure what I'm missing.
Here is basically what I have so far related to EEPROM functions and it seems to compile without errors but does not work for EEPROM. If I run it on a different board (Arduino Uno) it seems to activate but then the issue is that the code is intended to run only on SAMD21 or SAMD51 boards.
Is there a way to adapt the EEPROM functions for the Metro M4 or can any changes be made to get it functional? Please let me know if there are any questions, I appreciate any and all help!
void readAllConfiguration() {
readLogs();
AveragePeriodDuration = EEPROM.read(ADDR_AVERAGE_DAYS);
LogId = EEPROM.read(ADDR_LOGGED_COUNT);
Serial.print("Lod ID mem: ");
Serial.println(LogId);
if(LogId > 100)
LogId = 0;
if (AveragePeriodDuration > 100)
AveragePeriodDuration = 28;
}
bool checkResetEEPROM() {
uint8_t number = EEPROM.read(ADDR_MAGIC_NUMBER);
Serial.print("Magic number: ");
Serial.println(number);
if (number != MAGIC_NUMBER) {
for (uint8_t i=0; i<5; i++) {
saveLong(ADDR_START_TIME[i], 0);
saveLong(ADDR_END_TIME[i], 0);
for(uint8_t x=0; x<5; x++)
saveString(ADDR_SYMPTOMS[i][x], "");
}
EEPROM.write(ADDR_PERIOD_STATE, 0);
EEPROM.write(ADDR_AVERAGE_DAYS, 28);
EEPROM.write(ADDR_MAGIC_NUMBER, MAGIC_NUMBER);
EEPROM.commit();
Serial.println(EEPROM.read(ADDR_MAGIC_NUMBER));
return true;
}
return false;
}
void readLogs() {
if (LogId == 0)
return;
for (uint8_t i=0; i<5; i++) {
LogCycle[i].StartTime = readLong(ADDR_START_TIME[i]);
LogCycle[i].EndTime = readLong(ADDR_END_TIME[i]);
for (uint8_t x=0; x<5; x++)
LogCycle[i].symptoms[x] = readString(ADDR_SYMPTOMS[i][x]);
}
}
void saveString(int addr, const String &strToWrite) {
byte len = strToWrite.length();
for (int i = 0; i < len; i++){
EEPROM.update(addr + i, strToWrite[i]);
}
EEPROM.commit();
}
String readString(int addr) {
char read_data[16];
for (int i = 0; i < 16; i++)
read_data[i] = EEPROM.read(addr + i);
return String(read_data);
}
uint32_t readLong(int addr) {
long Byte4 = EEPROM.read(addr);
long Byte3 = EEPROM.read(addr + 1);
long Byte2 = EEPROM.read(addr + 2);
long Byte1 = EEPROM.read(addr + 3);
return ((Byte4 << 0) & 0xFF) + ((Byte3 << 8) & 0xFFFF) + ((Byte2 << 16) & 0xFFFFFF) + ((Byte1 << 24) & 0xFFFFFFFF);
}
void saveLong(int addr, uint32_t val) {
byte Byte4 = ((val >> 0) & 0xFF);
byte Byte3 = ((val >> 8) & 0xFF);
byte Byte2 = ((val >> 16) & 0xFF);
byte Byte1 = ((val >> 24) & 0xFF);
EEPROM.write(addr, Byte4);
EEPROM.write(addr + 1, Byte3);
EEPROM.write(addr + 2, Byte2);
EEPROM.write(addr + 3, Byte1);
EEPROM.commit();
}
void saveOneCycle(uint8_t i) {
saveLong(ADDR_START_TIME[i], LogCycle[i].StartTime);
saveLong(ADDR_END_TIME[i], LogCycle[i].EndTime);
for(uint8_t x=0; x<5; x++)
saveString(ADDR_SYMPTOMS[i][x], LogCycle[i].symptoms[x]);
EEPROM.commit();
}
void saveAllCycles() {
for(uint8_t i=0; i<5; i++) {
saveLong(ADDR_START_TIME[i], LogCycle[i].StartTime);
saveLong(ADDR_END_TIME[i], LogCycle[i].EndTime);
for(uint8_t x=0; x<5; x++)
saveString(ADDR_SYMPTOMS[i][x], LogCycle[i].symptoms[x]);
}
EEPROM.commit();
}
I am working on the medical GUI development with QT and VTK. I have made MPR (MultiPlanar reformation) in VTK alone, but it does not display when I show it in QT (basically I add the renderwindow and renderer to QVTKWidget). I also tried QVTKOpenGLNativeWidget as an option, but it does not work as well. I knew it needs vtkGenericOpenGLRenderWindow where for display.
coding environment:
QT5.9 VS2017 VTK8.2.0
alone:
in QT:
here is my code
void BorderWidgetQt::openMPRwindow(QVTKWidget* qvtkwidget) {
QVTKInteractor* iren = qvtkwidget->GetInteractor();
vtkRenderWindow* renWin = qvtkwidget->GetRenderWindow();
vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
reader->SetDirectoryName("C:\\Users\\u\\source\\repos\\myrobotapp\\DICOM");
reader->Update();
vtkSmartPointer<vtkRenderer> ren; //vtksmartpointer
//vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
renWin->SetMultiSamples(0);
ren = vtkSmartPointer<vtkRenderer>::New();
renWin->AddRenderer(ren);
//vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
//renWin->SetInteractor(iren);
vtkSmartPointer<vtkProperty> ipwProp = vtkSmartPointer<vtkProperty>::New();
int imageDims[3];
reader->GetOutput()->GetDimensions(imageDims);
for (int i = 0; i < 3; i++) {
std::cout << "imagesize L X W X H: " << imageDims[i] << std::endl;
}
vtkSmartPointer< vtkResliceCursor > resliceCursor = vtkSmartPointer< vtkResliceCursor >::New();
resliceCursor->SetCenter(reader->GetOutput()->GetCenter());
resliceCursor->SetThickMode(1);// mode 1 or more and thickness can be viewed
//set image that are resliced
resliceCursor->SetImage(reader->GetOutput());
vtkSmartPointer< vtkResliceCursorWidget > resliceCursorWidget;
vtkSmartPointer< vtkResliceCursorLineRepresentation > resliceCursorRep;
//camera viewup
double viewUp[3][3] = { { 1, 0, -1 }, { 0, 0, 1 }, { 0, 1, 0 } };
/************************/
resliceCursorWidget = vtkSmartPointer< vtkResliceCursorWidget >::New();
resliceCursorWidget->SetInteractor(iren);
resliceCursorRep = vtkSmartPointer< vtkResliceCursorLineRepresentation >::New();
resliceCursorWidget->SetRepresentation(resliceCursorRep);
resliceCursorRep->GetResliceCursorActor()->GetCursorAlgorithm()->SetResliceCursor(resliceCursor);
//thickness text is ediable and can turn off
//resliceCursorRep->DisplayTextOff();
resliceCursorRep->GetResliceCursorActor()->GetCursorAlgorithm()->SetReslicePlaneNormal(0);
cout << "number of input port: " << resliceCursorRep->GetResliceCursorActor()->GetCursorAlgorithm() << endl;
const double minVal = reader->GetOutput()->GetScalarRange()[0];
std::cout << "minVal: " << minVal << " maxVal: " << reader->GetOutput()->GetScalarRange()[1] << endl; //0~1059
if (vtkImageReslice *reslice = vtkImageReslice::SafeDownCast(resliceCursorRep->GetReslice()))
{
reslice->SetBackgroundColor(minVal, minVal, minVal, minVal);
}
resliceCursorWidget->SetDefaultRenderer(ren);
resliceCursorWidget->SetEnabled(1);
ren->GetActiveCamera()->SetFocalPoint(0, 0, 0);
double camPos[3] = { 1, 0, 0 };
ren->GetActiveCamera()->SetPosition(camPos);
ren->GetActiveCamera()->ParallelProjectionOn();
ren->GetActiveCamera()->SetViewUp(viewUp[0][0], viewUp[0][1], viewUp[0][2]);
ren->ResetCamera();
double range[2];
reader->GetOutput()->GetScalarRange(range);
std::cout << "range[0]: " << range[0] << " range[1]: " << range[1] << endl; // 0~1059
//cover full range of window
resliceCursorRep->SetWindowLevel(range[1] - range[0], (range[0] + range[1]) / 2.0);
//resliceCursorRep->SetLookupTable(resliceCursorRep->GetLookupTable());
//reslice cursor center
vtkResliceCursor *rc = resliceCursorRep->GetResliceCursorActor()->GetCursorAlgorithm()->GetResliceCursor();
double *center = rc->GetCenter();
std::cout << "cursor center: " << " [x]: "
<< center[0] << " [y]: " << center[1] << " [z]: " << center[2] << endl;
/************************/
//background of window
ren->SetBackground(0.3, 0.1, 0.1);
//whether it is a hole in the center of two cross hair
resliceCursor->SetHole(0);
resliceCursor->SetThickness(2, 2, 2);
cout << "thickness is : " << resliceCursor->GetThickness()[0] << endl;
vtkSmartPointer< vtkInteractorStyleImage > style = vtkSmartPointer< vtkInteractorStyleImage >::New();
iren->SetInteractorStyle(style);
renWin->Render();
//iren->Initialize();
//iren->Start();
}
it was solved when I just claim the following in head file and make corresponding change in cpp:
private:
vtkSmartPointer< vtkResliceCursorWidget > resliceCursorWidget;
I don't know the depth of the solution. Maybe the QT cannot read the source file if it is not claimed, and also it needs timely render the source.
i've seen this interesting method to encrypt/decrypt messages with RSA on YouTube and it works, I've tested it : https://www.youtube.com/watch?v=tXXnHXslVhw&t=98s minute 1:45 . I am not that good at math, is there a name for what this guy is doing?
void En() {
crypted= text;
unsigned long long temp=0;
unsigned long long enc = 0;
for (int i = 0; i < text.length() / 2; i++)
{
if (text[i]>='a' && text[i] <= 'z')
{
temp = (text[i] - 96) * 26 + text[i + 1] - 96;
enc = pow(temp, public_key);
enc= enc % N
cout << enc << endl;
enc_v2 = enc;
}
}
cout << "Enc: " << enc << endl;}
void De() {
unsigned long long temp2 = 0;
unsigned long long temp = 0;
char ch=' ', ch2=' ';
for (int i = 0; i < text.length()/2; i++)
{
cout << enc_v2 << private_key;
temp = pow(enc_v2, private_key);
cout << "Temp :" << temp;
temp = temp % N;
cout << "Temp modulo :" << temp;
temp2 = temp;
temp = temp / 26;
cout << " Temp char 1 :"<< temp;
ch = temp + 96;
temp2 = temp2 - temp * 26;
cout << " Temp char 1 :" << temp2;
ch2 = temp2 + 96;
}
cout << "Text: " << ch << ch2;}
P.S. I know about the pow and modular exponentiation , this in only to show what he is doing.
Thank you!
I want to display a floating number in Qt with a fixed amount of digits (4), but without filling non-used digits with zero (the equivalent of having a maximum number of digits). In other words, this is what I want to show for the following examples:
0 -> 0.0
10 -> 10.0
980.5 -> 980.5
1200.5 -> 1.200 k
9900.9 -> 9.900 k
120500.9 -> 120.5 k
999888.88 -> 999.9 k
etc.. I tried many combinations of both QString::number() as well as QString::args(), without success. So how can I do that?
Note: I'm aware that for numbers higher then 1000, I'll have to apply a division and add the label 'k' manually - I'm already doing that.
EDIT:
The following code does exactly what I want, only that it is quite inappropriate with all those if else. I would like to know how can I do that with Qt's functions:
float temp = getSomeValue();
const char* itemUnities[] = { "V", "W", "A", "J" };
if (temp < 10.0f)
{
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',3));
painter.drawText(defaultX + 110,yPosition,tr(itemUnities[aaa]));
}
else if (temp < 100.0f)
{
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',2));
painter.drawText(defaultX + 110,yPosition,tr(itemUnities[aaa]));
}
else if (temp < 1000.0f)
{
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',1));
painter.drawText(defaultX + 110,yPosition,tr(itemUnities[aaa]));
}
else if (temp < 10000.0f)
{
temp *= 0.001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',3));
painter.drawText(defaultX + 110,yPosition,tr("k") + tr(itemUnities[aaa]));
}
else if (temp < 100000.0f)
{
temp *= 0.001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',2));
painter.drawText(defaultX + 110,yPosition,tr("k") + tr(itemUnities[aaa]));
}
else if (temp < 1000000.0f)
{
temp *= 0.001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',1));
painter.drawText(defaultX + 110,yPosition,tr("k") + tr(itemUnities[aaa]));
}
else if (temp < 10000000.0f)
{
temp *= 0.000001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',3));
painter.drawText(defaultX + 110,yPosition,tr("M") + tr(itemUnities[aaa]));
}
else if (temp < 100000000.0f)
{
temp *= 0.000001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',2));
painter.drawText(defaultX + 110,yPosition,tr("M") + tr(itemUnities[aaa]));
}
else if (temp < 1000000000.0f)
{
temp *= 0.000001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',1));
painter.drawText(defaultX + 110,yPosition,tr("M") + tr(itemUnities[aaa]));
}
Since you have very specific wishes for the conversion, a built in method does not provide all the functionality, but with some tricks, you can use QString::number() and QString::truncate():
QString doubleToQStr(const double val, const size_t d)
{
QString str = QString::number(val,'g',15);
if( val >= std::pow(10.0,static_cast<double>(d-1)) )
{
str.truncate(d);
// find magnitude
size_t mag = 0;
while( val >= std::pow( 10.0, static_cast<double>(mag) ) ) { mag++; }
if ( mag > 3 )
{
size_t dotpos = mag % 3;
str.insert(dotpos,".");
size_t mag3 = mag - dotpos;
switch( mag3 )
{
case 3:
str += " k"; break;
case 6:
str += " M"; break;
case 9:
str += " G"; break;
case 12:
str += " T"; break;
default:
str += " ?"; break;
}
}
}
else if ( val < std::pow(10.0,static_cast<double>(-(static_cast<int>(d)-1))) )
{ str = "0.0"; }
else
{ str.truncate(d+1); }
return str;
}
Here are the test cases I used:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
std::cout << "99919999.9 -> " << doubleToQStr(99919999.9, 4).toStdString() << std::endl;
std::cout << "9999.9 -> " << doubleToQStr(9999.9, 4).toStdString() << std::endl;
std::cout << "999.9 -> " << doubleToQStr(999.9, 4).toStdString() << std::endl;
std::cout << "99.9 -> " << doubleToQStr(99.9, 4).toStdString() << std::endl;
std::cout << "9.9 -> " << doubleToQStr(9.9, 4).toStdString() << std::endl;
std::cout << "0.9 -> " << doubleToQStr(0.9, 4).toStdString() << std::endl;
std::cout << "0.09 -> " << doubleToQStr(0.09, 4).toStdString() << std::endl;
std::cout << "0.009 -> " << doubleToQStr(0.009, 4).toStdString() << std::endl;
std::cout << "0.0009 -> " << doubleToQStr(0.0009, 4).toStdString() << std::endl;
std::cout << "0.00009 -> " << doubleToQStr(0.00009, 4).toStdString() << std::endl;
return a.exec();
}
I have a vector of TrainingSets(struct below) called data
class TrainingSet
{
public:
int time;
float input[2];
float output[3*NUM_TRACKING_POINTS];
TrainingSet(int t, float in[2], float out[3*NUM_TRACKING_POINTS])
{
time = t;
for (int i = 0; i < 2; i++)
input[i] = in[i];
for (int i = 0; i < 3*NUM_TRACKING_POINTS; i++)
output[i] = out[i];
}
TrainingSet()
{
}
};
And then I try to take the contents of this Vector, and put them into CvMats for the purpose of training a Neural Network.
int datasize = data.size();
float** in = new float*[datasize];
float** out = new float*[datasize];
for (int i = 0; i < datasize; i++) {
in[i] = new float[2*TIME_STEPS];
out[i] = new float[3*NUM_TRACKING_POINTS];
}
for ( int i = 0 ; i < datasize; i ++)
{
// get the first set in the sequence.
TrainingSet tset = data.front();
data.pop();
// get the inputs
in[i] = new float[2*TIME_STEPS];
in[i][0] = tset.input[0];
in[i][1] = tset.input[1];
// get the outputs
out[i] = new float[3*NUM_TRACKING_POINTS];
for (int j = 0; j < 3*NUM_TRACKING_POINTS; j++)
out[i][j] = tset.output[j];
for (int j = 2; j < 2*TIME_STEPS; j++)
{
if (i == 0)
in[i][j] = 0.0f;
else
in[i][j] = in[i - 1][j - 2];
}
}
// make matrices from data.
CvMat *trainInput = cvCreateMat(datasize, 2*TIME_STEPS, CV_32FC1);
cvInitMatHeader(trainInput, datasize, 2*TIME_STEPS, CV_32FC1, in);
CvMat *trainOutput = cvCreateMat(datasize, 3*NUM_TRACKING_POINTS, CV_32FC1);
cvInitMatHeader(trainOutput, datasize, 3*NUM_TRACKING_POINTS, CV_32FC1, out);
for (int x = 0; x < datasize; x++)
{
cout << "IN: ";
for (int y = 0; y < 2*TIME_STEPS; y++)
cout << cvmGet(trainInput, x, y) << " ";
cout << endl << "IN: ";
for (int y = 0; y < 2*TIME_STEPS; y++)
cout << in[x][y] << " ";
cout << endl << "OUT: ";
for (int y = 0; y < 3 * NUM_TRACKING_POINTS; y++)
cout << cvmGet(trainOutput, x, y) << " ";
cout << endl << "OUT: ";
for (int y = 0; y < 3 * NUM_TRACKING_POINTS; y++)
cout << out[x][y] << " ";
cout << endl << endl;
}
That last forloop is to check to see if the matrices contents are the data I just fed it, but they don't match. The Matrices seem to have completely different data.
Any thoughts on what is going wrong?
Seems to me that in and out are not a contiguous array, but an array of pointers.
I think the cvMat needs a contiguous memory array to be able to operate on it.
Also once you create the array, you don't need to create a CvMat from it, just
use the
CvSetData( header, data ).