Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #102489 > unrolled thread

Passing values from structure arrays to a generic geometrical mean function

Started byAlla _ <modelling.data@gmail.com>
First post2017-01-26 12:15 -0800
Last post2017-01-28 18:56 +0000
Articles 20 on this page of 169 — 19 participants

Back to article view | Back to comp.lang.c


Contents

  Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-26 12:15 -0800
    Re: Passing values from structure arrays to a generic geometrical mean f unction Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-26 21:25 +0000
      Re: Passing values from structure arrays to a generic geometrical mean f unction Alla _ <modelling.data@gmail.com> - 2017-01-26 22:48 -0800
    Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-01-26 22:09 +0000
      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-27 00:25 -0800
        Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-01-27 08:35 +0000
          Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-27 01:53 -0800
            Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-01-27 10:33 +0000
              Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-27 13:29 +0100
                Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-01-27 13:05 +0000
                  Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-27 16:05 +0100
                    Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-01-27 15:31 +0000
                      Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-27 17:11 +0100
                      Re: Passing values from structure arrays to a generic geometrical mean function Ian Collins <ian-news@hotmail.com> - 2017-01-28 07:45 +1300
                    Re: Passing values from structure arrays to a generic geometrical mean function BartC <bc@freeuk.com> - 2017-01-27 15:35 +0000
                      Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-27 17:16 +0100
                        Re: Passing values from structure arrays to a generic geometrical mean function raltbos@xs4all.nl (Richard Bos) - 2017-01-27 17:13 +0000
                          Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-29 14:26 +0100
                            Re: Passing values from structure arrays to a generic geometrical mean function BartC <bc@freeuk.com> - 2017-01-29 14:51 +0000
                              Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-29 23:05 +0100
                            Re: Passing values from structure arrays to a generic geometrical mean function raltbos@xs4all.nl (Richard Bos) - 2017-01-31 11:23 +0000
                              Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-31 13:21 +0100
                          Re: Passing values from structure arrays to a generic geometrical mean function Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-02 00:59 -0800
                      Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-27 16:57 +0000
                        Re: Passing values from structure arrays to a generic geometrical mean function raltbos@xs4all.nl (Richard Bos) - 2017-01-27 17:16 +0000
                          Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-28 00:41 +0000
                      Re: Passing values from structure arrays to a generic geometrical mean function Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-28 05:05 -0800
                    Re: Passing values from structure arrays to a generic geometrical mean function James Kuyper <jameskuyper@verizon.net> - 2017-01-27 11:29 -0500
                    Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-27 09:25 -0800
                      Re: Passing values from structure arrays to a generic geometrical mean function supercat@casperkitty.com - 2017-01-27 10:00 -0800
                        Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-27 11:50 -0800
                          Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-29 14:41 +0100
                Re: Passing values from structure arrays to a generic geometrical mean function Manfred <noname@invalid.add> - 2017-01-27 15:36 +0100
                  Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-27 16:22 +0100
                    Re: Passing values from structure arrays to a generic geometrical mean function Manfred <noname@invalid.add> - 2017-01-27 16:53 +0100
                      Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-27 17:17 +0100
              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-27 05:38 -0800
                Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-27 16:44 +0000
                  Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-01-27 16:59 +0000
                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-27 09:44 -0800
                    Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-27 23:42 +0000
                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-27 21:59 -0800
                        Re: Passing values from structure arrays to a generic geometrical mean function luser droog <luser.droog@gmail.com> - 2017-01-27 22:23 -0800
                        Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-28 11:15 +0000
                        Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-28 09:51 -0500
                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-28 03:43 -0800
                        Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-28 14:49 +0000
                          Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-28 10:15 -0800
                            Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-28 14:13 -0500
                            Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-29 12:55 +0000
                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 05:11 -0800
                                Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-29 14:38 +0000
                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 09:00 -0800
                                    Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-29 17:11 +0000
                                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 10:09 -0800
                        Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-28 10:45 -0500
                          Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-28 10:26 -0800
                            Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-28 14:54 -0500
                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 01:54 -0800
                          Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-28 10:38 -0800
                            Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-28 14:52 -0500
                              Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-28 19:00 -0800
                                Re: Passing values from structure arrays to a generic geometrical mean function James Kuyper <jameskuyper@verizon.net> - 2017-01-28 22:54 -0500
                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 01:33 -0800
                                Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-29 10:37 -0500
                                  Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-29 15:57 +0000
                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 09:19 -0800
                                    Re: Passing values from structure arrays to a generic geometrical mean function fir <profesor.fir@gmail.com> - 2017-01-29 11:49 -0800
                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 01:40 -0800
                                Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-29 10:48 -0500
                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 09:59 -0800
                                    Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-29 13:52 -0500
                                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 12:48 -0800
                                        Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-29 16:27 -0500
                                          Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-30 04:57 -0800
                                            Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-30 12:26 -0500
                                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-30 10:04 -0800
                                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-30 10:28 -0800
                                                Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-30 14:38 -0500
                                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-31 12:45 -0800
                                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-30 10:39 -0800
                                                Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-30 12:41 -0800
                                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-31 13:02 -0800
                                                    Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-31 13:37 -0800
                                                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-02-02 21:36 -0800
                                                        Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-02-03 08:32 -0800
                                                          Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-02-03 10:39 -0800
                                                            Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-02-03 19:07 +0000
                                                              Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-02-03 11:40 -0800
                                                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-02-03 21:25 -0800
                                                                Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-02-04 09:01 +0000
                                                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-02-04 03:13 -0800
                                                                Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-04 11:37 -0500
                                                            Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-04 11:33 -0500
                                                          Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-02-03 11:02 -0800
                                                            Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-04 11:46 -0500
                                                Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-01-30 21:19 +0000
                                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-31 13:10 -0800
                                                    Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-01-31 21:18 +0000
                                                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-31 13:26 -0800
                                                Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-30 16:29 -0500
                                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-31 13:14 -0800
                                                    Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-31 16:46 -0500
                                                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-02-02 21:40 -0800
                                                Re: Passing values from structure arrays to a generic geometrical mean function luser droog <luser.droog@gmail.com> - 2017-01-30 21:26 -0800
                                                  Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-31 11:15 +0100
                                                    Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-01-31 10:35 +0000
                                                      Re: Passing values from structure arrays to a generic geometrical mean function mark.bluemel@gmail.com - 2017-01-31 02:59 -0800
                                                        Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-31 12:20 +0100
                                                          Re: Passing values from structure arrays to a generic geometrical mean function raltbos@xs4all.nl (Richard Bos) - 2017-01-31 11:52 +0000
                                                            Re: Passing values from structure arrays to a generic geometrical mean function mark.bluemel@gmail.com - 2017-01-31 06:52 -0800
                                                        Re: Passing values from structure arrays to a generic geometrical mean function Richard Heathfield <rjh@cpax.org.uk> - 2017-01-31 13:28 +0000
                                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-31 13:20 -0800
                                                    Re: Passing values from structure arrays to a generic geometrical mean function BartC <bc@freeuk.com> - 2017-01-31 23:33 +0000
                                        Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-29 21:55 +0000
                                          Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-30 11:48 -0500
                                            Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-30 09:15 -0800
                                              Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-30 14:27 -0500
                                                Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-31 12:41 -0800
                                                  Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-31 16:38 -0500
                                              Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-30 19:54 +0000
                                                Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-31 12:51 -0800
                                                  Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-31 16:54 -0500
                                              Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-30 12:19 -0800
                                                Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-30 13:54 -0800
                                                Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-31 12:57 -0800
                                                  Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-31 13:35 -0800
                                                  Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-31 17:01 -0500
                                                    Re: Passing values from structure arrays to a generic geometrical mean function raltbos@xs4all.nl (Richard Bos) - 2017-02-06 14:38 +0000
                                            Re: Passing values from structure arrays to a generic geometrical mean function Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-30 10:09 -0800
                                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-30 10:24 -0800
                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 01:48 -0800
                                Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-29 11:07 -0500
                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 01:52 -0800
                                Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-29 11:25 -0500
                              Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-04 13:26 -0500
                          Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-28 15:08 -0500
                          Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 01:20 -0800
                            Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-29 11:17 -0500
                            Re: Passing values from structure arrays to a generic geometrical mean function Barry Schwarz <schwarzb@dqel.com> - 2017-01-29 08:42 -0800
                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-27 09:58 -0800
                    Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-27 22:45 +0000
                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-28 00:56 -0800
                        Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-28 11:46 +0000
                          Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-28 05:08 -0800
                            Re: Passing values from structure arrays to a generic geometrical mean function Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-28 05:26 -0800
                              Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-28 13:01 -0800
                              Re: Passing values from structure arrays to a generic geometrical mean function supercat@casperkitty.com - 2017-01-30 09:46 -0800
                                Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-30 12:45 -0800
                            Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-28 15:05 +0000
                              Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-28 10:23 -0800
                                Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-29 13:06 +0000
                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 05:17 -0800
                                    Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-29 14:51 +0000
                                      Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-29 12:34 -0800
                                  Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 06:31 -0800
                                    Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-29 16:03 +0000
                                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-29 10:04 -0800
                                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-30 00:00 -0800
                                        Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-30 11:06 +0000
                                      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-30 00:13 -0800
              Re: Passing values from structure arrays to a generic geometrical mean function supercat@casperkitty.com - 2017-01-27 07:39 -0800
                Re: Passing values from structure arrays to a generic geometrical mean function David Brown <david.brown@hesbynett.no> - 2017-01-27 17:30 +0100
              Re: Passing values from structure arrays to a generic geometrical mean function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-27 16:16 +0000
    Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-27 11:49 -0800
      Re: Passing values from structure arrays to a generic geometrical mean function Alla _ <modelling.data@gmail.com> - 2017-01-28 00:48 -0800
        Re: Passing values from structure arrays to a generic geometrical mean function Keith Thompson <kst-u@mib.org> - 2017-01-28 11:02 -0800
      Re: Passing values from structure arrays to a generic geometrical mean function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-28 11:09 -0500
    Re: Passing values from structure arrays to a generic geometrical mean function Ike Naar <ike@iceland.freeshell.org> - 2017-01-28 18:56 +0000

Page 3 of 9 — ← Prev page 1 2 [3] 4 5 6 7 8 9  Next page →


#102612

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-27 23:42 +0000
Message-ID<87wpdgvzmp.fsf@bsb.me.uk>
In reply to#102566
Alla _ <modelling.data@gmail.com> writes:

