add noise for test & add fft check
authoryu.dongliang <18588496441@163.com>
Sun, 19 May 2024 08:59:51 +0000 (16:59 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 19 May 2024 08:59:51 +0000 (16:59 +0800)
12 files changed:
examples/sin_oscillator.cpk
examples/test.cpk [deleted file]
main.c
ses_core.h
ses_node_analysis.c
ses_step_simplify.c
ses_step_topo.c
test/Makefile
test/fft.c [new file with mode: 0644]
test/main.c
test/test.c [new file with mode: 0644]
test/v.txt [new file with mode: 0644]

index b6dd5c5d395cd8b8393eec277fd87321067ffb68..25cb122aff1f8b05b02288e083b2877f68692506 100644 (file)
Binary files a/examples/sin_oscillator.cpk and b/examples/sin_oscillator.cpk differ
diff --git a/examples/test.cpk b/examples/test.cpk
deleted file mode 100644 (file)
index ab37f70..0000000
Binary files a/examples/test.cpk and /dev/null differ
diff --git a/main.c b/main.c
index 869dd09bb9c2a4995c1146eaeb216883d14a1fb5..1d0596dea6c37ba097ad31982b4127cde99afc73 100644 (file)
--- a/main.c
+++ b/main.c
@@ -107,7 +107,7 @@ int main(int argc, char* argv[])
 
                printf("f: %s\n", f->name);
 
-               ses_steps_analyse(f, 1001);
+               ses_steps_analyse(f, 1000, 60 * 1000 + 10501);
        }
 #endif
 
index bfa81a3f1290f12a671ac07327ae05d1a1015227..1eda99c43ad0785d787e2cec72c70a9bae2a58b4 100644 (file)
@@ -247,7 +247,7 @@ void ses_elines_print    (ScfEfunction* f);
 int ses_layout_board (ScfEboard*    b);
 int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count);
 
-int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh);
+int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t ns, int64_t count);
 
 int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip,  ses_path_t* bridge);
 int ses_flow_find_pos  (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f);
index fd0874272ea4d7ed3863e04e96e29370bdea6eb6..8324cef06c38f405769fdee2ace188d351f8037a 100644 (file)
@@ -549,7 +549,7 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
        do {
                n_amplifiers = 0;
                memcpy(U, A, sizeof(double) * N * N);
-#if 1
+#if 0
                for (i = 0; i < N; i++) {
                        for (j = 0; j < N; j++)
                                printf("%8lg ", A[i * N + j]);
@@ -572,8 +572,8 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
                gsl_linalg_SV_decomp(&_A.matrix, &_V.matrix, &_S.vector, &_W.vector);
                gsl_linalg_SV_solve (&_A.matrix, &_V.matrix, &_S.vector, &_b.vector, &_X.vector);
 
-               scf_logi("X:\n");
-               gsl_vector_fprintf(stdout, &_X.vector, "%lg");
+//             scf_logi("X:\n");
+//             gsl_vector_fprintf(stdout, &_X.vector, "%lg");
 
                for (i = 0; i < nodes->size; i++) {
                        node      = nodes->data[i];
@@ -587,7 +587,7 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
 
                                        double dI = Ib * edge->npn_hfe - Ic;
 
-                                       if (dI < -1e-9) {
+                                       if (dI < -1e-10) {
                                                scf_logi("Ic: %lg, Ib: %lg, dI: %lg\n", Ic, Ib, dI);
 
                                                int k;
@@ -605,6 +605,9 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
                }
        } while (n_amplifiers > 0);
 
+       for (i = 0; i < N; i++)
+               scf_logi("%lg\n", X[i]);
+
        for (i = 0; i < nodes->size; i++) {
                node      = nodes->data[i];
 
@@ -644,7 +647,7 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
 
                                p0->dr = edge->r - p0->r;
                                p0->a  = edge->a;
-                               p1->a  = edge->a;
+                               p1->a  = c->pins[SCF_EDA_NPN_B]->a + c->pins[SCF_EDA_NPN_C]->a;
                                continue;
                        }
 
index fead9bf918f25523a261fa899d52e0dd53c6bdd7..2b1bdd49be189de4df4db3b20af462da0efbf521 100644 (file)
@@ -1,6 +1,8 @@
 #include<cairo/cairo.h>
 #include"ses_core.h"
 
+#define SHOW_BITS 1000000.0
+
 static void ses_text_a(cairo_t* cr, int x, int y, double a)
 {
        char text[64];
@@ -11,19 +13,19 @@ static void ses_text_a(cairo_t* cr, int x, int y, double a)
                cairo_set_source_rgb(cr, 0.0, 0.0, 0.7);
 
        if (a > 1e-1 || a < -1e-1) {
-               snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0);
+               snprintf(text, sizeof(text) - 1, "%lgA", (int64_t)(a * SHOW_BITS) / SHOW_BITS);
 
                cairo_move_to  (cr, x, y);
                cairo_show_text(cr, text);
 
        } else if (a > 1e-5 || a < -1e-5) {
-               snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0);
+               snprintf(text, sizeof(text) - 1, "%lgmA", (int64_t)(a * 1000.0 * SHOW_BITS) / SHOW_BITS);
 
                cairo_move_to  (cr, x, y);
                cairo_show_text(cr, text);
 
        } else if (a > 1e-9 || a < -1e-9) {
-               snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0);
+               snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000.0 * SHOW_BITS) / SHOW_BITS);
 
                cairo_move_to  (cr, x, y);
                cairo_show_text(cr, text);
