Tuesday, December 19, 2023

Hilbert Matrix 20x20 LDLT decomposition

 The following is LDLT decomposition of 20x20 Hilbert Matrix A.


It seems Firefox render this page correctly.

Hilbert Matrix H=[ 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 39 ]

L=[ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 4 9 10 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 5 4 5 12 7 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 6 5 7 25 14 25 9 5 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 7 9 14 25 14 10 3 45 11 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 8 7 12 7 4 245 66 245 44 147 26 7 2 1 0 0 0 0 0 0 0 0 0 0 0 0 1 9 8 15 56 33 392 99 980 143 112 13 112 15 4 1 0 0 0 0 0 0 0 0 0 0 0 1 10 27 55 18 11 588 143 1134 143 756 65 63 5 162 17 9 2 1 0 0 0 0 0 0 0 0 0 0 1 11 5 11 225 143 600 143 1260 143 189 13 315 17 300 17 225 19 5 1 0 0 0 0 0 0 0 0 0 1 12 11 26 275 182 55 13 495 52 7623 442 847 34 9075 323 1815 76 605 42 11 2 1 0 0 0 0 0 0 0 0 1 13 36 91 132 91 55 13 4455 442 4356 221 10164 323 13068 323 5445 133 220 7 396 23 6 1 0 0 0 0 0 0 0 1 14 13 35 39 28 143 34 715 68 14157 646 61347 1615 122694 2261 16731 266 9295 161 1859 46 507 25 13 2 1 0 0 0 0 0 0 1 15 7 20 91 68 637 153 7007 646 77077 3230 143143 3230 22308 323 39039 437 13013 138 91091 1150 1274 25 637 27 7 1 0 0 0 0 0 1 16 45 136 175 136 15925 3876 28665 2584 33033 1292 65065 1292 1254825 14858 418275 3496 13013 92 63063 460 637 6 2275 36 1575 58 15 2 1 0 0 0 0 1 17 16 51 400 323 3920 969 3640 323 8736 323 416416 7429 743600 7429 66924 437 4576 23 224224 1035 2912 15 36400 261 2240 29 960 31 8 1 0 0 0 1 18 17 57 68 57 680 171 2380 209 12376 437 80444 1311 252824 2185 82654 437 165308 621 330616 1035 420784 1305 210392 783 161840 899 2890 31 1156 33 17 2 1 0 0 1 19 27 95 153 133 816 209 55080 4807 12852 437 723996 10925 286416 2185 495924 2185 165308 483 1487772 3335 360672 725 420784 899 327726 899 78030 341 1224 11 1377 35 9 1 0 1 20 19 70 171 154 969 253 2907 253 17442 575 40698 575 16796 115 214149 805 29838094 70035 29838094 50025 16275324 22475 1356277 1798 6572727 9889 165699 341 110466 385 18411 140 3249 74 19 2 1 ]

D=[ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 180 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2800 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 44100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 698544 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 11099088 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 176679360 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2815827300 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 44914183600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 716830370256 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 11445589052352 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 182811491808400 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2920656969720000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 46670906271240000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 745904795339462400 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 11922821963004219300 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 190600129650794094000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3047248986392325330000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 48722219250572027160000 ]

Hilbert Matrix H= L D L T

Sunday, December 10, 2023

Move constructor and emplace_back for std::vector performance improvement (Native C++)

Performance improvement with move constructor and emplace_back against copy constructor and push_back is very visible: See below program output.

There are many pitfalls in move constructors. Please read the textbook before utilizing it.

BTW, this is just demonstration purpose for the pointer member to contain only one int value. In this particular case, replacing int *p with int  v improves the performance much more,

C++ Program

#include <iostream>
#include <vector>
#include <stdio.h>
#include <map>
using namespace std;

static int PtrToId(const void* p) {
    static int id = 400;
    static map<const void*, int> ptrIdMap;
    auto found = ptrIdMap.find(p);
    if (found != ptrIdMap.end()) {
        return found->second;
    }
    
    ptrIdMap[p] = id;
    id += 8;

    return ptrIdMap[p];
}

class A {
public:
    int *p = nullptr;
    static int newCounter;

    A(void) {
        p = new int;
        ++newCounter;
        *p = 0;
        cout << "Ctor  new this=" << PtrToId(this) << ", p=" << PtrToId(p) << endl;
    }