> On Friday, January 27, 2017 at 7:44:33 PM UTC+3, Ben Bacarisse wrote:
>> Alla _ <modelling.data@gmail.com> writes:
>> 
>> > On Friday, January 27, 2017 at 1:34:06 PM UTC+3, Richard Heathfield wrote:
>> >> On 27/01/17 09:53, Alla _ wrote:
>> > <snip>
>> > Here is how everything looks now. Far from being generic
>> > because I still have no idea how to name parameters to make
>> > them generic. Maybe I shouldn't try it now, and leave it for later:
>> > (oh, and, yes, offsets - they are still here; enum tool is yet to be 
>> > learned)
>> >
>> > /** Function to fill assumptions: rates
>> >  for depreciation, interest **/
>> > void assump_rates_2(income_st *income_ptr, assets *ba_ptr,
>> > assumptions *rates)
>> 
>> Putting aside the parameters, the function name is wrong.  There is very
>> rarely any reason to call a function something_2.  If you are doing that
>> it suggests you are not really sure what the purpose if the function is.
>> 
>> And this function is 'void'.  Do you recall what I said about that?
>> 
>> > {
>> >     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
>> 
>> You really must stop using offsetof.  It is a terrible hack that is only
>> very occasionally useful.  Reaching for it should be an indication that
>> you have the wrong design -- either of the function or of the data
>> structure.
>> 
> I can't stop doing it now. I have spent  more than 2 days
> working on the code, when everyone suddenly told me to 
> move away from offsets;

You have to stop using it *here*.  The offset has a purpose in the other
code but it has no place here.  At best, it is working like a complex
unsafe pointer; at worst it is mixing up the proper role of the calling
and called function.  Give the sketched parameters, it's hard to be sure
but it looks like a little of both.

Let me try to get some detail into this despite the sketching.  If the
parameter "rates" is in fact a pointer to a "struct assumptions" then
this:

     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
     *(double*)((char*)rates + dep_amor_offs) = gm_dep;

is a complex way of writing

    rates->av_dep_amor = gm_dep;

But, in general, programs should do calculations by calling functions
and alter data structures by assigning the result of those calls.  When
you write a function to add two numbers you don't expect it to do some
offsetof calculation to decide where to put the sum -- you expect it to
return the sum so that it can be used in any situation where a sum is
needed.

> I have tried to use the enum approach, 
> but it was too difficult, so I asked if I can learn it later, and I 
> have understood that you have agreed to that; but then, after
> I have moved quite far, you have said to switch away from it.

Thats's a red herring here.  Neither approach is needed in these
functions.  Stick with offsetof for the other parts but I see no need
for anything like it here.

> You know that I am still learning, and that some things are 
> too comprehensive for me now. 
>
>> >     //Compute rate for depreciation and amortization
>> >     double gm_dep = mean(income_ptr, ba_ptr);
>> >     if(gm_dep != 0.0)
>> >         *(double*)((char*)rates + dep_amor_offs) = gm_dep;
>> 
>> And when gm_dep is zero you are happy to leave the target unchanged?
> This part is dealt with by the calling routine.

That is not usually the best way to do it.  It creates a logical linkage
between distant parts of the program.

> And actually a zero depreciation rate during 5 (let alone 10 years) is
> hardly ever possible for a company that has depreciable assets.

That it's rare is not relevant.  If it's *impossible* you should either
ignore the situation or stop the program dead if it ever occurs.  But if
it is possible, however unlikely, then the program must do the right
thing whatever that is.

>> > }
>> >
>> > /** Function to compute the mean
>> >     for two numbers
>> >  **/
>> > double mean_twonums(double number1, double number2)
>> > {
>> >   if(number1 < 0 || number2 < 0)
>> >       return (number1+number2)/2;
>> 
>> What do you know for certain at this point after the if?
> After this 'if' the function stops and returns the simple
> arithmetic average, because at least one of the values
> is negative (which is actually also very rarely possible 
> for depreciation values, it would mean appreciation 
> of the asset, but that is not truly relative for now).

I meant after the whole if.  You know that the negation of the condition
is true, so...

>> >   if(fabs(number1) < 1 && fabs(number1) > 0)
>> >       number1 += 1.0;
>> >   if(fabs(number2) < 1 && fabs(number2) > 0)
>> >       number2 += 1.0;
>> >   return pow((number1*number2), 1.0/2);
>> 
>> This function is very odd.  It does not do one simple thing.  It does a
>> weird bunch of things depending on the data and this is very rarely a
>> good idea.
> By this code I check if any number is between 1 and zero. I don't see
> what wrong with this test :(

The function is odd, not the test.  The comment (and the name) says it
computes the mean of two numbers, but it doesn't.  It does not even
compute one of two means (the arithmetic or geometric) of two numbers.
It computed something even odder than that.

If this is a standard financial computation, what it is called?  I need
to look it up to see how it is usually done.

>> 
>> > }
>> >
>> > /** Function to compute arithmetic average
>> >     for depreciation and amortization
>> >  **/
>> > double arithmetic_av(income_st *income_ptr, assets *ba_ptr)
>> 
>> This is the wrong name.  Whatever it is that this function calculates it
>> is not the arithmetic average of anything!
> It computes an arithmetic average of ratios.

No.  If it did, it would not treat zero in any special way.
>> 
>> > {
>> >     double sum = 0.0;
>> >     double average = 0.0;
>> >     double mean_twonum1 = 0.0;
>> >     double mean_twonum2 = 0.0;
>> 
>> These two are in the wrong place, even (I would say) for Richard
>> Heathfield code (though he may wish to correct me on that).
> I see. They have to be right before the for loop, correct?

No, they should be declared inside the loop since there are not used
outside.  At least that's the style I thought you where using.

>> >     if(DATA_SIZE > 0)
>> >     {
>> >         for (int i = 1; i < DATA_SIZE; i++)
>> >         {
>> >             mean_twonum1 = mean_twonums(ba_ptr[i-1].gross_ppe, ba_ptr[i].gross_ppe);
>> >             mean_twonum2 = mean_twonums(ba_ptr[i-1].intang, ba_ptr[i].intang);
>> >             
>> >             if(mean_twonum1 != 0 || mean_twonum2 != 0)
>> >                 sum += income_ptr[i].dep_amor/(mean_twonum1 + mean_twonum2);
>> >             else
>> >             {
>> >                 sum = 0.0;
>> >                 break;
>> >             }
>> >         }
>> >         if(sum != 0.0)
>> >             average = sum / (DATA_SIZE-1);
>> >     }
>> >     return average;
>> 
>> I don't think this can really be the calculation you need.  I know I
>> know very little about finance, but this just looks bonkers.
> This is the best code I could come up with :)

OK.  Does this peculiar calculation have a name?  If it does I can look
it up a see how I'd write it.

> It does serve the purpose when I have negative values, which, again,
> will very rarely appear in "real life".

The rarity is irrelevant, unless it is never in which case you either
ignore it (after possibly commenting on that) or you report a serious
logic error because something impossible has happened.

>> > }
>> >
>> > /** Function to compute pro forma rate
>> >     for depreciation and amortization
>> >  **/
>> > double mean(income_st *income_ptr, assets *ba_ptr)
>> > {
>> >     double product = 1.0;
>> >     double mean = 0.0;
>> >     double mean_twonum1 = 0.0;
>> >     double mean_twonum2 = 0.0;
>> 
>> Ditto.
>> 
>> >     if(DATA_SIZE > 0)
>> >     {
>> >         //Take data for each year
>> >         for (int i = 1; i < DATA_SIZE; i++)
>> >         {
>> >             //Compute arithmetic average if negative depreciation
>> >             if (income_ptr[i].dep_amor < 0)
>> >                 return arithmetic_av(income_ptr, ba_ptr);
>> >             
>> >             mean_twonum1 = mean_twonums(ba_ptr[i-1].gross_ppe, ba_ptr[i].gross_ppe);
>> >             mean_twonum2 = mean_twonums(ba_ptr[i-1].intang, ba_ptr[i].intang);
>> >             
>> >             if(mean_twonum1 != 0 || mean_twonum2 != 0)
>> >                 product *= (1 + (income_ptr[i].dep_amor)/(mean_twonum1 + mean_twonum2) );
>> >             else
>> >                 product = 0.0;
>> >         }
>> >         if(product != 0.0)
>> >             mean = pow(product, 1.0/DATA_SIZE)-1;
>> 
>> Really?  I don't think so but I can't guess what you meant.
> Why? I don't understand your question.
> For example: mean = ( (1+x) x (1+y) x (1+z) ) ^ (1/number of periods)
> Actually I should have subtracted 1 from DATA_SIZE, but that gives 
> a better rate, so it's better to keep it lower. It's just an assumption
> to "play" around later in valuations and scenarios.

That answers one thing: you meant 1.0/(DATA_SIZE-1).  OK.  Why is
product == 0.0 special?  Why is mean_twonum1 == 0 && mean_twonum2 == 0
special (rather than mean_twonum1 + mean_twonum2 == 0 which makes the
division illegal)?  There's just enough odd things going on for someone
like me to get very confused.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#102619

FromAlla _ <modelling.data@gmail.com>
Date2017-01-27 21:59 -0800
Message-ID<5636255b-a169-49de-a40b-ee3c0218ed25@googlegroups.com>
In reply to#102612
On Saturday, January 28, 2017 at 2:42:29 AM UTC+3, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
> 
> > On Friday, January 27, 2017 at 7:44:33 PM UTC+3, Ben Bacarisse wrote:
> >> Alla _ <modelling.data@gmail.com> writes:
> >> 
> >> > On Friday, January 27, 2017 at 1:34:06 PM UTC+3, Richard Heathfield wrote:
> >> >> On 27/01/17 09:53, Alla _ wrote:
> >> > <snip>
> >> > Here is how everything looks now. Far from being generic
> >> > because I still have no idea how to name parameters to make
> >> > them generic. Maybe I shouldn't try it now, and leave it for later:
> >> > (oh, and, yes, offsets - they are still here; enum tool is yet to be 
> >> > learned)
> >> >
> >> > /** Function to fill assumptions: rates
> >> >  for depreciation, interest **/
> >> > void assump_rates_2(income_st *income_ptr, assets *ba_ptr,
> >> > assumptions *rates)
> >> 
> >> Putting aside the parameters, the function name is wrong.  There is very
> >> rarely any reason to call a function something_2.  If you are doing that
> >> it suggests you are not really sure what the purpose if the function is.
> >> 
> >> And this function is 'void'.  Do you recall what I said about that?
> >> 
> >> > {
> >> >     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
> >> 
> >> You really must stop using offsetof.  It is a terrible hack that is only
> >> very occasionally useful.  Reaching for it should be an indication that
> >> you have the wrong design -- either of the function or of the data
> >> structure.
> >> 
> > I can't stop doing it now. I have spent  more than 2 days
> > working on the code, when everyone suddenly told me to 
> > move away from offsets;
> 
> You have to stop using it *here*.  The offset has a purpose in the other
> code but it has no place here.  At best, it is working like a complex
> unsafe pointer; at worst it is mixing up the proper role of the calling
> and called function.  Give the sketched parameters, it's hard to be sure
> but it looks like a little of both.
> 
<snip>
I am confused ) Truly. 
Do you mean that I have to stop using the macro offsetof() , or the 
variable offset? Are you referring to this part:
void assump_rates_2(income_st *income_ptr, balance *bs_ptr, assumptions *rates)
{
    int dep_amor_offs = offsetof(assumptions, av_dep_amor);
where int dip_amor_offs is assigned the value of the macro? 
Do you mean that I have to find the place in the structure in that huge offset
function that determines all other offsets, and only pass the integer value here,
and then use that integer value in:
*(double*)((char*)rates + value_of_offset_found_elsewhere) = gr_dep;

[toc] | [prev] | [next] | [standalone]


#102621

Fromluser droog <luser.droog@gmail.com>
Date2017-01-27 22:23 -0800
Message-ID<9be647ad-b0cb-4d9a-b4b8-73281f93f5d6@googlegroups.com>
In reply to#102619
On Friday, January 27, 2017 at 11:59:42 PM UTC-6, Alla _ wrote:
> On Saturday, January 28, 2017 at 2:42:29 AM UTC+3, Ben Bacarisse wrote:
> > Alla _ <modelling.data@gmail.com> writes:
> > 
> > > On Friday, January 27, 2017 at 7:44:33 PM UTC+3, Ben Bacarisse wrote:
> > >> Alla _ <modelling.data@gmail.com> writes:
> > >> 
> > >> > On Friday, January 27, 2017 at 1:34:06 PM UTC+3, Richard Heathfield wrote:
> > >> >> On 27/01/17 09:53, Alla _ wrote:
> > >> > <snip>
> > >> > Here is how everything looks now. Far from being generic
> > >> > because I still have no idea how to name parameters to make
> > >> > them generic. Maybe I shouldn't try it now, and leave it for later:
> > >> > (oh, and, yes, offsets - they are still here; enum tool is yet to be 
> > >> > learned)
> > >> >
> > >> > /** Function to fill assumptions: rates
> > >> >  for depreciation, interest **/
> > >> > void assump_rates_2(income_st *income_ptr, assets *ba_ptr,
> > >> > assumptions *rates)
> > >> 
> > >> Putting aside the parameters, the function name is wrong.  There is very
> > >> rarely any reason to call a function something_2.  If you are doing that
> > >> it suggests you are not really sure what the purpose if the function is.
> > >> 
> > >> And this function is 'void'.  Do you recall what I said about that?
> > >> 
> > >> > {
> > >> >     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
> > >> 
> > >> You really must stop using offsetof.  It is a terrible hack that is only
> > >> very occasionally useful.  Reaching for it should be an indication that
> > >> you have the wrong design -- either of the function or of the data
> > >> structure.
> > >> 
> > > I can't stop doing it now. I have spent  more than 2 days
> > > working on the code, when everyone suddenly told me to 
> > > move away from offsets;
> > 
> > You have to stop using it *here*.  The offset has a purpose in the other
> > code but it has no place here.  At best, it is working like a complex
> > unsafe pointer; at worst it is mixing up the proper role of the calling
> > and called function.  Give the sketched parameters, it's hard to be sure
> > but it looks like a little of both.
> > 
> <snip>
> I am confused ) Truly. 
> Do you mean that I have to stop using the macro offsetof() , or the 
> variable offset? Are you referring to this part:
> void assump_rates_2(income_st *income_ptr, balance *bs_ptr, assumptions *rates)
> {
>     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
> where int dip_amor_offs is assigned the value of the macro? 
> Do you mean that I have to find the place in the structure in that huge offset
> function that determines all other offsets, and only pass the integer value here,
> and then use that integer value in:
> *(double*)((char*)rates + value_of_offset_found_elsewhere) = gr_dep;

The members of a structure should normally be accessed
by .name syntax. And no casts needed. If there are 2 
ways, and one way needs a cast, the other way is almost
certainly better ipso facto (note: I said 'almost').

So, do

    assumptions.av_dep_amor

when you need to access it, or

    assumptions->av_dep_amor

if you have a pointer to the struct.

This expression naturally has the appropriate type to
access the object it indicates. No casts needed.

If you need to access the object *indirectly* -- maybe
the result could go in one of two variables -- then take
a pointer to it.

double *result = condition
               ? &assumptions.av_dep_amor
               : &something_else;

*result = calc * u + lation;

Whatever you think you need offsetof() to achieve is almost
certainly an X/Y problem, and the wrong tool. IMO

[toc] | [prev] | [next] | [standalone]


#102625

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-28 11:15 +0000
Message-ID<874m0jwi4j.fsf@bsb.me.uk>
In reply to#102619
Alla _ <modelling.data@gmail.com> writes:

> On Saturday, January 28, 2017 at 2:42:29 AM UTC+3, Ben Bacarisse wrote:
>> Alla _ <modelling.data@gmail.com> writes:
>> 
>> > On Friday, January 27, 2017 at 7:44:33 PM UTC+3, Ben Bacarisse wrote:
>> >> Alla _ <modelling.data@gmail.com> writes:
<snip>
>> >> >     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
>> >> 
>> >> You really must stop using offsetof.  It is a terrible hack that is only
>> >> very occasionally useful.  Reaching for it should be an indication that
>> >> you have the wrong design -- either of the function or of the data
>> >> structure.
>> >> 
>> > I can't stop doing it now. I have spent  more than 2 days
>> > working on the code, when everyone suddenly told me to 
>> > move away from offsets;
>> 
>> You have to stop using it *here*.  The offset has a purpose in the other
>> code but it has no place here.  At best, it is working like a complex
>> unsafe pointer; at worst it is mixing up the proper role of the calling
>> and called function.  Give the sketched parameters, it's hard to be sure
>> but it looks like a little of both.
>> 
> <snip>
> I am confused ) Truly. 
> Do you mean that I have to stop using the macro offsetof() , or the 
> variable offset? Are you referring to this part:
> void assump_rates_2(income_st *income_ptr, balance *bs_ptr, assumptions *rates)
> {
>     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
> where int dip_amor_offs is assigned the value of the macro? 
> Do you mean that I have to find the place in the structure in that huge offset
> function that determines all other offsets, and only pass the integer value here,
> and then use that integer value in:
> *(double*)((char*)rates + value_of_offset_found_elsewhere) = gr_dep;

You must stop using offsets to find structure members in this function.
You don't use the offsets of the other members that the function
references, and there is (probably) no need to use it for "av_dep_amor".
I say probably because you have not yet written valid C so there may be
some aspect of the function's design (in your mind) that I am not privy
to.

But that is only a detail.  Once you write the function is real C it
should be clear that the offsetof macro is not needed.  (I wrote out how
I thought the key step would look without it.)

The underlying problem is that function is declared void and that should
ring alarm bells.  Functions that compute values are just about the most
useful structure C has, and to decline to return a value from a function
is very often a mistake.  This function (and the other related ones)
should take as arguments the data they need to perform the calculation
and should return the result of the calculation as a value.  The
*caller* should then decide where that result goes using a simple
assignment.  Again, I am at a disadvantage because I have no idea how or
where these functions will be called so all I can do is make general
remarks, but it is almost always wrong to have a function put the result
of a calculation in some very specific place like this.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#102636

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-01-28 09:51 -0500
Message-ID<1812b433-2e73-c3fe-fb6d-143469a398ab@verizon.net>
In reply to#102619
On 01/28/2017 12:59 AM, Alla _ wrote:
> On Saturday, January 28, 2017 at 2:42:29 AM UTC+3, Ben Bacarisse wrote:
...
>> You have to stop using it *here*.  The offset has a purpose in the other
>> code but it has no place here.  At best, it is working like a complex
>> unsafe pointer; at worst it is mixing up the proper role of the calling
>> and called function.  Give the sketched parameters, it's hard to be sure
>> but it looks like a little of both.
>>
> <snip>
> I am confused ) Truly.
> Do you mean that I have to stop using the macro offsetof() , or the
> variable offset? Are you referring to this part:
> void assump_rates_2(income_st *income_ptr, balance *bs_ptr, assumptions *rates)
> {
>     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
> where int dip_amor_offs is assigned the value of the macro?
> Do you mean that I have to find the place in the structure in that huge offset
> function that determines all other offsets, and only pass the integer value here,
> and then use that integer value in:
> *(double*)((char*)rates + value_of_offset_found_elsewhere) = gr_dep;

No. In the earlier message Ben was responding to,
      rates->av_dep_amor = gr_dep;

Here's the function as you wrote it on 2017-01-27 13:38:15 +0000:

> void assump_rates_2(income_st *income_ptr, assets *ba_ptr, assumptions *rates)
> {
>     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
>
>     //Compute rate for depreciation and amortization
>     double gm_dep = mean(income_ptr, ba_ptr);
>     if(gm_dep != 0.0)
>         *(double*)((char*)rates + dep_amor_offs) = gm_dep;
> }

Assuming that rates->av_dep_amor has the type 'double', the following 
code has exactly equivalent behavior:

void assump_rates_2(income_st *income_ptr, assets *ba_ptr, assumptions 
*rates)
{
     //Compute rate for depreciation and amortization
     double gm_dep = mean(income_ptr, ba_ptr);
     if(gm_dep != 0.0)
         rates->av_dep_amor = gm_dep;
}

If rates->av_dep_amor does not have the type double, you shouldn't be 
writing such code.

Can you give me any good reason for preferring to use the offset method?

[toc] | [prev] | [next] | [standalone]


#102627

FromAlla _ <modelling.data@gmail.com>
Date2017-01-28 03:43 -0800
Message-ID<522dd411-1a86-49fb-8df7-a1384f3c5da8@googlegroups.com>
In reply to#102612
On Saturday, January 28, 2017 at 2:42:29 AM UTC+3, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
> 
> > On Friday, January 27, 2017 at 7:44:33 PM UTC+3, Ben Bacarisse wrote:
> >> Alla _ <modelling.data@gmail.com> writes:
> >> 
> >> > On Friday, January 27, 2017 at 1:34:06 PM UTC+3, Richard Heathfield wrote:
> >> >> On 27/01/17 09:53, Alla _ wrote:
> >> > <snip>
> >> > Here is how everything looks now. Far from being generic
> >> > because I still have no idea how to name parameters to make
> >> > them generic. Maybe I shouldn't try it now, and leave it for later:
> >> > (oh, and, yes, offsets - they are still here; enum tool is yet to be 
> >> > learned)
> >> >
> >> > /** Function to fill assumptions: rates
> >> >  for depreciation, interest **/
> >> > void assump_rates_2(income_st *income_ptr, assets *ba_ptr,
> >> > assumptions *rates)
> >> 
> >> Putting aside the parameters, the function name is wrong.  There is very
> >> rarely any reason to call a function something_2.  If you are doing that
> >> it suggests you are not really sure what the purpose if the function is.
> >> 
> >> And this function is 'void'.  Do you recall what I said about that?
> >> 
> >> > {
> >> >     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
> >> 
> >> You really must stop using offsetof.  It is a terrible hack that is only
> >> very occasionally useful.  Reaching for it should be an indication that
> >> you have the wrong design -- either of the function or of the data
> >> structure.
> >> 
> > I can't stop doing it now. I have spent  more than 2 days
> > working on the code, when everyone suddenly told me to 
> > move away from offsets;
> 
> You have to stop using it *here*.  The offset has a purpose in the other
> code but it has no place here.  At best, it is working like a complex
> unsafe pointer; at worst it is mixing up the proper role of the calling
> and called function.  Give the sketched parameters, it's hard to be sure
> but it looks like a little of both.
> 
> Let me try to get some detail into this despite the sketching.  If the
> parameter "rates" is in fact a pointer to a "struct assumptions" then
> this:
> 
>      int dep_amor_offs = offsetof(assumptions, av_dep_amor);
>      *(double*)((char*)rates + dep_amor_offs) = gm_dep;
> 
> is a complex way of writing
> 
>     rates->av_dep_amor = gm_dep;
> 
> But, in general, programs should do calculations by calling functions
> and alter data structures by assigning the result of those calls.  When
> you write a function to add two numbers you don't expect it to do some
> offsetof calculation to decide where to put the sum -- you expect it to
> return the sum so that it can be used in any situation where a sum is
> needed.
> 
I am sorry for picking up pieces of this message when I reply. 
I have read this message again.
Referring to the above paragraph, this is precisely why I have come 
here with the question on how can I write a correct function declaration,
how can I pass parameters to it, etc. 
Actually the assumptions_rates function (now that second one is called
balance_rates) is computing two values - depreciation rate and interest 
rate; both are computed in the same way but, apparently, using different
members of arrays of structures, and assigning those rates to two
different members of the assumptions structure. 
Therefore the function computes two values. 
(1) I am passing the assumptions structure as on of the parameters;
but what if I make this function return the pointer to that same assumptions structure,
will it be all right if the function alters only two out of three members
of that structure (the first member is filled by the previous rates computing
function)?
(2) I see that I indeed don't need any offsets here because the assumptions 
structure is not an array, and hence I have a straightforward access to its
members. Huge mistake on my side. 
(3) I need to compute two values, but I can't use the same mean functions 
because, as has been discussed here, there is no good way to have generic 
parameters in a function declaration, which could have taken pointers to members
of an array of structures, and to make the calling function pass to it only 
the required members to loop through. 
This means that for now I have to repeat the exact same code of the mean
function twice, but using two different structure members within that function to
compute this. I wish I could call the mean function twice by doing this, and hence
avoiding repeating the same code for that function twice in a program:

mean(income_ptr->depreciation, bs_ptr->gr_ppe, bs_ptr->intang);
mean(income_ptr->int_exp, bs_ptr->ltd, NULL);

But I can't do that because I declare the mean function as:
double mean(income_st *income_ptr, balance *bs_ptr) 
passing pointers to whole arrays of relative structures. 

void balance_rates(income_st *income_ptr, balance *bs_ptr, assumptions *rates)
{
    //Compute rate for depreciation and amortization
    double gr_dep = mean(income_ptr, bs_ptr);
    if(gr_dep != 0.0)
        rates->av_dep_amor = gr_dep;
    
    //Compute rate for interest rate
    double gr_int = mean(income_ptr, bs_ptr);
    if(gr_int != 0.0)
        rates->av_int_exp = gr_int;
}

> > I have tried to use the enum approach, 
> > but it was too difficult, so I asked if I can learn it later, and I 
> > have understood that you have agreed to that; but then, after
> > I have moved quite far, you have said to switch away from it.
> 
> Thats's a red herring here.  Neither approach is needed in these
> functions.  Stick with offsetof for the other parts but I see no need
> for anything like it here.
> 
> > You know that I am still learning, and that some things are 
> > too comprehensive for me now. 
> >
> >> >     //Compute rate for depreciation and amortization
> >> >     double gm_dep = mean(income_ptr, ba_ptr);
> >> >     if(gm_dep != 0.0)
> >> >         *(double*)((char*)rates + dep_amor_offs) = gm_dep;
> >> 
> >> And when gm_dep is zero you are happy to leave the target unchanged?
> > This part is dealt with by the calling routine.
> 
> That is not usually the best way to do it.  It creates a logical linkage
> between distant parts of the program.
> 
> > And actually a zero depreciation rate during 5 (let alone 10 years) is
> > hardly ever possible for a company that has depreciable assets.
> 
> That it's rare is not relevant.  If it's *impossible* you should either
> ignore the situation or stop the program dead if it ever occurs.  But if
> it is possible, however unlikely, then the program must do the right
> thing whatever that is.
> 
> >> > }
> >> >
> >> > /** Function to compute the mean
> >> >     for two numbers
> >> >  **/
> >> > double mean_twonums(double number1, double number2)
> >> > {
> >> >   if(number1 < 0 || number2 < 0)
> >> >       return (number1+number2)/2;
> >> 
> >> What do you know for certain at this point after the if?
> > After this 'if' the function stops and returns the simple
> > arithmetic average, because at least one of the values
> > is negative (which is actually also very rarely possible 
> > for depreciation values, it would mean appreciation 
> > of the asset, but that is not truly relative for now).
> 
> I meant after the whole if.  You know that the negation of the condition
> is true, so...
> 
> >> >   if(fabs(number1) < 1 && fabs(number1) > 0)
> >> >       number1 += 1.0;
> >> >   if(fabs(number2) < 1 && fabs(number2) > 0)
> >> >       number2 += 1.0;
> >> >   return pow((number1*number2), 1.0/2);
> >> 
> >> This function is very odd.  It does not do one simple thing.  It does a
> >> weird bunch of things depending on the data and this is very rarely a
> >> good idea.
> > By this code I check if any number is between 1 and zero. I don't see
> > what wrong with this test :(
> 
> The function is odd, not the test.  The comment (and the name) says it
> computes the mean of two numbers, but it doesn't.  It does not even
> compute one of two means (the arithmetic or geometric) of two numbers.
> It computed something even odder than that.
Oh, please ) Not having a math background, I still don't believe this is 
something purely finance - everything used in finance is based on 
math, and I use very simple concepts here. This is a geo mean, or
also called compound growth rate, though here I apply it only for
two numbers. 
I have showed this above:
if two values are between 1 and zero (i.e. if they are ratios, or percents,
whatever one calls it), then to compute a geometric mean I do the following:
((1 + number2)*(1 + number2)*.....(1 + numberN))^(1/N)
Therefore, I take the absolute value of each number and see if it's 
between 1 and zero; if it is, then I add 1 to it, which also helps if 
some of those numbers are negative. 
> 
> If this is a standard financial computation, what it is called?  I need
> to look it up to see how it is usually done.

> 
> >> 
> >> > }
> >> >
> >> > /** Function to compute arithmetic average
> >> >     for depreciation and amortization
> >> >  **/
> >> > double arithmetic_av(income_st *income_ptr, assets *ba_ptr)
> >> 
> >> This is the wrong name.  Whatever it is that this function calculates it
> >> is not the arithmetic average of anything!
> > It computes an arithmetic average of ratios.
> 
> No.  If it did, it would not treat zero in any special way.
I used zero here because I needed something for the test. 
> >> 
> >> > {
> >> >     double sum = 0.0;
> >> >     double average = 0.0;
> >> >     double mean_twonum1 = 0.0;
> >> >     double mean_twonum2 = 0.0;
> >> 
> >> These two are in the wrong place, even (I would say) for Richard
> >> Heathfield code (though he may wish to correct me on that).
> > I see. They have to be right before the for loop, correct?
> 
> No, they should be declared inside the loop since there are not used
> outside.  At least that's the style I thought you where using.
> 
> >> >     if(DATA_SIZE > 0)
> >> >     {
> >> >         for (int i = 1; i < DATA_SIZE; i++)
> >> >         {
> >> >             mean_twonum1 = mean_twonums(ba_ptr[i-1].gross_ppe, ba_ptr[i].gross_ppe);
> >> >             mean_twonum2 = mean_twonums(ba_ptr[i-1].intang, ba_ptr[i].intang);
> >> >             
> >> >             if(mean_twonum1 != 0 || mean_twonum2 != 0)
> >> >                 sum += income_ptr[i].dep_amor/(mean_twonum1 + mean_twonum2);
> >> >             else
> >> >             {
> >> >                 sum = 0.0;
> >> >                 break;
> >> >             }
> >> >         }
> >> >         if(sum != 0.0)
> >> >             average = sum / (DATA_SIZE-1);
> >> >     }
> >> >     return average;
> >> 
> >> I don't think this can really be the calculation you need.  I know I
> >> know very little about finance, but this just looks bonkers.
> > This is the best code I could come up with :)
> 
> OK.  Does this peculiar calculation have a name?  If it does I can look
> it up a see how I'd write it.
> 
> > It does serve the purpose when I have negative values, which, again,
> > will very rarely appear in "real life".
> 
> The rarity is irrelevant, unless it is never in which case you either
> ignore it (after possibly commenting on that) or you report a serious
> logic error because something impossible has happened.
> 
> >> > }
> >> >
> >> > /** Function to compute pro forma rate
> >> >     for depreciation and amortization
> >> >  **/
> >> > double mean(income_st *income_ptr, assets *ba_ptr)
> >> > {
> >> >     double product = 1.0;
> >> >     double mean = 0.0;
> >> >     double mean_twonum1 = 0.0;
> >> >     double mean_twonum2 = 0.0;
> >> 
> >> Ditto.
> >> 
> >> >     if(DATA_SIZE > 0)
> >> >     {
> >> >         //Take data for each year
> >> >         for (int i = 1; i < DATA_SIZE; i++)
> >> >         {
> >> >             //Compute arithmetic average if negative depreciation
> >> >             if (income_ptr[i].dep_amor < 0)
> >> >                 return arithmetic_av(income_ptr, ba_ptr);
> >> >             
> >> >             mean_twonum1 = mean_twonums(ba_ptr[i-1].gross_ppe, ba_ptr[i].gross_ppe);
> >> >             mean_twonum2 = mean_twonums(ba_ptr[i-1].intang, ba_ptr[i].intang);
> >> >             
> >> >             if(mean_twonum1 != 0 || mean_twonum2 != 0)
> >> >                 product *= (1 + (income_ptr[i].dep_amor)/(mean_twonum1 + mean_twonum2) );
> >> >             else
> >> >                 product = 0.0;
> >> >         }
> >> >         if(product != 0.0)
> >> >             mean = pow(product, 1.0/DATA_SIZE)-1;
> >> 
> >> Really?  I don't think so but I can't guess what you meant.
> > Why? I don't understand your question.
> > For example: mean = ( (1+x) x (1+y) x (1+z) ) ^ (1/number of periods)
> > Actually I should have subtracted 1 from DATA_SIZE, but that gives 
> > a better rate, so it's better to keep it lower. It's just an assumption
> > to "play" around later in valuations and scenarios.
> 
> That answers one thing: you meant 1.0/(DATA_SIZE-1).  OK.  Why is
> product == 0.0 special? 
Because if it is zero (which I agree not the best test value), then 
the above condition is false, and hence the rate could have not
been computed. 
> Why is mean_twonum1 == 0 && mean_twonum2 == 0
> special (rather than mean_twonum1 + mean_twonum2 == 0 which makes the
> division illegal)? 
Agree. I have not written a correct test here, actually wanting to write
the test for illegal division.  
>There's just enough odd things going on for someone
> like me to get very confused.

[toc] | [prev] | [next] | [standalone]


#102635

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-28 14:49 +0000
Message-ID<87poj7utmr.fsf@bsb.me.uk>
In reply to#102627
Alla _ <modelling.data@gmail.com> writes:

> On Saturday, January 28, 2017 at 2:42:29 AM UTC+3, Ben Bacarisse wrote:
>> Alla _ <modelling.data@gmail.com> writes:
>> 
>> > On Friday, January 27, 2017 at 7:44:33 PM UTC+3, Ben Bacarisse wrote:
>> >> Alla _ <modelling.data@gmail.com> writes:
>> >> 
>> >> > On Friday, January 27, 2017 at 1:34:06 PM UTC+3, Richard Heathfield wrote:
>> >> >> On 27/01/17 09:53, Alla _ wrote:
>> >> > <snip>
>> >> > Here is how everything looks now. Far from being generic
>> >> > because I still have no idea how to name parameters to make
>> >> > them generic. Maybe I shouldn't try it now, and leave it for later:
>> >> > (oh, and, yes, offsets - they are still here; enum tool is yet to be 
>> >> > learned)
>> >> >
>> >> > /** Function to fill assumptions: rates
>> >> >  for depreciation, interest **/
>> >> > void assump_rates_2(income_st *income_ptr, assets *ba_ptr,
>> >> > assumptions *rates)
>> >> 
>> >> Putting aside the parameters, the function name is wrong.  There is very
>> >> rarely any reason to call a function something_2.  If you are doing that
>> >> it suggests you are not really sure what the purpose if the function is.
>> >> 
>> >> And this function is 'void'.  Do you recall what I said about that?
>> >> 
>> >> > {
>> >> >     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
>> >> 
>> >> You really must stop using offsetof.  It is a terrible hack that is only
>> >> very occasionally useful.  Reaching for it should be an indication that
>> >> you have the wrong design -- either of the function or of the data
>> >> structure.
>> >> 
>> > I can't stop doing it now. I have spent  more than 2 days
>> > working on the code, when everyone suddenly told me to 
>> > move away from offsets;
>> 
>> You have to stop using it *here*.  The offset has a purpose in the other
>> code but it has no place here.  At best, it is working like a complex
>> unsafe pointer; at worst it is mixing up the proper role of the calling
>> and called function.  Give the sketched parameters, it's hard to be sure
>> but it looks like a little of both.
>> 
>> Let me try to get some detail into this despite the sketching.  If the
>> parameter "rates" is in fact a pointer to a "struct assumptions" then
>> this:
>> 
>>      int dep_amor_offs = offsetof(assumptions, av_dep_amor);
>>      *(double*)((char*)rates + dep_amor_offs) = gm_dep;
>> 
>> is a complex way of writing
>> 
>>     rates->av_dep_amor = gm_dep;
>> 
>> But, in general, programs should do calculations by calling functions
>> and alter data structures by assigning the result of those calls.  When
>> you write a function to add two numbers you don't expect it to do some
>> offsetof calculation to decide where to put the sum -- you expect it to
>> return the sum so that it can be used in any situation where a sum is
>> needed.
>> 
> I am sorry for picking up pieces of this message when I reply. 
> I have read this message again.
> Referring to the above paragraph, this is precisely why I have come 
> here with the question on how can I write a correct function declaration,
> how can I pass parameters to it, etc. 
> Actually the assumptions_rates function (now that second one is called
> balance_rates) is computing two values - depreciation rate and interest 
> rate; both are computed in the same way but, apparently, using different
> members of arrays of structures, and assigning those rates to two
> different members of the assumptions structure. 
> Therefore the function computes two values.

I did not see a function that does that.  If I had I would have made
different comments.

Write your basic functions to compute only one value.

> (1) I am passing the assumptions structure as on of the parameters;
> but what if I make this function return the pointer to that same assumptions structure,
> will it be all right if the function alters only two out of three members
> of that structure (the first member is filled by the previous rates computing
> function)?

I can tell because I don't know what your program does.  It sounds
simple, but everything you write about it seem hugely complex.  I can
only assume that the calculations involve all sorts of inputs you have
not yet told me about.  In another post, your calculation looks very
simple: a number of years and three arrays.

> (2) I see that I indeed don't need any offsets here because the assumptions 
> structure is not an array, and hence I have a straightforward access to its
> members. Huge mistake on my side.

Good.  That's a very important step.

> (3) I need to compute two values, but I can't use the same mean functions 
> because, as has been discussed here, there is no good way to have generic 
> parameters in a function declaration,

What?  You must be using the words in some note-quite-standard way.  You
don't need generic parameters in the highly technical sense (it often
means parameters of any type) because all your data are 'double'.  I
can't see any reason why you can't use the same mean function for more
than one calculation.

> which could have taken pointers to members
> of an array of structures, and to make the calling function pass to it only 
> the required members to loop through. 
> This means that for now I have to repeat the exact same code of the mean
> function twice, but using two different structure members within that function to
> compute this. I wish I could call the mean function twice by doing this, and hence
> avoiding repeating the same code for that function twice in a program:
>
> mean(income_ptr->depreciation, bs_ptr->gr_ppe, bs_ptr->intang);
> mean(income_ptr->int_exp, bs_ptr->ltd, NULL);
>
> But I can't do that because I declare the mean function as:
> double mean(income_st *income_ptr, balance *bs_ptr)

That's incomprehensible without the typedefs being used.  Most of the
problems are probably due to having the wrong data structures, so I need
to see them.  A function called mean should look like this:

  double mean(int n, double *data);

Also, please choose better names.  mean should calculate the mean of
some data.  If you are calculating the mean of some ratios derived from
the data, call it mean_of_ratios or something like that (I can't choose
the name because I don't know the subject).

> passing pointers to whole arrays of relative structures.

I don't know what a relative structure is.

> void balance_rates(income_st *income_ptr, balance *bs_ptr, assumptions *rates)
> {
>     //Compute rate for depreciation and amortization
>     double gr_dep = mean(income_ptr, bs_ptr);
>     if(gr_dep != 0.0)
>         rates->av_dep_amor = gr_dep;
>     
>     //Compute rate for interest rate
>     double gr_int = mean(income_ptr, bs_ptr);
>     if(gr_int != 0.0)
>         rates->av_int_exp = gr_int;
> }

Is this real code?  I'm getting confused with what's a sketch and what's
real.

>> > I have tried to use the enum approach, 
>> > but it was too difficult, so I asked if I can learn it later, and I 
>> > have understood that you have agreed to that; but then, after
>> > I have moved quite far, you have said to switch away from it.
>> 
>> Thats's a red herring here.  Neither approach is needed in these
>> functions.  Stick with offsetof for the other parts but I see no need
>> for anything like it here.
>> 
>> > You know that I am still learning, and that some things are 
>> > too comprehensive for me now. 
>> >
>> >> >     //Compute rate for depreciation and amortization
>> >> >     double gm_dep = mean(income_ptr, ba_ptr);
>> >> >     if(gm_dep != 0.0)
>> >> >         *(double*)((char*)rates + dep_amor_offs) = gm_dep;
>> >> 
>> >> And when gm_dep is zero you are happy to leave the target unchanged?
>> > This part is dealt with by the calling routine.
>> 
>> That is not usually the best way to do it.  It creates a logical linkage
>> between distant parts of the program.
>> 
>> > And actually a zero depreciation rate during 5 (let alone 10 years) is
>> > hardly ever possible for a company that has depreciable assets.
>> 
>> That it's rare is not relevant.  If it's *impossible* you should either
>> ignore the situation or stop the program dead if it ever occurs.  But if
>> it is possible, however unlikely, then the program must do the right
>> thing whatever that is.
>> 
>> >> > }
>> >> >
>> >> > /** Function to compute the mean
>> >> >     for two numbers
>> >> >  **/
>> >> > double mean_twonums(double number1, double number2)
>> >> > {
>> >> >   if(number1 < 0 || number2 < 0)
>> >> >       return (number1+number2)/2;
>> >> 
>> >> What do you know for certain at this point after the if?
>> > After this 'if' the function stops and returns the simple
>> > arithmetic average, because at least one of the values
>> > is negative (which is actually also very rarely possible 
>> > for depreciation values, it would mean appreciation 
>> > of the asset, but that is not truly relative for now).
>> 
>> I meant after the whole if.  You know that the negation of the condition
>> is true, so...
>> 
>> >> >   if(fabs(number1) < 1 && fabs(number1) > 0)
>> >> >       number1 += 1.0;
>> >> >   if(fabs(number2) < 1 && fabs(number2) > 0)
>> >> >       number2 += 1.0;
>> >> >   return pow((number1*number2), 1.0/2);
>> >> 
>> >> This function is very odd.  It does not do one simple thing.  It does a
>> >> weird bunch of things depending on the data and this is very rarely a
>> >> good idea.
>> > By this code I check if any number is between 1 and zero. I don't see
>> > what wrong with this test :(
>> 
>> The function is odd, not the test.  The comment (and the name) says it
>> computes the mean of two numbers, but it doesn't.  It does not even
>> compute one of two means (the arithmetic or geometric) of two numbers.
>> It computed something even odder than that.
> Oh, please ) Not having a math background, I still don't believe this is 
> something purely finance - everything used in finance is based on 
> math, and I use very simple concepts here.
> This is a geo mean, or
> also called compound growth rate, though here I apply it only for
> two numbers.

Here is the function:

  /** Function to compute the mean
      for two numbers
   **/
  double mean_twonums(double number1, double number2)
  {
    if(number1 < 0 || number2 < 0)
        return (number1+number2)/2;

    if(fabs(number1) < 1 && fabs(number1) > 0)
        number1 += 1.0;
    if(fabs(number2) < 1 && fabs(number2) > 0)
        number2 += 1.0;
    return pow((number1*number2), 1.0/2);
  }

This is not an arithmetic mean nor is it a geometric mean.  As far as I
know, this calculation has no established name in mathematics.  It may
have a name in finance but it looks very odd even then.  It seems to be
trying to do several things at once.

> I have showed this above:
> if two values are between 1 and zero (i.e. if they are ratios, or percents,
> whatever one calls it), then to compute a geometric mean I do the following:
> ((1 + number2)*(1 + number2)*.....(1 + numberN))^(1/N)
> Therefore, I take the absolute value of each number and see if it's 
> between 1 and zero; if it is, then I add 1 to it, which also helps if 
> some of those numbers are negative.

I know what the function does because I can see the code.  I'm just
complaining about the comment and the name.  If this baroque calculation
is standard in finance, then it will have a name and you should use it.
What is certain is that it is not a mean

>> If this is a standard financial computation, what it is called?  I need
>> to look it up to see how it is usually done.

Please answer this.  Can you give me a name or a citation so I can go
study this calculation and it's uses?  I asked the same about the later
computation as well.
>
>> 
>> >> 
>> >> > }
>> >> >
>> >> > /** Function to compute arithmetic average
>> >> >     for depreciation and amortization
>> >> >  **/
>> >> > double arithmetic_av(income_st *income_ptr, assets *ba_ptr)
>> >> 
>> >> This is the wrong name.  Whatever it is that this function calculates it
>> >> is not the arithmetic average of anything!
>> > It computes an arithmetic average of ratios.
>> 
>> No.  If it did, it would not treat zero in any special way.
> I used zero here because I needed something for the test.

What test?  My point is that arithmetic averages don't treat a sum of
zero in any special way so why do you?

>> >> > {
>> >> >     double sum = 0.0;
>> >> >     double average = 0.0;
>> >> >     double mean_twonum1 = 0.0;
>> >> >     double mean_twonum2 = 0.0;
<snip> 
>> >> >     if(DATA_SIZE > 0)
>> >> >     {
>> >> >         for (int i = 1; i < DATA_SIZE; i++)
>> >> >         {
>> >> >             mean_twonum1 = mean_twonums(ba_ptr[i-1].gross_ppe, ba_ptr[i].gross_ppe);
>> >> >             mean_twonum2 = mean_twonums(ba_ptr[i-1].intang, ba_ptr[i].intang);
>> >> >             
>> >> >             if(mean_twonum1 != 0 || mean_twonum2 != 0)
>> >> >                 sum += income_ptr[i].dep_amor/(mean_twonum1 + mean_twonum2);
>> >> >             else
>> >> >             {
>> >> >                 sum = 0.0;
>> >> >                 break;
>> >> >             }
>> >> >         }
>> >> >         if(sum != 0.0)
>> >> >             average = sum / (DATA_SIZE-1);
>> >> >     }
>> >> >     return average;
>> >> > }
<snip>
>> >> >
>> >> > /** Function to compute pro forma rate
>> >> >     for depreciation and amortization
>> >> >  **/
>> >> > double mean(income_st *income_ptr, assets *ba_ptr)
>> >> > {
>> >> >     double product = 1.0;
>> >> >     double mean = 0.0;
>> >> >     double mean_twonum1 = 0.0;
>> >> >     double mean_twonum2 = 0.0;
>> >> >     if(DATA_SIZE > 0)
>> >> >     {
>> >> >         //Take data for each year
>> >> >         for (int i = 1; i < DATA_SIZE; i++)
>> >> >         {
>> >> >             //Compute arithmetic average if negative depreciation
>> >> >             if (income_ptr[i].dep_amor < 0)
>> >> >                 return arithmetic_av(income_ptr, ba_ptr);
>> >> >             
>> >> >             mean_twonum1 = mean_twonums(ba_ptr[i-1].gross_ppe, ba_ptr[i].gross_ppe);
>> >> >             mean_twonum2 = mean_twonums(ba_ptr[i-1].intang, ba_ptr[i].intang);
>> >> >             
>> >> >             if(mean_twonum1 != 0 || mean_twonum2 != 0)
>> >> >                 product *= (1 + (income_ptr[i].dep_amor)/(mean_twonum1 + mean_twonum2) );
>> >> >             else
>> >> >                 product = 0.0;
>> >> >         }
>> >> >         if(product != 0.0)
>> >> >             mean = pow(product, 1.0/DATA_SIZE)-1;
>> >> 
>> >> Really?  I don't think so but I can't guess what you meant.
>> > Why? I don't understand your question.
>> > For example: mean = ( (1+x) x (1+y) x (1+z) ) ^ (1/number of periods)
>> > Actually I should have subtracted 1 from DATA_SIZE, but that gives 
>> > a better rate, so it's better to keep it lower. It's just an assumption
>> > to "play" around later in valuations and scenarios.
>> 
>> That answers one thing: you meant 1.0/(DATA_SIZE-1).  OK.  Why is
>> product == 0.0 special? 
> Because if it is zero (which I agree not the best test value), then 
> the above condition is false, and hence the rate could have not
> been computed.

This is not a good idea.  If something can't be computed you should
report that fact to the function's caller.  Using 'magic' values to skip
subsequent parts of the calculation makes the code very hard to follow.
Better just to write the test an return immediately you see that
something is wrong.

But one even simpler solution (so you can imagine I would urge you to
consider it) is to take no special action at all.  On most modern
computers, division by floating-point zero will generate a special
"infinity" value.  The caller can report a problem if it sees the result
is infinity or it can simply leave the value there for the user of the
program to see.

>> Why is mean_twonum1 == 0 && mean_twonum2 == 0
>> special (rather than mean_twonum1 + mean_twonum2 == 0 which makes the
>> division illegal)? 
> Agree. I have not written a correct test here, actually wanting to write
> the test for illegal division.

Ah.  I hope you can see why I was a bit perplexed.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#102647

FromAlla _ <modelling.data@gmail.com>
Date2017-01-28 10:15 -0800
Message-ID<8d2814a0-6e93-4c8a-983f-072149b52786@googlegroups.com>
In reply to#102635
On Saturday, January 28, 2017 at 5:49:41 PM UTC+3, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
> 
> > On Saturday, January 28, 2017 at 2:42:29 AM UTC+3, Ben Bacarisse wrote:
> >> Alla _ <modelling.data@gmail.com> writes:
> >> 
> >> > On Friday, January 27, 2017 at 7:44:33 PM UTC+3, Ben Bacarisse wrote:
> >> >> Alla _ <modelling.data@gmail.com> writes:
> >> >> 
> >> >> > On Friday, January 27, 2017 at 1:34:06 PM UTC+3, Richard Heathfield wrote:
> >> >> >> On 27/01/17 09:53, Alla _ wrote:
> >> >> > <snip>
> >> >> > Here is how everything looks now. Far from being generic
> >> >> > because I still have no idea how to name parameters to make
> >> >> > them generic. Maybe I shouldn't try it now, and leave it for later:
> >> >> > (oh, and, yes, offsets - they are still here; enum tool is yet to be 
> >> >> > learned)
> >> >> >
> >> >> > /** Function to fill assumptions: rates
> >> >> >  for depreciation, interest **/
> >> >> > void assump_rates_2(income_st *income_ptr, assets *ba_ptr,
> >> >> > assumptions *rates)
> >> >> 
> >> >> Putting aside the parameters, the function name is wrong.  There is very
> >> >> rarely any reason to call a function something_2.  If you are doing that
> >> >> it suggests you are not really sure what the purpose if the function is.
> >> >> 
> >> >> And this function is 'void'.  Do you recall what I said about that?
> >> >> 
> >> >> > {
> >> >> >     int dep_amor_offs = offsetof(assumptions, av_dep_amor);
> >> >> 
> >> >> You really must stop using offsetof.  It is a terrible hack that is only
> >> >> very occasionally useful.  Reaching for it should be an indication that
> >> >> you have the wrong design -- either of the function or of the data
> >> >> structure.
> >> >> 
> >> > I can't stop doing it now. I have spent  more than 2 days
> >> > working on the code, when everyone suddenly told me to 
> >> > move away from offsets;
> >> 
> >> You have to stop using it *here*.  The offset has a purpose in the other
> >> code but it has no place here.  At best, it is working like a complex
> >> unsafe pointer; at worst it is mixing up the proper role of the calling
> >> and called function.  Give the sketched parameters, it's hard to be sure
> >> but it looks like a little of both.
> >> 
> >> Let me try to get some detail into this despite the sketching.  If the
> >> parameter "rates" is in fact a pointer to a "struct assumptions" then
> >> this:
> >> 
> >>      int dep_amor_offs = offsetof(assumptions, av_dep_amor);
> >>      *(double*)((char*)rates + dep_amor_offs) = gm_dep;
> >> 
> >> is a complex way of writing
> >> 
> >>     rates->av_dep_amor = gm_dep;
> >> 
> >> But, in general, programs should do calculations by calling functions
> >> and alter data structures by assigning the result of those calls.  When
> >> you write a function to add two numbers you don't expect it to do some
> >> offsetof calculation to decide where to put the sum -- you expect it to
> >> return the sum so that it can be used in any situation where a sum is
> >> needed.
> >> 
> > I am sorry for picking up pieces of this message when I reply. 
> > I have read this message again.
> > Referring to the above paragraph, this is precisely why I have come 
> > here with the question on how can I write a correct function declaration,
> > how can I pass parameters to it, etc. 
> > Actually the assumptions_rates function (now that second one is called
> > balance_rates) is computing two values - depreciation rate and interest 
> > rate; both are computed in the same way but, apparently, using different
> > members of arrays of structures, and assigning those rates to two
> > different members of the assumptions structure. 
> > Therefore the function computes two values.
> 
> I did not see a function that does that.  If I had I would have made
> different comments.
> 
> Write your basic functions to compute only one value.
> 
> > (1) I am passing the assumptions structure as on of the parameters;
> > but what if I make this function return the pointer to that same assumptions structure,
> > will it be all right if the function alters only two out of three members
> > of that structure (the first member is filled by the previous rates computing
> > function)?
> 
> I can tell because I don't know what your program does.  It sounds
> simple, but everything you write about it seem hugely complex.  I can
> only assume that the calculations involve all sorts of inputs you have
> not yet told me about.  In another post, your calculation looks very
> simple: a number of years and three arrays.
> 
> > (2) I see that I indeed don't need any offsets here because the assumptions 
> > structure is not an array, and hence I have a straightforward access to its
> > members. Huge mistake on my side.
> 
> Good.  That's a very important step.
> 
> > (3) I need to compute two values, but I can't use the same mean functions 
> > because, as has been discussed here, there is no good way to have generic 
> > parameters in a function declaration,
> 
> What?  You must be using the words in some note-quite-standard way.  You
> don't need generic parameters in the highly technical sense (it often
> means parameters of any type) because all your data are 'double'.  I
> can't see any reason why you can't use the same mean function for more
> than one calculation.
> 
> > which could have taken pointers to members
> > of an array of structures, and to make the calling function pass to it only 
> > the required members to loop through. 
> > This means that for now I have to repeat the exact same code of the mean
> > function twice, but using two different structure members within that function to
> > compute this. I wish I could call the mean function twice by doing this, and hence
> > avoiding repeating the same code for that function twice in a program:
> >
> > mean(income_ptr->depreciation, bs_ptr->gr_ppe, bs_ptr->intang);
> > mean(income_ptr->int_exp, bs_ptr->ltd, NULL);
> >
> > But I can't do that because I declare the mean function as:
> > double mean(income_st *income_ptr, balance *bs_ptr)
> 
> That's incomprehensible without the typedefs being used.  Most of the
> problems are probably due to having the wrong data structures, so I need
> to see them.  A function called mean should look like this:
> 
>   double mean(int n, double *data);
Please, see typedefs of structures I have. They are all right, I hope. 
Also I don't need to pass int n, as I have pointed elsewhere,
because I have a defined data_size I use throughout the program. 
income_st, cs_income_st, balance are all used as an array of such
structures. assumptions and offsets are both used as they are. 
offsets are now used only to fill those three basic arrays of structures
while reading each line from each file (two files). 

typedef struct data_1 {
    int       year;
    double    sales;
    double    cogs;
    double    gross_profit;
    double    sga;
    double    oper_inc;
    double    dep_amor;
    double    oper_prof;
    double    int_exp;
    double    gain_loss;
    double    pretax_inc;
    double    tax_exp;
    double    net_inc;
} income_st;

typedef struct data_2 {
    int       cs_year;
    double    cs_sales;
    double    cs_cogs;
    double    cs_gross_profit;
    double    cs_sga;
    double    cs_oper_inc;
    double    cs_dep_amor;
    double    cs_oper_prof;
    double    cs_int_exp;
    double    cs_gain_loss;
    double    cs_pretax_inc;
    double    cs_tax_exp;
    double    cs_net_inc;
} cs_income_st;

typedef struct balance_sheet {
    double    cash;
    double    ar;
    double    inv;
    double    o_cur_a;
    double    t_cur_a;
    double    gross_ppe;
    double    acc_dep;
    double    net_ppe;
    double    intang;
    double    ta;
    double    ap;
    double    tp;
    double    o_cur_l;
    double    t_cur_l;
    double    ltd;
    double    o_l;
    double    tl;
    double    se;
    double    tle;
} balance;

typedef struct assumptions {
    double gr_sales;
    double av_cogs;
    double av_gross_profit;
    double av_sga;
    double av_oper_inc;
    double av_dep_amor;
    double av_oper_prof;
    double av_int_exp;
    double av_gain_loss;
    double av_pretax_inc;
    double av_tax_exp;
    double av_net_inc;
} assumptions;

typedef struct offsets {
    int offset_income;
    int offset_cs_income;
    int offset_balance;
} offsets;

> 
> Also, please choose better names.  mean should calculate the mean of
> some data.  If you are calculating the mean of some ratios derived from
> the data, call it mean_of_ratios or something like that (I can't choose
> the name because I don't know the subject).
> 
All right. I will call those ratios_mean (to avoid the additional of in the middle),
or something of the sort - but it is a mean ))) I didn't think it can cause such
a discussion, but I assume for people who know math very well and who 
are good in math theory these things are very important. And I agree that 
functions should have precise names; my ones were rather bad and non-
descriptive.  

> > passing pointers to whole arrays of relative structures.
> 
> I don't know what a relative structure is.
> 
> > void balance_rates(income_st *income_ptr, balance *bs_ptr, assumptions *rates)
> > {
> >     //Compute rate for depreciation and amortization
> >     double gr_dep = mean(income_ptr, bs_ptr);
> >     if(gr_dep != 0.0)
> >         rates->av_dep_amor = gr_dep;
> >     
> >     //Compute rate for interest rate
> >     double gr_int = mean(income_ptr, bs_ptr);
> >     if(gr_int != 0.0)
> >         rates->av_int_exp = gr_int;
> > }
> 
> Is this real code?  I'm getting confused with what's a sketch and what's
> real.
It is in one version, where I pass the pointers to two arrays of structures
to at the time called mean function. And this is a calling function, 
which calls the mean function, which in turn calls mean_twonums
function, as you have seen. 
> 
> >> > I have tried to use the enum approach, 
> >> > but it was too difficult, so I asked if I can learn it later, and I 
> >> > have understood that you have agreed to that; but then, after
> >> > I have moved quite far, you have said to switch away from it.
> >> 
> >> Thats's a red herring here.  Neither approach is needed in these
> >> functions.  Stick with offsetof for the other parts but I see no need
> >> for anything like it here.
> >> 
> >> > You know that I am still learning, and that some things are 
> >> > too comprehensive for me now. 
> >> >
> >> >> >     //Compute rate for depreciation and amortization
> >> >> >     double gm_dep = mean(income_ptr, ba_ptr);
> >> >> >     if(gm_dep != 0.0)
> >> >> >         *(double*)((char*)rates + dep_amor_offs) = gm_dep;
> >> >> 
> >> >> And when gm_dep is zero you are happy to leave the target unchanged?
> >> > This part is dealt with by the calling routine.
> >> 
> >> That is not usually the best way to do it.  It creates a logical linkage
> >> between distant parts of the program.
> >> 
> >> > And actually a zero depreciation rate during 5 (let alone 10 years) is
> >> > hardly ever possible for a company that has depreciable assets.
> >> 
> >> That it's rare is not relevant.  If it's *impossible* you should either
> >> ignore the situation or stop the program dead if it ever occurs.  But if
> >> it is possible, however unlikely, then the program must do the right
> >> thing whatever that is.
> >> 
> >> >> > }
> >> >> >
> >> >> > /** Function to compute the mean
> >> >> >     for two numbers
> >> >> >  **/
> >> >> > double mean_twonums(double number1, double number2)
> >> >> > {
> >> >> >   if(number1 < 0 || number2 < 0)
> >> >> >       return (number1+number2)/2;
> >> >> 
> >> >> What do you know for certain at this point after the if?
> >> > After this 'if' the function stops and returns the simple
> >> > arithmetic average, because at least one of the values
> >> > is negative (which is actually also very rarely possible 
> >> > for depreciation values, it would mean appreciation 
> >> > of the asset, but that is not truly relative for now).
> >> 
> >> I meant after the whole if.  You know that the negation of the condition
> >> is true, so...
> >> 
> >> >> >   if(fabs(number1) < 1 && fabs(number1) > 0)
> >> >> >       number1 += 1.0;
> >> >> >   if(fabs(number2) < 1 && fabs(number2) > 0)
> >> >> >       number2 += 1.0;
> >> >> >   return pow((number1*number2), 1.0/2);
> >> >> 
> >> >> This function is very odd.  It does not do one simple thing.  It does a
> >> >> weird bunch of things depending on the data and this is very rarely a
> >> >> good idea.
> >> > By this code I check if any number is between 1 and zero. I don't see
> >> > what wrong with this test :(
> >> 
> >> The function is odd, not the test.  The comment (and the name) says it
> >> computes the mean of two numbers, but it doesn't.  It does not even
> >> compute one of two means (the arithmetic or geometric) of two numbers.
> >> It computed something even odder than that.
> > Oh, please ) Not having a math background, I still don't believe this is 
> > something purely finance - everything used in finance is based on 
> > math, and I use very simple concepts here.
> > This is a geo mean, or
> > also called compound growth rate, though here I apply it only for
> > two numbers.
> 
> Here is the function:
> 
>   /** Function to compute the mean
>       for two numbers
>    **/
>   double mean_twonums(double number1, double number2)
>   {
>     if(number1 < 0 || number2 < 0)
>         return (number1+number2)/2;
> 
>     if(fabs(number1) < 1 && fabs(number1) > 0)
>         number1 += 1.0;
>     if(fabs(number2) < 1 && fabs(number2) > 0)
>         number2 += 1.0;
>     return pow((number1*number2), 1.0/2);
>   }
> 
> This is not an arithmetic mean nor is it a geometric mean.  As far as I
> know, this calculation has no established name in mathematics.  It may
> have a name in finance but it looks very odd even then.  It seems to be
> trying to do several things at once.
> 
> > I have showed this above:
> > if two values are between 1 and zero (i.e. if they are ratios, or percents,
> > whatever one calls it), then to compute a geometric mean I do the following:
> > ((1 + number2)*(1 + number2)*.....(1 + numberN))^(1/N)
> > Therefore, I take the absolute value of each number and see if it's 
> > between 1 and zero; if it is, then I add 1 to it, which also helps if 
> > some of those numbers are negative.
> 
> I know what the function does because I can see the code.  I'm just
> complaining about the comment and the name.  If this baroque calculation
> is standard in finance, then it will have a name and you should use it.
> What is certain is that it is not a mean
What? A "baroque calculation"? ) This is such a standard math calculation,
which computes a geometric mean for percents, or ratios, and also accounts
for negative ones. I am truly surprised to hear that it looks unusual to you.
It's rather basic compounding.
Does anyone else think it's a weird one? Interesting, truly. But as this has 
nothing to do with C, then this discussion is not relative for this group. 
> 
> >> If this is a standard financial computation, what it is called?  I need
> >> to look it up to see how it is usually done.
> 
> Please answer this.  Can you give me a name or a citation so I can go
> study this calculation and it's uses?  I asked the same about the later
> computation as well.
Tears on my eyes. I did write a name, and have showed you the way 
it is computed. 
Here is the article I have googled; it's from investopedia
http://www.investopedia.com/articles/investing/071113/breaking-down-geometric-mean.asp


> >
> >> 
> >> >> 
> >> >> > }
> >> >> >
> >> >> > /** Function to compute arithmetic average
> >> >> >     for depreciation and amortization
> >> >> >  **/
> >> >> > double arithmetic_av(income_st *income_ptr, assets *ba_ptr)
> >> >> 
> >> >> This is the wrong name.  Whatever it is that this function calculates it
> >> >> is not the arithmetic average of anything!
> >> > It computes an arithmetic average of ratios.
> >> 
> >> No.  If it did, it would not treat zero in any special way.
> > I used zero here because I needed something for the test.
> 
> What test?  My point is that arithmetic averages don't treat a sum of
> zero in any special way so why do you?
My zero has nothing to do with the average, but with my inability to come
up, at that moment, with a better test value for success/failure. I am 
thinking to make all those mean/average functions boolean ones,
otherwise I don't see how I can test them for success, what value
could indicate failure. 
> 
> >> >> > {
> >> >> >     double sum = 0.0;
> >> >> >     double average = 0.0;
> >> >> >     double mean_twonum1 = 0.0;
> >> >> >     double mean_twonum2 = 0.0;
> <snip> 
> >> >> >     if(DATA_SIZE > 0)
> >> >> >     {
> >> >> >         for (int i = 1; i < DATA_SIZE; i++)
> >> >> >         {
> >> >> >             mean_twonum1 = mean_twonums(ba_ptr[i-1].gross_ppe, ba_ptr[i].gross_ppe);
> >> >> >             mean_twonum2 = mean_twonums(ba_ptr[i-1].intang, ba_ptr[i].intang);
> >> >> >             
> >> >> >             if(mean_twonum1 != 0 || mean_twonum2 != 0)
> >> >> >                 sum += income_ptr[i].dep_amor/(mean_twonum1 + mean_twonum2);
> >> >> >             else
> >> >> >             {
> >> >> >                 sum = 0.0;
> >> >> >                 break;
> >> >> >             }
> >> >> >         }
> >> >> >         if(sum != 0.0)
> >> >> >             average = sum / (DATA_SIZE-1);
> >> >> >     }
> >> >> >     return average;
> >> >> > }
> <snip>
> >> >> >
> >> >> > /** Function to compute pro forma rate
> >> >> >     for depreciation and amortization
> >> >> >  **/
> >> >> > double mean(income_st *income_ptr, assets *ba_ptr)
> >> >> > {
> >> >> >     double product = 1.0;
> >> >> >     double mean = 0.0;
> >> >> >     double mean_twonum1 = 0.0;
> >> >> >     double mean_twonum2 = 0.0;
> >> >> >     if(DATA_SIZE > 0)
> >> >> >     {
> >> >> >         //Take data for each year
> >> >> >         for (int i = 1; i < DATA_SIZE; i++)
> >> >> >         {
> >> >> >             //Compute arithmetic average if negative depreciation
> >> >> >             if (income_ptr[i].dep_amor < 0)
> >> >> >                 return arithmetic_av(income_ptr, ba_ptr);
> >> >> >             
> >> >> >             mean_twonum1 = mean_twonums(ba_ptr[i-1].gross_ppe, ba_ptr[i].gross_ppe);
> >> >> >             mean_twonum2 = mean_twonums(ba_ptr[i-1].intang, ba_ptr[i].intang);
> >> >> >             
> >> >> >             if(mean_twonum1 != 0 || mean_twonum2 != 0)
> >> >> >                 product *= (1 + (income_ptr[i].dep_amor)/(mean_twonum1 + mean_twonum2) );
> >> >> >             else
> >> >> >                 product = 0.0;
> >> >> >         }
> >> >> >         if(product != 0.0)
> >> >> >             mean = pow(product, 1.0/DATA_SIZE)-1;
> >> >> 
> >> >> Really?  I don't think so but I can't guess what you meant.
> >> > Why? I don't understand your question.
> >> > For example: mean = ( (1+x) x (1+y) x (1+z) ) ^ (1/number of periods)
> >> > Actually I should have subtracted 1 from DATA_SIZE, but that gives 
> >> > a better rate, so it's better to keep it lower. It's just an assumption
> >> > to "play" around later in valuations and scenarios.
> >> 
> >> That answers one thing: you meant 1.0/(DATA_SIZE-1).  OK.  Why is
> >> product == 0.0 special? 
> > Because if it is zero (which I agree not the best test value), then 
> > the above condition is false, and hence the rate could have not
> > been computed.
> 
> This is not a good idea.  If something can't be computed you should
> report that fact to the function's caller.  Using 'magic' values to skip
> subsequent parts of the calculation makes the code very hard to follow.
> Better just to write the test an return immediately you see that
> something is wrong.
> 
Oh, I have explained myself above before reaching this part. But 
yes, shortly speaking. 
> But one even simpler solution (so you can imagine I would urge you to
> consider it) is to take no special action at all.  On most modern
> computers, division by floating-point zero will generate a special
> "infinity" value.  The caller can report a problem if it sees the result
> is infinity or it can simply leave the value there for the user of the
> program to see.
Interesting. I think it is safer for the caller to report a problem;
because the user might not look at these numbers at all - they
are intermediary ones used to compute the final table. 

> >> Why is mean_twonum1 == 0 && mean_twonum2 == 0
> >> special (rather than mean_twonum1 + mean_twonum2 == 0 which makes the
> >> division illegal)? 
> > Agree. I have not written a correct test here, actually wanting to write
> > the test for illegal division.
> 
> Ah.  I hope you can see why I was a bit perplexed.
> 
> -- 
> Ben.

[toc] | [prev] | [next] | [standalone]


#102654

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-01-28 14:13 -0500
Message-ID<1d213be7-7c3c-ff15-e921-9be314b658ef@verizon.net>
In reply to#102647
On 01/28/2017 01:15 PM, Alla _ wrote:
> On Saturday, January 28, 2017 at 5:49:41 PM UTC+3, Ben Bacarisse wrote:
>> Alla _ <modelling.data@gmail.com> writes:
...
>> Here is the function:
>>
>>   /** Function to compute the mean
>>       for two numbers
>>    **/
>>   double mean_twonums(double number1, double number2)
>>   {
>>     if(number1 < 0 || number2 < 0)
>>         return (number1+number2)/2;
>>
>>     if(fabs(number1) < 1 && fabs(number1) > 0)
>>         number1 += 1.0;
>>     if(fabs(number2) < 1 && fabs(number2) > 0)
>>         number2 += 1.0;
>>     return pow((number1*number2), 1.0/2);
>>   }
>>
>> This is not an arithmetic mean nor is it a geometric mean.  As far as I
>> know, this calculation has no established name in mathematics.  It may
>> have a name in finance but it looks very odd even then.  It seems to be
>> trying to do several things at once.
>>
>>> I have showed this above:
>>> if two values are between 1 and zero (i.e. if they are ratios, or percents,
>>> whatever one calls it), then to compute a geometric mean I do the following:
>>> ((1 + number2)*(1 + number2)*.....(1 + numberN))^(1/N)
>>> Therefore, I take the absolute value of each number and see if it's
>>> between 1 and zero; if it is, then I add 1 to it, which also helps if
>>> some of those numbers are negative.
>>
>> I know what the function does because I can see the code.  I'm just
>> complaining about the comment and the name.  If this baroque calculation
>> is standard in finance, then it will have a name and you should use it.
>> What is certain is that it is not a mean
> What? A "baroque calculation"? ) This is such a standard math calculation,
> which computes a geometric mean for percents, or ratios, and also accounts
> for negative ones. I am truly surprised to hear that it looks unusual to you.
> It's rather basic compounding.
> Does anyone else think it's a weird one? Interesting, truly. But as this has
> nothing to do with C, then this discussion is not relative for this group.

Calculating

     number3 = sqrt(number1*number2)

would be a very conventional definition for a geometric mean routine: it 
finds the value for number3 such that

     number3*2 == number1*number2

Calculating

     number3 = sqrt((1.0 + number1)*(1.0 + number2))-1.0

finds the value for number3 such that

     (1.0 + number3)^2 == (1.0 + number1)*(1.0 + number2).

That would also be a fairly conventional need. However, your code 
doesn't subtract the 1.0 at the end, which means that the output from 
this routine has a meaning very different from the meaning of it's 
inputs - something that should not ordinarily be the case in a function 
whose name fails to convey that fact. The geometric mean of a bunch of 
1-year growth factors is itself a 1-year growth factor. The geometric 
mean of a bunch of Celsius temperatures is itself a Celsius temperature. 
Nothing similar can be said about the output and inputs to your routine 
when those inputs are between 0 and 1.

However, the fact that your code switches between adding or not adding 1 
to number1, depending upon the value of number1, and similarly for 
number2, is the key feature that marks this computation as truly 
bizarre, and probably not what's actually needed. You claim that it 
"accounts for negative ones" but it does so in a fashion that makes no 
sense to me - and I have some familiarity with the kinds of calculations 
that come up in financial data processing (it's not my specialty, but I 
have more familiarity with both accounting and economics than you might 
expect from my professional credentials). Why do you need to do a 
completely different calculation when number1 <= 0 or number1 >= 1 than 
you do when it's between those two values?

>>>> If this is a standard financial computation, what it is called?  I need
>>>> to look it up to see how it is usually done.
>>
>> Please answer this.  Can you give me a name or a citation so I can go
>> study this calculation and it's uses?  I asked the same about the later
>> computation as well.
> Tears on my eyes. I did write a name, and have showed you the way
> it is computed.

No, you gave us the name for a calculation that your function does not 
perform.

> Here is the article I have googled; it's from investopedia
> http://www.investopedia.com/articles/investing/071113/breaking-down-geometric-mean.asp

And where in that article does it suggest changing whether or not you 
add 1, depending upon the value of the number?

...
>>>> No.  If it did, it would not treat zero in any special way.
>>> I used zero here because I needed something for the test.
>>
>> What test?  My point is that arithmetic averages don't treat a sum of
>> zero in any special way so why do you?
> My zero has nothing to do with the average, but with my inability to come
> up, at that moment, with a better test value for success/failure. I am

Why should it fail? You're making it fail for no particular reason. An 
arithmetic mean only has reason to fail if the count is 0 or the sum 
overflows.

> thinking to make all those mean/average functions boolean ones,
> otherwise I don't see how I can test them for success, what value
> could indicate failure.

Key suggestion: there's no need to invent a reasons for a function to 
fail. Pay attention only to the reasons for failure that are actually 
present in the algorithm. Some functions can't fail, and others have 
failure modes that are so difficult to test for that it isn't worth the 
trouble (overflow often falls in this category).

[toc] | [prev] | [next] | [standalone]


#102683

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-29 12:55 +0000
Message-ID<87wpderpny.fsf@bsb.me.uk>
In reply to#102647
Alla _ <modelling.data@gmail.com> writes:

> On Saturday, January 28, 2017 at 5:49:41 PM UTC+3, Ben Bacarisse wrote:
>> Alla _ <modelling.data@gmail.com> writes:
<snip>
>> > mean(income_ptr->depreciation, bs_ptr->gr_ppe, bs_ptr->intang);
>> > mean(income_ptr->int_exp, bs_ptr->ltd, NULL);
>> >
>> > But I can't do that because I declare the mean function as:
>> > double mean(income_st *income_ptr, balance *bs_ptr)
>> 
>> That's incomprehensible without the typedefs being used.  Most of the
>> problems are probably due to having the wrong data structures, so I need
>> to see them.  A function called mean should look like this:
>> 
>>   double mean(int n, double *data);
> Please, see typedefs of structures I have. They are all right, I hope. 
> Also I don't need to pass int n, as I have pointed elsewhere,
> because I have a defined data_size I use throughout the program. 
> income_st, cs_income_st, balance are all used as an array of such
> structures. assumptions and offsets are both used as they are. 
> offsets are now used only to fill those three basic arrays of structures
> while reading each line from each file (two files). 
>
> typedef struct data_1 {
>     int       year;
>     double    sales;
>     double    cogs;
>     double    gross_profit;
>     double    sga;
>     double    oper_inc;
>     double    dep_amor;
>     double    oper_prof;
>     double    int_exp;
>     double    gain_loss;
>     double    pretax_inc;
>     double    tax_exp;
>     double    net_inc;
> } income_st;
>
> typedef struct data_2 {
>     int       cs_year;
>     double    cs_sales;
>     double    cs_cogs;
>     double    cs_gross_profit;
>     double    cs_sga;
>     double    cs_oper_inc;
>     double    cs_dep_amor;
>     double    cs_oper_prof;
>     double    cs_int_exp;
>     double    cs_gain_loss;
>     double    cs_pretax_inc;
>     double    cs_tax_exp;
>     double    cs_net_inc;
> } cs_income_st;

I suggest you represent the year as a double.  It will make the input
routine simpler since reading years will be the same as reading any
other value.

Why do you have two such similar structures?

> typedef struct balance_sheet {
>     double    cash;
>     double    ar;
>     double    inv;
>     double    o_cur_a;
>     double    t_cur_a;
>     double    gross_ppe;
>     double    acc_dep;
>     double    net_ppe;
>     double    intang;
>     double    ta;
>     double    ap;
>     double    tp;
>     double    o_cur_l;
>     double    t_cur_l;
>     double    ltd;
>     double    o_l;
>     double    tl;
>     double    se;
>     double    tle;
> } balance;
>
> typedef struct assumptions {
>     double gr_sales;
>     double av_cogs;
>     double av_gross_profit;
>     double av_sga;
>     double av_oper_inc;
>     double av_dep_amor;
>     double av_oper_prof;
>     double av_int_exp;
>     double av_gain_loss;
>     double av_pretax_inc;
>     double av_tax_exp;
>     double av_net_inc;
> } assumptions;
>
> typedef struct offsets {
>     int offset_income;
>     int offset_cs_income;
>     int offset_balance;
> } offsets;

I can see this is going to be very complicated.  With structures like
this you will probably end up having to write a large number of specific
calculation functions, each one picking out the parts it cares about.
Alternatively you will have to pass in one or more offsets of the members
to operate on, but that's not likely to be any clearer to the reader.

<snip>
>> Here is the function:
>> 
>>   /** Function to compute the mean
>>       for two numbers
>>    **/
>>   double mean_twonums(double number1, double number2)
>>   {
>>     if(number1 < 0 || number2 < 0)
>>         return (number1+number2)/2;
>> 
>>     if(fabs(number1) < 1 && fabs(number1) > 0)
>>         number1 += 1.0;
>>     if(fabs(number2) < 1 && fabs(number2) > 0)
>>         number2 += 1.0;
>>     return pow((number1*number2), 1.0/2);
>>   }
>> 
>> This is not an arithmetic mean nor is it a geometric mean.  As far as I
>> know, this calculation has no established name in mathematics.  It may
>> have a name in finance but it looks very odd even then.  It seems to be
>> trying to do several things at once.
>> 
>> > I have showed this above:
>> > if two values are between 1 and zero (i.e. if they are ratios, or percents,
>> > whatever one calls it), then to compute a geometric mean I do the following:
>> > ((1 + number2)*(1 + number2)*.....(1 + numberN))^(1/N)
>> > Therefore, I take the absolute value of each number and see if it's 
>> > between 1 and zero; if it is, then I add 1 to it, which also helps if 
>> > some of those numbers are negative.
>> 
>> I know what the function does because I can see the code.  I'm just
>> complaining about the comment and the name.  If this baroque calculation
>> is standard in finance, then it will have a name and you should use it.
>> What is certain is that it is not a mean
>
> What? A "baroque calculation"? ) This is such a standard math calculation,
> which computes a geometric mean for percents, or ratios, and also accounts
> for negative ones. I am truly surprised to hear that it looks unusual
> to you.

It is short yet it does four different calculations depending on the
inputs.  That makes it baroque.  It may be standard in finance but I am
starting to doubt that since your reference below is to the usual idea
of a geometric mean.

> It's rather basic compounding.
> Does anyone else think it's a weird one? Interesting, truly. But as this has 
> nothing to do with C, then this discussion is not relative for this
> group.

>> >> If this is a standard financial computation, what it is called?  I need
>> >> to look it up to see how it is usually done.
>> 
>> Please answer this.  Can you give me a name or a citation so I can go
>> study this calculation and it's uses?  I asked the same about the later
>> computation as well.
> Tears on my eyes. I did write a name, and have showed you the way 
> it is computed. 
> Here is the article I have googled; it's from investopedia
> http://www.investopedia.com/articles/investing/071113/breaking-down-geometric-mean.asp

That's no help.  It does not name the calculation you are doing and
presents the conventional description of the geometric mean.

But, as you say above, this is not a bot C so I am happy to leave it.
The details of the calculation make no different to the structure of the
program.

<snip>
>> But one even simpler solution (so you can imagine I would urge you to
>> consider it) is to take no special action at all.  On most modern
>> computers, division by floating-point zero will generate a special
>> "infinity" value.  The caller can report a problem if it sees the result
>> is infinity or it can simply leave the value there for the user of the
>> program to see.
> Interesting. I think it is safer for the caller to report a problem;
> because the user might not look at these numbers at all - they
> are intermediary ones used to compute the final table.

Infinity and NaN ("not a number") values propagate through subsequent
calculations in a well-defined way.  There is no way in which the end
result could look valid is some precursor produces and infinity.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#102686

FromAlla _ <modelling.data@gmail.com>
Date2017-01-29 05:11 -0800
Message-ID<fcd851d0-5567-42ae-9e86-9f8141698f6b@googlegroups.com>
In reply to#102683
On Sunday, January 29, 2017 at 3:55:51 PM UTC+3, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
> 
> > On Saturday, January 28, 2017 at 5:49:41 PM UTC+3, Ben Bacarisse wrote:
> >> Alla _ <modelling.data@gmail.com> writes:
> <snip>
> >> > mean(income_ptr->depreciation, bs_ptr->gr_ppe, bs_ptr->intang);
> >> > mean(income_ptr->int_exp, bs_ptr->ltd, NULL);
> >> >
> >> > But I can't do that because I declare the mean function as:
> >> > double mean(income_st *income_ptr, balance *bs_ptr)
> >> 
> >> That's incomprehensible without the typedefs being used.  Most of the
> >> problems are probably due to having the wrong data structures, so I need
> >> to see them.  A function called mean should look like this:
> >> 
> >>   double mean(int n, double *data);
> > Please, see typedefs of structures I have. They are all right, I hope. 
> > Also I don't need to pass int n, as I have pointed elsewhere,
> > because I have a defined data_size I use throughout the program. 
> > income_st, cs_income_st, balance are all used as an array of such
> > structures. assumptions and offsets are both used as they are. 
> > offsets are now used only to fill those three basic arrays of structures
> > while reading each line from each file (two files). 
> >
> > typedef struct data_1 {
> >     int       year;
> >     double    sales;
> >     double    cogs;
> >     double    gross_profit;
> >     double    sga;
> >     double    oper_inc;
> >     double    dep_amor;
> >     double    oper_prof;
> >     double    int_exp;
> >     double    gain_loss;
> >     double    pretax_inc;
> >     double    tax_exp;
> >     double    net_inc;
> > } income_st;
> >
> > typedef struct data_2 {
> >     int       cs_year;
> >     double    cs_sales;
> >     double    cs_cogs;
> >     double    cs_gross_profit;
> >     double    cs_sga;
> >     double    cs_oper_inc;
> >     double    cs_dep_amor;
> >     double    cs_oper_prof;
> >     double    cs_int_exp;
> >     double    cs_gain_loss;
> >     double    cs_pretax_inc;
> >     double    cs_tax_exp;
> >     double    cs_net_inc;
> > } cs_income_st;
> 
> I suggest you represent the year as a double.  It will make the input
> routine simpler since reading years will be the same as reading any
> other value.
> 
> Why do you have two such similar structures?
> 
The first one is a raw data, the second one ratios.
I need both of them. 
> > typedef struct balance_sheet {
> >     double    cash;
> >     double    ar;
> >     double    inv;
> >     double    o_cur_a;
> >     double    t_cur_a;
> >     double    gross_ppe;
> >     double    acc_dep;
> >     double    net_ppe;
> >     double    intang;
> >     double    ta;
> >     double    ap;
> >     double    tp;
> >     double    o_cur_l;
> >     double    t_cur_l;
> >     double    ltd;
> >     double    o_l;
> >     double    tl;
> >     double    se;
> >     double    tle;
> > } balance;
> >
> > typedef struct assumptions {
> >     double gr_sales;
> >     double av_cogs;
> >     double av_gross_profit;
> >     double av_sga;
> >     double av_oper_inc;
> >     double av_dep_amor;
> >     double av_oper_prof;
> >     double av_int_exp;
> >     double av_gain_loss;
> >     double av_pretax_inc;
> >     double av_tax_exp;
> >     double av_net_inc;
> > } assumptions;
> >
> > typedef struct offsets {
> >     int offset_income;
> >     int offset_cs_income;
> >     int offset_balance;
> > } offsets;
> 
> I can see this is going to be very complicated.  With structures like
> this you will probably end up having to write a large number of specific
> calculation functions, each one picking out the parts it cares about.
> Alternatively you will have to pass in one or more offsets of the members
> to operate on, but that's not likely to be any clearer to the reader.
> 
Sad. I hope that I will be able to improve this program once I am better
with programming. 
For now I have found one solution that allows me to skip repeating the same
function twice, although the code within is repeated - I pass a name to it:

/** Function to compute pro forma rate
    for depreciation and interest **/
double dep_int_geo_ratemean(char *name, income_st *income_ptr, balance *bs_ptr)
{
    double product = 1.0;
    
    if(DATA_SIZE > 0)
    {
        //Take data for each year
        for (int i = 1; i < DATA_SIZE; i++)
        {
            if(!strcmp(name, "dep_amor"))
            {
                double mean_ppe = mean_twonums(bs_ptr[i-1].gross_ppe, bs_ptr[i].gross_ppe);
                double mean_intang = mean_twonums(bs_ptr[i-1].intang, bs_ptr[i].intang);
       
                if(income_ptr[i].dep_amor < 0)
                    return dep_int_arith_ratemean(name, income_ptr, mean_ppe, mean_intang);
                
                product *= (1 + income_ptr[i].dep_amor/(mean_ppe + mean_intang));
            }
            else if(!strcmp(name, "int_exp"))
            {
                double mean_debt = mean_twonums(bs_ptr[i-1].ltd, bs_ptr[i].ltd);
               
                if(income_ptr[i].int_exp < 0)
                    return dep_int_arith_ratemean(name, income_ptr, mean_debt, 0.0);
                
                product *= (1 + income_ptr[i].int_exp/mean_debt);
            }
        }
    }
    return pow(product, 1.0/DATA_SIZE) - 1;
}

<snip>
> 
> Infinity and NaN ("not a number") values propagate through subsequent
> calculations in a well-defined way.  There is no way in which the end
> result could look valid is some precursor produces and infinity.
I am still thinking, and have not yet decided to use  isfinite macro for this purpose. 

[toc] | [prev] | [next] | [standalone]


#102695

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-29 14:38 +0000
Message-ID<87fuk2rkxa.fsf@bsb.me.uk>
In reply to#102686
Alla _ <modelling.data@gmail.com> writes:

> On Sunday, January 29, 2017 at 3:55:51 PM UTC+3, Ben Bacarisse wrote:
>> Alla _ <modelling.data@gmail.com> writes:
>> 
>> > On Saturday, January 28, 2017 at 5:49:41 PM UTC+3, Ben Bacarisse wrote:
>> >> Alla _ <modelling.data@gmail.com> writes:
>> <snip>
>> >> > mean(income_ptr->depreciation, bs_ptr->gr_ppe, bs_ptr->intang);
>> >> > mean(income_ptr->int_exp, bs_ptr->ltd, NULL);
>> >> >
>> >> > But I can't do that because I declare the mean function as:
>> >> > double mean(income_st *income_ptr, balance *bs_ptr)
>> >> 
>> >> That's incomprehensible without the typedefs being used.  Most of the
>> >> problems are probably due to having the wrong data structures, so I need
>> >> to see them.  A function called mean should look like this:
>> >> 
>> >>   double mean(int n, double *data);
>> > Please, see typedefs of structures I have. They are all right, I hope. 
>> > Also I don't need to pass int n, as I have pointed elsewhere,
>> > because I have a defined data_size I use throughout the program. 
>> > income_st, cs_income_st, balance are all used as an array of such
>> > structures. assumptions and offsets are both used as they are. 
>> > offsets are now used only to fill those three basic arrays of structures
>> > while reading each line from each file (two files). 
>> >
>> > typedef struct data_1 {
>> >     int       year;
>> >     double    sales;
>> >     double    cogs;
>> >     double    gross_profit;
>> >     double    sga;
>> >     double    oper_inc;
>> >     double    dep_amor;
>> >     double    oper_prof;
>> >     double    int_exp;
>> >     double    gain_loss;
>> >     double    pretax_inc;
>> >     double    tax_exp;
>> >     double    net_inc;
>> > } income_st;
>> >
>> > typedef struct data_2 {
>> >     int       cs_year;
>> >     double    cs_sales;
>> >     double    cs_cogs;
>> >     double    cs_gross_profit;
>> >     double    cs_sga;
>> >     double    cs_oper_inc;
>> >     double    cs_dep_amor;
>> >     double    cs_oper_prof;
>> >     double    cs_int_exp;
>> >     double    cs_gain_loss;
>> >     double    cs_pretax_inc;
>> >     double    cs_tax_exp;
>> >     double    cs_net_inc;
>> > } cs_income_st;
>> 
>> I suggest you represent the year as a double.  It will make the input
>> routine simpler since reading years will be the same as reading any
>> other value.
>> 
>> Why do you have two such similar structures?
>> 
> The first one is a raw data, the second one ratios.
> I need both of them.

But it's not obvious that you need two structures.  I don't define a new
data type when I need a ratio rather than a plain quantity -- I use the
object name to show which is which:

  double distance;
  double distance_ratio;

You might (and it is only a might) get simpler code with one structure
used for both the plain quantities and the ratios.

>> > typedef struct balance_sheet {
<snip>
>> > } balance;
>> >
>> > typedef struct assumptions {
<snip>
>> > } assumptions;
>> >
>> > typedef struct offsets {
<snip>
>> > } offsets;
>> 
>> I can see this is going to be very complicated.  With structures like
>> this you will probably end up having to write a large number of specific
>> calculation functions, each one picking out the parts it cares about.
>> Alternatively you will have to pass in one or more offsets of the members
>> to operate on, but that's not likely to be any clearer to the reader.
>> 
> Sad. I hope that I will be able to improve this program once I am better
> with programming. 
> For now I have found one solution that allows me to skip repeating the same
> function twice, although the code within is repeated - I pass a name to it:
>
> /** Function to compute pro forma rate
>     for depreciation and interest **/
> double dep_int_geo_ratemean(char *name, income_st *income_ptr, balance *bs_ptr)
> {
>     double product = 1.0;
>     
>     if(DATA_SIZE > 0)

Trying to concentrate on bigger issues but I can't always manage to do
that!  What do you think this test is adding?  It's redundant in all the
places I've seen it.

>     {
>         //Take data for each year
>         for (int i = 1; i < DATA_SIZE; i++)
>         {
>             if(!strcmp(name, "dep_amor"))
>             {
>                 double mean_ppe = mean_twonums(bs_ptr[i-1].gross_ppe, bs_ptr[i].gross_ppe);
>                 double mean_intang = mean_twonums(bs_ptr[i-1].intang, bs_ptr[i].intang);
>        
>                 if(income_ptr[i].dep_amor < 0)
>                     return dep_int_arith_ratemean(name, income_ptr, mean_ppe, mean_intang);
>                 
>                 product *= (1 + income_ptr[i].dep_amor/(mean_ppe + mean_intang));
>             }
>             else if(!strcmp(name, "int_exp"))
>             {
>                 double mean_debt = mean_twonums(bs_ptr[i-1].ltd, bs_ptr[i].ltd);
>                
>                 if(income_ptr[i].int_exp < 0)
>                     return dep_int_arith_ratemean(name, income_ptr, mean_debt, 0.0);
>                 
>                 product *= (1 + income_ptr[i].int_exp/mean_debt);
>             }
>         }
>     }
>     return pow(product, 1.0/DATA_SIZE) - 1;
> }

Sorry, but I don't think this is a good idea.  In effect you have two
functions but which one is selected is based on some data passed in.
There is an old adage in computing: pass data not control.  It means the
function should just compute something from it's parameters and not use
the parameters to decide what to compute.  Like all sayings, it's
sometimes wrong, but it's a good one to keep in mind.

Can you show me the calls to this function?  I might then be able to
show how having two functions is clearer (or I might turn out to be
wrong and this is a good idea), but without the calls I am having to
guess.

> <snip>
>> 
>> Infinity and NaN ("not a number") values propagate through subsequent
>> calculations in a well-defined way.  There is no way in which the end
>> result could look valid if some precursor produces and infinity.
(corrected "is" to "if")
> I am still thinking, and have not yet decided to use isfinite macro
> for this purpose.

Or, as I suggested, don't test at all.  Just leave the special values to
come out in the results.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#102707

FromAlla _ <modelling.data@gmail.com>
Date2017-01-29 09:00 -0800
Message-ID<015029dc-b4e3-44c4-be84-b33bef2bf765@googlegroups.com>
In reply to#102695
On Sunday, January 29, 2017 at 5:38:15 PM UTC+3, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
<snip>
> But it's not obvious that you need two structures.  I don't define a new
> data type when I need a ratio rather than a plain quantity -- I use the
> object name to show which is which:
> 
>   double distance;
>   double distance_ratio;
> 
> You might (and it is only a might) get simpler code with one structure
> used for both the plain quantities and the ratios.
> 
> >> > typedef struct balance_sheet {
> <snip>
> >> > } balance;
> >> >
> >> > typedef struct assumptions {
> <snip>
> >> > } assumptions;
> >> >
> >> > typedef struct offsets {
> <snip>
> >> > } offsets;
> >> 
Unfortunately, this will not reflect the data - as you have showed
me incorrect functions' names I used, this will have the same 
effect; also it will be very inconvenient for me. 
In fact, income_st and cs_income_st precisely tell the difference, 
because cs stands for common size, which tells that all data 
is in the ratio form. 
<snip>
> > For now I have found one solution that allows me to skip repeating the same
> > function twice, although the code within is repeated - I pass a name to it:
> >
> > /** Function to compute pro forma rate
> >     for depreciation and interest **/
> > double dep_int_geo_ratemean(char *name, income_st *income_ptr, balance *bs_ptr)
> > {
> >     double product = 1.0;
> >     
> >     if(DATA_SIZE > 0)
> 
> Trying to concentrate on bigger issues but I can't always manage to do
> that!  What do you think this test is adding?  It's redundant in all the
> places I've seen it.
Agree. I have left it in the code in case I add a changing variable instead of a 
defined value. 
> 
> >     {
> >         //Take data for each year
> >         for (int i = 1; i < DATA_SIZE; i++)
> >         {
> >             if(!strcmp(name, "dep_amor"))
> >             {
> >                 double mean_ppe = mean_twonums(bs_ptr[i-1].gross_ppe, bs_ptr[i].gross_ppe);
> >                 double mean_intang = mean_twonums(bs_ptr[i-1].intang, bs_ptr[i].intang);
> >        
> >                 if(income_ptr[i].dep_amor < 0)
> >                     return dep_int_arith_ratemean(name, income_ptr, mean_ppe, mean_intang);
> >                 
> >                 product *= (1 + income_ptr[i].dep_amor/(mean_ppe + mean_intang));
> >             }
> >             else if(!strcmp(name, "int_exp"))
> >             {
> >                 double mean_debt = mean_twonums(bs_ptr[i-1].ltd, bs_ptr[i].ltd);
> >                
> >                 if(income_ptr[i].int_exp < 0)
> >                     return dep_int_arith_ratemean(name, income_ptr, mean_debt, 0.0);
> >                 
> >                 product *= (1 + income_ptr[i].int_exp/mean_debt);
> >             }
> >         }
> >     }
> >     return pow(product, 1.0/DATA_SIZE) - 1;
> > }
> 
> Sorry, but I don't think this is a good idea.  In effect you have two
> functions but which one is selected is based on some data passed in.
> There is an old adage in computing: pass data not control.  It means the
> function should just compute something from it's parameters and not use
> the parameters to decide what to compute.  Like all sayings, it's
> sometimes wrong, but it's a good one to keep in mind.
> 
> Can you show me the calls to this function?  I might then be able to
> show how having two functions is clearer (or I might turn out to be
> wrong and this is a good idea), but without the calls I am having to
> guess.
> 
Of course. 
/** Function to fill assumptions: rates
    for depreciation, interest **/
void balance_rates(income_st *income_ptr, balance *bs_ptr, assumptions *rates)
{
    //Compute rate for depreciation and amortization
    char name_depreciation[] = "dep_amor";
    rates->av_dep_amor = dep_int_geo_ratemean(name_depreciation, income_ptr, bs_ptr);
    
    //Compute rate for interest rate
    char name_interest[] = "int_exp";
    rates->av_int_exp = dep_int_geo_ratemean(name_interest, income_ptr, bs_ptr);
}

<snip>

[toc] | [prev] | [next] | [standalone]


#102708

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-29 17:11 +0000
Message-ID<87lgttrdtj.fsf@bsb.me.uk>
In reply to#102707
Alla _ <modelling.data@gmail.com> writes:

> On Sunday, January 29, 2017 at 5:38:15 PM UTC+3, Ben Bacarisse wrote:
>> Alla _ <modelling.data@gmail.com> writes:
> <snip>
>> But it's not obvious that you need two structures.  I don't define a new
>> data type when I need a ratio rather than a plain quantity -- I use the
>> object name to show which is which:
>> 
>>   double distance;
>>   double distance_ratio;
>> 
>> You might (and it is only a might) get simpler code with one structure
>> used for both the plain quantities and the ratios.
>> 
>> >> > typedef struct balance_sheet {
>> <snip>
>> >> > } balance;
>> >> >
>> >> > typedef struct assumptions {
>> <snip>
>> >> > } assumptions;
>> >> >
>> >> > typedef struct offsets {
>> <snip>
>> >> > } offsets;
>> >> 
> Unfortunately, this will not reflect the data - as you have showed
> me incorrect functions' names I used, this will have the same 
> effect; also it will be very inconvenient for me. 
> In fact, income_st and cs_income_st precisely tell the difference, 
> because cs stands for common size, which tells that all data 
> is in the ratio form.

OK.  I disagree, but I won't push it.

> <snip>
>> > For now I have found one solution that allows me to skip repeating the same
>> > function twice, although the code within is repeated - I pass a name to it:
>> >
>> > /** Function to compute pro forma rate
>> >     for depreciation and interest **/
>> > double dep_int_geo_ratemean(char *name, income_st *income_ptr,
>> > balance *bs_ptr)
>> > {
>> >     double product = 1.0;
>> >     
>> >     if(DATA_SIZE > 0)
>> 
>> Trying to concentrate on bigger issues but I can't always manage to do
>> that!  What do you think this test is adding?  It's redundant in all the
>> places I've seen it.
> Agree. I have left it in the code in case I add a changing variable instead of a 
> defined value.

That's not my point.  What purpose does it serve even when the number of
data points is a variable?

>> >     {
>> >         //Take data for each year
>> >         for (int i = 1; i < DATA_SIZE; i++)
>> >         {
>> >             if(!strcmp(name, "dep_amor"))
>> >             {
>> >                 double mean_ppe = mean_twonums(bs_ptr[i-1].gross_ppe, bs_ptr[i].gross_ppe);
>> >                 double mean_intang = mean_twonums(bs_ptr[i-1].intang, bs_ptr[i].intang);
>> >        
>> >                 if(income_ptr[i].dep_amor < 0)
>> >                     return dep_int_arith_ratemean(name, income_ptr, mean_ppe, mean_intang);
>> >                 
>> >                 product *= (1 + income_ptr[i].dep_amor/(mean_ppe + mean_intang));
>> >             }
>> >             else if(!strcmp(name, "int_exp"))
>> >             {
>> >                 double mean_debt = mean_twonums(bs_ptr[i-1].ltd, bs_ptr[i].ltd);
>> >                
>> >                 if(income_ptr[i].int_exp < 0)
>> >                     return dep_int_arith_ratemean(name, income_ptr, mean_debt, 0.0);
>> >                 
>> >                 product *= (1 + income_ptr[i].int_exp/mean_debt);
>> >             }
>> >         }
>> >     }
>> >     return pow(product, 1.0/DATA_SIZE) - 1;
>> > }
>> 
>> Sorry, but I don't think this is a good idea.  In effect you have two
>> functions but which one is selected is based on some data passed in.
>> There is an old adage in computing: pass data not control.  It means the
>> function should just compute something from it's parameters and not use
>> the parameters to decide what to compute.  Like all sayings, it's
>> sometimes wrong, but it's a good one to keep in mind.
>> 
>> Can you show me the calls to this function?  I might then be able to
>> show how having two functions is clearer (or I might turn out to be
>> wrong and this is a good idea), but without the calls I am having to
>> guess.
>> 
> Of course. 
> /** Function to fill assumptions: rates
>     for depreciation, interest **/
> void balance_rates(income_st *income_ptr, balance *bs_ptr, assumptions *rates)
> {
>     //Compute rate for depreciation and amortization
>     char name_depreciation[] = "dep_amor";
>     rates->av_dep_amor = dep_int_geo_ratemean(name_depreciation,
> income_ptr, bs_ptr);
>     
>     //Compute rate for interest rate
>     char name_interest[] = "int_exp";
>     rates->av_int_exp = dep_int_geo_ratemean(name_interest, income_ptr, bs_ptr);
> }

It is clearer to represent to different action in the name of the
function.  So I'd write:

  rates->av_dep_amor = dep_int_geo_ratemean_dep_amor(income_ptr, bs_ptr);
  rates->av_int_exp = dep_int_geo_ratemean_int_exp(income_ptr, bs_ptr);

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#102714

FromAlla _ <modelling.data@gmail.com>
Date2017-01-29 10:09 -0800
Message-ID<23a59305-103f-4c4a-a8fb-a26b82ef289b@googlegroups.com>
In reply to#102708
On Sunday, January 29, 2017 at 8:11:50 PM UTC+3, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
> <snip>
> > /** Function to fill assumptions: rates
> >     for depreciation, interest **/
> > void balance_rates(income_st *income_ptr, balance *bs_ptr, assumptions *rates)
> > {
> >     //Compute rate for depreciation and amortization
> >     char name_depreciation[] = "dep_amor";
> >     rates->av_dep_amor = dep_int_geo_ratemean(name_depreciation,
> > income_ptr, bs_ptr);
> >     
> >     //Compute rate for interest rate
> >     char name_interest[] = "int_exp";
> >     rates->av_int_exp = dep_int_geo_ratemean(name_interest, income_ptr, bs_ptr);
> > }
> 
> It is clearer to represent to different action in the name of the
> function.  So I'd write:
> 
>   rates->av_dep_amor = dep_int_geo_ratemean_dep_amor(income_ptr, bs_ptr);
>   rates->av_int_exp = dep_int_geo_ratemean_int_exp(income_ptr, bs_ptr);
> 
I see. I will change that and make two separate mean functions. 

[toc] | [prev] | [next] | [standalone]


#102640

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-01-28 10:45 -0500
Message-ID<4f8b2e49-6a8b-fb05-e35b-d21fb00f6779@verizon.net>
In reply to#102627
On 01/28/2017 06:43 AM, Alla _ wrote:
> On Saturday, January 28, 2017 at 2:42:29 AM UTC+3, Ben Bacarisse wrote:
>> Alla _ <modelling.data@gmail.com> writes:
>>
>>> On Friday, January 27, 2017 at 7:44:33 PM UTC+3, Ben Bacarisse wrote:
>>>> Alla _ <modelling.data@gmail.com> writes:
...
>>>>>   if(fabs(number1) < 1 && fabs(number1) > 0)
>>>>>       number1 += 1.0;
>>>>>   if(fabs(number2) < 1 && fabs(number2) > 0)
>>>>>       number2 += 1.0;
>>>>>   return pow((number1*number2), 1.0/2);

Why do you use pow(x, 1.0/2) rather than sqrt(x)? A sufficiently good 
implementation where FLT_RADIX is a power of 2 will generate the same 
code in both cases. A sufficiently poor implementation is likely to 
implement pow(x, 1.0/2) as either slower or less accurate (possibly 
both) than sqrt(x).

>>>> This function is very odd.  It does not do one simple thing.  It does a
>>>> weird bunch of things depending on the data and this is very rarely a
>>>> good idea.
>>> By this code I check if any number is between 1 and zero. I don't see
>>> what wrong with this test :(
>>
>> The function is odd, not the test.  The comment (and the name) says it
>> computes the mean of two numbers, but it doesn't.  It does not even
>> compute one of two means (the arithmetic or geometric) of two numbers.
>> It computed something even odder than that.
> Oh, please ) Not having a math background, I still don't believe this is
> something purely finance - everything used in finance is based on
> math, and I use very simple concepts here. This is a geo mean, or
> also called compound growth rate, though here I apply it only for
> two numbers.
> I have showed this above:
> if two values are between 1 and zero (i.e. if they are ratios, or percents,
> whatever one calls it), ...

Neither ratios nor percents are required to be between 0 and 1. Numbers 
between 0 and 1 are not required to be either ratios or percents. If 
your code was intended to work with percents, it should have factors of 
100 in a variety of places, which it does not.

> ... then to compute a geometric mean I do the following:
> ((1 + number2)*(1 + number2)*.....(1 + numberN))^(1/N)
> Therefore, I take the absolute value of each number and see if it's
> between 1 and zero; if it is, then I add 1 to it, which also helps if
> some of those numbers are negative.

If both arguments to your function are <=0.0, or if both are >=1.0, then 
what it calculates is the geometric mean of those numbers. If number1 
and number2 are both >0.0 and <1.0, what it calculates is the geometric 
mean of 1.0+number1 and 1.0+number2, which is something quite different 
from the geometric mean of number1 and number2. If one of the numbers is 
<=0.0, and the other is not, what you calculate is a domain error. 
Otherwise, if only one of the numbers is >=1.0, there's no simple 
standard name for the function you're calculating.


Specific cases:
===============
The geometric mean of 0.2 and 0.8 is sqrt(0.2*0.8) = 0.4. Your function 
calculates pow(1.2*1.8, 0.5), giving 1.47.

The geometric mean of -1 and 0.5 is csqrt(-1*0.5) = csqrt(-0.50) which 
is 0.71*I, where I is defined in <complex.h> to be the square root of 
-1. Your program calculates pow(-1*1.5, 0.5) = pow(-1.5, 0.5), which is 
a domain error. You do nothing to prevent the domain error, and you 
don't check for the possibility that it occurred.

The geometric mean of -1 and 9 is csqrt(-1*9) = csqrt(-9) = 3*I. Your 
function calculates sqrt(-1*9) = sqrt(-9) which is a domain error - 
again, it does nothing to prevent or detect the domain error.

The geometric mean of 1.0/3.0 and 3.0 is sqrt(1.0/3.0 * 3.0) = sqrt(1) = 
1. Your routine calculates pow((1+1.0/3.0)*3, 0.5) = pow(4, 0.5) = 2.


Because your program changes how it calculates it's result, depending 
upon the values of the numbers, it has discontinuities at number1==0, 
number1==1, number2==0, and number2==1: it calculates something very 
different on one side of each discontinuity than it does on the other 
side. For example:

When number1==0.5 and number2 = 0.99, your function calculates

      pow(1.5*1.99, 0.5) = pow(2.985, 0.5) = 1.73.

When number1=0.5 and number2==1.0, your function calculates

      pow(1.5*1.0, 0.5) = pow(1.5, 0.5) = 1.22

If your function were intended to only be applied to numbers between 0 
and 1, it would make more sense. But you do nothing to reject values 
outside of those ranges, and what it calculates outside of those ranges 
is quite different. And you said above that it was intended to work with 
negative numbers.

[toc] | [prev] | [next] | [standalone]


#102649

FromAlla _ <modelling.data@gmail.com>
Date2017-01-28 10:26 -0800
Message-ID<034bc0b9-1505-4dcb-88e6-5d3ce7570d90@googlegroups.com>
In reply to#102640
On Saturday, January 28, 2017 at 6:46:04 PM UTC+3, James R. Kuyper wrote:
> On 01/28/2017 06:43 AM, Alla _ wrote:
> > On Saturday, January 28, 2017 at 2:42:29 AM UTC+3, Ben Bacarisse wrote:
> >> Alla _ <modelling.data@gmail.com> writes:
> >>
> >>> On Friday, January 27, 2017 at 7:44:33 PM UTC+3, Ben Bacarisse wrote:
> >>>> Alla _ <modelling.data@gmail.com> writes:
> ...
> >>>>>   if(fabs(number1) < 1 && fabs(number1) > 0)
> >>>>>       number1 += 1.0;
> >>>>>   if(fabs(number2) < 1 && fabs(number2) > 0)
> >>>>>       number2 += 1.0;
> >>>>>   return pow((number1*number2), 1.0/2);
> 
> Why do you use pow(x, 1.0/2) rather than sqrt(x)? A sufficiently good 
> implementation where FLT_RADIX is a power of 2 will generate the same 
> code in both cases. A sufficiently poor implementation is likely to 
> implement pow(x, 1.0/2) as either slower or less accurate (possibly 
> both) than sqrt(x).
> 
> >>>> This function is very odd.  It does not do one simple thing.  It does a
> >>>> weird bunch of things depending on the data and this is very rarely a
> >>>> good idea.
> >>> By this code I check if any number is between 1 and zero. I don't see
> >>> what wrong with this test :(
> >>
> >> The function is odd, not the test.  The comment (and the name) says it
> >> computes the mean of two numbers, but it doesn't.  It does not even
> >> compute one of two means (the arithmetic or geometric) of two numbers.
> >> It computed something even odder than that.
> > Oh, please ) Not having a math background, I still don't believe this is
> > something purely finance - everything used in finance is based on
> > math, and I use very simple concepts here. This is a geo mean, or
> > also called compound growth rate, though here I apply it only for
> > two numbers.
> > I have showed this above:
> > if two values are between 1 and zero (i.e. if they are ratios, or percents,
> > whatever one calls it), ...
> 
> Neither ratios nor percents are required to be between 0 and 1. Numbers 
> between 0 and 1 are not required to be either ratios or percents. If 
> your code was intended to work with percents, it should have factors of 
> 100 in a variety of places, which it does not.
> 
> > ... then to compute a geometric mean I do the following:
> > ((1 + number2)*(1 + number2)*.....(1 + numberN))^(1/N)
> > Therefore, I take the absolute value of each number and see if it's
> > between 1 and zero; if it is, then I add 1 to it, which also helps if
> > some of those numbers are negative.
> 
> If both arguments to your function are <=0.0, or if both are >=1.0, then 
> what it calculates is the geometric mean of those numbers. If number1 
> and number2 are both >0.0 and <1.0, what it calculates is the geometric 
> mean of 1.0+number1 and 1.0+number2, which is something quite different 
> from the geometric mean of number1 and number2. If one of the numbers is 
> <=0.0, and the other is not, what you calculate is a domain error. 
> Otherwise, if only one of the numbers is >=1.0, there's no simple 
> standard name for the function you're calculating.
Yes! Precisely! )
Ben, please, take a look at this. 
> 
> 
> Specific cases:
> ===============
> The geometric mean of 0.2 and 0.8 is sqrt(0.2*0.8) = 0.4. Your function 
> calculates pow(1.2*1.8, 0.5), giving 1.47.
> 
> The geometric mean of -1 and 0.5 is csqrt(-1*0.5) = csqrt(-0.50) which 
> is 0.71*I, where I is defined in <complex.h> to be the square root of 
> -1. Your program calculates pow(-1*1.5, 0.5) = pow(-1.5, 0.5), which is 
> a domain error. You do nothing to prevent the domain error, and you 
> don't check for the possibility that it occurred.
> 
> The geometric mean of -1 and 9 is csqrt(-1*9) = csqrt(-9) = 3*I. Your 
> function calculates sqrt(-1*9) = sqrt(-9) which is a domain error - 
> again, it does nothing to prevent or detect the domain error.
> 
> The geometric mean of 1.0/3.0 and 3.0 is sqrt(1.0/3.0 * 3.0) = sqrt(1) = 
> 1. Your routine calculates pow((1+1.0/3.0)*3, 0.5) = pow(4, 0.5) = 2.
> 
> 
> Because your program changes how it calculates it's result, depending 
> upon the values of the numbers, it has discontinuities at number1==0, 
> number1==1, number2==0, and number2==1: it calculates something very 
> different on one side of each discontinuity than it does on the other 
> side. For example:
> 
> When number1==0.5 and number2 = 0.99, your function calculates
> 
>       pow(1.5*1.99, 0.5) = pow(2.985, 0.5) = 1.73.
> 
> When number1=0.5 and number2==1.0, your function calculates
> 
>       pow(1.5*1.0, 0.5) = pow(1.5, 0.5) = 1.22
> 
> If your function were intended to only be applied to numbers between 0 
> and 1, it would make more sense. But you do nothing to reject values 
> outside of those ranges, and what it calculates outside of those ranges 
> is quite different. And you said above that it was intended to work with 
> negative numbers.

[toc] | [prev] | [next] | [standalone]


#102656

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-01-28 14:54 -0500
Message-ID<b8a9e7cc-0d0c-2acc-5071-19dbb4daa1ab@verizon.net>
In reply to#102649
On 01/28/2017 01:26 PM, Alla _ wrote:
> On Saturday, January 28, 2017 at 6:46:04 PM UTC+3, James R. Kuyper wrote:
...
>> If both arguments to your function are <=0.0, or if both are >=1.0, then
>> what it calculates is the geometric mean of those numbers. If number1
>> and number2 are both >0.0 and <1.0, what it calculates is the geometric
>> mean of 1.0+number1 and 1.0+number2, which is something quite different
>> from the geometric mean of number1 and number2. If one of the numbers is
>> <=0.0, and the other is not, what you calculate is a domain error.
>> Otherwise, if only one of the numbers is >=1.0, there's no simple
>> standard name for the function you're calculating.
> Yes! Precisely! )
> Ben, please, take a look at this.

I'm sure that Ben was either aware of everything I said above, or at 
least could have easily figured it out. It's precisely because of the 
things I described above that he was criticizing your function. You 
weren't under the impression that I was confirming the validity of your 
function as an implementation of the geometric mean, were you?

[toc] | [prev] | [next] | [standalone]


#102677

FromAlla _ <modelling.data@gmail.com>
Date2017-01-29 01:54 -0800
Message-ID<0172c485-f902-47c3-960f-d1be3290e229@googlegroups.com>
In reply to#102656
On Saturday, January 28, 2017 at 10:54:10 PM UTC+3, James Kuyper wrote:
> On 01/28/2017 01:26 PM, Alla _ wrote:
> > On Saturday, January 28, 2017 at 6:46:04 PM UTC+3, James R. Kuyper wrote:
> ...
> >> If both arguments to your function are <=0.0, or if both are >=1.0, then
> >> what it calculates is the geometric mean of those numbers. If number1
> >> and number2 are both >0.0 and <1.0, what it calculates is the geometric
> >> mean of 1.0+number1 and 1.0+number2, which is something quite different
> >> from the geometric mean of number1 and number2. If one of the numbers is
> >> <=0.0, and the other is not, what you calculate is a domain error.
> >> Otherwise, if only one of the numbers is >=1.0, there's no simple
> >> standard name for the function you're calculating.
> > Yes! Precisely! )
> > Ben, please, take a look at this.
> 
> I'm sure that Ben was either aware of everything I said above, or at 
> least could have easily figured it out. It's precisely because of the 
> things I described above that he was criticizing your function. You 
> weren't under the impression that I was confirming the validity of your 
> function as an implementation of the geometric mean, were you?
No, of course not ) I was only referring to your precise description of 
what I am doing, and what this basic geo mean is. 

