Login [Register]
Don't have an account? Register now to chat, post, use our tools, and much more.
Sorry for being busy today Razz Addressing your first post's points:

0.1 and .1... I thought that it was working just fine :-X Guess I need to look it over

Yeah, that function is incomplete. You read the commit message "Pushing all changes to svn so I don't lose them", since I usually note if things get fixed, or is unstable, etc.. These commits were done even though I wasn't finished and stopped mid-command due to that netbook dieing and is scheduled for a new os.

Yup, those functions aren't there. However, gCAS2 shouldn't crash on them.

Hmm... I need to rethink adding official prizm support. I need to first figure out how to get 3 targets to work with my Makefiles Razz

The mallocs failing would be very useful for GlassOS, maybe not useful on the prizm, and not an issue on desktops Razz I will 3+-2 is valid, treated as (3)+(-2), much trail and error coding went into that. 3.3.3 ... uh, silly gCAS2 Razz If it tells you 3.3 as the result, then (1) my parser for getting the wrong length and (2) atof for filtering out invalid characters, stopping at the second '.'.

Second post (reading in the order I type):

Sorry, I tried to track down all hard coded values, but definately missed some. I had them in when I was mearly testing out functions for the first time.

I believe it does free them on an error, not sure.

For that new function, I like your return method Smile

Ok, so here comes my problem with the C language.... VS doesn't simply refer to the fact that a node has many children, it also points out that the malloc is of a variable size. C structs, as far as I tried, cannot be made to recognize the last variable as an array of undefined size. So, the last variable is technically a cas_node array (from the last variable until the end of the malloc'd struct) of pointers. I did it awkwardly to avoid different compilers from yelling at me.

So, your gcas_tree_copy function is incorrect as the nodes variable is not a pointer to a malloc'd buffer, it is an array itself of length 'size'. If you look at my line to create a cas_node_vs:
Code:
(cas_node_vs*)malloc(sizeof(cas_node_vs)+(size-1)*(sizeof(cas_node*)))
You can see that the cas_node_vs has on cas_node* as the last variable and is included in sizeof(cas_node_vs). I do size-1 to account for that. the *sizeof(cas_node) is there since the malloc holds the array.

I hope that clears up the VS nodes. Fire away more questions if you need to, as my phone line came back up today Smile

Warning! I have committed revision 78 that fixes the building of gCAS, please update to that version! The problem with the arbitrary functions has been fixed already and was finally committed. Building also works. This revision does not have bug fixes mentioned in above in the post.
I feel that your solution, ie, what is essentially a variable-sized struct, is somewhat poor. C is design so that structs are always constant-size, no if, ands, or buts. Therefore, I modified your code to make nodes be a pointer to a malloc'd array of (cas_node*) items, each of which points to a malloc'd (cas_node) or (cas_node_vs). I updated all relevant functions accordingly that deal with that, and I'm happy with my fix. Hope you don't mind. Smile It seems to make a lot of the code much clearer. My complaint was not so much that you did what you did, because I sort of understood your intent, but that it seemed you were inconsistent with how you implemented it. As far as I read it, it didn't seem like it would function properly, but I could easily have been missing a lot of stuff.

The gcas_tree_copy() that I posted is no longer current; I will post my new one. I added a function that forces variables to be replaced with their values during simplification of nNUMBER nodes, but I think that may be in error. I'm currently working with that.
can you post a diff of your code so I can merge it? (The VS node changes)

Oh, I will try to get on to hcwp to do gcas2 work.

<edit>

functions are being redone a bit. Firstly, functions are no longer cas_nodes. They are now cas_node_vs_functions, which is just the cas_node_vs with a cas_function_types funcType; at the end (so casting works much better now).

Second, the nodes are now declaired as cas_node **.

Third, nFUNCTION is removed, nVS_FUNCTION is used since the function is a variable-sized node.

Forth, all functions that change the nN/nP values of a function need to create another node.
I'm probably going to keep my version after all the wrastling I've done with it. Smile And I'm going to fill in the if(flags & lApprox) section of the gcas_alg_func_sqrt() function. In the end, the problem with my tree_copy turned out to be malloc'ing something of size cas_node* instead of cas_node. Sad Here's the current full form:


Code:
int gcas_tree_copy(cas_node** dest, cas_node *src) {

   if (src->type == nVS_FUNCTION || src->type == nVS_ADD || src->type == nVS_SUB) {

      if (NULL == (*dest = realloc(*dest,sizeof(cas_node_vs))))
         return -1;

      _g_memmove(*dest,src,sizeof(cas_node_vs));
   
      //get an array of pointers
      int size = (int)(((cas_node_vs*)src)->size);
      cas_node** array = NULL;
      array = malloc(size*sizeof(cas_node*));
      ((cas_node_vs*)*dest)->nodes = array;
      if (array == NULL)
         return -1;

      //fill in the array elements
      for(int i=0; i<size; i++) {
         if ((((cas_node_vs*)src)->nodes)[i] != NULL) {
            if (NULL == (array[i] = malloc(sizeof(cas_node))))
               return -1;
            if (0 > gcas_tree_copy(&(array[i]),(((cas_node_vs*)src)->nodes)[i]))
               return -1;
         } else (((cas_node_vs*)*dest)->nodes)[i] = NULL;
      }
   } else {
      _g_memmove(*dest,src,sizeof(cas_node));
      if (src->n1)
      {
         if (NULL == ((*dest)->n1 = (cas_node*)malloc(sizeof(cas_node))))
            return -1;
         if (0 > gcas_tree_copy(&((*dest)->n1), src->n1))
            return -1;
      }
      if (src->n2)
      {
         if (NULL == ((*dest)->n2 = (cas_node*)malloc(sizeof(cas_node))))
            return -1;
         if (0 > gcas_tree_copy(&((*dest)->n2), src->n2))
            return -1;
      }
   }
   return 0;
}
Slight fix for the nVS_FUNCTION:


Code:
int gcas_tree_copy(cas_node** dest, cas_node *src) {

   if (src->type == nVS_FUNCTION || src->type == nVS_ADD || src->type == nVS_SUB) {
      unsigned char nodesize = src->type == nVS_FUNCTION ? sizeof(cas_node_vs_function) : sizeof(cas_node_vs);

      if (NULL == (*dest = realloc(*dest,nodesize)))
         return -1;

      _g_memmove(*dest,src,nodesize);
   
      //get an array of pointers
      int size = (int)(((cas_node_vs*)src)->size);
      cas_node** array = NULL;
      array = malloc(size*sizeof(cas_node*));
      ((cas_node_vs*)*dest)->nodes = array;
      if (array == NULL)
         return -1;

      //fill in the array elements
      for(int i=0; i<size; i++) {
         if ((((cas_node_vs*)src)->nodes)[i] != NULL) {
            if (NULL == (array[i] = malloc(sizeof(cas_node))))
               return -1;
            if (0 > gcas_tree_copy(&(array[i]),(((cas_node_vs*)src)->nodes)[i]))
               return -1;
         } else (((cas_node_vs*)*dest)->nodes)[i] = NULL;
      }
   } else {
      _g_memmove(*dest,src,sizeof(cas_node));
      if (src->n1)
      {
         if (NULL == ((*dest)->n1 = (cas_node*)malloc(sizeof(cas_node))))
            return -1;
         if (0 > gcas_tree_copy(&((*dest)->n1), src->n1))
            return -1;
      }
      if (src->n2)
      {
         if (NULL == ((*dest)->n2 = (cas_node*)malloc(sizeof(cas_node))))
            return -1;
         if (0 > gcas_tree_copy(&((*dest)->n2), src->n2))
            return -1;
      }
   }
   return 0;
}


<edit>

Def. for the nodes here:

Code:
typedef struct
{
  cas_node_type type;
  unsigned char size;
  cas_node **nodes; // Pointer to array of cas_node*
} cas_node_vs;
typedef struct
{
  cas_node_type type;
  unsigned char size;
  cas_node **nodes;
  cas_function_types funcType;
} cas_node_vs_function;


