can I create a window in c++ using existing project code - c++

I was wondering if i could create a window using my existing project code. This is a school project. However, I have completed the actual coding part and just wanted to make the project fancier, so to say. Thank you so much in advance for all the support.
Here is the actual code in case it would be of any help. It's a bit lengthy so be warned :) Once again, thank you in advance
#define NOMINMAX
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <windows.h>
#include <Windows.h>
#include <chrono>
#include <string>
#include <fstream>
#include <iomanip>
#include <cstdlib>
using namespace std;
int key[3][3];
double inverted[3][3];
int store[1][3] = { 0 };
int conv[666];
int random1()
{
unsigned long long int xRan;
srand(time(NULL));
xRan = rand() % 9999 + 1;
return xRan;
}
int random2()
{
unsigned long long int xRan;
xRan = rand() % 9999 + 1;
return xRan;
}
int random3()
{
int xRan;
xRan = rand() % 9999 + 1;
return xRan;
}
void clear_screen(char fill = ' ') {
COORD tl = { 0, 0 };
CONSOLE_SCREEN_BUFFER_INFO s;
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(console, &s);
DWORD written, cells = s.dwSize.X * s.dwSize.Y;
FillConsoleOutputCharacter(console, fill, cells, tl, &written);
FillConsoleOutputAttribute(console, s.wAttributes, cells, tl, &written);
SetConsoleCursorPosition(console, tl);
}
int convert(char letter) {
int conv;
conv = (int)letter;
return conv;
}
void reverseMult(double inv[3][3], int decode[1][3])
{
store[0][0] = decode[0][0] * inv[0][0] + decode[0][1] * inv[1][0] + decode[0][2] * inv[2][0] + 0.5;
store[0][1] = decode[0][0] * inv[0][1] + decode[0][1] * inv[1][1] + decode[0][2] * inv[2][1] + 0.5;
store[0][2] = decode[0][0] * inv[0][2] + decode[0][1] * inv[1][2] + decode[0][2] * inv[2][2] + 0.5;
}
void matrixMult(int q, int w, int e, int a[3][3])
{
int A[1][3] = { q, w, e };
int B[3][3] = {
{ a[0][0], a[0][1], a[0][2] },
{ a[1][0], a[1][1], a[1][2] },
{ a[2][0], a[2][1], a[2][2] }
};
store[0][0] = A[0][0] * B[0][0] + A[0][1] * B[1][0] + A[0][2] * B[2][0];
store[0][1] = A[0][0] * B[0][1] + A[0][1] * B[1][1] + A[0][2] * B[2][1];
store[0][2] = A[0][0] * B[0][2] + A[0][1] * B[1][2] + A[0][2] * B[2][2];
//cout << store[0][0] << endl << store[0][1] << endl << store[0][2] << endl << endl;
}
char reverseConv(int x){
char conv;
conv = (char)x;
return conv;
}
void inverse(int key[3][3], double det){
int cofactor[3][3] = {
{ (key[1][1] * key[2][2] - key[1][2] * key[2][1]), -(key[1][0] * key[2][2] - key[1][2] * key[2][0]), (key[1][0] * key[2][1] - key[1][1] * key[2][0]) },
{ -(key[0][1] * key[2][2] - key[0][2] * key[2][1]), (key[0][0] * key[2][2] - key[0][2] * key[2][0]), -(key[0][0] * key[2][1] - key[0][1] * key[2][0]) },
{ (key[0][1] * key[1][2] - key[0][2] * key[1][1]), -(key[0][0] * key[1][2] - key[0][2] * key[1][0]), (key[0][0] * key[1][1] - key[0][1] * key[1][0]) }
};
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
inverted[i][j] =det * cofactor[i][j];
}
}
}
int main()
{
while (1){
cout << "Would you like to encrypt or decrypt?(e/d)\n " << endl;
string ende;
cin >> ende;
clear_screen();
if (ende == "e")
{
cout << "Please enter a name for the message: " << endl << endl;
string file;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
getline(cin, file);
clear_screen();
file += ".txt";
ofstream encrypt;
encrypt.open(file);
string message;
cout << "Please enter the message you would like to encrypt: " << endl << endl;
//cin.ignore(numeric_limits<streamsize>::max(), '\n'); --- Not needed anymore, uncomment if you cannot input message
getline(cin, message);
if (message.length() % 3 != 0)
message += ' ';
if (message.length() % 3 != 0)
message += ' ';
clear_screen();
for (int i = 0; i < message.length(); ++i)
{
conv[i] = convert(message[i]);
}
int det = 0;
while (1){
key[0][0] = random1(); //1
key[0][1] = random2(); //2
key[0][2] = random3(); //3
key[1][0] = random1() * 13 / 7; //4
key[1][1] = random2() * 23 / 7; //5
key[1][2] = random3() * 33 / 7; //6
key[2][0] = random1() * 18 / 15; //7
key[2][1] = random2() * 18 / 12; //8
key[2][2] = random3() * 18 / 10; //9
det = key[0][0] * key[1][1] * key[2][2] + key[0][1] * key[1][2] * key[2][0] + key[0][2] * key[1][0] * key[2][1]
- key[0][2] * key[1][1] * key[2][0] - key[0][0] * key[1][2] * key[2][1] - key[0][1] * key[1][0] * key[2][2];
if (det != 0)
break;
}
encrypt << key[0][0] << ' ' << key[0][1] << ' ' << key[0][2] << ' '
<< key[1][0] << ' ' << key[1][1] << ' ' << key[1][2] << ' '
<< key[2][0] << ' ' << key[2][1] << ' ' << key[2][2] << endl << endl;
int a, b, c;
int count = 0;
for (int i = 0; i < (message.length)() / 3; ++i)
{
int counting = 0;
a = conv[count];
count++;
b = conv[count];
count++;
c = conv[count];
count++;
matrixMult(a, b, c, key);
encrypt << store[0][counting] << ' ';
counting++;
encrypt << store[0][counting] << ' ';
counting++;
encrypt << store[0][counting] << endl;
}
encrypt.close();
Sleep(750);
cout << "Your message has been encrypted." << endl;
Sleep(750);
cout << "Please check " << file << " for the encrypted message and key" << endl << endl;
Sleep(750);
}
if (ende == "d")
{
cout << "Please enter the name of the file you would like to decrypt: " << endl << endl;
string file;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
getline(cin, file);
clear_screen();
file += ".txt";
ifstream decrypt;
decrypt.open(file);
int key[3][3];
for (int i = 0; i < 3; ++i)
{
for (int k = 0; k < 3; ++k){
decrypt >> key[k][i];
}
}
int det = 0;
det = key[0][0] * key[1][1] * key[2][2] + key[0][1] * key[1][2] * key[2][0] + key[0][2] * key[1][0] * key[2][1] - key[0][2] * key[1][1] * key[2][0] - key[0][0] * key[1][2] * key[2][1] - key[0][1] * key[1][0] * key[2][2];
double detInv = 1;
detInv /= det;
//double inv;
inverse(key, detInv);
int out[1][3];
int count = 0;
while (!decrypt.eof()){
for (int i = 0; i < 3; ++i)
{
decrypt >> out[0][i];
}
reverseMult(inverted, out);
count++;
char a, b, c;
a = reverseConv(store[0][0]);
b = reverseConv(store[0][1]);
c = reverseConv(store[0][2]);
if (decrypt.eof())
break;
cout << a << b << c;
}
}
cout << endl << endl;
cout << "Would you like to continue?(y/n) ";
char again;
cin >> again;
if (again != 'y')
exit(0);
clear_screen();
}
return 0;
}