    A(int d) {
        p = new int;
        ++newCounter;
        *p = d;
        cout << "Ctor(int) this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
    }

    A(const A& rhs) {
        p = new int;
        ++newCounter;
        *p = *(rhs.p);
        cout << "Copy ctor this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
    }

    ~A(void) {
        cout << "Dtor  del this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
        delete p;
        p = nullptr;
    }
};
int A::newCounter = 0;

class B {
public:
    int *p = nullptr;
    static int newCounter;

    B(void) {
        p = new int;
        ++newCounter;
        *p = 0;
        cout << "Ctor  new this=" << PtrToId(this) << ", p=" << PtrToId(p) << endl;
    }

    B(int d) {
        p = new int;
        ++newCounter;
        *p = d;
        cout << "Ctor(int) this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
    };

    B(const B& rhs) {
        p = new int;
        ++newCounter;
        *p = *(rhs.p);
        cout << "Copy ctor this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << ", &rhs=" << PtrToId(&rhs) << endl;
    }

    B(B&& rhs) noexcept {
        p = rhs.p;
        rhs.p = nullptr;

        cout << "Move ctor this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << ", &rhs=" << PtrToId(&rhs) << endl;
    }

    ~B(void) {
        if (p) {
            cout << "Dtor  del this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
            delete p;
            p = nullptr;
        } else {
            cout << "Dtor      this=" << PtrToId(this) << ", p=nullptr" << endl;
        }
    }
};
int B::newCounter = 0;

template <typename T>
static void Print(vector<T> &v, const char* name)
{
    for (int i = 0; i < v.size(); ++i) {
        printf(" &(%s[%d])=%d, p=%d, *p=%d\n", name, i, PtrToId(&(v[i])), PtrToId(v[i].p), *(v[i].p));
    }
}

int main(void)
{
    {
        printf("vA/push_back Begin\n");
        vector<A> vA;

        printf("push_back(10)\n");
        vA.push_back(10);
        Print(vA, "vA");

        printf("\npush_back(20)\n");
        vA.push_back(20);
        Print(vA, "vA");

        printf("\npush_back(30)\n");
        vA.push_back(30);
        Print(vA, "vA");

        printf("\nvA/push_back end\n");
    }
    printf("new int is called %d times.\n", A::newCounter);
    A::newCounter = 0;

    {
        printf("\nvA/emplace_back Begin\n");
        vector<A> vA;

        printf("emplace_back(10)\n");
        vA.emplace_back(10);
        Print(vA, "vA");

        printf("\nemplace_back(20)\n");
        vA.emplace_back(20);
        Print(vA, "vA");

        printf("\nemplace_back(30)\n");
        vA.emplace_back(30);
        Print(vA, "vA");

        printf("\nvA/emplace_back end\n");
    }
    printf("new int is called %d times.\n", A::newCounter);

    {
        printf("\nvB/push_back begin\n");
        vector<B> vB;

        printf("push_back(10)\n");
        vB.push_back(10);
        Print(vB, "vB");

        printf("\npush_back(20)\n");
        vB.push_back(20);
        Print(vB, "vB");

        printf("\npush_back(30)\n");
        vB.push_back(30);
        Print(vB, "vB");

        printf("\nvB/push_back end\n");
    }
    printf("new int is called %d times.\n", B::newCounter);

    B::newCounter = 0;
    {
        printf("\nvB/emplace_back begin\n");
        vector<B> vB;

        printf("emplace_back(10)\n");
        vB.emplace_back(10);
        Print(vB, "vB");

        printf("\emplace_back(20)\n");
        vB.emplace_back(20);
        Print(vB, "vB");

        printf("\emplace_back(30)\n");
        vB.emplace_back(30);
        Print(vB, "vB");

        printf("\nvB/emplace_back end\n");
    }
    printf("new int is called %d times.\n", B::newCounter);

    return 0;
}





 

Program Output

vA/push_back Begin
push_back(10)
Ctor(int) this=408, p=400, *p=10
Copy ctor this=424, p=416, *p=10
Dtor  del this=408, p=400, *p=10
 &(vA[0])=424, p=416, *p=10

