Statistics
| Revision:

root / branches / gvSIG_03_SLD / applications / appgvSIG / src / com / iver / cit / gvsig / gui / thememanager / legendmanager / panels / NaturalIntervalGenerator.java @ 2076

History | View | Annotate | Download (27.1 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (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
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.gui.thememanager.legendmanager.panels;
42

    
43
import com.hardcode.gdbms.engine.data.driver.DriverException;
44
import com.hardcode.gdbms.engine.values.DoubleValue;
45

    
46
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
47
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
48

    
49
import java.util.ArrayList;
50

    
51

    
52
/**
53
 * Calcula los intervalos naturales.
54
 *
55
 * @author Vicente Caballero Navarro
56
 */
57
public class NaturalIntervalGenerator {
58
        private AlphanumericData mLayer;
59
        private String msFieldName;
60
        private int miNumIntervalosSolicitados;
61
        private int miNumIntervalosGenerados;
62
        private double[] mdaValoresRuptura;
63

    
64
        /**
65
         * Crea un nuevo IntervalGenerator.
66
         *
67
         * @param layer AlphanumericData
68
         * @param field Nombre del campo.
69
         * @param numIntervals N?mero de intervalos.
70
         */
71
        public NaturalIntervalGenerator(AlphanumericData layer, String field,
72
                int numIntervals) {
73
                mLayer = layer;
74
                msFieldName = field;
75
                miNumIntervalosSolicitados = numIntervals;
76
        }
77

    
78
        /**
79
         * Esta funci?n busca en el vector de datos la posici?n que le corresponde
80
         * al valor almacenado en vdValor y devuelve dicha posici?n en
81
         * vdValorAInsertar. Para hallar la posici?n se realiza una b?squeda
82
         * binaria. Si se trata de un elemento que ya est? en el vector devolvemos
83
         * el ?ndice que le corresponde en rlIndiceCorrespondiente y false en
84
         * rbNuevoElemento. Si se trata de un nuevo elemento que hay que
85
         * insertar... devolvemos el ?ndice en el que ir?a y True en
86
         * rbNuevoElemento En caso de que ocurra alg?n error devuelve false
87
         *
88
         * @param rVectorDatos ArrayList con los datos.
89
         * @param vdValorAInsertar Valor a insertar.
90
         * @param rlIndiceCorrespondiente ?ndice.
91
         * @param rbNuevoElemento True si es un nuevo elemento.
92
         *
93
         * @return True si ha conseguido correctamente la posici?n en el vector.
94
         */
95
        private boolean mbObtenerPosicionEnVector(ArrayList rVectorDatos,
96
                double vdValorAInsertar, int[] rlIndiceCorrespondiente,
97
                boolean[] rbNuevoElemento) {
98
                int llIndiceIzq;
99
                int llIndiceDer;
100
                int llMedio;
101

    
102
                double ldValorComparacion;
103

    
104
                rbNuevoElemento[0] = false;
105
                rlIndiceCorrespondiente[0] = -1;
106

    
107
                //'Si el vector estiviese vac?o... (tuviese un s?lo elemento y el n?mero de coincidencias fuese 0)
108
                if (rVectorDatos.size() == 1) {
109
                        if (((udtDatosEstudio) rVectorDatos.get(0)).Coincidencias == 0) {
110
                                rlIndiceCorrespondiente[0] = 0;
111
                                rbNuevoElemento[0] = false; //'No tenemos que a?adir un nuevo elemento al vector
112

    
113
                                return true;
114
                        }
115
                }
116

    
117
                llIndiceIzq = 0;
118
                llIndiceDer = rVectorDatos.size() - 1;
119
                llMedio = (llIndiceIzq + llIndiceDer) / 2; //'Divisi?n entera!
120

    
121
                while (llIndiceIzq <= llIndiceDer) {
122
                        //'Coger el valor situado en la mitad de la zona de b?squeda como valor de comparaci?n
123
                        ldValorComparacion = ((udtDatosEstudio) rVectorDatos.get(llMedio)).Valor;
124

    
125
                        //'Si el valor a insertar es mayor que el valor de comparaci?n...
126
                        if (vdValorAInsertar > ldValorComparacion) {
127
                                //      'La zona de b?squeda queda restringida a la parte de la derecha
128
                                llIndiceIzq = llMedio + 1;
129
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
130

    
131
                                //    'Si el valor a insertar es menor que el valor de comparaci?n...
132
                        } else if (vdValorAInsertar < ldValorComparacion) {
133
                                //          'La zona de b?squeda queda restringida a la parte de la derecha
134
                                llIndiceDer = llMedio - 1;
135
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
136

    
137
                                //        'Si el valor de comparaci?n coincide con el valor a insertar
138
                        } else if (vdValorAInsertar == ldValorComparacion) {
139
                                rlIndiceCorrespondiente[0] = llMedio;
140
                                rbNuevoElemento[0] = false;
141

    
142
                                return true;
143
                        }
144
                }
145

    
146
                //  'Si llegamos a este punto es que no hemos encontrado el valor a insertar en el vector, es decir,
147
                //  'seguro que tendremos que a?adir un nuevo elemento.
148
                rbNuevoElemento[0] = true;
149

    
150
                //  'Nota:
151
                //  'En este caso (cuando en rbNuevoElemento se devuelve True) lo que hay que hacer al salir de esta funci?n
152
                //  'es a?adir un nuevo elemento al vector y desplazar todos los valores correspondientes a partir de rlIndiceCorrespondiente
153
                //  '?D?nde va el nuevo elemento?
154
                //  'El ?ltimo sitio estudiado viene dado por el valor de llMedio.
155
                //  'Si el valor a insertar es menor que el valor almacenado en la posici?n llMedio, el nuevo valor deber? ir a su izquierda.
156
                //  'Si fuera mayor deber?a ir a su derecha.
157
                ldValorComparacion = ((udtDatosEstudio) rVectorDatos.get(llMedio)).Valor;
158

    
159
                if (vdValorAInsertar > ldValorComparacion) {
160
                        rlIndiceCorrespondiente[0] = llMedio + 1;
161
                } else {
162
                        rlIndiceCorrespondiente[0] = llMedio;
163
                }
164

    
165
                return true;
166
        }
167

    
168
        /**
169
         * M?todo para generar los intervalos.
170
         *
171
         * @return true si se han generado correctamente.
172
         *
173
         * @throws com.iver.cit.gvsig.fmap.DriverException
174
         * @throws DriverException
175
         */
176
        public boolean generarIntervalos()
177
                throws com.iver.cit.gvsig.fmap.DriverException, DriverException {
178
                ArrayList lVectorDatos;
179
                double[] ldMediaTotal = new double[1];
180
                double[] ldSDAM = new double[1];
181

    
182
                int[] llaIndicesRupturas;
183

    
184
                double[] ldUltimaGVF = new double[1];
185
                double[] ldNuevaGVF = new double[1];
186

    
187
                int i;
188
                int liNumClasesReales;
189
                int llNumElementosPorClase;
190

    
191
                //    'Obtener los datos a estudiar ordenados ascendentemente y obtener la media total
192
                //ReDim lVectorDatos(0)
193
                lVectorDatos = new ArrayList();
194

    
195
                lVectorDatos.add(new udtDatosEstudio());
196

    
197
                if (!mbObtenerDatos(lVectorDatos, ldMediaTotal)) {
198
                        return false; //SalidaSinMensaje
199
                }
200

    
201
                System.out.println("Analizando datos ...");
202

    
203
                /// Call gEstablecerDescripcionProceso("Analizando datos ...", False)
204
                //  'Calcular la suma de las desviaciones t?picas del total de los datos respecto de la media total
205
                ldSDAM[0] = mbGetSumSquaredDeviationArrayMean(lVectorDatos,
206
                                ldMediaTotal[0]);
207

    
208
                ///if (lVectorDatos.length==0){
209
                if (lVectorDatos.isEmpty()) {
210
                        //      'S?lo se pueden generar dos intervalos -> hay un valor de ruptura
211
                        ///ReDim mdaValoresRuptura(0)
212
                        mdaValoresRuptura[0] = ((udtDatosEstudio) lVectorDatos.get(0)).Valor;
213
                        miNumIntervalosGenerados = 2;
214

    
215
                        return true;
216
                }
217

    
218
                //  'Calculamos el n?mero m?ximo de clases reales que podemos generar.
219
                //  'Este n?mero ser?a igual al n? de elementos que tenga el vector de datos.
220
                if (miNumIntervalosSolicitados > (lVectorDatos.size())) {
221
                        liNumClasesReales = lVectorDatos.size() + 1;
222
                } else {
223
                        liNumClasesReales = miNumIntervalosSolicitados;
224
                }
225

    
226
                //  'Establecemos las clases iniciales especificando unos ?ndices de ruptura en ppo. equidistantes
227
                llaIndicesRupturas = new int[liNumClasesReales - 1];
228
                llNumElementosPorClase = (lVectorDatos.size()) / liNumClasesReales;
229

    
230
                for (i = 0; i <llaIndicesRupturas.length; i++) {
231
                        if (i == 0) {
232
                                llaIndicesRupturas[i] = llNumElementosPorClase - 1;
233
                        } else {
234
                                llaIndicesRupturas[i] = llaIndicesRupturas[i - 1] +
235
                                        llNumElementosPorClase;
236
                        }
237
                }
238

    
239
                udtDatosClase[] ldaSDCM_Parciales = new udtDatosClase[llaIndicesRupturas.length+1];
240
                udtDatosClase[] ldaSDCM_Validos = new udtDatosClase[llaIndicesRupturas.length+1];
241

    
242
                ///ReDim ldaSDCM_Parciales(UBound(llaIndicesRupturas()) + 1)
243
                ///ReDim ldaSDCM_Validos(UBound(ldaSDCM_Parciales()) + 1)
244
                if (llaIndicesRupturas.length==0)return true;
245
                //  'Calcular la bondad inicial
246
                if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales, llaIndicesRupturas,
247
                                        ldSDAM[0], ldUltimaGVF, -1,false)) {
248
                        return false;
249
                }
250

    
251
                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
252

    
253
                boolean lbMoverADerecha;
254
                boolean lbMoverAIzquierda;
255
                boolean lbIntentarDesplazamiento;
256
                int llIndiceRupturaOriginal;
257

    
258
                long k;
259
                double ldGVFentrepasadas;
260

    
261
                ldGVFentrepasadas = ldUltimaGVF[0];
262

    
263
                //'liNumClasesReales no ser? muy grande (11 es el m?ximo)
264
                for (k = 1; k <= 100; k++) {
265
                        //      'Para cada ?ndice de ruptura...
266
                        for (i = 0; i < (llaIndicesRupturas.length); i++) {
267
                                lbMoverADerecha = false;
268
                                lbMoverAIzquierda = false;
269
                                llIndiceRupturaOriginal = llaIndicesRupturas[i];
270
                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
271

    
272
                                //'Hay que decidir hacia donde hay que desplazar el ?ndice de ruptura
273
                                //'Probamos moviendo a derecha (si se puede)
274
                                lbIntentarDesplazamiento = false;
275

    
276
                                if (i == (llaIndicesRupturas.length - 1)) {
277
                                        if ((llaIndicesRupturas[i] + 1) < lVectorDatos.size()) {
278
                                                lbIntentarDesplazamiento = true;
279
                                        }
280
                                } else {
281
                                        if ((llaIndicesRupturas[i] + 1) < llaIndicesRupturas[i + 1]) {
282
                                                lbIntentarDesplazamiento = true;
283
                                        } //'If (llaIndicesRupturas(i) + 1) < llaIndicesRupturas(i + 1) Then
284
                                } //'If i = UBound(llaIndicesRupturas) Then
285

    
286
                                if (lbIntentarDesplazamiento) {
287
                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] + 1;
288

    
289
                                        if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
290
                                                                llaIndicesRupturas, ldSDAM[0], ldNuevaGVF, i,
291
                                                                false)) {
292
                                                return false;
293
                                        }
294

    
295
                                        if (ldNuevaGVF[0] > ldUltimaGVF[0]) {
296
                                                lbMoverADerecha = true;
297
                                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
298
                                        } else {
299
                                                //'Dejamos el ?ndice de ruputura como estaba y probamos con un desplazamiento a izquierda
300
                                                llaIndicesRupturas[i] = llIndiceRupturaOriginal;
301
                                                ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
302
                                        }
303
                                } //'If lbIntentarDesplazamiento Then
304

    
305
                                lbIntentarDesplazamiento = false;
306

    
307
                                //'Probamos moviendo a izquierda (si se puede y no estamos moviendo ya a derechas)
308
                                if (!lbMoverADerecha) {
309
                                        if (i == 0) { //LBound(llaIndicesRupturas) Then
310

    
311
                                                if ((llaIndicesRupturas[i] - 1) >= 0) { //LBound(lVectorDatos()) Then
312
                                                        lbIntentarDesplazamiento = true;
313
                                                } //'If (llaIndicesRupturas(i) - 1) >= LBound(lVectorDatos()) Then
314
                                        } else {
315
                                                if ((llaIndicesRupturas[i] - 1) > llaIndicesRupturas[i -
316
                                                                1]) {
317
                                                        lbIntentarDesplazamiento = true;
318
                                                } //'If (llaIndicesRupturas(i) - 1) > llaIndicesRupturas(i - 1) Then
319
                                        } //'If i = LBound(llaIndicesRupturas) Then
320
                                } //'If Not lbMoverADerecha Then
321

    
322
                                if (lbIntentarDesplazamiento) {
323
                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] - 1;
324

    
325
                                        if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
326
                                                                llaIndicesRupturas, ldSDAM[0], ldNuevaGVF, i,
327
                                                                true)) {
328
                                                return false;
329
                                        }