Yes, you can convert your project to a Windowing application. You have two choices:
Use Windows (native) API
Use graphics framework
Windows API
The Windows API is the direct method for creating windows. However, it is a lot of code, lots of chances for defects to be injected. It is a good learning experience about how the Windowing system works. Get Petzold's book.
GUI Framework
There are a lot of GUI frameworks out there. These C++ frameworks have simplified the GUI and Widget creation, using object oriented programming. There are many out there, so search the internet for "GUI Framework C++ review".
A Different Programming Perspective
In your present project, the OS executes the program and statements are executed in order. A windowing system is based on event driven programming. In summary, your GUI is waiting for an event to occur.
A simple example for your project is a window with a single button. When the User clicks on the button, the Windowing system sends a message to the button event handler. The event handler is a function that will execute your code.

As Thomas said, yes you can migrate your code to a Windows application, by either going native with Win32 or by either using a C++ GUI Framework (QT, wxWindows, ...).
However, you will need to invest time to learn one of the solution. I would suggest to learn a C++ Framework, programming with low-level Win32 api is not very used today.
Although it's off-topic, I would suggest some improvements to your code.
First, you shouldn't use goto, and replace them by a while. You can replace
again:
xRan = rand() % 9999 + 1;
if (xRan <1)
goto again;
By
do{
xRan = rand() % 9999 + 1;
} while (xRan < 1);
Note that in this case, a goto or a while is useless as xRan will always be superior or equal to 1 (rand() always returns a positive value)
Also you can replace convert and reverseConv very long functions by a constant array of struct values (struct contains a int and a const char*). convert and reverseConvert functions would only parse the array to find a proper match.

Related

Receiving char array via MPI_Recv results in the output image being partially black

