1 2/* 3 * M_APM - mapm5sin.c 4 * 5 * Copyright (C) 1999 - 2007 Michael C. Ring 6 * 7 * Permission to use, copy, and distribute this software and its 8 * documentation for any purpose with or without fee is hereby granted, 9 * provided that the above copyright notice appear in all copies and 10 * that both that copyright notice and this permission notice appear 11 * in supporting documentation. 12 * 13 * Permission to modify the software is granted. Permission to distribute 14 * the modified code is granted. Modifications are to be distributed by 15 * using the file 'license.txt' as a template to modify the file header. 16 * 'license.txt' is available in the official MAPM distribution. 17 * 18 * This software is provided "as is" without express or implied warranty. 19 */ 20 21/* 22 * $Id: mapm5sin.c,v 1.10 2007/12/03 01:26:16 mike Exp $ 23 * 24 * This file contains the functions that implement the sin (5x) 25 * and cos (4x) multiple angle relations 26 * 27 * $Log: mapm5sin.c,v $ 28 * Revision 1.10 2007/12/03 01:26:16 mike 29 * Update license 30 * 31 * Revision 1.9 2002/11/03 21:50:36 mike 32 * Updated function parameters to use the modern style 33 * 34 * Revision 1.8 2001/03/25 20:57:03 mike 35 * move cos_to_sin func in here 36 * 37 * Revision 1.7 2000/05/04 23:50:21 mike 38 * use multiple angle identity 4 times of larger COS angles 39 * 40 * Revision 1.6 1999/06/30 00:08:53 mike 41 * pass more decimal places to raw functions 42 * 43 * Revision 1.5 1999/06/20 23:41:32 mike 44 * changed COS to use 4x multiple angle identity instead of 5x 45 * 46 * Revision 1.4 1999/06/20 19:42:26 mike 47 * tweak number of dec places passed to sub-functions 48 * 49 * Revision 1.3 1999/06/20 19:03:56 mike 50 * changed local static variables to MAPM stack variables 51 * 52 * Revision 1.2 1999/05/12 21:30:09 mike 53 * replace local 5.0 with global 54 * 55 * Revision 1.1 1999/05/10 20:56:31 mike 56 * Initial revision 57 */ 58 59#include "m_apm_lc.h" 60 61/****************************************************************************/ 62void M_5x_sin(M_APM r, int places, M_APM x) 63{ 64M_APM tmp8, tmp9; 65 66tmp8 = M_get_stack_var(); 67tmp9 = M_get_stack_var(); 68 69m_apm_multiply(tmp9, x, MM_5x_125R); /* 1 / (5*5*5) */ 70M_raw_sin(tmp8, (places + 6), tmp9); 71M_5x_do_it(tmp9, (places + 4), tmp8); 72M_5x_do_it(tmp8, (places + 4), tmp9); 73M_5x_do_it(r, places, tmp8); 74 75M_restore_stack(2); 76} 77/****************************************************************************/ 78void M_4x_cos(M_APM r, int places, M_APM x) 79{ 80M_APM tmp8, tmp9; 81 82tmp8 = M_get_stack_var(); 83tmp9 = M_get_stack_var(); 84 85/* 86 * if |x| >= 1.0 use multiple angle identity 4 times 87 * if |x| < 1.0 use multiple angle identity 3 times 88 */ 89 90if (x->m_apm_exponent > 0) 91 { 92 m_apm_multiply(tmp9, x, MM_5x_256R); /* 1 / (4*4*4*4) */ 93 M_raw_cos(tmp8, (places + 8), tmp9); 94 M_4x_do_it(tmp9, (places + 8), tmp8); 95 M_4x_do_it(tmp8, (places + 6), tmp9); 96 M_4x_do_it(tmp9, (places + 4), tmp8); 97 M_4x_do_it(r, places, tmp9); 98 } 99else 100 { 101 m_apm_multiply(tmp9, x, MM_5x_64R); /* 1 / (4*4*4) */ 102 M_raw_cos(tmp8, (places + 6), tmp9); 103 M_4x_do_it(tmp9, (places + 4), tmp8); 104 M_4x_do_it(tmp8, (places + 4), tmp9); 105 M_4x_do_it(r, places, tmp8); 106 } 107 108M_restore_stack(2); 109} 110/****************************************************************************/ 111/* 112 * calculate the multiple angle identity for sin (5x) 113 * 114 * sin (5x) == 16 * sin^5 (x) - 20 * sin^3 (x) + 5 * sin(x) 115 */ 116void M_5x_do_it(M_APM rr, int places, M_APM xx) 117{ 118M_APM tmp0, tmp1, t2, t3, t5; 119 120tmp0 = M_get_stack_var(); 121tmp1 = M_get_stack_var(); 122t2 = M_get_stack_var(); 123t3 = M_get_stack_var(); 124t5 = M_get_stack_var(); 125 126m_apm_multiply(tmp1, xx, xx); 127m_apm_round(t2, (places + 4), tmp1); /* x ^ 2 */ 128 129m_apm_multiply(tmp1, t2, xx); 130m_apm_round(t3, (places + 4), tmp1); /* x ^ 3 */ 131 132m_apm_multiply(t5, t2, t3); /* x ^ 5 */ 133 134m_apm_multiply(tmp0, xx, MM_Five); 135m_apm_multiply(tmp1, t5, MM_5x_Sixteen); 136m_apm_add(t2, tmp0, tmp1); 137m_apm_multiply(tmp1, t3, MM_5x_Twenty); 138m_apm_subtract(tmp0, t2, tmp1); 139 140m_apm_round(rr, places, tmp0); 141M_restore_stack(5); 142} 143/****************************************************************************/ 144/* 145 * calculate the multiple angle identity for cos (4x) 146 * 147 * cos (4x) == 8 * [ cos^4 (x) - cos^2 (x) ] + 1 148 */ 149void M_4x_do_it(M_APM rr, int places, M_APM xx) 150{ 151M_APM tmp0, tmp1, t2, t4; 152 153tmp0 = M_get_stack_var(); 154tmp1 = M_get_stack_var(); 155t2 = M_get_stack_var(); 156t4 = M_get_stack_var(); 157 158m_apm_multiply(tmp1, xx, xx); 159m_apm_round(t2, (places + 4), tmp1); /* x ^ 2 */ 160m_apm_multiply(t4, t2, t2); /* x ^ 4 */ 161 162m_apm_subtract(tmp0, t4, t2); 163m_apm_multiply(tmp1, tmp0, MM_5x_Eight); 164m_apm_add(tmp0, MM_One, tmp1); 165m_apm_round(rr, places, tmp0); 166M_restore_stack(4); 167} 168/****************************************************************************/ 169/* 170 * compute r = sqrt(1 - a ^ 2). 171 */ 172void M_cos_to_sin(M_APM r, int places, M_APM a) 173{ 174M_APM tmp1, tmp2; 175 176tmp1 = M_get_stack_var(); 177tmp2 = M_get_stack_var(); 178 179m_apm_multiply(tmp1, a, a); 180m_apm_subtract(tmp2, MM_One, tmp1); 181m_apm_sqrt(r, places, tmp2); 182M_restore_stack(2); 183} 184/****************************************************************************/ 185