Possible loss of precision with Gram-Schmidt - c++

I have a code that uses Gram-Schmidt inside a loop. I want to reduce the number of calls to this algorithm as much as possible, but the thing is that despite of getting the same result before and after the call, when I print the results of some operations using these values they are different. For example, on the code below the result of abs(muGS[k][0]) - abs(before2) should be 0 or very close to 0, since the printed values of this variable (before and after the call) are the same. However, this not what happens. muGS is a double matrix and its values are usually between 0 and 1.
int k = 1;
double before2;
while(k < end) {
before2 = muGS[k][0];
gramSchmidt(b, muGS, cGS, k);
//prints for debug
if (abs(muGS[k][0]) - abs(before2) > 0.1) {
if (abs(muGS[k][0]) - abs(before2) > 0.1) {
cout << "1 muGS[k] diff:" << abs(muGS[k][0]) - abs(before2) << endl;
cout << "1 muGS[k] before:" << muGS[k][0] << endl;
cout << "1 muGS[k] after:" << muGS[k][0] << endl;
cout << "1 muGS[k] mult before:" << before2 * before2 << endl;
cout << "1 muGS[k] mult after:" << muGS[k][0] * muGS[k][0] << endl;
cout << "1 muGS[k] abs before:" << abs(before2) << endl;
cout << "1 muGS[k] abs after:" << abs(muGS[k][0]) << endl;
}
getchar();
}
for (i = k-1; i >= 0; i--) {
for (j = 0; j < i; j++) {
muGS[k][j] -= round(muGS[k][i]) * muGS[i][j];
}
}
//some other operations that don't change the value of muGS
k++;
}
Output:
1 muGS[k] diff:0.157396
1 muGS[k] before:0.288172
1 muGS[k] after:0.288172
1 muGS[k] mult before:0.0171023
1 muGS[k] mult after:0.083043
1 muGS[k] abs before:0.130776
1 muGS[k] abs after:0.288172
Another thing that happens is that the absolute value of before2 is very different from the value of before2.
Is it possible that I'm having some precision loss or why is this happening?
Thanks

There is no precision loss. You just have a mistake in your code:
cout << "1 muGS[k] before:" << muGS[k][0] << endl;
cout << "1 muGS[k] after:" << muGS[k][0] << endl;
You print same value for both before and after.
But shoulde be:
cout << "1 muGS[k] before:" << before2 << endl;
cout << "1 muGS[k] after:" << muGS[k][0] << endl;

Related

Basic cash system in C++

In the below code, I've got some bugs and I don't know why it doesn't work.
I used a fmod to do the decimals but I got some bugs in the part where it gives you the 0.10 and 0.05 $ and most of the time I never get the good amount that I'm supposed to give back if there is.
#include<iostream>
#include <cmath>
using namespace std;
int main()
{
int iAmount_due = { 0 };
int iGiven_money = { 0 };
int iMoney_back;
iMoney_back = iGiven_money - iAmount_due;
cout << "Enter the amount due please: " << endl;
cin >> iAmount_due;
cout << "Enter the amount given please: " << endl;
cin >> iGiven_money;
if (iGiven_money >= iAmount_due) {
iMoney_back = iGiven_money - iAmount_due;
cout << "We will give you : " << iMoney_back << " $ back" << endl;
}
else {
cout << "No money back" << endl;
}
if (iMoney_back >= 100) {
cout << "You will receive: " << iMoney_back % 100 << " x 100$" << endl;
}
else {
cout << "No 100$ bill" << endl;
}
if (iMoney_back >= 50) {
cout << "You will receive: " << iMoney_back % 50 << " x 50$" << endl;
}
else {
cout << "No 50$ bill" << endl;
}
if (iMoney_back >= 20) {
cout << "You will receive: " << iMoney_back % 20 << " x 20$" << endl;
}
else {
cout << "No 20$ bill" << endl;
}
if (iMoney_back >= 10) {
cout << "You will receive: " << iMoney_back % 10 << " x 10$" << endl;
}
else {
cout << "No 10$ bill" << endl;
}
if (iMoney_back >= 5) {
cout << "You will receive: " << iMoney_back % 5 << " x 5$" << endl;
}
else {
cout << "No 5$ bill" << endl;
}
if (iMoney_back >= 0.25) {
cout << "You will receive: " << fmod (iMoney_back, 0.25) << " x 0.25$ " << endl;
}
else {
cout << "No 0.25$ " << endl;
}
if (iMoney_back >= 0.10) {
cout << "You will receive: " << fmod (iMoney_back, 0.10) << " x 0.10$ " << endl;
}
else {
cout << "No 0.10$ " << endl;
}
if (iMoney_back >= 0.05) {
cout << "You will receive: " << fmod (iMoney_back, 0.05) << " x 0.05$ " << endl;
}
else {
cout << "No 0.05$ " << endl;
}
return 0;
}
int holds only integer values. 0.05 is not an integer value. You might be tempted to use double values instead that probably work for your simple problem; however, they generally have rounding errors which is something you really do not want to have with currency values.
The better solution will be to still use integers. You would need to define 1 as the smallest possible unit (e.g. 1 cent), meaning that all your values will be in cent. You would need to write extra code to be able to enter and display values as dollars instead of cents.