330

    
331
                                        if (ldNuevaGVF[0] > ldUltimaGVF[0]) {
332
                                                lbMoverAIzquierda = true;
333
                                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
334
                                        } else {
335
                                                //'Dejamos el ?ndice de ruputura como estaba
336
                                                llaIndicesRupturas[i] = llIndiceRupturaOriginal;
337
                                                ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
338
                                        }
339
                                } //'If lbIntentarDesplazamiento Then
340

    
341
                                lbIntentarDesplazamiento = false;
342

    
343
                                //'Si se ha decidido desplazar el ?ndice ... continuamos hasta que no podamos mejorar la GVF
344
                                if (lbMoverAIzquierda || lbMoverADerecha) {
345
                                        ldUltimaGVF[0] = ldNuevaGVF[0];
346

    
347
                                        boolean exit = false;
348

    
349
                                        while (!exit) {
350
                                                llIndiceRupturaOriginal = llaIndicesRupturas[i];
351

    
352
                                                if (lbMoverADerecha) {
353
                                                        if (i == llaIndicesRupturas.length-1) {
354
                                                                if ((llaIndicesRupturas[i] + 1) >= lVectorDatos.size()) {
355
                                                                        exit = true;
356
                                                                }
357
                                                        } else {
358
                                                                if ((llaIndicesRupturas[i] + 1) >= llaIndicesRupturas[i +
359
                                                                                1]) {
360
                                                                        exit = true;
361
                                                                }
362
                                                        } //'If i = UBound(llaIndicesRupturas) Then
363

    
364
                                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] + 1;
365
                                                } else { //'If lbMoverAIzquierda Then
366

    
367
                                                        if (i == 0) { //LBound(llaIndicesRupturas) Then
368

    
369
                                                                if ((llaIndicesRupturas[i] - 1) < 0) { //LBound(lVectorDatos()) Then Exit Do
370
                                                                        exit = true;
371
                                                                }
372
                                                        } else {
373
                                                                if ((llaIndicesRupturas[i] - 1) <= llaIndicesRupturas[i -
374
                                                                                1]) {
375
                                                                        exit = true;
376
                                                                }
377
                                                        } //'If i = LBound(llaIndicesRupturas) Then
378

    
379
                                                        llaIndicesRupturas[i] = llaIndicesRupturas[i]-1;//////////////////
380
                                                } //'If lbMoverADerecha Then
381

    
382
                                                if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
383
                                                                        llaIndicesRupturas, ldSDAM[0], ldNuevaGVF,
384
                                                                        i, lbMoverAIzquierda)) {
385
                                                        return false;
386
                                                }
387

    
388
                                                if (ldNuevaGVF[0] < ldUltimaGVF[0]) {
389
                                                        // 'Dejar el ?ndice donde estaba
390
                                                        llaIndicesRupturas[i] = llIndiceRupturaOriginal;
391
                                                        ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
392
                                                        exit = true;
393
                                                } else {
394
                                                        ldUltimaGVF[0] = ldNuevaGVF[0];
395
                                                        ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
396
                                                }
397
                                        }
398
                                } //'If lbMoverAIzquierda Or lbMoverADerecha Then
399
                        }
400

    
401
                        if (ldUltimaGVF[0] <= ldGVFentrepasadas) {
402
                                i = 101;
403
                        }
404

    
405
                        ldGVFentrepasadas = ldUltimaGVF[0];
406
                }
407

    
408
                //   'A partir de aqu? ya no se puede cancelar nada
409
                mdaValoresRuptura = new double[llaIndicesRupturas.length];
410

    
411
                for (i = 0; i < mdaValoresRuptura.length; i++) { // LBound(mdaValoresRuptura) To UBound(mdaValoresRuptura)
412
                        mdaValoresRuptura[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i])).Valor;
413

    
414
                        //      'Hay que aplicar una peque?a correcci?n a los valores de ruptura para que los intervalos que genera
