From: Brian Gough <bjg@network-theory.co.uk>
To: redonnet@lgmt.ups-tlse.fr
Cc: gsl-discuss@sourceware.cygnus.com
Subject: Re: Some (probably) ridiculous questions
Date: Wed, 19 Dec 2001 13:20:00 -0000 [thread overview]
Message-ID: <15176.48461.51558.274409@debian> (raw)
In-Reply-To: <01070712471300.13471@lgmt-fab5.ups-tlse.fr>
Jean-Max Redonnet writes:
> I think I have defined a surface function type as you proposed.
> This part seems to work as expected.
> but I don't see how to define a function to create the appropriate
> gsl_function...
>
The gsl_function has to be a parametric function. The example below
defines a gsl_function 'line.f' for |F|^2 on a path P(t),
(u(t),v(t)) = (0.5,0.5) + 0.1*(cos(t),sin(t))
and then finds the minimum (which is at t=pi) using the standard gsl
minimization routines. The relevant functions are line_eval() and
make_line_function().
#include <stdlib.h>
#include <stdio.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_diff.h>
#include <gsl/gsl_min.h>
#include <gsl/gsl_errno.h>
#define RAD2DEG(X) (X*180/M_PI)
#define DEG2RAD(X) (X*M_PI/180)
struct surf_function_struct {
double (* fx)(double u, double v);
double (* fy)(double u, double v);
double (* fz)(double u, double v);;
};
typedef struct surf_function_struct surf_function ;
double C0_fx(double u)
{
return 80*u;
}
double C0_fy(double u)
{
return 80*tan(DEG2RAD(22.5))*(u-0.5);
}
double C0_fz(double u)
{
return 40;
}
double C1_fx(double u)
{
return 80*u;
}
double C1_fy(double u)
{
return -80*tan(DEG2RAD(22.5))*(u-0.5);
}
double C1_fz(double u)
{
return -40;
}
double S_fx(double u, double v)
{
return (1-v)*C0_fx(u)+v*C1_fx(u);
}
double S_fy(double u, double v)
{
return (1-v)*C0_fy(u)+v*C1_fy(u);
}
double S_fz(double u, double v)
{
return (1-v)*C0_fz(u)+v*C1_fz(u);
}
struct path_function_struct {
void (* uv)(double t, double *u, double *v);
};
typedef struct path_function_struct path_function ;
void P_uv(double t, double *u, double *v)
{
*u = 0.5 + 0.1 * cos(t);
*v = 0.5 + 0.1 * sin(t);
}
struct line_function_struct
{
path_function p;
surf_function s;
gsl_function f;
};
typedef struct line_function_struct line_function ;
double
line_eval (double t, void * params)
{
line_function * line = (line_function *) params;
double u, v;
line->p.uv(t, &u, &v);
{
double a = line->s.fx(u,v);
double b = line->s.fy(u,v);
double c = line->s.fz(u,v);
/* compute |F|^2 */
return a*a + b*b + c*c;
}
}
void
make_line_function (path_function path, surf_function surf,
line_function * line)
{
line->p = path;
line->s = surf;
line->f.function = &line_eval;
line->f.params = line;
}
int main (void)
{
double u,v,t;
surf_function surf;
path_function path;
surf.fx = &S_fx;
surf.fy = &S_fy;
surf.fz = &S_fz;
path.uv = &P_uv;
for (t = 0 ; t < 2*M_PI; t+= 0.5)
{
path.uv(t, &u, &v);
printf(" | %f \n", S_fx(u,v));
printf(" S(%.3f,%.3f) = | %f \n", u, v, S_fy(u,v));
printf(" | %f \n", S_fz(u,v));
printf(" | %f \n", surf.fx(u,v));
printf(" S(%.3f,%.3f) = | %f \n", u, v, surf.fy(u,v));
printf(" | %f \n", surf.fz(u,v));
}
{
line_function line;
make_line_function(path, surf, &line);
{
int status, iterations = 0;
double m = 1.23;
gsl_interval x = {0.0, 2*M_PI};
gsl_min_fminimizer * s
= gsl_min_fminimizer_alloc (gsl_min_fminimizer_brent);
gsl_min_fminimizer_set (s, &line.f, m, x);
do
{
iterations++;
status = gsl_min_fminimizer_iterate (s);
m = gsl_min_fminimizer_minimum (s);
x = gsl_min_fminimizer_interval (s);
status = gsl_min_test_interval (x, 0.001, 0.0);
if (status == GSL_SUCCESS)
printf ("Converged:\n");
printf ("%5d [%.7f, %.7f] %.7f %.7f %+.7f\n",
iterations, x.lower, x.upper,
m, s->f_minimum, x.upper - x.lower);
}
while (status == GSL_CONTINUE && iterations < 100);
}
}
return 0;
}
prev parent reply other threads:[~2001-12-19 13:20 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-12-19 13:20 Jean-Max Redonnet
2001-12-19 13:20 ` Brian Gough
2001-12-19 13:20 ` Jean-Max Redonnet
2001-12-19 13:20 ` Brian Gough [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=15176.48461.51558.274409@debian \
--to=bjg@network-theory.co.uk \
--cc=gsl-discuss@sourceware.cygnus.com \
--cc=redonnet@lgmt.ups-tlse.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).