C++ How To Show Percentage Output Of Dice Simulator Results

newbie here to C++. I am having trouble displaying the correct format + results in percentage form for this dice simulator our professor has asked us to make. I'll copy/paste her instructions here and would appreciate help with how to correct my mistake(s) in regard to the formatting of the percentage output in my program. Thank you!
INSTRUCTIONS:
This program should simulate the roll of a single die (dice) (1-6) using the C++ random number functions. First ask the user how many times they would like to have the die (dice) rolled.
Next, have the program simulate the number of rolls of the die (dice) the user requested and keep track of which number the die (dice) landed on for each roll. At the end of the program print out a report showing how many times the die (dice) roll landed on each number and what percentage of the total times the die (dice) roll landed on each number.
Do NOT use functions or arrays on this - use what I showed you during lecture, you should always listen during lecture to get the right techniques, if you forgot what I said during lecture look at the slides.
Input Validation: Do not allow the user to enter a number less than 1 as the number of times they would like to roll the dice.
How output should be (on left) vs what mine outputs (on right):
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand((unsigned int)time(NULL));
int timesRolled;
int rolled;
float num1 = 0;
float num2 = 0;
float num3 = 0;
float num4 = 0;
float num5 = 0;
float num6 = 0;
cout << "How many times would you like to roll the dice?" << endl;
cin >> timesRolled;
for (int i = 0; i < timesRolled; i++)
{
rolled = rand() % 6 + 1;
if (rolled == 1)
{
num1++;
}
else if (rolled == 2)
{
num2++;
}
else if (rolled == 3)
{
num3++;
}
else if (rolled == 4)
{
num4++;
}
else if (rolled == 5)
{
num5++;
}
else if (rolled == 6)
{
num6++;
}
}
while (timesRolled < 1)
{
cout << "This is an invalid number. " << endl
<< "The number of rolls should be equal to or greater than 1." << endl
<< "Please enter again." << endl;
cin >> timesRolled;
}
cout << "\nDICE ROLL STATISTICS" << endl << endl
<< "# Rolled # Times % Times" << endl
<< "-------- -------- --------" << endl
<< setw(7) << "1" << setw(17) << fixed << setprecision(0) << num1 << setw(17) << fixed << setprecision(2) << (num1 / timesRolled) * 100 << "%" << endl
<< setw(7) << "2" << setw(17) << fixed << setprecision(0) << num2 << setw(17) << fixed << setprecision(2) << (num2 / timesRolled) * 100 << "%" << endl
<< setw(7) << "3" << setw(17) << fixed << setprecision(0) << num3 << setw(17) << fixed << setprecision(2) << (num3 / timesRolled) * 100 << "%" << endl
<< setw(7) << "4" << setw(17) << fixed << setprecision(0) << num4 << setw(17) << fixed << setprecision(2) << (num4 / timesRolled) * 100 << "%" << endl
<< setw(7) << "5" << setw(17) << fixed << setprecision(0) << num5 << setw(17) << fixed << setprecision(2) << (num5 / timesRolled) * 100 << "%" << endl
<< setw(7) << "6" << setw(17) << fixed << setprecision(0) << num6 << setw(17) << fixed << setprecision(2) << (num6 / timesRolled) * 100 << "%" << endl;
system("PAUSE");
return 0;
}
You can see where I tried to use setprecision (at the end of my program) to manipulate the output of decimals in my final percentage number, but it doesn't seem to be working and this is where I need help please.
Your problem is an integer division e.g.:
(num1 / timesRolled) * 100 = 10 / 50 * 100 = 0 * 100 = 0;
Use floating point values instead or cast before division:
float num1 = 0;
or
(static_cast<float>(num1) / timesRolled) * 100