push_back(20)
Ctor(int) this=440, p=432, *p=20
Copy ctor this=456, p=448, *p=20
Copy ctor this=472, p=464, *p=10
Dtor  del this=424, p=416, *p=10
Dtor  del this=440, p=432, *p=20
 &(vA[0])=472, p=464, *p=10
 &(vA[1])=456, p=448, *p=20

push_back(30)
Ctor(int) this=488, p=480, *p=30
Copy ctor this=496, p=416, *p=30
Copy ctor this=512, p=504, *p=10
Copy ctor this=528, p=520, *p=20
Dtor  del this=472, p=464, *p=10
Dtor  del this=456, p=448, *p=20
Dtor  del this=488, p=480, *p=30
 &(vA[0])=512, p=504, *p=10
 &(vA[1])=528, p=520, *p=20
 &(vA[2])=496, p=416, *p=30

vA/push_back end
Dtor  del this=512, p=504, *p=10
Dtor  del this=528, p=520, *p=20
Dtor  del this=496, p=416, *p=30
new int is called 9 times.

vA/emplace_back Begin
emplace_back(10)
Ctor(int) this=472, p=480, *p=10
 &(vA[0])=472, p=480, *p=10

emplace_back(20)
Ctor(int) this=544, p=536, *p=20
Copy ctor this=560, p=552, *p=10
Dtor  del this=472, p=480, *p=10
 &(vA[0])=560, p=552, *p=10
 &(vA[1])=544, p=536, *p=20

emplace_back(30)
Ctor(int) this=576, p=568, *p=30
Copy ctor this=592, p=584, *p=10
Copy ctor this=608, p=600, *p=20
Dtor  del this=560, p=552, *p=10
Dtor  del this=544, p=536, *p=20
 &(vA[0])=592, p=584, *p=10
 &(vA[1])=608, p=600, *p=20
 &(vA[2])=576, p=568, *p=30

vA/emplace_back end
Dtor  del this=592, p=584, *p=10
Dtor  del this=608, p=600, *p=20
Dtor  del this=576, p=568, *p=30
new int is called 6 times.

vB/push_back begin
push_back(10)
Ctor(int) this=624, p=616, *p=10
Move ctor this=632, p=616, *p=10, &rhs=624
Dtor      this=624, p=nullptr
 &(vB[0])=632, p=616, *p=10

push_back(20)
Ctor(int) this=648, p=640, *p=20
Move ctor this=656, p=640, *p=20, &rhs=648
Move ctor this=664, p=616, *p=10, &rhs=632
Dtor      this=632, p=nullptr
Dtor      this=648, p=nullptr
 &(vB[0])=664, p=616, *p=10
 &(vB[1])=656, p=640, *p=20

push_back(30)
Ctor(int) this=680, p=672, *p=30
Move ctor this=688, p=672, *p=30, &rhs=680
Move ctor this=696, p=616, *p=10, &rhs=664
Move ctor this=704, p=640, *p=20, &rhs=656
Dtor      this=664, p=nullptr
Dtor      this=656, p=nullptr
Dtor      this=680, p=nullptr
 &(vB[0])=696, p=616, *p=10
 &(vB[1])=704, p=640, *p=20
 &(vB[2])=688, p=672, *p=30

vB/push_back end
Dtor  del this=696, p=616, *p=10
Dtor  del this=704, p=640, *p=20
Dtor  del this=688, p=672, *p=30
new int is called 3 times.

vB/emplace_back begin
emplace_back(10)
Ctor(int) this=712, p=552, *p=10
 &(vB[0])=712, p=552, *p=10
emplace_back(20)
Ctor(int) this=728, p=720, *p=20
Move ctor this=632, p=552, *p=10, &rhs=712
Dtor      this=712, p=nullptr
 &(vB[0])=632, p=552, *p=10
 &(vB[1])=728, p=720, *p=20
emplace_back(30)
Ctor(int) this=576, p=448, *p=30
Move ctor this=592, p=552, *p=10, &rhs=632
Move ctor this=608, p=720, *p=20, &rhs=728
Dtor      this=632, p=nullptr
Dtor      this=728, p=nullptr
 &(vB[0])=592, p=552, *p=10
 &(vB[1])=608, p=720, *p=20
 &(vB[2])=576, p=448, *p=30

vB/emplace_back end
Dtor  del this=592, p=552, *p=10
Dtor  del this=608, p=720, *p=20
Dtor  del this=576, p=448, *p=30
new int is called 3 times.