1 /* Copyright 2014-2018 The PySCF Developers. All Rights Reserved.
2 
3    Licensed under the Apache License, Version 2.0 (the "License");
4     you may not use this file except in compliance with the License.
5     You may obtain a copy of the License at
6 
7         http://www.apache.org/licenses/LICENSE-2.0
8 
9     Unless required by applicable law or agreed to in writing, software
10     distributed under the License is distributed on an "AS IS" BASIS,
11     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12     See the License for the specific language governing permissions and
13     limitations under the License.
14 
15  *
16  * Author: Qiming Sun <osirpt.sun@gmail.com>
17  */
18 
19 #include <stdlib.h>
20 #include <math.h>
21 #define MIN(X,Y)        ((X)<(Y) ? (X) : (Y))
22 #define MAX(X,Y)        ((X)>(Y) ? (X) : (Y))
23 
24 /*
25  * def condense(op, a, loc):
26  *     nd = loc[-1]
27  *     out = numpy.empty((nd,nd))
28  *     for i,i0 in enumerate(loc):
29  *         i1 = loc[i+1]
30  *         for j,j0 in enumerate(loc):
31  *             j1 = loc[j+1]
32  *             out[i,j] = op(a[i0:i1,j0:j1])
33  *     return out
34  */
35 
NPcondense(double (* op)(double *,int,int,int),double * out,double * a,int * loc_x,int * loc_y,int nloc_x,int nloc_y)36 void NPcondense(double (*op)(double *, int, int, int), double *out, double *a,
37                 int *loc_x, int *loc_y, int nloc_x, int nloc_y)
38 {
39         const size_t nj = loc_y[nloc_y];
40         const size_t Nloc_y = nloc_y;
41 #pragma omp parallel
42 {
43         int i, j, i0, j0, di, dj;
44 #pragma omp for
45         for (i = 0; i < nloc_x; i++) {
46                 i0 = loc_x[i];
47                 di = loc_x[i+1] - i0;
48                 for (j = 0; j < nloc_y; j++) {
49                         j0 = loc_y[j];
50                         dj = loc_y[j+1] - j0;
51                         out[i*Nloc_y+j] = op(a+i0*nj+j0, nj, di, dj);
52                 }
53         }
54 }
55 }
56 
NP_sum(double * a,int nd,int di,int dj)57 double NP_sum(double *a, int nd, int di, int dj)
58 {
59         int i, j;
60         double out = 0;
61         for (i = 0; i < di; i++) {
62         for (j = 0; j < dj; j++) {
63                 out += a[i*nd+j];
64         } }
65         return out;
66 }
NP_max(double * a,int nd,int di,int dj)67 double NP_max(double *a, int nd, int di, int dj)
68 {
69         int i, j;
70         double out = a[0];
71         for (i = 0; i < di; i++) {
72         for (j = 0; j < dj; j++) {
73                 out = MAX(out, a[i*nd+j]);
74         } }
75         return out;
76 }
NP_min(double * a,int nd,int di,int dj)77 double NP_min(double *a, int nd, int di, int dj)
78 {
79         int i, j;
80         double out = a[0];
81         for (i = 0; i < di; i++) {
82         for (j = 0; j < dj; j++) {
83                 out = MIN(out, a[i*nd+j]);
84         } }
85         return out;
86 }
NP_abssum(double * a,int nd,int di,int dj)87 double NP_abssum(double *a, int nd, int di, int dj)
88 {
89         int i, j;
90         double out = 0;
91         for (i = 0; i < di; i++) {
92         for (j = 0; j < dj; j++) {
93                 out += fabs(a[i*nd+j]);
94         } }
95         return out;
96 }
NP_absmax(double * a,int nd,int di,int dj)97 double NP_absmax(double *a, int nd, int di, int dj)
98 {
99         int i, j;
100         double out = fabs(a[0]);
101         for (i = 0; i < di; i++) {
102         for (j = 0; j < dj; j++) {
103                 out = MAX(out, fabs(a[i*nd+j]));
104         } }
105         return out;
106 }
NP_absmin(double * a,int nd,int di,int dj)107 double NP_absmin(double *a, int nd, int di, int dj)
108 {
109         int i, j;
110         double out = fabs(a[0]);
111         for (i = 0; i < di; i++) {
112         for (j = 0; j < dj; j++) {
113                 out = MIN(out, fabs(a[i*nd+j]));
114         } }
115         return out;
116 }
NP_norm(double * a,int nd,int di,int dj)117 double NP_norm(double *a, int nd, int di, int dj)
118 {
119         int i, j;
120         double out = 0;
121         for (i = 0; i < di; i++) {
122         for (j = 0; j < dj; j++) {
123                 out += a[i*nd+j] * a[i*nd+j];
124         } }
125         return sqrt(out);
126 }
127