415
                        //    'mapobjects se aprechen en su totalidad, o lo que es lo mismo, vengan todos representados en el mapa.
416
                        //  'Con esto tambi?n se consigue hallar intervalos equivalentes a los de ArcView. Esta correcci?n consiste
417
                        //'en sumar el m?nimo incremento a los valores de ruptura. No lo hago aqu? sino en la ventana de propiedades de capa.
418
                }
419

    
420
                miNumIntervalosGenerados = mdaValoresRuptura.length + 2;
421

    
422
                ldaSDCM_Validos = null;
423
                ldaSDCM_Parciales = null;
424
                lVectorDatos = null;
425

    
426
                return true;
427
        }
428
        private udtDatosClase[] getArray(udtDatosClase[] array){
429
                udtDatosClase[] aux=new udtDatosClase[array.length];
430
                for (int i=0;i<array.length;i++){
431
                        aux[i]=new udtDatosClase();
432
                        aux[i].Media=array[i].Media;
433
                        aux[i].NumElementos=array[i].NumElementos;
434
                        aux[i].SDCM=array[i].SDCM;
435
                        aux[i].SumaCuadradoTotal=array[i].SumaCuadradoTotal;
436
                        aux[i].SumaTotal=array[i].SumaTotal;
437
                }
438
        return aux;
439
        }
