1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
// Copyright (C) 2015 - IIT Bombay - FOSSEE
//
// This file must be used under the terms of the CeCILL.
// This source file is licensed as described in the file COPYING, which
// you should have received as part of this distribution. The terms
// are also available at
// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
// Author: Sai Kiran
// Organization: FOSSEE, IIT Bombay
// Email: toolbox@scilab.in
#include <symphony.h>
#include <sci_iofunc.hpp>
extern sym_environment* global_sym_env;//defined in globals.cpp
extern "C" {
#include <api_scilab.h>
#include <Scierror.h>
#include <BOOL.h>
#include <stdlib.h>
#include <malloc.h>
#include <localization.h>
#include <sciprint.h>
#include <string.h>
/*
* Proto-type of function that converts column-major (sparse) representation
* to row-major (sparse) representation .
*/
void column_major_to_row_major(int,int,int,double *,int *,int *,double *,int *,int *);
/* This function is to retrieve the problem's constraint matrix (sparse) .
* Symphony uses column-major (sparse) representation.
* Scilab uses row-major (sparse) representation.
* So, This function takes column-major (sparse) representation from symphony ,
* converts that to row-major (sparse) representation and writes to scilab's memory.
*
**/
int sci_sym_get_matrix(char *fname, unsigned long fname_len){
int nz_ele=0;// No.of non-zero elements of the matrix
int rows=0; //No. of rows in constraint matrix
int columns=0; //No. of columns in constraint matrix
/* Variables that store column-major representation of matrix.
* These variables will be filled by symphony
*/
int *column_start=NULL;// Starting index(in elements array) of each column
int *row_indices=NULL;// Row indices corresponding to each non-zero element
double *elements=NULL;// Non-zero elements of matrix
/* Variables that store row-major representation of matrix.
* Filled by a function column_major_to_row_major.
*/
double *new_list=NULL; // Non-zero elements of row-major representation
int *count_per_row=NULL; //Count of non-zero elements in earch row
int *column_position=NULL; //Column of each non-zero element
//check whether we have no input and one output argument or not
CheckInputArgument(pvApiCtx, 0, 0) ; //no input argument
CheckOutputArgument(pvApiCtx, 1, 1) ; //one output argument
if(global_sym_env==NULL) //There is no environment opened.
sciprint("Error: Symphony environment is not initialized.\n");
else { //There is an environment opened
int status1=sym_get_num_elements(global_sym_env,&nz_ele); //No. of non-zero elements
int status2=sym_get_num_cols(global_sym_env , &columns); //Columns
int status3=sym_get_num_rows(global_sym_env , &rows); //Rows
int status4=FUNCTION_TERMINATED_ABNORMALLY;
//Make sure functions terminated normally
if (status1 == status2 && status1 == status3 && status1 == FUNCTION_TERMINATED_NORMALLY){
//Allocate memory for column-major representation
column_start=(int*)malloc(sizeof(int) * (columns+1));
row_indices=(int*)malloc(sizeof(int) * nz_ele);
elements=(double*)malloc(sizeof(double) * nz_ele);
//Take column-major representation from symphony
status4=sym_get_matrix(global_sym_env,&nz_ele,column_start,row_indices,elements);
if (status1 == status4) { //Check termination status of function, if normal
//Allocate memory for row-major representation
new_list=(double*) calloc( nz_ele , sizeof(double));
count_per_row=(int*) calloc( rows, sizeof(int ) );
column_position=(int*) calloc( nz_ele, sizeof(int));
//Convert column-major representation to row-major representation
column_major_to_row_major(rows,columns,nz_ele,elements,row_indices,column_start,new_list,count_per_row,column_position);
/*
(Important)Scilab considers indices from 1 , But we have column indices starting from 0 in column_position.
Hence add 1 to each index
*/
int iter=0;
for (;iter < nz_ele ; ++iter) column_position[iter]++;
}
else { //If termination status is abnormal
sciprint("\nFunction invoked unsuccessfully.\n");
sciprint("\n Is a problem loaded ? \n");
}
}
else //If termination status of any of functions is abnormal
sciprint("\nFunction invoked unsuccessfully.\n");
}
//Copy the result to scilab. Location is position next to input arguments.
SciErr err=createSparseMatrix(pvApiCtx,nbInputArgument(pvApiCtx)+1,rows,columns,nz_ele,count_per_row,column_position,new_list);
/*
*Free allocated memory before exit
*/
free(row_indices);
free(column_start);
free(elements);
free(new_list);
free(count_per_row);
free(column_position);
if (err.iErr){ //Process error
printError(&err, 0);
AssignOutputVariable(pvApiCtx, 1) = 0;
return 1;
}
//assign result position to output argument
AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;
//ReturnArguments(pvApiCtx);
return 0;
}
}
/*
* It converts column-major representation to row-major representation
* :: ARGUMENTS ::
* rows - No. of rows IN
* columns - No. of columns IN
* nz_ele - No. of non-zero elements IN
* elements - Non-zero elements in column-major representation IN
* row_indices - Row index( starts from 0 : symphony) of each non-zero element IN
* column_start - Starting index in elements of each column IN
* new_list - Non-zero elements in row-major representation OUT
* count_per_row - Count of non-zero elements in each row OUT
* column_position - Column index ( starts from 0 (we'll add 1 to each index later)) of each non-zero element OUT
*/
void column_major_to_row_major(int rows,int columns,int nz_ele,double *elements,int *row_indices,int *column_start,double *new_list,int *count_per_row,int *column_position) {
int iter=0,iter2,iter3=0,index=0;
for (iter=0;iter < rows;++iter) {
for (iter2=0;iter2 < nz_ele;++iter2) {
if (row_indices[iter2] == iter) {
count_per_row[iter]++; //Count of non-zero elements per row.
new_list[index]=elements[iter2];
for (iter3=0; iter3 < columns+1 ; ++iter3) {
if (iter2 < column_start[iter3])
break;
}
column_position[index] = iter3 - 1;
index++ ;
}
}
}
}
|