GLM multiplication order

I am a little amazed. I have been debugging my code for hours now, and GLM seems to be giving up on me. I am struggling with the following 2 instances:
....
cout << "multiplying A:" << endl;
displayMatrix(node->wMatrix);
cout << "and B:" << endl;
displayMatrix((node->children)[i]->wMatrix);
//switch order!
mat4 temp = (node->children)[i]->wMatrix * node->wMatrix;
cout << "Get result as:" << endl;
displayMatrix(temp);
...
The displayMatrix method is as follows:
void displayMatrix(mat4 &m)
{
cout << m[0][0] << " " << m[0][1] << " " << m[0][2] << " " << m[0][3] << endl;
cout << m[1][0] << " " << m[1][1] << " " << m[1][2] << " " << m[1][3] << endl;
cout << m[2][0] << " " << m[2][1] << " " << m[2][2] << " " << m[2][3] << endl;
cout << m[3][0] << " " << m[3][1] << " " << m[3][2] << " " << m[3][3] << endl;
}
Here is the output I get:
multiplying A:
1 0 0 0
0 1 0 0.5
0 0 1 0
0 0 0 1
and B:
0.540302 -0.841471 0 0
0.841471 0.540302 0 -0.5
0 0 1 0
0 0 0 1
Get result as:
0.540302 -0.841471 0 0
0.841471 0.540302 0 0
0 0 1 0
0 0 0 1
NOTICE that in the code above, the matrix multiplication order is the reverse of what you would write on paper. In other words, the code says B * A. I was very thrown off by this.
The second instance:
cout << "temp:" << endl;
cout << temp.x << " " << temp.y << " " << temp.z << " " << temp.w << endl;
cout << "binding matrix inverse: " << endl;
displayMatrix(bindingInvs.at(jIndex));
temp = bindingInvs.at(jIndex) * temp;
cout << "now temp:" << endl;
cout << temp.x << " " << temp.y << " " << temp.z << " " << temp.w << endl;
cout << "joint world matrix: " << endl;
displayMatrix(joints.at(jIndex)->wMatrix);
temp = (joints.at(jIndex)->wMatrix) * temp;
cout << "now temp:" << endl;
cout << temp.x << " " << temp.y << " " << temp.z << " " << temp.w << endl;
cout << "weight: " << jWeight << endl;
temp = jWeight * temp;
cout << "now temp:" << endl;
cout << temp.x << " " << temp.y << " " << temp.z << " " << temp.w << endl;
The output that I get now is:
temp:
0.087 0 -0.05 1
binding matrix inverse:
1 -0 0 -0
-0 1 -0 0
0 -0 1 -0
-0 0 -0 1
now temp:
0.087 0 -0.05 1
joint world matrix:
1 0 0 0
0 1 0 0.5
0 0 1 0
0 0 0 1
now temp:
0.087 0 -0.05 1
weight: 1
now temp:
0.087 0 -0.05 1
Temp is never getting changed for some reason. I don't know what to do, or why this is happening. My programs compiles and runs (I am pasting from output above). Of course, this is not the entire program. This is only the steps for debugging. But I feel confident that this much should be enough to tell what's going on.
Your displayMatrix function is confusing you, since you print the matrices transposed to what you would expect on paper. GLM uses column major ordering, so the addressing is m[col][row].
Now with that in mind, the operation A*B is actually what you should expect.
For the temp vector, the same problem arises: the first matrix you multiply it by is identity, so it is unchanged. The second matrix is identity, except the last row is 0 0.5 0 1, so x, y and z will be unchanged and the new w' will be 0.5 * y + w. Since y is 0 to begin with, nothing is changed here,too.

not using input after first pass of loop

The intent is to ask a user if they want to play, output options, receive userinput and then simulate a 'roll' the appropriately sided dice. Output the results, and then ask for another choice, etc.
The first cycle of the program works as it should, but instead of it asking if you want to play again it is blank. If you enter a number to select the dice it will output how many sides the first dice had no matter what is chosen.
#include <iostream>
#include <ctime>
using namespace std;
int throwDie(int Sides, int &throwResult)
{
throwResult = 1 + rand() % (Sides - 1 + 1);
return throwResult;
}
int main()
{
int dieTot = 0,
throwNumber = 0,
numberSides = 0,
throwResult = 0;
int die1 = 4;
int die2 = 6;
int die3 = 8;
int die4 = 10;
int die5 = 12;
int die6 = 20;
char rollAgain;
srand(unsigned(time(0) ));
START:
cout << "Do you want Play? ";
cin >> rollAgain;
cout << "How many sides? " << endl;
cout << "1 - 4 sided die\n";
cout << "2 - 6 sided die\n";
cout << "3 - 8 sided die\n";
cout << "4 - 10 sided die\n";
cout << "5 - 12 sided die\n";
cout << "6 - 20 sided die\n";
int choice;
cout << "Enter choice: ";
cin >> choice;
switch( choice ) {
case 1:
do {
cout << "You have choosen a 4 sided die? " << endl;
int numberSides = die1;
cout << numberSides << "-sided die rolled for a value of "
<< throwDie(numberSides, throwResult) << "!" << endl;
dieTot = dieTot + throwResult;
throwNumber++;
cin >> numberSides;
} while (choice != numberSides );
goto START;
break;
case 2:
do {
cout << "You have choosen a 6 sided die? " << endl;
int numberSides = die2;
cout << numberSides << "-sided die rolled for a value of "
<< throwDie(numberSides, throwResult) << "!" << endl;
dieTot = dieTot + throwResult;
throwNumber++;
cin >> numberSides;
cout << endl << "Total for " << throwNumber << " throws = " << dieTot << endl;
} while (choice != numberSides );
break;
case 3:
do {
cout << "You have choosen a 8 sided die? " << endl;
int numberSides = die3;
cout << numberSides << "-sided die rolled for a value of "
<< throwDie(numberSides, throwResult) << "!" << endl;
dieTot = dieTot + throwResult;
throwNumber++;
cin >> numberSides;
cout << endl << "Total for " << throwNumber << " throws = " << dieTot << endl;
} while (choice != numberSides );
break;
case 4:
do {
cout << "You have choosen a 10 sided die? " << endl;
int numberSides = die4;
cout << numberSides << "-sided die rolled for a value of "
<< throwDie(numberSides, throwResult) << "!" << endl;
dieTot = dieTot + throwResult;
throwNumber++;
cin >> numberSides;
cout << endl << "Total for " << throwNumber << " throws = " << dieTot << endl;
} while (choice != numberSides );
break;
case 5:
do {
cout << "You have choosen a 12 sided die? " << endl;
int numberSides = die5;
cout << numberSides << "-sided die rolled for a value of "
<< throwDie(numberSides, throwResult) << "!" << endl;
dieTot = dieTot + throwResult;
throwNumber++;
cin >> numberSides;
cout << endl << "Total for " << throwNumber << " throws = " << dieTot << endl;
} while (choice != numberSides );
break;
case 6:
do {
cout << "You have choosen a 20 sided die? " << endl;
int numberSides = die6;
cout << numberSides << "-sided die rolled for a value of "
<< throwDie(numberSides, throwResult) << "!" << endl;
dieTot = dieTot + throwResult;
throwNumber++;
cin >> numberSides;
cout << endl << "Total for " << throwNumber << " throws = " << dieTot << endl;
} while (choice != numberSides );
break;
default:
cout << "Not a proper entry.\n";
break;
cout << endl << "Total for " << throwNumber << " throws = " << dieTot << endl;
return 0;
}
}
I am assuming the extra code in each of the case statments is:
cout << numberSides << "-sided die rolled for a value of " << throwDie(numberSides, throwResult) << "!" << endl;
dieTot = dieTot + throwResult;
throwNumber++;
cin >> numberSides;
cout << endl << "Total for " << throwNumber << " throws = " << dieTot << endl;
}
while (choice != numberSides );
break;
Would that go at the end of the code? Not in every case statement. Also if I do that would I even need to put the while/do into functions?
This has nothing do with looping.
Try printout out the values obtained from your cin's and you'll see the problem.
You use your goto statement inconsistently, you only return to START in your first case
You don't properly terminate your switch statement
You should just about never use a goto unless you can't do it any other way.
This is horribly written. Why do you need to duplicate everything in each case statement? Seems like you only need to use the switch for setting the value of numberSides and the print out.. The rest should be common... I don't think you need the variables either... see my raw refactor just of your code to simply things...
Refactoring your code makes it much more readable: see below
#include <iostream>
#include <ctime>
using namespace std;
//This function will throw a dice returning the result while updating the parameter.
int throwDie(int Sides, int &throwResult)
{
throwResult = 1 + rand() % (Sides); //Sides - 1 + 1 == Sides
return throwResult;
}
//Display the menu
void displayMenu()
{
cout << "How many sides? \n"
<< "1 - 4 sided die\n"
<< "2 - 6 sided die\n"
<< "3 - 8 sided die\n"
<< "4 - 10 sided die\n"
<< "5 - 12 sided die\n"
<< "6 - 20 sided die\n"
<< "CTRL-D to quit";
}
int main()
{
int dieTot = 0,
throwNumber = 0,
numberSides = 0,
throwResult = 0;
// THESE ARENT NEEDED
// sides = 4+2*(X-1)
//int die1 = 4;
//int die2 = 6;
//int die3 = 8;
//int die4 = 10;
//int die5 = 12;
//int die6 = 20;
srand(unsigned(time(0) ));
displayMenu();
int choice;
while ( cin >> choice ) {
/* cin >> choice will return 0 / fail if they enter CTRL-D or enter
something other than a number... you'll have to handle that in another way */
if ( choice < 1 || choice > 6 ) {
cout << "Invalid choice try again!";
continue;
}
//numberSides = 4+2*(choice-1); //fast way
switch (choice) {
case 6:
numberSides = 20;
break;
case 1:
//if you dont want to do this slick trick of fall through
//numberSides = 4;
//break;
case 2:
case 3:
case 4:
case 5:
numberSides = 4+2*(choice-1); // use this for 1,2,3,4,5;
break;
}
cout << "You have chosen a " << numberSides << " sided die.\n"
<< numberSides << "-sided die rolled for a value of "
<< throwDie(numberSides, throwResult) << "!" << endl;
dieTot += throwResult;
throwNumber++;
}
cout << "\n\n" << "Total for " << throwNumber << " throws = " << dieTot << endl;
return 0;
}