440
        /**
441
         * Devuelve la "SDAM" de un conjunto de datos que vienen almacenados en el
442
         * vector rVectorDatos
443
         *
444
         * @param rVectorDatos Datos
445
         * @param vdMedia Media
446
         *
447
         * @return suma de las desviaciones t?picas del total de los datos respecto
448
         *                    de la media total
449
         */
450
        private double mbGetSumSquaredDeviationArrayMean(ArrayList rVectorDatos,
451
                double vdMedia) {
452
                int i;
453

    
454
                double rdSDAM = 0;
455

    
456
                for (i = 0; i < rVectorDatos.size(); i++) { // LBound(rVectorDatos) To UBound(rVectorDatos)
457
                        rdSDAM = rdSDAM +
458
                                (Math.pow((((udtDatosEstudio) rVectorDatos.get(i)).Valor -
459
                                        vdMedia), 2) * ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias);
460
                }
461

    
462
                return rdSDAM;
463
        }
464

    
465
        /**
466
         * Esta funci?n obtiene los datos en los que queremos hallar las rupturas
467
         * naturales. Los datos se devuelven ordenados en un vector. Tambi?n
468
         * devuelve la media total
469
         *
470
         * @param rVectorDatos Datos
471
         * @param rdMediaTotal Media total
472
         *
473
         * @return True si se ha calculado correctamente.
474
         *
475
         * @throws com.iver.cit.gvsig.fmap.DriverException
476
         * @throws DriverException
477
         */
478
        private boolean mbObtenerDatos(ArrayList rVectorDatos, double[] rdMediaTotal)
479
                throws com.iver.cit.gvsig.fmap.DriverException, DriverException {
480
                double ldValor;
481

    
482
                int i;
483
                long llRecordCount;
484

    
485
                int[] llIndice = new int[1];
486
                boolean[] lbNuevoElemento = new boolean[1];
487
                int j;
488

    
489
                SelectableDataSource sds = mLayer.getRecordset();
490
                llRecordCount = sds.getRowCount();
491

    
492
                if (!gbExisteCampoEnRegistro(mLayer.getRecordset(), msFieldName)) {
493
                        if (msFieldName == "") {
494
                                System.out.println(
495
                                        "No se ha establecido el nombre del campo origen!");
496
                        } else {
497
                                System.out.println("El campo '" + msFieldName +
498
                                        "' no pertence a la capa!");
499
                        }
500

    
501
                        return false;
502
                }
503

    
504
                // 'Nos cuidamos de recorrer todos los registros sin consultar la propiedad EOF del recordset
505
                for (i = 0; i < llRecordCount; i++) {
506
                        ldValor = ((DoubleValue) sds.getFieldValue(i,
507
                                        sds.getFieldIndexByName(msFieldName))).doubleValue(); //.Fields(msFieldName).Value;
508

    
509
                        rdMediaTotal[0] = rdMediaTotal[0] + ldValor;
510

    
511
                        //       'Hay que insertar el valor en la posici?n adecuada. Para ello hacemos una b?squeda binaria
512
                        if (!mbObtenerPosicionEnVector(rVectorDatos, ldValor, llIndice,
513
                                                lbNuevoElemento)) {
514
                                return false;
515
                        }
516

    
517
                        if (!lbNuevoElemento[0]) {
518
                                if ((llIndice[0] < 0) || (llIndice[0] > rVectorDatos.size())) {
519
                                        System.out.println("?ndice incorrecto!");
520

    
521
                                        return false;
522
                                }
523

    
524
                                ((udtDatosEstudio) rVectorDatos.get(llIndice[0])).Valor = ldValor; //'Por si fuese el primer elemento
525

    
526
                                //'Incrementamos el n? de coincidencias y damos el valor por insertado
527
                                ((udtDatosEstudio) rVectorDatos.get(llIndice[0])).Coincidencias = ((udtDatosEstudio) rVectorDatos.get(llIndice[0])).Coincidencias +
528
                                        1;
529
                        } else {
530
                                udtDatosEstudio udt = new udtDatosEstudio();
531
                                udt.Valor = ldValor;
532
                                udt.Coincidencias = 1;
533
                                rVectorDatos.add(llIndice[0], udt);
534
                        }
535
                }
536

    
537
                rdMediaTotal[0] = rdMediaTotal[0] / llRecordCount;
538

    
539
                return true;
540
        }