I am calculating a picture and i am using OpenMPI to destribute my loop onto several cores.
Every core calculates a part of the loop correctly, but merging
both arrays on the core with rank 0 results in part of the picture being black.
I do not know if sending/receiving the char array corrupts the data or
if my merge is not correct.
(My virtual machine has 2 cores).
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <xmmintrin.h>
#include "complex.h"
#include "lodepng.h"
using namespace std;
#include <sys/time.h>
#include <mpi.h>
int julia(int width, int height, int x, int y, const complex &c, const int max_iter) {
/*
* calculates the number of iterations (between 0 and 255) for a pixel (x,y)
*/
complex z(1.5f * (x - width / 2) / (0.5f * width), (y - height / 2) / (0.5f * height));
int n = 0;
for (int i = 0; ((z.abs() < 2.0f) && (i < max_iter)); i++) {
float tmp = z.re() * z.re() - z.im() * z.im() + c.re();
z.set_im(2.0f * z.re() * z.im() + c.im());
z.set_re(tmp);
n++;
}
return max_iter - n;
}
int main(int argc, char **argv) {
int rank, num_procs;
//Initialize the infrastructure necessary for coomunication
MPI_Init(&argc, &argv);
//Identify this process
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
//Find out how many processes are active
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
const complex c(-0.7, 0.27015); // pretty
// const complex c( -0.8, 0.156); // alternative complex number
const int width = 2 * 1024, height = 2 * 1024; // image size
int max_iter = 256;
// Allocate aligned image buffer
unsigned char *image = NULL;
int err = posix_memalign((void **) &image, 64, width * height * 4 * sizeof(unsigned char));
if (err){
cout << "[Error] Couldn't allocate memory for regular Image." << endl;
}
int count = height / num_procs;
int remainder = height % num_procs;
int start, stop;
if (rank < remainder) {
// The first 'remainder' ranks get 'count + 1' tasks each
start = rank * (count + 1);
stop = start + count;
} else {
// The remaining 'size - remainder' ranks get 'count' task each
start = rank * count + remainder;
stop = start + (count - 1);
}
/*
* Creates a pictures of a julia set
*/
cout << "--------------------- " << endl;
cout << "my rank " << rank << endl;
cout << "number of procs " << num_procs << endl;
cout << "start " << start << endl;
cout << "end " << stop << endl;
cout << "--------------------- "<< endl;
// iterate over image pixels and calculate their value
for (int y = start; y <= stop; y++) {
for (int x = 0; x < width; x++) {
int a = julia(width, height, x, y, c, max_iter);
image[4 * width * y + 4 * (x + 0) + 0] = a; // R
image[4 * width * y + 4 * (x + 0) + 1] = a; // G
image[4 * width * y + 4 * (x + 0) + 2] = a; // B
image[4 * width * y + 4 * (x + 0) + 3] = 255; // Alpha
}
}
if(rank != 0)
{
//send image to rank 0
MPI_Send(image, sizeof(image), MPI_UNSIGNED_CHAR, 0, 0, MPI_COMM_WORLD);
}
if(rank == 0 && (num_procs > 0))
{
// Allocate aligned image buffer
unsigned char *lImage = (unsigned char *) malloc(width * height * 4 * sizeof(unsigned char));
/*
unsigned char *lImage = NULL;
int err = posix_memalign((void **) &lImage, 64, width * height * 4 * sizeof(unsigned char));
if (err){
cout << "[Error] Couldn't allocate memory for regular Image." << endl;
}
*/
for(int i = 1; i < num_procs; i++)
{
//lImage receives the image array from process i
MPI_Recv(lImage, sizeof(lImage), MPI_UNSIGNED_CHAR, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
//calculate start and stop for the following for loop
int lCount = height / num_procs;
int lRemainder = height % num_procs;
int lStart, lStop;
if (i < lRemainder) {
// The first 'remainder' ranks get 'count + 1' tasks each
lStart = i * (lCount + 1);
lStop = lStart + lCount;
} else {
// The remaining 'size - remainder' ranks get 'count' task each
lStart = i * lCount + lRemainder;
lStop = lStart + (lCount - 1);
}
cout << "--------inside loop----------- " << endl;
cout << "my rank " << i << endl;
cout << "start " << lStart << endl;
cout << "end " << lStop << endl;
cout << "--------------------- "<< endl;
for (int y = lStart; y <= lStop; y++) {
for (int x = 0; x < width; x++) {
image[4 * width * y + 4 * (x + 0) + 0] = lImage[4 * width * y + 4 * (x + 0) + 0]; // R
image[4 * width * y + 4 * (x + 0) + 1] = lImage[4 * width * y + 4 * (x + 0) + 1]; // G
image[4 * width * y + 4 * (x + 0) + 2] = lImage[4 * width * y + 4 * (x + 0) + 2]; // B
image[4 * width * y + 4 * (x + 0) + 3] = 255; // Alpha
}
}
//receive image of the rank i
//merge received image array and rank 0 image array
}
free(lImage);
}
if(rank == 0)
{
/*Encode the image*/
unsigned error = lodepng_encode32_file("julia_openmp0.png", image, width, height);
if (error) {
std::cout << "[Error] " << error << " : " << lodepng_error_text(error) << std::endl;
}
}
if(rank == 1)
{
/*Encode the image*/
unsigned error = lodepng_encode32_file("julia_openmp1.png", image, width, height);
if (error) {
std::cout << "[Error] " << error << " : " << lodepng_error_text(error) << std::endl;
}
}
/*cleanup*/
free(image);
/* Tear down the communication infrastructure */
MPI_Finalize();
return 0;
Sorry I had no chance to do a proper checking, but I think it boils down to this line:
MPI_Recv(lImage, sizeof(lImage), MPI_UNSIGNED_CHAR, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
You are trying to receive the messages in a particular order (process 1, process 2), while you don't really know which one is ready first. And MPI_Recv receive operation is blocking. Can you try to rewrite the logic in such a way that it does not depend on the order of computation? One way to do it would be to use MPI_Gather(). Another option would be to include process number into the message you send, then use MPI_ANY_SOURCE to receive the next incoming message and to use process number in the loop to handle the block correctly.

Using codeblocks code in visual studio

I am used to write C++ project in CodeBlocks, but for some stupid reasons I have to show it to my teacher in VisualStudio. I tried to make a console app or an empty project, and copied my main file there, but with the first one I get bunch of erorrs and the second one I get 'The system cannot find the way specified'. What is different in VisualStudio? I don't understand at all what is wrong.
here is my code
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;
const int kroku = 1000;
const double aa = 0; //pocatecni bod intervalu
const double bb = 1; //konečný bod intervalu
double a; //parametr
const double h = (bb - aa) / kroku; //krok
double p(double t) { //(py')' - qy = f
return exp(a*pow(t, 2));
}
double q(double t) {
return -exp(a*pow(t, 2))*pow(a, 2)*pow(t, 2);
}
double dp(double t) {
return 2 * t*a*exp(a*pow(t, 2));
}
double y[kroku + 1]; //řešení původní rce
double dydx[kroku + 1];
double z[kroku + 1]; //řešení dílčí rce
double dzdx[kroku + 1];
double x[kroku + 1]; //rozdělení intervalu (aa, bb) po krocích h
void generateX() { //generuje hodnoty x
for (int k = 0; k <= kroku; k++) {
x[k] = aa + k*h;
}
}
double partial(double pp1, double pp2, double w[kroku + 1], double dwdx[kroku + 1], double v)//řešení rce (pw')' - qw = g s pp
{
w[v] = pp1; //inicializace - počáteční podmínka
dwdx[v] = pp2; //inicialzace - počáteční podmínka
for (int i = 0; i <= kroku; i++) { //substituce dwdx proměnná -> dwdx = (w_(n+1) - w_n)/h) && dwdx =
w[i + 1] = h*dwdx[i] + w[i];
dwdx[i + 1] = (h / p(aa + h*i))*(q(aa + h*i)*w[i] - dp(aa + h*i)*dwdx[i]) + dwdx[i];
}
return 0;
}
double omega1, omega2; //nové počáteční podmínky omega1 = y(x0), omega2 = y'(x0)
void print(double N[kroku + 1])
{
fstream file;
file.open("data.dat", ios::out | ios::in | ios::trunc);//otevření/vytvoření(trunc) souboru
if (file.is_open()) //zápis do souboru
{
cout << "Writing";
file << "#" << "X" << " " << "Y" << endl;
for (int j = 0; j <= kroku; j++) {
file << x[j] << " " << N[j] << endl;
}
file << "#end";
}
else
{
cout << "Somethinq went wrong!";
}
file.close();
}
int main()
{
double alpha; //pocatecni podminka y(aa) = alpha
double beta; //y(bb) = beta
cout << "Assign the value of beta " << endl;
cin >> beta;
cout << "Assign the value of alpha " << endl;
cin >> alpha;
cout << "Assign the value of parameter a" << endl;
cin >> a;
double alpha1 = 0; //alpha1*p(aa)*y'(aa) - beta1*y(aa) = gamma1
//double alpha2 = 0; //alpha2*p(bb)*y'(bb) + beta2*y(bb) = gamma2
double beta1 = -1;
double beta2 = 1;
double gamma1 = alpha;
double gamma2 = beta;
generateX();
partial(alpha1, beta1 / p(aa), z, dzdx, aa); //(pz')'-qz = 0
omega1 = gamma2 / beta2;
omega2 = 1 / (z[kroku] * p(bb))*(gamma1 + dzdx[kroku] * p(bb));
partial(omega1, omega2, y, dydx, aa);//(py')' - qy = f = 0
print(y);
return 0;
strong text}
when I add
#include "stdafx.h"
I get four errors
2x 'Expression must have integral or unscoped enum type'
2x 'subscript is not of integral type'
for these lines
w[v] = pp1;
dwdx[v] = pp2;
Could anyone please help me? Thank you a lot
array subscript v in your line
w[v]
can not be double. It must be of interger type.

Strange output when using atof(optarg)

Edit::
Resolved- This was due to a misunderstanding of the use of the getOpt function.
I referenced the materials in the man here, on stack overflow (http://linux.die.net/man/3/getopt) and the getOpt documentation on GNU's website here: gnu.org/software/libc/manual/html_node/Example-of-Getopt.html Thanks to Bill Lynch and Remyabel for referencing source materials previously mentioned.
there seems to be an issue when I run this program using the -f variable to run the "Football" Commands, alongside using -c, However, I'm primarily concerned on getting just one to work for now.
Placing in the input:
-f -p 16 -a 25 -y 267 -t 1 -i 2
Gives out::
pC = 0
pC = 32738
pY = -1052776240
T = 32738
I = 1
Now, these variables should just be spitting out exactly what I put in, as the only conversion I'm using ( as seen below) is X = atof(optarg);
I suspect this may have something to do with the ASCII values, though I'm almost entirely clueless.
#
#include <iostream>
#include <unistd.h>
#include <cstdlib>
#include <time.h>
#include <stdlib.h>
#include <cmath>
using namespace std;
int main(int argc, char *argv[])
{
srand(time(NULL));
double r = (6 + ( std::rand() % ( 8 - 6 + 1 ) )) / 10;
int c;
int pA;
int pY;
int T;
int I;
int pC;
double mass;
double bMass;
double dist;
double velo;
double Cr = .001;
double k = .18;
double g = 9.8;
double CFdraft;
double Pair;
double Proll;
double Psec;
double timeTravel = 0.0;
double Et;
double E;
double Eavg = 0;
int x = 0;
double cT;
double cC;
double cY;
double cI;
double PasserRating;
while ((c = getopt (argc, argv, "c:m:b:v:d:f:p:a:y:t:i:")) != -1)
{
if (c == 'f') // There seems to be some kind of misunderstanding with what this is doing
// The c=='f' line is there to designate which set of calculations to run, so, that needs to be the //foremost variable to be checked at the beginning of the program.
{
if (c == 'p')
{
pC = atof(optarg);
}
if (c == 'a')
{
pA = atof(optarg);
}
if (c == 'y')
{
pY = atof(optarg);
}
if (c == 't')
{
T = atof(optarg);
}
if (c == 'i')
{
I = atof(optarg);
}
cout << "pC " << pC << endl;
cout << "pC " << pA << endl;
cout << "pY " << pY << endl;
cout << "T " << T << endl;
cout << "I " << I << endl;
//Calculations
cC = ((pC / pA) - 0 / 30) * 5;
cY = ((pY / pA) - 3) * 0.25;
cT = ((T / pA) * 20);
cI = ((2.375) - (I / pA) * 25);
if (cC <= 0)
{
cC = 0;
}
if (cC >= 2.375)
{
cC = 2.375;
}
if (cY <= 0)
{
cY = 0;
}
if (cY >= 2.375)
{
cY = 2.375;
}
if (cT <= 0)
{
cT = 0;
}
if (cT >= 2.375)
{
cT = 2.375;
}
if (cI <= 0)
{
cI = 0;
}
if (cI >= 2.375)
{
cI = 2.375;
}
PasserRating = (((cC + cY + cT + cI) / 6) * 100);
string strPR = "Poor";
if (PasserRating <= 85)
{
strPR = "poor";
}
if (PasserRating > 85)
{
strPR = "mediocre";
}
if (PasserRating > 90)
{
strPR = "good ";
}
if (PasserRating > 95)
{
strPR = "great ";
}
cout << strPR << " " << PasserRating << endl;
}
if (c == 'c')
{
if (c == 'm')
{
mass = atof(optarg);
}
if (c == 'b')
{
bMass = atof(optarg);
}
if (c == 'd')
{
dist = atof(optarg);
}
if (c == 'v')
{
velo = atof(optarg);
}
timeTravel = (dist * 1000) / velo;
cout << "time:" << timeTravel << endl;
cout << "mass " << mass << endl;
cout << "bMass " << bMass << endl;
cout << "dist " << dist << endl;
cout << "velo " << velo << endl;
for (x = 0; x < (10); x ++)
{
CFdraft = r;
Pair = k * CFdraft * (pow(velo, 3));
Proll = Cr * g * (mass + bMass) * velo;
Psec = Pair + Proll;
Et = (Psec * timeTravel);
E = E + Et;
Eavg = E / timeTravel;
}
cout << Eavg << " KJ" << endl;
}
}
return 0;
}
I seriously recommend properly indenting your code. If you did, you would see this:
if(c == 'f'){
if (c == 'p')
...
}
Clearly c is not going to be equal to 'f' and 'p' at the same time.
You never execute your parsing code - everything is inside if(c == 'f') condition, which is obviously true only for the first time you run the loop... So you just get random values from the memory.

Outputting a Square Shape C++ using '*'

Hello I am very new to programming and my assignment is to output shapes. The first is the square:
int main(){
unsigned size;
cout <<"Size: ? ";
cin >>size;
for ( unsigned r = 0; r < size; r++ ){ // Square
for ( unsigned c = 0; c < size ; c++ )
if ( r == c )
cout <<'*';
cout <<endl;
}
cout <<endl;
}
When I input "5" after being prompted. The output results in:
5
*
*
*
*
*
Can anyone explain what is wrong with my code? I need to have both horizontal and vertical outputs. Thank you
You are only outputting a * on the diagonal, when r is the same as c. And you output nothing else but some endlines, so you end up with just a single star on each line.
#include <iostream>
using namespace std;
int main(){
unsigned size;
bool solid = true; //solid or hollow shape?
cout <<"Size: ? ";
cin >>size;
size = 5;
cout << endl;
for ( unsigned r = 0; r < size; r++ ){ // Square
for ( unsigned c = 0; c < size ; c++ ){
if(solid){
cout << " * ";
}
else{
if(r == 0 || r == size-1 || c == 0 or c == size-1){
cout << " * ";
}
else{
cout << " ";
}
}
}
cout <<endl;
}
cout <<endl;
}
Output Hollow:
* * * * *
* *
* *
* *
* * * * *
Solid:
* * * * *
* * * * *
* * * * *
* * * * *
* * * * *
Only time the * is printed is when r == c. What's the purpose of the if statement?
Try commenting the if statement and see the result.

Simple 3x3 matrix inverse code (C++)

What's the easiest way to compute a 3x3 matrix inverse?
I'm just looking for a short code snippet that'll do the trick for non-singular matrices, possibly using Cramer's rule. It doesn't need to be highly optimized. I'd prefer simplicity over speed. I'd rather not link in additional libraries.
Here's a version of batty's answer, but this computes the correct inverse. batty's version computes the transpose of the inverse.
// computes the inverse of a matrix m
double det = m(0, 0) * (m(1, 1) * m(2, 2) - m(2, 1) * m(1, 2)) -
m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) +
m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0));
double invdet = 1 / det;
Matrix33d minv; // inverse of matrix m
minv(0, 0) = (m(1, 1) * m(2, 2) - m(2, 1) * m(1, 2)) * invdet;
minv(0, 1) = (m(0, 2) * m(2, 1) - m(0, 1) * m(2, 2)) * invdet;
minv(0, 2) = (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) * invdet;
minv(1, 0) = (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2)) * invdet;
minv(1, 1) = (m(0, 0) * m(2, 2) - m(0, 2) * m(2, 0)) * invdet;
minv(1, 2) = (m(1, 0) * m(0, 2) - m(0, 0) * m(1, 2)) * invdet;
minv(2, 0) = (m(1, 0) * m(2, 1) - m(2, 0) * m(1, 1)) * invdet;
minv(2, 1) = (m(2, 0) * m(0, 1) - m(0, 0) * m(2, 1)) * invdet;
minv(2, 2) = (m(0, 0) * m(1, 1) - m(1, 0) * m(0, 1)) * invdet;
This piece of code computes the transposed inverse of the matrix A:
double determinant = +A(0,0)*(A(1,1)*A(2,2)-A(2,1)*A(1,2))
-A(0,1)*(A(1,0)*A(2,2)-A(1,2)*A(2,0))
+A(0,2)*(A(1,0)*A(2,1)-A(1,1)*A(2,0));
double invdet = 1/determinant;
result(0,0) = (A(1,1)*A(2,2)-A(2,1)*A(1,2))*invdet;
result(1,0) = -(A(0,1)*A(2,2)-A(0,2)*A(2,1))*invdet;
result(2,0) = (A(0,1)*A(1,2)-A(0,2)*A(1,1))*invdet;
result(0,1) = -(A(1,0)*A(2,2)-A(1,2)*A(2,0))*invdet;
result(1,1) = (A(0,0)*A(2,2)-A(0,2)*A(2,0))*invdet;
result(2,1) = -(A(0,0)*A(1,2)-A(1,0)*A(0,2))*invdet;
result(0,2) = (A(1,0)*A(2,1)-A(2,0)*A(1,1))*invdet;
result(1,2) = -(A(0,0)*A(2,1)-A(2,0)*A(0,1))*invdet;
result(2,2) = (A(0,0)*A(1,1)-A(1,0)*A(0,1))*invdet;
Though the question stipulated non-singular matrices, you might still want to check if determinant equals zero (or very near zero) and flag it in some way to be safe.
Why don't you try to code it yourself? Take it as a challenge. :)
For a 3×3 matrix
(source: wolfram.com)
the matrix inverse is
(source: wolfram.com)
I'm assuming you know what the determinant of a matrix |A| is.
Images (c) Wolfram|Alpha and
mathworld.wolfram (06-11-09,
22.06)
With all due respect to our unknown (yahoo) poster, I look at code like that and just die a little inside. Alphabet soup is just so insanely difficult to debug. A single typo anywhere in there can really ruin your whole day. Sadly, this particular example lacked variables with underscores. It's so much more fun when we have a_b-c_d*e_f-g_h. Especially when using a font where _ and - have the same pixel length.
Taking up Suvesh Pratapa on his suggestion, I note:
Given 3x3 matrix:
y0x0 y0x1 y0x2
y1x0 y1x1 y1x2
y2x0 y2x1 y2x2
Declared as double matrix [/*Y=*/3] [/*X=*/3];
(A) When taking a minor of a 3x3 array, we have 4 values of interest. The lower X/Y index is always 0 or 1. The higher X/Y index is always 1 or 2. Always! Therefore:
double determinantOfMinor( int theRowHeightY,
int theColumnWidthX,
const double theMatrix [/*Y=*/3] [/*X=*/3] )
{
int x1 = theColumnWidthX == 0 ? 1 : 0; /* always either 0 or 1 */
int x2 = theColumnWidthX == 2 ? 1 : 2; /* always either 1 or 2 */
int y1 = theRowHeightY == 0 ? 1 : 0; /* always either 0 or 1 */
int y2 = theRowHeightY == 2 ? 1 : 2; /* always either 1 or 2 */
return ( theMatrix [y1] [x1] * theMatrix [y2] [x2] )
- ( theMatrix [y1] [x2] * theMatrix [y2] [x1] );
}
(B) Determinant is now: (Note the minus sign!)
double determinant( const double theMatrix [/*Y=*/3] [/*X=*/3] )
{
return ( theMatrix [0] [0] * determinantOfMinor( 0, 0, theMatrix ) )
- ( theMatrix [0] [1] * determinantOfMinor( 0, 1, theMatrix ) )
+ ( theMatrix [0] [2] * determinantOfMinor( 0, 2, theMatrix ) );
}
(C) And the inverse is now:
bool inverse( const double theMatrix [/*Y=*/3] [/*X=*/3],
double theOutput [/*Y=*/3] [/*X=*/3] )
{
double det = determinant( theMatrix );
/* Arbitrary for now. This should be something nicer... */
if ( ABS(det) < 1e-2 )
{
memset( theOutput, 0, sizeof theOutput );
return false;
}
double oneOverDeterminant = 1.0 / det;
for ( int y = 0; y < 3; y ++ )
for ( int x = 0; x < 3; x ++ )
{
/* Rule is inverse = 1/det * minor of the TRANSPOSE matrix. *
* Note (y,x) becomes (x,y) INTENTIONALLY here! */
theOutput [y] [x]
= determinantOfMinor( x, y, theMatrix ) * oneOverDeterminant;
/* (y0,x1) (y1,x0) (y1,x2) and (y2,x1) all need to be negated. */
if( 1 == ((x + y) % 2) )
theOutput [y] [x] = - theOutput [y] [x];
}
return true;
}
And round it out with a little lower-quality testing code:
void printMatrix( const double theMatrix [/*Y=*/3] [/*X=*/3] )
{
for ( int y = 0; y < 3; y ++ )
{
cout << "[ ";
for ( int x = 0; x < 3; x ++ )
cout << theMatrix [y] [x] << " ";
cout << "]" << endl;
}
cout << endl;
}
void matrixMultiply( const double theMatrixA [/*Y=*/3] [/*X=*/3],
const double theMatrixB [/*Y=*/3] [/*X=*/3],
double theOutput [/*Y=*/3] [/*X=*/3] )
{
for ( int y = 0; y < 3; y ++ )
for ( int x = 0; x < 3; x ++ )
{
theOutput [y] [x] = 0;
for ( int i = 0; i < 3; i ++ )
theOutput [y] [x] += theMatrixA [y] [i] * theMatrixB [i] [x];
}
}
int
main(int argc, char **argv)
{
if ( argc > 1 )
SRANDOM( atoi( argv[1] ) );
double m[3][3] = { { RANDOM_D(0,1e3), RANDOM_D(0,1e3), RANDOM_D(0,1e3) },
{ RANDOM_D(0,1e3), RANDOM_D(0,1e3), RANDOM_D(0,1e3) },
{ RANDOM_D(0,1e3), RANDOM_D(0,1e3), RANDOM_D(0,1e3) } };
double o[3][3], mm[3][3];
if ( argc <= 2 )
cout << fixed << setprecision(3);
printMatrix(m);
cout << endl << endl;
SHOW( determinant(m) );
cout << endl << endl;
BOUT( inverse(m, o) );
printMatrix(m);
printMatrix(o);
cout << endl << endl;
matrixMultiply (m, o, mm );
printMatrix(m);
printMatrix(o);
printMatrix(mm);
cout << endl << endl;
}
Afterthought:
You may also want to detect very large determinants as round-off errors will affect your accuracy!
Don't try to do this yourself if you're serious about getting edge cases right. So while they many naive/simple methods are theoretically exact, they can have nasty numerical behavior for nearly singular matrices. In particular you can get cancelation/round-off errors that cause you to get arbitrarily bad results.
A "correct" way is Gaussian elimination with row and column pivoting so that you're always dividing by the largest remaining numerical value. (This is also stable for NxN matrices.). Note that row pivoting alone doesn't catch all the bad cases.
However IMO implementing this right and fast is not worth your time - use a well tested library and there are a heap of header only ones.
I have just created a QMatrix class. It uses the built in vector > container. QMatrix.h
It uses the Jordan-Gauss method to compute the inverse of a square matrix.
You can use it as follows:
#include "QMatrix.h"
#include <iostream>
int main(){
QMatrix<double> A(3,3,true);
QMatrix<double> Result = A.inverse()*A; //should give the idendity matrix
std::cout<<A.inverse()<<std::endl;
std::cout<<Result<<std::endl; // for checking
return 0;
}
The inverse function is implemented as follows:
Given a class with the following fields:
template<class T> class QMatrix{
public:
int rows, cols;
std::vector<std::vector<T> > A;
the inverse() function:
template<class T>
QMatrix<T> QMatrix<T>:: inverse(){
Identity<T> Id(rows); //the Identity Matrix as a subclass of QMatrix.
QMatrix<T> Result = *this; // making a copy and transforming it to the Identity matrix
T epsilon = 0.000001;
for(int i=0;i<rows;++i){
//check if Result(i,i)==0, if true, switch the row with another
for(int j=i;j<rows;++j){
if(std::abs(Result(j,j))<epsilon) { //uses Overloading()(int int) to extract element from Result Matrix
Result.replace_rows(i,j+1); //switches rows i with j+1
}
else break;
}
// main part, making a triangular matrix
Id(i)=Id(i)*(1.0/Result(i,i));
Result(i)=Result(i)*(1.0/Result(i,i)); // Using overloading ()(int) to get a row form the matrix
for(int j=i+1;j<rows;++j){
T temp = Result(j,i);
Result(j) = Result(j) - Result(i)*temp;
Id(j) = Id(j) - Id(i)*temp; //doing the same operations to the identity matrix
Result(j,i)=0; //not necessary, but looks nicer than 10^-15
}
}
// solving a triangular matrix
for(int i=rows-1;i>0;--i){
for(int j=i-1;j>=0;--j){
T temp = Result(j,i);
Id(j) = Id(j) - temp*Id(i);
Result(j)=Result(j)-temp*Result(i);
}
}
return Id;
}
A rather nice (I think) header file containing macros for most 2x2, 3x3 and 4x4 matrix operations has been available with most OpenGL toolkits. Not as standard but I've seen it at various places.
You can check it out here. At the end of it you will find both inverse of 2x2, 3x3 and 4x4.
vvector.h
I would also recommend Ilmbase, which is part of OpenEXR. It's a good set of templated 2,3,4-vector and matrix routines.
# include <conio.h>
# include<iostream.h>
const int size = 9;
int main()
{
char ch;
do
{
clrscr();
int i, j, x, y, z, det, a[size], b[size];
cout << " **** MATRIX OF 3x3 ORDER ****"
<< endl
<< endl
<< endl;
for (i = 0; i <= size; i++)
a[i]=0;
for (i = 0; i < size; i++)
{
cout << "Enter "
<< i + 1
<< " element of matrix=";
cin >> a[i];
cout << endl
<<endl;
}
clrscr();
cout << "your entered matrix is "
<< endl
<<endl;
for (i = 0; i < size; i += 3)
cout << a[i]
<< " "
<< a[i+1]
<< " "
<< a[i+2]
<< endl
<<endl;
cout << "Transpose of given matrix is"
<< endl
<< endl;
for (i = 0; i < 3; i++)
cout << a[i]
<< " "
<< a[i+3]
<< " "
<< a[i+6]
<< endl
<< endl;
cout << "Determinent of given matrix is = ";
x = a[0] * (a[4] * a[8] -a [5] * a[7]);
y = a[1] * (a[3] * a[8] -a [5] * a[6]);
z = a[2] * (a[3] * a[7] -a [4] * a[6]);
det = x - y + z;
cout << det
<< endl
<< endl
<< endl
<< endl;
if (det == 0)
{
cout << "As Determinent=0 so it is singular matrix and its inverse cannot exist"
<< endl
<< endl;
goto quit;
}
b[0] = a[4] * a[8] - a[5] * a[7];
b[1] = a[5] * a[6] - a[3] * a[8];
b[2] = a[3] * a[7] - a[4] * a[6];
b[3] = a[2] * a[7] - a[1] * a[8];
b[4] = a[0] * a[8] - a[2] * a[6];
b[5] = a[1] * a[6] - a[0] * a[7];
b[6] = a[1] * a[5] - a[2] * a[4];
b[7] = a[2] * a[3] - a[0] * a[5];
b[8] = a[0] * a[4] - a[1] * a[3];
cout << "Adjoint of given matrix is"
<< endl
<< endl;
for (i = 0; i < 3; i++)
{
cout << b[i]
<< " "
<< b[i+3]
<< " "
<< b[i+6]
<< endl
<<endl;
}
cout << endl
<<endl;
cout << "Inverse of given matrix is "
<< endl
<< endl
<< endl;
for (i = 0; i < 3; i++)
{
cout << b[i]
<< "/"
<< det
<< " "
<< b[i+3]
<< "/"
<< det
<< " "
<< b[i+6]
<< "/"
<< det
<< endl
<<endl;
}
quit:
cout << endl
<< endl;
cout << "Do You want to continue this again press (y/yes,n/no)";
cin >> ch;
cout << endl
<< endl;
} /* end do */
while (ch == 'y');
getch ();
return 0;
}
#include <iostream>
using namespace std;
int main()
{
double A11, A12, A13;
double A21, A22, A23;
double A31, A32, A33;
double B11, B12, B13;
double B21, B22, B23;
double B31, B32, B33;
cout << "Enter all number from left to right, from top to bottom, and press enter after every number: ";
cin >> A11;
cin >> A12;
cin >> A13;
cin >> A21;
cin >> A22;
cin >> A23;
cin >> A31;
cin >> A32;
cin >> A33;
B11 = 1 / ((A22 * A33) - (A23 * A32));
B12 = 1 / ((A13 * A32) - (A12 * A33));
B13 = 1 / ((A12 * A23) - (A13 * A22));
B21 = 1 / ((A23 * A31) - (A21 * A33));
B22 = 1 / ((A11 * A33) - (A13 * A31));
B23 = 1 / ((A13 * A21) - (A11 * A23));
B31 = 1 / ((A21 * A32) - (A22 * A31));
B32 = 1 / ((A12 * A31) - (A11 * A32));
B33 = 1 / ((A11 * A22) - (A12 * A21));
cout << B11 << "\t" << B12 << "\t" << B13 << endl;
cout << B21 << "\t" << B22 << "\t" << B23 << endl;
cout << B31 << "\t" << B32 << "\t" << B33 << endl;
return 0;
}
//Title: Matrix Header File
//Writer: Say OL
//This is a beginner code not an expert one
//No responsibilty for any errors
//Use for your own risk
using namespace std;
int row,col,Row,Col;
double Coefficient;
//Input Matrix
void Input(double Matrix[9][9],int Row,int Col)
{
for(row=1;row<=Row;row++)
for(col=1;col<=Col;col++)
{
cout<<"e["<<row<<"]["<<col<<"]=";
cin>>Matrix[row][col];
}
}
//Output Matrix
void Output(double Matrix[9][9],int Row,int Col)
{
for(row=1;row<=Row;row++)
{
for(col=1;col<=Col;col++)
cout<<Matrix[row][col]<<"\t";
cout<<endl;
}
}
//Copy Pointer to Matrix
void CopyPointer(double (*Pointer)[9],double Matrix[9][9],int Row,int Col)
{
for(row=1;row<=Row;row++)
for(col=1;col<=Col;col++)
Matrix[row][col]=Pointer[row][col];
}
//Copy Matrix to Matrix
void CopyMatrix(double MatrixInput[9][9],double MatrixTarget[9][9],int Row,int Col)
{
for(row=1;row<=Row;row++)
for(col=1;col<=Col;col++)
MatrixTarget[row][col]=MatrixInput[row][col];
}
//Transpose of Matrix
double MatrixTran[9][9];
double (*(Transpose)(double MatrixInput[9][9],int Row,int Col))[9]
{
for(row=1;row<=Row;row++)
for(col=1;col<=Col;col++)
MatrixTran[col][row]=MatrixInput[row][col];
return MatrixTran;
}
//Matrix Addition
double MatrixAdd[9][9];
double (*(Addition)(double MatrixA[9][9],double MatrixB[9][9],int Row,int Col))[9]
{
for(row=1;row<=Row;row++)
for(col=1;col<=Col;col++)
MatrixAdd[row][col]=MatrixA[row][col]+MatrixB[row][col];
return MatrixAdd;
}
//Matrix Subtraction
double MatrixSub[9][9];
double (*(Subtraction)(double MatrixA[9][9],double MatrixB[9][9],int Row,int Col))[9]
{
for(row=1;row<=Row;row++)
for(col=1;col<=Col;col++)
MatrixSub[row][col]=MatrixA[row][col]-MatrixB[row][col];
return MatrixSub;
}
//Matrix Multiplication
int mRow,nCol,pCol,kcol;
double MatrixMult[9][9];
double (*(Multiplication)(double MatrixA[9][9],double MatrixB[9][9],int mRow,int nCol,int pCol))[9]
{
for(row=1;row<=mRow;row++)
for(col=1;col<=pCol;col++)
{
MatrixMult[row][col]=0.0;
for(kcol=1;kcol<=nCol;kcol++)
MatrixMult[row][col]+=MatrixA[row][kcol]*MatrixB[kcol][col];
}
return MatrixMult;
}
//Interchange Two Rows
double RowTemp[9][9];
double MatrixInter[9][9];
double (*(InterchangeRow)(double MatrixInput[9][9],int Row,int Col,int iRow,int jRow))[9]
{
CopyMatrix(MatrixInput,MatrixInter,Row,Col);
for(col=1;col<=Col;col++)
{
RowTemp[iRow][col]=MatrixInter[iRow][col];
MatrixInter[iRow][col]=MatrixInter[jRow][col];
MatrixInter[jRow][col]=RowTemp[iRow][col];
}
return MatrixInter;
}
//Pivote Downward
double MatrixDown[9][9];
double (*(PivoteDown)(double MatrixInput[9][9],int Row,int Col,int tRow,int tCol))[9]
{
CopyMatrix(MatrixInput,MatrixDown,Row,Col);
Coefficient=MatrixDown[tRow][tCol];
if(Coefficient!=1.0)
for(col=1;col<=Col;col++)
MatrixDown[tRow][col]/=Coefficient;
if(tRow<Row)
for(row=tRow+1;row<=Row;row++)
{
Coefficient=MatrixDown[row][tCol];
for(col=1;col<=Col;col++)
MatrixDown[row][col]-=Coefficient*MatrixDown[tRow][col];
}
return MatrixDown;
}
//Pivote Upward
double MatrixUp[9][9];
double (*(PivoteUp)(double MatrixInput[9][9],int Row,int Col,int tRow,int tCol))[9]
{
CopyMatrix(MatrixInput,MatrixUp,Row,Col);
Coefficient=MatrixUp[tRow][tCol];
if(Coefficient!=1.0)
for(col=1;col<=Col;col++)
MatrixUp[tRow][col]/=Coefficient;
if(tRow>1)
for(row=tRow-1;row>=1;row--)
{
Coefficient=MatrixUp[row][tCol];
for(col=1;col<=Col;col++)
MatrixUp[row][col]-=Coefficient*MatrixUp[tRow][col];
}
return MatrixUp;
}
//Pivote in Determinant
double MatrixPiv[9][9];
double (*(Pivote)(double MatrixInput[9][9],int Dim,int pTarget))[9]
{
CopyMatrix(MatrixInput,MatrixPiv,Dim,Dim);
for(row=pTarget+1;row<=Dim;row++)
{
Coefficient=MatrixPiv[row][pTarget]/MatrixPiv[pTarget][pTarget];
for(col=1;col<=Dim;col++)
{
MatrixPiv[row][col]-=Coefficient*MatrixPiv[pTarget][col];
}
}
return MatrixPiv;
}
//Determinant of Square Matrix
int dCounter,dRow;
double Det;
double MatrixDet[9][9];
double Determinant(double MatrixInput[9][9],int Dim)
{
CopyMatrix(MatrixInput,MatrixDet,Dim,Dim);
Det=1.0;
if(Dim>1)
{
for(dRow=1;dRow<Dim;dRow++)
{
dCounter=dRow;
while((MatrixDet[dRow][dRow]==0.0)&(dCounter<=Dim))
{
dCounter++;
Det*=-1.0;
CopyPointer(InterchangeRow(MatrixDet,Dim,Dim,dRow,dCounter),MatrixDet,Dim,Dim);
}
if(MatrixDet[dRow][dRow]==0)
{
Det=0.0;
break;
}
else
{
Det*=MatrixDet[dRow][dRow];
CopyPointer(Pivote(MatrixDet,Dim,dRow),MatrixDet,Dim,Dim);
}
}
Det*=MatrixDet[Dim][Dim];
}
else Det=MatrixDet[1][1];
return Det;
}
//Matrix Identity
double MatrixIdent[9][9];
double (*(Identity)(int Dim))[9]
{
for(row=1;row<=Dim;row++)
for(col=1;col<=Dim;col++)
if(row==col)
MatrixIdent[row][col]=1.0;
else
MatrixIdent[row][col]=0.0;
return MatrixIdent;
}
//Join Matrix to be Augmented Matrix
double MatrixJoin[9][9];
double (*(JoinMatrix)(double MatrixA[9][9],double MatrixB[9][9],int Row,int ColA,int ColB))[9]
{
Col=ColA+ColB;
for(row=1;row<=Row;row++)
for(col=1;col<=Col;col++)
if(col<=ColA)
MatrixJoin[row][col]=MatrixA[row][col];
else
MatrixJoin[row][col]=MatrixB[row][col-ColA];
return MatrixJoin;
}
//Inverse of Matrix
double (*Pointer)[9];
double IdentMatrix[9][9];
int Counter;
double MatrixAug[9][9];
double MatrixInv[9][9];
double (*(Inverse)(double MatrixInput[9][9],int Dim))[9]
{
Row=Dim;
Col=Dim+Dim;
Pointer=Identity(Dim);
CopyPointer(Pointer,IdentMatrix,Dim,Dim);
Pointer=JoinMatrix(MatrixInput,IdentMatrix,Dim,Dim,Dim);
CopyPointer(Pointer,MatrixAug,Row,Col);
for(Counter=1;Counter<=Dim;Counter++)
{
Pointer=PivoteDown(MatrixAug,Row,Col,Counter,Counter);
CopyPointer(Pointer,MatrixAug,Row,Col);
}
for(Counter=Dim;Counter>1;Counter--)
{
Pointer=PivoteUp(MatrixAug,Row,Col,Counter,Counter);
CopyPointer(Pointer,MatrixAug,Row,Col);
}
for(row=1;row<=Dim;row++)
for(col=1;col<=Dim;col++)
MatrixInv[row][col]=MatrixAug[row][col+Dim];
return MatrixInv;
}
//Gauss-Jordan Elemination
double MatrixGJ[9][9];
double VectorGJ[9][9];
double (*(GaussJordan)(double MatrixInput[9][9],double VectorInput[9][9],int Dim))[9]
{
Row=Dim;
Col=Dim+1;
Pointer=JoinMatrix(MatrixInput,VectorInput,Dim,Dim,1);
CopyPointer(Pointer,MatrixGJ,Row,Col);
for(Counter=1;Counter<=Dim;Counter++)
{
Pointer=PivoteDown(MatrixGJ,Row,Col,Counter,Counter);
CopyPointer(Pointer,MatrixGJ,Row,Col);
}
for(Counter=Dim;Counter>1;Counter--)
{
Pointer=PivoteUp(MatrixGJ,Row,Col,Counter,Counter);
CopyPointer(Pointer,MatrixGJ,Row,Col);
}
for(row=1;row<=Dim;row++)
for(col=1;col<=1;col++)
VectorGJ[row][col]=MatrixGJ[row][col+Dim];
return VectorGJ;
}
//Generalized Gauss-Jordan Elemination
double MatrixGGJ[9][9];
double VectorGGJ[9][9];
double (*(GeneralizedGaussJordan)(double MatrixInput[9][9],double VectorInput[9][9],int Dim,int vCol))[9]
{
Row=Dim;
Col=Dim+vCol;
Pointer=JoinMatrix(MatrixInput,VectorInput,Dim,Dim,vCol);
CopyPointer(Pointer,MatrixGGJ,Row,Col);
for(Counter=1;Counter<=Dim;Counter++)
{
Pointer=PivoteDown(MatrixGGJ,Row,Col,Counter,Counter);
CopyPointer(Pointer,MatrixGGJ,Row,Col);
}
for(Counter=Dim;Counter>1;Counter--)
{
Pointer=PivoteUp(MatrixGGJ,Row,Col,Counter,Counter);
CopyPointer(Pointer,MatrixGGJ,Row,Col);
}
for(row=1;row<=Row;row++)
for(col=1;col<=vCol;col++)
VectorGGJ[row][col]=MatrixGGJ[row][col+Dim];
return VectorGGJ;
}
//Matrix Sparse, Three Diagonal Non-Zero Elements
double MatrixSpa[9][9];
double (*(Sparse)(int Dimension,double FirstElement,double SecondElement,double ThirdElement))[9]
{
MatrixSpa[1][1]=SecondElement;
MatrixSpa[1][2]=ThirdElement;
MatrixSpa[Dimension][Dimension-1]=FirstElement;
MatrixSpa[Dimension][Dimension]=SecondElement;
for(int Counter=2;Counter<Dimension;Counter++)
{
MatrixSpa[Counter][Counter-1]=FirstElement;
MatrixSpa[Counter][Counter]=SecondElement;
MatrixSpa[Counter][Counter+1]=ThirdElement;
}
return MatrixSpa;
}
Copy and save the above code as Matrix.h then try the following code:
#include<iostream>
#include<conio.h>
#include"Matrix.h"
int Dim;
double Matrix[9][9];
int main()
{
cout<<"Enter your matrix dimension: ";
cin>>Dim;
Input(Matrix,Dim,Dim);
cout<<"Your matrix:"<<endl;
Output(Matrix,Dim,Dim);
cout<<"The inverse:"<<endl;
Output(Inverse(Matrix,Dim),Dim,Dim);
getch();
}
//Function for inverse of the input square matrix 'J' of dimension 'dim':
vector<vector<double > > inverseVec33(vector<vector<double > > J, int dim)
{
//Matrix of Minors
vector<vector<double > > invJ(dim,vector<double > (dim));
for(int i=0; i<dim; i++)
{
for(int j=0; j<dim; j++)
{
invJ[i][j] = (J[(i+1)%dim][(j+1)%dim]*J[(i+2)%dim][(j+2)%dim] -
J[(i+2)%dim][(j+1)%dim]*J[(i+1)%dim][(j+2)%dim]);
}
}
//determinant of the matrix:
double detJ = 0.0;
for(int j=0; j<dim; j++)
{ detJ += J[0][j]*invJ[0][j];}
//Inverse of the given matrix.
vector<vector<double > > invJT(dim,vector<double > (dim));
for(int i=0; i<dim; i++)
{
for(int j=0; j<dim; j++)
{
invJT[i][j] = invJ[j][i]/detJ;
}
}
return invJT;
}
void main()
{
//given matrix:
vector<vector<double > > Jac(3,vector<double > (3));
Jac[0][0] = 1; Jac[0][1] = 2; Jac[0][2] = 6;
Jac[1][0] = -3; Jac[1][1] = 4; Jac[1][2] = 3;
Jac[2][0] = 5; Jac[2][1] = 1; Jac[2][2] = -4;`
//Inverse of the matrix Jac:
vector<vector<double > > JacI(3,vector<double > (3));
//call function and store inverse of J as JacI:
JacI = inverseVec33(Jac,3);
}