@@ -40,19 +42,19 @@ static void ses_text_v(cairo_t* cr, int x, int y, double v)
                cairo_set_source_rgb(cr, 0.0, 0.0, 0.7);
 
        if (v > 1e-1 || v < -1e-1) {
-               snprintf(text, sizeof(text) - 1, "%lgv", (int)(v * 1000) / 1000.0);
+               snprintf(text, sizeof(text) - 1, "%lgv", (int64_t)(v * SHOW_BITS) / SHOW_BITS);
 
                cairo_move_to  (cr, x, y);
                cairo_show_text(cr, text);
 
        } else if (v > 1e-5 || v < -1e-5) {
-               snprintf(text, sizeof(text) - 1, "%lgmV", (int)(v * 1000000) / 1000.0);
+               snprintf(text, sizeof(text) - 1, "%lgmV", (int64_t)(v * 1000.0 * SHOW_BITS) / SHOW_BITS);
 
                cairo_move_to  (cr, x, y);
                cairo_show_text(cr, text);
 
        } else if (v > 1e-9 || v < -1e-9) {
-               snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(v * 1000000000LL) / 1000.0);
+               snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(v * 1000000.0 * SHOW_BITS) / SHOW_BITS);
 
                cairo_move_to  (cr, x, y);
                cairo_show_text(cr, text);
@@ -237,12 +239,12 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
                                ses_text_a(cr, c->x + 10, c->y + 25, c->a);
 
                                cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
-                               if (c->r > 1e6)
-                                       snprintf(text, sizeof(text) - 1, "%lgM", (int)(c->r / 10000) / 100.0);
-                               else if (c->r > 999)
-                                       snprintf(text, sizeof(text) - 1, "%lgk", (int)(c->r / 10) / 100.0);
+                               if (c->r + c->dr > 1e6)
+                                       snprintf(text, sizeof(text) - 1, "%lgM", (int64_t)(c->r + c->dr) / 1000.0);
+                               else if (c->r + c->dr > 999)
+                                       snprintf(text, sizeof(text) - 1, "%lgk", (int64_t)((c->r + c->dr) * 1000.0) / 1000000.0);
                                else
-                                       snprintf(text, sizeof(text) - 1, "%dΩ", (int)c->r);
+                                       snprintf(text, sizeof(text) - 1, "%lgΩ", (int64_t)((c->r + c->dr) * 1000.0) / 1000.0);
 
                                cairo_move_to  (cr, c->x + 4, c->y - 5);
                                cairo_show_text(cr, text);
@@ -340,7 +342,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
        }
 }
 
-int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh)
+int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t ns, int64_t count)
 {
        ScfEcomponent*   B;
        ScfEcomponent*   c;
@@ -359,6 +361,24 @@ int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t b
        cairo_fill(cr);
        cairo_stroke(cr);
 
+       cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+       cairo_set_font_size(cr, 20);
+       cairo_set_source_rgb(cr, 0, 0, 0);
+
+       int64_t t = ns * count;
+       int64_t s = t / 1000000000;
+       t %= 1000000000;
+       int64_t ms = t / 1000000;
+       t %= 1000000;
+       int64_t us = t / 1000;
+       t %= 1000;
+
+       uint8_t time[512];
+       snprintf(time, sizeof(time) - 1, "%ld,%ld,%ld,%ldns", s, ms, us, t);
+       cairo_move_to  (cr, 10, 20);
+       cairo_show_text(cr, time);
+       cairo_stroke(cr);
+
        long i;
        long j;
        long k;
@@ -423,29 +443,29 @@ int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t b
                                        n = snprintf(text, sizeof(text) - 1, "%lgv", B->pins[SCF_EDA_Battery_POS]->v);
 
                                else if (el->v > 1e-2 || el->v < -1e-2)
-                                       n = snprintf(text, sizeof(text) - 1, "%lgv", (int)(el->v * 1000) / 1000.0);
+                                       n = snprintf(text, sizeof(text) - 1, "%lgv", (int64_t)(el->v * SHOW_BITS) / SHOW_BITS);
 
                                else if (el->v > 1e-5 || el->v < -1e-5)
-                                       n = snprintf(text, sizeof(text) - 1, "%lgmV", (int)(el->v * 1000000) / 1000.0);
+                                       n = snprintf(text, sizeof(text) - 1, "%lgmV", (int64_t)(el->v * 1000.0 * SHOW_BITS) / SHOW_BITS);
                                else
-                                       n = snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(el->v * 1000000000LL) / 1000.0);
+                                       n = snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(el->v * 1000000.0 * SHOW_BITS) / SHOW_BITS);
 
                                // A of line
                                if (el->aout > 1e-1 || el->aout < -1e-1)
-                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgA", (int)(el->aout * 1000) / 1000.0);
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgA", (int64_t)(el->aout * SHOW_BITS) / SHOW_BITS);
 
                                else if (el->aout > 1e-5 || el->aout < -1e-5)
-                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgmA", (int)(el->aout * 1000000) / 1000.0);
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgmA", (int64_t)(el->aout * 1000.0 * SHOW_BITS) / SHOW_BITS);
                                else
-                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lguA", (int64_t)(el->aout * 1000000000LL) / 1000.0);
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lguA", (int64_t)(el->aout * 1000000.0 * SHOW_BITS) / SHOW_BITS);
 
                                if (el->ain > 1e-1 || el->ain < -1e-1)
-                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgA", (int)(el->ain * 1000) / 1000.0);
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgA", (int64_t)(el->ain * SHOW_BITS) / SHOW_BITS);
 
                                else if (el->ain > 1e-5 || el->ain < -1e-5)
