I have written a C program in which I output the lowest and highest temperature with day of the week and time in the lower function. However, sometimes values are duplicated. How can I implement this in my function so that both times are displayed?
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <limits.h>
double week_statistics(double array[52][7][24], int kalenderwoche, int j, int i, int k, int daymin, int hourmin, int daymax, int hourmax){
double min = array[0][0][0];
for(j = 0; j < 7; j++){
for(k = 0; k < 24; k++){
if(array[i][j][k] < min){
min = array[i][j][k];
daymin = j + 1;
hourmin = k + 1;
}}}
printf("Die niedrigste Temperatur war %lf° in der %d. Kalenderwoche am %d. Wochentag um %d Uhr.\n", min, kalenderwoche, daymin, hourmin);
double max = array[0][0][0];
for(i = 0; i < 52; i++){
for(j = 0; j < 7; j++){
for(k = 0; k < 24; k++){
if(array[i][j][k] > max){
max = array[i][j][k];
daymax = j + 1;
hourmax = k + 1;
}}}}
printf("Die höchste Temperatur war %lf° in der %d. Kalenderwoche am %d. Wochentag um %d Uhr.\n", max, kalenderwoche, daymax, hourmax);
}
int main(){
double array[52][7][24] = {{
{9.6, 9.4, 9.3, 9.1, 7.9, 7.7, 7.3, 7.2, 8.8, 9.3, 9.7, 9.4, 10.2, 9.7, 9.9, 9.5, 9.2, 9.3, 9.2, 7.1, 6.1, 5.9, 5.6, 5.2},
{4.9, 4.6, 4.6, 4.1, 3.5, 3.1, 2.6, 2.6, 3.5, 5.1, 6.2, 8.3, 9.0, 9.3, 9.1, 8.0, 6.8, 6.4, 5.4, 5.2, 4.8, 4.5, 5.0, 5.5},
{6.3, 6.8, 7.0, 7.2, 7.1, 7.2, 7.1, 7.4, 7.7, 8.2, 8.7, 9.1, 8.8, 8.7, 8.6, 8.4, 8.0, 7.9, 7.7, 7.6, 7.5, 7.3, 7.3, 7.2},
{7.1, 7.0, 6.9, 6.8, 6.7, 6.7, 6.7, 6.6, 6.7, 6.8, 6.9, 7.2, 7.5, 7.7, 8.1, 8.3, 8.0, 7.7, 8.1, 8.2, 7.7, 7.5, 7.7, 7.9},
{8.1, 8.0, 7.9, 7.8, 7.5, 7.2, 6.9, 7.2, 8.0, 8.4, 8.7, 9.0, 8.7, 8.9, 9.0, 7.8, 8.5, 8.1, 7.7, 7.7, 6.7, 7.0, 6.5, 7.1},
{6.4, 6.6, 6.3, 5.8, 5.0, 4.9, 4.7, 4.6, 4.9, 5.3, 6.1, 5.5, 5.3, 5.7, 5.8, 6.5, 6.6, 5.8, 5.8, 7.1, 7.0, 7.0, 6.3, 5.8},
{4.4, 4.0, 3.8, 3.8, 4.2, 4.2, 4.3, 3.8, 4.4, 5.2, 5.7, 5.9, 6.1, 6.7, 6.3, 5.9, 5.5, 5.1, 5.0, 5.0, 5.2, 5.7, 7.2, 7.7}
}};
int kalenderwoche = 45;
int i, j,k;
int daymin,daymax = 1;
int hourmin,hourmax = 1;
week_statistics(array, kalenderwoche, i, j ,k, daymin, hourmin, daymax, hourmax); //c)
}
In C programming for storing the values that you don't have their count without using any third party libraries, you have two main approaches. One way is to create an very large array and store your data into it, by using this approach you must have an upper bound for your number of inputs. Another way is using dynamic memory allocation. There are multiple ways for using dynamic memory allocation and one the simplest approach is using realloc and increasing a dynamically allocated memory one by one (this solution is simple for implementation and may not good enough for memory/time consumption).
First approach:
int daymin[100] = {0};
int dayminindex = 0;
...
daymin[dayminindex] = j + 1;
dayminindex++;
and the second approach is:
int *daymin = NULL;
int dayminlen = 0;
...
dayminlen++;
daymin = realloc(daymin, len * sizeof(int));
daymin[dayminlen - 1] = j + 1;
After applying the second approach in your code, we will have:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <limits.h>
double week_statistics(double array[52][7][24], int kalenderwoche){
int i, j, k;
int minlen = 0;
int *daymin = NULL;
int *hourmin = NULL;
double min = array[0][0][0];
for(i = 0; i < 52; i++){
for(j = 0; j < 7; j++){
for(k = 0; k < 24; k++){
if(array[i][j][k] < min) {
min = array[i][j][k];
minlen = 0;
free(daymin);
free(hourmin);
daymin = NULL;
hourmin = NULL;
}
// here we will add the first one
if(array[i][j][k] == min) {
minlen++;
daymin = realloc(daymin, minlen * sizeof(int));
daymin[minlen - 1] = j + 1;
hourmin = realloc(hourmin, minlen * sizeof(int));
hourmin[minlen - 1] = k + 1;
}
}
}
}
for (int i = 0; i < minlen; i++) {
printf("Die niedrigste Temperatur war %lf° in der %d. Kalenderwoche am %d. Wochentag um %d Uhr.\n", min, kalenderwoche, daymin[i], hourmin[i]);
}
int maxlen = 0;
int *daymax = NULL;
int *hourmax = NULL;
double max = array[0][0][0];
for(i = 0; i < 52; i++){
for(j = 0; j < 7; j++){
for(k = 0; k < 24; k++){
if(array[i][j][k] > max){
max = array[i][j][k];
maxlen = 0;
free(daymax);
free(hourmax);
daymax = NULL;
hourmax = NULL;
}
// here we will add the first one
if(array[i][j][k] == max){
maxlen++;
daymax = realloc(daymax, maxlen * sizeof(int));
daymax[maxlen - 1] = j + 1;
hourmax = realloc(hourmax, maxlen * sizeof(int));
hourmax[maxlen - 1] = k + 1;
}
}
}
}
for (int i = 0; i < maxlen; i++) {
printf("Die höchste Temperatur war %lf° in der %d. Kalenderwoche am %d. Wochentag um %d Uhr.\n", max, kalenderwoche, daymax[i], hourmax[i]);
}
}
int main(){
double array[52][7][24] = {
{
{9.6, 9.4, 9.3, 9.1, 7.9, 7.7, 7.3, 7.2, 8.8, 9.3, 9.7, 9.4, 10.2, 9.7, 9.9, 9.5, 9.2, 9.3, 9.2, 7.1, 6.1, 5.9, 5.6, 5.2},
{4.9, 4.6, 4.6, 4.1, 3.5, 3.1, 2.6, 2.6, 3.5, 5.1, 6.2, 8.3, 9.0, 9.3, 9.1, 8.0, 6.8, 6.4, 5.4, 5.2, 4.8, 4.5, 5.0, 5.5},
{6.3, 6.8, 7.0, 7.2, 7.1, 7.2, 7.1, 7.4, 7.7, 8.2, 8.7, 9.1, 8.8, 8.7, 8.6, 8.4, 8.0, 7.9, 7.7, 7.6, 7.5, 7.3, 7.3, 7.2},
{7.1, 7.0, 6.9, 6.8, 6.7, 6.7, 6.7, 6.6, 6.7, 6.8, 6.9, 7.2, 7.5, 7.7, 8.1, 8.3, 8.0, 7.7, 8.1, 8.2, 7.7, 7.5, 7.7, 7.9},
{8.1, 8.0, 7.9, 7.8, 7.5, 7.2, 6.9, 7.2, 8.0, 8.4, 8.7, 9.0, 8.7, 8.9, 9.0, 7.8, 8.5, 8.1, 7.7, 7.7, 6.7, 7.0, 6.5, 7.1},
{6.4, 6.6, 6.3, 5.8, 5.0, 4.9, 4.7, 4.6, 4.9, 5.3, 6.1, 5.5, 5.3, 5.7, 5.8, 6.5, 6.6, 5.8, 5.8, 7.1, 7.0, 7.0, 6.3, 5.8},
{4.4, 4.0, 3.8, 3.8, 4.2, 4.2, 4.3, 3.8, 4.4, 5.2, 5.7, 5.9, 6.1, 6.7, 6.3, 5.9, 5.5, 5.1, 5.0, 5.0, 5.2, 5.7, 7.2, 7.7}
}
};
int kalenderwoche = 45;
week_statistics(array, kalenderwoche);
}
There is a third approach that sometimes preferable when you have a stream of values and you just care about the statistics, not the individual values. (As you seem to have here.) You can take the data on-line in a single pass, only updating the values you care about.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct measure {
size_t count;
/* On-line numerically stable first-order, <Welford, 1962, Note>. */
double mean, ssdm;
struct { double min, max; } value;
struct { size_t min, max; } arg_hour, arg_day;
};
static void m_add(struct measure *const m, const double replica,
const size_t hour, const size_t day) {
const size_t n = ++m->count;
const double delta = replica - m->mean;
m->mean += delta / n;
m->ssdm += delta * (replica - m->mean);
if(n == 1 || replica < m->arg_hour.min) m->arg_hour.min = hour; /* argmin */
if(n == 1 || replica > m->arg_hour.max) m->arg_hour.max = hour; /* argmax */
if(n == 1 || replica < m->arg_day.min) m->arg_day.min = day; /* argmin */
if(n == 1 || replica > m->arg_day.max) m->arg_day.max = day; /* argmax */
if(n == 1 || replica < m->value.min) m->value.min = replica;
if(n == 1 || replica > m->value.max) m->value.max = replica;
}
static double m_mean(const struct measure *const m)
{ return m->count ? m->mean : 0. / 0.; }
static double m_sample_variance(const struct measure *const m)
{ return m->count > 1 ? m->ssdm / (m->count - 1) : 0. / 0.; }
static double m_stddev(const struct measure *const m)
{ return sqrt(m_sample_variance(m)); }
int main(void) {
double array[][7][24] = {
{
{ 9.6, 9.4, 9.3, 9.1, 7.9, 7.7, 7.3, 7.2, 8.8, 9.3, 9.7, 9.4,
10.2, 9.7, 9.9, 9.5, 9.2, 9.3, 9.2, 7.1, 6.1, 5.9, 5.6, 5.2 },
{ 4.9, 4.6, 4.6, 4.1, 3.5, 3.1, 2.6, 2.6, 3.5, 5.1, 6.2, 8.3, 9.0,
9.3, 9.1, 8.0, 6.8, 6.4, 5.4, 5.2, 4.8, 4.5, 5.0, 5.5 },
{ 6.3, 6.8, 7.0, 7.2, 7.1, 7.2, 7.1, 7.4, 7.7, 8.2, 8.7, 9.1, 8.8,
8.7, 8.6, 8.4, 8.0, 7.9, 7.7, 7.6, 7.5, 7.3, 7.3, 7.2 },
{ 7.1, 7.0, 6.9, 6.8, 6.7, 6.7, 6.7, 6.6, 6.7, 6.8, 6.9, 7.2, 7.5,
7.7, 8.1, 8.3, 8.0, 7.7, 8.1, 8.2, 7.7, 7.5, 7.7, 7.9},
{ 8.1, 8.0, 7.9, 7.8, 7.5, 7.2, 6.9, 7.2, 8.0, 8.4, 8.7, 9.0, 8.7,
8.9, 9.0, 7.8, 8.5, 8.1, 7.7, 7.7, 6.7, 7.0, 6.5, 7.1},
{ 6.4, 6.6, 6.3, 5.8, 5.0, 4.9, 4.7, 4.6, 4.9, 5.3, 6.1, 5.5, 5.3,
5.7, 5.8, 6.5, 6.6, 5.8, 5.8, 7.1, 7.0, 7.0, 6.3, 5.8},
{ 4.4, 4.0, 3.8, 3.8, 4.2, 4.2, 4.3, 3.8, 4.4, 5.2, 5.7, 5.9, 6.1,
6.7, 6.3, 5.9, 5.5, 5.1, 5.0, 5.0, 5.2, 5.7, 7.2, 7.7 }
}
};
const int kalenderwoche = 45;
size_t j, k;
struct measure m = { 0 };
for(j = 0; j < sizeof *array / sizeof **array; j++) {
for(k = 0; k < sizeof **array / sizeof ***array; k++) {
m_add(&m, array[0][j][k], k + 1, j + 1);
}
}
printf("Die niedrigste Temperatur war %lf° in der %d. Kalenderwoche am %zu. Wochentag um %zu Uhr.\n"
"Die höchste Temperatur war %lf° in der %d. Kalenderwoche am %zu. Wochentag um %zu Uhr.\n"
"Mean %f +/- %1.1f.\n",
m.value.min, kalenderwoche, m.arg_day.min, m.arg_hour.min,
m.value.max, kalenderwoche, m.arg_day.max, m.arg_hour.max,
m_mean(&m), m_stddev(&m));
}
I've also calculated the mean and standard-deviation using numerically-stable Welford's on-line algorithm using mean and ssdm, if you care about this.
i am having trouble writing a program that prints a matrix, and then I generate the identity matrix. Here is my ccode below and any help would be greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int PrintMatrix(int dim, double matrix[dim][dim]);
int main()
int PrintMatrix(int dim, double matrix[dim][dim]) {
int aa, bb;
for (aa = 0; aa <= dim; aa++) {
for (bb = 0; bb <= dim; bb++) {
printf("%lf ", matrix[aa][bb]);
}
printf("\n");
}
}
double TestMatrix[7][7] = {
{1,0,0,0,0,0,0},
{0,1,0,0,0,0,0},
{0,0,1,0,0,0,0},
{0,0,0,1,0,0,0},
{0,0,0,0,1,0,0},
{0,0,0,0,0,1,0},
{0,0,0,0,0,0,1}
};
PrintMatrix(7, TestMatrix);
return 0;
Your code won't compile successfully.
After main there is no opening brace.
You are defining function inside main, which is an issue.
Check for parentheses in whole code.
Fixed the loop controls from <= to <.
Here is the modified code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int PrintMatrix(int dim, double matrix[dim][dim]);
int main()
{
double TestMatrix[7][7] = {
{1,0,0,0,0,0,0},
{0,1,0,0,0,0,0},
{0,0,1,0,0,0,0},
{0,0,0,1,0,0,0},
{0,0,0,0,1,0,0},
{0,0,0,0,0,1,0},
{0,0,0,0,0,0,1},
};
PrintMatrix(7, TestMatrix);
return 0;
}
int PrintMatrix(int dim, double matrix[dim][dim]) {
int aa, bb;
for (aa = 0; aa < dim; aa++) {
for (bb = 0; bb < dim; bb++) {
printf("%lf ", matrix[aa][bb]);
}
printf("\n");
}
}
The code in the question is an appalling non-compiling mess. One of the comments is:
It still isn't returning the identity for dim = 2 up to 7; any thoughts?
As BluePixy hinted, if you lie to your compiler about the size of the input matrix to the function, for example by passing a 7x7 matrix but telling that it has a 3x3 matrix, it gets its revenge by printing different information from what you wanted. Don't lie to the compiler!
If you want to print identity matrices of sizes 1..7 from a 7x7 matrix, tell the compiler (function) both the actual size of the matrix and the size you want printed. For an identity matrix, you don't actually need the original matrix — you could synthesize the data.
#include <stdio.h>
static void printIdentityMatrix(int size)
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
printf("%4.1f", (i == j) ? 1.0 : 0.0);
putchar('\n');
}
}
int main(void)
{
for (int i = 1; i < 8; i++)
printIdentityMatrix(i);
return 0;
}
For printing the top left square subset of an arbitrarily sized square matrix, you must pass both the size of the data to be printed and the actual size of the matrix.
#include <assert.h>
#include <stdio.h>
static void PrintMatrix(int size, int dim, double matrix[dim][dim])
{
assert(size <= dim);
for (int aa = 0; aa < size; aa++)
{
for (int bb = 0; bb < size; bb++)
printf("%lf ", matrix[aa][bb]);
putchar('\n');
}
}
int main(void)
{
double TestMatrix[7][7] =
{
{1,0,0,0,0,0,0},
{0,1,0,0,0,0,0},
{0,0,1,0,0,0,0},
{0,0,0,1,0,0,0},
{0,0,0,0,1,0,0},
{0,0,0,0,0,1,0},
{0,0,0,0,0,0,1},
};
for (int i = 1; i < 8; i++)
{
PrintMatrix(i, 7, TestMatrix);
putchar('\n');
}
return 0;
}
Printing an arbitrary rectangular submatrix of an arbitrarily sized rectangular matrix requires many more function parameters (7 if I am counting correctly:
void PrintSubMatrix(int x_off, int y_off, int x_len, int y_len, int x_size, int y_size,
double matrix[x_size][y_size]);
and that's before you specify the file stream to write on.
#include <assert.h>
#include <stdio.h>
static void PrintSubMatrix(int x_off, int y_off, int x_len, int y_len, int x_size, int y_size,
double matrix[x_size][y_size])
{
assert(x_off >= 0 && x_off < x_size && x_off + x_len <= x_size);
assert(y_off >= 0 && y_off < y_size && y_off + y_len <= y_size);
printf("SubMatrix size %dx%d at (%d,%d) in M[%d][%d]\n",
x_len, y_len, x_off, y_off, x_size, y_size);
for (int x = x_off; x < x_off + x_len; x++)
{
for (int y = y_off; y < y_off + y_len; y++)
printf("%4.1f ", matrix[x][y]);
putchar('\n');
}
putchar('\n');
}
int main(void)
{
double TestMatrix[7][9] =
{
{ 1, 2, 3, 4, 3, 2, 1, 2, 3 },
{ 2, 1, 9, 8, 4, 6, 0, 0, 1 },
{ 3, 0, 8, 7, 5, 5, 0, 0, 1 },
{ 4, 0, 5, 6, 6, 8, 4, 4, 4 },
{ 5, 0, 1, 4, 7, 9, 0, 0, 1 },
{ 6, 0, 1, 0, 8, 1, 0, 0, 1 },
{ 7, 0, 0, 0, 9, 0, 1, 0, 1 },
};
PrintSubMatrix(0, 0, 7, 9, 7, 9, TestMatrix);
for (int i = 1; i < 4; i++)
{
for (int j = 2; j < 4; j++)
PrintSubMatrix(i, j, 3 + j - i, i + j, 7, 9, TestMatrix);
}
return 0;
}
Sample run:
SubMatrix size 7x9 at (0,0) in M[7][9]
1.0 2.0 3.0 4.0 3.0 2.0 1.0 2.0 3.0
2.0 1.0 9.0 8.0 4.0 6.0 0.0 0.0 1.0
3.0 0.0 8.0 7.0 5.0 5.0 0.0 0.0 1.0
4.0 0.0 5.0 6.0 6.0 8.0 4.0 4.0 4.0
5.0 0.0 1.0 4.0 7.0 9.0 0.0 0.0 1.0
6.0 0.0 1.0 0.0 8.0 1.0 0.0 0.0 1.0
7.0 0.0 0.0 0.0 9.0 0.0 1.0 0.0 1.0
SubMatrix size 4x3 at (1,2) in M[7][9]
9.0 8.0 4.0
8.0 7.0 5.0
5.0 6.0 6.0
1.0 4.0 7.0
SubMatrix size 5x4 at (1,3) in M[7][9]
8.0 4.0 6.0 0.0
7.0 5.0 5.0 0.0
6.0 6.0 8.0 4.0
4.0 7.0 9.0 0.0
0.0 8.0 1.0 0.0
SubMatrix size 3x4 at (2,2) in M[7][9]
8.0 7.0 5.0 5.0
5.0 6.0 6.0 8.0
1.0 4.0 7.0 9.0
SubMatrix size 4x5 at (2,3) in M[7][9]
7.0 5.0 5.0 0.0 0.0
6.0 6.0 8.0 4.0 4.0
4.0 7.0 9.0 0.0 0.0
0.0 8.0 1.0 0.0 0.0
SubMatrix size 2x5 at (3,2) in M[7][9]
5.0 6.0 6.0 8.0 4.0
1.0 4.0 7.0 9.0 0.0
SubMatrix size 3x6 at (3,3) in M[7][9]
6.0 6.0 8.0 4.0 4.0 4.0
4.0 7.0 9.0 0.0 0.0 1.0
0.0 8.0 1.0 0.0 0.0 1.0
It would be better if the code was fixed not to print a blank at the end of each line; that's left as an exercise for the reader.
I am testing the functions of Intel MKL in a C test-program and I found that I just can't make the spareblas: mkl_scsrmm function CSR one-based indexing work. I am using CSR with the val, columns, pntrb and pntre variation. The original examples where placed in:
"...mkl\examples\examples_core_c\spblasc\source\cspblas_scsr.c"
This is the first code for zero-based indexing:
Example #1
#include <stdio.h>
#include "mkl_types.h"
#include "mkl_spblas.h"
int main() {
#define M 2
#define NNZ 4
MKL_INT m = M, nnz = NNZ;
float values[NNZ] = {2.0,4.0,4.0,2.0};
MKL_INT columns[NNZ] = {1,2,1,2};
MKL_INT rowIndex[M+1] = {1,3,5};
#define N 2
MKL_INT n = N;
float b[M][N] = {2.0, 1.0, 5.0, 2.0};
float c[M][N] = {0.0, 0.0, 0.0, 0.0};
float alpha = 1.0, beta = 0.0;
char transa, uplo, nonunit;
char matdescra[6];
MKL_INT i, j, is;
transa = 'N';
matdescra[0] = 'S';
matdescra[1] = 'L';
matdescra[2] = 'N';
matdescra[3] = 'F';
mkl_scsrmm(&transa, &m, &n, &m, &alpha, matdescra, values, columns, rowIndex, &(rowIndex[1]), &(b[0][0]), &n, &beta, &(c[0][0]), &n);
printf(" \n");
printf(" OUTPUT DATA FOR MKL_SCSRMM\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%7.1f", c[i][j]);
};
printf("\n");
};
return 0;
}
The results I get are this:
Zero-based indexing(the right one):
24.0 10.0
18.0 8.0
One-based indexing:
8.0 10.0
18.0 24.0
Though it seems like it only changes the diagonal elements position, with 3x3 matrix the solution its completly different from the right one. I suspected that it might be something with the input format of the matrix b. I think that there's lack of clarity on the description of array b for the function mkl_scsrmm placed in the MKL reference manual. Thus I changed b format, in this example and it worked (I placed elements position in this order: `{2.0, 5.0, 1.0, 2.0}) But I did the same for another 3x3 example I coded and it didn't work so I think it may be just a coincidence. I don't really know what to do with this problem, I would like to understand what happens here.
References:
CSR format
https://software.intel.com/en-us/node/471374
Spare Blas mkl_scsrmm function
https://software.intel.com/sites/products/documentation/doclib/iss/2013/mkl/mklman/hh_goto.htm#GUID-78C55D9B-86FF-4A9F-B5D5-D2F61B9314FC.htm
Spare Blas Interface Considerations
https://software.intel.com/sites/products/documentation/doclib/iss/2013/mkl/mklman/hh_goto.htm#GUID-34C8DB79-0139-46E0-8B53-99F3BEE7B2D4.htm
And here is another example, the 3x3 one:
Example #2
// matrix A
//
// 2 4 3
// 4 2 1
// 3 1 6
//
// matrix B
//
// 2 1 3
// 4 5 6
// 7 8 9
//
// ZERO-BASED INDEXING
//
// a = {2 4 3 4 2 1 3 1 6}
// columns= {0 1 2 0 1 2 0 1 2}
// idexRow = {0 3 6 9}
//
// b = {2 1 3 4 5 6 7 8 9} (row order array)
//
// We print the array in row-major order
//
// ONE-BASED INDEXING
//
// a = {2 4 3 4 2 1 3 1 6}
// columns={1 2 3 1 2 3 1 2 3}
// indexRow = {0 3 6 9}
//
// b = {2 4 7 1 5 8 3 6 9} (column order array)
//
// We print the array in column-major order (because the resoult is in column major order, ie transposed)
//
//
//
#include <stdio.h>
#include "mkl_types.h"
#include "mkl_spblas.h"
int main()
{
#define M 3
#define NNZ 9
#define N 3
MKL_INT m = M, nnz = NNZ, n=N;
float a[NNZ] = {2.0,4.0,3.0,4.0,2.0,1.0,3.0,1.0,6.0};
MKL_INT columns[NNZ] = {0,1,2,0,1,2,0,1,2};
MKL_INT rowIndex[M+1] = {0,3,6,9};
float b[M][N] = {2.0, 1.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
float c[M][N] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
float alpha = 1.0, beta = 0.0;
MKL_INT i, j;
char transa;
char matdescra[6];
float a1[NNZ] = {2.0,4.0,3.0,4.0,2.0,1.0,3.0,1.0,6.0};
MKL_INT columns1[NNZ] = {1,2,3,1,2,3,1,2,3};
MKL_INT rowIndex1[M+1] = {1,4,7,10};
float b1[M][N] = {2.0, 4.0, 7.0, 1.0, 5.0, 8.0, 3.0, 6.0, 9.0};
float c1[M][N] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
//********************************
//ZERO-BASED INDEXING
//********************************
transa = 'n';
matdescra[0] = 's';
matdescra[1] = 'l';
matdescra[2] = 'n';
matdescra[3] = 'c';
mkl_scsrmm(&transa, &m, &n, &m, &alpha, matdescra, a, columns, rowIndex, &(rowIndex[1]), &(b[0][0]), &n, &beta, &(c[0][0]), &n);
printf(" \n");
printf(" Right Solution: ZERO-BASED: C \n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++) {
printf("%7.1f", c[i][j]);
};
printf("\n");
};
printf(" \n");
printf(" ZERO-BASED: C' \n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%7.1f", c[j][i]);
};
printf("\n");
};
//********************************
//ONE-BASED INDEXING
//********************************
matdescra[3] = 'f';
mkl_scsrmm(&transa, &m, &n, &m, &alpha, matdescra, a1, columns1, rowIndex1, &(rowIndex1[1]), &(b1[0][0]), &n, &beta, &(c1[0][0]), &n);
printf(" \n");
printf(" ONE-BASED: C \n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%7.1f", c1[i][j]);
};
printf("\n");
};
printf(" \n");
printf(" ONE-BASED: C' \n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%7.1f", c1[j][i]);
};
printf("\n");
};
return 0;
}
I asked the same question at Intel's forum and I got some help there and get to the solution of the problem. The deal was that when calling the routine from C interface with zero-based indexing you can send the matrix stored in an array following row-major order (native C array storage), and when you call the routine with one-based indexing you have to store the matrix in column-major order. This changes the way the matrix B and C need to be stored, and the way the result will be stored. For the matrix A it only changes the indexing (from 0 to 1). From Intel's documentation you may think that the C interface accepts always the row-major ordering for both types of indexing.
Notice that it that in general, column-major ordering is not the same as storing the transposed matrix in row-major ordering (it is the same if matrices are square).