CR2RE Pipeline Reference Manual 1.6.7
hdrl_cat_utils.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2017 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "hdrl_cat_utils_sort.h"
21
22/*---------------------------------------------------------------------------*/
30/*----------------------------------------------------------------------------*/
31
34/* ---------------------------------------------------------------------------*/
48/* ---------------------------------------------------------------------------*/
49double fraction(double x, double y, double r_out)
50{
51 double r = sqrt(x * x + y * y);
52 double sqrt2o2 = 0.5 * CPL_MATH_SQRT2;
53
54 if (r > r_out + sqrt2o2) { /* Is it worth bothering? */
55 return 0.;
56 } else if (r < r_out - sqrt2o2) { /* Is it trivially all in? */
57 return(1.);
58 }
59
60 /* bugger - have to do some work then ... ok first ...
61 * use 8-fold symmetry to convert to 0-45 degree range */
62 x = fabs(x);
63 y = fabs(y);
64 if (y > x) {
65 double t = x;
66 x = y;
67 y = t;
68 }
69
70 /* If the angles are too close to cardinal points, then fudge something */
71 double tanao2;
72 double tanp2a;
73 double cosa;
74 if (x > 0. && y > 0.) {
75 tanao2 = 0.5 * y / x;
76 tanp2a = x / y;
77 cosa = x / sqrt(x * x + y * y);
78 } else {
79 tanao2 = 0.00005;
80 tanp2a = 10000.;
81 cosa = 1.;
82 }
83
84 /* only outer radius - compute linear intersections top and bot of pixel */
85 double frac;
86
87 double x_a = x - tanao2 + (r_out - r) / cosa;
88 if (x_a < x + 0.5) {
89
90 /* intersects */
91 double x_b = x + tanao2 + (r_out - r) / cosa;
92
93 /* three cases to consider */
94 if (x_a < x - 0.5) {
95 frac = 0.5 * CPL_MAX(0., x_b - (x - 0.5)) * CPL_MAX(0., x_b - (x - 0.5)) * tanp2a;
96 } else if (x_b > x + 0.5) {
97 frac = 1. - 0.5 * (x + 0.5 - x_a) * (x + 0.5 - x_a) * tanp2a;
98 } else {
99 frac = 0.5 - (x - x_a) + 0.5 * (x_b - x_a);
100 }
101
102 } else { /* missed entirely */
103 frac = 1.;
104 }
105
106 return frac;
107}
108
109/* ---------------------------------------------------------------------------*/
120/* ---------------------------------------------------------------------------*/
121void dchole(double a[IMNUM+1][IMNUM+1], double b[IMNUM+1], cpl_size n)
122{
123 double l[IMNUM + 1][IMNUM + 1];
124
125 cpl_boolean restart = CPL_FALSE;
126 do {
127
128 l[0][0] = sqrt(a[0][0]);
129
130 for (cpl_size k = 1; k < n && !restart; k++) {
131
132 for (cpl_size j = 0; j <= k - 1; j++) {
133
134 double sum = a[j][k];
135 if (j != 0) {
136 for (cpl_size i = 0; i <= j - 1; i++) sum -= l[i][k] * l[i][j];
137 }
138
139 l[j][k] = sum / l[j][j];
140 }
141
142 double sum = a[k][k];
143 for (cpl_size i = 0; i <= k - 1; i++) {
144 sum -= l[i][k] * l[i][k];
145 }
146
147 /* if true -> warning: matrix ill-conditioned. max eigenvalue < trace. Offset added to diagonal */
148 if (sum <= 0.) {
149
150 double aveigv = a[0][0];
151 for (cpl_size i = 1; i < n; i++) aveigv += a[i][i];
152
153 double offset = 0.1 * aveigv / (double)n;
154 for (cpl_size i = 0; i < n; i++) a[i][i] += offset;
155
156 restart = CPL_TRUE;
157 }
158
159 if (!restart) {
160 l[k][k] = sqrt(sum);
161 }
162 }
163
164 } while (restart);
165
166
167 double y[IMNUM + 1];
168
169 /* solve Ly = b */
170 y[0] = b[0] / l[0][0];
171 for (cpl_size i = 1; i < n; i++) {
172
173 double sum = b[i];
174 for (cpl_size k = 0; k <= i - 1; k++) {
175 sum -= l[k][i] * y[k];
176 }
177
178 y[i] = sum / l[i][i];
179 }
180
181 /* solve L(T)x = y */
182 b[n - 1] = y[n - 1] / l[n - 1][n - 1];
183 for (cpl_size i = n - 2; i >= 0; i--) {
184
185 double sum = y[i];
186 for (cpl_size k = i+1; k < n; k++) {
187 sum -= l[i][k] * b[k];
188 }
189
190 b[i] = sum / l[i][i];
191 }
192}
193
double fraction(double x, double y, double r_out)
Fraction of pixel bounded.
void dchole(double a[IMNUM+1][IMNUM+1], double b[IMNUM+1], cpl_size n)
Cholesky decomposition of definite symmetric matrix to solve Ax = b.