Math Problems 1

Problem 1

what is the area of the rectangle?
the minimum area of the triangle satisfied these conditions?

part 1

so the area of a rectangle is

xy=12

part 2

Problem 2

find the radius of biggest circuit

take first two circuits
hypotenuse of both are collinear

Problem 3

a cable of 80 meters hanging from the top of two poles there are two 50 meters from the ground
what is the distance from two poles if center of cable 20 meters above the ground ?

Problem 4

find the area of the red segments

C++ Useful Libraries

random standard c++ library

#include<random>
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(1,6);
int dice_roll = distribution(generator);  //between [1,6]
#include<random>
std::default_random_engine generator;
std::uniform_real_distribution<double> distribution(0.0,2.0);
double random = distribution(generator);//between [0.0,2.0)

simd library( single instruction multiple data)

C++ wrappers for SIMD intrinsics and parallelized, optimized mathematical functions (SSE, AVX, NEON, AVX512)

#include <iostream>
#include "xsimd/xsimd.hpp"

namespace xs = xsimd;

int main(int argc, char* argv[])
{
    xs::batch<double, xs::avx2> a(1.5, 2.5, 3.5, 4.5);
    xs::batch<double, xs::avx2> b(2.5, 3.5, 4.5, 5.5);
    auto mean = (a + b) / 2;
    std::cout << mean << std::endl;
    return 0;
}
#include <cstddef>
#include <vector>
#include "xsimd/xsimd.hpp"

namespace xs = xsimd;
using vector_type = std::vector<double, xsimd::aligned_allocator<double>>;

void mean(const vector_type& a, const vector_type& b, vector_type& res)
{
    std::size_t size = a.size();
    constexpr std::size_t simd_size = xsimd::simd_type<double>::size;
    std::size_t vec_size = size - size % simd_size;

    for(std::size_t i = 0; i < vec_size; i += simd_size)
    {
        auto ba = xs::load_aligned(&a[i]);
        auto bb = xs::load_aligned(&b[i]);
        auto bres = (ba + bb) / 2.;
        bres.store_aligned(&res[i]);
    }
    for(std::size_t i = vec_size; i < size; ++i)
    {
        res[i] = (a[i] + b[i]) / 2.;
    }
}
#include <cstddef>
#include <vector>
#include "xsimd/xsimd.hpp"
#include "xsimd/stl/algorithms.hpp"

namespace xs = xsimd;
using vector_type = std::vector<double, xsimd::aligned_allocator<double>>;

void mean(const vector_type& a, const vector_type& b, vector_type& res)
{
    xsimd::transform(a.begin(), a.end(), b.begin(), res.begin(),
                     [](const auto& x, const auto& y) { (x + y) / 2.; });
}

dlfcn Lybrary

Tree Traversals

Depth-First Search and Breadth-First Search

class Node{
    int value;
    Node *parent;
    std::vector<Node*> childs;
public:
    Node(int v):value(v){

    }
    void AppendChild(Node* n){
        n->parent=this;
        childs.push_back(n);
    }
    void RemoveChild(Node* n){
        n->parent=nullptr;
        this->childs.erase(std::find(childs.begin(),childs.end(),n));
    }
    void AppendChilds(std::initializer_list<Node*> childs){
        for(Node* n:childs)
            this->AppendChild(n);
    }
    std::vector<Node*> GetChildren(){
        return childs;
    }
    Node* GetParent(){
        return parent;
    }
    Node* GetRoot(){
        Node* root=this;
        while(root->GetParent())
            root=parent->GetParent();
        return root;
    }
    operator int(){
        return value;
    }
};

void DFS(Node* root){
    qDebug()<<*root;
    std::vector<Node*> nodes=root->GetChildren();
    for(Node* n:nodes)
        DFS(n);
}

void BFS(Node* root){
    std::queue<Node*> nodes;
    nodes.push(root);
    while(nodes.size()>0){
        Node* current=nodes.front();
        nodes.pop();
        qDebug()<<*current;
        for(Node* n : current->GetChildren())
            nodes.push(n);
    }
}

int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);
    Node n1=1,n2=2,n3=3,n4=4,n5=5,n6=6,n7=7,n8=8,n9=9,n10=10,n11=11,n12=12,n13=13,n14=14,n15=15,n16=16,n17=17,n18=18,n19=19;
    n1.AppendChilds({&n2,&n3});
    n2.AppendChilds({&n4,&n5});
    n3.AppendChilds({&n6,&n7});
    n4.AppendChilds({&n8,&n9});
    n5.AppendChilds({&n10,&n11});
    n6.AppendChilds({&n12,&n13});
    n7.AppendChilds({&n14,&n15});
    n8.AppendChilds({&n16,&n17});
    n9.AppendChilds({&n18,&n19});
    BFS(&n1);

    return a.exec();
}

Binary Tree Traversals

struct Node {
    int data;
    struct Node *left, *right;
    Node(int data)
    {
        this->data = data;
        left = right = NULL;
    }
};
 