541

    
542
        /**
543
         * Devuelve true si existe el campo en el registro.
544
         *
545
         * @param recordset Recordset.
546
         * @param msFieldName2 Nombre del campo.
547
         *
548
         * @return True si existe el campo.
549
         *
550
         * @throws DriverException
551
         */
552
        private boolean gbExisteCampoEnRegistro(SelectableDataSource recordset,
553
                String msFieldName2) throws DriverException {
554
                if (recordset.getFieldIndexByName(msFieldName2) == -1) {
555
                        return false;
556
                }
557

    
558
                return true;
559
        }
560

    
561
        /**
562
         * Esta funci?n s?lo calcula las SDCM de las clases adyacentes al ?ndice de
563
         * ruptura actual. Si el ?ndice de ruptura actual es -1 entonces las
564
         * calcula todas! . En este caso no importa el valor de
565
         * vbDesplazAIzquierda
566
         *
567
         * @param rVectorDatos Datos
568
         * @param raClases Clases encontradas
569
         * @param rlaIndicesRuptura ?ndices de ruptura
570
         * @param vdSDAM suma de la desviaci?n standard.
571
         * @param rdGVF Desviaci?n standard de los intervalos.
572
         * @param vlIndiceRupturaActual ?ndice de ruptura actual.
573
         *
574
         * @return True si se ha calcula do correctamente.
575
         */
576
        private boolean mbCalcularGVF(ArrayList rVectorDatos,
577
                udtDatosClase[] raClases, int[] rlaIndicesRuptura, double vdSDAM,
578
                double[] rdGVF, int vlIndiceRupturaActual /* As Long = -1*/) {
579
                return mbCalcularGVF(rVectorDatos, raClases, rlaIndicesRuptura, vdSDAM,
580
                        rdGVF, vlIndiceRupturaActual, true);
581
        }
582

    
583
        /**
584
         * Esta funci?n s?lo calcula las SDCM de las clases adyacentes al ?ndice de
585
         * ruptura actual. Si el ?ndice de ruptura actual es -1 entonces las
586
         * calcula todas! . En este caso no importa el valor de
587
         * vbDesplazAIzquierda
588
         *
589
         * @param rVectorDatos Datos
590
         * @param raClases Calses que representan a los intervalos.
591
         * @param rlaIndicesRuptura ?ndices de ruptura.
592
         * @param vdSDAM Desviaci?n standard.
593
         * @param rdGVF Desviaci?n standard de los intervalos.
594
         * @param vlIndiceRupturaActual ?ndice de ruptura actual.
595
         * @param vbDesplazAIzquierda Desplazamiento a la izquierda.
596
         *
597
         * @return True si se ha calculado correctamente.
598
         */
599
        private boolean mbCalcularGVF(ArrayList rVectorDatos,
600
                udtDatosClase[] raClases, int[] rlaIndicesRuptura, double vdSDAM,
601
                double[] rdGVF, int vlIndiceRupturaActual /* As Long = -1*/,
602
                boolean vbDesplazAIzquierda) {
603
                double ldSDCM_aux;
604

    
605
                int i;
606

    
607
                if (vlIndiceRupturaActual == -1) {
608
                        // 'Obtenemos los datos para todas las clases = intervalos
609
                        for (i = 0; i < rlaIndicesRuptura.length; i++) {
610
                                if (i == 0) { // LBound(rlaIndicesRuptura) Then
611

    
612
                                        if (!mbGetDatosClase(rVectorDatos, 0, rlaIndicesRuptura[i],
613
                                                                raClases, i)) {
614
                                                return false;
615
                                        }
616
                                } else {
617
                                        if (!mbGetDatosClase(rVectorDatos,
618
                                                                rlaIndicesRuptura[i - 1] + 1,
619
                                                                rlaIndicesRuptura[i], raClases, i)) {
620
                                                return false;
621
                                        }
622
                                }
623
                        }
624

    
625
                        //'Falta la ?ltima clase
626
                        if (!mbGetDatosClase(rVectorDatos,
627
                                                rlaIndicesRuptura[rlaIndicesRuptura.length-1] + 1,
628
                                                rVectorDatos.size()-1, raClases, raClases.length-1)) {
629
                                return false;
630
                        }
631
                } else {
632
                        i = vlIndiceRupturaActual;
633

    
634
                        //'Hay que determinar para qu? clases debemos volver a recalcular los datos en funci?n del ?ndice de ruptura que estamos modificando
635
                        if (vbDesplazAIzquierda) {
636
                                //  'Recalcular los datos de la clase izquierda
637
                                if (!mbRecalcularDatosClase(raClases,i, rVectorDatos,
638
                                                        rlaIndicesRuptura[i] + 1, vdSDAM, false)) {
639
                                        return false;
640
                                }
641

    
642
                                //  'Recalcular los datos de la clase derecha
643
                                if (!mbRecalcularDatosClase(raClases,i + 1, rVectorDatos,
644
                                                        rlaIndicesRuptura[i] + 1, vdSDAM, true)) {
645
                                        return false;
646
                                }
647
                        } else {
648
                                //  'Recalcular los datos de la clase izquierda
649
                                if (!mbRecalcularDatosClase(raClases,i, rVectorDatos,
650
                                                        rlaIndicesRuptura[i], vdSDAM, true)) {
651
                                        return false;
652
                                }
653

    
654
                                //  'Recalcular los datos de la clase derecha
655
                                if (!mbRecalcularDatosClase(raClases,i + 1, rVectorDatos,
656
                                                        rlaIndicesRuptura[i], vdSDAM, false)) {
657
                                        return false;
658
                                }
659
                        }
660
                }
661

    
662
                ldSDCM_aux = 0;
663

    
664
                for (i = 0; i < raClases.length; i++) { //LBound(raClases) To UBound(raClases)
665
                        ldSDCM_aux = ldSDCM_aux + raClases[i].SDCM;
666
                }
667

    
668
                rdGVF[0] = (vdSDAM - ldSDCM_aux) / vdSDAM;
669

    
670
                return true;
671
        }
