0

I am trying to simulate Markov chain transitions by multiplying a 2x2 matrix (the transition matrix) by a 2x1 matrix in C++, and then taking that output as a 2x1 matrix and then using it again in a multiplication, repeated again up to a set number of times.

#include <iostream>

using namespace std;

int main(void){

// initialize variables
float trMat1,trMat2,trMat3,trMat4,iniA,iniB;
int cycle;

// initialize transition matrix
trMat1 = 0.883; // top left
trMat2 = 0.259; // top right
trMat3 = 0.117; // bottom left
trMat4 = 0.741; // bottom right

    cout << "Enter the product preference for A: ";
    cin >> iniA;

    cout << "Enter the product preference for B: ";
    cin >> iniB;

    if(iniA + iniB != 1){
        cout << "ERROR: Probabilities do not add to 1. Terminating" << endl;
        return 0;
    }

    cout << "Enter number of cycles to simulate: ";
    cin >> cycle;

    cout << "Simulating... " << endl;

    // matrix multiplication starts
    for(int z = 0; z < cycle; z++){
        iniA = trMat1 * iniA + trMat2 * iniB;
        iniB = trMat3 * iniA + trMat4 * iniB;
    }
    
    cout << "A (end): ";
    cout << iniA << endl;

    cout << "B (end): ";
    cout << iniB << endl;

}

Since these are probabilities, iniA and iniB are meant to add to exactly 1, but they never do (always a little over or under 1 but never exactly). Could this be due to a rounding error or perhaps something else? Thank you.

rwbc1601
  • 15
  • 4
  • none of the values 0.883, 0.259, 0.117, 0.741 are representable in binary floating-point types, so obviously any operations on them will never give the exact result – phuclv Nov 21 '20 at 08:36
  • I think I understand, thank you! Sorry, I am very new at programming, so from what I understand, because these numbers can't be represented exactly, the final values won't be exact either? And is there any way to resolve this, for example if I rounded the values for 0.883, 0.259, 0.117, 0.741 or made them fractions? – rwbc1601 Nov 21 '20 at 08:42
  • In addition to the rounding issue, note that the implementation of the matrix multiplication is not correct. For `iniB` calculation, the input value of `iniA` must be used, not the newly calculated one. Use a temporary value `temp = iniA;` – Damien Nov 21 '20 at 10:22
  • It works! Using the temporary value makes it add to exactly 1. Thank you! – rwbc1601 Nov 23 '20 at 04:26

0 Answers0