1 #include "svd_si.h"
2 #ifdef HAVE_SVD
3 
4 /************************************************************************
5 Storage of mpfr lists
6 ************************************************************************/
7 std::vector< amp::mpfr_record* > _mpfr_storage_v;
8 VAR gmp_randstate_t _mpfr_storage_rs;
9 VAR bool _mpfr_storage_init = false;
10 
newMpfr(unsigned int Precision)11 amp::mpfr_record* amp::mpfr_storage::newMpfr(unsigned int Precision)
12 {
13     amp::mpfr_record_ptr &lst = getList(Precision);
14     if( lst==NULL )
15     {
16         amp::mpfr_record *rec = new amp::mpfr_record;
17         rec->Precision = Precision;
18         rec->refCount = 0;
19         mpfr_init2(rec->value, Precision);
20         rec->next = lst;
21         lst = rec;
22     }
23 
24     amp::mpfr_record *p = lst;
25     p->refCount = 1;
26     lst = lst->next;
27     return p;
28 }
29 
deleteMpfr(amp::mpfr_record * ref)30 void amp::mpfr_storage::deleteMpfr(amp::mpfr_record* ref)
31 {
32     amp::mpfr_record_ptr &lst = getList(ref->Precision);
33     ref->next = lst;
34     lst = ref;
35 }
36 
getRandState()37 gmp_randstate_t* amp::mpfr_storage::getRandState()
38 {
39     if( !_mpfr_storage_init )
40     {
41         time_t _timer;
42         gmp_randinit_default(_mpfr_storage_rs);
43         gmp_randseed_ui(_mpfr_storage_rs, (unsigned long int)(time(&_timer)));
44         _mpfr_storage_init = true;
45     }
46     return &_mpfr_storage_rs;
47 }
48 
49 /*amp::mpfr_storage::clearStorage()
50 {
51     unsigned int i;
52     amp::mpfr_record *p;
53     for(i=0; i<v.size(); i++)
54         while( v[i]!=NULL )
55         {
56             p = _mpfr_storage_v[i]->next;
57             mpfr_clear(_mpfr_storage_v[i]->value);
58             delete _mpfr_storage_v[i];
59             _mpfr_storage_v[i] = p;
60         }
61 }*/
62 
getList(unsigned int Precision)63 amp::mpfr_record_ptr& amp::mpfr_storage::getList(unsigned int Precision)
64 {
65     static amp::mpfr_record_ptr tmp       = NULL;
66     STATIC_VAR int lastPrec                   = -1;
67     static amp::mpfr_record_ptr &lastList = tmp;
68     if( lastPrec!=Precision )
69     {
70         while( _mpfr_storage_v.size()<Precision+1 )
71             _mpfr_storage_v.push_back(NULL);
72         lastPrec = (int)Precision;
73         lastList = _mpfr_storage_v[Precision];
74     }
75     return lastList;
76 }
77 
78 
79 /************************************************************************
80 Storage of mpfr lists
81 ************************************************************************/
mpfr_reference()82 amp::mpfr_reference::mpfr_reference()
83 {
84     ref = NULL;
85 }
86 
mpfr_reference(const amp::mpfr_reference & r)87 amp::mpfr_reference::mpfr_reference(const amp::mpfr_reference& r)
88 {
89     ref = r.ref;
90     if( ref!=NULL )
91         ref->refCount++;
92 }
93 
operator =(const amp::mpfr_reference & r)94 amp::mpfr_reference& amp::mpfr_reference::operator= (
95     const amp::mpfr_reference &r)
96 {
97     if ( &r==this )
98         return *this;
99     if ( ref==r.ref )
100         return *this;
101     if( ref!=NULL )
102         free();
103     ref = r.ref;
104     if( ref!=NULL )
105         ref->refCount++;
106     return *this;
107 }
108 
~mpfr_reference()109 amp::mpfr_reference::~mpfr_reference()
110 {
111     if( ref!=NULL )
112         free();
113 }
114 
initialize(int Precision)115 void amp::mpfr_reference::initialize(int Precision)
116 {
117     if( ref!=NULL )
118         free();
119     ref = amp::mpfr_storage::newMpfr(Precision);
120     ref->refCount = 1;
121 }
122 
free()123 void amp::mpfr_reference::free()
124 {
125     if( ref==NULL )
126         //throw amp::internalError();
127 	{WerrorS("internalError");return;}
128     ref->refCount--;
129     if( ref->refCount==0 )
130         amp::mpfr_storage::deleteMpfr(ref);
131     ref = NULL;
132 }
133 
getReadPtr() const134 mpfr_srcptr amp::mpfr_reference::getReadPtr() const
135 {
136     if( ref==NULL )
137         //throw amp::internalError();
138 	{WerrorS("internalError");return NULL;}
139     return ref->value;
140 }
141 
getWritePtr()142 mpfr_ptr amp::mpfr_reference::getWritePtr()
143 {
144     if( ref==NULL )
145         //throw amp::internalError();
146 	{WerrorS("internalError");return NULL;}
147     if( ref->refCount==1 )
148         return ref->value;
149 
150     amp::mpfr_record *newref = amp::mpfr_storage::newMpfr(ref->Precision);
151     mpfr_set(newref->value, ref->value, GMP_RNDN);
152 
153     free();
154     ref = newref;
155     return ref->value;
156 }
157 #endif
158