/* Given a binary tree, print its nodes according to the
"bottom-up" postorder traversal. */
void printPostorder(struct Node* node)
{
    if (node == NULL)
        return;
 
    // first recur on left subtree
    printPostorder(node->left);
 
    // then recur on right subtree
    printPostorder(node->right);
 
    // now deal with the node
    cout << node->data << " ";
}
 
/* Given a binary tree, print its nodes in inorder*/
void printInorder(struct Node* node)
{
    if (node == NULL)
        return;
 
    /* first recur on left child */
    printInorder(node->left);
 
    /* then print the data of node */
    cout << node->data << " ";
 
    /* now recur on right child */
    printInorder(node->right);
}
 
/* Given a binary tree, print its nodes in preorder*/
void printPreorder(struct Node* node)
{
    if (node == NULL)
        return;
 
    /* first print data of node */
    cout << node->data << " ";
 
    /* then recur on left sutree */
    printPreorder(node->left);
 
    /* now recur on right subtree */
    printPreorder(node->right);
}
 
/* Driver program to test above functions*/
int main()
{
    struct Node* root = new Node(1);
    root->left = new Node(2);
    root->right = new Node(3);
    root->left->left = new Node(4);
    root->left->right = new Node(5);
 
    cout << "\nPreorder traversal of binary tree is \n";
    printPreorder(root);
 
    cout << "\nInorder traversal of binary tree is \n";
    printInorder(root);
 
    cout << "\nPostorder traversal of binary tree is \n";
    printPostorder(root);
 
    return 0;
}

Arithmetic Expression Tree

after that we can calculate the tree by postfix or post-order

Sorting Algorithms

 it is sometimes useful to know if a sorting algorithm is stable
A sorting algorithm is stable if it preserves the original order of elements with equal key values (where the key is the value the algorithm sorts by). For example,

Bubble Sort

Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in wrong order.
Example:


First Pass: 
( 5 1 4 2 8 ) –> ( 1 5 4 2 8 ), Here, algorithm compares the first two elements, and swaps since 5 > 1. 
( 1 5 4 2 8 ) –>  ( 1 4 5 2 8 ), Swap since 5 > 4 
( 1 4 5 2 8 ) –>  ( 1 4 2 5 8 ), Swap since 5 > 2 
( 1 4 2 5 8 ) –> ( 1 4 2 5 8 ), Now, since these elements are already in order (8 > 5), algorithm does not swap them.
Second Pass: 
( 1 4 2 5 8 ) –> ( 1 4 2 5 8 ) 
( 1 4 2 5 8 ) –> ( 1 2 4 5 8 ), Swap since 4 > 2 
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 ) 
( 1 2 4 5 8 ) –>  ( 1 2 4 5 8 ) 
Now, the array is already sorted, but our algorithm does not know if it is completed. The algorithm needs one whole pass without any swap to know it is sorted.
Third Pass: 
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 ) 
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 ) 
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 ) 
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 ) 
template<class T>
void Swap(T* p1,T* p2){
    T p3=*p1;
    *p1=*p2;
    *p2=p3;
    return;
}

template<typename T ,int size>
void BubbleSort(T (&t)[size]){
    for(int i=1;i<size;i++){
        for(int ii=0;ii<size-i;ii++){
            if(t[ii]>t[ii+1])
                Swap(t+(ii+1),t+(ii));
        }
    }
}

Insertion Sort

void insertionSort(int arr[], int n)
{
    int i, key, j;
    for (i = 1; i < n; i++)
    {
        key = arr[i];
        j = i - 1;
        while (j >= 0 && arr[j] > key)
        {
            arr[j + 1] = arr[j];
            j = j - 1;
        }
        arr[j + 1] = key;
    }
}

Merge Sort

void merge(int array[], int const left, int const mid, int const right)
{
    auto const subArrayOne = mid - left + 1;
    auto const subArrayTwo = right - mid;

    auto *leftArray = new int[subArrayOne],
         *rightArray = new int[subArrayTwo];

    for (auto i = 0; i < subArrayOne; i++)
        leftArray[i] = array[left + i];
    for (auto j = 0; j < subArrayTwo; j++)
        rightArray[j] = array[mid + 1 + j];
 
    auto indexOfSubArrayOne = 0, 
        indexOfSubArrayTwo = 0; 
    int indexOfMergedArray = left; 
 
    while (indexOfSubArrayOne < subArrayOne && indexOfSubArrayTwo < subArrayTwo) {
        if (leftArray[indexOfSubArrayOne] <= rightArray[indexOfSubArrayTwo]) {
            array[indexOfMergedArray] = leftArray[indexOfSubArrayOne];
            indexOfSubArrayOne++;
        }
        else {
            array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo];
            indexOfSubArrayTwo++;
        }
        indexOfMergedArray++;
    }

    while (indexOfSubArrayOne < subArrayOne) {
        array[indexOfMergedArray] = leftArray[indexOfSubArrayOne];
        indexOfSubArrayOne++;
        indexOfMergedArray++;
    }

    while (indexOfSubArrayTwo < subArrayTwo) {
        array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo];
        indexOfSubArrayTwo++;
        indexOfMergedArray++;
    }
}