<edit>

So, for groups, I need to sort them better. That means that variables and functions will have to have more callbacks. So far, I need a >, ==, +, -, *, and / function per each function/type. I am still thinking it over, so Razz
Much to my confusion, parsing/evaluating X-Y or X/Y crashes on my Prizm, but works fine running the same code on a computer. I might have to valgrind it again and see what's happening.

Edit: Even 3/X and 3+X are crashing. Sad
I also had crashing with variables, fixed in the latest svn commit. I believe it was copying the nodes when resolving.
AHelper wrote:
I also had crashing with variables, fixed in the latest svn commit. I believe it was copying the nodes when resolving.
Sounds good. I noticed that part of the problem is when eval is complete, it is returning an nADD instead of an nNUMBER for 3+X, even when X has a value and lApprox is specified. Any thoughts?
First, is the nADD showing you a number and a variable? If it shows two numbers (as in it substituted the variable), then you forget to use the lBasic flag (required for basic maths).
AHelper wrote:
First, is the nADD showing you a number and a variable? If it shows two numbers (as in it substituted the variable), then you forget to use the lBasic flag (required for basic maths).
Ahhh, I wasn't entirely clear what the flags were about. So I need both lBasic and lApprox to get out a number reliably for my particular application? Smile
I believe so. I usually do lBasic, lGroup, lDistribute, and lApprox.
AHelper wrote:
I believe so. I usually do lBasic, lGroup, lDistribute, and lApprox.
What would your expectations be in terms of execution speed with and without the lGroup and lDistribute flags? Also, it appears that the lBasic tip was a good one; that seems to have fixed the issue I reported about it returning an nADD node for addition.
Distribute is required if you do (x+1)*(2*x-3) and want it to be expanded. Group is used to group together addition. It doesn't let you do much. It will have a speed improvement for stuff like 3*(a+b+c) since the 3* will be distributed quickly to all nodes.
Since I'm working with approximations and pure numbers, though, I would expect something like the first example to be collapsed to (number)*(number-3), then (number)*(number), then just number, correct? In which case the distribute operation would be an extra waste of time, no?
If you are working with pure numbers, you will never have numbers grouped as, like you said, it would be collapsed to a number*number. You can pass lGroup, however if you look at gcas_tree_eval, it passes flags to tree_eval_step from lowest to highest. You will never get the lGroup called as the tree will probably be evaluated on lBasic.
That makes sense, thanks for explaining that. Unfortunately, due to one of my latest changes it seems Graph3DP is crashing on each and every equation that I give it, but it must be something in my graphing code, as the crash doesn't happen at all for the PC version.

Edit: So (XY)^2 doesn't crash, even if I don't give variable XY a value. sqrt(X^2) does not crash. sqrt((X+Y)^2) does not crash. But sqrt((XY)^2) seems to hang indefinitely (X is defined, Y is defined, XY is not). Thoughts?
From the top of my head, look at the code of the sqrt function. That issues sounds like sqrt is returning 1 when it shouldn't. Returning 1 means that it modified a node.gcas will keep looping until all functions return 1.
I think you're right about that, because sin((XY)^2) just yields a blank graph, aka a field full of NaNs. I'll edit this post with what I find.

Edit: There's a control flow path that flows out with _no_ return value, namely if(flags & lApprox) and the node is not an immediate non-variable-reference number with a value. Check it out to see what I mean. Should it return an NaN node somehow in that case, or what?
The return 0; at the end of that function covers that. I tested sqrt((XY)^2) and it returns ok.

Remember that XY != X*Y.
AHelper wrote:
The return 0; at the end of that function covers that. I tested sqrt((XY)^2) and it returns ok.

Remember that XY != X*Y.
Ah, the issue is that in my version of the code, there is no return 0; at the end of the function. Smile That must have appeared when you fixed up compilation in version 78, and I missed it when I did my comparison. Smile
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
» Goto page Previous  1, 2, 3 ... 9, 10, 11, 12  Next
» View previous topic :: View next topic  
Page 10 of 12
» All times are GMT - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement