svd_3x4.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2020 Intel Corporation. All Rights Reserved.
3 
4 // Code generated by Matlab Coder
5 
6 #include "utils.h"
7 #include <limits>
8 #include <cmath>
9 #include <cstring>
10 
11 
12 namespace
13 {
14 
15  double b_xnrm2( int n, const double x[4], int ix0 )
16  {
17  double y;
18  double scale;
19  int kend;
20  int k;
21  double absxk;
22  double t;
23  y = 0.0;
24  if( n >= 1 )
25  {
26  if( n == 1 )
27  {
28  y = std::abs( x[ix0 - 1] );
29  }
30  else
31  {
32  scale = 3.3121686421112381E-170;
33  kend = (ix0 + n) - 1;
34  for( k = ix0; k <= kend; k++ )
35  {
36  absxk = std::abs( x[k - 1] );
37  if( absxk > scale )
38  {
39  t = scale / absxk;
40  y = 1.0 + y * t * t;
41  scale = absxk;
42  }
43  else
44  {
45  t = absxk / scale;
46  y += t * t;
47  }
48  }
49 
50  y = scale * std::sqrt( y );
51  }
52  }
53 
54  return y;
55  }
56 
57  double xnrm2( int n, const double x[12], int ix0 )
58  {
59  double y;
60  double scale;
61  int kend;
62  int k;
63  double absxk;
64  double t;
65  y = 0.0;
66  if( n >= 1 )
67  {
68  if( n == 1 )
69  {
70  y = std::abs( x[ix0 - 1] );
71  }
72  else
73  {
74  scale = 3.3121686421112381E-170;
75  kend = (ix0 + n) - 1;
76  for( k = ix0; k <= kend; k++ )
77  {
78  absxk = std::abs( x[k - 1] );
79  if( absxk > scale )
80  {
81  t = scale / absxk;
82  y = 1.0 + y * t * t;
83  scale = absxk;
84  }
85  else
86  {
87  t = absxk / scale;
88  y += t * t;
89  }
90  }
91 
92  y = scale * std::sqrt( y );
93  }
94  }
95 
96  return y;
97  }
98 
99  void b_xaxpy( int n, double a, const double x[12], int ix0, double y[3], int iy0 )
100  {
101  int ix;
102  int iy;
103  int i1;
104  int k;
105  if( (n < 1) || (a == 0.0) )
106  {
107  }
108  else
109  {
110  ix = ix0 - 1;
111  iy = iy0 - 1;
112  i1 = n - 1;
113  for( k = 0; k <= i1; k++ )
114  {
115  y[iy] += a * x[ix];
116  ix++;
117  iy++;
118  }
119  }
120  }
121 
122  void c_xaxpy( int n, double a, const double x[3], int ix0, double y[12], int iy0 )
123  {
124  int ix;
125  int iy;
126  int i2;
127  int k;
128  if( (n < 1) || (a == 0.0) )
129  {
130  }
131  else
132  {
133  ix = ix0 - 1;
134  iy = iy0 - 1;
135  i2 = n - 1;
136  for( k = 0; k <= i2; k++ )
137  {
138  y[iy] += a * x[ix];
139  ix++;
140  iy++;
141  }
142  }
143  }
144 
145  void xaxpy( int n, double a, int ix0, double y[12], int iy0 )
146  {
147  int ix;
148  int iy;
149  int i0;
150  int k;
151  if( (n < 1) || (a == 0.0) )
152  {
153  }
154  else
155  {
156  ix = ix0 - 1;
157  iy = iy0 - 1;
158  i0 = n - 1;
159  for( k = 0; k <= i0; k++ )
160  {
161  y[iy] += a * y[ix];
162  ix++;
163  iy++;
164  }
165  }
166  }
167 
168  double xdotc( int n, const double x[12], int ix0, const double y[12], int iy0 )
169  {
170  double d;
171  int ix;
172  int iy;
173  int k;
174  d = 0.0;
175  if( n >= 1 )
176  {
177  ix = ix0;
178  iy = iy0;
179  for( k = 0; k < n; k++ )
180  {
181  d += x[ix - 1] * y[iy - 1];
182  ix++;
183  iy++;
184  }
185  }
186 
187  return d;
188  }
189 
190  void xrotg( double * a, double * b, double * c, double * s )
191  {
192  double roe;
193  double absa;
194  double absb;
195  double scale;
196  double ads;
197  double bds;
198  roe = *b;
199  absa = std::abs( *a );
200  absb = std::abs( *b );
201  if( absa > absb )
202  {
203  roe = *a;
204  }
205 
206  scale = absa + absb;
207  if( scale == 0.0 )
208  {
209  *s = 0.0;
210  *c = 1.0;
211  *a = 0.0;
212  *b = 0.0;
213  }
214  else
215  {
216  ads = absa / scale;
217  bds = absb / scale;
218  scale *= std::sqrt( ads * ads + bds * bds );
219  if( roe < 0.0 )
220  {
221  scale = -scale;
222  }
223 
224  *c = *a / scale;
225  *s = *b / scale;
226  if( absa > absb )
227  {
228  *b = *s;
229  }
230  else if( *c != 0.0 )
231  {
232  *b = 1.0 / *c;
233  }
234  else
235  {
236  *b = 1.0;
237  }
238 
239  *a = scale;
240  }
241  }
242 
243 
244  // Test if value is not a number
245  inline bool rtIsNaN( double value ) { return (value != value); }
246 
247 } // anon namespace
248 
249 
250 void librealsense::algo::depth_to_rgb_calibration::svd_3x4( const double A[12], double U[3] )
251 {
252  double b_A[12];
253  double e[4];
254  double work[3];
255  bool apply_transform;
256  double s[4];
257  int k;
258  int qjj;
259  double r;
260  int m;
261  int iter;
262  double snorm;
263  double b;
264  int exitg1;
265  int q;
266  int qs;
267  bool exitg2;
268  double scale;
269  double sm;
270  double sqds;
271  memcpy( &b_A[0], &A[0], 12U * sizeof( double ) );
272  e[0] = 0.0;
273  e[1] = 0.0;
274  e[2] = 0.0;
275  e[3] = 0.0;
276  work[0] = 0.0;
277  work[1] = 0.0;
278  work[2] = 0.0;
279  apply_transform = false;
280  double nrm = xnrm2( 3, b_A, 1 );
281  if( nrm > 0.0 )
282  {
283  apply_transform = true;
284  if( b_A[0] < 0.0 )
285  {
286  nrm = -nrm;
287  }
288 
289  if( std::abs( nrm ) >= 1.0020841800044864E-292 )
290  {
291  r = 1.0 / nrm;
292  for( k = 1; k < 4; k++ )
293  {
294  b_A[k - 1] *= r;
295  }
296  }
297  else
298  {
299  for( k = 1; k < 4; k++ )
300  {
301  b_A[k - 1] /= nrm;
302  }
303  }
304 
305  b_A[0]++;
306  s[0] = -nrm;
307  }
308  else
309  {
310  s[0] = 0.0;
311  }
312 
313  for( k = 2; k < 5; k++ )
314  {
315  qjj = 3 * ( k - 1 );
316  if( apply_transform )
317  {
318  xaxpy( 3, -( xdotc( 3, b_A, 1, b_A, qjj + 1 ) / b_A[0] ), 1, b_A, qjj + 1 );
319  }
320 
321  e[k - 1] = b_A[qjj];
322  }
323 
324  nrm = b_xnrm2( 3, e, 2 );
325  if( nrm == 0.0 )
326  {
327  e[0] = 0.0;
328  }
329  else
330  {
331  if( e[1] < 0.0 )
332  {
333  e[0] = -nrm;
334  }
335  else
336  {
337  e[0] = nrm;
338  }
339 
340  r = e[0];
341  if( std::abs( e[0] ) >= 1.0020841800044864E-292 )
342  {
343  r = 1.0 / e[0];
344  for( k = 2; k < 5; k++ )
345  {
346  e[k - 1] *= r;
347  }
348  }
349  else
350  {
351  for( k = 2; k < 5; k++ )
352  {
353  e[k - 1] /= r;
354  }
355  }
356 
357  e[1]++;
358  e[0] = -e[0];
359  for( qjj = 2; qjj < 4; qjj++ )
360  {
361  work[qjj - 1] = 0.0;
362  }
363 
364  for( k = 2; k < 5; k++ )
365  {
366  b_xaxpy( 2, e[k - 1], b_A, 3 * ( k - 1 ) + 2, work, 2 );
367  }
368 
369  for( k = 2; k < 5; k++ )
370  {
371  c_xaxpy( 2, -e[k - 1] / e[1], work, 2, b_A, 3 * ( k - 1 ) + 2 );
372  }
373  }
374 
375  apply_transform = false;
376  nrm = xnrm2( 2, b_A, 5 );
377  if( nrm > 0.0 )
378  {
379  apply_transform = true;
380  if( b_A[4] < 0.0 )
381  {
382  nrm = -nrm;
383  }
384 
385  if( std::abs( nrm ) >= 1.0020841800044864E-292 )
386  {
387  r = 1.0 / nrm;
388  for( k = 5; k < 7; k++ )
389  {
390  b_A[k - 1] *= r;
391  }
392  }
393  else
394  {
395  for( k = 5; k < 7; k++ )
396  {
397  b_A[k - 1] /= nrm;
398  }
399  }
400 
401  b_A[4]++;
402  s[1] = -nrm;
403  }
404  else
405  {
406  s[1] = 0.0;
407  }
408 
409  for( k = 3; k < 5; k++ )
410  {
411  qjj = 1 + 3 * ( k - 1 );
412  if( apply_transform )
413  {
414  xaxpy( 2, -( xdotc( 2, b_A, 5, b_A, qjj + 1 ) / b_A[4] ), 5, b_A, qjj + 1 );
415  }
416 
417  e[k - 1] = b_A[qjj];
418  }
419 
420  nrm = b_xnrm2( 2, e, 3 );
421  if( nrm == 0.0 )
422  {
423  e[1] = 0.0;
424  }
425  else
426  {
427  if( e[2] < 0.0 )
428  {
429  e[1] = -nrm;
430  }
431  else
432  {
433  e[1] = nrm;
434  }
435 
436  r = e[1];
437  if( std::abs( e[1] ) >= 1.0020841800044864E-292 )
438  {
439  r = 1.0 / e[1];
440  for( k = 3; k < 5; k++ )
441  {
442  e[k - 1] *= r;
443  }
444  }
445  else
446  {
447  for( k = 3; k < 5; k++ )
448  {
449  e[k - 1] /= r;
450  }
451  }
452 
453  e[2]++;
454  e[1] = -e[1];
455  for( qjj = 3; qjj < 4; qjj++ )
456  {
457  work[2] = 0.0;
458  }
459 
460  for( k = 3; k < 5; k++ )
461  {
462  b_xaxpy( 1, e[k - 1], b_A, 3 * ( k - 1 ) + 3, work, 3 );
463  }
464 
465  for( k = 3; k < 5; k++ )
466  {
467  c_xaxpy( 1, -e[k - 1] / e[2], work, 3, b_A, 3 * ( k - 1 ) + 3 );
468  }
469  }
470 
471  m = 2;
472  s[2] = b_A[8];
473  s[3] = 0.0;
474  e[2] = b_A[11];
475  e[3] = 0.0;
476  iter = 0;
477  snorm = 0.0;
478  nrm = s[0];
479  if( s[0] != 0.0 )
480  {
481  nrm = std::abs( s[0] );
482  r = s[0] / nrm;
483  s[0] = nrm;
484  e[0] /= r;
485  }
486 
487  if( e[0] != 0.0 )
488  {
489  b = std::abs( e[0] );
490  r = b / e[0];
491  e[0] = b;
492  s[1] *= r;
493  }
494 
495  nrm = std::abs( nrm );
496  r = std::abs( e[0] );
497  if( ( nrm > r ) || rtIsNaN( r ) )
498  {
499  r = nrm;
500  }
501 
502  if( ! rtIsNaN( r ) )
503  {
504  snorm = r;
505  }
506 
507  nrm = s[1];
508  if( s[1] != 0.0 )
509  {
510  nrm = std::abs( s[1] );
511  r = s[1] / nrm;
512  s[1] = nrm;
513  e[1] /= r;
514  }
515 
516  if( e[1] != 0.0 )
517  {
518  b = std::abs( e[1] );
519  r = b / e[1];
520  e[1] = b;
521  s[2] = b_A[8] * r;
522  }
523 
524  nrm = std::abs( nrm );
525  r = std::abs( e[1] );
526  if( ( nrm > r ) || rtIsNaN( r ) )
527  {
528  r = nrm;
529  }
530 
531  if( ( ! ( snorm > r ) ) && ( ! rtIsNaN( r ) ) )
532  {
533  snorm = r;
534  }
535 
536  nrm = s[2];
537  if( s[2] != 0.0 )
538  {
539  nrm = std::abs( s[2] );
540  r = s[2] / nrm;
541  s[2] = nrm;
542  e[2] = b_A[11] / r;
543  }
544 
545  if( e[2] != 0.0 )
546  {
547  b = std::abs( e[2] );
548  r = b / e[2];
549  e[2] = b;
550  s[3] = 0.0 * r;
551  }
552 
553  nrm = std::abs( nrm );
554  r = std::abs( e[2] );
555  if( ( nrm > r ) || rtIsNaN( r ) )
556  {
557  r = nrm;
558  }
559 
560  if( ( ! ( snorm > r ) ) && ( ! rtIsNaN( r ) ) )
561  {
562  snorm = r;
563  }
564 
565  if( s[3] != 0.0 )
566  {
567  s[3] = std::numeric_limits< double >::quiet_NaN(); // rtNaN;
568  }
569 
570  if( ! ( snorm > 0.0 ) )
571  {
572  snorm = 0.0;
573  }
574 
575  while( ( m + 2 > 0 ) && ( iter < 75 ) )
576  {
577  qjj = m;
578  do
579  {
580  exitg1 = 0;
581  q = qjj + 1;
582  if( qjj + 1 == 0 )
583  {
584  exitg1 = 1;
585  }
586  else
587  {
588  nrm = std::abs( e[qjj] );
589  if( ( nrm
590  <= 2.2204460492503131E-16 * ( std::abs( s[qjj] ) + std::abs( s[qjj + 1] ) ) )
591  || ( nrm <= 1.0020841800044864E-292 )
592  || ( ( iter > 20 ) && ( nrm <= 2.2204460492503131E-16 * snorm ) ) )
593  {
594  e[qjj] = 0.0;
595  exitg1 = 1;
596  }
597  else
598  {
599  qjj--;
600  }
601  }
602  } while( exitg1 == 0 );
603 
604  if( qjj + 1 == m + 1 )
605  {
606  qjj = 4;
607  }
608  else
609  {
610  qs = m + 2;
611  k = m + 2;
612  exitg2 = false;
613  while( ( ! exitg2 ) && ( k >= qjj + 1 ) )
614  {
615  qs = k;
616  if( k == qjj + 1 )
617  {
618  exitg2 = true;
619  }
620  else
621  {
622  nrm = 0.0;
623  if( k < m + 2 )
624  {
625  nrm = std::abs( e[k - 1] );
626  }
627 
628  if( k > qjj + 2 )
629  {
630  nrm += std::abs( e[k - 2] );
631  }
632 
633  r = std::abs( s[k - 1] );
634  if( ( r <= 2.2204460492503131E-16 * nrm ) || ( r <= 1.0020841800044864E-292 ) )
635  {
636  s[k - 1] = 0.0;
637  exitg2 = true;
638  }
639  else
640  {
641  k--;
642  }
643  }
644  }
645 
646  if( qs == qjj + 1 )
647  {
648  qjj = 3;
649  }
650  else if( qs == m + 2 )
651  {
652  qjj = 1;
653  }
654  else
655  {
656  qjj = 2;
657  q = qs;
658  }
659  }
660 
661  switch( qjj )
662  {
663  case 1:
664  r = e[m];
665  e[m] = 0.0;
666  qjj = m + 1;
667  for( k = qjj; k >= q + 1; k-- )
668  {
669  xrotg( &s[k - 1], &r, &sm, &sqds );
670  if( k > q + 1 )
671  {
672  r = -sqds * e[k - 2];
673  e[k - 2] *= sm;
674  }
675  }
676  break;
677 
678  case 2:
679  r = e[q - 1];
680  e[q - 1] = 0.0;
681  for( k = q + 1; k <= m + 2; k++ )
682  {
683  xrotg( &s[k - 1], &r, &sm, &sqds );
684  b = e[k - 1];
685  r = -sqds * b;
686  e[k - 1] = b * sm;
687  }
688  break;
689 
690  case 3:
691  qjj = m + 1;
692  scale = std::abs( s[m + 1] );
693  r = std::abs( s[m] );
694  if( ( ! ( scale > r ) ) && ( ! rtIsNaN( r ) ) )
695  {
696  scale = r;
697  }
698 
699  r = std::abs( e[m] );
700  if( ( ! ( scale > r ) ) && ( ! rtIsNaN( r ) ) )
701  {
702  scale = r;
703  }
704 
705  r = std::abs( s[q] );
706  if( ( ! ( scale > r ) ) && ( ! rtIsNaN( r ) ) )
707  {
708  scale = r;
709  }
710 
711  r = std::abs( e[q] );
712  if( ( ! ( scale > r ) ) && ( ! rtIsNaN( r ) ) )
713  {
714  scale = r;
715  }
716 
717  sm = s[m + 1] / scale;
718  nrm = s[m] / scale;
719  r = e[m] / scale;
720  sqds = s[q] / scale;
721  b = ( ( nrm + sm ) * ( nrm - sm ) + r * r ) / 2.0;
722  nrm = sm * r;
723  nrm *= nrm;
724  if( ( b != 0.0 ) || ( nrm != 0.0 ) )
725  {
726  r = std::sqrt( b * b + nrm );
727  if( b < 0.0 )
728  {
729  r = -r;
730  }
731 
732  r = nrm / ( b + r );
733  }
734  else
735  {
736  r = 0.0;
737  }
738 
739  r += ( sqds + sm ) * ( sqds - sm );
740  nrm = sqds * ( e[q] / scale );
741  for( k = q + 1; k <= qjj; k++ )
742  {
743  xrotg( &r, &nrm, &sm, &sqds );
744  if( k > q + 1 )
745  {
746  e[k - 2] = r;
747  }
748 
749  b = e[k - 1];
750  nrm = s[k - 1];
751  e[k - 1] = sm * b - sqds * nrm;
752  r = sqds * s[k];
753  s[k] *= sm;
754  s[k - 1] = sm * nrm + sqds * b;
755  xrotg( &s[k - 1], &r, &sm, &sqds );
756  b = e[k - 1];
757  r = sm * b + sqds * s[k];
758  s[k] = -sqds * b + sm * s[k];
759  nrm = sqds * e[k];
760  e[k] *= sm;
761  }
762 
763  e[m] = r;
764  iter++;
765  break;
766 
767  default:
768  if( s[q] < 0.0 )
769  {
770  s[q] = -s[q];
771  }
772 
773  qjj = q + 1;
774  while( ( q + 1 < 4 ) && ( s[q] < s[qjj] ) )
775  {
776  nrm = s[q];
777  s[q] = s[qjj];
778  s[qjj] = nrm;
779  q = qjj;
780  qjj++;
781  }
782 
783  iter = 0;
784  m--;
785  break;
786  }
787  }
788 
789  U[0] = s[0];
790  U[1] = s[1];
791  U[2] = s[2];
792 }
GLboolean GLboolean GLboolean b
GLint y
GLint i1
GLdouble s
const GLfloat * m
Definition: glext.h:6814
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:10806
GLfloat value
static bool rtIsNaN(double value)
d
Definition: rmse.py:171
GLdouble n
Definition: glext.h:1966
e
Definition: rmse.py:177
GLdouble t
GLboolean GLboolean GLboolean GLboolean a
const GLubyte * c
Definition: glext.h:12690
GLdouble GLdouble r
GLdouble x
GLdouble GLdouble GLdouble q
void svd_3x4(const double in[12], double out[3])
Definition: svd_3x4.cpp:250
GLint GLint i2


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:50:11