So, I am creating a GUI in which you are able to calculate either the molar mass, mass or moles and I cannot seem to get a calculation back when I call my methods. I am using parallel arrays and I am thinking that may be the problem. Btw, molarMass was declared globally but I didn't know how to format it on here. Thanks.
private void btnGoActionPerformed(java.awt.event.ActionEvent evt) {
int indexOfElements = cmbElements.getSelectedIndex();
Double numberOfMass = Double.parseDouble(txtInputMass.getText());
Double numberOfMoles = Double.parseDouble(txtInputMoles.getText());
if (chkMoles.isSelected()==true)
{
txtAnswer.setText(solveForMoles(numberOfMass).toString() + " mol");
}
else if (chkMolarMass.isSelected()==true)
{
txtAnswer.setText(solveForMolarMass(numberOfMass, numberOfMoles).toString() + "
g/mol");
}
else if (chkMass.isSelected()==true)
{
txtAnswer.setText(solveForMass(numberOfMoles).toString() + " g");
}
else
{
txtAnswer.setText ("Please make a selection");
}
private Double solveForMoles (double mass){
int indexOfElements = cmbElements.getSelectedIndex();
double numberOfMoles = mass/molarMass[indexOfElements];
return (Double.parseDouble (x.format(numberOfMoles)));
}
private Double solveForMass (double moles){
int indexOfElements = cmbElements.getSelectedIndex();
double numberOfMass = moles*molarMass[indexOfElements];
return (Double.parseDouble (x.format(numberOfMass)));
}
private Double solveForMolarMass (double masss, double moless){
double numberOfMolarMass = masss/moless;
return (Double.parseDouble(x.format (numberOfMolarMass)));
}
I'd recommend that you make some changes:
Encapsulate all those calculations into a sensible Java object rather than parallel arrays. Java's an object-oriented language.
Move all the calculations outside of the UI. Write that calculation object, JUnit test it thoroughly, then introduce it into the UI. Computer science, and all problem solving, is best done using divide and conquer.
Related
I am trying to pass a struct of 2D arrays and to do calculations on them.
typedef struct{
float X[80][2];
float Y[80][2];
float Z[80][2];
int T[80][2];
int K[80];
} STATS;
void MovingAverage(STATS *stat_array, int last_stat) {
//Average = Average(Prev) + (ValueToAverage/n) - (Average(Prev)/n)
stat_array->**X**[last_stat][0] = stat_array->**X**[last_stat][0] +
(stat_array->**X**[last_stat][1] / stat_array->T[last_stat][0]) -
(stat_array->**X**[last_stat][0] / stat_array->T[last_stat][0]);
}
calling the function:
MovingAverage(*stat_array, last_stat);
My question is:
how do I access in a generic way to X Y and Z inside MovingAverage function?
Edit:
void MovingAverage(STATS *stat_array, int last_stat, (char *(array_idx)) {
//Average = Average(Prev) + (ValueToAverage/n) - (Average(Prev)/n)
stat_array->**array_idx**[last_stat][0] =
stat_array->**array_idx**[last_stat][0] +
(stat_array->**array_idx**[last_stat][1] /
stat_array->T[last_stat][0]) -
(stat_array->**array_idx**[last_stat][0] /
stat_array->T[last_stat][0]);
}
I know it won't work, but just to demonstrate my willings,
Somebody here (not me) could probably come up with some preprocessor magic to do what you're asking, but that is a solution I would not pursue. I consider it bad practice since macros can quickly get hairy and tough to debug. You can't have "variables" inside your source code, if that makes sense. During the build procedure, one of the first things that runs is the preprocessor, which resolves all your macros. It then passes that source code to the compiler. The compiler is not going to do any text substitutions for you, it cranks on the source code it has. To achieve what you want, write a function that operates on the type you want, and call that function with all your types. I'd change your MovingAverage function to something like this:
void MovingAverage(float arr[80][2], const int T[80][2], int last_stat)
{
arr[last_stat][0] = ... // whatever calculation you want to do here
}
int main(void)
{
STATS stat_array;
int last_stat;
// .. initialize stat_array and last_stat
// now call MovingAverage with each of your 3 arrays
MovingAverage(stat_array.X, stat_array.T, last_stat);
MovingAverage(stat_array.Y, stat_array.T, last_stat);
MovingAverage(stat_array.Z, stat_array.T, last_stat);
...
return 0;
}
I am a new to C++. and writing a CLI wrapper to consume managed code (DLL)
public:array<double, 3>^ CallingBrownianManagedCode(int numPaths, int dimension, double time, int seed, array<double, 2>^ covMatrix, double stepSize, int scrambling)
{
std::string str = "Sobol";
String^ newSystemString = gcnew String(str.c_str());
Object^ result;
result = IDevModel::RandomNumberGenerator::iBrownianBridge(numPaths, dimension, time, seed, covMatrix, stepSize, newSystemString, scrambling);
array<double, 3>^ devArray = (array<double, 3>^) result;
return devArray;
}
I've tested the above code using CLI console app it works as desired. Now I need to expose this method to
UnManged C++
__declspec(dllexport) void CallBrownianManagedAdapter()
{
BrownianWrapper::BrownianBridgeAdapter objectBrownian;
array<double, 3>^ brownianArray = objectBrownian.CallingBrownianManagedCodeTemp();
return brownianArray;
}
instead of void it has to be a 3d array. I tried returning manged array^, but it throws an error.
Can you please help me? I appreciate it.
Given a C file, I want to compute the backward slice for some criteria and compare the slice to the original code. Because I don't want to implement a slicing program from cratch, I've already tried to get used to Frama-C which seems to help with this task.
However, my problem is, that Frama-C's slicing plugin changes the preprocessed input code, so that it makes it harder to identify which lines of the original also appear in the slice.
Example:
Input file test1.c:
double func1(double param) {
return 2+param;
}
int main() {
int a=3;
double c=4.0;
double d=10.0;
if(a<c)
c=(double)a/4.0;
double res = func1(c);
return 0;
}
Preprocessed file (yielded by frama-c test1.c -print -ocode test1_norm.c):
/* Generated by Frama-C */
double func1(double param)
{
double __retres;
__retres = (double)2 + param;
return __retres;
}
int main(void)
{
int __retres;
int a;
double c;
double d;
double res;
a = 3;
c = 4.0;
d = 10.0;
if ((double)a < c) c = (double)a / 4.0;
res = func1(c);
__retres = 0;
return __retres;
}
Slice (yielded by frama-c -slice-calls func1 test1.c -then-on 'Slicing export' -print):
/* Generated by Frama-C */
double func1_slice_1(double param)
{
double __retres;
__retres = (double)2 + param;
return __retres;
}
void main(void)
{
int a;
double c;
double res;
a = 3;
c = 4.0;
c = (double)a / 4.0;
res = func1_slice_1(c);
return;
}
Note that the signature of main differs and that the name of func1 was changed to func1_slice_1.
Is there a way to suppress that behaviour in order to make the slice and the (preprocessed) original more easily comparable (in terms of a computable diff)?
First, to clarify a simpler question that you don't need answering but that someone searching for the same keywords could, you cannot have the sliced program printed as a selection of the lines of the original program (most of the differences between the two corresponds to lost information, basically. If the information was there, it would be used to print the most resembling program possible).
What you can do is print Frama-C's representation of the original program, which you are already doing with frama-c test2.c -print -ocode test2_norm.c.
To solve your problem of func1 being renamed to func1_slice_1, you can try playing with option -slicing-level 0:
$ frama-c -slicing-level 0 -slice-calls func1 test1.c -then-on 'Slicing export' -print
...
/* Generated by Frama-C */
double func1(double param)
{
double __retres;
__retres = (double)2 + param;
return __retres;
}
void main(void)
{
int a;
double c;
double res;
a = 3;
c = 4.0;
c = (double)a / 4.0;
res = func1(c);
return;
}
I think this will prevent the slicer from slicing inside func1 at all. The help says:
-slicing-level <n> set the default level of slicing used to propagate to the
calls
0 : don't slice the called functions
1 : don't slice the called functions but propagate the
marks anyway
2 : try to use existing slices, create at most one
3 : most precise slices
I'm new programing in C. I have a main code with 781 lines that is out of control because garbage value is stored in vectors. A short part of the main code is shown below where it calls a subroutine called diff_conv_intermedia1.
diff_conv_intermedia1(&factorteta,&N,ID,DIFF,X1_intermedia,Y1_intermedia,X1C_intermedia,Y1C_intermedia,CU1_intermedia,CV1_intermedia,AW1_intermedia,AE1_intermedia,AS1_intermedia,AN1_intermedia,AP1_intermedia,Q1_intermedia,FXI1,FYI1,FI_intermedia1,1,2,1,1);
int q,w;
for(q=1;q<(*factorteta_Ptr)*2+1;q++)
{
for(w=1;w<(*N_Ptr)+1;w++)
{
printf("%lf\n",AP1_intermedia[q][w]);
}
}
So the subroutine shown below. When I print the results inside the subroutine, everything is OK, but when I print the results outside the subroutine, in the main code, garbage is stored in the vectors as AP1_intermedia. I don't know what could be wrong. I repeat the same procedure with other subroutines and I don't have any errors.
int diff_conv_intermedia1(int *factorteta_Ptr,
int *N_Ptr,
int ID,
double DIFF,
double X[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double Y[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double XC[(*factorteta_Ptr)*2+2][*N_Ptr+2],
double YC[(*factorteta_Ptr)*2+2][*N_Ptr+2],
double CU[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double CV[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AW[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AE[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AS[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AN[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AP[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double Q[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double FX[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double FY[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double FI[(*factorteta_Ptr)*2+1][*N_Ptr+1],
int WBC,int EBC,int SBC,int NBC)
{
int i,j;
double value,* valuePtr;
double AED, AWD, AND, ASD;
double AEC, AWC, ANC, ASC;
valuePtr = &value;
// Diffusive coefficients
for(i=1;i<(*factorteta_Ptr)*2+1;i++)
{
for(j=1;j<*N_Ptr+1;j++)
{
AWD = -DIFF*(Y[i][j-1]-Y[i-1][j-1])/(XC[i][j]-XC[i][j-1]);
AED = -DIFF*(Y[i][j]-Y[i-1][j])/(XC[i][j+1]-XC[i][j]);
AND = -DIFF*(X[i][j]-X[i][j-1])/(YC[i+1][j]-YC[i][j]);
ASD = -DIFF*(X[i-1][j]-X[i-1][j-1])/(YC[i][j]-YC[i-1][j]);
// Convection term
if(ID==2)
{
max1_or_min2(CU[i][j-1],1,&value);
AWC=-*valuePtr;
max1_or_min2(CU[i][j],2,&value);
AEC=*valuePtr;
max1_or_min2(CV[i-1][j],1,&value);
ASC=-*valuePtr;
max1_or_min2(CV[i][j],2,&value);
ANC=*valuePtr;
}
if(ID==1)
{
AWC =-CU[i][j-1]*(1.0-FX[i][j-1]);
AEC =CU[i][j]*FX[i][j];
ASC =-CV[i-1][j]*(1.0-FY[i-1][j]);
ANC =CV[i][j]*FY[i][j];
}
// Set Coefficients matrix
AW[i][j] = AWD+AWC;
AE[i][j] = AED+AEC;
AS[i][j] = ASD+ASC;
AN[i][j] = AND+ANC;
AP[i][j] = -(AE[i][j]+AW[i][j]+AN[i][j]+AS[i][j]);
Q[i][j] = 0.0;
}
}
// West Boundary - Inlet B.C
for(i=1;i<(*factorteta_Ptr)*2+1;i++)
{
if(WBC==1) Q[i][1] = Q[i][1]-AW[i][1]*FI[i][0];
if(WBC==2) AP[i][1] = AP[i][1] + AW[i][1];
AW[i][1] = 0.0;
// East Boundary - (1)Dirichlet (2)ZERP-GRAD Outflow B.C
if(EBC==1) Q[i][*N_Ptr] = Q[i][*N_Ptr] - AE[i][*N_Ptr]*FI[i][*N_Ptr+1];
if(EBC==2) AP[i][*N_Ptr] = AP[i][*N_Ptr] + AE[i][*N_Ptr];
AE[i][*N_Ptr] = 0.0;
}
// South Boundary - (1)Dirichlet (2)ZERO-GRAD
for(j=1;j<*N_Ptr+1;j++)
{
if(SBC==1) Q[1][j] = Q[1][j] - AS[1][j]*FI[0][j];
if(SBC==2) AP[1][j] = AP[1][j] + AS[1][j];
AS[1][j] = 0.0;
// North Boundary - (1)Dirichlet (2)ZERO-GRAD
if(NBC==1) Q[(*factorteta_Ptr)*2][j] = Q[(*factorteta_Ptr)*2][j] - AN[(*factorteta_Ptr)*2][j]*FI[(*factorteta_Ptr)*2+1][j];
if(NBC==2) AP[(*factorteta_Ptr)*2][j] = AP[(*factorteta_Ptr)*2][j] + AN[(*factorteta_Ptr)*2][j];
AN[(*factorteta_Ptr)*2][j] = 0.0;
}
// Print
int l,k;
for(l=1;l<(*factorteta_Ptr)*2+1;l++)
{
for(k=1;k<*N_Ptr+1;k++)
{
printf("%lf %lf %lf %lf\n",AP[l][k],AS[l][k],AN[l][k],FI[l][k]);
}
}
return 0;
}
If anybody wants I can send all code, but have many extensions.
In your function declaration:
double AP[(*factorteta_Ptr)*2+1][*N_Ptr+1]
I don't quite think this is doing what you think it is doing. While I haven't seen something like this myself before, I believe that this is telling the compiler to create a variable length 2D array for you based on the other given parameters. Then, you fill in these values in your function. But, because you don't return this value nor do you declare it as pass by reference, it is thrown away when you return, thus the work is lost and you have garbage in your array in main(). Better form would be to create this array in main(), then pass it in by reference something like double *AP[][], or return this array upon exit, or hack things up even worse than this function and just make it a global so that you can see it anywhere.
I have tested my code for some real functions using a forward FFT and IFFT (normalized the result), this works fine.
I would, however, like to take a second derivative of a real function. For simplicity sake, I take sin(2*pi*t) as a test case. Here is the relevant code I use (FFT functions in a library):
int main(void)
{
int i;
int nyh = (N/2) + 1;
double result_array[nyh][2];
double x_k[nyh][2];
double x_r[N];
FILE* psit;
psit=fopen("psitest.txt","w");
init();
fft(x, result_array); //function in a library, this has been tested
psi(result_array, x_k);
ifft(x_k, x_r); //function in a library, this has been tested
for(i=0;i<N;i++)
{
fprintf(psit, "%f\n", x_r[i]);
}
fclose(psit);
return 0;
}
void psi(double array[nyh][2], double out[nyh][2])
{
int i;
for ( i = 0; i < N/2; i++ )
{
out[i][0] = -4.0*pi*pi*i*i*array[i][0];
out[i][1] = -4.0*pi*pi*i*i*array[i][1];
}
out[N/2][0]=0.0;
out[N/2][1]=0.0;
}
void init()
{
int i;
for(i=0;i<N;i++)
{
x[i] = sin(2.0*pi*i/N);
}
}
Now here is the problem: This algorithm works perfectly for any function of the form sin( 2*pi*t*K), where K is an integer, but if I take as a test function sin(3*pi*t), the algorithm fails. I am not able to see the mistake in my coding.
Please note that because the function is real, I only need to take half of the k values. This is not the problem.
My guess is that sin(3*pi*t) introduces a discontinuity, since it does not give an integer number of cycles in your sample interval. For most FFT-related applications you would apply a window function to deal with such discontinuities, but obviously this will introduce an error term into your derivative and I'm not sure whether you will be able to correct for this.
I don't know if you have fixed this problem... But I guess the major problem is that sin(3 Pi t) is not periodic in the domain [0,1](sin(0) != sin (3 * Pi)).
FFT could not work properly...