672

    
673
        /**
674
         * Devuelve la "SDCM" de un conjunto de datos que vienen almacenados en el
675
         * vector rVectorDatos y que est?n delimitados por vlLimiteInf y
676
         * vlLimiteInf
677
         *
678
         * @param rVectorDatos Datos
679
         * @param vlLimiteInf L?mite inferior.
680
         * @param vlLimiteSup L?mite superior.
681
         * @param rClase Calses que representan a los intervalos.
682
         * @param numClas N?mero de calses.
683
         *
684
         * @return True si se ha calculado correctamente.
685
         */
686
        private boolean mbGetDatosClase(ArrayList rVectorDatos, int vlLimiteInf,
687
                int vlLimiteSup, udtDatosClase[] rClase, int numClas) {
688
                int i;
689

    
690
                if (vlLimiteInf < 0) {
691
                        return false;
692
                }
693

    
694
                if (vlLimiteSup > rVectorDatos.size()) {
695
                        return false;
696
                }
697

    
698
                if (vlLimiteSup < vlLimiteInf) {
699
                        return false;
700
                }
701

    
702
                // 'Inicializamos los datos de la clase
703
                rClase[numClas] = new udtDatosClase();
704
                
705
                //'Hallamos la media de la clase
706
                for (i = vlLimiteInf; i < vlLimiteSup+1; i++) {
707
                        rClase[numClas].NumElementos = rClase[numClas].NumElementos +
708
                                ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias;
709

    
710
                        //'rClase.Media = rClase.Media + (rVectorDatos(i).Valor * rVectorDatos(i).Coincidencias)
711
                        rClase[numClas].SumaTotal = rClase[numClas].SumaTotal +
712
                                (((udtDatosEstudio) rVectorDatos.get(i)).Valor * ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias);
713

    
714
                        //'rClase.ProductoTotal = rClase.ProductoTotal * (rVectorDatos(i).Valor * rVectorDatos(i).Coincidencias)
715
                        rClase[numClas].SumaCuadradoTotal = rClase[numClas].SumaCuadradoTotal +
716
                                (Math.pow(((udtDatosEstudio) rVectorDatos.get(i)).Valor * ((udtDatosEstudio) rVectorDatos.get(
717
                                                i)).Coincidencias, 2));
718
                }
719

    
720
                //'rClase.Media = rClase.Media / llTotalElementos
721
                rClase[numClas].Media = rClase[numClas].SumaTotal / rClase[numClas].NumElementos;
722
                rClase[numClas].SDCM = (rClase[numClas].SumaCuadradoTotal) -
723
                        (2 * rClase[numClas].Media * rClase[numClas].SumaTotal) +
724
                        (rClase[numClas].NumElementos * Math.pow(rClase[numClas].Media, 2));
725

    
726
                return true;
727
        }
728

    
729
        /**
730
         * Recalcula los datos de las clases.
731
         *
732
         * @param rClase Clases.
733
         * @param rVectorDatos Datos.
734
         * @param vlIndiceElemento es el ?ndice del elemento que se le va a?adir o
735
         *                   a quitar a la clase
736
         * @param vdSDAM desviaci?n standard.
737
         * @param vbA ?adir ?adir ?adir ?adir indica si a la clase se le a?ade un
738
         *                   elemento (True) o se le quita (False)
739
         *
740
         * @return True si se ha calculado correctamente.
741
         */
