I'm focusing on 3x3 matrices for now as my code is volatile. I read the matrix from a text file and print to the console, based on its dimensions I generate the identity matrix.
const int m = 3;
const int n = 3;
int ID[m][n] = {};
for (i = 1; i <= n; ++i){
ID[i][i] = 1;
}
For some reason ID(2)[3] gets printed as 4227276 so I have to force it to zero manually after the fact.
Aside from other elementary row operations like swapping rows based on leading entry position, the main chunk of my code consists of the following:
float matrix[m][n];
int i,j,k,p,s;
for(s = 1;s <= m;++s){
j = s;
k = j + 1;
p = j;
for(i = n;i >= j;--i){ // makes leading entries 1
ID[j][i] = ID[j][i]/matrix[j][j];
matrix[j][i] = matrix[j][i]/matrix[j][j];
}
for(j = k;j <= m;++j){ //converts to upper triangular
for(i = n;i >= 1;--i){
ID[j][i] = ID[j][i] - matrix[j][i]*matrix[p][i];
matrix[j][i] = matrix[j][i] - matrix[j][i]*matrix[p][i];
}
}
}
for(j = (m-1);j >= 1;--j){ //makes entries above diagonal zero
for(i = n;i > j;--i){
ID[j][i] = ID[j][i] - matrix[j][i]*matrix[i][i];
matrix[j][i] = matrix[j][i] - matrix[j][i]*matrix[i][i];
}
}
I'm basically doing to the identity matrix whatever I do to matrix[m][n] to reduce it to row echelon form as you would with the augmented matrix. The row operations are pretty haphazard as I was just doing whatever worked to make matrix[m][n] an identity matrix. Afterwards, I just slotted ID[m][n] in there... not really sure what's happening but the result is half right.
my result
right answer
I realize that I the term I subtract from ID might need to be a multiple of ID but that makes it even worse. What mistakes have I made?
In C++ the indexes of a n-dimensional array start from 0 to n-1: so the first element of the array a is a[0], the second element is a[1], ..., the n-th element is a[n-1].
When you use the for
for (i = 1; i <= n; ++i){
ID[i][i] = 1;
}
you are discarding the first elements of each row and each column, accessing moreover to memory positions that do not belong to ID (e.g. ID[n][n]) which contain some unknown values.
You have to iterate over your arrays using for cycles such as
for (i = 0; i < n; ++i){
ID[i][i] = 1;
}
or if you desire
for (i = 1; i <= n; ++i){
ID[i-1][i-1] = 1;
}
but I found last solution quite confusing.
Related
I came up with this algorithm for matrix multiplication. I read somewhere that matrix multiplication has a time complexity of o(n^2).
But I think my this algorithm will give o(n^3).
I don't know how to calculate time complexity of nested loops. So please correct me.
for i=1 to n
for j=1 to n
c[i][j]=0
for k=1 to n
c[i][j] = c[i][j]+a[i][k]*b[k][j]
Using linear algebra, there exist algorithms that achieve better complexity than the naive O(n3). Solvay Strassen algorithm achieves a complexity of O(n2.807) by reducing the number of multiplications required for each 2x2 sub-matrix from 8 to 7.
The fastest known matrix multiplication algorithm is Coppersmith-Winograd algorithm with a complexity of O(n2.3737). Unless the matrix is huge, these algorithms do not result in a vast difference in computation time. In practice, it is easier and faster to use parallel algorithms for matrix multiplication.
The naive algorithm, which is what you've got once you correct it as noted in comments, is O(n^3).
There do exist algorithms that reduce this somewhat, but you're not likely to find an O(n^2) implementation. I believe the question of the most efficient implementation is still open.
See this wikipedia article on Matrix Multiplication for more information.
The standard way of multiplying an m-by-n matrix by an n-by-p matrix has complexity O(mnp). If all of those are "n" to you, it's O(n^3), not O(n^2). EDIT: it will not be O(n^2) in the general case. But there are faster algorithms for particular types of matrices -- if you know more you may be able to do better.
In matrix multiplication there are 3 for loop, we are using since execution of each for loop requires time complexity O(n). So for three loops it becomes O(n^3)
I recently had a matrix multiplication problem in my college assignment, this is how I solved it in O(n^2).
import java.util.Scanner;
public class q10 {
public static int[][] multiplyMatrices(int[][] A, int[][] B) {
int ra = A.length; // rows in A
int ca = A[0].length; // columns in A
int rb = B.length; // rows in B
int cb = B[0].length; // columns in B
// if columns of A is not equal to rows of B, then the two matrices,
// cannot be multiplied.
if (ca != rb) {
System.out.println("Incorrect order, multiplication cannot be performed");
return A;
} else {
// AB is the product of A and B, and it will have rows,
// equal to rown in A and columns equal to columns in B
int[][] AB = new int[ra][cb];
int k = 0; // column number of matrix B, while multiplying
int entry; // = Aij, value in ith row and at jth index
for (int i = 0; i < A.length; i++) {
entry = 0;
k = 0;
for (int j = 0; j < A[i].length; j++) {
// to evaluate a new Aij, clear the earlier entry
if (j == 0) {
entry = 0;
}
int currA = A[i][j]; // number selected in matrix A
int currB = B[j][k]; // number selected in matrix B
entry += currA * currB; // adding to the current entry
// if we are done with all the columns for this entry,
// reset the loop for next one.
if (j + 1 == ca) {
j = -1;
// put the evaluated value at its position
AB[i][k] = entry;
// increase the column number of matrix B as we are done with this one
k++;
}
// if this row is done break this loop,
// move to next row.
if (k == cb) {
j = A[i].length;
}
}
}
return AB;
}
}
#SuppressWarnings({ "resource" })
public static void main(String[] args) {
Scanner ip = new Scanner(System.in);
System.out.println("Input order of first matrix (r x c):");
int ra = ip.nextInt();
int ca = ip.nextInt();
System.out.println("Input order of second matrix (r x c):");
int rb = ip.nextInt();
int cb = ip.nextInt();
int[][] A = new int[ra][ca];
int[][] B = new int[rb][cb];
System.out.println("Enter values in first matrix:");
for (int i = 0; i < ra; i++) {
for (int j = 0; j < ca; j++) {
A[i][j] = ip.nextInt();
}
}
System.out.println("Enter values in second matrix:");
for (int i = 0; i < rb; i++) {
for (int j = 0; j < cb; j++) {
B[i][j] = ip.nextInt();
}
}
int[][] AB = multiplyMatrices(A, B);
System.out.println("The product of first and second matrix is:");
for (int i = 0; i < AB.length; i++) {
for (int j = 0; j < AB[i].length; j++) {
System.out.print(AB[i][j] + " ");
}
System.out.println();
}
}
}
why is A[k][i][j] better for spatial locality in a 3D array? ( where i,j,k are row, col, depth) CMU lecture 55min
I think that OP's question
why is A[k][i][j] better for spatial locality in a 3D array? ( where i,j,k are row, col, depth)
Comes from a misunderstanding of the exercise given as an example of spatial locality, where the reader is asked to
permute the loops so that the function ... has good spatial locality
and this code is given:
int sum_array_3d(int a[M][N][N])
{
int i, j, k, sum = 0;
for (i = 0; i < M; i++)
for (j = 0; j < N; j++)
for (k = 0; k < N; k++)
sum += a[k][i][j];
return sum;
}
My interpretation of this task is that the students are asked to either rewrite the inner statement as sum += a[i][j][k]; or change the order of the loops:
int sum_array_3d(int a[M][N][N])
{
int i, j, k, sum = 0;
for (k = 0; k < M; k++) // <-- those are reordered
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
sum += a[k][i][j]; // <-- this is mantained, verbatim
return sum;
}
Actually, that example is completely wrong. While rank 0 goes from 0..M-1, that loop is iterating 0..N-1. Unless M==N, you'll be reading the wrong element.
The goal is to have your loop iteratively access physically-adjacent locations in memory by manipulating the order of the loops.
Whenever your program reads a value, the CPU requests it from the cache controller. If it's not in cache, that value - and those near it - are retrieved from memory and stored in the cache.
If you then read the next element, it should (usually) already be in the cache, so there's no slow round-trip out to the next cache or host RAM.
If your loop is walking all over the place rather than taking advantage of spatial locality, then you run the risk of suffering far more cache misses, which makes things slow.
In short: getting stuff from the cache is fast, getting it from RAM is slow, and ordering your loops so that they touch adjacent locations helps keep the cache happy.
In graphics, we typically do this:
int a[M*N*N];
for(int offset=0; offset < M*N*N; ++offset)
{
//int y = offset / cols;
//int x = offset % rows;
sum += a[offset];
}
if you need an element by it's X,Y, just
offset = Y * cols + X;
int val = a[offset];
or for 3D
offset = Z*N*N + Y*N + X
or
offset = Z * rows * cols + Y * cols + X;
... and skip all the multidimensional array silliness.
Personally, I'd just do this:
int *p = &a[0][0][0]; // could probably just do int* p=a, but for clarity...
//... array gets populated somehow
for(int i=0;i<M*N*N;++i)
{
sum += p[i];
}
... but that assumes the array is a regular square array, not an array of pointers, or an array of an array of pointers.
im trying to explain the problem i have.
I need a 2-d matrix which contains 233x233 row and columns.
for(int i = 0; i < dimension;i++)
for(int j = 0 ; j < dimension;j++)
distance3 = sqrt(pow((apointCollection2[j].x - apointCollection[i].x1), 2) + pow((apointCollection2[j].y - apointCollection[i].y1), 2));
if (distance3 < Min)
{
Min = distance3;
station = busStation;
}
distance2 = sqrt(pow((apointCollection2[j].x - apointCollection[i].x2), 2) + pow((apointCollection2[j].y - apointCollection[i].y2), 2));
if (distance2 < Min2)
{
Min2 = distance2;
station1 = busStation;
}
So i find the minimum distance and two stations with minimum distance. The first station(station) corresponds to row and the second one (station1) corresponds to column. Then i need to increment the number of people these(can be called route) has.
Then i need to find the station and station1 after the second iteration and if they are the same i need just to increment people and not add the same stations to the vector.
Or another variant i thought
I creat a 2-d vector with 233x233 and 0 values in each cell.
vector< vector<int> > m;
cout << "Filling matrix with test numbers.";
m.resize(233);
for (int i = 0; i < 233; i++)
{
m[i].resize(233);
for (int j = 0; j < 233; j++)
{
}
}
After the loop above i decided to create the following where i find the min distance :
Here i want to increment somehow:
m[station][station1] = person;
if (find(m.begin(), m.end(), station, station1))
{
person++;
}
else
{
m[station][station1] = person;
}
I have an error in "find" because there is no instance of function template.Another problem i don't add values to vector but here also a mistake when i want to add.
This should be done very easy just need to find out the logic i should follow.
Thanks in advance
This question already has answers here:
Number of all increasing subsequences in given sequence?
(7 answers)
Closed 8 years ago.
Given an array A of size N I need to count such triplets (i,j,k) such that:
Condition 1 : i < j < k
Condition 2 : A[i] > A[j] > A[k]
I know a O(N^3) solution to do it. Can their be something like O(N) or O(NlogN) solution to do this problem as N can be up to 100000
Example : Let N=4 and array be [4,3,2,1] then answer is 4 as {4,3,2},{4,3,1},{4,2,1} and {3,2,1} are all possible answers
How to find this count for given N and array A?
My Approach :
int n;
cin>>n;
vector<int> A(n);
for(int i=0;i<n;i++){
cin>>A[i];
}
int count=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
for(int k=j+1;k<n;k++){
if(A[i]>A[j] && A[j]>A[k]){
count++;
}
}
}
}
cout<<count<<"\n";
First, sort the array, maintain the index of each element.
class Node{
int index, val;
}
For comparing two nodes, we first need to compare their values. If the values equals, we will compare their index, consider a node is greater if its index is smaller.
Now, process each node in sorted order, we try to add each node's index into a Fenwick tree. So, for each index i, we query the tree for the frequency of this index, which added previously in the tree. This is the number of index that has value greater than value of the current index.
Note for the case elements have equal value, by the sorting mechanism mentioned above, we will add those have greater index to the tree first, thus, doesn't affect the frequency value query from the tree.
Apply similar step to obtains those elements that smaller than i and has index j < i.
For example:
If we have an array
{0(1) ,1(2) , 2(2) ,3(4) , 4(4) ,5(4) ,6(1)} //index(value)
After sort -> {5(4), 4(4), 3(4), 2(2), 1(2), 6(1), 0(1) }
Pseudo code
Node[]data;
sort(data)
Fenwick tree;
int[]less;
int[]more;
for(int i = 0; i < data.length; i++){
less[data[i].index] = tree.query(data[i].index);
tree.add(data[i].index, 1);
}
tree.clear();
for(int i = data.length - 1; i >= 0; i--){
more[data[i].index] = tree.query(data.length) -tree.query(data[i].index);
tree.add(data[i].index, 1);
}
int result = 0;
for(int i = 0; i < data.length; i++)
result += more[i]*less[i];
Time complexity will be O(n logn).
Working Java code (FT is my Fenwick tree)
PrintWriter out;
Scanner in = new Scanner(System.in);
out = new PrintWriter(System.out);
int n = in.nextInt();
Node[] data = new Node[n];
for (int i = 0; i < n; i++) {
data[i] = new Node(i + 1, in.nextInt());
}
FT tree = new FT(n + 2);
Arrays.sort(data, new Comparator<Node>() {
#Override
public int compare(Node o1, Node o2) {
if (o1.val != o2.val) {
return o2.val - o1.val;
}
return o2.index - o1.index;
}
});
int[] less = new int[n];//Store all nodes with greater index and smaller value;
int[] greater = new int[n];//Store all nodes with smaller index and greater value
for (int i = 0; i < n; i++) {
greater[data[i].index - 1] = (int) tree.get(data[i].index);
tree.update(data[i].index, 1);
}
tree = new FT(n + 2);
for (int i = n - 1; i >= 0; i--) {
less[data[i].index - 1] = (int) (tree.get(n) - tree.get(data[i].index));
tree.update(data[i].index, 1);
}
long total = 0;
for (int i = 0; i < n; i++) {
total += less[i] * greater[i];
}
out.println(total);
out.close();
You can do this in O(n*n) pretty easily, you just need to keep track of how many smaller number each element had:
vector<int> smallerNumbers(A.size());
for (int i = A.size() - 2; i >= 0; --i){
for (int j = i + 1; j < A.size(); ++j){
if (A[i] > A[j]){
smallerNumbers[i]++;
count += smallerNumbers[j];
}
}
}
For an O(nklogn) solution see my answer here: https://stackoverflow.com/a/28379003/2642059
Note that is for an increasing sequence and you're asking for a decreasing sequence.
To accomplish that you will need to reverse the ranking created by mapIndex. So simply reverse temp before creating mapIndex by swapping the partial_sort_copy line with this one:
partial_sort_copy(values.cbegin(), values.cend(), temp.rbegin(), temp.rend());
I want to compute the error in linear least squares method.
I have matrices A,B and X. (AX=B).
Sizes are : A(NxN) , B(NxNRHS) , X(N,NRHS) ,where NRHS is number of right hand side.
The error is computed as sqrt(sum(B-AX)).
But I must take into account every column of B and X in order to make the substraction.
I must substract B[i]-A[..]X[i] -> where i is every column of B and X.
I can't figure how to do it ,hence how to extract every column.I can't find the right indices for B and X matrices (I think) ,because I must go beyond whole A matrix and only beyond every column of B and X.
I am doing something like this (using column major order):
int N=128;
int NRHS =1;
int Asize=N*N;
int Bsize=N*NRHS;
int Xsize=N*NRHS;
A=(double*)malloc(Asize*sizeof(double));
B=(double*)malloc(Bsize*sizeof(double));
X=(double*)malloc(Xsize*sizeof(double));
...
for(int i = 0; i < N; i++)
{
for (int j=0;j<NRHS; j++){
diff[i+j*N] = fabs(B[i+j*N] - A[i+j*N]*X[i+j*N]);
abs_error=sqrt(sums(diff,N));
}
}
I thought of adding some statement using the modulo operator but I couldn't figure.
sums is just a function which gives the sum of an array where the second argument is the number of elements.
You could first do a matrix multiplication of A and X using loops.
Then you could write another 2 loops to compute the difference (B - AX). This would simply your problem.
Edit
After you compute the product of A and X, assuming that you store the product in a variable named AX,the following code will give you the difference between corresponding elements.
differenceMatrix = (double*)malloc(Bsize*sizeof(double));
for(int i = 0; i < N; i++)
{
for (int j = 0; j < NRHS; j++){
differenceMatrix[i+j*N] = fabs(B[i+j*N] - AX[i+j*N]);
}
}
Each column of the differenceMatrix contains the difference between corresponding elements.
Edit
To obtain the sum of difference of each column
double sumOfDifferencePerColumn;
for(int i = 0; i < N; i++)
{
sumOfDifferencePerColumn = 0.0;
for (int j = 0; j < NRHS; j++){
sumOfDifferencePerColumn += ( fabs(B[i+j*N] - AX[i+j*N]) );
}
// add code to take square root or use the sum of difference of each column
}