-                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgmA", (int)(el->ain * 1000000) / 1000.0);
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgmA", (int64_t)(el->ain * 1000.0 * SHOW_BITS) / SHOW_BITS);
                                else
-                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lguA", (int64_t)(el->ain * 1000000000LL) / 1000.0);
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lguA", (int64_t)(el->ain * 1000000.0 * SHOW_BITS) / SHOW_BITS);
 
                                int cx = INT_MAX;
                                int cy = l->y0;
@@ -504,27 +524,28 @@ int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t b
 
 static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
 {
-       ScfEline* el;
+       static int64_t i = 0;
 
-       int i;
-#if 0
-       for (i = 0; i < f->n_elines; i++) {
-               el =        f->elines[i];
-
-               if (el->flags & SCF_EDA_PIN_OUT) {
-                       if (el->v < 1)
-                               return 0;
-                       else
-                               break;
-               }
-       }
+       char file[128];
+       snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", i);
+#if 1
+       if (count < 60 * 1000)
+               return 0;
 #endif
 
-       char file[128];
-       snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", count);
+       if (count % 10 == 0) {
+#if 1
+               static FILE* fp = NULL;
+               if (!fp)
+                       fp = fopen("v.txt", "w");
+
+               if (fp)
+                       fprintf(fp, "%ld, %lg\n", i, f->elines[4]->v);
+#endif
+//             ses_simplify_draw(f, file, f->x, f->y, f->w, f->h, ns, count);
+               i++;
+       }
 
-//     if (count % 100 < 5)
-               ses_simplify_draw(f, file, f->x, f->y, f->w, f->h);
        return 0;
 }
 