void mergeSort(int array[], int const begin, int const end)
{
    if (begin >= end)
        return; 
    auto mid = begin + (end - begin) / 2;
    mergeSort(array, begin, mid);
    mergeSort(array, mid + 1, end);
    merge(array, begin, mid, end);
}

Quick Sort

The key process in quickSort is partition(). Target of partitions is, given an array and an element x of array as pivot, put x at its correct position in sorted array and put all smaller elements (smaller than x) before x, and put all greater elements (greater than x) after x. All this should be done in linear time.

#include <bits/stdc++.h>
using namespace std;

void swap(int* a, int* b)
{
    int t = *a;
    *a = *b;
    *b = t;
}

int partition (int arr[], int low, int high)
{
    int pivot = arr[high]; // pivot
    int i = (low - 1); // Index of smaller element and indicates the right position of pivot found so far
 
    for (int j = low; j <= high - 1; j++)
    {
        if (arr[j] < pivot)
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return (i + 1);
}

void quickSort(int arr[], int low, int high)
{
    if (low < high)
    {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}
 

Counting Sort

void countSort(char arr[])
{
    char output[strlen(arr)];
    int count[RANGE + 1], i;
    memset(count, 0, sizeof(count));
    for (i = 0; arr[i]; ++i)
        ++count[arr[i]];
    for (i = 1; i <= RANGE; ++i)
        count[i] += count[i - 1];
    for (i = 0; arr[i]; ++i) {
        output[count[arr[i]] - 1] = arr[i];
        --count[arr[i]];
    }
    for (i = 0; arr[i]; ++i)
        arr[i] = output[i];
}
void countSort(vector<int>& arr)
{
    int max = *max_element(arr.begin(), arr.end());
    int min = *min_element(arr.begin(), arr.end());
    int range = max - min + 1;
 
    vector<int> count(range), output(arr.size());
    for (int i = 0; i < arr.size(); i++)
        count[arr[i] - min]++;
 
    for (int i = 1; i < count.size(); i++)
        count[i] += count[i - 1];
 
    for (int i = arr.size() - 1; i >= 0; i--) {
        output[count[arr[i] - min] - 1] = arr[i];
        count[arr[i] - min]--;
    }
 
    for (int i = 0; i < arr.size(); i++)
        arr[i] = output[i];
}

Amplifier Classes

Amplifier ClassDescriptionConduction Angle
Class-AFull cycle 360o of Conduction
very low efficiency at around 30%
θ = 2π
Class-BHalf cycle 180o of Conductionθ = π
Class-ABSlightly more than 180o of conduction
with conversion efficiencies reaching about 50% to 60%.
π < θ < 2π
class A
class A
class B
class B
class AB
class AB

Audio amplifier and I2S DAC

The sound wave is converted into data through a series of snapshot measurements, or samples. A sample is taken at a particular time in the audio wave, recording amplitude. This information is then converted into digestible, binary data.

The system makes thousands of measurements per second. If we can take tons of measurements extremely quickly with enough possible amplitude values, we can effectively use these snapshots to reconstruct the resolution and complexity of an analog wave.

What is an audio sample rate

The system takes these measurements at a speed called the audio sample rate, measured in kilohertz. The audio sample rate determines the range of frequencies captured in digital audio. In most DAWs, you’ll find an adjustable sample rate in your audio preferences. This controls the sample rate for audio in your project.

What is audio bit depth?

The audio bit depth determines the number of possible amplitude values we can record for each sample. The most common audio bit depths are 16-bit, 24-bit, and 32-bit. Each is a binary term, representing a number of possible values. 

https://www.izotope.com/en/learn/digital-audio-basics-sample-rate-and-bit-depth.html

LM386 Audio Amplifier

I2S DAC

The stated purpose of I2S is to facilitate the development of audio electronics by means of a standardized interface for transmission of digital data among ADCs, DACs, digital filters, digital signal processors, and other types of ICs used in audio systems. It is inherently a two-channel protocol, because it was designed for stereophonic sound
Data is driven on the SD line, the state of the WS line corresponds to the audio channel (right or left) that is currently being transmitted, and the clock line carries the serial clock.

Serial Data (SD)

  • Digital values are transmitted MSb first.
  • Transmitter and receiver do not need to have an agreed-upon word length; the transmitter sends what it has, and the receiver takes what it can use.
  • New data bits can be clocked out on the rising or falling edge of the clock. However, they must be clocked in on the rising edge, so the more straightforward approach here is the arrangement shown in the diagram below—i.e., we clock data out on the falling edge and we clock it in on the rising edge.
  • The protocol does not include unused clock periods between words; the LSb of one word is followed immediately by the MSb of the next word.

Word Select (WS)

  • A logic low on WS indicates that the word currently being transferred is part of the data stream for the left audio channel; logic high on WS indicates right-channel audio.
  • To facilitate data handling on both the transmitter and the receiver side, the WS signal transitions one clock period before the completion of a data word:

Clock

  • The protocol does not specify a maximum data rate.
  • The clock runs continuously.