742
        private boolean mbRecalcularDatosClase(udtDatosClase[] rClase,int i,
743
                ArrayList rVectorDatos, int vlIndiceElemento, double vdSDAM,
744
                boolean vbA?adir) {
745
                double ldValor;
746
                long llNumCoincidencias;
747

    
748
                ldValor = ((udtDatosEstudio) rVectorDatos.get(vlIndiceElemento)).Valor;
749
                llNumCoincidencias = ((udtDatosEstudio) rVectorDatos.get(vlIndiceElemento)).Coincidencias;
750

    
751
                if (vbA?adir) {
752
                        //'Actualizamos la suma total
753
                        rClase[i].SumaTotal = rClase[i].SumaTotal +
754
                                (ldValor * llNumCoincidencias);
755

    
756
                        //'Actualizamos la suma de cuadrados total
757
                        rClase[i].SumaCuadradoTotal = rClase[i].SumaCuadradoTotal +
758
                                (Math.pow((ldValor * llNumCoincidencias), 2));
759

    
760
                        //'Actualizamos el producto total
761
                        //'rClase.ProductoTotal = rClase.ProductoTotal * (ldValor * llNumCoincidencias)
762
                        //'Actualizamos el n? de elementos
763
                        rClase[i].NumElementos = rClase[i].NumElementos + llNumCoincidencias;
764
                } else {
765
                        //'Actualizamos la suma total
766
                        rClase[i].SumaTotal = rClase[i].SumaTotal -
767
                                (ldValor * llNumCoincidencias);
768

    
769
                        // 'Actualizamos la suma de cuadrados total
770
                        rClase[i].SumaCuadradoTotal = rClase[i].SumaCuadradoTotal -
771
                                (Math.pow((ldValor * llNumCoincidencias), 2));
772

    
773
                        // 'Actualizamos el producto total
774
                        // 'rClase.ProductoTotal = rClase.ProductoTotal / (ldValor * llNumCoincidencias)
775
                        // 'Actualizamos el n? de elementos
776
                        rClase[i].NumElementos = rClase[i].NumElementos - llNumCoincidencias;
777
                } // 'If vbA?adir Then
778

    
779
                //'Obtenemos la nueva media
780
                rClase[i].Media = rClase[i].SumaTotal / rClase[i].NumElementos;
781

    
782
                //'Actualizamos la SDCM
783
                rClase[i].SDCM = (rClase[i].SumaCuadradoTotal) -
784
                        (2 * rClase[i].Media * rClase[i].SumaTotal) +
785
                        (rClase[i].NumElementos * Math.pow(rClase[i].Media, 2));
786

    
787
                return true;
788
        }
789

    
790
        /**
791
         * Devuelve el valor de ruptura seg?n el ?ndice que se le pasa como
792
         * par?metro.
793
         *
794
         * @param viIndice ?nidice del valor de ruptura.
795
         *
796
         * @return Valor de ruptura.
797
         */
798
        public double getValorRuptura(int viIndice) {
799
                return mdaValoresRuptura[viIndice];
800
        }
801

    
802
        /**
803
         * Devuelve el n?mero de intervalos que se pueden representar, no tiene
804
         * porque coincidir con el n?mero de intervalos que se piden.
805
         *
806
         * @return N?mero de intervalos calculados.
807
         */
808
        public int getNumIntervals() {
809
                return miNumIntervalosGenerados;
810
        }
811

    
812
        /**
813
         * Clase para contener los atributos Valor y coincidencias.
814
         *
815
         * @author Vicente Caballero Navarro
816
         */
817
        private class udtDatosEstudio {
818
                private double Valor; // 
819
                private long Coincidencias;
820
        }
821

    
822
        /**
823
         * Clase para contener los atributos: N?mero de Elementos. Media.
824
         * SumaTotal. SumaCuadradoTotal. Desviaci?n standard.
825
         *
826
         * @author Vicente Caballero Navarro
827
         */
828
        private class udtDatosClase {
829
                private long NumElementos; //             'N? total de elementos que hay en la clase
830
                private double Media; //                 'Media de la clase
831
                private double SumaTotal; //              'Suma total de los elementos
832

    
833
                //'ProductoTotal          'Producto total de los elementos '?dar? problemas de desbordamiento?
834
                private double SumaCuadradoTotal; //      'Suma del total de los cuadrados de los elementos
835
                private double SDCM; //                  'Suma de la desviaci?n t?pica de los elementos de la clase respecto de la media de la clase
836
        }
837
}