index 8717581b43a3e45f80f0860d5d3e793eb0475f05..9bf978a878a4ad9cdc89c7c36564ceea74a8cb4c 100644 (file)
@@ -1382,6 +1382,7 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t*
 {
        ses_path_t*      path;
        ScfEcomponent*   B;
+       ScfEcomponent*   R;
        ScfEline*        el;
 
        _topo_clear(f);
@@ -1402,7 +1403,21 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t*
        ret = _topo_bridge_connections(f, ctx->paths);
        if (ret < 0)
                return ret;
-
+#if 1
+//     if (count > 30000) {
+               R = f->components[10];
+
+               double w0 = 2 * 3.1415926 * 100;
+               double w1 = 2 * 3.1415926 * 1000;
+               double w2 = 2 * 3.1415926 * 5000;
+               double r0 = sin(w0 * ns * (count - 30000) / 1e9);
+               double r1 = sin(w1 * ns * (count - 30000) / 1e9);
+               double r2 = sin(w2 * ns * (count - 30000) / 1e9);
+               R->dr = 10.0 * (r0 + r1 + r2);
+
+               scf_logi("### c%ld->r: %lg, r: %lg\n", R->id, R->r, R->dr);
+//     }
+#endif
        int i;
        for (i = 0; i < ctx->paths->size; i++) {
                path      = ctx->paths->data[i];
index 637b0522c6428320eba7c0a5fad5adfe33c54d6f..34d479ec0a46c331261f604a1c6b5706416bb498 100644 (file)
@@ -1,5 +1,6 @@
 #CFILES += main.c
-CFILES += test.c
+#CFILES += test.c
+CFILES += fft.c
 CFILES += ../scf_eda_pack.c
 CFILES += ../pack/scf_pack.c
 
@@ -7,7 +8,7 @@ CFLAGS += -g
 CFLAGS += -I../
 CFLAGS += -I../pack
 
-LDFLAGS += -lcairo
+LDFLAGS += -lcairo -lm -lgsl -lgslcblas
 
 all:
        gcc $(CFLAGS) $(CFILES) $(LDFLAGS)
diff --git a/test/fft.c b/test/fft.c
new file mode 100644 (file)
index 0000000..f2384dc
--- /dev/null
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <math.h>
+#include <gsl/gsl_errno.h>
+#include <gsl/gsl_fft_complex.h>
+#include <gsl/gsl_fft_real.h>
+#include <gsl/gsl_fft_halfcomplex.h>
+
+#define REAL(z,i) ((z)[2*(i)])
+#define IMAG(z,i) ((z)[2*(i)+1])
+
+#define N 1024
+
+int main()
+{
+       double v;
+
+       int i;
+       int j;
+
+       FILE* fp = fopen("v.txt", "r");
+
+       double data[2 * N];
+
+       for (i = 0; i < N; i++) {
+               fscanf(fp, "%d, %lg", &j, &v);
+               REAL(data, i) = v;
+               IMAG(data, i) = 0.0;
+       }
+       gsl_fft_complex_radix2_forward(data, 1, N);
+
+       double Zmax = 0;
+       double sum  = 0;
+       int    imax = 0;
+
+       for (i = 0; i < N; i++) {
+
+               if (i > 0) {
+                       double real = REAL(data, i) / sqrt(N);
+                       double imag = IMAG(data, i) / sqrt(N);
+                       double Z    = sqrt(real * real + imag * imag);
+
+                       if (Zmax < Z) {
+                               Zmax = Z;
+                               imax = i;
+                       }
+
+                       sum += Z;
+               }
+
+               printf("%d, %lg %lg\n", i, REAL(data, i) / sqrt(N), IMAG(data, i) / sqrt(N));
+       }
+
+       double f = 100 * 1000 * imax / N;
+
+       printf("avg: %lg, Zmax: %lg, imax: %d, f: %lg\n", sum / (N - 1), Zmax, imax, f);
+
+       fclose(fp);
+       return 0;
+}
index 4e0a28498ca2658389e6841d70d2cda6cdb2269a..ea6a110488b06d8aa14b535788131ff9e794d0fe 100644 (file)
@@ -70,7 +70,7 @@ int main(int argc, char* argv[])
        EDA_PIN_ADD_PIN(R2, 0,                    B,  SCF_EDA_Battery_NEG);
 
        T0->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT;
-       T0->pins[SCF_EDA_NPN_C]->hfe    = 80;
+       T0->pins[SCF_EDA_NPN_C]->hfe    = 150;
 
        R1->r  = 1000 * 10;
        R2->r  = 1000 * 10;
@@ -82,6 +82,9 @@ int main(int argc, char* argv[])
        C1->uf = 0.01;
        C2->uf = 0.01;
        C3->uf = 0.01;
+       C1->r  = 1;
+       C2->r  = 1;
+       C3->r  = 1;
 
        scf_eboard__add_function(b, f);
 
diff --git a/test/test.c b/test/test.c
new file mode 100644 (file)
index 0000000..6c2816f
--- /dev/null
@@ -0,0 +1,63 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include"ses_core.h"
+
+int main(int argc, char* argv[])
+{
+       ScfEcomponent* B;
+
+       ScfEcomponent* R0;
+       ScfEcomponent* T0;
+       ScfEcomponent* R1;
+       ScfEcomponent* R2;
+
+       ScfEfunction*  f;
+       ScfEboard*     b;
+
+       b = scf_eboard__alloc();
+       f = scf_efunction__alloc("sin_oscillator");
+
+       EDA_INST_ADD_COMPONENT(f, B,  SCF_EDA_Battery);
+
+       B->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG;
+       B->pins[SCF_EDA_Battery_POS]->flags = SCF_EDA_PIN_POS;
+
+       EDA_INST_ADD_COMPONENT(f, R0, SCF_EDA_Resistor);
+       EDA_INST_ADD_COMPONENT(f, T0, SCF_EDA_NPN);
+       EDA_INST_ADD_COMPONENT(f, R1, SCF_EDA_Resistor);
+       EDA_INST_ADD_COMPONENT(f, R2, SCF_EDA_Resistor);
+
+       EDA_PIN_ADD_PIN(B,  SCF_EDA_Battery_POS,  R0, 1);
+       EDA_PIN_ADD_PIN(B,  SCF_EDA_Battery_POS,  R1, 1);
+
+       EDA_PIN_ADD_PIN(R0, 0,                    T0, SCF_EDA_NPN_B);
+       EDA_PIN_ADD_PIN(R1, 0,                    T0, SCF_EDA_NPN_C);
+       EDA_PIN_ADD_PIN(T0, SCF_EDA_NPN_E,        R2, 1);
+       EDA_PIN_ADD_PIN(R2, 0,                    B,  SCF_EDA_Battery_NEG);
+
+       T0->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT;
+       T0->pins[SCF_EDA_NPN_C]->hfe    = 80;
+
+       R0->r  = 1000 * 10;
+       R1->r  = 1000;
+       R2->r  = 100;
+
+       scf_eboard__add_function(b, f);
+
+       int      len = 0;
+       uint8_t* buf = NULL;
+
+       ScfEboard_pack(b, &buf, &len);
+       ScfEboard_free(b);
+       b = NULL;
+
+       FILE* fp = fopen("./test.cpk", "wb");
+       if (!fp)
+               return -EINVAL;
+
+       fwrite(buf, len, 1, fp);
+       fclose(fp);
+
+       return 0;
+}
diff --git a/test/v.txt b/test/v.txt
new file mode 100644 (file)
index 0000000..d858f69
--- /dev/null
@@ -0,0 +1,1051 @@
+0, 3.5787
+1, 3.68047
+2, 3.78351
+3, 3.88737
+4, 3.99158
+5, 4.0956
+6, 4.19892
+7, 4.30097
+8, 4.40122
+9, 4.49914
+10, 4.59422
+11, 4.68597
+12, 4.77396
+13, 4.85778
+14, 4.93709
+15, 5.01156
+16, 5.08091
+17, 5.1449
+18, 5.20328
+19, 5.25584
+20, 5.30236
+21, 5.34265
+22, 5.37647
+23, 5.40363
+24, 5.42389
+25, 5.43705
+26, 5.44291
+27, 5.44129
+28, 5.43205
+29, 5.41508
+30, 5.39032
+31, 5.35778
+32, 5.31752
+33, 5.26967
+34, 5.21441
+35, 5.15201
+36, 5.08275
+37, 5.00697
+38, 4.92505
+39, 4.83738
+40, 4.74436
+41, 4.64639
+42, 4.54389
+43, 4.43723
+44, 4.32683
+45, 4.21306
+46, 4.09631
+47, 3.97698
+48, 3.85548
+49, 3.73225
+50, 3.60774
+51, 3.48246
+52, 3.35693
+53, 3.23173
+54, 3.10744
+55, 2.9847
+56, 2.86413
+57, 2.74639
+58, 2.63211
+59, 2.52191
+60, 2.41636
+61, 2.31602
+62, 2.27093
+63, 2.37933
+64, 2.31907
+65, 2.26466
+66, 2.28757
+67, 2.30183
+68, 2.27642
+69, 2.30433
+70, 2.2949
+71, 2.29114
+72, 2.29311
+73, 2.30087
+74, 2.31448
+75, 2.334
+76, 2.35948
+77, 2.39095
+78, 2.42843
+79, 2.47188
+80, 2.52124
+81, 2.57638
+82, 2.63713
+83, 2.70327
+84, 2.7745
+85, 2.85051
+86, 2.93092
+87, 3.01533
+88, 3.10333
+89, 3.19448
+90, 3.28834
+91, 3.38451
+92, 3.48257
+93, 3.58212
+94, 3.68279
+95, 3.78423
+96, 3.88608
+97, 3.98799
+98, 4.08963
+99, 4.19063
+100, 4.29061
+101, 4.38918
+102, 4.4859
+103, 4.58033
+104, 4.67201
+105, 4.76045
+106, 4.84514
+107, 4.92562
+108, 5.0014
+109, 5.07203
+110, 5.13711
+111, 5.19626
+112, 5.24917
+113, 5.29556
+114, 5.33524
+115, 5.36804
+116, 5.39385
+117, 5.41259
+118, 5.42421
+119, 5.4287
+120, 5.42603
+121, 5.41622
+122, 5.39925
+123, 5.37513
+124, 5.34387
+125, 5.30547
+126, 5.25997
+127, 5.20742
+128, 5.14789
+129, 5.08152
+130, 5.00846
+131, 4.92895
+132, 4.84326
+133, 4.75174
+134, 4.65478
+135, 4.55284
+136, 4.4464
+137, 4.33598
+138, 4.22213
+139, 4.1054
+140, 3.98635
+141, 3.86552
+142, 3.74344
+143, 3.62063
+144, 3.49756
+145, 3.37471
+146, 3.25254
+147, 3.1315
+148, 3.01204
+149, 2.89461
+150, 2.77969
+151, 2.66775
+152, 2.5593
+153, 2.45487
+154, 2.35498
+155, 2.26024
+156, 2.26102
+157, 2.3029
+158, 2.30494
+159, 2.32172
+160, 2.28791
+161, 2.26952
+162, 2.29027
+163, 2.2798
+164, 2.2756
+165, 2.27766
+166, 2.28596
+167, 2.30041
+168, 2.32092
+169, 2.34736
+170, 2.37961
+171, 2.41753
+172, 2.461
+173, 2.5099
+174, 2.56409
+175, 2.62345
+176, 2.68786
+177, 2.75717
+178, 2.8312
+179, 2.90977
+180, 2.99264
+181, 3.07952
+182, 3.17008
+183, 3.26396
+184, 3.36072
+185, 3.45992
+186, 3.56105
+187, 3.66361
+188, 3.76707
+189, 3.87092
+190, 3.97465
+191, 4.07776
+192, 4.17979
+193, 4.28031
+194, 4.37892
+195, 4.47523
+196, 4.5689
+197, 4.65959
+198, 4.74698
+199, 4.83076
+200, 4.91058
+201, 4.98612
+202, 5.05704
+203, 5.12297
+204, 5.18355
+205, 5.23842
+206, 5.28719
+207, 5.32954
+208, 5.36513
+209, 5.39367
+210, 5.41493
+211, 5.4287
+212, 5.43487
+213, 5.43336
+214, 5.42416
+215, 5.40733
+216, 5.38296
+217, 5.35118
+218, 5.31219
+219, 5.26617
+220, 5.21333
+221, 5.1539
+222, 5.08811
+223, 5.01616
+224, 4.9383
+225, 4.85474
+226, 4.76573
+227, 4.67152
+228, 4.57239
+229, 4.46865
+230, 4.36066
+231, 4.24881
+232, 4.13355
+233, 4.01538
+234, 3.89483
+235, 3.77248
+236, 3.64893
+237, 3.52481
+238, 3.40075
+239, 3.27738
+240, 3.15531
+241, 3.03512
+242, 2.91737
+243, 2.80259
+244, 2.69125
+245, 2.5838
+246, 2.48067
+247, 2.38225
+248, 2.28892
+249, 2.381
+250, 2.31552
+251, 2.31703
+252, 2.26859
+253, 2.31632
+254, 2.28796
+255, 2.31161
+256, 2.2995
+257, 2.29332
+258, 2.29324
+259, 2.29939
+260, 2.31186
+261, 2.33068
+262, 2.35583
+263, 2.38724
+264, 2.42479
+265, 2.46828
+266, 2.51751
+267, 2.57221
+268, 2.63209
+269, 2.69686
+270, 2.76622
+271, 2.83985
+272, 2.91745
+273, 2.99875
+274, 3.08346
+275, 3.1713
+276, 3.262
+277, 3.35529
+278, 3.45086
+279, 3.54842
+280, 3.64761
+281, 3.74806
+282, 3.84937
+283, 3.95108
+284, 4.05271
+285, 4.15377
+286, 4.25372
+287, 4.35204
+288, 4.44819
+289, 4.54167
+290, 4.63199
+291, 4.71868
+292, 4.80134
+293, 4.87958
+294, 4.95309
+295, 5.02157
+296, 5.08478
+297, 5.14249
+298, 5.1945
+299, 5.24063
+300, 5.28071
+301, 5.31456
+302, 5.34199
+303, 5.36284
+304, 5.37691
+305, 5.38404
+306, 5.38405
+307, 5.37682
+308, 5.36221
+309, 5.34017
+310, 5.31067
+311, 5.27375
+312, 5.22948
+313, 5.17804
+314, 5.11964
+315, 5.05454
+316, 4.98307
+317, 4.90559
+318, 4.82249
+319, 4.73416
+320, 4.64103
+321, 4.5435
+322, 4.442
+323, 4.33691
+324, 4.22863
+325, 4.11755
+326, 4.00404
+327, 3.88849
+328, 3.77131
+329, 3.65292
+330, 3.53375
+331, 3.41429
+332, 3.29505
+333, 3.17656
+334, 3.05939
+335, 2.94414
+336, 2.83141
+337, 2.72181
+338, 2.61593
+339, 2.51434
+340, 2.41761
+341, 2.32621
+342, 2.33945
+343, 2.26971
+344, 2.29682
+345, 2.33427
+346, 2.29953
+347, 2.27064
+348, 2.28057
+349, 2.28396
+350, 2.27757
+351, 2.27703
+352, 2.28236
+353, 2.29359
+354, 2.31078
+355, 2.33394
+356, 2.36312
+357, 2.39832
+358, 2.43953
+359, 2.48669
+360, 2.5397
+361, 2.59843
+362, 2.66266
+363, 2.73216
+364, 2.80662
+365, 2.88568
+366, 2.96895
+367, 3.05602
+368, 3.14644
+369, 3.23977
+370, 3.33554
+371, 3.43334
+372, 3.53273
+373, 3.6333
+374, 3.73468
+375, 3.83649
+376, 3.93838
+377, 4.03999
+378, 4.14098
+379, 4.24098
+380, 4.33962
+381, 4.4365
+382, 4.53119
+383, 4.62327
+384, 4.71227
+385, 4.7977
+386, 4.87911
+387, 4.956
+388, 5.02792
+389, 5.09445
+390, 5.15519
+391, 5.20979
+392, 5.25795
+393, 5.29944
+394, 5.33408
+395, 5.36172
+396, 5.38228
+397, 5.39572
+398, 5.40202
+399, 5.40119
+400, 5.39325
+401, 5.37821
+402, 5.35612
+403, 5.32701
+404, 5.29091
+405, 5.24787
+406, 5.19794
+407, 5.1412
+408, 5.07776
+409, 5.00777
+410, 4.93143
+411, 4.84898
+412, 4.76073
+413, 4.66704
+414, 4.56832
+415, 4.46505
+416, 4.35773
+417, 4.24689
+418, 4.13308
+419, 4.01688
+420, 3.89884
+421, 3.7795
+422, 3.6594
+423, 3.53905
+424, 3.41893
+425, 3.2995
+426, 3.18122
+427, 3.06452
+428, 2.94984
+429, 2.83761
+430, 2.72828
+431, 2.62232
+432, 2.5202
+433, 2.42242
+434, 2.32949
+435, 2.31217
+436, 2.33284
+437, 2.2732
+438, 2.30019
+439, 2.3461
+440, 2.32083
+441, 2.30167
+442, 2.28875
+443, 2.28217
+444, 2.28196
+445, 2.2881
+446, 2.30052
+447, 2.31913
+448, 2.34381
+449, 2.3744
+450, 2.41075
+451, 2.4527
+452, 2.5001
+453, 2.55279
+454, 2.61063
+455, 2.67347
+456, 2.74115
+457, 2.81349
+458, 2.89032
+459, 2.9714
+460, 3.05648
+461, 3.14526
+462, 3.23739
+463, 3.33248
+464, 3.43009
+465, 3.52974
+466, 3.63094
+467, 3.73316
+468, 3.83588
+469, 3.93856
+470, 4.0407
+471, 4.14179
+472, 4.24138
+473, 4.33904
+474, 4.43437
+475, 4.52699
+476, 4.61658
+477, 4.7028
+478, 4.78535
+479, 4.86393
+480, 4.93823
+481, 5.00794
+482, 5.07273
+483, 5.13227
+484, 5.18623
+485, 5.23426
+486, 5.27603
+487, 5.31122
+488, 5.33954
+489, 5.36074
+490, 5.37461
+491, 5.381
+492, 5.37981
+493, 5.37101
+494, 5.35464
+495, 5.33077
+496, 5.29955
+497, 5.26116
+498, 5.21581
+499, 5.16374
+500, 5.10519
+501, 5.04043
+502, 4.9697
+503, 4.89327
+504, 4.81139
+505, 4.72431
+506, 4.63231
+507, 4.53567
+508, 4.43468
+509, 4.32968
+510, 4.22105
+511, 4.10919
+512, 3.99456
+513, 3.87767
+514, 3.75907
+515, 3.63932
+516, 3.51904
+517, 3.39885
+518, 3.27938
+519, 3.16123
+520, 3.04502
+521, 2.93131
+522, 2.82063
+523, 2.71348
+524, 2.61032
+525, 2.51158
+526, 2.41763
+527, 2.32885
+528, 2.28167
+529, 2.33358
+530, 2.27705
+531, 2.29317
+532, 2.33135
+533, 2.30576
+534, 2.28588
+535, 2.27219
+536, 2.29547
+537, 2.2966
+538, 2.30398
+539, 2.31772
+540, 2.33787
+541, 2.36442
+542, 2.39731
+543, 2.43644
+544, 2.48163
+545, 2.53266
+546, 2.58928
+547, 2.65117
+548, 2.71802
+549, 2.78949
+550, 2.86523
+551, 2.94489
+552, 3.02815
+553, 3.11467
+554, 3.20414
+555, 3.29625
+556, 3.3907
+557, 3.48719
+558, 3.58539
+559, 3.68496
+560, 3.78555
+561, 3.88675
+562, 3.98814
+563, 4.08927
+564, 4.18964
+565, 4.28873
+566, 4.38603
+567, 4.48101
+568, 4.57312
+569, 4.66188
+570, 4.74679
+571, 4.82742
+572, 4.90336
+573, 4.97427
+574, 5.03983
+575, 5.09979
+576, 5.15393
+577, 5.20207
+578, 5.24403
+579, 5.27968
+580, 5.30888
+581, 5.3315
+582, 5.34741
+583, 5.35649
+584, 5.35859
+585, 5.35359
+586, 5.3414
+587, 5.32192
+588, 5.29509
+589, 5.2609
+590, 5.21939
+591, 5.17064
+592, 5.11482
+593, 5.05213
+594, 4.98285
+595, 4.90731
+596, 4.82589
+597, 4.73899
+598, 4.64707
+599, 4.55057
+600, 4.44996
+601, 4.34571
+602, 4.23826
+603, 4.12805
+604, 4.01552
+605, 3.90108
+606, 3.78515
+607, 3.66813
+608, 3.55046
+609, 3.43257
+610, 3.31492
+611, 3.19799
+612, 3.0823
+613, 2.96839
+614, 2.85682
+615, 2.74817
+616, 2.64304
+617, 2.54201
+618, 2.44565
+619, 2.35452
+620, 2.26912
+621, 2.27739
+622, 2.26286
+623, 2.34326
+624, 2.30768
+625, 2.27821
+626, 2.27566
+627, 2.27375
+628, 2.27498
+629, 2.28097
+630, 2.28685
+631, 2.29877
+632, 2.31669
+633, 2.34062
+634, 2.37051
+635, 2.40637
+636, 2.44814
+637, 2.49578
+638, 2.54922
+639, 2.60835
+640, 2.673
+641, 2.74298
+642, 2.81803
+643, 2.89784
+644, 2.98205
+645, 3.07025
+646, 3.16201
+647, 3.25684
+648, 3.35427
+649, 3.4538
+650, 3.55494
+651, 3.65721
+652, 3.76015
+653, 3.86333
+654, 3.96634
+655, 4.06878
+656, 4.17027
+657, 4.27046
+658, 4.36898
+659, 4.46546
+660, 4.55953
+661, 4.65079
+662, 4.73884
+663, 4.82324
+664, 4.90355
+665, 4.97933
+666, 5.05011
+667, 5.11547
+668, 5.17497
+669, 5.22823
+670, 5.27491
+671, 5.3147
+672, 5.34737
+673, 5.37273
+674, 5.39067
+675, 5.40112
+676, 5.40405
+677, 5.3995
+678, 5.38753
+679, 5.36822
+680, 5.34168
+681, 5.308
+682, 5.26731
+683, 5.21971
+684, 5.16534
+685, 5.10432
+686, 5.03678
+687, 4.9629
+688, 4.88286
+689, 4.7969
+690, 4.70529
+691, 4.60836
+692, 4.50648
+693, 4.4001
+694, 4.2897
+695, 4.17581
+696, 4.05901
+697, 3.93987
+698, 3.81903
+699, 3.69708
+700, 3.57463
+701, 3.45226
+702, 3.33055
+703, 3.21002
+704, 3.09118
+705, 2.97451
+706, 2.86046
+707, 2.74948
+708, 2.642
+709, 2.53843
+710, 2.43922
+711, 2.3448
+712, 2.25764
+713, 2.393
+714, 2.33486
+715, 2.28227
+716, 2.26812
+717, 2.27953
+718, 2.28625
+719, 2.30347
+720, 2.29618
+721, 2.29536
+722, 2.30108
+723, 2.31335
+724, 2.33212
+725, 2.35729
+726, 2.38873
+727, 2.42625
+728, 2.46965
+729, 2.51868
+730, 2.57313
+731, 2.63274
+732, 2.69728
+733, 2.76651
+734, 2.84021
+735, 2.91815
+736, 3.00009
+737, 3.08581
+738, 3.17502
+739, 3.26746
+740, 3.36279
+741, 3.46066
+742, 3.56066
+743, 3.66235
+744, 3.76526
+745, 3.86886
+746, 3.97261
+747, 4.07598
+748, 4.1784
+749, 4.27933
+750, 4.37824
+751, 4.47464
+752, 4.56807
+753, 4.65809
+754, 4.74434
+755, 4.82645
+756, 4.90413
+757, 4.97707
+758, 5.04501
+759, 5.10769
+760, 5.16486
+761, 5.21627
+762, 5.26166
+763, 5.30076
+764, 5.33331
+765, 5.35905
+766, 5.37773
+767, 5.38912
+768, 5.39303
+769, 5.3893
+770, 5.37783
+771, 5.35855
+772, 5.3315
+773, 5.29674
+774, 5.25441
+775, 5.20473
+776, 5.14793
+777, 5.08431
+778, 5.01421
+779, 4.93796
+780, 4.85593
+781, 4.76848
+782, 4.67599
+783, 4.57881
+784, 4.4773
+785, 4.37181
+786, 4.26271
+787, 4.15037
+788, 4.03517
+789, 3.91752
+790, 3.79788
+791, 3.67672
+792, 3.55456
+793, 3.43196
+794, 3.30951
+795, 3.18783
+796, 3.06756
+797, 2.94934
+798, 2.83382
+799, 2.72161
+800, 2.61331
+801, 2.50949
+802, 2.41065
+803, 2.31727
+804, 2.39864
+805, 2.33363
+806, 2.2744
+807, 2.32808
+808, 2.29059
+809, 2.33323
+810, 2.31472
+811, 2.30195
+812, 2.29503
+813, 2.29404
+814, 2.29908
+815, 2.31025
+816, 2.32763
+817, 2.35129
+818, 2.38127
+819, 2.41757
+820, 2.46015
+821, 2.5089
+822, 2.56369
+823, 2.62429
+824, 2.69045
+825, 2.76186
+826, 2.83815
+827, 2.91894
+828, 3.00382
+829, 3.09236
+830, 3.18413
+831, 3.27872
+832, 3.3757
+833, 3.47469
+834, 3.5753
+835, 3.67716
+836, 3.77991
+837, 3.8832
+838, 3.98666
+839, 4.08991
+840, 4.19256
+841, 4.29419
+842, 4.39434
+843, 4.49255
+844, 4.58832
+845, 4.68114
+846, 4.77049
+847, 4.85586
+848, 4.93673
+849, 5.01263
+850, 5.08312
+851, 5.14781
+852, 5.20632
+853, 5.25839
+854, 5.30375
+855, 5.34224
+856, 5.37369
+857, 5.398
+858, 5.41512
+859, 5.42497
+860, 5.42753
+861, 5.42278
+862, 5.41068
+863, 5.39122
+864, 5.36438
+865, 5.33016
+866, 5.28857
+867, 5.23965
+868, 5.18346
+869, 5.12012
+870, 5.04978
+871, 4.97266
+872, 4.88905
+873, 4.79927
+874, 4.70373
+875, 4.60288
+876, 4.49721
+877, 4.38725
+878, 4.27354
+879, 4.15666
+880, 4.03718
+881, 3.91563
+882, 3.79258
+883, 3.66855
+884, 3.54403
+885, 3.41952
+886, 3.29551
+887, 3.17244
+888, 3.0508
+889, 2.93107
+890, 2.81373
+891, 2.69928
+892, 2.58826
+893, 2.48121
+894, 2.37868
+895, 2.28125
+896, 2.37248
+897, 2.30374
+898, 2.26273
+899, 2.33767
+900, 2.30092
+901, 2.27047
+902, 2.27143
+903, 2.27878
+904, 2.28164
+905, 2.28227
+906, 2.2893
+907, 2.30267
+908, 2.32228
+909, 2.34803
+910, 2.37978
+911, 2.41742
+912, 2.46082
+913, 2.50984
+914, 2.56437
+915, 2.62427
+916, 2.68942
+917, 2.75966
+918, 2.83481
+919, 2.91467
+920, 2.99898
+921, 3.08746
+922, 3.17975
+923, 3.27547
+924, 3.37419
+925, 3.47541
+926, 3.57864
+927, 3.68334
+928, 3.78898
+929, 3.895
+930, 4.00088
+931, 4.1061
+932, 4.21018
+933, 4.31266
+934, 4.41312
+935, 4.51116
+936, 4.60641
+937, 4.6985
+938, 4.7871
+939, 4.87187
+940, 4.95246
+941, 5.02852
+942, 5.09968
+943, 5.16559
+944, 5.22585
+945, 5.28008
+946, 5.32791
+947, 5.36899
+948, 5.40298
+949, 5.42959
+950, 5.44857
+951, 5.45973
+952, 5.46295
+953, 5.45816
+954, 5.44536
+955, 5.4246
+956, 5.396
+957, 5.35971
+958, 5.31592
+959, 5.26485
+960, 5.20673
+961, 5.1418
+962, 5.07031
+963, 4.99251
+964, 4.90866
+965, 4.819
+966, 4.72381
+967, 4.62338
+968, 4.51801
+969, 4.40806
+970, 4.29392
+971, 4.17601
+972, 4.05482
+973, 3.93089
+974, 3.80478
+975, 3.67711
+976, 3.54852
+977, 3.41968
+978, 3.29126
+979, 3.16391
+980, 3.03828
+981, 2.91499
+982, 2.79462
+983, 2.67774
+984, 2.56483
+985, 2.45639
+986, 2.35285
+987, 2.25621
+988, 2.33484
+989, 2.26359
+990, 2.36702
+991, 2.32251
+992, 2.28342
+993, 2.3178
+994, 2.29664
+995, 2.28131
+996, 2.29143
+997, 2.29029
+998, 2.29544
+999, 2.307
+1000, 2.32506
+1001, 2.34962
+1002, 2.38066
+1003, 2.41807
+1004, 2.46172
+1005, 2.51141
+1006, 2.56688
+1007, 2.62785
+1008, 2.69402
+1009, 2.76506
+1010, 2.84064
+1011, 2.92042
+1012, 3.00409
+1013, 3.09131
+1014, 3.18178
+1015, 3.2752
+1016, 3.37127
+1017, 3.46967
+1018, 3.57008
+1019, 3.67216
+1020, 3.77554
+1021, 3.87981
+1022, 3.98454
+1023, 4.08926
+1024, 4.19345
+1025, 4.29659
+1026, 4.39814
+1027, 4.49753
+1028, 4.59423
+1029, 4.68769
+1030, 4.77742
+1031, 4.86294
+1032, 4.94383
+1033, 5.0197
+1034, 5.09022
+1035, 5.1551
+1036, 5.21408
+1037, 5.26694
+1038, 5.31349
+1039, 5.35356
+1040, 5.38697
+1041, 5.41356
+1042, 5.43317
+1043, 5.44564
+1044, 5.4508
+1045, 5.44852
+1046, 5.43864
+1047, 5.42106
+1048, 5.3957
+1049, 5.36253
+1050, 5.32154