[toc] | [prev] | [next] | [standalone]


#102650

FromAlla _ <modelling.data@gmail.com>
Date2017-01-28 10:38 -0800
Message-ID<899963c8-4716-422b-93c9-59e98c91a160@googlegroups.com>
In reply to#102640
On Saturday, January 28, 2017 at 6:46:04 PM UTC+3, James R. Kuyper wrote:
> On 01/28/2017 06:43 AM, Alla _ wrote:
> > On Saturday, January 28, 2017 at 2:42:29 AM UTC+3, Ben Bacarisse wrote:
> >> Alla _ <modelling.data@gmail.com> writes:
> >>
> >>> On Friday, January 27, 2017 at 7:44:33 PM UTC+3, Ben Bacarisse wrote:
> >>>> Alla _ <modelling.data@gmail.com> writes:
> ...
> >>>>>   if(fabs(number1) < 1 && fabs(number1) > 0)
> >>>>>       number1 += 1.0;
> >>>>>   if(fabs(number2) < 1 && fabs(number2) > 0)
> >>>>>       number2 += 1.0;
> >>>>>   return pow((number1*number2), 1.0/2);
> 
> Why do you use pow(x, 1.0/2) rather than sqrt(x)? A sufficiently good 
> implementation where FLT_RADIX is a power of 2 will generate the same 
> code in both cases. A sufficiently poor implementation is likely to 
> implement pow(x, 1.0/2) as either slower or less accurate (possibly 
> both) than sqrt(x).
> 
> >>>> This function is very odd.  It does not do one simple thing.  It does a
> >>>> weird bunch of things depending on the data and this is very rarely a
> >>>> good idea.
> >>> By this code I check if any number is between 1 and zero. I don't see
> >>> what wrong with this test :(
> >>
> >> The function is odd, not the test.  The comment (and the name) says it
> >> computes the mean of two numbers, but it doesn't.  It does not even
> >> compute one of two means (the arithmetic or geometric) of two numbers.
> >> It computed something even odder than that.
> > Oh, please ) Not having a math background, I still don't believe this is
> > something purely finance - everything used in finance is based on
> > math, and I use very simple concepts here. This is a geo mean, or
> > also called compound growth rate, though here I apply it only for
> > two numbers.
> > I have showed this above:
> > if two values are between 1 and zero (i.e. if they are ratios, or percents,
> > whatever one calls it), ...
> 
> Neither ratios nor percents are required to be between 0 and 1. Numbers 
> between 0 and 1 are not required to be either ratios or percents. If 
> your code was intended to work with percents, it should have factors of 
> 100 in a variety of places, which it does not.
> 
> > ... then to compute a geometric mean I do the following:
> > ((1 + number2)*(1 + number2)*.....(1 + numberN))^(1/N)
> > Therefore, I take the absolute value of each number and see if it's
> > between 1 and zero; if it is, then I add 1 to it, which also helps if
> > some of those numbers are negative.
> 
> If both arguments to your function are <=0.0, or if both are >=1.0, then 
> what it calculates is the geometric mean of those numbers. If number1 
> and number2 are both >0.0 and <1.0, what it calculates is the geometric 
> mean of 1.0+number1 and 1.0+number2, which is something quite different 
> from the geometric mean of number1 and number2. If one of the numbers is 
> <=0.0, and the other is not, what you calculate is a domain error. 
> Otherwise, if only one of the numbers is >=1.0, there's no simple 
> standard name for the function you're calculating.
> 
> 
> Specific cases:
> ===============
> The geometric mean of 0.2 and 0.8 is sqrt(0.2*0.8) = 0.4. Your function 
> calculates pow(1.2*1.8, 0.5), giving 1.47.
> 
> The geometric mean of -1 and 0.5 is csqrt(-1*0.5) = csqrt(-0.50) which 
> is 0.71*I, where I is defined in <complex.h> to be the square root of 
> -1. Your program calculates pow(-1*1.5, 0.5) = pow(-1.5, 0.5), which is 
> a domain error. You do nothing to prevent the domain error, and you 
> don't check for the possibility that it occurred.
> 
> The geometric mean of -1 and 9 is csqrt(-1*9) = csqrt(-9) = 3*I. Your 
> function calculates sqrt(-1*9) = sqrt(-9) which is a domain error - 
> again, it does nothing to prevent or detect the domain error.
No no, you can't use this standard geo mean formula for negative
numbers, which are not in the range between zero and one. 