How do I make spaces between numbers in a random number generated app in C++?

I need to be able to have spaces come up between each number. Here is my code. Any help would be awesome! This app allows you too have 6 rows of 6 numbers generated for your insta pick numbers between 1 - 49, it has to pick two rows of 6 numbers, 1 - 49 for twist and 1 row of 6 numbers for tag.
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
int main()
{
{
cout << "*** LOTTO MAX INSTA PICK ***" << endl;
cout<< " " << endl << endl;
}
{
cout << "Your Insta Pick Numbers" << endl;
cout<< " " << endl << endl;
}
for (int counter = 1; counter <= 24; ++ counter)
{
cout << setw(1) << (1 + rand() % 49);
if (counter % 6 == 0)
cout << endl;
}
{
cout<< " " << endl << endl;
cout<< " " << endl << endl;
}
{
cout << "Your Twist Numbers" << endl;
cout<< " " << endl << endl;
}
for (int counter = 1; counter <= 12; ++ counter)
{
cout << setw(1) << (1 + rand() % 49) , " ";
if (counter % 6 == 0)
cout << endl;
}
{
cout<< " " << endl << endl;
cout<< " " << endl << endl;
}
{
cout << "Your Tag Numbers" << endl;
cout<< " " << endl << endl;
}
for (int counter = 1; counter <= 6; ++ counter)
{
cout << setw(1) << (1 + rand() % 12);
if (counter % 6 == 0)
cout << endl;
}
{
cout<< " " << endl << endl;
cout<< " " << endl << endl;
}
{
cout << "Thank you for playing!! please check ticket a year minus a day from date of purchase" <<endl;
}
};
You almost had it when you did
cout << setw(1) << (1 + rand() % 49) , " ";
but that doesn't do what you think it does. It evaluates two expressions, separated by a comma - cout << setw(1) << (1 + rand() % 49) and " ". The first does the setw and prints (1 + rand() % 49), and the second one just evaluates to itself and has no effect. Remember that << is the output operator for cout, so you just need to change the comma to a <<:
cout << setw(1) << (1 + rand() % 49) << " ";
The same thing goes for the other places you are printing numbers.
Use cout << setw(1) << (1 + rand() % 49) << " "; in your loop. (Note that , was replaced with <<.