Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to work with a C library, and I had to create the following bit of code:
void *foo = malloc(sizeof(MAGtype_MagneticModel *));
MAGtype_MagneticModel* *MagneticModels = (MAGtype_MagneticModel **)foo;
this is then passed to one of the C library functions as follows:
if(!MAG_robustReadMagModels(filename, (MAGtype_MagneticModel* (*)[]) &MagneticModels, epochs)) {
//ERROR
}
When it passes the above function, I then am wanting to get the value from one of the components of this function.
int var = 0;
if (var < (&MagneticModels[0]->nMax)) var = (&MagneticModels[0]->nMax);
This gives the compiler error:
C2446: '<' : no conversion from 'int *' to 'int'
How would I go about getting the value of MagneticModels[0]->nMax instead of just pointers?
Edit: Here is the struct for MAGtype_MagneticModel:
typedef struct {
double EditionDate;
double epoch; /*Base time of Geomagnetic model epoch (yrs)*/
char ModelName[32];
double *Main_Field_Coeff_G; /* C - Gauss coefficients of main geomagnetic model (nT) Index is (n * (n + 1) / 2 + m) */
double *Main_Field_Coeff_H; /* C - Gauss coefficients of main geomagnetic model (nT) */
double *Secular_Var_Coeff_G; /* CD - Gauss coefficients of secular geomagnetic model (nT/yr) */
double *Secular_Var_Coeff_H; /* CD - Gauss coefficients of secular geomagnetic model (nT/yr) */
int nMax; /* Maximum degree of spherical harmonic model */
int nMaxSecVar; /* Maximum degree of spherical harmonic secular model */
int SecularVariationUsed; /* Whether or not the magnetic secular variation vector will be needed by program*/
double CoefficientFileEndDate;
} MAGtype_MagneticModel;
And for reference, I am working with the library found under WMM2015_Windows.zip that is found here
One thing that may help is to to create an int variable for what you want.
This will allow you to check the variable at compile time
example
int myInt = MagneticModels[0]->nMax
should work
Here is where you need more information on the structure of
MAGtype_MagneticModel
For example, is nMax defined as an integer, or an int *
if the latter, you may need the correct address
&(MagneticModels[0]->nMax)
However, in general, using the array notation [0] 'dereferences the pointer'
Hope this helps
just dont take the address of it
if (var < MagneticModels[0]->nMax)....
Related
I am using Coin-Or's rehearse to implement linear programming.
I need a modulo constraint. Example: x shall be a multiple of 3.
OsiCbcSolverInterface solver;
CelModel model(solver);
CelNumVar x;
CelIntVar z;
unsigned int mod = 3;
// Maximize
solver.setObjSense(-1.0);
model.setObjective(x);
model.addConstraint(x <= 7.5);
// The modulo constraint:
model.addConstraint(x == z * mod);
The result for x should be 6. However, z is set to 2.5, which should not be possible as I declared it as a CellIntVar.
How can I enforce z to be an integer?
I never used that lib, but you i think you should follow the tests.
The core message comes from the readme:
If you want some of your variables to be integers, use CelIntVar instead of CelNumVar. You must bind the solver to an Integer Linear Programming solver as well, for example Coin-cbc.
Looking at Rehearse/tests/testRehearse.cpp -> exemple4() (here presented: incomplete code; no copy-paste):
OsiClpSolverInterface *solver = new OsiClpSolverInterface();
CelModel model(*solver);
...
CelIntVar x1("x1");
...
solver->initialSolve(); // this is the relaxation (and maybe presolving)!
...
CbcModel cbcModel(*solver); // MIP-solver
cbcModel.branchAndBound(); // Use MIP-solver
printf("Solution for x1 : %g\n", model.getSolutionValue(x1, *cbcModel.solver()));
printf("Solution objvalue = : %g\n", cbcModel.solver()->getObjValue());
This kind of usage (use Osi to get LP-solver; build MIP-solver on top of that Osi-provided-LP-solver and call brandAndBound) basically follows Cbc's internal interface (with python's cylp this looks similar).
Just as reference: This is the official CoinOR Cbc (Rehearse-free) example from here:
// Copyright (C) 2005, International Business Machines
// Corporation and others. All Rights Reserved.
#include "CbcModel.hpp"
// Using CLP as the solver
#include "OsiClpSolverInterface.hpp"
int main (int argc, const char *argv[])
{
OsiClpSolverInterface solver1;
// Read in example model in MPS file format
// and assert that it is a clean model
int numMpsReadErrors = solver1.readMps("../../Mps/Sample/p0033.mps","");
assert(numMpsReadErrors==0);
// Pass the solver with the problem to be solved to CbcModel
CbcModel model(solver1);
// Do complete search
model.branchAndBound();
/* Print the solution. CbcModel clones the solver so we
need to get current copy from the CbcModel */
int numberColumns = model.solver()->getNumCols();
const double * solution = model.bestSolution();
for (int iColumn=0;iColumn<numberColumns;iColumn++) {
double value=solution[iColumn];
if (fabs(value)>1.0e-7&&model.solver()->isInteger(iColumn))
printf("%d has value %g\n",iColumn,value);
}
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Update:
As Pete Kirkham correctly pointed out println shortens the digits to two places. I updated my code with just plain old print and it still cuts those two off only. You have to put Serial.print(some_number, 7) if you want it to have 7 decimal places.
Thanks Pete
Original Post
I am pretty new to C++ and am writing an arduino GPS app and noticing one value keeps getting shortened to two decimal places while the other value in the struct does not.
Here is the struct declaration
struct Poi {
char name[30];
double lat;
double lng;
};
Here is the actual struct instance:
Poi poi_list[3] = {
{"AK Plaza W",36.9905263,127.0847449}
,
{"AK Plaza East",36.9905263,127.0861048}
,
{"Ramen Place",36.9905263,127.0895004}
}
Now when I try to see poi_list[0].lat or [1].lat or [2].lat all the values are 36.99 and it cuts off the rest, where the .lng value is always the entire number.
The entire file is on github here
#include "TinyGPS++.h"
#include "SoftwareSerial.h"
SoftwareSerial serial_connection(10, 11); //RX=pin 10, TX=pin 11
TinyGPSPlus gps;//This is the GPS object that will pretty much do all the grunt work with the NMEA data
TinyGPSLocation loc;
const double EIFFEL_TOWER_LAT = 36.96070;
const double EIFFEL_TOWER_LNG = 127.05692;
struct Poi {
char name[30];
double lat;
double lng;
};
Poi poi_list[13] = {
{"AK Plaza W",36.9905263,127.0847449}
,
{"AK Plaza East",36.9905263,127.0861048}
,
{"Ramen Place",36.9905263,127.0895004}
,
{"BX Center",36.9905263,127.0339894}
,
{"BX West",36.9905263,127.0350462}
,
{"Osan Chilis",36.9905263,127.0365375}
,
{"Work Main Gate",36.9905263,127.0219141}
,
{"Commissary",36.9905263,127.0024359}
,
{"PX Food Court",36.9905263,127.0002204}
,
{"PX Main entrance",36.9905263,126.9993058}
,
{"One Stop",36.9905263,127.0221126}
,
{"AMC",36.9905263,127.0425832}
,
{"Braii Republic",36.9905263,127.0446378}
};
int number_of_points = 13;
void setup()
{
Serial.begin(9600);//This opens up communications to the Serial monitor in the Arduino IDE
serial_connection.begin(9600);//This opens up communications to the GPS
Serial.println("GPS Start");//Just show to the monitor that the sketch has started
}
void loop()
{
while(serial_connection.available())//While there are characters to come from the GPS
{
gps.encode(serial_connection.read());//This feeds the serial NMEA data into the library one char at a time
}
if(gps.location.isUpdated())
{
for(int i=0;i<number_of_points;i++){
Serial.print("Name: ");
Serial.println(poi_list[i].name);
Serial.print("Distance: ");
Serial.print(calculate_distance(poi_list[i]));
}
}
}
float calculate_distance(Poi point){
float distance = gps.distanceBetween(
gps.location.lat(),
gps.location.lng(),
point.lat,
point.lng);
Serial.print("lat is ");
Serial.print(point.lat);
Serial.println("");
Serial.print("longitutde is ");
Serial.print(point.lng);
return distance;
}
According to the Arduino documentation, the output function Serial.println() will round floats to two digits after the coma:
Serial.print(1.23456) gives "1.23"
If you want more detailed presentation, you have to specify the number of digits you want as second argument:
Serial.println(1.23456, 4) gives "1.2346"
As Arduino's float have only 6-7 digits of precision, you could go for
Serial.println(point.lat, 5);
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
In my project, I am responsible for migrating some MATLAB code to C++. The code below refers to serial communication from a computer to a microcontroller. The function CreatePackage generates a package which is then sent to the microcontroller using MATLAB's fwrite(serial) function.
function package = CreatePackage(V)
for ii = 1:size(V,2)
if V(ii) > 100
V(ii) = 100;
elseif V(ii) < -100
V(ii) = -100;
end
end
vel = zeros(1, 6);
for ii = 1:size(V,2)
if V(ii) > 0
vel(ii) = uint8(V(ii));
else
vel(ii) = uint8(128 + abs(V(ii)));
end
end
package = ['BD' 16+[6, vel(1:6)], 'P' 10 13]+0;
And then, to send the package:
function SendPackage(S, Package)
for ii = 1:length(S)
fwrite(S(ii), Package);
end
How can I create an array/vector in C++ to represent the package variable used in the MATLAB code above?
I have no experience with MATLAB so any help would be greatly apreciated.
Thank you!
The package variable is being streamed as 12, unsigned 8-bit integers in your MATLAB code, so I would use a char[12] array in C++. You can double check sizeof(char) on your platform to ensure that char is only 1 byte.
Yes, MATLAB default data-type is a double, but that does not mean your vector V isn't filled with integer values. You have to look at this data or the specs from your equipment to figure this out.
Whatever the values are coming in, you are setting/clipping the outgoing range to [-100, 100] and then offsetting them to the byte range [0, 255].
If you do not know a whole lot about MATLAB, you may be able to leverage what you know from C++ and use C as an interim. MATLAB's fwrite functionality lines up with that of C's, and you can include these functions in C++ with the #include<cstdio.h> preprocessor directive.
Here is an example solution:
#include <cstdio.h> // fwrite
#include <algorithm> // min, max
...
void makeAndSendPackage(int * a6x1array, FILE * fHandles, int numHandles){
char packageBuffer[13] = {'B','D',24,0,0,0,0,0,0,'P','\n','\r',0};
for(int i=0;i<6;i++){
int tmp = a6x1array[i];
packageBuffer[i+3] = tmp<0: abs(max(-100,tmp))+144 ? min(100,tmp)+16;
}
for(int i=0;i<6;i++){
fwrite(fHandles[i],"%s",packageBuffer);
}
}
Let me know if you have questions about the above code.
I am looking for a function which calculate a Butterworth Nth filter design coefficients like a Matlab function:
[bl,al]=butter(but_order,Ws);
and
[bh,ah]=butter(but_order,2*bandwidth(1)/fs,'high');
I found many examples of calculating 2nd order but not Nth order (for example I work with order 18 ...). - unfortunately I haven't any knowledge about DSP.
Do you know any library or a way to easily implement this method? When I know just order, cut off frequency and sample rate. I just need to get a vectors of B (numerator) and A (denominator).
There is also a requirement that the method works under different platforms - Windows, Linux, ...
It can be easily found (in Debian or Ubuntu):
$ aptitude search ~dbutterworth | grep lib
Which gives you answer immediately:
p librtfilter-dev - realtime digital filtering library (dev)
p librtfilter1 - realtime digital filtering library
p librtfilter1-dbg - realtime digital filtering library (dbg)
So you need library called rtfilter. Description:
rtfilter is a library that provides a set of routines implementing realtime digital filter for multichannel signals (i.e. filtering multiple signals with the same filter parameters). It implements FIR, IIR filters and downsampler for float and double data type (both for real and complex valued signal). Additional functions are also provided to design few usual filters: Butterworth, Chebyshev, windowed sinc, analytical filter...
This library is cross-platform, i.e. works under Linux, MacOS and Windows. From
official site:
rtfilter should compile and run on any POSIX platform (GNU/Linux, MacOSX, BSD...) and Windows platforms.
You can install it like this:
$ sudo aptitude install librtfilter-dev librtfilter1
After -dev package is installed, you can even find an example (with Butterworth filter usage) at /usr/share/doc/librtfilter1/examples/butterworth.c. This example (along with corresponding Makefile) also can be found here.
Particularly you are interested in rtf_create_butterworth() function. You can access documentation for this function via command:
$ man rtf_create_butterworth
or you can read it here.
You can specify any filter order passing it as num_pole param to rtf_create_butterworth() function (as far as I remember the number of poles it's the same thing as filter order).
UPDATE
This library doesn't provide external API for coefficients calculation. It only provides actual filtering capabilities, so you can use rtf_filter() to obtain samples (data) after filtering.
But, you can find the code for coefficients calculation in library sources. See compute_cheby_iir() function. This function is static, so it's only can be used inside the library itself. But, you can copy this function code as is to your project and use it. Also, don't let the name of this function confuse you: it is the same algorithm for Butterworth filter and Chebyshev filter coefficients calculation.
Let's say, you have prepared parameters for rtf_create_butterworth() function:
const double cutoff = 8.0; /* cutoff frequency, in Hz */
const double fs = 512.0; /* sampling rate, in Hz */
unsigned int nchann = 1; /* channels number */
int proctype = RTF_FLOAT; /* samples have float type */
double fc = cutoff / fs; /* normalized cut-off frequency, Hz */
unsigned int num_pole = 2; /* filter order */
int highpass = 0; /* lowpass filter */
Now you want to calculate numerator and denominator for your filter. I have written the wrapper for you:
struct coeff {
double *num;
double *den;
};
/* TODO: Insert compute_cheby_iir() function here, from library:
* https://github.com/nbourdau/rtfilter/blob/master/src/common-filters.c#L250
*/
/* Calculate coefficients for Butterworth filter.
* coeff: contains calculated coefficients
* Returns 0 on success or negative value on failure.
*/
static int calc_coeff(unsigned int nchann, int proctype, double fc,
unsigned int num_pole, int highpass,
struct coeff *coeff)
{
double *num = NULL, *den = NULL;
double ripple = 0.0;
int res = 0;
if (num_pole % 2 != 0)
return -1;
num = calloc(num_pole+1, sizeof(*num));
if (num == NULL)
return -2;
den = calloc(num_pole+1, sizeof(*den));
if (den == NULL) {
res = -3;
goto err1;
}
/* Prepare the z-transform of the filter */
if (!compute_cheby_iir(num, den, num_pole, highpass, ripple, fc)) {
res = -4;
goto err2;
}
coeff->num = num;
coeff->den = den;
return 0;
err2:
free(den);
err1:
free(num);
return res;
}
You can use this wrapper like this:
int main(void)
{
struct coeff coeff;
int res;
int i;
/* Calculate coefficients */
res = calc_coeff(nchann, proctype, fc, num_pole, highpass, &coeff);
if (res != 0) {
fprintf(stderr, "Error: unable to calculate coefficients: %d\n", res);
return EXIT_FAILURE;
}
/* TODO: Work with calculated coefficients here (coeff.num, coeff.den) */
for (i = 0; i < num_pole+1; ++i)
printf("num[%d] = %f\n", i, coeff.num[i]);
for (i = 0; i < num_pole+1; ++i)
printf("den[%d] = %f\n", i, coeff.den[i]);
/* Don't forget to free memory allocated in calc_coeff() */
free(coeff.num);
free(coeff.den);
return EXIT_SUCCESS;
}
If you are interested in math background for those coefficients calculation, look at DSP Guide, chapter 33.
This question already has an answer here:
OpenMP program is slower than sequential one
(1 answer)
Closed 8 years ago.
I have this code that I parallelized using OpenMP that seems to run slower than the serial version. Here's the relevant fragment of the code:
Out_props ion_out;
#pragma omp parallel for firstprivate(Egx,Egy,vi_inlet,dt,xmin,xmax,ymin,ymax,qmi,dy,Nx) private(ion_out)
for (int i=0;i<Np;i++)
{
ion_out = ApplyReflectionBC(dt,Nx,xmin,xmax,ymin,ymax,qmi,dy,vi_inlet,Egx,Egy,xi_i[2*i],xi_i[1+2*i],vi_i[2*i],vi_i[1+2*i]);
xi_o[1-1+2*i]=ion_out.xout;
xi_o[2-1+2*i]=ion_out.yout;
vi_o[1-1+2*i]=ion_out.vxout;
vi_o[2-1+2*i]=ion_out.vyout;
}
Here outprops is just a structure with 4 members of the double type. The ApplyReflectionBC functions (given below) just applies some operations for each i. All these operations are completely independent of each other. Egx and Egy are 60x60 matrices defined prior to entering this loop and vi_inlet is 2x1 vector. I've tried making ion_out a matrix of size Np to further increase independence, but that seems to make no difference. Everything else inside firstprivate is a double type defined prior to entering this loop.
I'd really appreciate any insights into why this might be running many times slower than the serial version. Thank you!
Out_props ApplyReflectionBC(double dt,int Nx,double xmin,double xmax,double ymin, double ymax,double qmp, double dy, double *vp_inlet,double *Egx,double *Egy, double xpx,double xpy,double vpx,double vpy)
{
Out_props part_out;
double Lgy=ymax-ymin;
double xp_inp[2]={xpx,xpy};
double vp_inp[2]={vpx,vpy};
double xp_out[2];
double vp_out[2];
struct vector
{
double x;
double y;
}vnmf,Ep,xnmf;
if((xp_inp[1-1]>xmin) && (xp_inp[1-1]<xmax) && (xp_inp[2-1]<ymin)) //ONLY below lower wall
{
xp_out[1-1]=xp_inp[1-1];
xp_out[2-1]=ymin;
vp_out[1-1]=vp_inp[1-1];
vp_out[2-1]=-vp_inp[2-1];
}
else if((xp_inp[1-1]<xmin) || (xp_inp[1-1]>xmax) || (xp_inp[2-1]>ymax))
{//Simple Boris Push
xnmf.x=xmin;
xnmf.y=ymin+Lgy*rand()/RAND_MAX;
vnmf.x=vp_inlet[0];
vnmf.y=vp_inlet[1];
//Find E field at x,y
double yjp=ymin+dy*floor((xnmf.y-ymin)/(1.0*dy));
double yjp1p=yjp+dy;
int kp=(yjp-ymin)/dy;
int kpp1=kp+1;
double ylg=xnmf.y-yjp;
double wjk=1.0*(dy-ylg)/(1.0*dy);
double wjkp1=1.0*ylg/(1.0*dy);
Ep.x=wjk*Egx[Nx*kp]+wjkp1*Egx[Nx*kpp1];
Ep.y=wjk*Egy[Nx*kp]+wjkp1*Egy[Nx*kpp1];
do
{
double f=1.0*rand()/RAND_MAX;
xp_out[1-1]=xnmf.x+f*dt*(vnmf.x+qmp*Ep.x*f*dt/2.0);
xp_out[2-1]=xnmf.y+f*dt*(vnmf.y+qmp*Ep.y*f*dt/2.0);
vp_out[1-1]=vnmf.x+qmp*Ep.x*(f-0.5)*dt;
vp_out[2-1]=vnmf.y+qmp*Ep.y*(f-0.5)*dt;
} while((xp_out[1-1]<xmin) || (xp_out[1-1]>xmax) || (xp_out[2-1]<ymin) || (xp_out[2-1]>ymax));
}
else
{
xp_out[1-1]=xp_inp[1-1];
xp_out[2-1]=xp_inp[2-1];
vp_out[1-1]=vp_inp[1-1];
vp_out[2-1]=vp_inp[2-1];
}
part_out.xout=xp_out[0];
part_out.yout=xp_out[1];
part_out.vxout=vp_out[0];
part_out.vyout=vp_out[1];
return part_out;
}
Some points:
First, the firstprivate directive creates a copy of the declared variables into each thread's stack, so that takes some time. Since these variables won't be changed (i.e., read-only), you may declare them as shared.
Second, but causing less impact, the ApplyReflectionBC function takes everything by value, so it will create local copies of each argument. Use references (double &dt, for example).
Edit:
As Hristo pointed out, rand() is the source of your problems. You must replace it with some other random number generator function. For both better random numbers and thread-safety, you may use this Mersenne Twister class (if the LGPL 2.1 isn't a problem): http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/MersenneTwister.h . Just declare it private to your threads, like:
MTRand rng;
#pragma omp parallel for private(rng, ...)
for (..)
{
ApplyReflectionBC(..., rng);
}
Out_props ApplyReflectionBC(...,MTRand &rng)
{
// .... Code ....
xnmf.y=ymin+Lgy*rng.rand(); // MTRand::rand will return a number in the range [0; 1]
// ........
}