> 
> The geometric mean of 1.0/3.0 and 3.0 is sqrt(1.0/3.0 * 3.0) = sqrt(1) = 
> 1. Your routine calculates pow((1+1.0/3.0)*3, 0.5) = pow(4, 0.5) = 2.
> 
I have to look into this. This is bad, and I have completely missed 
this case. I have to changed my if condition, so this formula is used
only when both numbers are between 0 and 1. 
> 
> Because your program changes how it calculates it's result, depending 
> upon the values of the numbers, it has discontinuities at number1==0, 
> number1==1, number2==0, and number2==1: it calculates something very 
> different on one side of each discontinuity than it does on the other 
> side. For example:
> 
> When number1==0.5 and number2 = 0.99, your function calculates
> 
>       pow(1.5*1.99, 0.5) = pow(2.985, 0.5) = 1.73.
> 
> When number1=0.5 and number2==1.0, your function calculates
> 
>       pow(1.5*1.0, 0.5) = pow(1.5, 0.5) = 1.22
> 
> If your function were intended to only be applied to numbers between 0 
> and 1, it would make more sense. But you do nothing to reject values 
> outside of those ranges, and what it calculates outside of those ranges 
> is quite different. And you said above that it was intended to work with 
> negative numbers.
Yes, this is a flaw; I have answered above. As to negatives, I was referring
to those between 1 and 0, for example x = -0.3, y = 0.6, hence pow(0.7*1.6, 0.5),
eliminates the negative number. 
Thank you very much for spotting these flaws. I am too much overwhelmed with 
the code and C, and how to make those functions work given the data format
I have, so I completely miss any analysis on how the math works, what I check
and what I don't. It's very bad ) 

[toc] | [prev] | [next] | [standalone]


Page 3 of 9 — ← Prev page 1 2 [3] 4 5 6 7 8 9  Next page →

Back to top | Article view | comp.lang.c


csiph-web